Round of Code Cleanup;

This commit is contained in:
lwvmobile
2023-07-28 17:47:33 -04:00
parent 56a5df86a0
commit 3bac7ba99b
8 changed files with 34 additions and 951 deletions

View File

@@ -485,12 +485,8 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
//NOTE: We want this to play regardless of whether the slot is voice or data, to play silence in one slot and voice in the second, or voices in both
if (internalslot == 0 && opts->floating_point == 1 && opts->pulse_digi_rate_out == 8000)
playSynthesizedVoiceFS3 (opts, state); //Float Stereo Mix 3v2
if (internalslot == 0 && opts->floating_point == 1 && opts->pulse_digi_rate_out == 48000)
playSynthesizedVoiceFS3_48k (opts, state); //Float Stereo Mix 3v2
if (internalslot == 0 && opts->floating_point == 0 && opts->pulse_digi_rate_out == 8000)
playSynthesizedVoiceSS3 (opts, state); //Short Stereo Mix 3v2
if (internalslot == 0 && opts->floating_point == 0 && opts->pulse_digi_rate_out == 48000)
playSynthesizedVoiceSS3_48k (opts, state); //Short Stereo Mix 3v2
if (skipcount > 2) //after 2 consecutive data frames, drop back to getFrameSync and process with dmr_data_sync
{
@@ -833,12 +829,8 @@ void dmrBSBootstrap (dsd_opts * opts, dsd_state * state)
//NOTE: Only play on slot 0, if slot 1, then it'll play after the next TDMA frame in the BS loop instead
if (internalslot == 0 && opts->floating_point == 1 && opts->pulse_digi_rate_out == 8000)
playSynthesizedVoiceFS3 (opts, state); //Float Stereo Mix 3v2
if (internalslot == 0 && opts->floating_point == 1 && opts->pulse_digi_rate_out == 48000)
playSynthesizedVoiceFS3_48k (opts, state); //Float Stereo Mix 3v2
if (internalslot == 0 && opts->floating_point == 0 && opts->pulse_digi_rate_out == 8000)
playSynthesizedVoiceSS3 (opts, state); //Short Stereo Mix 3v2
if (internalslot == 0 && opts->floating_point == 0 && opts->pulse_digi_rate_out == 48000)
playSynthesizedVoiceSS3_48k (opts, state); //Short Stereo Mix 3v2
dmrBS (opts, state); //bootstrap into full TDMA frame for BS mode
END:

View File

@@ -11,15 +11,12 @@
#include "dsd.h"
//TODO: Add audio handling for left over types (X2-TDMA, dPMR, Provoice...MBEPlayback?)
//TODO: Test All voice decoders with all combos 'short mono, short stereo, float mono, float stereo)
//TODO: Look at upscaling on M17 codec 2 audio for OSS support and backport to 2.1b
//TODO: Clean comments and unused code in here
//TODO: Change + and - keys to allow switching to '0' on shorts for auto or manual with values
//CHECKLIST(PULSE): DMR BS(OK) DMR MS (OK) P25p1 (OK) P25p2 (OK) YSF (OK) NXDN (OK) M17 (short only!) pV (OK) dPMR (OK) MBEplayback (OK) X2-TDMA (who cares lol)
//TODO: WAV File saving (works fine on shorts, but on float, writing short to wav is not auto-gained, so super quiet, either convert to float wav files, or run processAudio AFTER memcpy of the temp_buf)
//CHECKLIST(PULSE): DMR BS(OK) DMR MS (OK) P25p1 (OK) P25p2 (OK) YSF (OK) NXDN (OK) M17 (short only!) pV (OK) dPMR (OK) MBEplayback (OK) X2-TDMA (who cares lol) D-STAR (WIP)
//TODO: WAV File saving (works fine on shorts, but on float, writing short to wav is not auto-gained,
//so super quiet, either convert to float wav files, or run processAudio AFTER memcpy of the temp_buf)
void agf (dsd_opts * opts, dsd_state * state, float samp[160], int slot)
{
@@ -233,188 +230,6 @@ void playSynthesizedVoiceFS3 (dsd_opts * opts, dsd_state * state)
}
//float stereo mix 3v2 DMR with 8k to 48k upsample
void playSynthesizedVoiceFS3_48k (dsd_opts * opts, dsd_state * state)
{
//NOTE: The old version UpsampleF had a high pitch ring to it
//new version has an odd 'pattering' or 'crackle' sound or clipping?
int i, n;
uint8_t encL, encR;
// int j, k;
// float prev;
float stereo_samp1[320*6]; //48k 2-channel stereo interleave mix
float stereo_samp2[320*6]; //48k 2-channel stereo interleave mix
float stereo_samp3[320*6]; //48k 2-channel stereo interleave mix
float stereo_samp4[320*6]; //48k 2-channel stereo interleave mix
float out[6];
float temp_l[4][160*6]; //temp storage
float temp_r[4][160*6]; //temp storage
float baseline = 0.0f;
memset (stereo_samp1, baseline, sizeof(stereo_samp1));
memset (stereo_samp2, baseline, sizeof(stereo_samp2));
memset (stereo_samp3, baseline, sizeof(stereo_samp3));
memset (stereo_samp4, baseline, sizeof(stereo_samp4));
memset (temp_l, baseline, sizeof(temp_l));
memset (temp_r, baseline, sizeof(temp_r));
memset (out, baseline, sizeof(out));
//dmr enc checkdown for whether or not to fill the stereo sample or not for playback or writing
encL = encR = 0;
encL = (state->dmr_so >> 6) & 0x1;
encR = (state->dmr_soR >> 6) & 0x1;
//checkdown to see if we can lift the 'mute' if a key is available
if (encL)
{
if (state->payload_algid == 0)
{
if (state->K != 0 || state->K1 != 0)
{
encL = 0;
}
}
else if (state->payload_algid == 0x21)
{
if (state->R != 0)
{
encL = 0;
}
}
}
if (encR)
{
if (state->payload_algidR == 0)
{
if (state->K != 0 || state->K1 != 0)
{
encR = 0;
}
}
else if (state->payload_algidR == 0x21)
{
if (state->RR != 0)
{
encR = 0;
}
}
}
//at this point, if both channels are still flagged as enc, then we can skip all playback/writing functions
if (encL && encR)
goto FS348_END;
//TODO: Test Upsampling //void upsampleF (float invalue, float prev, float outbuf[6])
// prev = 0.0f;
// for (j = 0; j < 3; j++)
// {
// for (i = 0; i < 160; i++)
// {
// upsampleF (state->f_l4[j][i] / ((float) 480*10), prev, out);
// // upsampleF (state->f_l4[j][i], prev, out);
// for (k = 0; k < 6; k++) temp_l[j][i*6+k] = out[k];
// }
// }
// prev = 0.0f; //test value
// for (j = 0; j < 3; j++)
// {
// for (i = 0; i < 160; i++)
// {
// upsampleF (state->f_r4[j][i] / ((float) 480*10), prev, out);
// // upsampleF (state->f_r4[j][i], prev, out);
// for (k = 0; k < 6; k++) temp_r[j][i*6+k] = out[k];
// }
// }
n = 160;
fdmdv_8_to_48_float(temp_l[0], state->f_l4[0], n);
fdmdv_8_to_48_float(temp_l[1], state->f_l4[1], n);
fdmdv_8_to_48_float(temp_l[2], state->f_l4[2], n);
fdmdv_8_to_48_float(temp_r[0], state->f_r4[0], n);
fdmdv_8_to_48_float(temp_r[1], state->f_r4[1], n);
fdmdv_8_to_48_float(temp_r[2], state->f_r4[2], n);
//interleave left and right channels from the temp (float) buffer
for (i = 0; i < 160*6; i++)
{
if (!encL)
stereo_samp1[i*2+0] = temp_l[0][i];
if (!encR)
stereo_samp1[i*2+1] = temp_r[0][i];
}
for (i = 0; i < 160*6; i++)
{
if (!encL)
stereo_samp2[i*2+0] = temp_l[1][i];
if (!encR)
stereo_samp2[i*2+1] = temp_r[1][i];
}
for (i = 0; i < 160*6; i++)
{
if (!encL)
stereo_samp3[i*2+0] = temp_l[2][i];
if (!encR)
stereo_samp3[i*2+1] = temp_r[2][i];
}
if (opts->audio_out_type == 0) //Pulse Audio
{
pa_simple_write(opts->pulse_digi_dev_out, stereo_samp1, 320*4*6, NULL);
pa_simple_write(opts->pulse_digi_dev_out, stereo_samp2, 320*4*6, NULL);
pa_simple_write(opts->pulse_digi_dev_out, stereo_samp3, 320*4*6, NULL);
}
//No OSS, since we can't use float output, but STDOUT can with play, aplay, etc
if (opts->audio_out_type == 1) //STDOUT
{
write (opts->audio_out_fd, stereo_samp1, 320*4*6);
write (opts->audio_out_fd, stereo_samp2, 320*4*6);
write (opts->audio_out_fd, stereo_samp3, 320*4*6);
}
FS348_END:
memset (state->audio_out_temp_buf, baseline, sizeof(state->audio_out_temp_buf));
memset (state->audio_out_temp_bufR, baseline, sizeof(state->audio_out_temp_bufR));
//set float temp buffer to baseline
memset (state->f_l4, baseline, sizeof(state->f_l4));
memset (state->f_r4, baseline, sizeof(state->f_r4));
//if we don't run processAudio, then I don't think we really need any of the items below active
state->audio_out_idx = 0;
state->audio_out_idxR = 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;
}
if (state->audio_out_idx2R >= 800000)
{
state->audio_out_float_buf_pR = state->audio_out_float_bufR + 100;
state->audio_out_buf_pR = state->audio_out_bufR + 100;
memset (state->audio_out_float_bufR, 0, 100 * sizeof (float));
memset (state->audio_out_bufR, 0, 100 * sizeof (short));
state->audio_out_idx2R = 0;
}
}
//float stereo mix 4v2 P25p2
void playSynthesizedVoiceFS4 (dsd_opts * opts, dsd_state * state)
{
@@ -578,193 +393,6 @@ void playSynthesizedVoiceFS4 (dsd_opts * opts, dsd_state * state)
}
//float stereo mix 4v2 P25p2 with 8k to 48k upsample
void playSynthesizedVoiceFS4_48k (dsd_opts * opts, dsd_state * state)
{
//NOTE: The old version UpsampleF had a high pitch ring to it
//new version has an odd 'pattering' or 'crackle' sound or clipping?
int i, n, encL, encR;
// int j, k;
// float prev;
float stereo_samp1[320*6]; //48k 2-channel stereo interleave mix
float stereo_samp2[320*6]; //48k 2-channel stereo interleave mix
float stereo_samp3[320*6]; //48k 2-channel stereo interleave mix
float stereo_samp4[320*6]; //48k 2-channel stereo interleave mix
float out[6];
float temp_l[4][160*6]; //temp storage
float temp_r[4][160*6]; //temp storage
float empty[320*6];
float baseline = 0.0f;
memset (stereo_samp1, baseline, sizeof(stereo_samp1));
memset (stereo_samp2, baseline, sizeof(stereo_samp2));
memset (stereo_samp3, baseline, sizeof(stereo_samp3));
memset (stereo_samp4, baseline, sizeof(stereo_samp4));
memset (temp_l, baseline, sizeof(temp_l));
memset (temp_r, baseline, sizeof(temp_r));
memset (out, baseline, sizeof(out));
memset (empty, baseline, sizeof(empty));
//p25p2 enc checkdown for whether or not to fill the stereo sample or not for playback or writing
encL = encR = 1;
if (state->payload_algid == 0 || state->payload_algid == 0x80)
encL = 0;
if (state->payload_algidR == 0 || state->payload_algidR == 0x80)
encR = 0;
//checkdown to see if we can lift the 'mute' if a key is available
if (encL)
{
if (state->payload_algid == 0xAA)
{
if (state->R != 0)
{
encL = 0;
}
}
}
if (encR)
{
if (state->payload_algidR == 0xAA)
{
if (state->RR != 0)
{
encR = 0;
}
}
}
//at this point, if both channels are still flagged as enc, then we can skip all playback/writing functions
if (encL && encR)
goto FS448_END;
//TODO: Test Upsampling //void upsampleF (float invalue, float prev, float outbuf[6])
// prev = 0.0f;
// for (j = 0; j < 4; j++)
// {
// for (i = 0; i < 160; i++)
// {
// upsampleF (state->f_l4[j][i] / ((float) 480*10), prev, out);
// // upsampleF (state->f_l4[j][i], prev, out);
// for (k = 0; k < 6; k++) temp_l[j][i*6+k] = out[k];
// }
// }
// prev = 0.0f; //test value
// for (j = 0; j < 4; j++)
// {
// for (i = 0; i < 160; i++)
// {
// upsampleF (state->f_r4[j][i] / ((float) 480*10), prev, out);
// // upsampleF (state->f_r4[j][i], prev, out);
// for (k = 0; k < 6; k++) temp_r[j][i*6+k] = out[k];
// }
// }
n = 160; //not sure why we are using 159 though
fdmdv_8_to_48_float(temp_l[0], state->f_l4[0], n);
fdmdv_8_to_48_float(temp_l[1], state->f_l4[1], n);
fdmdv_8_to_48_float(temp_l[2], state->f_l4[2], n);
fdmdv_8_to_48_float(temp_l[3], state->f_l4[3], n);
fdmdv_8_to_48_float(temp_r[0], state->f_r4[0], n);
fdmdv_8_to_48_float(temp_r[1], state->f_r4[1], n);
fdmdv_8_to_48_float(temp_r[2], state->f_r4[2], n);
fdmdv_8_to_48_float(temp_r[3], state->f_r4[3], n);
//interleave left and right channels from the temp (float) buffer
for (i = 0; i < 160*6; i++)
{
if (!encL)
stereo_samp1[i*2+0] = temp_l[0][i];
if (!encR)
stereo_samp1[i*2+1] = temp_r[0][i];
}
for (i = 0; i < 160*6; i++)
{
if (!encL)
stereo_samp2[i*2+0] = temp_l[1][i];
if (!encR)
stereo_samp2[i*2+1] = temp_r[1][i];
}
for (i = 0; i < 160*6; i++)
{
if (!encL)
stereo_samp3[i*2+0] = temp_l[2][i];
if (!encR)
stereo_samp3[i*2+1] = temp_r[2][i];
}
for (i = 0; i < 160*6; i++)
{
if (!encL)
stereo_samp4[i*2+0] = temp_l[3][i];
if (!encR)
stereo_samp4[i*2+1] = temp_r[3][i];
}
if (opts->audio_out_type == 0) //Pulse Audio
{
pa_simple_write(opts->pulse_digi_dev_out, stereo_samp1, 320*4*6, NULL);
pa_simple_write(opts->pulse_digi_dev_out, stereo_samp2, 320*4*6, NULL);
if (memcmp(empty, stereo_samp3, sizeof(empty)) != 0)
pa_simple_write(opts->pulse_digi_dev_out, stereo_samp3, 320*4*6, NULL);
if (memcmp(empty, stereo_samp4, sizeof(empty)) != 0)
pa_simple_write(opts->pulse_digi_dev_out, stereo_samp4, 320*4*6, NULL);
}
//No OSS, since we can't use float output, but STDOUT can with play, aplay, etc
if (opts->audio_out_type == 1) //STDOUT
{
write (opts->audio_out_fd, stereo_samp1, 320*4*6);
write (opts->audio_out_fd, stereo_samp2, 320*4*6);
if (memcmp(empty, stereo_samp3, sizeof(empty)) != 0)
write (opts->audio_out_fd, stereo_samp3, 320*4*6);
if (memcmp(empty, stereo_samp4, sizeof(empty)) != 0)
write (opts->audio_out_fd, stereo_samp4, 320*4*6);
}
FS448_END:
memset (state->audio_out_temp_buf, baseline, sizeof(state->audio_out_temp_buf));
memset (state->audio_out_temp_bufR, baseline, sizeof(state->audio_out_temp_bufR));
//set float temp buffer to baseline
memset (state->f_l4, baseline, sizeof(state->f_l4));
memset (state->f_r4, baseline, sizeof(state->f_r4));
//if we don't run processAudio, then I don't think we really need any of the items below active
state->audio_out_idx = 0;
state->audio_out_idxR = 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;
}
if (state->audio_out_idx2R >= 800000)
{
state->audio_out_float_buf_pR = state->audio_out_float_bufR + 100;
state->audio_out_buf_pR = state->audio_out_bufR + 100;
memset (state->audio_out_float_bufR, 0, 100 * sizeof (float));
memset (state->audio_out_bufR, 0, 100 * sizeof (short));
state->audio_out_idx2R = 0;
}
}
//float stereo mix -- when using P25p1 and P25p2, we need to send P25p1 to this, also DMR MS/Simplex and YSF
void playSynthesizedVoiceFS (dsd_opts * opts, dsd_state * state)
{
@@ -880,7 +508,7 @@ void playSynthesizedVoiceSS (dsd_opts * opts, dsd_state * state)
//dmr enc checkdown for whether or not to fill the stereo sample or not for playback or writing
encL = 0;
//TODO: Enc Checkdown
//TODO: Enc Checkdown -- would need to cover more ground than otherwise would like for it to, these should ultimately be passed to each encoding type decoder instead
//TODO: add option to bypass enc with a toggle as well
@@ -1231,279 +859,4 @@ void playSynthesizedVoiceSS4 (dsd_opts * opts, dsd_state * state)
state->audio_out_idx2R = 0;
}
}
//short stereo mix 3v2 DMR with tapped 8k to 48k upsample
void playSynthesizedVoiceSS3_48k (dsd_opts * opts, dsd_state * state)
{
//NOTE: This runs once for every two timeslots, if we are in the BS voice loop
//it doesn't matter if both slots have voice, or if one does, the slot without voice
//will play silence while this runs if no voice present
int i;
uint8_t encL, encR;
short stereo_samp1[320*6]; //48k 2-channel stereo interleave mix
short stereo_samp2[320*6]; //48k 2-channel stereo interleave mix
short stereo_samp3[320*6]; //48k 2-channel stereo interleave mix
memset (stereo_samp1, 1, sizeof(stereo_samp1));
memset (stereo_samp2, 1, sizeof(stereo_samp2));
memset (stereo_samp3, 1, sizeof(stereo_samp3));
//dmr enc checkdown for whether or not to fill the stereo sample or not for playback or writing
encL = encR = 0;
encL = (state->dmr_so >> 6) & 0x1;
encR = (state->dmr_soR >> 6) & 0x1;
//checkdown to see if we can lift the 'mute' if a key is available
if (encL)
{
if (state->payload_algid == 0)
{
if (state->K != 0 || state->K1 != 0)
{
encL = 0;
}
}
else if (state->payload_algid == 0x21)
{
if (state->R != 0)
{
encL = 0;
}
}
}
if (encR)
{
if (state->payload_algidR == 0)
{
if (state->K != 0 || state->K1 != 0)
{
encR = 0;
}
}
else if (state->payload_algidR == 0x21)
{
if (state->RR != 0)
{
encR = 0;
}
}
}
//TODO: add option to bypass enc with a toggle as well
//interleave left and right channels from the short storage area
for (i = 0; i < 160*6; i++)
{
if (!encL)
stereo_samp1[i*2+0] = state->s_l4u[0][i];
if (!encR)
stereo_samp1[i*2+1] = state->s_r4u[0][i];
}
for (i = 0; i < 160*6; i++)
{
if (!encL)
stereo_samp2[i*2+0] = state->s_l4u[1][i];
if (!encR)
stereo_samp2[i*2+1] = state->s_r4u[1][i];
}
for (i = 0; i < 160*6; i++)
{
if (!encL)
stereo_samp3[i*2+0] = state->s_l4u[2][i];
if (!encR)
stereo_samp3[i*2+1] = state->s_r4u[2][i];
}
//at this point, if both channels are still flagged as enc, then we can skip all playback/writing functions
if (encL && encR)
goto SS3u_END;
if (opts->audio_out_type == 0) //Pulse Audio
{
pa_simple_write(opts->pulse_digi_dev_out, stereo_samp1, 320*2*6, NULL);
pa_simple_write(opts->pulse_digi_dev_out, stereo_samp2, 320*2*6, NULL);
pa_simple_write(opts->pulse_digi_dev_out, stereo_samp3, 320*2*6, NULL);
}
if (opts->audio_out_type == 1 || opts->audio_out_type == 5) //STDOUT or OSS
{
write (opts->audio_out_fd, stereo_samp1, 320*2*6);
write (opts->audio_out_fd, stereo_samp2, 320*2*6);
write (opts->audio_out_fd, stereo_samp3, 320*2*6);
}
SS3u_END:
//run cleanup since we pulled stuff from processAudio
state->audio_out_idx = 0;
state->audio_out_idxR = 0;
//set short temp buffer to baseline
memset (state->s_l4u, 1, sizeof(state->s_l4u));
memset (state->s_r4u, 1, sizeof(state->s_r4u));
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;
}
if (state->audio_out_idx2R >= 800000)
{
state->audio_out_float_buf_pR = state->audio_out_float_bufR + 100;
state->audio_out_buf_pR = state->audio_out_bufR + 100;
memset (state->audio_out_float_bufR, 0, 100 * sizeof (float));
memset (state->audio_out_bufR, 0, 100 * sizeof (short));
state->audio_out_idx2R = 0;
}
}
//short stereo mix 4v2 P25p2 with tapped 8k to 48k upsample
void playSynthesizedVoiceSS4_48k (dsd_opts * opts, dsd_state * state)
{
int i, encL, encR;
short stereo_samp1[320*6]; //48k 2-channel stereo interleave mix
short stereo_samp2[320*6]; //48k 2-channel stereo interleave mix
short stereo_samp3[320*6]; //48k 2-channel stereo interleave mix
short stereo_samp4[320*6]; //48k 2-channel stereo interleave mix
memset (stereo_samp1, 1, sizeof(stereo_samp1));
memset (stereo_samp2, 1, sizeof(stereo_samp2));
memset (stereo_samp3, 1, sizeof(stereo_samp3));
memset (stereo_samp4, 1, sizeof(stereo_samp4));
float empty[320]; //this is used to see if we want to play a single 2v or double 2v or not
memset (empty, 1, sizeof(empty));
//p25p2 enc checkdown for whether or not to fill the stereo sample or not for playback or writing
encL = encR = 1;
if (state->payload_algid == 0 || state->payload_algid == 0x80)
encL = 0;
if (state->payload_algidR == 0 || state->payload_algidR == 0x80)
encR = 0;
//checkdown to see if we can lift the 'mute' if a key is available
if (encL)
{
if (state->payload_algid == 0xAA)
{
if (state->R != 0)
{
encL = 0;
}
}
}
if (encR)
{
if (state->payload_algidR == 0xAA)
{
if (state->RR != 0)
{
encR = 0;
}
}
}
//TODO: add option to bypass enc with a toggle as well
//interleave left and right channels from the short storage area
for (i = 0; i < 160*6; i++)
{
if (!encL)
stereo_samp1[i*2+0] = state->s_l4u[0][i];
if (!encR)
stereo_samp1[i*2+1] = state->s_r4u[0][i];
}
for (i = 0; i < 160*6; i++)
{
if (!encL)
stereo_samp2[i*2+0] = state->s_l4u[1][i];
if (!encR)
stereo_samp2[i*2+1] = state->s_r4u[1][i];
}
for (i = 0; i < 160*6; i++)
{
if (!encL)
stereo_samp3[i*2+0] = state->s_l4u[2][i];
if (!encR)
stereo_samp3[i*2+1] = state->s_r4u[2][i];
}
for (i = 0; i < 160*6; i++)
{
if (!encL)
stereo_samp4[i*2+0] = state->s_l4u[3][i];
if (!encR)
stereo_samp4[i*2+1] = state->s_r4u[3][i];
}
//at this point, if both channels are still flagged as enc, then we can skip all playback/writing functions
if (encL && encR)
goto SS4u_END;
if (opts->audio_out_type == 0) //Pulse Audio
{
pa_simple_write(opts->pulse_digi_dev_out, stereo_samp1, 320*2*6, NULL);
pa_simple_write(opts->pulse_digi_dev_out, stereo_samp2, 320*2*6, NULL);
if (memcmp(empty, stereo_samp3, sizeof(empty)) != 0)
pa_simple_write(opts->pulse_digi_dev_out, stereo_samp3, 320*2*6, NULL);
if (memcmp(empty, stereo_samp4, sizeof(empty)) != 0)
pa_simple_write(opts->pulse_digi_dev_out, stereo_samp4, 320*2*6, NULL);
}
if (opts->audio_out_type == 1 || opts->audio_out_type == 5) //STDOUT or OSS
{
write (opts->audio_out_fd, stereo_samp1, 320*2*6);
write (opts->audio_out_fd, stereo_samp2, 320*2*6);
if (memcmp(empty, stereo_samp3, sizeof(empty)) != 0)
write (opts->audio_out_fd, stereo_samp3, 320*2*6);
if (memcmp(empty, stereo_samp4, sizeof(empty)) != 0)
write (opts->audio_out_fd, stereo_samp4, 320*2*6);
}
SS4u_END:
//run cleanup since we pulled stuff from processAudio
state->audio_out_idx = 0;
state->audio_out_idxR = 0;
//set short temp buffer to baseline
memset (state->s_l4u, 1, sizeof(state->s_l4u));
memset (state->s_r4u, 1, sizeof(state->s_r4u));
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;
}
if (state->audio_out_idx2R >= 800000)
{
state->audio_out_float_buf_pR = state->audio_out_float_bufR + 100;
state->audio_out_buf_pR = state->audio_out_bufR + 100;
memset (state->audio_out_float_bufR, 0, 100 * sizeof (float));
memset (state->audio_out_bufR, 0, 100 * sizeof (short));
state->audio_out_idx2R = 0;
}
}

