diff --git a/CMakeLists.txt b/CMakeLists.txt index fd2c0d0..cdf3e4a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,9 +11,11 @@ find_package(MBE REQUIRED) find_package(ITPP REQUIRED) find_package(LibPortAudio) find_package(RTLSDR) +#more fucking around +find_package(Curses REQUIRED) -include_directories(SYSTEM ${LIBSNDFILE_INCLUDE_DIR} ${MBE_INCLUDE_DIR} ${ITPP_INCLUDE_DIR}) -set(LIBS ${MBE_LIBRARY} ${LIBSNDFILE_LIBRARY} ${ITPP_LIBRARY}) +include_directories(SYSTEM ${LIBSNDFILE_INCLUDE_DIR} ${MBE_INCLUDE_DIR} ${ITPP_INCLUDE_DIR} ${CURSES_INCLUDE_DIR}) +set(LIBS ${MBE_LIBRARY} ${LIBSNDFILE_LIBRARY} ${ITPP_LIBRARY} ${CURSES_LIBRARY}) if(PORTAUDIO_FOUND) include_directories(SYSTEM ${PORTAUDIO_INCLUDE_DIRS}) diff --git a/cmake/FindCURSES.cmake b/cmake/FindCURSES.cmake new file mode 100644 index 0000000..29818ba --- /dev/null +++ b/cmake/FindCURSES.cmake @@ -0,0 +1,16 @@ +# - Try to find NCURSES +# Once done this will define +# +# ITPP_FOUND - System has ITPP +# ITPP_INCLUDE_DIR - The ITPP include directory +# ITPP_LIBRARY - The library needed to use ITPP +# +set(CURSES_LIBRARY "/opt/lib/libncurses.so") +set(CURSES_INCLUDE_PATH "/opt/include") +find_path(CURSES_INCLUDE_DIR /usr/ncurses.h) + +set(CURSES_NAMES ${CURSES_NAMES} curses.h curses curses5w curses6w curses6 curses5 libncursesw) +FIND_LIBRARY(CURSES_LIBRARY NAMES ${CURSES_NAMES}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(CURSES DEFAULT_MSG NCURSES_LIBRARY CURSES_INCLUDE_DIR) diff --git a/include/dsd.h b/include/dsd.h index 1171d75..16583a7 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -66,6 +66,7 @@ * global variables */ static volatile int exitflag; +//volatile int exitflag; //didn't work, couldn't build, multiple definitions of exitflag typedef struct { @@ -134,6 +135,8 @@ typedef struct int delay; int use_cosine_filter; int unmute_encrypted_p25; + int rtl_dev_index; + int rtl_gain_value; } dsd_opts; typedef struct diff --git a/src/dsd_audio.c b/src/dsd_audio.c index e706deb..6c7ab9c 100644 --- a/src/dsd_audio.c +++ b/src/dsd_audio.c @@ -17,7 +17,6 @@ #include "dsd.h" - void processAudio (dsd_opts * opts, dsd_state * state) { @@ -164,7 +163,7 @@ writeSynthesizedVoice (dsd_opts * opts, dsd_state * state) // for(n=0; n<160; n++) // printf("%d ", ((short*)(state->audio_out_temp_buf))[n]); // printf("\n"); - + aout_buf_p = aout_buf; state->audio_out_temp_buf_p = state->audio_out_temp_buf; @@ -214,6 +213,84 @@ writeSynthesizedVoice (dsd_opts * opts, dsd_state * state) */ } +//Test playing raw audio HERE +//get_rtlsdr_sample(&sample); +void +playRawAudio (dsd_opts * opts, dsd_state * state) +{ + ssize_t result; + + //if (state->audio_out_idx > opts->delay) + if (opts->audio_in_type == 3) //if set to rtl_fm, maybe it shouldn't matter but for now, using this + { + // output synthesized speech to sound card + if(opts->audio_out_type == 2) + { +#ifdef USE_PORTAUDIO + PaError err = paNoError; + do + { + long available = Pa_GetStreamWriteAvailable( opts->audio_out_pa_stream ); + if(available < 0) + err = available; + //printf("Frames available: %d\n", available); + if( err != paNoError ) + break; + if(available > SAMPLE_RATE_OUT * PA_LATENCY_OUT) + { + //It looks like this might not be needed for very small latencies. However, it's definitely needed for a bit larger ones. + //When PA_LATENCY_OUT == 0.500 I get output buffer underruns if I don't use this. With PA_LATENCY_OUT <= 0.100 I don't see those happen. + //But with PA_LATENCY_OUT < 0.100 I run the risk of choppy audio and stream errors. + printf("\nSyncing voice output stream\n"); + err = Pa_StopStream( opts->audio_out_pa_stream ); + if( err != paNoError ) + break; + } + + err = Pa_IsStreamActive( opts->audio_out_pa_stream ); + if(err == 0) + { + printf("Start voice output stream\n"); + err = Pa_StartStream( opts->audio_out_pa_stream ); + } + else if(err == 1) + { + err = paNoError; + } + if( err != paNoError ) + break; + + //printf("write stream %d\n", state->audio_out_idx); + err = Pa_WriteStream( opts->audio_out_pa_stream, (state->audio_out_buf_p - state->audio_out_idx), state->audio_out_idx ); + if( err != paNoError ) + break; + } while(0); + + if( err != paNoError ) + { + fprintf( stderr, "An error occured while using the portaudio output stream\n" ); + fprintf( stderr, "Error number: %d\n", err ); + fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + } + +#endif + } + else + result = write (opts->audio_out_fd, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2)); + state->audio_out_idx = 0; + } + + if (state->audio_out_idx2 >= 800000) + { + state->audio_out_float_buf_p = state->audio_out_float_buf + 100; + state->audio_out_buf_p = state->audio_out_buf + 100; + memset (state->audio_out_float_buf, 0, 100 * sizeof (float)); + memset (state->audio_out_buf, 0, 100 * sizeof (short)); + state->audio_out_idx2 = 0; + } +} + +//end test raw audio void playSynthesizedVoice (dsd_opts * opts, dsd_state * state) @@ -309,7 +386,7 @@ int getPADevice(char* dev, int input, PaStream** stream) printf( "ERROR: Requested device %d is larger than number of devices.\n", devnum ); return(1); } - + const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo( devnum ); /* print device name */ @@ -500,7 +577,7 @@ openAudioInDevice (dsd_opts * opts) exit(1); #endif } - else if(strncmp(opts->audio_in_dev, "rtl:", 3) == 0) + else if(strncmp(opts->audio_in_dev, "rtl", 3) == 0) { opts->audio_in_type = 3; } @@ -533,9 +610,9 @@ openAudioInDevice (dsd_opts * opts) #ifdef SOLARIS sample_info_t aset, aget; int rgain; - + rgain = 64; - + if (opts->split == 1) { opts->audio_in_fd = open (opts->audio_in_dev, O_RDONLY); @@ -549,10 +626,10 @@ openAudioInDevice (dsd_opts * opts) printf ("Error, couldn't open %s\n", opts->audio_in_dev); exit(1); } - + // get current ioctl (opts->audio_in_fd, AUDIO_GETINFO, &aset); - + aset.record.sample_rate = SAMPLE_RATE_IN; aset.play.sample_rate = SAMPLE_RATE_IN; aset.record.channels = 1; @@ -563,7 +640,7 @@ openAudioInDevice (dsd_opts * opts) aset.play.encoding = AUDIO_ENCODING_LINEAR; aset.record.port = AUDIO_LINE_IN; aset.record.gain = rgain; - + if (ioctl (opts->audio_in_fd, AUDIO_SETINFO, &aset) == -1) { printf ("Error setting sample device parameters\n"); @@ -573,7 +650,7 @@ openAudioInDevice (dsd_opts * opts) #if defined(BSD) && !defined(__APPLE__) int fmt; - + if (opts->split == 1) { opts->audio_in_fd = open (opts->audio_in_dev, O_RDONLY); @@ -582,13 +659,13 @@ openAudioInDevice (dsd_opts * opts) { opts->audio_in_fd = open (opts->audio_in_dev, O_RDWR); } - + if (opts->audio_in_fd == -1) { printf ("Error, couldn't open %s\n", opts->audio_in_dev); opts->audio_out = 0; } - + fmt = 0; if (ioctl (opts->audio_in_fd, SNDCTL_DSP_RESET) < 0) { diff --git a/src/dsd_file.c b/src/dsd_file.c index c805885..36f7dee 100644 --- a/src/dsd_file.c +++ b/src/dsd_file.c @@ -211,7 +211,8 @@ closeMbeOutFile (dsd_opts * opts, dsd_state * state) fclose (opts->mbe_out_f); opts->mbe_out_f = NULL; strftime (datestr, 31, "%Y-%m-%d-%H%M%S", &timep); - sprintf (newfilename, "nac%X-%s-tg%i%s", state->nac, datestr, talkgroup, ext); + //sprintf (newfilename, "nac%X-%s-tg%i%s", state->nac, datestr, talkgroup, ext); + sprintf (newfilename, "%s%s", datestr, ext); //this one sprintf (new_path, "%s%s", opts->mbe_out_dir, newfilename); #ifdef _WIN32 sprintf (shell, "move %s %s", opts->mbe_out_path, new_path); diff --git a/src/dsd_frame.c b/src/dsd_frame.c index 539c391..8234ff1 100644 --- a/src/dsd_frame.c +++ b/src/dsd_frame.c @@ -31,7 +31,7 @@ printFrameInfo (dsd_opts * opts, dsd_state * state) level = (int) state->max / 164; if (opts->verbose > 0) { - printf ("inlvl: %2i%% ", level); + //printf ("inlvl: %2i%% ", level); } if (state->nac != 0) { @@ -89,7 +89,7 @@ processFrame (dsd_opts * opts, dsd_state * state) if (opts->verbose > 0) { level = (int) state->max / 164; - printf ("inlvl: %2i%% ", level); + //printf ("inlvl: %2i%% ", level); } } state->nac = 0; @@ -112,7 +112,7 @@ processFrame (dsd_opts * opts, dsd_state * state) if (opts->verbose > 0) { level = (int) state->max / 164; - printf ("inlvl: %2i%% ", level); + //printf ("inlvl: %2i%% ", level); } } state->nac = 0; @@ -134,7 +134,7 @@ processFrame (dsd_opts * opts, dsd_state * state) if (opts->verbose > 0) { level = (int) state->max / 164; - printf ("inlvl: %2i%% ", level); + //printf ("inlvl: %2i%% ", level); } } state->nac = 0; @@ -156,7 +156,7 @@ processFrame (dsd_opts * opts, dsd_state * state) if (opts->verbose > 0) { level = (int) state->max / 164; - printf ("inlvl: %2i%% ", level); + //printf ("inlvl: %2i%% ", level); } } state->nac = 0; @@ -179,7 +179,7 @@ processFrame (dsd_opts * opts, dsd_state * state) if (opts->verbose > 0) { level = (int) state->max / 164; - printf ("inlvl: %2i%% ", level); + //printf ("inlvl: %2i%% ", level); } } if ((state->synctype == 11) || (state->synctype == 12)) @@ -233,7 +233,7 @@ processFrame (dsd_opts * opts, dsd_state * state) if (opts->verbose > 0) { level = (int) state->max / 164; - printf ("inlvl: %2i%% ", level); + //printf ("inlvl: %2i%% ", level); } } if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL)) diff --git a/src/dsd_frame_sync.c b/src/dsd_frame_sync.c index 1993c23..52999d3 100644 --- a/src/dsd_frame_sync.c +++ b/src/dsd_frame_sync.c @@ -16,27 +16,73 @@ */ #include "dsd.h" +#include +#include + +time_t now; +char * getTime(void) //get pretty hh:mm:ss timestamp +{ + time_t t = time(NULL); + + char * curr; + char * stamp = asctime(localtime( & t)); + + curr = strtok(stamp, " "); + curr = strtok(NULL, " "); + curr = strtok(NULL, " "); + curr = strtok(NULL, " "); + + return curr; +} + +char * getDate(void) { + char datename[32]; + char * curr2; + struct tm * to; + time_t t; + t = time(NULL); + to = localtime( & t); + strftime(datename, sizeof(datename), "%Y-%m-%d", to); + curr2 = strtok(datename, " "); + return curr2; +} + void printFrameSync (dsd_opts * opts, dsd_state * state, char *frametype, int offset, char *modulation) { + //char datestr[32]; + //struct tm timep; + erase(); + attron(COLOR_PAIR(4)); + for (short int i = 0; i < 7; i++) { + printw("%s \n", FM_banner2[i]);} + attroff(COLOR_PAIR(4)); if (opts->verbose > 0) { - printf ("Sync: %s ", frametype); + //strftime (datestr, 31, "%Y-%m-%d-%H%M%S", &timep); + //printf ("Sync: %s ", frametype); + //printf ("%s %s Sync: %s ", getDate(), getTime(), frametype); + printf ("%s Sync: %s ", getTime(), frametype); + printw("%s Sync: %s ", getTime(), frametype); } if (opts->verbose > 2) { printf ("o: %4i ", offset); + printw("o: %4i ", offset); } if (opts->verbose > 1) { printf ("mod: %s ", modulation); + printw("mod: %s ", modulation); } if (opts->verbose > 2) { printf ("g: %f ", state->aout_gain); + printw("g: %f ", state->aout_gain); } + refresh(); } int @@ -100,6 +146,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) if ((opts->symboltiming == 1) && (state->carrier == 1)) { printf ("\nSymbol Timing:\n"); + //printw("\nSymbol Timing:\n"); } while (sync == 0) { @@ -489,8 +536,10 @@ getFrameSync (dsd_opts * opts, dsd_state * state) state->min = ((state->min) + lmin) / 2; sprintf (state->ftype, " ProVoice "); if (opts->errorbars == 1) + //if (opts->errorbars == 1 && (time(NULL) - now) > 2 ) { printFrameSync (opts, state, " -ProVoice ", synctest_pos + 1, modulation); + now = time(NULL); } state->lastsynctype = 14; return (14); @@ -503,8 +552,10 @@ getFrameSync (dsd_opts * opts, dsd_state * state) state->min = ((state->min) + lmin) / 2; sprintf (state->ftype, " ProVoice "); if (opts->errorbars == 1) + //if (opts->errorbars == 1 && (time(NULL) - now) > 2 ) { printFrameSync (opts, state, " -ProVoice ", synctest_pos + 1, modulation); + now = time(NULL); } state->lastsynctype = 15; return (15); @@ -819,6 +870,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) if ((opts->errorbars == 1) && (opts->verbose > 1) && (state->carrier == 1)) { printf ("Sync: no sync\n"); + printf("Press CTRL + C to close.\n"); //Kindly remind user to double tap CTRL + C } noCarrier (opts, state); return (-1); diff --git a/src/dsd_main.c b/src/dsd_main.c index 075175e..17af283 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -28,6 +28,17 @@ #include "p25p1_heuristics.h" #include "pa_devs.h" +#include +#include +char * FM_banner[9] = { + " CTRL + C twice to exit", + "██████╗ ██████╗██████╗    ███████╗███╗ ███╗███████╗", + "██╔══██╗██╔════╝██╔══██╗   ██╔════╝████╗ ████║██╔════╝", + "██║ ██║╚█████╗ ██║ ██║   █████╗ ██╔████╔██║█████╗ ", + "██║ ██║ ╚═══██╗██║ ██║   ██╔══╝ ██║╚██╔╝██║██╔══╝ ", + "██████╔╝██████╔╝██████╔╝   ██║ ██║ ╚═╝ ██║███████╗", + "╚═════╝ ╚═════╝ ╚═════╝    ╚═╝ ╚═╝ ╚═╝╚══════╝", +}; int comp (const void *a, const void *b) @@ -79,6 +90,11 @@ noCarrier (dsd_opts * opts, dsd_state * state) sprintf (state->algid, "________"); sprintf (state->keyid, "________________"); mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced); + //test below + //uint16_t sample; + //get_rtlsdr_sample(&sample); + //Pa_StartStream(sample); + //end test } void @@ -141,6 +157,8 @@ initOpts (dsd_opts * opts) opts->delay = 0; opts->use_cosine_filter = 1; opts->unmute_encrypted_p25 = 0; + opts->rtl_dev_index = 0; //choose which device we want by index number + opts->rtl_gain_value = 0; //set actual gain and not automatic gain } void @@ -266,16 +284,20 @@ usage () printf (" -z Frame rate for datascope\n"); printf ("\n"); printf ("Input/Output options:\n"); - printf (" -i Audio input device (default is /dev/audio, - for piped stdin)\n"); + printf (" -i Audio input device (default is /dev/audio, - for piped stdin, rtl for rtl device)\n"); printf (" -o Audio output device (default is /dev/audio)\n"); printf (" -d Create mbe data files, use this directory\n"); - printf (" -r Read/Play saved mbe data from file(s)\n"); + printf (" -r Read/Play saved mbe data from file(s)\n"); printf (" -g Audio output gain (default = 0 = auto, disable = -1)\n"); printf (" -n Do not send synthesized speech to audio output device\n"); - printf (" -w Output synthesized speech to a .wav file\n"); + printf (" -w Output synthesized speech to a .wav file\n"); printf (" -a Display port audio devices\n"); - printf (" -c RTL-SDR center frequency\n"); + printf ("\n"); + printf ("RTL-SDR options:\n"); + printf (" -c RTL-SDR tune to frequency\n"); printf (" -P RTL-SDR ppm error (default = 0)\n"); + printf (" -D RTL-SDR Device Index Number\n"); + printf (" -G RTL-SDR Device Gain (0-49) (default = 0 Auto Gain)\n"); printf ("\n"); printf ("Scanner control options:\n"); printf (" -B Serial port baud rate (default=115200)\n"); @@ -286,7 +308,7 @@ usage () printf (" -fa Auto-detect frame type (default)\n"); printf (" -f1 Decode only P25 Phase 1\n"); printf (" -fd Decode only D-STAR\n"); - printf (" -fi Decode only NXDN48* (6.25 kHz) / IDAS*\n"); + printf (" -fi Decode only NXDN48* (6.25 kHz) / IDAS*\n"); printf (" -fn Decode only NXDN96 (12.5 kHz)\n"); printf (" -fp Decode only ProVoice*\n"); printf (" -fr Decode only DMR/MOTOTRBO\n"); @@ -323,9 +345,9 @@ liveScanner (dsd_opts * opts, dsd_state * state) PaError err = Pa_StartStream( opts->audio_in_pa_stream ); if( err != paNoError ) { - fprintf( stderr, "An error occured while starting the portaudio input stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + //fprintf( stderr, "An error occured while starting the portaudio input stream\n" ); + //fprintf( stderr, "Error number: %d\n", err ); + //fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); return; } } @@ -385,9 +407,9 @@ cleanupAndExit (dsd_opts * opts, dsd_state * state) err = Pa_CloseStream( opts->audio_in_pa_stream ); if( err != paNoError ) { - fprintf( stderr, "An error occured while closing the portaudio input stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + //fprintf( stderr, "An error occured while closing the portaudio input stream\n" ); + //fprintf( stderr, "Error number: %d\n", err ); + //fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); } } if(opts->audio_out_pa_stream != NULL) @@ -397,24 +419,24 @@ cleanupAndExit (dsd_opts * opts, dsd_state * state) err = Pa_StopStream( opts->audio_out_pa_stream ); if( err != paNoError ) { - fprintf( stderr, "An error occured while closing the portaudio output stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + //fprintf( stderr, "An error occured while closing the portaudio output stream\n" ); + //fprintf( stderr, "Error number: %d\n", err ); + //fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); } err = Pa_CloseStream( opts->audio_out_pa_stream ); if( err != paNoError ) { - fprintf( stderr, "An error occured while closing the portaudio output stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + //fprintf( stderr, "An error occured while closing the portaudio output stream\n" ); + //fprintf( stderr, "Error number: %d\n", err ); + //fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); } } err = Pa_Terminate(); if( err != paNoError ) { - fprintf( stderr, "An error occured while terminating portaudio\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + //fprintf( stderr, "An error occured while terminating portaudio\n" ); + //fprintf( stderr, "Error number: %d\n", err ); + //fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); } } #endif @@ -468,6 +490,32 @@ sigfun (int sig) #endif } +//LEH version of sigfun +/* +void sigfun (int sig) +{ + UNUSED_VARIABLE(sig); //what is this and where is it defined? + exitflag = 1; + signal (SIGINT, SIG_DFL); +} + +//another LEH thing to free allocated memory +void freeAllocatedMemory(dsd_opts * opts, dsd_state * state) +{ + UNUSED_VARIABLE(opts); + + // Free allocated memory // + free(state->prev_mp_enhanced); + free(state->prev_mp); + free(state->cur_mp); + free(state->audio_out_float_buf); + free(state->audio_out_buf); + free(state->dibit_buf); +} + +*/ +//end LEH version of sigfun + double atofs(char *s) { char last; @@ -505,7 +553,12 @@ main (int argc, char **argv) char versionstr[25]; mbe_printVersion (versionstr); - printf ("Digital Speech Decoder 1.7.0-dev (build:%s)\n", GIT_TAG); + + for (short int i = 0; i < 7; i++) { + printf("%s \n", FM_banner[i]); + } + //printf ("Digital Speech Decoder 1.7.0-dev (build:%s)\n", GIT_TAG); + printf ("Digital Speech Decoder: Florida Man Edition\n"); printf ("mbelib version %s\n", versionstr); initOpts (&opts); @@ -514,7 +567,7 @@ main (int argc, char **argv) exitflag = 0; signal (SIGINT, sigfun); - while ((c = getopt (argc, argv, "haep:P:qstv:z:i:o:d:c:g:nw:B:C:R:f:m:u:x:A:S:M:rl")) != -1) + while ((c = getopt (argc, argv, "haep:P:qstv:z:i:o:d:c:g:nw:B:C:R:f:m:u:x:A:S:M:G:D:rl")) != -1) { opterr = 0; switch (c) @@ -575,6 +628,18 @@ main (int argc, char **argv) case 'v': sscanf (optarg, "%d", &opts.verbose); break; + + case 'G': //Set rtl device gain + sscanf (optarg, "%d", &opts.rtl_gain_value); //multiple value by ten to make it consitent with the way rtl_fm really works + //opts->audio_in_type = 3; //set to use RTL this way and maybe ditch the other shitty way + break; + + case 'D': //Set rtl device index number + sscanf (optarg, "%d", &opts.rtl_dev_index); + //opts->audio_in_type = 3; //set to use RTL this way and maybe ditch the other shitty way + break; + + case 'z': sscanf (optarg, "%d", &opts.scoperate); opts.errorbars = 0; @@ -589,6 +654,7 @@ main (int argc, char **argv) case 'i': strncpy(opts.audio_in_dev, optarg, 1023); opts.audio_in_dev[1023] = '\0'; + //printf("audio_in_dev = %s\n", opts.audio_in_dev); break; case 'o': strncpy(opts.audio_out_dev, optarg, 1023); @@ -601,7 +667,7 @@ main (int argc, char **argv) break; case 'c': opts.rtlsdr_center_freq = (uint32_t)atofs(optarg); - printf("Using center freq: %i\n", opts.rtlsdr_center_freq); + printf("Tuning to frequency: %i\n", opts.rtlsdr_center_freq); break; case 'g': sscanf (optarg, "%f", &opts.audio_gain); @@ -866,9 +932,9 @@ main (int argc, char **argv) PaError err = Pa_Initialize(); if( err != paNoError ) { - fprintf( stderr, "An error occured while initializing portaudio\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + //fprintf( stderr, "An error occured while initializing portaudio\n" ); + //fprintf( stderr, "Error number: %d\n", err ); + //fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); exit(err); } } @@ -902,7 +968,25 @@ main (int argc, char **argv) openAudioOutDevice (&opts, SAMPLE_RATE_OUT); } openAudioInDevice (&opts); + setlocale(LC_ALL, ""); + //sleep(3); + //initscr(); //Initialize NCURSES screen window + start_color(); + init_pair(1, COLOR_YELLOW, COLOR_BLACK); //Yellow/Amber for frame sync/control channel, NV style + init_pair(2, COLOR_RED, COLOR_BLACK); //Red for Terminated Calls + init_pair(3, COLOR_GREEN, COLOR_BLACK); //Green for Active Calls + init_pair(4, COLOR_CYAN, COLOR_BLACK); //Cyan for Site Extra and Patches + init_pair(5, COLOR_MAGENTA, COLOR_BLACK); //Magenta for no frame sync/signal + noecho(); + cbreak(); + erase(); + for (short int i = 0; i < 7; i++) { + printw("%s \n", FM_banner[i]); } + attroff(COLOR_PAIR(4)); + refresh(); + printf("Press CTRL + C twice to close.\n"); //Kindly remind user to double tap CTRL + C } + else { opts.split = 0; @@ -916,10 +1000,12 @@ main (int argc, char **argv) { playMbeFiles (&opts, &state, argc, argv); } + else { liveScanner (&opts, &state); } cleanupAndExit (&opts, &state); + endwin(); return (0); } diff --git a/src/dsd_mbe.c b/src/dsd_mbe.c index 3e93a82..35c37c1 100644 --- a/src/dsd_mbe.c +++ b/src/dsd_mbe.c @@ -135,6 +135,7 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a if (opts->errorbars == 1) { printf ("%s", state->err_str); + //printw("%s", state->err_str); } state->debug_audio_errors += state->errs2; diff --git a/src/provoice.c b/src/provoice.c index 2c01329..799cbdd 100644 --- a/src/provoice.c +++ b/src/provoice.c @@ -5,25 +5,28 @@ void processProVoice (dsd_opts * opts, dsd_state * state) { int i, j, dibit; - + //char datestr[32]; char imbe7100_fr1[7][24]; char imbe7100_fr2[7][24]; const int *w, *x; + //struct tm timep; if (opts->errorbars == 1) { - printf ("VOICE e:"); + //strftime (datestr, 31, "%Y-%m-%d-%H%M%S", &timep); + //printf ("%s VOICE e:", datestr); + //printf ("VOICE e:"); } for (i = 0; i < 64; i++) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif } #ifdef PROVOICE_DUMP - printf (" "); + //printf (" "); #endif // lid @@ -31,22 +34,22 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif } #ifdef PROVOICE_DUMP - printf (" "); + //printf (" "); #endif for (i = 0; i < 64; i++) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif } #ifdef PROVOICE_DUMP - printf (" "); + //printf (" "); #endif // imbe frames 1,2 first half @@ -59,14 +62,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr1[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif w -= 6; x -= 6; @@ -74,14 +77,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr2[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif } @@ -89,14 +92,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr1[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif w -= 6; x -= 6; @@ -104,25 +107,25 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr2[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf (" "); + //printf (" "); #endif // spacer bits dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); - printf (" "); + //printf ("%i", dibit); + //printf (" "); #endif // imbe frames 1,2 second half @@ -131,14 +134,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr2[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif for (i = 0; i < 3; i++) @@ -147,14 +150,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr1[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif w -= 6; x -= 6; @@ -162,14 +165,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr2[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif } @@ -177,14 +180,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr1[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif w -= 5; x -= 5; @@ -192,14 +195,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr2[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif for (i = 0; i < 7; i++) @@ -208,14 +211,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr1[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif w -= 6; x -= 6; @@ -223,14 +226,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr2[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif } @@ -238,14 +241,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr1[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif w -= 5; x -= 5; @@ -253,14 +256,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr2[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf (" "); + //printf (" "); #endif processMbeFrame (opts, state, NULL, NULL, imbe7100_fr1); @@ -269,23 +272,23 @@ processProVoice (dsd_opts * opts, dsd_state * state) // spacer bits dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); - printf (" "); + //printf ("%i", dibit); + //printf (" "); #endif for (i = 0; i < 16; i++) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif } #ifdef PROVOICE_DUMP - printf (" "); + //printf (" "); #endif // imbe frames 3,4 first half @@ -297,14 +300,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr1[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif w -= 6; x -= 6; @@ -312,28 +315,28 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr2[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif } for (j = 0; j < 6; j++) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr1[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif w -= 6; x -= 6; @@ -341,25 +344,25 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr2[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf (" "); + //printf (" "); #endif // spacer bits dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); - printf ("_"); + //printf ("%i", dibit); + //printf ("_"); #endif // imbe frames 3,4 second half @@ -367,14 +370,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr2[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif for (i = 0; i < 3; i++) { @@ -382,14 +385,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr1[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif w -= 6; x -= 6; @@ -397,14 +400,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr2[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif } @@ -412,14 +415,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr1[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif w -= 5; x -= 5; @@ -427,14 +430,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr2[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf (" "); + //printf (" "); #endif for (i = 0; i < 7; i++) @@ -443,14 +446,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr1[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif w -= 6; x -= 6; @@ -458,14 +461,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr2[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif } @@ -473,14 +476,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr1[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf ("_"); + //printf ("_"); #endif w -= 5; x -= 5; @@ -488,14 +491,14 @@ processProVoice (dsd_opts * opts, dsd_state * state) { dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif imbe7100_fr2[*w][*x] = dibit; w++; x++; } #ifdef PROVOICE_DUMP - printf (" "); + //printf (" "); #endif processMbeFrame (opts, state, NULL, NULL, imbe7100_fr1); @@ -504,12 +507,12 @@ processProVoice (dsd_opts * opts, dsd_state * state) // spacer bits dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); + //printf ("%i", dibit); #endif dibit = getDibit (opts, state); #ifdef PROVOICE_DUMP - printf ("%i", dibit); - printf (" "); + //printf ("%i", dibit); + //printf (" "); #endif if (opts->errorbars == 1) diff --git a/src/rtl_sdr_fm.cpp b/src/rtl_sdr_fm.cpp index b8b6cb5..a33b218 100644 --- a/src/rtl_sdr_fm.cpp +++ b/src/rtl_sdr_fm.cpp @@ -31,9 +31,9 @@ #include #include "dsd.h" -#define DEFAULT_SAMPLE_RATE 48000 +#define DEFAULT_SAMPLE_RATE 48000 //48000 #define DEFAULT_BUF_LENGTH (1 * 16384) -#define MAXIMUM_OVERSAMPLE 16 +#define MAXIMUM_OVERSAMPLE 16 //16 #define MAXIMUM_BUF_LENGTH (MAXIMUM_OVERSAMPLE * DEFAULT_BUF_LENGTH) #define AUTO_GAIN -100 #define BUFFER_DUMP 4096 @@ -46,7 +46,11 @@ static int ACTUAL_BUF_LENGTH; static int *atan_lut = NULL; static int atan_lut_size = 131072; /* 512 KB */ static int atan_lut_coef = 8; - +//new for UDP +#include +#include +static pthread_t socket_freq; +// struct dongle_state { int exit_flag; @@ -585,6 +589,7 @@ static void *demod_thread_fn(void *arg) int nearest_gain(rtlsdr_dev_t *dev, int target_gain) { + //target_gain = 36; int i, r, err1, err2, count, nearest; int* gains; r = rtlsdr_set_tuner_gain_mode(dev, 1); @@ -617,7 +622,8 @@ int verbose_set_frequency(rtlsdr_dev_t *dev, uint32_t frequency) if (r < 0) { fprintf(stderr, "WARNING: Failed to set center freq.\n"); } else { - fprintf(stderr, "Tuned to %u Hz.\n", frequency); + //fprintf(stderr, "Tuned to %u Hz.\n", frequency); + fprintf(stderr, "Tuned to center frequency %u Hz.\n", frequency); } return r; } @@ -665,6 +671,7 @@ int verbose_offset_tuning(rtlsdr_dev_t *dev) int verbose_auto_gain(rtlsdr_dev_t *dev) { + int r; r = rtlsdr_set_tuner_gain_mode(dev, 0); if (r != 0) { @@ -677,6 +684,7 @@ int verbose_auto_gain(rtlsdr_dev_t *dev) int verbose_gain_set(rtlsdr_dev_t *dev, int gain) { + //gain = 36; int r; r = rtlsdr_set_tuner_gain_mode(dev, 1); if (r < 0) { @@ -694,6 +702,7 @@ int verbose_gain_set(rtlsdr_dev_t *dev, int gain) int verbose_ppm_set(rtlsdr_dev_t *dev, int ppm_error) { + //ppm_error = -2; //fix this opt arg to accept negative float values, i.e. float or double?? int r; if (ppm_error == 0) { return 0;} @@ -715,10 +724,12 @@ int verbose_reset_buffer(rtlsdr_dev_t *dev) return r; } -static void optimal_settings(int freq, int rate) +//static void optimal_settings(struct fm_state *fm, int freq, int hopping) +static void optimal_settings(int freq, int rate) //why did you fuck with optimal settings? { // giant ball of hacks // seems unable to do a single pass, 2:1 + //int r, capture_freq, capture_rate; int capture_freq, capture_rate; struct dongle_state *d = &dongle; struct demod_state *dm = &demod; @@ -771,6 +782,7 @@ static void *controller_thread_fn(void *arg) /* Set the sample rate */ verbose_set_sample_rate(dongle.dev, dongle.rate); fprintf(stderr, "Output at %u Hz.\n", demod.rate_in/demod.post_downsample); + fprintf(stderr, "Press CTRL + C to close.\n"); //Kindly remind user to double tap CTRL + C while (!exitflag) { safe_cond_wait(&s->hop, &s->hop_m); @@ -791,8 +803,9 @@ void dongle_init(struct dongle_state *s) s->gain = AUTO_GAIN; // tenths of a dB s->mute = 0; s->direct_sampling = 0; - s->offset_tuning = 0; + s->offset_tuning = 0; //0 by default, but don't think it listens to proper frequency when 0, offset and tuned seem to be mixed up s->demod_target = &demod; + //s->dev_index = 1; //need to set dev_index from dsd_main as well... } void demod_init(struct demod_state *s) @@ -879,11 +892,148 @@ void sanity_checks(void) } } +//UDP remote all below HERE +static unsigned int chars_to_int(unsigned char* buf) { + + int i; + unsigned int val = 0; + + for(i=1; i<5; i++) { + val = val | ((buf[i]) << ((i-1)*8)); + } + + return val; +} + +static void *socket_thread_fn(void *arg) { + //struct fm_state *fm = arg; + struct demod_state *d = static_cast(arg); + int port = 6020; + int r, n; + int sockfd, newsockfd, portno; + socklen_t clilen; + unsigned char buffer[5]; + struct sockaddr_in serv_addr, cli_addr; + + sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + + if (sockfd < 0) { + perror("ERROR opening socket"); + } + + bzero((char *) &serv_addr, sizeof(serv_addr)); + + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = INADDR_ANY; + serv_addr.sin_port = htons(port); + + if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { + perror("ERROR on binding"); + } + + bzero(buffer,5); + + fprintf (stderr, "Main socket started! :-) Tuning enabled on UDP/%d \n", port); + + int new_freq, demod_type, new_squelch, new_gain, agc_mode; + + while((n = read(sockfd,buffer,5)) != 0) { + if(buffer[0] == 0) { + new_freq = chars_to_int(buffer); + dongle.freq = new_freq; //not sure if still needed, or ever was needed lul + optimal_settings(new_freq, demod.rate_in); + rtlsdr_set_center_freq(dongle.dev, dongle.freq); + //fprintf (stderr, "Tuning to: %d [Hz] (central freq: %d [Hz])\n", new_freq, new_freq + freq_offset); + fprintf (stderr, "Tuning to: %d [Hz] \n", new_freq); + } +/* + if(buffer[0] == 1) { + // change demod type + int type = chars_to_int(buffer); + + switch(type) { + case 0: + fprintf (stderr, "Changing demod type to FM\n"); + fm->mode_demod = &fm_demod; + break; + case 1: + fprintf (stderr, "Changing demod type to AM\n"); + fm->mode_demod = &am_demod; + break; + case 2: + fprintf (stderr, "Changing demod type to USB\n"); + fm->mode_demod = &usb_demod; + fm->custom_atan = 1; + break; + case 3: + fprintf (stderr, "Changing demod type to LSB\n"); + fm->mode_demod = &lsb_demod; + break; + default: + fprintf (stderr, "Unknown demod type %d\n", type); + break; + } + } +*/ + +//SQUELCH HERE + + if (buffer[0] == 2) { + new_squelch = chars_to_int(buffer); + demod.squelch_level = new_squelch; //demod, or d*? or d-> + //full_demod(d); + //new_freq = 850000000; + //dongle.freq = new_freq; + //optimal_settings(new_freq, demod.rate_in); //hacky way to 'squelch', just setting it to a dead freq instead + //rtlsdr_set_center_freq(dongle.dev, dongle.freq); + fprintf (stderr, "Changing squelch to %d \n", new_squelch); + } + +/* + if (buffer[0] == 3) { + new_gain = chars_to_int(buffer); + if (new_gain == AUTO_GAIN) { + r = rtlsdr_set_tuner_gain_mode(dev, 0); + } else { + r = rtlsdr_set_tuner_gain_mode(dev, 1); + new_gain = nearest_gain(new_gain); + r = rtlsdr_set_tuner_gain(dev, new_gain); + } + + if (r != 0) { + fprintf(stderr, "WARNING: Failed to set tuner gain.\n"); + } else if (new_gain == AUTO_GAIN) { + fprintf(stderr, "Tuner gain set to automatic.\n"); + } else { + fprintf(stderr, "Tuner gain set to %0.2f dB.\n", new_gain/10.0); + } + } +*/ +/* + if (buffer[0] == 8) { + agc_mode = chars_to_int(buffer); + if (agc_mode == 0 || agc_mode == 1) { + fprintf(stderr, "Setting AGC to %d\n", agc_mode); + rtlsdr_set_agc_mode(dev, agc_mode); + } else { + fprintf(stderr, "Failed to set AGC to %d\n", agc_mode); + } + } +*/ + } + + close(sockfd); + return 0; +} +//UDP Control all above HERE void rtlsdr_sighandler() { fprintf(stderr, "Signal caught, exiting!\n"); + fprintf(stderr, "Press CTRL + C again to close. Thanks. \n"); //Kindly remind user to double tap CTRL + C rtlsdr_cancel_async(dongle.dev); + //cleanup_rtlsdr_stream(); //thank the wraith for this one...if it works...didn't work + //_Exit(1); } void open_rtlsdr_stream(dsd_opts *opts) @@ -901,10 +1051,18 @@ void open_rtlsdr_stream(dsd_opts *opts) controller.freq_len++; } - if (opts->rtlsdr_ppm_error > 0) { + if (opts->rtlsdr_ppm_error > 0 || opts->rtlsdr_ppm_error < 0) { //this way will adjust PPM based on negative values as well dongle.ppm_error = opts->rtlsdr_ppm_error; } + if (opts->audio_in_type == 3) { + dongle.dev_index = opts->rtl_dev_index; + } + + if (opts->rtl_gain_value > 0) { + dongle.gain = opts->rtl_gain_value * 10; //multiple by ten to make it consitent with the way rtl_fm really works + } + /* quadruple sample_rate to limit to Δθ to ±π/2 */ demod.rate_in *= demod.post_downsample; @@ -915,13 +1073,15 @@ void open_rtlsdr_stream(dsd_opts *opts) if (controller.freq_len > 1) demod.terminate_on_squelch = 0; ACTUAL_BUF_LENGTH = lcm_post[demod.post_downsample] * DEFAULT_BUF_LENGTH; - r = rtlsdr_open(&dongle.dev, (uint32_t)dongle.dev_index); + if (r < 0) { fprintf(stderr, "Failed to open rtlsdr device %d.\n", dongle.dev_index); exit(1); - } + } else { + fprintf(stderr, "Using RTLSDR Device Index: %d. \n", dongle.dev_index); //Kindly tell us which device we are using + } // sigact.sa_handler = sighandler; // sigemptyset(&sigact.sa_mask); @@ -952,6 +1112,7 @@ void open_rtlsdr_stream(dsd_opts *opts) usleep(100000); pthread_create(&demod.thread, NULL, demod_thread_fn, (void*)(&demod)); pthread_create(&dongle.thread, NULL, dongle_thread_fn, (void*)(&dongle)); + pthread_create(&socket_freq, NULL, socket_thread_fn, (void *)(&controller)); } void cleanup_rtlsdr_stream() @@ -971,6 +1132,7 @@ void cleanup_rtlsdr_stream() controller_cleanup(&controller); rtlsdr_close(dongle.dev); + } void get_rtlsdr_sample(int16_t *sample)