From 7428a87d8093ec46cf43d5549a1994a5a2f67a7a Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Tue, 19 Aug 2025 02:35:17 -0400 Subject: [PATCH] WAV: Fix Issues with Per Call; Fix Per Call Issue introduced with commit re-enabling single static wav file where single channel audio decode types would not write to per call temp wav files and be deleted after event history cycled them; Fix Issue with YSF where double writes would occur in .wav files; Fix Issue with M17 where incorrect rate audio would write to static .wav file by converting to stereo output; Seperate Per Call and Create Method to Allow EDACS Analog Calls to be written to static wav file by downsampling and stereo interleaving audio to proper spec; Issues were introduced in commit # c7b25c60af1bb1bc74c77ec7f4ced3b3900bf1fe --- src/dsd_mbe.c | 23 +++++++++-------------- src/edacs-fme.c | 28 +++++++++++++++++++++++++++- src/m17.c | 47 +++++++++++++++++++++++++++++++++++++++++++---- src/ysf.c | 7 ++++--- 4 files changed, 83 insertions(+), 22 deletions(-) diff --git a/src/dsd_mbe.c b/src/dsd_mbe.c index d303a30..58e9c2c 100644 --- a/src/dsd_mbe.c +++ b/src/dsd_mbe.c @@ -1423,20 +1423,15 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a memcpy (state->f_l, state->audio_out_temp_buf, sizeof(state->f_l)); //P25p1 FDMA 8k/1 channel -f1 switch } - //static wav file saving, if using old method (fallback if issues arise, but disable all in dsd_audio2.c) - // if (opts->static_wav_file == 1 && opts->wav_out_f != NULL) - // { - // if (state->currentslot == 0) - // { - // if (state->dmr_encL == 0 || opts->dmr_mute_encL == 0) - // writeSynthesizedVoice (opts, state); - // } - // else if (state->currentslot == 1) - // { - // if (state->dmr_encR == 0 || opts->dmr_mute_encR == 0) - // writeSynthesizedVoiceR (opts, state); - // } - // } + //still need this for any switch that opens a 1 channel output config + if (opts->static_wav_file == 0) + { + //if using anything but DMR Stereo, borrowing state->dmr_encL to signal enc or clear for other types + if (opts->wav_out_f != NULL && opts->dmr_stereo == 0 && (opts->unmute_encrypted_p25 == 1 || state->dmr_encL == 0)) + { + writeSynthesizedVoice (opts, state); + } + } //per call wav file writing for slot 1 if (opts->dmr_stereo_wav == 1 && opts->dmr_stereo == 1 && state->currentslot == 0) diff --git a/src/edacs-fme.c b/src/edacs-fme.c index 73cd8c2..db18c0f 100644 --- a/src/edacs-fme.c +++ b/src/edacs-fme.c @@ -461,12 +461,38 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn ncursesPrinter(opts, state); //write to wav file if opened - if (opts->wav_out_f != NULL) + if (opts->wav_out_f != NULL && opts->dmr_stereo_wav == 1) //Per Call { sf_write_short(opts->wav_out_f, analog1, 960); sf_write_short(opts->wav_out_f, analog2, 960); sf_write_short(opts->wav_out_f, analog3, 960); } + else if (opts->wav_out_f != NULL && opts->static_wav_file == 1) //Static Wav File + { + //downsample and stereo out (960 / 6 = 160; 160*2 = 320;) + short ss[320]; + memset(ss, 0, sizeof(ss)); + for (i = 0; i < 160; i++) + { + ss[(i*2)+0] = analog1[i*6]; //grab every 6th sample to downsample + ss[(i*2)+1] = analog1[i*6]; //grab every 6th sample to downsample + } + sf_write_short(opts->wav_out_f, ss, 320); + memset(ss, 0, sizeof(ss)); + for (i = 0; i < 160; i++) + { + ss[(i*2)+0] = analog2[i*6]; //grab every 6th sample to downsample + ss[(i*2)+1] = analog2[i*6]; //grab every 6th sample to downsample + } + sf_write_short(opts->wav_out_f, ss, 320); + memset(ss, 0, sizeof(ss)); + for (i = 0; i < 160; i++) + { + ss[(i*2)+0] = analog3[i*6]; //grab every 6th sample to downsample + ss[(i*2)+1] = analog3[i*6]; //grab every 6th sample to downsample + } + sf_write_short(opts->wav_out_f, ss, 320); + } //debug // fprintf (stderr, " SR: %016llX", sr); diff --git a/src/m17.c b/src/m17.c index f2b1ca5..702c5ea 100644 --- a/src/m17.c +++ b/src/m17.c @@ -425,11 +425,25 @@ void M17processCodec2_1600(dsd_opts * opts, dsd_state * state, uint8_t * payload } - //WIP: Wav file saving -- still need a way to open/close/label wav files similar to call history - if(opts->wav_out_f != NULL && state->m17_enc == 0) //WAV + //Wav file saving + if(opts->wav_out_f != NULL && state->m17_enc == 0 && opts->dmr_stereo_wav == 1) //Per Call { sf_write_short(opts->wav_out_f, samp1, nsam); } + else if (opts->wav_out_f != NULL && state->m17_enc == 0 && opts->static_wav_file == 1) //Static Wav File + { + //convert to stereo for new static wav file setup + short ss[nsam*2]; + memset (ss, 0, sizeof(ss)); + + for (i = 0; i < nsam; i++) + { + ss[(i*2)+0] = samp1[i]; + ss[(i*2)+1] = samp1[i]; + } + + sf_write_short(opts->wav_out_f, ss, nsam*2); + } //TODO: Codec2 Raw file saving // if(mbe_out_dir) @@ -559,12 +573,37 @@ void M17processCodec2_3200(dsd_opts * opts, dsd_state * state, uint8_t * payload } - //WIP: Wav file saving -- still need a way to open/close/label wav files similar to call history - if(opts->wav_out_f != NULL && state->m17_enc == 0) //WAV + //Wav file saving + if(opts->wav_out_f != NULL && state->m17_enc == 0 && opts->dmr_stereo_wav == 1) //WAV { sf_write_short(opts->wav_out_f, samp1, nsam); sf_write_short(opts->wav_out_f, samp2, nsam); } + else if (opts->wav_out_f != NULL && state->m17_enc == 0 && opts->static_wav_file == 1) //Static Wav File + { + //convert to stereo for new static wav file setup + short ss[nsam*2]; + memset (ss, 0, sizeof(ss)); + + for (i = 0; i < nsam; i++) + { + ss[(i*2)+0] = samp1[i]; + ss[(i*2)+1] = samp1[i]; + } + + sf_write_short(opts->wav_out_f, ss, nsam*2); + + memset (ss, 0, sizeof(ss)); + + for (i = 0; i < nsam; i++) + { + ss[(i*2)+0] = samp2[i]; + ss[(i*2)+1] = samp2[i]; + } + + sf_write_short(opts->wav_out_f, ss, nsam*2); + + } //TODO: Codec2 Raw file saving // if(mbe_out_dir) diff --git a/src/ysf.c b/src/ysf.c index a6f3c0b..5cd8624 100644 --- a/src/ysf.c +++ b/src/ysf.c @@ -732,7 +732,7 @@ void ysf_ehr (dsd_opts * opts, dsd_state * state, uint8_t dbuf[180], int start, { // processAudio(opts, state); //needed here? -- nothign to test it with - if (opts->wav_out_f != NULL) + if (opts->wav_out_f != NULL && opts->dmr_stereo_wav == 1) writeSynthesizedVoice (opts, state); if (opts->pulse_digi_out_channels == 1) @@ -1021,8 +1021,9 @@ void processYSF(dsd_opts * opts, dsd_state * state) { processAudio(opts, state); - if (opts->wav_out_f != NULL) + if (opts->wav_out_f != NULL && opts->dmr_stereo_wav == 1) writeSynthesizedVoice (opts, state); + if (opts->pulse_digi_out_channels == 1) playSynthesizedVoiceMS(opts, state); @@ -1140,7 +1141,7 @@ void processYSF(dsd_opts * opts, dsd_state * state) { // processAudio(opts, state); //needed here? -- seems to be running from within mbelib - if (opts->wav_out_f != NULL) + if (opts->wav_out_f != NULL && opts->dmr_stereo_wav == 1) writeSynthesizedVoice (opts, state); if (opts->pulse_digi_out_channels == 1)