View File

@@ -2803,7 +2803,6 @@ main (int argc, char **argv)
opts.pulse_digi_rate_out = 8000;
opts.pulse_digi_out_channels = 1;
if (opts.audio_out_type == 0) openPulseOutput(&opts);
if (opts.audio_out_type == 5) openAudioOutDevice (&opts, SAMPLE_RATE_OUT);
}
//this particular if-elseif-else could be rewritten to be a lot neater and simpler

View File

@@ -17,8 +17,8 @@
#include "dsd.h"
//NOTE: I attempted to fix the atrocious tab/space alignnment issues that happened in this file,
//it looks fine in VSCodium, but no telling how it will translate when pushed to Github or another editor
//NOTE: This set of functions will be reorganized and simplified (hopefully) or at least
//a more logical flow will be established to jive with the new audio handling
void keyring(dsd_opts * opts, dsd_state * state)
{
@@ -1084,7 +1084,6 @@ 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)); //these are for mono or FDMA where we don't need to buffer and wait for a stereo mix
// playSynthesizedVoiceFL (opts, state); //Float Left
}
@@ -1159,7 +1158,6 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
}
memcpy (state->f_r, state->audio_out_temp_bufR, sizeof(state->f_r));
// playSynthesizedVoiceFR (opts, state); //Float Right
}
@@ -1175,13 +1173,10 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
// {
// playSynthesizedVoice (opts, state);
// }
// playSynthesizedVoiceFL (opts, state);
memcpy (state->f_l, state->audio_out_temp_buf, sizeof(state->f_l)); //P25p1 FDMA 8k/1 channel -f1 switch
}
// playSynthesizedVoiceFS (opts, state); //Float Stereo Mix -- disable and move this later on
//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))
{

View File

@@ -136,3 +136,23 @@ upsample (dsd_state * state, float invalue)
}
}
//produce 6 short samples (48k) for every 1 short sample (8k)
void upsampleS (short invalue, short prev, short outbuf[6])
{
float c, d;
c = prev;
d = invalue;
// basic triangle interpolation
outbuf[0] = c = ((invalue * (float) 0.166) + (c * (float) 0.834));
outbuf[1] = c = ((invalue * (float) 0.332) + (c * (float) 0.668));
outbuf[2] = c = ((invalue * (float) 0.500) + (c * (float) 0.5));
outbuf[3] = c = ((invalue * (float) 0.668) + (c * (float) 0.332));
outbuf[4] = c = ((invalue * (float) 0.834) + (c * (float) 0.166));
outbuf[5] = c = d;
prev = d; //shift prev to the last d value for the next repitition
}

