mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-15 02:07:24 -05:00
Round of Code Cleanup;
This commit is contained in:
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;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user