mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-12 16:57:23 -05:00
Round of Code Cleanup;
This commit is contained in:
@@ -889,35 +889,24 @@ typedef struct
|
||||
void processdPMRvoice (dsd_opts * opts, dsd_state * state);
|
||||
void processAudio (dsd_opts * opts, dsd_state * state);
|
||||
void processAudioR (dsd_opts * opts, dsd_state * state);
|
||||
void openPulseInput (dsd_opts * opts); //not sure if we need to just pass opts, or opts and state yet
|
||||
void openPulseOutput (dsd_opts * opts); //not sure if we need to just pass opts, or opts and state yet
|
||||
void openPulseInput (dsd_opts * opts);
|
||||
void openPulseOutput (dsd_opts * opts);
|
||||
void closePulseInput (dsd_opts * opts);
|
||||
void closePulseOutput (dsd_opts * opts);
|
||||
void writeSynthesizedVoice (dsd_opts * opts, dsd_state * state);
|
||||
void writeSynthesizedVoiceR (dsd_opts * opts, dsd_state * state);
|
||||
void playSynthesizedVoice (dsd_opts * opts, dsd_state * state); //short mono output
|
||||
void playSynthesizedVoiceR (dsd_opts * opts, dsd_state * state); //short mono output rigth (obsolete)?
|
||||
void playSynthesizedVoice (dsd_opts * opts, dsd_state * state); //short mono output slot 1
|
||||
void playSynthesizedVoiceR (dsd_opts * opts, dsd_state * state); //short mono output slot 2
|
||||
//new float stuff
|
||||
void playSynthesizedVoiceFS (dsd_opts * opts, dsd_state * state); //float stereo mix
|
||||
void playSynthesizedVoiceFS3 (dsd_opts * opts, dsd_state * state); //float stereo mix 3v2 DMR...and X2-TDMA
|
||||
void playSynthesizedVoiceFS3 (dsd_opts * opts, dsd_state * state); //float stereo mix 3v2 DMR
|
||||
void playSynthesizedVoiceFS4 (dsd_opts * opts, dsd_state * state); //float stereo mix 4v2 P25p2
|
||||
// void playSynthesizedVoiceFL (dsd_opts * opts, dsd_state * state); //float left when using stereo configuration
|
||||
void playSynthesizedVoiceFM (dsd_opts * opts, dsd_state * state); //float mono
|
||||
|
||||
//new short stuff
|
||||
void playSynthesizedVoiceSS (dsd_opts * opts, dsd_state * state); //short stereo mix
|
||||
void playSynthesizedVoiceSS3 (dsd_opts * opts, dsd_state * state); //short stereo mix 3v2 DMR...and X2-TDMA
|
||||
void playSynthesizedVoiceSS3 (dsd_opts * opts, dsd_state * state); //short stereo mix 3v2 DMR
|
||||
void playSynthesizedVoiceSS4 (dsd_opts * opts, dsd_state * state); //short stereo mix 4v2 P25p2
|
||||
|
||||
void upsampleF (float invalue, float prev, float outbuf[6]);
|
||||
void playSynthesizedVoiceFS3_48k (dsd_opts * opts, dsd_state * state);
|
||||
void playSynthesizedVoiceFS4_48k (dsd_opts * opts, dsd_state * state);
|
||||
|
||||
void upsampleS (short invalue, short prev, short outbuf[6]);
|
||||
void playSynthesizedVoiceSS3_48k (dsd_opts * opts, dsd_state * state);
|
||||
void playSynthesizedVoiceSS4_48k (dsd_opts * opts, dsd_state * state);
|
||||
|
||||
//borrowed from CODEC2 for testing
|
||||
void fdmdv_8_to_48_float(float out48k[], float in8k[], int n);
|
||||
void upsampleS (short invalue, short prev, short outbuf[6]); //upsample 8k to 48k short in M17
|
||||
|
||||
//
|
||||
void openAudioOutDevice (dsd_opts * opts, int speed);
|
||||
|
||||
@@ -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:
|
||||
|
||||
655
src/dsd_audio2.c
655
src/dsd_audio2.c
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user