View File

@@ -1,259 +0,0 @@
#include "dsd.h"
static const float fdmdv_os_filter48[48]= {
-3.55606818e-04,
-8.98615286e-04,
-1.40119781e-03,
-1.71713852e-03,
-1.56471179e-03,
-6.28128960e-04,
1.24522223e-03,
3.83138676e-03,
6.41309478e-03,
7.85893186e-03,
6.93514929e-03,
2.79361991e-03,
-4.51051400e-03,
-1.36671853e-02,
-2.21034939e-02,
-2.64084653e-02,
-2.31425052e-02,
-9.84218694e-03,
1.40648474e-02,
4.67316298e-02,
8.39615986e-02,
1.19925275e-01,
1.48381174e-01,
1.64097819e-01,
1.64097819e-01,
1.48381174e-01,
1.19925275e-01,
8.39615986e-02,
4.67316298e-02,
1.40648474e-02,
-9.84218694e-03,
-2.31425052e-02,
-2.64084653e-02,
-2.21034939e-02,
-1.36671853e-02,
-4.51051400e-03,
2.79361991e-03,
6.93514929e-03,
7.85893186e-03,
6.41309478e-03,
3.83138676e-03,
1.24522223e-03,
-6.28128960e-04,
-1.56471179e-03,
-1.71713852e-03,
-1.40119781e-03,
-8.98615286e-04,
-3.55606818e-04
};
//from CODEC2
//float filter /* Generate using fir1(47,1/2) in Octave */
static const float fdmdv_os_filter[48]= {
-0.0008215855034550382,
-0.0007833023901802921,
0.001075563790768233,
0.001199092367787555,
-0.001765309502928316,
-0.002055372115328064,
0.002986877604154257,
0.003462567920638414,
-0.004856570111126334,
-0.005563143845031497,
0.007533613299748122,
0.008563932468880897,
-0.01126857129039911,
-0.01280782411693687,
0.01651443896361847,
0.01894875110322284,
-0.02421604439474981,
-0.02845107338464062,
0.03672973563400258,
0.04542046150312214,
-0.06189165826716491,
-0.08721876380763803,
0.1496157094199961,
0.4497962274137046,
0.4497962274137046,
0.1496157094199961,
-0.08721876380763803,
-0.0618916582671649,
0.04542046150312216,
0.03672973563400257,
-0.02845107338464062,
-0.02421604439474984,
0.01894875110322284,
0.01651443896361848,
-0.01280782411693687,
-0.0112685712903991,
0.008563932468880899,
0.007533613299748123,
-0.005563143845031501,
-0.004856570111126346,
0.003462567920638419,
0.002986877604154259,
-0.002055372115328063,
-0.001765309502928318,
0.001199092367787557,
0.001075563790768233,
-0.0007833023901802925,
-0.0008215855034550383
};
//produce 6 float samples (48k) for every 1 float sample (8k)
void upsampleF (float invalue, float prev, float outbuf[6])
{
float c, d;
c = prev; //may ned up needing storage for the prev value to prevent the high pitch 'ring' sound
d = invalue;
// basic triangle interpolation
outbuf[0] = c = ((invalue * (float) 0.166) + (c * (float) 0.834));
outbuf[1] = c = ((invalue * (float) 0.332) + (c * (float) 0.668));
outbuf[2] = c = ((invalue * (float) 0.500) + (c * (float) 0.5));
outbuf[3] = c = ((invalue * (float) 0.668) + (c * (float) 0.332));
outbuf[4] = c = ((invalue * (float) 0.834) + (c * (float) 0.166));
outbuf[5] = c = d;
prev = d; //shift prev to the last d value for the next repitition
// fdmdv_os_filter48
}
//produce 6 short samples (48k) for every 1 short sample (8k)
void upsampleS (short invalue, short prev, short outbuf[6])
{
float c, d;
c = prev;
d = invalue;
// basic triangle interpolation
outbuf[0] = c = ((invalue * (float) 0.166) + (c * (float) 0.834));
outbuf[1] = c = ((invalue * (float) 0.332) + (c * (float) 0.668));
outbuf[2] = c = ((invalue * (float) 0.500) + (c * (float) 0.5));
outbuf[3] = c = ((invalue * (float) 0.668) + (c * (float) 0.332));
outbuf[4] = c = ((invalue * (float) 0.834) + (c * (float) 0.166));
outbuf[5] = c = d;
prev = d; //shift prev to the last d value for the next repitition
}
// void fdmdv_8_to_48_short(short out48k[], short in8k[], int n)
// {
// int i,j,k,l;
// float acc;
// //FDMDV_OS_TAPS_48K = 48
// //FDMDV_OS_48 = 6
// //unsure of what the n value would be, could be number of samples to process?
// for(i=0; i<n; i++) {
// for(j=0; j<FDMDV_OS_48; j++) {
// acc = 0.0;
// for(k=0,l=0; k<FDMDV_OS_TAPS_48K; k+=FDMDV_OS_48,l++)
// acc += fdmdv_os_filter48[k+j]*in8k[i-l];
// out48k[i*FDMDV_OS_48+j] = acc*FDMDV_OS_48;
// }
// }
// /* update filter memory */
// for(i=-FDMDV_OS_TAPS_48_8K; i<0; i++)
// in8k[i] = in8k[i + n];
// }
//this might be useful for the cygwin 'warning' that pops up during compilation
/* set up the calling convention for DLL function import/export for
WIN32 cross compiling */
/*
#ifdef __CODEC2_WIN32__
#ifdef __CODEC2_BUILDING_DLL__
#define CODEC2_WIN32SUPPORT __declspec(dllexport) __stdcall //but use optarg?
#else
#define CODEC2_WIN32SUPPORT __declspec(dllimport) __stdcall
#endif
#else
#define CODEC2_WIN32SUPPORT
#endif
*/
//modified from CODEC2 source code
/*
t48_8_short.c
David Rowe
Dec 2021
*/
void fdmdv_8_to_48_float(float out48k[], float in8k[], int n)
{
int i,j,k,l;
// int a,b;
// a = 48;
// b = 6;
float baseline = 0.0f;
//n = #define N8 159 /* processing buffer size at 8 kHz (odd number deliberate) */
//a = FDMDV_OS_TAPS_48K = 48
//b = FDMDV_OS_48 = 6
//unsure of what the n value would be, could be number of samples to process, or to produce?
float empty[160];
memset (empty, baseline, sizeof(empty));
//skip processing if its dead silence (2v or SF)
if (memcmp(empty, in8k, sizeof(empty)) == 0)
goto END_48f;
// //add a float decimation value here -- switch to 192.0f * aout_gain later on
// for (i = 0; i < 160; i++)
// in8k[i] /= 4800.0f;
//shut up the warnings for now
UNUSED(fdmdv_os_filter); //this filter sounds a bit 'tinny' and 'thin'
// UNUSED(fdmdv_os_filter48); //this filter has a 'dampening' effect
for(i=0; i<n; i++)
{
for(j=0; j<6; j++)
{
out48k[i*6+j] = 0.0f;
for(k=0,l=0; k<48; k+=6,l++)
out48k[i*6+j] += fdmdv_os_filter48[k+j]*in8k[i-l];
out48k[i*6+j] *= 6.0f;
}
}
/* update filter memory */ //is this working properly?
// for(i=-a; i<0; i++)
// in8k[i] = in8k[i + n];
//doesn't really seem to matter much if before or after, I wonder if we lose a smmidge of float precision though going before
//add a float decimation value here -- switch to 192.0f * aout_gain later on
for (i = 0; i < 960; i++)
out48k[i] /= 4800.0f;
//debug
// fprintf (stderr, "\n SAMPS = ");
for (i = 0; i < 960; i++)
{
if (!(i % 6))
fprintf (stderr, "\n SAMPS = ");
fprintf (stderr, "(%f) ", out48k[i]);
}
END_48f: ; //do nothing
}

