diff options
author | José Bollo <jose.bollo@iot.bzh> | 2017-01-03 11:13:47 +0100 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2017-01-03 11:13:47 +0100 |
commit | 2db7c92c0b4f5840884481fa4c95facbdea63bb6 (patch) | |
tree | 6c56f2c5288069eed41d78789f66c60e7422ee3c /bindings/radio | |
parent | a38382e89710db2c298f7f101e3ba0cf3681287c (diff) |
Cleanup of the project
The bindings "audio", "media" and "radio"
were in the project since its beginning
for historical reasons.
But this bindings msut not be part of the
current tree of sources.
Change-Id: I9d903f094ddc4d2457e63987df0c221d2bd7b4d1
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
Diffstat (limited to 'bindings/radio')
-rw-r--r-- | bindings/radio/CMakeLists.txt | 17 | ||||
-rw-r--r-- | bindings/radio/export.map | 1 | ||||
-rw-r--r-- | bindings/radio/radio-api.c | 376 | ||||
-rw-r--r-- | bindings/radio/radio-api.h | 49 | ||||
-rw-r--r-- | bindings/radio/radio-rtlsdr.c | 427 | ||||
-rw-r--r-- | bindings/radio/radio-rtlsdr.h | 100 |
6 files changed, 0 insertions, 970 deletions
diff --git a/bindings/radio/CMakeLists.txt b/bindings/radio/CMakeLists.txt deleted file mode 100644 index 4df7adb2..00000000 --- a/bindings/radio/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -INCLUDE(FindPkgConfig) -PKG_CHECK_MODULES(librtlsdr librtlsdr>=0.5.0) - -IF(librtlsdr_FOUND) - - MESSAGE(STATUS "librtlsdr found ; will compile Radio binding... (binding)") - INCLUDE_DIRECTORIES(${include_dirs} ${librtlsdr_INCLUDE_DIRS}) - ADD_LIBRARY(radio-api MODULE radio-api.c radio-rtlsdr.c) - SET_TARGET_PROPERTIES(radio-api PROPERTIES - PREFIX "" - LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/export.map" - ) - TARGET_LINK_LIBRARIES(radio-api ${link_libraries} ${librtlsdr_LIBRARIES} -lm) - INSTALL(TARGETS radio-api - LIBRARY DESTINATION ${binding_install_dir}) - -ENDIF(librtlsdr_FOUND) diff --git a/bindings/radio/export.map b/bindings/radio/export.map deleted file mode 100644 index 0ef1ac79..00000000 --- a/bindings/radio/export.map +++ /dev/null @@ -1 +0,0 @@ -{ global: afbBindingV1Register; local: *; }; diff --git a/bindings/radio/radio-api.c b/bindings/radio/radio-api.c deleted file mode 100644 index 9c1fef6c..00000000 --- a/bindings/radio/radio-api.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright (C) 2015, 2016, 2017 "IoT.bzh" - * Author "Manuel Bachmann" - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define _GNU_SOURCE -#include <strings.h> -#include <json-c/json.h> - -#include "radio-api.h" -#include "radio-rtlsdr.h" - -#include <afb/afb-binding.h> -#include <afb/afb-req-itf.h> - -/* ******************************************************** - - FULUP integration proposal with client session context - - ******************************************************** */ - -/* ------ LOCAL HELPER FUNCTIONS --------- */ - -static pluginHandleT *the_radio = NULL; - -/* detect new radio devices */ -void updateRadioDevList(pluginHandleT *handle) { - - int idx; - - // loop on existing radio if any - for (idx = 0; idx < _radio_dev_count(); idx++) { - if (idx == MAX_RADIO) break; - handle->radios[idx] = calloc(1, sizeof(radioDevT)); /* use calloc to set "used" to FALSE */ - handle->radios[idx]->name = (char *) _radio_dev_name(idx); - } - handle->devCount = _radio_dev_count(); -} - -/* global plugin context creation ; at loading time [radio devices might not be visible] */ -static void initRadioPlugin() { - - pluginHandleT *handle; - - handle = calloc (1, sizeof(pluginHandleT)); - updateRadioDevList (handle); - the_radio = handle; -} - -/* private client context creation ; default values */ -static radioCtxHandleT* initRadioCtx () { - - radioCtxHandleT *ctx; - - ctx = malloc (sizeof(radioCtxHandleT)); - ctx->radio = NULL; - ctx->idx = -1; - ctx->mode = FM; - ctx->freq = 100.0; - ctx->mute = 0; - ctx->is_playing = 0; - - return ctx; -} - -/* reserve a radio device for requesting client, power it on */ -unsigned char reserveRadio (pluginHandleT *handle, radioCtxHandleT *ctx) { - - unsigned int idx; - - /* loop on all devices, find an unused one */ - for (idx = 0; idx < _radio_dev_count(); idx++) { - if (idx == MAX_RADIO) break; - if (handle->radios[idx]->used == FALSE) goto found_radio; /* found one */ - } - return 0; - - found_radio: - /* try to power it on, passing client context info such as frequency... */ - - _radio_on (idx, ctx); - /* TODO : try to re-iterate from the next ones if it failed ! */ - - /* globally mark it as reserved */ - handle->radios[idx]->used = TRUE; - - /* store relevant info to client context (direct pointer, index) */ - ctx->radio = handle->radios[idx]; - ctx->idx = idx; - - return 1; -} - -/* free a radio device from requesting client, power it off */ -unsigned char releaseRadio (pluginHandleT *handle, radioCtxHandleT *ctx) { - - /* stop playing if it was doing this (blocks otherwise) */ - if (ctx->is_playing) { - ctx->is_playing = 0; - _radio_stop (ctx->idx); - } - - /* power it off */ - _radio_off (ctx->idx); - - /* globally mark it as free */ - handle->radios[ctx->idx]->used = FALSE; - - /* clean client context */ - ctx->radio = NULL; - ctx->idx = -1; - - return 1; -} - -/* called when client session dies [e.g. client quits for more than 15mns] */ -static void freeRadio (void *context) { - - releaseRadio (the_radio, context); - free (context); -} - - -/* ------ PUBLIC PLUGIN FUNCTIONS --------- */ - -static void init (struct afb_req request) { /* AFB_SESSION_CHECK */ - - radioCtxHandleT *ctx = afb_req_context_get (request); - json_object *jresp; - - /* create a global plugin handle */ - if (!the_radio) - initRadioPlugin(); - - /* create a private client context */ - if (!ctx) { - ctx = initRadioCtx(); - afb_req_context_set (request, ctx, free); - } - - jresp = json_object_new_object(); - json_object_object_add(jresp, "init", json_object_new_string ("success")); - afb_req_success (request, jresp, "Radio initialized"); -} - -static void power (struct afb_req request) { /* AFB_SESSION_CHECK */ - - pluginHandleT *handle = the_radio; - radioCtxHandleT *ctx = afb_req_context_get (request); - const char *value = afb_req_value (request, "value"); - json_object *jresp; - - if (!ctx) { - afb_req_fail (request, "failed", "you must call 'init' first"); - return; - } - jresp = json_object_new_object(); - - /* no "?value=" parameter : return current state */ - if (!value) { - ctx->radio ? - json_object_object_add (jresp, "power", json_object_new_string ("on")) - : json_object_object_add (jresp, "power", json_object_new_string ("off")); - afb_req_success (request, jresp, "Radio - Power status obtained"); - return; - } - - /* "?value=" parameter is "1" or "true" */ - else if ( atoi(value) == 1 || !strcasecmp(value, "true") ) { - if (!ctx->radio) { - if (!reserveRadio (handle, ctx)) { - afb_req_fail (request, "failed", "no more radio devices available"); - return; - } - } - json_object_object_add (jresp, "power", json_object_new_string ("on")); - } - - /* "?value=" parameter is "0" or "false" */ - else if ( atoi(value) == 0 || !strcasecmp(value, "false") ) { - if (ctx->radio) { - if (!releaseRadio (handle, ctx)) { - afb_req_fail (request, "failed", "Unable to release radio device"); - return; - } - } - json_object_object_add (jresp, "power", json_object_new_string ("off")); - } - else - jresp = NULL; - - afb_req_success (request, jresp, "Radio - Power set"); -} - -static void mode (struct afb_req request) { /* AFB_SESSION_CHECK */ - - radioCtxHandleT *ctx = afb_req_context_get (request); - const char *value = afb_req_value (request, "value"); - json_object *jresp; - - if (!ctx) { - afb_req_fail (request, "failed", "you must call 'init' first"); - return; - } - jresp = json_object_new_object(); - - /* no "?value=" parameter : return current state */ - if (!value || !ctx->radio) { - ctx->mode ? - json_object_object_add (jresp, "mode", json_object_new_string ("AM")) - : json_object_object_add (jresp, "mode", json_object_new_string ("FM")); - } - - /* "?value=" parameter is "1" or "AM" */ - else if ( atoi(value) == 1 || !strcasecmp(value, "AM") ) { - ctx->mode = AM; - _radio_set_mode (ctx->idx, ctx->mode); - json_object_object_add (jresp, "mode", json_object_new_string ("AM")); - } - - /* "?value=" parameter is "0" or "FM" */ - else if ( atoi(value) == 0 || !strcasecmp(value, "FM") ) { - ctx->mode = FM; - _radio_set_mode (ctx->idx, ctx->mode); - json_object_object_add (jresp, "mode", json_object_new_string ("FM")); - } - - afb_req_success (request, jresp, "Radio - Mode set"); -} - -static void freq (struct afb_req request) { /* AFB_SESSION_CHECK */ - - radioCtxHandleT *ctx = afb_req_context_get (request); - const char *value = afb_req_value (request, "value"); - json_object *jresp; - double freq; - char freq_str[256]; - - if (!ctx) { - afb_req_fail (request, "failed", "you must call 'init' first"); - return; - } - jresp = json_object_new_object(); - - /* no "?value=" parameter : return current state */ - if (!value || !ctx->radio) { - snprintf (freq_str, sizeof(freq_str), "%f", ctx->freq); - json_object_object_add (jresp, "freq", json_object_new_string (freq_str)); - } - - /* "?value=" parameter, set frequency */ - else { - freq = strtod (value, NULL); - _radio_set_freq (ctx->idx, freq); - ctx->freq = (float)freq; - - snprintf (freq_str, sizeof(freq_str), "%f", ctx->freq); - json_object_object_add (jresp, "freq", json_object_new_string (freq_str)); - } - - afb_req_success (request, jresp, "Radio - Frequency Set"); -} - -static void mute (struct afb_req request) { /* AFB_SESSION_CHECK */ - - radioCtxHandleT *ctx = afb_req_context_get (request); - const char *value = afb_req_value (request, "value"); - json_object *jresp = json_object_new_object(); - - if (!ctx) { - afb_req_fail (request, "failed", "you must call 'init' first"); - return; - } - - /* no "?value=" parameter : return current state */ - if (!value || !ctx->radio) { - ctx->mute ? - json_object_object_add (jresp, "mute", json_object_new_string ("on")) - : json_object_object_add (jresp, "mute", json_object_new_string ("off")); - } - - /* "?value=" parameter is "1" or "true" */ - else if ( atoi(value) == 1 || !strcasecmp(value, "true") ) { - ctx->mute = 1; - _radio_set_mute (ctx->idx, ctx->mute); - json_object_object_add (jresp, "mute", json_object_new_string ("on")); - } - - /* "?value=" parameter is "0" or "false" */ - else if ( atoi(value) == 0 || !strcasecmp(value, "off") ) { - ctx->mute = 0; - _radio_set_mute (ctx->idx, ctx->mute); - json_object_object_add (jresp, "mute", json_object_new_string ("off")); - } - - afb_req_success (request, jresp, "Radio - Mute set"); -} - -static void play (struct afb_req request) { /* AFB_SESSION_CHECK */ - - radioCtxHandleT *ctx = afb_req_context_get (request); - const char *value = afb_req_value (request, "value"); - json_object *jresp = json_object_new_object(); - - if (!ctx) { - afb_req_fail (request, "failed", "you must call 'init' first"); - return; - } - - /* no "?value=" parameter : return current state */ - if (!value || !ctx->radio) { - ctx->is_playing ? - json_object_object_add (jresp, "play", json_object_new_string ("on")) - : json_object_object_add (jresp, "play", json_object_new_string ("off")); - } - - /* "?value=" parameter is "1" or "true" */ - else if ( atoi(value) == 1 || !strcasecmp(value, "true") ) { - /* radio playback */ - ctx->is_playing = 1; - _radio_play (ctx->idx); - json_object_object_add (jresp, "play", json_object_new_string ("on")); - } - - /* "?value=" parameter is "0" or "false" */ - else if ( atoi(value) == 0 || !strcasecmp(value, "false") ) { - /* radio stop */ - ctx->is_playing = 0; - _radio_stop (ctx->idx); - json_object_object_add (jresp, "play", json_object_new_string ("off")); - } - - afb_req_success (request, jresp, "Radio - Play succeeded"); -} - -static void ping (struct afb_req request) { /* AFB_SESSION_NONE */ - afb_req_success (request, NULL, "Radio - Ping succeeded"); -} - - -static const struct afb_verb_desc_v1 verbs[] = { - {"init" , AFB_SESSION_CHECK, init , "Radio API - init"}, - {"power" , AFB_SESSION_CHECK, power , "Radio API - power"}, - {"mode" , AFB_SESSION_CHECK, mode , "Radio API - mode"}, - {"freq" , AFB_SESSION_CHECK, freq , "Radio API - freq"}, - {"mute" , AFB_SESSION_CHECK, mute , "Radio API - mute"}, - {"play" , AFB_SESSION_CHECK, play , "Radio API - play"}, - {"ping" , AFB_SESSION_NONE, ping , "Radio API - ping"}, - {NULL} -}; - -static const struct afb_binding pluginDesc = { - .type = AFB_BINDING_VERSION_1, - .v1 = { - .info = "Application Framework Binder - Radio plugin", - .prefix = "radio", - .verbs = verbs - } -}; - -const struct afb_binding *afbBindingV1Register (const struct afb_binding_interface *itf) -{ - return &pluginDesc; -} diff --git a/bindings/radio/radio-api.h b/bindings/radio/radio-api.h deleted file mode 100644 index e2e7ab20..00000000 --- a/bindings/radio/radio-api.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2015, 2016, 2017 "IoT.bzh" - * Author "Manuel Bachmann" - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef RADIO_API_H -#define RADIO_API_H - -/* -------------- PLUGIN DEFINITIONS ----------------- */ - -#define MAX_RADIO 10 -typedef enum { FM, AM } Mode; - -/* structure holding one radio device with current usage status */ -typedef struct { - int idx; - char *name; - int used; -} radioDevT; - -/* global plugin handle, should store everything we may need */ -typedef struct { - radioDevT *radios[MAX_RADIO]; // pointer to existing radio - unsigned int devCount; -} pluginHandleT; - -/* private client context [will be destroyed when client leaves] */ -typedef struct { - radioDevT *radio; /* pointer to client radio */ - int idx; /* radio index within global array */ - Mode mode; /* radio mode: AM/FM */ - float freq; /* radio frequency (Mhz) */ - unsigned char mute; /* radio muted: 0(false)/1(true) */ - unsigned char is_playing; /* radio is playing: 0(false)/1(true) */ -} radioCtxHandleT; - -#endif /* RADIO_API_H */ diff --git a/bindings/radio/radio-rtlsdr.c b/bindings/radio/radio-rtlsdr.c deleted file mode 100644 index 3f705cbc..00000000 --- a/bindings/radio/radio-rtlsdr.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Copyright (C) 2015, 2016, 2017 "IoT.bzh" - * Author "Manuel Bachmann" - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "radio-api.h" -#include "radio-rtlsdr.h" - -static void* _dongle_thread_fn (void *); -static void* _demod_thread_fn (void *); -static void* _output_thread_fn (void *); - -static unsigned int init_dev_count = 0; -static struct dev_ctx **dev_ctx = NULL; - -/* ------------- RADIO RTLSDR IMPLEMENTATION ---------------- */ - -/* --- PUBLIC FUNCTIONS --- */ - -/* Radio initialization should be done only when user start the radio and not at plugin initialization - Making this call too early would impose to restart the binder to detect a radio */ -unsigned char _radio_on (unsigned int num, radioCtxHandleT *ctx) { - - if (num >= _radio_dev_count()) - return 0; - - if (init_dev_count < _radio_dev_count()) { - init_dev_count = _radio_dev_count(); - dev_ctx = (dev_ctx_T**) realloc (dev_ctx, init_dev_count * sizeof(dev_ctx_T*)); - } - - dev_ctx[num] = (dev_ctx_T*) malloc (sizeof(dev_ctx_T)); - dev_ctx[num]->dev = NULL; - dev_ctx[num]->mode = ctx->mode; - dev_ctx[num]->freq = ctx->freq; - dev_ctx[num]->mute = ctx->mute; - dev_ctx[num]->should_run = 0; - dev_ctx[num]->dongle = NULL; - dev_ctx[num]->demod = NULL; - dev_ctx[num]->output = NULL; - _radio_dev_init (dev_ctx[num], num); - - return 1; -} - -void _radio_off (unsigned int num) { - - if (num >= _radio_dev_count()) - return; - - if (dev_ctx[num]) { - _radio_dev_free (dev_ctx[num]); - free (dev_ctx[num]); - } - - /* free(dev_ctx); */ -} - -void _radio_set_mode (unsigned int num, Mode mode) { - if (!dev_ctx || !dev_ctx[num]) - return; - - dev_ctx[num]->mode = mode; - _radio_apply_params (dev_ctx[num]); -} - -void _radio_set_freq (unsigned int num, double freq) { - if (!dev_ctx || !dev_ctx[num]) - return; - - dev_ctx[num]->freq = (float)freq; - _radio_apply_params (dev_ctx[num]); -} - -void _radio_set_mute (unsigned int num, unsigned char mute) { - if (!dev_ctx || !dev_ctx[num]) - return; - - dev_ctx[num]->mute = mute; - _radio_apply_params (dev_ctx[num]); -} - -void _radio_play (unsigned int num) { - if (!dev_ctx || !dev_ctx[num]) - return; - - _radio_start_threads (dev_ctx[num]); -} - -void _radio_stop (unsigned int num) { - if (!dev_ctx || !dev_ctx[num]) - return; - - _radio_stop_threads (dev_ctx[num]); -} - -unsigned int _radio_dev_count () { - return rtlsdr_get_device_count(); -} - -const char* _radio_dev_name (unsigned int num) { - return rtlsdr_get_device_name (num); -} - - -/* --- LOCAL HELPER FUNCTIONS --- */ - -unsigned char _radio_dev_init (dev_ctx_T *dev_ctx, unsigned int num) { - rtlsdr_dev_t *dev = dev_ctx->dev; - - if (rtlsdr_open (&dev, num) < 0) - return 0; - - rtlsdr_set_tuner_gain_mode (dev, 0); - - if (rtlsdr_reset_buffer (dev) < 0) - return 0; - - dev_ctx->dev = dev; - - _radio_apply_params (dev_ctx); - - return 1; -} - -unsigned char _radio_dev_free (dev_ctx_T *dev_ctx) { - rtlsdr_dev_t *dev = dev_ctx->dev; - - if (rtlsdr_close (dev) < 0) - return 0; - dev = NULL; - - dev_ctx->dev = dev; - - return 1; -} - -void _radio_apply_params (dev_ctx_T *dev_ctx) { - rtlsdr_dev_t *dev = dev_ctx->dev; - Mode mode = dev_ctx->mode; - float freq = dev_ctx->freq; - int rate; - - freq *= 1000000; - rate = ((1000000 / 200000) + 1) * 200000; - - if (mode == FM) - freq += 16000; - freq += rate / 4; - - rtlsdr_set_center_freq (dev, freq); - rtlsdr_set_sample_rate (dev, rate); - - dev_ctx->dev = dev; -} - -void _radio_start_threads (dev_ctx_T *dev_ctx) { - dev_ctx->dongle = (dongle_ctx*) malloc (sizeof(dongle_ctx)); - dev_ctx->demod = (demod_ctx*) malloc (sizeof(demod_ctx)); - dev_ctx->output = (output_ctx*) malloc (sizeof(output_ctx)); - - dongle_ctx *dongle = dev_ctx->dongle; - demod_ctx *demod = dev_ctx->demod; - output_ctx *output = dev_ctx->output; - - pthread_rwlock_init (&demod->lck, NULL); - pthread_cond_init (&demod->ok, NULL); - pthread_mutex_init (&demod->ok_m, NULL); - pthread_rwlock_init (&output->lck, NULL); - pthread_cond_init (&output->ok, NULL); - pthread_mutex_init (&output->ok_m, NULL); - - dev_ctx->should_run = 1; - - /* dongle thread */ - dongle->thr_finished = 0; - pthread_create (&dongle->thr, NULL, _dongle_thread_fn, (void*)dev_ctx); - - /* demod thread */ - demod->pre_r = demod->pre_j = 0; - demod->now_r = demod->now_j = 0; - demod->index = demod->pre_index = demod->now_index = 0; - demod->thr_finished = 0; - pthread_create (&demod->thr, NULL, _demod_thread_fn, (void*)dev_ctx); - - /* output thread */ - output->thr_finished = 0; - pthread_create (&output->thr, NULL, _output_thread_fn, (void*)dev_ctx); -} - -void _radio_stop_threads (dev_ctx_T *dev_ctx) { - rtlsdr_dev_t *dev = dev_ctx->dev; - dongle_ctx *dongle = dev_ctx->dongle; - demod_ctx *demod = dev_ctx->demod; - output_ctx *output = dev_ctx->output; - - if (!dongle || !demod || !output) - return; - - /* stop each "while" loop in threads */ - dev_ctx->should_run = 0; - - rtlsdr_cancel_async (dev); - pthread_signal (&demod->ok, &demod->ok_m); - pthread_signal (&output->ok, &output->ok_m); - - while (!dongle->thr_finished || - !demod->thr_finished || - !output->thr_finished) - usleep (100000); - - pthread_join (dongle->thr, NULL); - pthread_join (demod->thr, NULL); - pthread_join (output->thr, NULL); - pthread_rwlock_destroy (&demod->lck); - pthread_cond_destroy (&demod->ok); - pthread_mutex_destroy (&demod->ok_m); - pthread_rwlock_destroy (&output->lck); - pthread_cond_destroy (&output->ok); - pthread_mutex_destroy (&output->ok_m); - - free (dongle); dev_ctx->dongle = NULL; - free (demod); dev_ctx->demod = NULL; - free (output); dev_ctx->output = NULL; -} - - /* ---- LOCAL THREADED FUNCTIONS ---- */ - -static void _rtlsdr_callback (unsigned char *buf, uint32_t len, void *ctx) { - dev_ctx_T *dev_ctx = (dev_ctx_T *)ctx; - dongle_ctx *dongle = dev_ctx->dongle; - demod_ctx *demod = dev_ctx->demod; - unsigned char tmp; - int i; - - if (!dev_ctx->should_run) - return; - - /* rotate 90° */ - for (i = 0; i < (int)len; i += 8) { - tmp = 255 - buf[i+3]; - buf[i+3] = buf[i+2]; - buf[i+2] = tmp; - - buf[i+4] = 255 - buf[i+4]; - buf[i+5] = 255 - buf[i+5]; - - tmp = 255 - buf[i+6]; - buf[i+6] = buf[i+7]; - buf[i+7] = tmp; - } - - /* write data */ - for (i = 0; i < (int)len; i++) - dongle->buf[i] = (int16_t)buf[i] - 127; - - /* lock demod thread, write to it, unlock */ - pthread_rwlock_wrlock (&demod->lck); - memcpy (demod->buf, dongle->buf, 2 * len); - demod->buf_len = len; - pthread_rwlock_unlock (&demod->lck); - pthread_signal (&demod->ok, &demod->ok_m); -} - /**/ -static void* _dongle_thread_fn (void *ctx) { - dev_ctx_T *dev_ctx = (dev_ctx_T *)ctx; - dongle_ctx *dongle = dev_ctx->dongle; - - rtlsdr_read_async (dev_ctx->dev, _rtlsdr_callback, dev_ctx, 0, 0); - - dongle->thr_finished = 1; - return 0; -} - -static void _lowpass_demod (void *ctx) { - demod_ctx *demod = (demod_ctx *)ctx; - int i=0, i2=0; - - while (i < demod->buf_len) { - demod->now_r += demod->buf[i]; - demod->now_j += demod->buf[i+1]; - i += 2; - demod->index++; - if (demod->index < ((1000000 / 200000) + 1)) - continue; - demod->buf[i2] = demod->now_r; - demod->buf[i2+1] = demod->now_j; - demod->index = 0; - demod->now_r = demod->now_j = 0; - i2 += 2; - } - demod->buf_len = i2; -} - /**/ -static void _lowpassreal_demod (void *ctx) { - demod_ctx *demod = (demod_ctx *)ctx; - int i=0, i2=0; - int fast = 200000; - int slow = 48000; - - while (i < demod->res_len) { - demod->now_index += demod->res[i]; - i++; - demod->pre_index += slow; - if (demod->pre_index < fast) - continue; - demod->res[i2] = (int16_t)(demod->now_index / (fast/slow)); - demod->pre_index -= fast; - demod->now_index = 0; - i2 += 1; - } - demod->res_len = i2; -} - /**/ -static void _multiply (int ar, int aj, int br, int bj, int *cr, int *cj) { - *cr = ar*br - aj*bj; - *cj = aj*br + ar*bj; -} - /**/ -static int _polar_discriminant (int ar, int aj, int br, int bj) { - int cr, cj; - double angle; - _multiply (ar, aj, br, -bj, &cr, &cj); - angle = atan2 ((double)cj, (double)cr); - return (int)(angle / 3.14159 * (1<<14)); -} - /**/ -static void _fm_demod (void *ctx) { - demod_ctx *demod = (demod_ctx *)ctx; - int16_t *buf = demod->buf; - int buf_len = demod->buf_len; - int pcm, i; - - pcm = _polar_discriminant (buf[0], buf[1], demod->pre_r, demod->pre_j); - demod->res[0] = (int16_t)pcm; - - for (i = 2; i < (buf_len-1); i += 2) { - pcm = _polar_discriminant (buf[i], buf[i+1], buf[i-2], buf[i-1]); - demod->res[i/2] = (int16_t)pcm; - } - demod->pre_r = buf[buf_len - 2]; - demod->pre_j = buf[buf_len - 1]; - demod->res_len = buf_len/2; -} - /**/ -static void _am_demod (void *ctx) { - demod_ctx *demod = (demod_ctx *)ctx; - int16_t *buf = demod->buf; - int buf_len = demod->buf_len; - int pcm, i; - - for (i = 0; i < buf_len; i += 2) { - pcm = buf[i] * buf[i]; - pcm += buf[i+1] * buf[i+1]; - demod->res[i/2] = (int16_t)sqrt(pcm); - } - demod->res_len = buf_len/2; -} - /**/ -static void* _demod_thread_fn (void *ctx) { - dev_ctx_T *dev_ctx = (dev_ctx_T *)ctx; - demod_ctx *demod = dev_ctx->demod; - output_ctx *output = dev_ctx->output; - - while(dev_ctx->should_run) { - pthread_wait (&demod->ok, &demod->ok_m); - pthread_rwlock_wrlock (&demod->lck); - _lowpass_demod (demod); - if (dev_ctx->mode == FM) - _fm_demod (demod); - else - _am_demod (demod); - _lowpassreal_demod (demod); - pthread_rwlock_unlock (&demod->lck); - - /* lock demod thread, write to it, unlock */ - pthread_rwlock_wrlock (&output->lck); - memcpy (output->buf, demod->res, 2 * demod->res_len); - output->buf_len = demod->res_len; - pthread_rwlock_unlock (&output->lck); - pthread_signal (&output->ok, &output->ok_m); - } - - demod->thr_finished = 1; - return 0; -} - -static void* _output_thread_fn (void *ctx) { - dev_ctx_T *dev_ctx = (dev_ctx_T *)ctx; - output_ctx *output = dev_ctx->output; - FILE *file; - - file = fopen (AUDIO_BUFFER, "wb"); - - while (dev_ctx->should_run) { - pthread_wait (&output->ok, &output->ok_m); - pthread_rwlock_rdlock (&output->lck); - if (!dev_ctx->mute && file) { - fwrite (output->buf, 2, output->buf_len, file); - fflush (file); - fseek (file, 0, SEEK_SET); - } - pthread_rwlock_unlock (&output->lck); - } - if (file) fclose(file); - unlink (AUDIO_BUFFER); - - output->thr_finished = 1; - return 0; -} diff --git a/bindings/radio/radio-rtlsdr.h b/bindings/radio/radio-rtlsdr.h deleted file mode 100644 index 3ee80af8..00000000 --- a/bindings/radio/radio-rtlsdr.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2015, 2016, 2017 "IoT.bzh" - * Author "Manuel Bachmann" - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef RADIO_RTLSDR_H -#define RADIO_RTLSDR_H - -/* -------------- RADIO RTLSDR DEFINITIONS ------------------ */ - -#include <math.h> -#include <pthread.h> -#include <rtl-sdr.h> - -#include "radio-api.h" - -#define pthread_signal(n, m) pthread_mutex_lock(m); pthread_cond_signal(n); pthread_mutex_unlock(m) -#define pthread_wait(n, m) pthread_mutex_lock(m); pthread_cond_wait(n, m); pthread_mutex_unlock(m) -#define BUF_LEN 16*16384 -#define AUDIO_BUFFER "/tmp/audio_buf" - -typedef struct dongle_ctx dongle_ctx; -typedef struct demod_ctx demod_ctx; -typedef struct output_ctx output_ctx; -typedef struct dev_ctx dev_ctx_T; - -struct dongle_ctx { - pthread_t thr; - unsigned char thr_finished; - uint16_t buf[BUF_LEN]; - uint32_t buf_len; -}; - -struct demod_ctx { - pthread_t thr; - unsigned char thr_finished; - pthread_rwlock_t lck; - pthread_cond_t ok; - pthread_mutex_t ok_m; - int pre_r, pre_j, now_r, now_j, index; - int pre_index, now_index; - int16_t buf[BUF_LEN]; - int buf_len; - int16_t res[BUF_LEN]; - int res_len; -}; - -struct output_ctx { - pthread_t thr; - unsigned char thr_finished; - pthread_rwlock_t lck; - pthread_cond_t ok; - pthread_mutex_t ok_m; - int16_t buf[BUF_LEN]; - int buf_len; -}; - -struct dev_ctx { - int used; /* TODO: radio is free ??? */ - rtlsdr_dev_t* dev; - Mode mode; - float freq; - unsigned char mute; - unsigned char should_run; - /* thread contexts */ - dongle_ctx *dongle; - demod_ctx *demod; - output_ctx *output; -}; - -unsigned int _radio_dev_count (void); -const char* _radio_dev_name (unsigned int); - -unsigned char _radio_on (unsigned int, radioCtxHandleT *); -void _radio_off (unsigned int); -void _radio_stop (unsigned int); -void _radio_play (unsigned int); -void _radio_set_mode (unsigned int, Mode); -void _radio_set_freq (unsigned int, double); -void _radio_set_mute (unsigned int, unsigned char); - -unsigned char _radio_dev_init (struct dev_ctx *, unsigned int); -unsigned char _radio_dev_free (struct dev_ctx *); -void _radio_apply_params (struct dev_ctx *); -void _radio_start_threads (struct dev_ctx *); -void _radio_stop_threads (struct dev_ctx *); - -#endif /* RADIO_RTLSDR_H */ |