rtl_airband.cpp 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349
  1. /*
  2. * RTLSDR AM/NFM demodulator, mixer, streamer and recorder
  3. *
  4. * Copyright (c) 2014 Wong Man Hang <microtony@gmail.com>
  5. * Copyright (c) 2015-2021 Tomasz Lemiech <szpajder@gmail.com>
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include "config.h"
  21. #if defined WITH_BCM_VC && !defined __arm__
  22. #error Broadcom VideoCore support can only be enabled on ARM builds
  23. #endif
  24. // From this point we may safely assume that WITH_BCM_VC implies __arm__
  25. #ifdef WITH_BCM_VC
  26. #include "hello_fft/gpu_fft.h"
  27. #include "hello_fft/mailbox.h"
  28. #endif /* WITH_BCM_VC */
  29. #include <fcntl.h>
  30. #include <lame/lame.h>
  31. #include <ogg/ogg.h>
  32. #include <pthread.h>
  33. #include <shout/shout.h>
  34. #include <stdint.h> // uint8_t
  35. #include <sys/stat.h>
  36. #include <sys/time.h>
  37. #include <sys/types.h>
  38. #include <sys/wait.h>
  39. #include <syslog.h>
  40. #include <unistd.h>
  41. #include <vorbis/vorbisenc.h>
  42. #include <algorithm>
  43. #include <cassert>
  44. #include <cerrno>
  45. #include <cmath>
  46. #include <csignal>
  47. #include <cstdarg>
  48. #include <cstdio>
  49. #include <cstdlib>
  50. #include <cstring>
  51. #include <ctime>
  52. #include <iostream>
  53. #include <libconfig.h++>
  54. #include "input-common.h"
  55. #include "logging.h"
  56. #include "rtl_airband.h"
  57. #include "squelch.h"
  58. #include <semaphore.h>
  59. #ifdef WITH_PROFILING
  60. #include "gperftools/profiler.h"
  61. #endif /* WITH_PROFILING */
  62. #include <gpiod.h>
  63. #include <ncurses.h>
  64. using namespace std;
  65. using namespace libconfig;
  66. struct gpiod_chip *chip;
  67. struct gpiod_line *gpio16line;
  68. struct gpiod_line *gpio20line;
  69. struct gpiod_line *gpio26line;
  70. #define MAX_BUFFERS 10
  71. sem_t mutex_sem, spooler_sem;
  72. pthread_mutex_t lock_data;
  73. device_t* devices;
  74. mixer_t* mixers;
  75. int bel_start_on_time = 0;
  76. int bel_open_time = 0;
  77. int bel_prolong_time = 0;
  78. float bel_wave_out_level = 0;
  79. float bel_wave_in_level = 0;
  80. int bel_blink_time = 0;
  81. int squelch_status = 0;
  82. int audio_status = 0;
  83. int status_data = 0;
  84. int status_data_old = 0;
  85. int device_count, mixer_count;
  86. static int devices_running = 0;
  87. int tui = 0; // do not display textual user interface
  88. int shout_metadata_delay = 3;
  89. volatile int do_exit = 0;
  90. bool use_localtime = false;
  91. bool multiple_demod_threads = false;
  92. bool multiple_output_threads = false;
  93. bool log_scan_activity = false;
  94. char* stats_filepath = NULL;
  95. size_t fft_size_log = DEFAULT_FFT_SIZE_LOG;
  96. size_t fft_size = 1 << fft_size_log;
  97. #ifdef NFM
  98. float alpha = exp(-1.0f / (WAVE_RATE * 2e-4));
  99. enum fm_demod_algo { FM_FAST_ATAN2, FM_QUADRI_DEMOD };
  100. enum fm_demod_algo fm_demod = FM_FAST_ATAN2;
  101. #endif /* NFM */
  102. #ifdef DEBUG
  103. char* debug_path;
  104. #endif /* DEBUG */
  105. void sighandler(int sig) {
  106. log(LOG_NOTICE, "Got signal %d, exiting\n", sig);
  107. do_exit = 1;
  108. }
  109. void* controller_thread(void* params) {
  110. device_t* dev = (device_t*)params;
  111. int i = 0;
  112. int consecutive_squelch_off = 0;
  113. int new_centerfreq = 0;
  114. struct timeval tv;
  115. if (dev->channels[0].freq_count < 2)
  116. return 0;
  117. while (!do_exit) {
  118. SLEEP(200);
  119. if (dev->channels[0].axcindicate == NO_SIGNAL) {
  120. if (consecutive_squelch_off < 10) {
  121. consecutive_squelch_off++;
  122. } else {
  123. i++;
  124. i %= dev->channels[0].freq_count;
  125. dev->channels[0].freq_idx = i;
  126. new_centerfreq = dev->channels[0].freqlist[i].frequency + 20 * (double)(dev->input->sample_rate / fft_size);
  127. if (input_set_centerfreq(dev->input, new_centerfreq) < 0) {
  128. break;
  129. }
  130. }
  131. } else {
  132. if (consecutive_squelch_off == 10) {
  133. if (log_scan_activity)
  134. log(LOG_INFO, "Activity on %7.3f MHz\n", dev->channels[0].freqlist[i].frequency / 1000000.0);
  135. if (i != dev->last_frequency) {
  136. // squelch has just opened on a new frequency - we might need to update outputs' metadata
  137. gettimeofday(&tv, NULL);
  138. tag_queue_put(dev, i, tv);
  139. dev->last_frequency = i;
  140. }
  141. }
  142. consecutive_squelch_off = 0;
  143. }
  144. }
  145. return 0;
  146. }
  147. void multiply(float ar, float aj, float br, float bj, float* cr, float* cj) {
  148. *cr = ar * br - aj * bj;
  149. *cj = aj * br + ar * bj;
  150. }
  151. void* belysning_control_thread(void*){
  152. struct timespec ts;
  153. struct timeval tv;
  154. long int start_time;
  155. long int stop_time;
  156. long int sq_start_time=0;
  157. long int sq_stop_time=0;
  158. bool sq_status = false;
  159. long int audio_start_time=0;
  160. bool active=false;
  161. gettimeofday(&tv, 0);
  162. start_time=tv.tv_sec;
  163. stop_time=tv.tv_sec+1;
  164. while (!do_exit) {
  165. //double t;
  166. status_data=status_data;
  167. int sem_try=0;
  168. bool activate=false;
  169. bool prolong=false;
  170. if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
  171. printf("clock_gettime");
  172. ts.tv_sec +=1;
  173. sem_try = sem_timedwait(&mutex_sem, &ts);
  174. if (sem_try == 0){
  175. if (sq_status == false && (status_data & 1)){
  176. sq_start_time = tv.tv_sec;
  177. sq_status = true;
  178. }
  179. if (sq_status == true && !(status_data & 1)){
  180. sq_stop_time = tv.tv_sec;
  181. sq_status = false;
  182. }
  183. //printf("ST %u, %u ",(status_data & 1),(status_data >> 1));
  184. if ( (status_data >> 1) ){
  185. audio_start_time = tv.tv_sec;
  186. }
  187. prolong = true;
  188. sem_post(&spooler_sem);
  189. }
  190. //printf("DATA %u, %ld, %ld, %ld %u\n",sq_status,sq_start_time,audio_start_time,tv.tv_sec,prolong);
  191. if (sq_status == true && sq_start_time+bel_open_time < tv.tv_sec && audio_start_time+bel_open_time < tv.tv_sec){
  192. sq_start_time=sq_start_time;
  193. sq_stop_time=sq_stop_time;
  194. activate=true;
  195. }
  196. gettimeofday(&tv, 0);
  197. //First time activation
  198. if (active==false && activate==true){
  199. start_time=tv.tv_sec;
  200. stop_time=tv.tv_sec+bel_start_on_time;
  201. active=true;
  202. printf("Start\n");
  203. }
  204. // Prolong
  205. if (active==true && prolong==true){
  206. if (tv.tv_sec+10 >= stop_time){
  207. stop_time=tv.tv_sec+bel_prolong_time;
  208. printf("Prolong %u\n",bel_prolong_time);
  209. prolong = false;
  210. }
  211. }
  212. if (stop_time<=tv.tv_sec && active){
  213. active=false;
  214. start_time=start_time;
  215. printf("Stop\n");
  216. }
  217. if (active)
  218. if ((stop_time<tv.tv_sec+bel_blink_time) && tv.tv_sec % 2 && bel_blink_time ){
  219. gpiod_line_set_value(gpio26line, 0);
  220. }else{
  221. gpiod_line_set_value(gpio26line, 1);
  222. }
  223. else
  224. gpiod_line_set_value(gpio26line, 0);
  225. }
  226. return 0;
  227. }
  228. #ifdef NFM
  229. float fast_atan2(float y, float x) {
  230. float yabs, angle;
  231. float pi4 = M_PI_4, pi34 = 3 * M_PI_4;
  232. if (x == 0.0f && y == 0.0f) {
  233. return 0;
  234. }
  235. yabs = y;
  236. if (yabs < 0.0f) {
  237. yabs = -yabs;
  238. }
  239. if (x >= 0.0f) {
  240. angle = pi4 - pi4 * (x - yabs) / (x + yabs);
  241. } else {
  242. angle = pi34 - pi4 * (x + yabs) / (yabs - x);
  243. }
  244. if (y < 0.0f) {
  245. return -angle;
  246. }
  247. return angle;
  248. }
  249. float polar_disc_fast(float ar, float aj, float br, float bj) {
  250. float cr, cj;
  251. multiply(ar, aj, br, -bj, &cr, &cj);
  252. return (float)(fast_atan2(cj, cr) * M_1_PI);
  253. }
  254. float fm_quadri_demod(float ar, float aj, float br, float bj) {
  255. return (float)((br * aj - ar * bj) / (ar * ar + aj * aj + 1.0f) * M_1_PI);
  256. }
  257. #endif /* NFM */
  258. class AFC {
  259. const status _prev_axcindicate;
  260. #ifdef WITH_BCM_VC
  261. float square(const GPU_FFT_COMPLEX* fft_results, size_t index) {
  262. return fft_results[index].re * fft_results[index].re + fft_results[index].im * fft_results[index].im;
  263. }
  264. #else
  265. float square(const fftwf_complex* fft_results, size_t index) {
  266. return fft_results[index][0] * fft_results[index][0] + fft_results[index][1] * fft_results[index][1];
  267. }
  268. #endif /* WITH_BCM_VC */
  269. template <class FFT_RESULTS, int STEP>
  270. size_t check(const FFT_RESULTS* fft_results, const size_t base, const float base_value, unsigned char afc) {
  271. float threshold = 0;
  272. size_t bin;
  273. for (bin = base;; bin += STEP) {
  274. if (STEP < 0) {
  275. if (bin < -STEP)
  276. break;
  277. } else if ((size_t)(bin + STEP) >= fft_size)
  278. break;
  279. const float value = square(fft_results, (size_t)(bin + STEP));
  280. if (value <= base_value)
  281. break;
  282. if (base == (size_t)bin) {
  283. threshold = (value - base_value) / (float)afc;
  284. } else {
  285. if ((value - base_value) < threshold)
  286. break;
  287. threshold += threshold / 10.0;
  288. }
  289. }
  290. return bin;
  291. }
  292. public:
  293. AFC(device_t* dev, int index) : _prev_axcindicate(dev->channels[index].axcindicate) {}
  294. template <class FFT_RESULTS>
  295. void finalize(device_t* dev, int index, const FFT_RESULTS* fft_results) {
  296. channel_t* channel = &dev->channels[index];
  297. if (channel->afc == 0)
  298. return;
  299. const char axcindicate = channel->axcindicate;
  300. if (axcindicate != NO_SIGNAL && _prev_axcindicate == NO_SIGNAL) {
  301. const size_t base = dev->base_bins[index];
  302. const float base_value = square(fft_results, base);
  303. size_t bin = check<FFT_RESULTS, -1>(fft_results, base, base_value, channel->afc);
  304. if (bin == base)
  305. bin = check<FFT_RESULTS, 1>(fft_results, base, base_value, channel->afc);
  306. if (dev->bins[index] != bin) {
  307. #ifdef AFC_LOGGING
  308. log(LOG_INFO, "AFC device=%d channel=%d: base=%zu prev=%zu now=%zu\n", dev->device, index, base, dev->bins[index], bin);
  309. #endif /* AFC_LOGGING */
  310. dev->bins[index] = bin;
  311. if (bin > base)
  312. channel->axcindicate = AFC_UP;
  313. else if (bin < base)
  314. channel->axcindicate = AFC_DOWN;
  315. }
  316. } else if (axcindicate == NO_SIGNAL && _prev_axcindicate != NO_SIGNAL)
  317. dev->bins[index] = dev->base_bins[index];
  318. }
  319. };
  320. void init_demod(demod_params_t* params, Signal* signal, int device_start, int device_end) {
  321. assert(params != NULL);
  322. assert(signal != NULL);
  323. params->mp3_signal = signal;
  324. params->device_start = device_start;
  325. params->device_end = device_end;
  326. #ifndef WITH_BCM_VC
  327. params->fftin = fftwf_alloc_complex(fft_size);
  328. params->fftout = fftwf_alloc_complex(fft_size);
  329. params->fft = fftwf_plan_dft_1d(fft_size, params->fftin, params->fftout, FFTW_FORWARD, FFTW_MEASURE);
  330. #endif /* WITH_BCM_VC */
  331. }
  332. void init_output(output_params_t* params, int device_start, int device_end, int mixer_start, int mixer_end) {
  333. assert(params != NULL);
  334. params->mp3_signal = new Signal;
  335. params->device_start = device_start;
  336. params->device_end = device_end;
  337. params->mixer_start = mixer_start;
  338. params->mixer_end = mixer_end;
  339. }
  340. int next_device(demod_params_t* params, int current) {
  341. current++;
  342. if (current < params->device_end) {
  343. return current;
  344. }
  345. return params->device_start;
  346. }
  347. void* demodulate(void* params) {
  348. assert(params != NULL);
  349. demod_params_t* demod_params = (demod_params_t*)params;
  350. debug_print("Starting demod thread, devices %d:%d, signal %p\n", demod_params->device_start, demod_params->device_end, demod_params->mp3_signal);
  351. // initialize fft engine
  352. #ifdef WITH_BCM_VC
  353. int mb = mbox_open();
  354. struct GPU_FFT* fft;
  355. int ret = gpu_fft_prepare(mb, fft_size_log, GPU_FFT_FWD, FFT_BATCH, &fft);
  356. switch (ret) {
  357. case -1:
  358. log(LOG_CRIT, "Unable to enable V3D. Please check your firmware is up to date.\n");
  359. error();
  360. break;
  361. case -2:
  362. log(LOG_CRIT, "log2_N=%d not supported. Try between 8 and 17.\n", fft_size_log);
  363. error();
  364. break;
  365. case -3:
  366. log(LOG_CRIT, "Out of memory. Try a smaller batch or increase GPU memory.\n");
  367. error();
  368. break;
  369. }
  370. #else
  371. fftwf_complex* fftin = demod_params->fftin;
  372. fftwf_complex* fftout = demod_params->fftout;
  373. #endif /* WITH_BCM_VC */
  374. float ALIGNED32 levels_u8[256], levels_s8[256];
  375. float* levels_ptr = NULL;
  376. for (int i = 0; i < 256; i++) {
  377. levels_u8[i] = (i - 127.5f) / 127.5f;
  378. }
  379. for (int16_t i = -127; i < 128; i++) {
  380. levels_s8[(uint8_t)i] = i / 128.0f;
  381. }
  382. // initialize fft window
  383. // blackman 7
  384. // the whole matrix is computed
  385. #ifdef WITH_BCM_VC
  386. float ALIGNED32 window[fft_size * 2];
  387. #else
  388. float ALIGNED32 window[fft_size];
  389. #endif /* WITH_BCM_VC */
  390. const double a0 = 0.27105140069342f;
  391. const double a1 = 0.43329793923448f;
  392. const double a2 = 0.21812299954311f;
  393. const double a3 = 0.06592544638803f;
  394. const double a4 = 0.01081174209837f;
  395. const double a5 = 0.00077658482522f;
  396. const double a6 = 0.00001388721735f;
  397. for (size_t i = 0; i < fft_size; i++) {
  398. double x = a0 - (a1 * cos((2.0 * M_PI * i) / (fft_size - 1))) + (a2 * cos((4.0 * M_PI * i) / (fft_size - 1))) - (a3 * cos((6.0 * M_PI * i) / (fft_size - 1))) +
  399. (a4 * cos((8.0 * M_PI * i) / (fft_size - 1))) - (a5 * cos((10.0 * M_PI * i) / (fft_size - 1))) + (a6 * cos((12.0 * M_PI * i) / (fft_size - 1)));
  400. #ifdef WITH_BCM_VC
  401. window[i * 2] = window[i * 2 + 1] = (float)x;
  402. #else
  403. window[i] = (float)x;
  404. #endif /* WITH_BCM_VC */
  405. }
  406. #ifdef DEBUG
  407. struct timeval ts, te;
  408. gettimeofday(&ts, NULL);
  409. #endif /* DEBUG */
  410. size_t available;
  411. int device_num = demod_params->device_start;
  412. while (true) {
  413. if (do_exit) {
  414. #ifdef WITH_BCM_VC
  415. log(LOG_INFO, "Freeing GPU memory\n");
  416. gpu_fft_release(fft);
  417. #endif /* WITH_BCM_VC */
  418. return NULL;
  419. }
  420. device_t* dev = devices + device_num;
  421. pthread_mutex_lock(&dev->input->buffer_lock);
  422. if (dev->input->bufe >= dev->input->bufs)
  423. available = dev->input->bufe - dev->input->bufs;
  424. else
  425. available = dev->input->buf_size - dev->input->bufs + dev->input->bufe;
  426. pthread_mutex_unlock(&dev->input->buffer_lock);
  427. if (devices_running == 0) {
  428. log(LOG_ERR, "All receivers failed, exiting\n");
  429. do_exit = 1;
  430. continue;
  431. }
  432. if (dev->input->state != INPUT_RUNNING) {
  433. if (dev->input->state == INPUT_FAILED) {
  434. dev->input->state = INPUT_DISABLED;
  435. disable_device_outputs(dev);
  436. devices_running--;
  437. }
  438. device_num = next_device(demod_params, device_num);
  439. continue;
  440. }
  441. // number of input bytes per output wave sample (x 2 for I and Q)
  442. size_t bps = 2 * dev->input->bytes_per_sample * (size_t)round((double)dev->input->sample_rate / (double)WAVE_RATE);
  443. if (available < bps * FFT_BATCH + fft_size * dev->input->bytes_per_sample * 2) {
  444. // move to next device
  445. device_num = next_device(demod_params, device_num);
  446. SLEEP(10);
  447. continue;
  448. }
  449. if (dev->input->sfmt == SFMT_S16) {
  450. float const scale = 1.0f / dev->input->fullscale;
  451. #ifdef WITH_BCM_VC
  452. struct GPU_FFT_COMPLEX* ptr = fft->in;
  453. for (size_t b = 0; b < FFT_BATCH; b++, ptr += fft->step) {
  454. short* buf2 = (short*)(dev->input->buffer + dev->input->bufs + b * bps);
  455. for (size_t i = 0; i < fft_size; i++, buf2 += 2) {
  456. ptr[i].re = scale * (float)buf2[0] * window[i * 2];
  457. ptr[i].im = scale * (float)buf2[1] * window[i * 2];
  458. }
  459. }
  460. #else
  461. short* buf2 = (short*)(dev->input->buffer + dev->input->bufs);
  462. for (size_t i = 0; i < fft_size; i++, buf2 += 2) {
  463. fftin[i][0] = scale * (float)buf2[0] * window[i];
  464. fftin[i][1] = scale * (float)buf2[1] * window[i];
  465. }
  466. #endif /* WITH_BCM_VC */
  467. } else if (dev->input->sfmt == SFMT_F32) {
  468. float const scale = 1.0f / dev->input->fullscale;
  469. #ifdef WITH_BCM_VC
  470. struct GPU_FFT_COMPLEX* ptr = fft->in;
  471. for (size_t b = 0; b < FFT_BATCH; b++, ptr += fft->step) {
  472. float* buf2 = (float*)(dev->input->buffer + dev->input->bufs + b * bps);
  473. for (size_t i = 0; i < fft_size; i++, buf2 += 2) {
  474. ptr[i].re = scale * buf2[0] * window[i * 2];
  475. ptr[i].im = scale * buf2[1] * window[i * 2];
  476. }
  477. }
  478. #else // WITH_BCM_VC
  479. float* buf2 = (float*)(dev->input->buffer + dev->input->bufs);
  480. for (size_t i = 0; i < fft_size; i++, buf2 += 2) {
  481. fftin[i][0] = scale * buf2[0] * window[i];
  482. fftin[i][1] = scale * buf2[1] * window[i];
  483. }
  484. #endif /* WITH_BCM_VC */
  485. } else { // S8 or U8
  486. levels_ptr = (dev->input->sfmt == SFMT_U8 ? levels_u8 : levels_s8);
  487. #ifdef WITH_BCM_VC
  488. sample_fft_arg sfa = {fft_size / 4, fft->in};
  489. for (size_t i = 0; i < FFT_BATCH; i++) {
  490. samplefft(&sfa, dev->input->buffer + dev->input->bufs + i * bps, window, levels_ptr);
  491. sfa.dest += fft->step;
  492. }
  493. #else
  494. unsigned char* buf2 = dev->input->buffer + dev->input->bufs;
  495. for (size_t i = 0; i < fft_size; i++, buf2 += 2) {
  496. fftin[i][0] = levels_ptr[buf2[0]] * window[i];
  497. fftin[i][1] = levels_ptr[buf2[1]] * window[i];
  498. }
  499. #endif /* WITH_BCM_VC */
  500. }
  501. #ifdef WITH_BCM_VC
  502. gpu_fft_execute(fft);
  503. #else
  504. fftwf_execute(demod_params->fft);
  505. #endif /* WITH_BCM_VC */
  506. #ifdef WITH_BCM_VC
  507. for (int i = 0; i < dev->channel_count; i++) {
  508. float* wavein = dev->channels[i].wavein + dev->waveend;
  509. __builtin_prefetch(wavein, 1);
  510. const int bin = dev->bins[i];
  511. const GPU_FFT_COMPLEX* fftout = fft->out + bin;
  512. for (int j = 0; j < FFT_BATCH; j++, ++wavein, fftout += fft->step)
  513. *wavein = sqrtf(fftout->im * fftout->im + fftout->re * fftout->re);
  514. }
  515. for (int j = 0; j < dev->channel_count; j++) {
  516. if (dev->channels[j].needs_raw_iq) {
  517. struct GPU_FFT_COMPLEX* ptr = fft->out;
  518. for (int job = 0; job < FFT_BATCH; job++) {
  519. dev->channels[j].iq_in[2 * (dev->waveend + job)] = ptr[dev->bins[j]].re;
  520. dev->channels[j].iq_in[2 * (dev->waveend + job) + 1] = ptr[dev->bins[j]].im;
  521. ptr += fft->step;
  522. }
  523. }
  524. }
  525. #else
  526. for (int j = 0; j < dev->channel_count; j++) {
  527. dev->channels[j].wavein[dev->waveend] = sqrtf(fftout[dev->bins[j]][0] * fftout[dev->bins[j]][0] + fftout[dev->bins[j]][1] * fftout[dev->bins[j]][1]);
  528. if (dev->channels[j].needs_raw_iq) {
  529. dev->channels[j].iq_in[2 * dev->waveend] = fftout[dev->bins[j]][0];
  530. dev->channels[j].iq_in[2 * dev->waveend + 1] = fftout[dev->bins[j]][1];
  531. }
  532. }
  533. #endif /* WITH_BCM_VC */
  534. dev->waveend += FFT_BATCH;
  535. if (dev->waveend >= WAVE_BATCH + AGC_EXTRA) {
  536. for (int i = 0; i < dev->channel_count; i++) {
  537. AFC afc(dev, i);
  538. channel_t* channel = dev->channels + i;
  539. freq_t* fparms = channel->freqlist + channel->freq_idx;
  540. // set to NO_SIGNAL, will be updated to SIGNAL based on squelch below
  541. channel->axcindicate = NO_SIGNAL;
  542. for (int j = AGC_EXTRA; j < WAVE_BATCH + AGC_EXTRA; j++) {
  543. float& real = channel->iq_in[2 * (j - AGC_EXTRA)];
  544. float& imag = channel->iq_in[2 * (j - AGC_EXTRA) + 1];
  545. fparms->squelch.process_raw_sample(channel->wavein[j]);
  546. // If squelch is open / opening and using I/Q, then cleanup the signal and possibly update squelch.
  547. if (fparms->squelch.should_filter_sample() && channel->needs_raw_iq) {
  548. // remove phase rotation introduced by FFT sliding window
  549. float swf, cwf, re_tmp, im_tmp;
  550. sincosf_lut(channel->dm_phi, &swf, &cwf);
  551. multiply(real, imag, cwf, -swf, &re_tmp, &im_tmp);
  552. channel->dm_phi += channel->dm_dphi;
  553. channel->dm_phi &= 0xffffff;
  554. // apply lowpass filter, will be a no-op if not configured
  555. fparms->lowpass_filter.apply(re_tmp, im_tmp);
  556. // update I/Q and wave
  557. real = re_tmp;
  558. imag = im_tmp;
  559. channel->wavein[j] = sqrt(real * real + imag * imag);
  560. // update squelch post-cleanup
  561. if (fparms->lowpass_filter.enabled()) {
  562. fparms->squelch.process_filtered_sample(channel->wavein[j]);
  563. }
  564. }
  565. if (fparms->modulation == MOD_AM) {
  566. // if squelch is just opening then bootstrip agcavgfast with prior values of wavein
  567. if (fparms->squelch.first_open_sample()) {
  568. for (int k = j - AGC_EXTRA; k < j; k++) {
  569. if (channel->wavein[k] >= fparms->squelch.squelch_level()) {
  570. fparms->agcavgfast = fparms->agcavgfast * 0.9f + channel->wavein[k] * 0.1f;
  571. }
  572. }
  573. }
  574. // if squelch is just closing then fade out the prior samples of waveout
  575. else if (fparms->squelch.last_open_sample()) {
  576. for (int k = j - AGC_EXTRA + 1; k < j; k++) {
  577. channel->waveout[k] = channel->waveout[k - 1] * 0.94f;
  578. }
  579. }
  580. }
  581. float& waveout = channel->waveout[j];
  582. // If squelch sees power then do modulation-specific processing
  583. if (fparms->squelch.should_process_audio()) {
  584. if (fparms->modulation == MOD_AM) {
  585. if (channel->wavein[j] > fparms->squelch.squelch_level()) {
  586. fparms->agcavgfast = fparms->agcavgfast * 0.995f + channel->wavein[j] * 0.005f;
  587. }
  588. waveout = (channel->wavein[j - AGC_EXTRA] - fparms->agcavgfast) / (fparms->agcavgfast * 1.5f);
  589. if (abs(waveout) > 0.8f) {
  590. waveout *= 0.85f;
  591. fparms->agcavgfast *= 1.15f;
  592. }
  593. if ((abs(waveout)>bel_wave_out_level && channel->wavein[j]>bel_wave_in_level) ){
  594. gpiod_line_set_value(gpio20line, 1);
  595. audio_status=1;
  596. }else{
  597. gpiod_line_set_value(gpio20line, 0);
  598. audio_status=0;
  599. }
  600. int temp_status = squelch_status + (audio_status << 1);
  601. if (status_data_old !=temp_status){
  602. pthread_mutex_lock(&lock_data);
  603. status_data = temp_status;
  604. if (sem_post (&mutex_sem) == -1) {
  605. perror ("sem_post: mutex_sem"); exit (1);
  606. }
  607. if (sem_wait(&spooler_sem) == -1){
  608. perror ("sem_post: spooler_sem"); exit (1);
  609. }
  610. status_data_old = status_data;
  611. pthread_mutex_unlock(&lock_data);
  612. }
  613. }
  614. #ifdef NFM
  615. else if (fparms->modulation == MOD_NFM) {
  616. // FM demod
  617. if (fm_demod == FM_FAST_ATAN2) {
  618. waveout = polar_disc_fast(real, imag, channel->pr, channel->pj);
  619. } else if (fm_demod == FM_QUADRI_DEMOD) {
  620. waveout = fm_quadri_demod(real, imag, channel->pr, channel->pj);
  621. }
  622. channel->pr = real;
  623. channel->pj = imag;
  624. // de-emphasis IIR + DC blocking
  625. fparms->agcavgfast = fparms->agcavgfast * 0.995f + waveout * 0.005f;
  626. waveout -= fparms->agcavgfast;
  627. waveout = waveout * (1.0f - channel->alpha) + channel->prev_waveout * channel->alpha;
  628. // save off waveout before notch and ampfactor
  629. channel->prev_waveout = waveout;
  630. }
  631. #endif /* NFM */
  632. // process audio sample for CTCSS, will be no-op if not configured
  633. fparms->squelch.process_audio_sample(waveout);
  634. }
  635. // If squelch is still open then save samples to output
  636. if (fparms->squelch.is_open()) {
  637. // apply the notch filter, will be a no-op if not configured
  638. fparms->notch_filter.apply(waveout);
  639. // apply the ampfactor
  640. waveout *= fparms->ampfactor;
  641. // make sure the value is between +/- 1 (requirement for libmp3lame)
  642. if (isnan(waveout)) {
  643. waveout = 0.0;
  644. } else if (waveout > 1.0) {
  645. waveout = 1.0;
  646. } else if (waveout < -1.0) {
  647. waveout = -1.0;
  648. }
  649. channel->axcindicate = SIGNAL;
  650. if (channel->has_iq_outputs) {
  651. channel->iq_out[2 * (j - AGC_EXTRA)] = real;
  652. channel->iq_out[2 * (j - AGC_EXTRA) + 1] = imag;
  653. }
  654. // Squelch is closed
  655. } else {
  656. waveout = 0;
  657. if (channel->has_iq_outputs) {
  658. channel->iq_out[2 * (j - AGC_EXTRA)] = 0;
  659. channel->iq_out[2 * (j - AGC_EXTRA) + 1] = 0;
  660. }
  661. }
  662. }
  663. memmove(channel->wavein, channel->wavein + WAVE_BATCH, (dev->waveend - WAVE_BATCH) * sizeof(float));
  664. if (channel->needs_raw_iq) {
  665. memmove(channel->iq_in, channel->iq_in + 2 * WAVE_BATCH, (dev->waveend - WAVE_BATCH) * sizeof(float) * 2);
  666. }
  667. #ifdef WITH_BCM_VC
  668. afc.finalize(dev, i, fft->out);
  669. #else
  670. afc.finalize(dev, i, demod_params->fftout);
  671. #endif /* WITH_BCM_VC */
  672. if (tui) {
  673. char symbol = fparms->squelch.signal_outside_filter() ? '~' : (char)channel->axcindicate;
  674. if (dev->mode == R_SCAN) {
  675. //GOTOXY(0, device_num * 17 + dev->row + 3);
  676. //printf("%4.0f/%3.0f%c %7.3f ", level_to_dBFS(fparms->squelch.signal_level()), level_to_dBFS(fparms->squelch.noise_level()), symbol,
  677. // (dev->channels[0].freqlist[channel->freq_idx].frequency / 1000000.0));
  678. } else {
  679. //GOTOXY(i * 10, device_num * 17 + dev->row + 3);
  680. //printf("%4.0f/%3.0f%c ", level_to_dBFS(fparms->squelch.signal_level()), level_to_dBFS(fparms->squelch.noise_level()), symbol);
  681. }
  682. if (symbol=='*'){
  683. gpiod_line_set_value(gpio16line, 1);
  684. squelch_status = 1;
  685. }else{
  686. gpiod_line_set_value(gpio16line, 0);
  687. squelch_status = 0;
  688. }
  689. int temp_status = squelch_status + (audio_status << 1);
  690. if (status_data_old !=temp_status){
  691. pthread_mutex_lock(&lock_data);
  692. status_data = temp_status;
  693. if (sem_post (&mutex_sem) == -1) {
  694. perror ("sem_post: mutex_sem"); exit (1);
  695. }
  696. if (sem_wait(&spooler_sem) == -1){
  697. perror ("sem_post: spooler_sem"); exit (1);
  698. }
  699. status_data_old = status_data;
  700. pthread_mutex_unlock(&lock_data);
  701. }
  702. fflush(stdout);
  703. }
  704. if (channel->axcindicate != NO_SIGNAL) {
  705. channel->freqlist[channel->freq_idx].active_counter++;
  706. }
  707. }
  708. if (dev->waveavail == 1) {
  709. debug_print("devices[%d]: output channel overrun\n", device_num);
  710. dev->output_overrun_count++;
  711. } else {
  712. dev->waveavail = 1;
  713. }
  714. dev->waveend -= WAVE_BATCH;
  715. #ifdef DEBUG
  716. gettimeofday(&te, NULL);
  717. debug_bulk_print("waveavail %lu.%lu %lu\n", te.tv_sec, (unsigned long)te.tv_usec, (te.tv_sec - ts.tv_sec) * 1000000UL + te.tv_usec - ts.tv_usec);
  718. ts.tv_sec = te.tv_sec;
  719. ts.tv_usec = te.tv_usec;
  720. #endif /* DEBUG */
  721. demod_params->mp3_signal->send();
  722. dev->row++;
  723. if (dev->row == 12) {
  724. dev->row = 0;
  725. }
  726. }
  727. dev->input->bufs = (dev->input->bufs + bps * FFT_BATCH) % dev->input->buf_size;
  728. device_num = next_device(demod_params, device_num);
  729. }
  730. }
  731. void usage() {
  732. cout << "Usage: rtl_airband [options] [-c <config_file_path>]\n\
  733. \t-h\t\t\tDisplay this help text\n\
  734. \t-f\t\t\tRun in foreground, display textual waterfalls\n\
  735. \t-F\t\t\tRun in foreground, do not display waterfalls (for running as a systemd service)\n";
  736. #ifdef NFM
  737. cout << "\t-Q\t\t\tUse quadri correlator for FM demodulation (default is atan2)\n";
  738. #endif /* NFM */
  739. #ifdef DEBUG
  740. cout << "\t-d <file>\t\tLog debugging information to <file> (default is " << DEBUG_PATH << ")\n";
  741. #endif /* DEBUG */
  742. cout << "\t-e\t\t\tPrint messages to standard error (disables syslog logging)\n";
  743. cout << "\t-c <config_file_path>\tUse non-default configuration file\n\t\t\t\t(default: " << CFGFILE << ")\n\
  744. \t-v\t\t\tDisplay version and exit\n";
  745. exit(EXIT_SUCCESS);
  746. }
  747. static int count_devices_running() {
  748. int ret = 0;
  749. for (int i = 0; i < device_count; i++) {
  750. if (devices[i].input->state == INPUT_RUNNING) {
  751. ret++;
  752. }
  753. }
  754. return ret;
  755. }
  756. int main(int argc, char* argv[]) {
  757. #ifdef WITH_PROFILING
  758. ProfilerStart("rtl_airband.prof");
  759. #endif /* WITH_PROFILING */
  760. // initialization
  761. sem_init (&mutex_sem, 1, 0);
  762. sem_init (&spooler_sem, 1, 0);
  763. if (pthread_mutex_init(&lock_data, NULL) != 0) {
  764. printf("\n mutex init has failed\n");
  765. return 1;
  766. }
  767. printf("SEM and locks OPEN\n");
  768. char const *chipname = "gpiochip0";
  769. unsigned int gpio16 = 16;
  770. unsigned int gpio20 = 20;
  771. unsigned int gpio26 = 26;
  772. chip = gpiod_chip_open_by_name(chipname);
  773. if (!chip) {
  774. perror("gpiod_chip_open_by_name");
  775. return 1;
  776. }
  777. gpio16line = gpiod_chip_get_line(chip, gpio16);
  778. gpio20line = gpiod_chip_get_line(chip, gpio20);
  779. gpio26line = gpiod_chip_get_line(chip, gpio26);
  780. gpiod_line_request_output(gpio16line, "Consumer1", 0);
  781. gpiod_line_set_value(gpio16line, 0);
  782. gpiod_line_request_output(gpio20line, "Consumer2", 0);
  783. gpiod_line_set_value(gpio20line, 0);
  784. gpiod_line_request_output(gpio26line, "Consumer3", 0);
  785. gpiod_line_set_value(gpio26line, 0);
  786. #pragma GCC diagnostic ignored "-Wwrite-strings"
  787. char* cfgfile = CFGFILE;
  788. char* pidfile = PIDFILE;
  789. #pragma GCC diagnostic warning "-Wwrite-strings"
  790. int opt;
  791. char optstring[16] = "efFhvc:";
  792. #ifdef NFM
  793. strcat(optstring, "Q");
  794. #endif /* NFM */
  795. #ifdef DEBUG
  796. strcat(optstring, "d:");
  797. #endif /* DEBUG */
  798. int foreground = 0; // daemonize
  799. int do_syslog = 1;
  800. while ((opt = getopt(argc, argv, optstring)) != -1) {
  801. switch (opt) {
  802. #ifdef NFM
  803. case 'Q':
  804. fm_demod = FM_QUADRI_DEMOD;
  805. break;
  806. #endif /* NFM */
  807. #ifdef DEBUG
  808. case 'd':
  809. debug_path = strdup(optarg);
  810. break;
  811. #endif /* DEBUG */
  812. case 'e':
  813. do_syslog = 0;
  814. break;
  815. case 'f':
  816. foreground = 1;
  817. tui = 1;
  818. break;
  819. case 'F':
  820. foreground = 1;
  821. tui = 0;
  822. break;
  823. case 'c':
  824. cfgfile = optarg;
  825. break;
  826. case 'v':
  827. cout << "RTLSDR-Airband version " << RTL_AIRBAND_VERSION << "\n";
  828. exit(EXIT_SUCCESS);
  829. case 'h':
  830. default:
  831. usage();
  832. break;
  833. }
  834. }
  835. #ifdef DEBUG
  836. if (!debug_path)
  837. debug_path = strdup(DEBUG_PATH);
  838. init_debug(debug_path);
  839. #endif /* DEBUG */
  840. // If executing other than as root, GPU memory gets alloc'd and the
  841. // 'permission denied' message on /dev/mem kills rtl_airband without
  842. // releasing GPU memory.
  843. #ifdef WITH_BCM_VC
  844. // should probably do this check in other circumstances also.
  845. if (0 != getuid()) {
  846. cerr << "FFT library requires that rtl_airband be executed as root\n";
  847. exit(1);
  848. }
  849. #endif /* WITH_BCM_VC */
  850. // read config
  851. try {
  852. Config config;
  853. config.readFile(cfgfile);
  854. Setting& root = config.getRoot();
  855. if (root.exists("pidfile"))
  856. pidfile = strdup(root["pidfile"]);
  857. if (root.exists("fft_size")) {
  858. int fsize = (int)(root["fft_size"]);
  859. fft_size_log = 0;
  860. for (size_t i = MIN_FFT_SIZE_LOG; i <= MAX_FFT_SIZE_LOG; i++) {
  861. if (fsize == 1 << i) {
  862. fft_size = (size_t)fsize;
  863. fft_size_log = i;
  864. break;
  865. }
  866. }
  867. if (fft_size_log == 0) {
  868. cerr << "Configuration error: invalid fft_size value (must be a power of two in range " << (1 << MIN_FFT_SIZE_LOG) << "-" << (1 << MAX_FFT_SIZE_LOG) << ")\n";
  869. error();
  870. }
  871. }
  872. if (root.exists("shout_metadata_delay"))
  873. shout_metadata_delay = (int)(root["shout_metadata_delay"]);
  874. if (shout_metadata_delay < 0 || shout_metadata_delay > 2 * TAG_QUEUE_LEN) {
  875. cerr << "Configuration error: shout_metadata_delay is out of allowed range (0-" << 2 * TAG_QUEUE_LEN << ")\n";
  876. error();
  877. }
  878. if (root.exists("localtime") && (bool)root["localtime"] == true)
  879. use_localtime = true;
  880. if (root.exists("multiple_demod_threads") && (bool)root["multiple_demod_threads"] == true) {
  881. #ifdef WITH_BCM_VC
  882. cerr << "Using multiple_demod_threads not supported with BCM VideoCore for FFT\n";
  883. exit(1);
  884. #endif /* WITH_BCM_VC */
  885. multiple_demod_threads = true;
  886. }
  887. if (root.exists("multiple_output_threads") && (bool)root["multiple_output_threads"] == true) {
  888. multiple_output_threads = true;
  889. }
  890. if (root.exists("log_scan_activity") && (bool)root["log_scan_activity"] == true)
  891. log_scan_activity = true;
  892. if (root.exists("stats_filepath"))
  893. stats_filepath = strdup(root["stats_filepath"]);
  894. #ifdef NFM
  895. if (root.exists("tau"))
  896. alpha = ((int)root["tau"] == 0 ? 0.0f : exp(-1.0f / (WAVE_RATE * 1e-6 * (int)root["tau"])));
  897. #endif /* NFM */
  898. if (root.exists("bel_start_on_time"))
  899. bel_start_on_time=(int)(root["bel_start_on_time"]);
  900. if (root.exists("bel_open_time"))
  901. bel_open_time=(int)(root["bel_open_time"]);
  902. if (root.exists("bel_blink_time"))
  903. bel_blink_time=(int)(root["bel_blink_time"]);
  904. if (root.exists("bel_wave_out_level"))
  905. bel_wave_out_level=(float)(root["bel_wave_out_level"]);
  906. if (root.exists("bel_wave_in_level"))
  907. bel_wave_in_level=(float)(root["bel_wave_in_level"]);
  908. if (root.exists("bel_prolong_time"))
  909. bel_prolong_time=(int)(root["bel_prolong_time"]);
  910. Setting& devs = config.lookup("devices");
  911. device_count = devs.getLength();
  912. if (device_count < 1) {
  913. cerr << "Configuration error: no devices defined\n";
  914. error();
  915. }
  916. struct sigaction sigact, pipeact;
  917. memset(&sigact, 0, sizeof(sigact));
  918. memset(&pipeact, 0, sizeof(pipeact));
  919. pipeact.sa_handler = SIG_IGN;
  920. sigact.sa_handler = &sighandler;
  921. sigaction(SIGPIPE, &pipeact, NULL);
  922. sigaction(SIGHUP, &sigact, NULL);
  923. sigaction(SIGINT, &sigact, NULL);
  924. sigaction(SIGQUIT, &sigact, NULL);
  925. sigaction(SIGTERM, &sigact, NULL);
  926. devices = (device_t*)XCALLOC(device_count, sizeof(device_t));
  927. shout_init();
  928. if (do_syslog) {
  929. openlog("rtl_airband", LOG_PID, LOG_DAEMON);
  930. log_destination = SYSLOG;
  931. } else if (foreground) {
  932. log_destination = STDERR;
  933. } else {
  934. log_destination = NONE;
  935. }
  936. if (root.exists("mixers")) {
  937. Setting& mx = config.lookup("mixers");
  938. mixers = (mixer_t*)XCALLOC(mx.getLength(), sizeof(struct mixer_t));
  939. if ((mixer_count = parse_mixers(mx)) > 0) {
  940. mixers = (mixer_t*)XREALLOC(mixers, mixer_count * sizeof(struct mixer_t));
  941. } else {
  942. free(mixers);
  943. }
  944. } else {
  945. mixer_count = 0;
  946. }
  947. uint32_t devs_enabled = parse_devices(devs);
  948. if (devs_enabled < 1) {
  949. cerr << "Configuration error: no devices defined\n";
  950. error();
  951. }
  952. device_count = devs_enabled;
  953. debug_print("mixer_count=%d\n", mixer_count);
  954. #ifdef DEBUG
  955. for (int z = 0; z < mixer_count; z++) {
  956. mixer_t* m = &mixers[z];
  957. debug_print("mixer[%d]: name=%s, input_count=%d, output_count=%d\n", z, m->name, m->input_count, m->channel.output_count);
  958. }
  959. #endif /* DEBUG */
  960. } catch (const FileIOException& e) {
  961. cerr << "Cannot read configuration file " << cfgfile << "\n";
  962. error();
  963. } catch (const ParseException& e) {
  964. cerr << "Error while parsing configuration file " << cfgfile << " line " << e.getLine() << ": " << e.getError() << "\n";
  965. error();
  966. } catch (const SettingNotFoundException& e) {
  967. cerr << "Configuration error: mandatory parameter missing: " << e.getPath() << "\n";
  968. error();
  969. } catch (const SettingTypeException& e) {
  970. cerr << "Configuration error: invalid parameter type: " << e.getPath() << "\n";
  971. error();
  972. } catch (const ConfigException& e) {
  973. cerr << "Unhandled config exception\n";
  974. error();
  975. }
  976. log(LOG_INFO, "RTLSDR-Airband version %s starting\n", RTL_AIRBAND_VERSION);
  977. if (!foreground) {
  978. int pid1, pid2;
  979. if ((pid1 = fork()) == -1) {
  980. cerr << "Cannot fork child process: " << strerror(errno) << "\n";
  981. error();
  982. }
  983. if (pid1) {
  984. waitpid(-1, NULL, 0);
  985. return (0);
  986. } else {
  987. if ((pid2 = fork()) == -1) {
  988. cerr << "Cannot fork child process: " << strerror(errno) << "\n";
  989. error();
  990. }
  991. if (pid2) {
  992. return (0);
  993. } else {
  994. int nullfd, dupfd;
  995. if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
  996. log(LOG_CRIT, "Cannot open /dev/null: %s\n", strerror(errno));
  997. error();
  998. }
  999. for (dupfd = 0; dupfd <= 2; dupfd++) {
  1000. if (dup2(nullfd, dupfd) == -1) {
  1001. log(LOG_CRIT, "dup2(): %s\n", strerror(errno));
  1002. error();
  1003. }
  1004. }
  1005. if (nullfd > 2)
  1006. close(nullfd);
  1007. FILE* f = fopen(pidfile, "w");
  1008. if (f == NULL) {
  1009. log(LOG_WARNING, "Cannot write pidfile: %s\n", strerror(errno));
  1010. } else {
  1011. fprintf(f, "%ld\n", (long)getpid());
  1012. fclose(f);
  1013. }
  1014. }
  1015. }
  1016. }
  1017. for (int i = 0; i < mixer_count; i++) {
  1018. if (mixers[i].enabled == false) {
  1019. continue; // no inputs connected = no need to initialize output
  1020. }
  1021. channel_t* channel = &mixers[i].channel;
  1022. if (channel->need_mp3) {
  1023. channel->lame = airlame_init(mixers[i].channel.mode, mixers[i].channel.highpass, mixers[i].channel.lowpass);
  1024. channel->lamebuf = (unsigned char*)malloc(sizeof(unsigned char) * LAMEBUF_SIZE);
  1025. }
  1026. for (int k = 0; k < channel->output_count; k++) {
  1027. output_t* output = channel->outputs + k;
  1028. if (output->type == O_ICECAST) {
  1029. shout_setup((icecast_data*)(output->data), channel->mode);
  1030. } else if (output->type == O_UDP_STREAM) {
  1031. udp_stream_data* sdata = (udp_stream_data*)(output->data);
  1032. if (!udp_stream_init(sdata, channel->mode, (size_t)WAVE_BATCH * sizeof(float))) {
  1033. cerr << "Failed to initialize mixer " << i << " output " << k << " - aborting\n";
  1034. error();
  1035. }
  1036. #ifdef WITH_PULSEAUDIO
  1037. } else if (output->type == O_PULSE) {
  1038. pulse_init();
  1039. pulse_setup((pulse_data*)(output->data), channel->mode);
  1040. #endif /* WITH_PULSEAUDIO */
  1041. }
  1042. }
  1043. }
  1044. for (int i = 0; i < device_count; i++) {
  1045. device_t* dev = devices + i;
  1046. for (int j = 0; j < dev->channel_count; j++) {
  1047. channel_t* channel = dev->channels + j;
  1048. // If the channel has icecast or MP3 file output, we will attempt to
  1049. // initialize a separate LAME context for MP3 encoding.
  1050. if (channel->need_mp3) {
  1051. channel->lame = airlame_init(channel->mode, channel->highpass, channel->lowpass);
  1052. channel->lamebuf = (unsigned char*)malloc(sizeof(unsigned char) * LAMEBUF_SIZE);
  1053. }
  1054. for (int k = 0; k < channel->output_count; k++) {
  1055. output_t* output = channel->outputs + k;
  1056. if (output->type == O_ICECAST) {
  1057. shout_setup((icecast_data*)(output->data), channel->mode);
  1058. } else if (output->type == O_UDP_STREAM) {
  1059. udp_stream_data* sdata = (udp_stream_data*)(output->data);
  1060. if (!udp_stream_init(sdata, channel->mode, (size_t)WAVE_BATCH * sizeof(float))) {
  1061. cerr << "Failed to initialize device " << i << " channel " << j << " output " << k << " - aborting\n";
  1062. error();
  1063. }
  1064. #ifdef WITH_PULSEAUDIO
  1065. } else if (output->type == O_PULSE) {
  1066. pulse_init();
  1067. pulse_setup((pulse_data*)(output->data), channel->mode);
  1068. #endif /* WITH_PULSEAUDIO */
  1069. }
  1070. }
  1071. }
  1072. if (input_init(dev->input) != 0 || dev->input->state != INPUT_INITIALIZED) {
  1073. if (errno != 0) {
  1074. cerr << "Failed to initialize input device " << i << ": " << strerror(errno) << " - aborting\n";
  1075. } else {
  1076. cerr << "Failed to initialize input device " << i << " - aborting\n";
  1077. }
  1078. error();
  1079. }
  1080. if (input_start(dev->input) != 0) {
  1081. cerr << "Failed to start input on device " << i << ": " << strerror(errno) << " - aborting\n";
  1082. error();
  1083. }
  1084. if (dev->mode == R_SCAN) {
  1085. // FIXME: set errno
  1086. if (pthread_mutex_init(&dev->tag_queue_lock, NULL) != 0) {
  1087. cerr << "Failed to initialize mutex - aborting\n";
  1088. error();
  1089. }
  1090. // FIXME: not needed when freq_count == 1?
  1091. pthread_create(&dev->controller_thread, NULL, &controller_thread, dev);
  1092. }
  1093. }
  1094. int timeout = 50; // 5 seconds
  1095. while ((devices_running = count_devices_running()) != device_count && timeout > 0) {
  1096. SLEEP(100);
  1097. timeout--;
  1098. }
  1099. if ((devices_running = count_devices_running()) != device_count) {
  1100. log(LOG_ERR, "%d device(s) failed to initialize - aborting\n", device_count - devices_running);
  1101. error();
  1102. }
  1103. if (tui) {
  1104. printf("\e[1;1H\e[2J");
  1105. GOTOXY(0, 0);
  1106. printf(" ");
  1107. for (int i = 0; i < device_count; i++) {
  1108. GOTOXY(0, i * 17 + 1);
  1109. for (int j = 0; j < devices[i].channel_count; j++) {
  1110. printf(" %7.3f ", devices[i].channels[j].freqlist[devices[i].channels[j].freq_idx].frequency / 1000000.0);
  1111. }
  1112. if (i != device_count - 1) {
  1113. GOTOXY(0, i * 17 + 16);
  1114. printf("-------------------------------------------------------------------------------");
  1115. }
  1116. }
  1117. }
  1118. THREAD belysning_control_check;
  1119. pthread_create(&belysning_control_check, NULL, &belysning_control_thread, NULL);
  1120. THREAD output_check;
  1121. pthread_create(&output_check, NULL, &output_check_thread, NULL);
  1122. int demod_thread_count = multiple_demod_threads ? device_count : 1;
  1123. demod_params_t* demod_params = (demod_params_t*)XCALLOC(demod_thread_count, sizeof(demod_params_t));
  1124. THREAD* demod_threads = (THREAD*)XCALLOC(demod_thread_count, sizeof(THREAD));
  1125. int output_thread_count = 1;
  1126. if (multiple_output_threads) {
  1127. output_thread_count = demod_thread_count;
  1128. if (mixer_count > 0) {
  1129. output_thread_count++;
  1130. }
  1131. }
  1132. output_params_t* output_params = (output_params_t*)XCALLOC(output_thread_count, sizeof(output_params_t));
  1133. THREAD* output_threads = (THREAD*)XCALLOC(output_thread_count, sizeof(THREAD));
  1134. // Setup the output and demod threads
  1135. if (multiple_output_threads == false) {
  1136. init_output(&output_params[0], 0, device_count, 0, mixer_count);
  1137. if (multiple_demod_threads == false) {
  1138. init_demod(&demod_params[0], output_params[0].mp3_signal, 0, device_count);
  1139. } else {
  1140. for (int i = 0; i < demod_thread_count; i++) {
  1141. init_demod(&demod_params[i], output_params[0].mp3_signal, i, i + 1);
  1142. }
  1143. }
  1144. } else {
  1145. if (multiple_demod_threads == false) {
  1146. init_output(&output_params[0], 0, device_count, 0, 0);
  1147. init_demod(&demod_params[0], output_params[0].mp3_signal, 0, device_count);
  1148. } else {
  1149. for (int i = 0; i < device_count; i++) {
  1150. init_output(&output_params[i], i, i + 1, 0, 0);
  1151. init_demod(&demod_params[i], output_params[i].mp3_signal, i, i + 1);
  1152. }
  1153. }
  1154. if (mixer_count > 0) {
  1155. init_output(&output_params[output_thread_count - 1], 0, 0, 0, mixer_count);
  1156. }
  1157. }
  1158. // Startup the output threads
  1159. for (int i = 0; i < output_thread_count; i++) {
  1160. pthread_create(&output_threads[i], NULL, &output_thread, &output_params[i]);
  1161. }
  1162. // Startup the mixer thread (if there is one) using the signal for the last output thread
  1163. THREAD mixer;
  1164. if (mixer_count > 0) {
  1165. pthread_create(&mixer, NULL, &mixer_thread, output_params[output_thread_count - 1].mp3_signal);
  1166. }
  1167. #ifdef WITH_PULSEAUDIO
  1168. pulse_start();
  1169. #endif /* WITH_PULSEAUDIO */
  1170. sincosf_lut_init();
  1171. // Startup the demod threads
  1172. for (int i = 0; i < demod_thread_count; i++) {
  1173. pthread_create(&demod_threads[i], NULL, &demodulate, &demod_params[i]);
  1174. }
  1175. // Wait for demod threads to exit
  1176. for (int i = 0; i < demod_thread_count; i++) {
  1177. pthread_join(demod_threads[i], NULL);
  1178. }
  1179. log(LOG_INFO, "Cleaning up\n");
  1180. for (int i = 0; i < device_count; i++) {
  1181. if (devices[i].mode == R_SCAN)
  1182. pthread_join(devices[i].controller_thread, NULL);
  1183. if (input_stop(devices[i].input) != 0 || devices[i].input->state != INPUT_STOPPED) {
  1184. if (errno != 0) {
  1185. log(LOG_ERR, "Failed do stop device #%d: %s\n", i, strerror(errno));
  1186. } else {
  1187. log(LOG_ERR, "Failed do stop device #%d\n", i);
  1188. }
  1189. }
  1190. }
  1191. log(LOG_INFO, "Input threads closed\n");
  1192. for (int i = 0; i < device_count; i++) {
  1193. device_t* dev = devices + i;
  1194. disable_device_outputs(dev);
  1195. }
  1196. if (mixer_count > 0) {
  1197. log(LOG_INFO, "Closing mixer thread\n");
  1198. pthread_join(mixer, NULL);
  1199. }
  1200. log(LOG_INFO, "Closing output thread(s)\n");
  1201. for (int i = 0; i < output_thread_count; i++) {
  1202. output_params[i].mp3_signal->send();
  1203. pthread_join(output_threads[i], NULL);
  1204. }
  1205. for (int i = 0; i < device_count; i++) {
  1206. device_t* dev = devices + i;
  1207. for (int j = 0; j < dev->channel_count; j++) {
  1208. channel_t* channel = dev->channels + j;
  1209. if (channel->need_mp3 && channel->lame) {
  1210. lame_close(channel->lame);
  1211. }
  1212. }
  1213. }
  1214. close_debug();
  1215. #ifdef WITH_PROFILING
  1216. ProfilerStop();
  1217. #endif /* WITH_PROFILING */
  1218. return 0;
  1219. }