From 90206eac924aa345d5f07944057bbb6401369a98 Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Tue, 16 Apr 2024 22:43:22 -0400 Subject: [PATCH] Patch: Add the AFD "April Fools Day" Ghost Box Gag Update as a patch to bring back around Halloween; --- patch/extra/ghost_box_wip3_awd.patch | 330 +++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 patch/extra/ghost_box_wip3_awd.patch diff --git a/patch/extra/ghost_box_wip3_awd.patch b/patch/extra/ghost_box_wip3_awd.patch new file mode 100644 index 0000000..b64d7cc --- /dev/null +++ b/patch/extra/ghost_box_wip3_awd.patch @@ -0,0 +1,330 @@ +diff --git a/include/dsd.h b/include/dsd.h +index 4a75702..3cf085e 100644 +--- a/include/dsd.h ++++ b/include/dsd.h +@@ -317,6 +317,7 @@ typedef struct + long int rtl_rms; + int monitor_input_audio; + int analog_only; ++ int ghosts_only; + int pulse_raw_rate_in; + int pulse_raw_rate_out; + int pulse_digi_rate_in; +@@ -1342,6 +1343,8 @@ void rtl_udp_tune(dsd_opts * opts, dsd_state * state, long int frequency); + long int GetCurrentFreq(int sockfd); + bool SetFreq(int sockfd, long int freq); + bool SetModulation(int sockfd, int bandwidth); ++bool SetModulationWFM(int sockfd, int bandwidth); ++void death (dsd_opts * opts, dsd_state * state); + //commands below unique to GQRX only, not usable on SDR++ + bool GetSignalLevel(int sockfd, double *dBFS); + bool GetSquelchLevel(int sockfd, double *dBFS); +diff --git a/src/3.c b/src/3.c +index e104993..b9033bd 100644 +--- a/src/3.c ++++ b/src/3.c +@@ -591,4 +591,176 @@ long int raw_rms(int16_t *samples, int len, int step) //use samplespersymbol as + rms = (long int)sqrt((p-err) / len); + if (rms < 0) rms = 150; + return rms; +-} +\ No newline at end of file ++} ++ ++ ++//Ghosts ++void death (dsd_opts * opts, dsd_state * state) ++{ ++ int i, x, result = 0; ++ short ghosts[960]; ++ short spooks[960]; ++ short demons[960]; ++ short sample = 0; ++ ++ memset (ghosts, 0, 960*sizeof(short)); ++ memset (spooks, 0, 960*sizeof(short)); ++ memset (demons, 0, 960*sizeof(short)); ++ ++ while (!exitflag) //while the software is running ++ { ++ //death on speaks at 48k/1 short output ++ if (opts->audio_in_type == 0) ++ { ++ for (i = 0; i < 960; i++) ++ { ++ pa_simple_read(opts->pulse_digi_dev_in, &sample, 2, NULL ); ++ ghosts[i] = sample; ++ } ++ ++ for (i = 0; i < 960; i++) ++ { ++ pa_simple_read(opts->pulse_digi_dev_in, &sample, 2, NULL ); ++ spooks[i] = sample; ++ } ++ ++ for (i = 0; i < 960; i++) ++ { ++ pa_simple_read(opts->pulse_digi_dev_in, &sample, 2, NULL ); ++ demons[i] = sample; ++ } ++ } ++ ++ if (opts->audio_in_type == 8) ++ { ++ for (i = 0; i < 960; i++) ++ { ++ result = sf_read_short(opts->tcp_file_in, &sample, 1); ++ if (result == 0) ++ { ++ sf_close(opts->tcp_file_in); ++ fprintf (stderr, "Connection to the Underworld Severed.\n"); ++ fprintf (stderr, "Closing Death Speech Decoder.\n"); ++ cleanupAndExit(opts, state); ++ } ++ ghosts[i] = sample; ++ } ++ ++ for (i = 0; i < 960; i++) ++ { ++ result = sf_read_short(opts->tcp_file_in, &sample, 1); ++ if (result == 0) ++ { ++ sf_close(opts->tcp_file_in); ++ fprintf (stderr, "Connection to the Underworld Severed.\n"); ++ fprintf (stderr, "Closing Death Speech Decoder.\n"); ++ cleanupAndExit(opts, state); ++ } ++ spooks[i] = sample; ++ } ++ ++ for (i = 0; i < 960; i++) ++ { ++ result = sf_read_short(opts->tcp_file_in, &sample, 1); ++ if (result == 0) ++ { ++ sf_close(opts->tcp_file_in); ++ fprintf (stderr, "Connection to the Underworld Severed.\n"); ++ fprintf (stderr, "Closing Death Speech Decoder.\n"); ++ cleanupAndExit(opts, state); ++ } ++ demons[i] = sample; ++ } ++ } ++ ++ //RTL Input ++ #ifdef USE_RTLSDR ++ if (opts->audio_in_type == 3) ++ { ++ for (i = 0; i < 960; i++) ++ { ++ get_rtlsdr_sample(&sample, opts, state); ++ ghosts[i] = sample; ++ } ++ ++ for (i = 0; i < 960; i++) ++ { ++ get_rtlsdr_sample(&sample, opts, state); ++ spooks[i] = sample; ++ } ++ ++ for (i = 0; i < 960; i++) ++ { ++ get_rtlsdr_sample(&sample, opts, state); ++ demons[i] = sample; ++ } ++ } ++ #endif ++ ++ //The Dead Don't Like OSS input yet ++ ++ //Listen to the Howls of the Deceased ++ if (opts->audio_out_type == 0 && opts->slot1_on == 1) ++ { ++ pa_simple_write(opts->pulse_raw_dev_out, ghosts, 960*2, NULL); ++ pa_simple_write(opts->pulse_raw_dev_out, spooks, 960*2, NULL); ++ pa_simple_write(opts->pulse_raw_dev_out, demons, 960*2, NULL); ++ } ++ ++ if (opts->audio_out_type == 8) //UDP Audio ++ { ++ udp_socket_blasterA (opts, state, 960*2, ghosts); ++ udp_socket_blasterA (opts, state, 960*2, spooks); ++ udp_socket_blasterA (opts, state, 960*2, demons); ++ } ++ ++ //added a condition check so that if OSS output and 8K, switches to 48K when opening OSS ++ if (opts->audio_out_type == 5 && opts->floating_point == 0 && opts->slot1_on == 1) ++ { ++ write (opts->audio_out_fd, ghosts, 960*2); ++ write (opts->audio_out_fd, spooks, 960*2); ++ write (opts->audio_out_fd, demons, 960*2); ++ } ++ ++ //STDOUT -- I don't see the harm of adding this here, will be fine for analog only or digital only (non-mixed analog and digital) ++ if (opts->audio_out_type == 1 && opts->floating_point == 0 && opts->slot1_on == 1) ++ { ++ write (opts->audio_out_fd, ghosts, 960*2); ++ write (opts->audio_out_fd, spooks, 960*2); ++ write (opts->audio_out_fd, demons, 960*2); ++ } ++ ++ //Undulate the Crystal Ball ++ if (x >= opts->trunk_hangtime) ++ { ++ long int spook_channel = state->trunk_lcn_freq[0]; ++ ++ //rigctl ++ if (opts->use_rigctl == 1) ++ { ++ if (opts->setmod_bw != 0 ) SetModulationWFM(opts->rigctl_sockfd, opts->setmod_bw); ++ SetFreq(opts->rigctl_sockfd, spook_channel); ++ } ++ ++ //rtl ++ if (opts->audio_in_type == 3) ++ { ++ #ifdef USE_RTLSDR ++ rtl_dev_tune(opts, spook_channel); ++ #endif ++ } ++ ++ // ++ state->trunk_lcn_freq[0] += 200000; ++ ++ if (state->trunk_lcn_freq[0] > 106100000) ++ state->trunk_lcn_freq[0] = 87900000; ++ ++ x = 0; ++ ++ } ++ ++ x++; ++ ++ } //end while loop ++} //end ghosts +\ No newline at end of file +diff --git a/src/dsd_main.c b/src/dsd_main.c +index ca878e9..f14995d 100644 +--- a/src/dsd_main.c ++++ b/src/dsd_main.c +@@ -696,6 +696,7 @@ initOpts (dsd_opts * opts) + + opts->monitor_input_audio = 0; //enable with -8 + opts->analog_only = 0; //only turned on with -fA ++ opts->ghosts_only = 0; //ghostbox mode with -fG + + opts->inverted_p2 = 0; + opts->p2counter = 0; +@@ -1358,6 +1359,7 @@ usage () + printf ("Decoder options:\n"); + printf (" -fa Auto Detection\n"); + printf (" -fA Passive Analog Audio Monitor\n"); ++ printf (" -fG Ghosts, Demons, Specters, Ghouls, and Skeletons (Ghost Box)\n"); + printf (" -ft TDMA Trunking P25p1 Control and Voice, P25p2 Trunked Channels, and DMR\n"); + printf (" -fs DMR TDMA BS and MS Simplex\n"); + printf (" -f1 Decode only P25 Phase 1\n"); +@@ -2172,6 +2174,35 @@ main (int argc, char **argv) + sprintf (opts.output_name, "Analog Monitor"); + fprintf (stderr,"Only Monitoring Passive Analog Signal\n"); + } ++ else if (optarg[0] == 'G') //listen to spooky scary skeletons ++ { ++ opts.frame_dstar = 0; ++ opts.frame_x2tdma = 0; ++ opts.frame_p25p1 = 0; ++ opts.frame_p25p2 = 0; ++ opts.frame_nxdn48 = 0; ++ opts.frame_nxdn96 = 0; ++ opts.frame_dmr = 0; ++ opts.frame_dpmr = 0; ++ opts.frame_provoice = 0; ++ opts.frame_ysf = 0; ++ opts.frame_m17 = 0; ++ opts.pulse_digi_rate_out = 8000; ++ opts.pulse_digi_out_channels = 1; ++ opts.dmr_stereo = 0; ++ state.dmr_stereo = 0; ++ opts.dmr_mono = 0; ++ state.rf_mod = 0; ++ opts.monitor_input_audio = 1; ++ opts.ghosts_only = 1; ++ state.trunk_lcn_freq[0] = 87900000; //everybody knows ghosts live on the Broadcast FM band ++ opts.setmod_bw = 150000; //Ghosts annunciate clearly with about 150,000 PB ++ opts.trunk_hangtime = 0; ++ opts.rtlsdr_center_freq = 850000000; ++ opts.rtl_bandwidth = 48; ++ sprintf (opts.output_name, "Ghost Box"); ++ fprintf (stderr,"Sounds of the Dead.\n"); ++ } + else if (optarg[0] == 'd') + { + opts.frame_dstar = 1; +@@ -3462,6 +3493,22 @@ main (int argc, char **argv) + processM17IPF(&opts, &state); + } + ++ else if (opts.ghosts_only == 1) ++ { ++ #ifdef USE_RTLSDR ++ if(opts.audio_in_type == 3) ++ open_rtlsdr_stream(&opts); ++ #endif ++ ++ if (opts.audio_in_type == 0) ++ openPulseInput(&opts); ++ ++ if (opts.audio_out_type == 0) ++ openPulseOutput(&opts); ++ ++ death(&opts, &state); ++ } ++ + else + { + +diff --git a/src/dsd_rigctl.c b/src/dsd_rigctl.c +index 820ac7e..f12bacc 100644 +--- a/src/dsd_rigctl.c ++++ b/src/dsd_rigctl.c +@@ -163,6 +163,28 @@ bool SetModulation(int sockfd, int bandwidth) + return true; + } + ++bool SetModulationWFM(int sockfd, int bandwidth) ++{ ++ char buf[BUFSIZE]; ++ //the bandwidth is now a user/system based configurable variable ++ sprintf (buf, "M WFM %d\n", bandwidth); //SDR++ has changed the token from FM to NFM, even if Ryzerth fixes it later, users may still have an older version ++ Send(sockfd, buf); ++ Recv(sockfd, buf); ++ ++ //if it fails the first time, send the other token instead ++ if (strcmp(buf, "RPRT 1\n") == 0 ) //sdr++ has a linebreak here, is that in all versions of the protocol? ++ { ++ sprintf (buf, "M WFM %d\n", bandwidth); //anything not SDR++ ++ Send(sockfd, buf); ++ Recv(sockfd, buf); ++ } ++ ++ if (strcmp(buf, "RPRT 1\n") == 0 ) ++ return false; ++ ++ return true; ++} ++ + bool GetSignalLevel(int sockfd, double *dBFS) + { + char buf[BUFSIZE]; +diff --git a/src/rtl_sdr_fm.cpp b/src/rtl_sdr_fm.cpp +index ad04667..dd6566c 100644 +--- a/src/rtl_sdr_fm.cpp ++++ b/src/rtl_sdr_fm.cpp +@@ -1034,7 +1034,7 @@ void open_rtlsdr_stream(dsd_opts *opts) + //init with low pass if decoding P25 or EDACS/Provoice + if (opts->frame_p25p1 == 1 || opts->frame_p25p2 == 1 || opts->frame_provoice == 1) + demod_init_ro2(&demod); +- else if (opts->analog_only == 1 || opts->m17encoder == 1) ++ else if (opts->analog_only == 1 || opts->m17encoder == 1 || opts->ghosts_only == 1) + demod_init_analog(&demod); + else demod_init(&demod); + output_init(&output);