View File

@@ -928,15 +928,9 @@ void process_P2_DUID (dsd_opts * opts, dsd_state * state)
if (sacch == 0 && ts_counter & 1 && opts->floating_point == 1 && opts->pulse_digi_rate_out == 8000) //this should be a real TS value %2 and non-inverted frames, so 0-9, need a way to get real TS number each go around
playSynthesizedVoiceFS4 (opts, state);
if (sacch == 0 && ts_counter & 1 && opts->floating_point == 1 && opts->pulse_digi_rate_out == 48000) //this should be a real TS value %2 and non-inverted frames, so 0-9, need a way to get real TS number each go around
playSynthesizedVoiceFS4_48k (opts, state);
if (sacch == 0 && ts_counter & 1 && opts->floating_point == 0 && opts->pulse_digi_rate_out == 8000) //this should be a real TS value %2 and non-inverted frames, so 0-9, need a way to get real TS number each go around
playSynthesizedVoiceSS4 (opts, state);
if (sacch == 0 && ts_counter & 1 && opts->floating_point == 0 && opts->pulse_digi_rate_out == 48000) //this should be a real TS value %2 and non-inverted frames, so 0-9, need a way to get real TS number each go around
playSynthesizedVoiceSS4_48k (opts, state);
//flip slots after each TS processed
if (state->currentslot == 0)
{