WIP: audio_work 2;

This commit is contained in:
lwvmobile
2023-07-24 18:32:09 -04:00
parent f2f20f8f94
commit 16959cac7a
16 changed files with 2902 additions and 273 deletions

View File

@@ -65,7 +65,7 @@
#include <pulse/error.h> //PULSE AUDIO
#define SAMPLE_RATE_IN 48000 //48000
#define SAMPLE_RATE_OUT 48000 //8000,
#define SAMPLE_RATE_OUT 8000 //8000
#ifdef USE_RTLSDR
#include <rtl-sdr.h>
@@ -399,6 +399,9 @@ typedef struct
//Use P25p1 heuristics
uint8_t use_heuristics;
//Use floating point audio output
int floating_point;
} dsd_opts;
typedef struct
@@ -420,6 +423,22 @@ typedef struct
float *audio_out_temp_buf_p;
float audio_out_temp_bufR[160];
float *audio_out_temp_buf_pR;
//new stereo float sample storage
float f_l[160]; //single sample left
float f_r[160]; //single sample right
float f_l4[4][160]; //quad sample for up to a P25p2 4V
float f_r4[4][160]; //quad sample for up to a P25p2 4V
//new stereo short sample storage
short s_l[160]; //single sample left
short s_r[160]; //single sample right
short s_l4[4][160]; //quad sample for up to a P25p2 4V
short s_r4[4][160]; //quad sample for up to a P25p2 4V
//new stereo short sample storage tapped from 48_k internal upsampling
short s_lu[160*6]; //single sample left
short s_ru[160*6]; //single sample right
short s_l4u[4][160*6]; //quad sample for up to a P25p2 4V
short s_r4u[4][160*6]; //quad sample for up to a P25p2 4V
//end
int audio_out_idx;
int audio_out_idx2;
int audio_out_idxR;
@@ -872,8 +891,31 @@ 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);
void playSynthesizedVoiceR (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)?
//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 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
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 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 openAudioOutDevice (dsd_opts * opts, int speed);
void openAudioInDevice (dsd_opts * opts);

View File

@@ -373,8 +373,51 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
memcpy (m3, ambe_fr3, sizeof(m3));
processMbeFrame (opts, state, NULL, ambe_fr, NULL);
if(internalslot == 0)
{
memcpy(state->f_l4[0], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[0], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[0], state->s_lu, sizeof(state->s_lu));
}
else
{
memcpy(state->f_r4[0], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR));
memcpy(state->s_r4[0], state->s_r, sizeof(state->s_r));
memcpy(state->s_r4u[0], state->s_ru, sizeof(state->s_ru));
}
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
if(internalslot == 0)
{
memcpy(state->f_l4[1], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[1], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[1], state->s_lu, sizeof(state->s_lu));
}
else
{
memcpy(state->f_r4[1], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR));
memcpy(state->s_r4[1], state->s_r, sizeof(state->s_r));
memcpy(state->s_r4u[1], state->s_ru, sizeof(state->s_ru));
}
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
if(internalslot == 0)
{
memcpy(state->f_l4[2], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[2], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[2], state->s_lu, sizeof(state->s_lu));
}
else
{
memcpy(state->f_r4[2], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR));
memcpy(state->s_r4[2], state->s_r, sizeof(state->s_r));
memcpy(state->s_r4u[2], state->s_ru, sizeof(state->s_ru));
}
//run sbrc here to look for the late entry key and alg after we observe potential errors in VC6
if (internalslot == 0 && vc1 == 6) dmr_sbrc (opts, state, power);
@@ -437,6 +480,18 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
}
SKIP:
//both working now, will need support added for ENC audio and no key
//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
{
//set tests to all good so we don't get a bogus/redundant voice error
@@ -722,9 +777,49 @@ void dmrBSBootstrap (dsd_opts * opts, dsd_state * state)
memcpy (m3, ambe_fr3, sizeof(m3));
if (opts->payload == 1) fprintf (stderr, "\n"); //extra line break necessary here
// processMbeFrame (opts, state, NULL, ambe_fr, NULL);
// processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
// processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
processMbeFrame (opts, state, NULL, ambe_fr, NULL);
if(internalslot == 0)
{
memcpy(state->f_l4[0], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[0], state->s_l, sizeof(state->s_l));
}
else
{
memcpy(state->f_r4[0], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR));
memcpy(state->s_r4[0], state->s_r, sizeof(state->s_r));
}
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
if(internalslot == 0)
{
memcpy(state->f_l4[1], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[1], state->s_l, sizeof(state->s_l));
}
else
{
memcpy(state->f_r4[1], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR));
memcpy(state->s_r4[1], state->s_r, sizeof(state->s_r));
}
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
if(internalslot == 0)
{
memcpy(state->f_l4[2], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[2], state->s_l, sizeof(state->s_l));
}
else
{
memcpy(state->f_r4[2], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR));
memcpy(state->s_r4[2], state->s_r, sizeof(state->s_r));
}
//collect the mi fragment
dmr_late_entry_mi_fragment (opts, state, 1, m1, m2, m3);
@@ -735,6 +830,16 @@ void dmrBSBootstrap (dsd_opts * opts, dsd_state * state)
//update voice sync time for trunking purposes (particularly Con+)
if (opts->p25_is_tuned == 1) state->last_vc_sync_time = time(NULL);
//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:
//if we have a tact err, then produce sync pattern/err message

View File

@@ -280,17 +280,61 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
if (state->directmode == 0)
{
processMbeFrame (opts, state, NULL, ambe_fr, NULL);
memcpy(state->f_l4[0], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[0], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[0], state->s_lu, sizeof(state->s_lu));
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
memcpy(state->f_l4[1], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[1], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[1], state->s_lu, sizeof(state->s_lu));
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
memcpy(state->f_l4[2], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[2], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[2], state->s_lu, sizeof(state->s_lu));
}
else
{
processMbeFrame (opts, state, NULL, ambe_fr4, NULL); //play duplicate of 2 here to smooth audio on tdma direct
memcpy(state->f_l4[0], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[0], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[0], state->s_lu, sizeof(state->s_lu));
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
memcpy(state->f_l4[1], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[1], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[1], state->s_lu, sizeof(state->s_lu));
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
memcpy(state->f_l4[2], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[2], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[2], state->s_lu, sizeof(state->s_lu));
}
}
if (opts->floating_point == 0)
{
// processAudio(opts, state); //needed here? -- nothign to test it with
// if (opts->wav_out_f != NULL)
// writeSynthesizedVoice (opts, state);
// if (opts->pulse_digi_out_channels == 1)
// playSynthesizedVoice(opts, state);
if(opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS3(opts, state);
}
if (opts->floating_point == 1) //float audio is really quiet now (look into it)
{
memcpy (state->f_l, state->audio_out_temp_buf, sizeof(state->f_l));
// if (opts->pulse_digi_out_channels == 1)
// playSynthesizedVoiceFM3(opts, state);
if(opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS3(opts, state);
}
if (vc == 6)
{
dmr_data_burst_handler(opts, state, (uint8_t *)dummy_bits, 0xEB);
@@ -557,14 +601,58 @@ void dmrMSBootstrap (dsd_opts * opts, dsd_state * state)
if (state->directmode == 0)
{
processMbeFrame (opts, state, NULL, ambe_fr, NULL);
memcpy(state->f_l4[0], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[0], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[0], state->s_lu, sizeof(state->s_lu));
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
memcpy(state->f_l4[1], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[1], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[1], state->s_lu, sizeof(state->s_lu));
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
memcpy(state->f_l4[2], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[2], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[2], state->s_lu, sizeof(state->s_lu));
}
else
{
processMbeFrame (opts, state, NULL, ambe_fr4, NULL); //play duplicate of 2 here to smooth audio
processMbeFrame (opts, state, NULL, ambe_fr4, NULL); //play duplicate of 2 here to smooth audio on tdma direct
memcpy(state->f_l4[0], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[0], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[0], state->s_lu, sizeof(state->s_lu));
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
memcpy(state->f_l4[1], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[1], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[1], state->s_lu, sizeof(state->s_lu));
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
memcpy(state->f_l4[2], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[2], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[2], state->s_lu, sizeof(state->s_lu));
}
if (opts->floating_point == 0)
{
// processAudio(opts, state); //NOTE: -fa switch will not work with this set up -- honestly shouldn't be needed
// if (opts->wav_out_f != NULL)
// writeSynthesizedVoice (opts, state);
// if (opts->pulse_digi_out_channels == 1)
// playSynthesizedVoice(opts, state);
if(opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS3(opts, state);
}
if (opts->floating_point == 1) //float audio is really quiet now (look into it)
{
memcpy (state->f_l, state->audio_out_temp_buf, sizeof(state->f_l));
// if (opts->pulse_digi_out_channels == 1)
// playSynthesizedVoiceFM(opts, state);
if(opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS3(opts, state);
}
//collect the mi fragment

View File

@@ -21,14 +21,15 @@ pa_sample_spec ss;
pa_sample_spec tt;
pa_sample_spec zz;
pa_sample_spec cc;
pa_sample_spec ff; //float
void closePulseOutput (dsd_opts * opts)
{
pa_simple_free (opts->pulse_digi_dev_out);
if (opts->dmr_stereo == 1)
{
pa_simple_free (opts->pulse_digi_dev_outR);
}
// if (opts->dmr_stereo == 1)
// {
// pa_simple_free (opts->pulse_digi_dev_outR);
// }
}
void closePulseInput (dsd_opts * opts)
@@ -40,32 +41,35 @@ void openPulseOutput(dsd_opts * opts)
{
ss.format = PA_SAMPLE_S16NE;
ss.channels = opts->pulse_raw_out_channels; //doing tests with 2 channels at 22050 for 44100 audio default in pulse
ss.rate = opts->pulse_raw_rate_out; //48000
ss.channels = opts->pulse_raw_out_channels;
ss.rate = opts->pulse_raw_rate_out;
tt.format = PA_SAMPLE_S16NE;
tt.channels = opts->pulse_digi_out_channels; //doing tests with 2 channels at 22050 for 44100 audio default in pulse
tt.rate = opts->pulse_digi_rate_out; //48000, switches to 8000 when using RTL dongle
tt.channels = opts->pulse_digi_out_channels;
tt.rate = opts->pulse_digi_rate_out;
ff.format = PA_SAMPLE_FLOAT32NE;
ff.channels = opts->pulse_digi_out_channels;
ff.rate = opts->pulse_digi_rate_out;
if (opts->monitor_input_audio == 1)
{
opts->pulse_raw_dev_out = pa_simple_new(NULL, "DSD-FME3", PA_STREAM_PLAYBACK, NULL, "Raw Audio Out", &ss, NULL, NULL, NULL);
}
//tt
pa_channel_map* left = 0; //NULL and 0 are same in this context
pa_channel_map* right = 0; //NULL and 0 are same in this context
pa_channel_map* fl = 0; //NULL and 0 are same in this context
pa_channel_map* ss = 0; //NULL and 0 are same in this context
if (opts->dmr_stereo == 0)
if (opts->floating_point == 0)
{
opts->pulse_digi_dev_out = pa_simple_new(NULL, "DSD-FME", PA_STREAM_PLAYBACK, NULL, opts->output_name, &tt, left, NULL, NULL);
opts->pulse_digi_dev_out = pa_simple_new(NULL, "DSD-FME", PA_STREAM_PLAYBACK, NULL, opts->output_name, &tt, ss, NULL, NULL);
}
if (opts->dmr_stereo == 1)
if (opts->floating_point == 1)
{
opts->pulse_digi_dev_out = pa_simple_new(NULL, "DSD-FME1", PA_STREAM_PLAYBACK, NULL, "XDMA SLOT 1", &tt, left, NULL, NULL);
opts->pulse_digi_dev_outR = pa_simple_new(NULL, "DSD-FME2", PA_STREAM_PLAYBACK, NULL, "XDMA SLOT 2", &tt, right, NULL, NULL);
opts->pulse_digi_dev_out = pa_simple_new(NULL, "DSD-FME", PA_STREAM_PLAYBACK, NULL, opts->output_name, &ff, fl, NULL, NULL);
}
}
@@ -197,6 +201,8 @@ processAudio (dsd_opts * opts, dsd_state * state)
*state->audio_out_float_buf_p = -32768.0F;
}
*state->audio_out_buf_p = (short) *state->audio_out_float_buf_p;
//tap the pointer here and store the short upsample buffer samples
state->s_lu[n] = (short) *state->audio_out_float_buf_p;
state->audio_out_buf_p++;
state->audio_out_float_buf_p++;
}
@@ -215,6 +221,10 @@ processAudio (dsd_opts * opts, dsd_state * state)
*state->audio_out_temp_buf_p = -32768.0F;
}
*state->audio_out_buf_p = (short) *state->audio_out_temp_buf_p;
//tap the pointer here and store the short buffer samples
state->s_l[n] = (short) *state->audio_out_temp_buf_p;
//debug
// fprintf (stderr, " %d", state->s_l[n]);
state->audio_out_buf_p++;
state->audio_out_temp_buf_p++;
state->audio_out_idx++;
@@ -339,6 +349,8 @@ processAudioR (dsd_opts * opts, dsd_state * state)
*state->audio_out_float_buf_pR = -32768.0F;
}
*state->audio_out_buf_pR = (short) *state->audio_out_float_buf_pR;
//tap the pointer here and store the short upsample buffer samples
state->s_ru[n] = (short) *state->audio_out_float_buf_pR;
state->audio_out_buf_pR++;
state->audio_out_float_buf_pR++;
}
@@ -357,6 +369,8 @@ processAudioR (dsd_opts * opts, dsd_state * state)
*state->audio_out_temp_buf_pR = -32768.0F;
}
*state->audio_out_buf_pR = (short) *state->audio_out_temp_buf_pR;
//tap the pointer here and store the short buffer samples
state->s_r[n] = (short) *state->audio_out_temp_buf_pR;
state->audio_out_buf_pR++;
state->audio_out_temp_buf_pR++;
state->audio_out_idxR++;

1450
src/dsd_audio2.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -101,6 +101,14 @@ void
noCarrier (dsd_opts * opts, dsd_state * state)
{
//is this not being set properly?
if (opts->floating_point == 1)
{
//test for WIP auto gain, disable later if needbe
state->aout_gain = 25.0f;
state->aout_gainR = 25.0f;
}
//clear heuristics from last carrier signal
if (opts->frame_p25p1 == 1 && opts->use_heuristics == 1)
{
@@ -286,17 +294,18 @@ noCarrier (dsd_opts * opts, dsd_state * state)
sprintf (state->slot1light, "%s", "");
sprintf (state->slot2light, "%s", "");
state->firstframe = 0;
if (opts->audio_gain == (float) 0)
{
if (state->audio_smoothing == 0) state->aout_gain = 15; //15
else state->aout_gain = 25; //25
}
//this really isn't the best placement for this sort of check
// if (opts->audio_gain == (float) 0)
// {
// if (state->audio_smoothing == 0) state->aout_gain = 15; //15
// else state->aout_gain = 25; //25
// }
if (opts->audio_gainR == (float) 0)
{
if (state->audio_smoothing == 0) state->aout_gainR = 15; //15
else state->aout_gainR = 25; //25
}
// if (opts->audio_gainR == (float) 0)
// {
// if (state->audio_smoothing == 0) state->aout_gainR = 15; //15
// else state->aout_gainR = 25; //25
// }
memset (state->aout_max_buf, 0, sizeof (float) * 200);
state->aout_max_buf_p = state->aout_max_buf;
state->aout_max_buf_idx = 0;
@@ -485,12 +494,35 @@ noCarrier (dsd_opts * opts, dsd_state * state)
state->m17_enc_st = 0;
memset(state->m17_meta, 0, sizeof(state->m17_meta));
//set float temp buffer to baseline
memset (state->audio_out_temp_buf, 0.1f, sizeof(state->audio_out_temp_buf));
memset (state->audio_out_temp_bufR, 0.1f, sizeof(state->audio_out_temp_bufR));
//set float temp buffer to baseline
memset (state->f_l, 0.1f, sizeof(state->f_l));
memset (state->f_r, 0.1f, sizeof(state->f_r));
//set float temp buffer to baseline
memset (state->f_l4, 0.1f, sizeof(state->f_l4));
memset (state->f_r4, 0.1f, sizeof(state->f_r4));
//zero out the short sample storage buffers
memset (state->s_l, 1, sizeof(state->s_l));
memset (state->s_r, 1, sizeof(state->s_r));
memset (state->s_l4, 1, sizeof(state->s_l4));
memset (state->s_r4, 1, sizeof(state->s_r4));
memset (state->s_lu, 1, sizeof(state->s_lu));
memset (state->s_ru, 1, sizeof(state->s_ru));
memset (state->s_l4u, 1, sizeof(state->s_l4u));
memset (state->s_r4u, 1, sizeof(state->s_r4u));
} //nocarrier
void
initOpts (dsd_opts * opts)
{
opts->floating_point = 0; //use floating point audio output
opts->onesymbol = 10;
opts->mbe_in_file[0] = 0;
opts->mbe_in_f = NULL;
@@ -589,9 +621,9 @@ initOpts (dsd_opts * opts)
opts->rtl_rms = 0; //root means square power level on rtl input signal
//end RTL user options
opts->pulse_raw_rate_in = 48000;
opts->pulse_raw_rate_out = 48000; //
opts->pulse_raw_rate_out = 48000;//
opts->pulse_digi_rate_in = 48000;
opts->pulse_digi_rate_out = 24000; //new default for XDMA
opts->pulse_digi_rate_out = 8000; //
opts->pulse_raw_in_channels = 1;
opts->pulse_raw_out_channels = 1;
opts->pulse_digi_in_channels = 1; //2
@@ -700,7 +732,10 @@ initOpts (dsd_opts * opts)
opts->use_dsp_output = 0;
//Use P25p1 heuristics
opts->use_heuristics = 0;
opts->use_heuristics = 0;
// if (opts->floating_point == 1)
// state->aout_gain = 25.0f;
} //initopts
@@ -724,6 +759,28 @@ initState (dsd_state * state)
//Upsampled Audio Smoothing
state->audio_smoothing = 0;
memset (state->audio_out_temp_buf, 0.1f, sizeof(state->audio_out_temp_buf));
memset (state->audio_out_temp_bufR, 0.1f, sizeof(state->audio_out_temp_bufR));
//set float temp buffer to baseline
memset (state->f_l, 0.1f, sizeof(state->f_l));
memset (state->f_r, 0.1f, sizeof(state->f_r));
//set float temp buffer to baseline
memset (state->f_l4, 0.1f, sizeof(state->f_l4));
memset (state->f_r4, 0.1f, sizeof(state->f_r4));
//zero out the short sample storage buffers
memset (state->s_l, 1, sizeof(state->s_l));
memset (state->s_r, 1, sizeof(state->s_r));
memset (state->s_l4, 1, sizeof(state->s_l4));
memset (state->s_r4, 1, sizeof(state->s_r4));
memset (state->s_lu, 1, sizeof(state->s_lu));
memset (state->s_ru, 1, sizeof(state->s_ru));
memset (state->s_l4u, 1, sizeof(state->s_l4u));
memset (state->s_r4u, 1, sizeof(state->s_r4u));
state->audio_out_buf = malloc (sizeof (short) * 1000000);
state->audio_out_bufR = malloc (sizeof (short) * 1000000);
memset (state->audio_out_buf, 0, 100 * sizeof (short));
@@ -800,8 +857,8 @@ initState (dsd_state * state)
state->firstframe = 0;
sprintf (state->slot1light, "%s", "");
sprintf (state->slot2light, "%s", "");
state->aout_gain = 0;
state->aout_gainR = 0;
state->aout_gain = 15; //was 0
state->aout_gainR = 15; //was 0
memset (state->aout_max_buf, 0, sizeof (float) * 200);
state->aout_max_buf_p = state->aout_max_buf;
state->aout_max_buf_idx = 0;
@@ -1136,7 +1193,7 @@ usage ()
printf (" null for no audio output\n");
printf (" -d <dir> Create mbe data files, use this directory (TDMA version is experimental)\n");
printf (" -r <files> Read/Play saved mbe data from file(s)\n");
printf (" -g <num> Audio output gain (default = 0 = auto, disable = -1)\n");
printf (" -g <float> Audio output gain (default = 0 = auto, disable = -1)\n");
printf (" -w <file> Output synthesized speech to a .wav file, FDMA modes only.\n");
printf (" -7 <dir> Create/Use Custom directory for Per Call decoded .wav file saving.\n");
printf (" (Single Nested Directory Only! Use Before the -P option!)\n");
@@ -1152,6 +1209,7 @@ usage ()
printf (" -V Enable Audio Smoothing on Upsampled 48k/1 or 24k/2 Audio (Capital V)\n");
printf (" (Audio Smoothing is now disabled on all upsampled output by default -- fix crackle/buzz bug)\n");
printf (" -z Set TDMA Voice Slot Preference when using /dev/dsp audio output (prevent lag and stuttering)\n");
printf (" -y Enable Experimental Pulse Audio Float Audio Output\n");
printf ("\n");
printf ("RTL-SDR options:\n");
printf (" Usage: rtl:dev:freq:gain:ppm:bw:sq:udp\n");
@@ -1276,38 +1334,38 @@ void
liveScanner (dsd_opts * opts, dsd_state * state)
{
if (opts->audio_in_type == 1)
{
opts->pulse_digi_rate_out = 48000;
opts->pulse_digi_out_channels = 1;
if (opts->dmr_stereo == 1)
{
opts->pulse_digi_rate_out = 24000;
opts->pulse_digi_out_channels = 2;
fprintf (stderr, "STDIN Audio Rate Out set to 24000 Khz/2 Channel \n");
}
else fprintf (stderr, "STDIN Audio Rate Out set to 48000 Khz/1 Channel \n");
opts->pulse_raw_rate_out = 48000;
opts->pulse_raw_out_channels = 1;
// if (opts->audio_in_type == 1)
// {
// opts->pulse_digi_rate_out = 48000;
// opts->pulse_digi_out_channels = 1;
// if (opts->dmr_stereo == 1)
// {
// opts->pulse_digi_rate_out = 24000;
// opts->pulse_digi_out_channels = 2;
// fprintf (stderr, "STDIN Audio Rate Out set to 24000 Khz/2 Channel \n");
// }
// else fprintf (stderr, "STDIN Audio Rate Out set to 48000 Khz/1 Channel \n");
// opts->pulse_raw_rate_out = 48000;
// opts->pulse_raw_out_channels = 1;
}
// }
#ifdef USE_RTLSDR
if(opts->audio_in_type == 3)
{
//still need this section mostly due the the crackling on the rtl dongle when upsampled
//probably need to dig a little deeper, maybe inlvl releated?
opts->pulse_digi_rate_out = 48000; //revert to 8K/1 for RTL input, random crackling otherwise
opts->pulse_digi_out_channels = 1;
if (opts->dmr_stereo == 1)
{
opts->pulse_digi_rate_out = 24000; //rtl needs 24000 by 2 channel for DMR TDMA Stereo output
opts->pulse_digi_out_channels = 2; //minimal crackling 'may' be observed, not sure, can't test to see on DMR with RTL
// fprintf (stderr, "RTL Audio Rate Out set to 24000 Khz/2 Channel \n");
}
// else fprintf (stderr, "RTL Audio Rate Out set to 48000 Khz/1 Channel \n");
opts->pulse_raw_rate_out = 48000;
opts->pulse_raw_out_channels = 1;
// opts->pulse_digi_rate_out = 48000; //revert to 8K/1 for RTL input, random crackling otherwise
// opts->pulse_digi_out_channels = 1;
// if (opts->dmr_stereo == 1)
// {
// opts->pulse_digi_rate_out = 24000; //rtl needs 24000 by 2 channel for DMR TDMA Stereo output
// opts->pulse_digi_out_channels = 2; //minimal crackling 'may' be observed, not sure, can't test to see on DMR with RTL
// // fprintf (stderr, "RTL Audio Rate Out set to 24000 Khz/2 Channel \n");
// }
// // else fprintf (stderr, "RTL Audio Rate Out set to 48000 Khz/1 Channel \n");
// opts->pulse_raw_rate_out = 48000;
// opts->pulse_raw_out_channels = 1;
open_rtlsdr_stream(opts);
opts->rtl_started = 1; //set here so ncurses terminal doesn't attempt to open it again
@@ -1482,7 +1540,7 @@ main (int argc, char **argv)
exitflag = 0;
while ((c = getopt (argc, argv, "haepPqs:t:v:z:i:o:d:c:g:nw:B:C:R:f:m:u:x:A:S:M:G:D:L:VU:YK:b:H:X:NQ:WrlZTF01:2:345:6:7:89:Ek:")) != -1)
while ((c = getopt (argc, argv, "yhaepPqs:t:v:z:i:o:d:c:g:nw:B:C:R:f:m:u:x:A:S:M:G:D:L:VU:YK:b:H:X:NQ:WrlZTF01:2:345:6:7:89:Ek:")) != -1)
{
opterr = 0;
switch (c)
@@ -1524,6 +1582,13 @@ main (int argc, char **argv)
fprintf (stderr,"DMR Late Entry Encryption Identifiers Disabled (VC6 Single Burst)\n");
break;
case 'y': //use experimental 'float' audio output
opts.floating_point = 1; //enable floating point audio output
opts.audio_gain = 0;
state.aout_gain = 25.0f; //seems like a nonimal value for float during testing anyways
fprintf (stderr,"Enabling Experimental Floating Point Audio Output\n");
break;
case 'Y': //conventional scanner mode
opts.scanner_mode = 1; //enable scanner
opts.p25_trunk = 0; //turn off trunking mode if user enabled it
@@ -1868,7 +1933,7 @@ main (int argc, char **argv)
opts.frame_provoice = 0;
opts.frame_ysf = 1;
opts.frame_m17 = 0;
opts.pulse_digi_rate_out = 48000; // /dev/dsp does need this set to 48000 to properly process the upsampling
opts.pulse_digi_rate_out = 8000;
opts.pulse_digi_out_channels = 1;
opts.dmr_stereo = 0; //switching in 'stereo' for 'mono'
opts.dmr_mono = 1;
@@ -1889,7 +1954,7 @@ main (int argc, char **argv)
opts.frame_provoice = 0;
opts.frame_ysf = 0;
opts.frame_m17 = 0;
opts.pulse_digi_rate_out = 48000;
opts.pulse_digi_rate_out = 8000;
opts.pulse_digi_out_channels = 1;
opts.dmr_stereo = 0;
state.dmr_stereo = 0;
@@ -1911,7 +1976,7 @@ main (int argc, char **argv)
opts.frame_provoice = 0;
opts.frame_ysf = 0;
opts.frame_m17 = 0;
opts.pulse_digi_rate_out = 48000;
opts.pulse_digi_rate_out = 8000;
opts.pulse_digi_out_channels = 1;
opts.dmr_stereo = 0;
opts.dmr_mono = 0;
@@ -1938,7 +2003,7 @@ main (int argc, char **argv)
opts.mod_qpsk = 0;
opts.mod_gfsk = 1;
state.rf_mod = 2;
opts.pulse_digi_rate_out = 48000;
opts.pulse_digi_rate_out = 8000;
opts.pulse_digi_out_channels = 1;
opts.dmr_stereo = 0;
opts.dmr_mono = 0;
@@ -2112,7 +2177,7 @@ main (int argc, char **argv)
opts.dmr_stereo = 1;
opts.dmr_mono = 0;
// opts.setmod_bw = 12000; //safe default on both DMR and P25
opts.pulse_digi_rate_out = 24000;
opts.pulse_digi_rate_out = 8000;
opts.pulse_digi_out_channels = 2;
sprintf (opts.output_name, "XDMA");
fprintf (stderr,"Decoding XDMA P25 and DMR\n");
@@ -2134,7 +2199,7 @@ main (int argc, char **argv)
opts.mod_qpsk = 0;
opts.mod_gfsk = 0;
state.rf_mod = 0;
opts.pulse_digi_rate_out = 48000;
opts.pulse_digi_rate_out = 8000;
opts.pulse_digi_out_channels = 1;
opts.dmr_stereo = 0;
opts.dmr_mono = 0;
@@ -2160,7 +2225,7 @@ main (int argc, char **argv)
opts.mod_qpsk = 0;
opts.mod_gfsk = 0; //
state.rf_mod = 0; //
opts.pulse_digi_rate_out = 24000;
opts.pulse_digi_rate_out = 8000;
opts.pulse_digi_out_channels = 2;
opts.dmr_mono = 0;
opts.dmr_stereo = 1;
@@ -2190,7 +2255,7 @@ main (int argc, char **argv)
opts.mod_qpsk = 0;
opts.mod_gfsk = 0;
state.rf_mod = 0;
opts.pulse_digi_rate_out = 48000;
opts.pulse_digi_rate_out = 8000;
opts.pulse_digi_out_channels = 1;
opts.dmr_stereo = 0;
opts.dmr_mono = 0;
@@ -2519,19 +2584,22 @@ main (int argc, char **argv)
#endif
}
//doesn't work correctly, so just going to reroute to /dev/dsp instead
// if((strncmp(opts.audio_in_dev, "udp", 3) == 0)) //udp socket input from SDR++, GQRX, and others
// {
// fprintf (stderr, "UDP Input not working, falling back to OSS /dev/dsp Audio Input.\n");
// sprintf (opts.audio_in_dev, "%s", "/dev/dsp");
// opts.audio_in_type = 5;
// }
int fmt;
int speed = 48000;
int speed;
//The long of the short is that PADSP can open multiple virtual /dev/dsp devices each with different sampling rates and channel configurations
//but the instance inside of Cygwin is a single instance tied to one sample rate AND one channel configuration, so if you change it on the output, it
//also changes on the input, and the way dsd handles this is to upsample output to make it work correctly, so if we were to make a true short stereo mix,
//we would have to handle upsampling for it as well in Cygwin (alternatively, find another output method, like RTAudio, or something else)
//NOTE: Both /dev/audio AND /dev/dsp randomly open multiple input streams in Linux under padsp wrapper
//It should be noted that Pulse Audio instances do not have this same issue, and can run at different input/rate and output/rate/channel configurations
//TL:DR; the only reason /dev/dsp works as both input and output in Cygwin is because both input and output are exactly 1 channel - 48k
//TODO: Test opening OSS input as 2-channel 48k, and see if we can read it in, if not, then double samplespersymble and center
//doing so will break the filters though
speed = 48000;
if((strncmp(opts.audio_in_dev, "/dev/audio", 10) == 0))
{
sprintf (opts.audio_in_dev, "%s", "/dev/dsp");
@@ -2551,7 +2619,6 @@ main (int argc, char **argv)
if (opts.audio_in_fd == -1)
{
fprintf (stderr, "Error, couldn't open %s\n", opts.audio_in_dev);
opts.audio_out = 0;
}
fmt = 0;
@@ -2578,10 +2645,7 @@ main (int argc, char **argv)
opts.audio_in_type = 5; //5 will become OSS input type
}
//Codec2 only running at 8k output currently, need to match for OSS
if (opts.frame_m17 == 1)
speed = 8000;
//check for OSS output
if((strncmp(opts.audio_out_dev, "/dev/audio", 10) == 0))
{
sprintf (opts.audio_out_dev, "%s", "/dev/dsp");
@@ -2597,8 +2661,7 @@ main (int argc, char **argv)
if((strncmp(opts.audio_out_dev, "/dev/dsp", 8) == 0))
{
fprintf (stderr, "OSS Output %s.\n", opts.audio_out_dev);
opts.audio_out_fd = open (opts.audio_out_dev, O_RDWR); //O_WRONLY
opts.audio_out_fdR = open (opts.audio_out_dev, O_RDWR);
opts.audio_out_fd = open (opts.audio_out_dev, O_RDWR);
if (opts.audio_out_fd == -1)
{
fprintf (stderr, "Error, couldn't open #1 %s\n", opts.audio_out_dev);
@@ -2606,49 +2669,37 @@ main (int argc, char **argv)
exit(1);
}
if (opts.audio_out_fdR == -1)
{
fprintf (stderr, "Error, couldn't open #2 %s\n", opts.audio_out_dev);
opts.audio_out = 0;
exit(1);
}
fmt = 0;
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_RESET) < 0)
{
fprintf (stderr, "ioctl reset error \n");
}
if (ioctl (opts.audio_out_fdR, SNDCTL_DSP_RESET) < 0)
{
fprintf (stderr, "ioctl reset error \n");
}
fmt = speed;
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_SPEED, &fmt) < 0)
{
fprintf (stderr, "ioctl speed error \n");
}
if (ioctl (opts.audio_out_fdR, SNDCTL_DSP_SPEED, &fmt) < 0)
{
fprintf (stderr, "ioctl speed error \n");
}
fmt = 0;
fmt = 0; //this seems okay to be 1 or 0, not sure what the difference really is (works in stereo on 0)
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_STEREO, &fmt) < 0)
{
fprintf (stderr, "ioctl stereo error \n");
}
if (ioctl (opts.audio_out_fdR, SNDCTL_DSP_STEREO, &fmt) < 0)
{
fprintf (stderr, "ioctl stereo error \n");
}
fmt = AFMT_S16_LE;
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
{
fprintf (stderr, "ioctl setfmt error \n");
}
if (ioctl (opts.audio_out_fdR, SNDCTL_DSP_SETFMT, &fmt) < 0)
{
fprintf (stderr, "ioctl setfmt error \n");
}
//setup for one or two-channel configuration -- OSS -- cygwin OSS does not like this at all, even when set to 1
// fmt = opts.pulse_digi_out_channels; //number of channels is also be a problem for Cygwin...
// if (ioctl (opts.audio_out_fd, SNDCTL_DSP_CHANNELS, &fmt) < 0)
// {
// fprintf (stderr, "ioctl channels error \n");
// }
opts.audio_out_type = 5; //5 will become OSS output type
}
@@ -2668,19 +2719,19 @@ main (int argc, char **argv)
opts.audio_out = 0; //turn off so we won't playSynthesized
}
if (opts.playfiles == 1)
if((strncmp(opts.audio_out_dev, "-", 1) == 0))
{
opts.audio_out_fd = fileno(stdout); //STDOUT_FILENO;
opts.audio_out_type = 1; //using 1 for stdout to match input stdin as 1
fprintf(stderr, "Audio Out Device: -\n");
}
if (opts.playfiles == 1) //redo?
{
opts.split = 1;
opts.playoffset = 0;
opts.playoffsetR = 0;
opts.delay = 0;
//open wav file should be handled directly by the -w switch now
// if (strlen(opts.wav_out_file) > 0 && opts.dmr_stereo_wav == 0)
// {
// openWavOutFile (&opts, &state);
// }
opts.pulse_digi_rate_out = 48000;
opts.pulse_digi_out_channels = 1;
if (opts.audio_out_type == 0) openPulseOutput(&opts);
@@ -2709,11 +2760,10 @@ main (int argc, char **argv)
else
{
opts.split = 0;
opts.playoffset = 0; //not sure what the playoffset actually does for us
opts.playoffset = 0;
opts.playoffsetR = 0;
opts.delay = 0;
openAudioInDevice (&opts);
// opts.audio_out_fd = opts.audio_in_fd; //not sure that this really does much anymore, other than cause problems
}
signal(SIGINT, handler);
@@ -2727,6 +2777,8 @@ main (int argc, char **argv)
else
{
//debug
fprintf (stderr, "AIT: %d AOT: %d RATE: %d GAIN: %f \n", opts.audio_in_type, opts.audio_out_type, opts.pulse_digi_rate_out, state.aout_gain);
liveScanner (&opts, &state);
}

View File

@@ -24,11 +24,11 @@ void keyring(dsd_opts * opts, dsd_state * state)
{
UNUSED(opts);
if (state->currentslot == 0)
state->R = state->rkey_array[state->payload_keyid];
if (state->currentslot == 0)
state->R = state->rkey_array[state->payload_keyid];
if (state->currentslot == 1)
state->RR = state->rkey_array[state->payload_keyidR];
if (state->currentslot == 1)
state->RR = state->rkey_array[state->payload_keyidR];
}
void RC4(int drop, uint8_t keylength, uint8_t messagelength, uint8_t key[], uint8_t cipher[], uint8_t plain[])
@@ -528,7 +528,7 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
uint8_t cipher[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t plain[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t rckey[9] = {0x00, 0x00, 0x00, 0x00, 0x00, // <- RC4 Key
0x00, 0x00, 0x00, 0x00}; // <- MI
0x00, 0x00, 0x00, 0x00}; // <- MI
//easier to manually load up rather than make a loop
rckey[0] = ((state->R & 0xFF00000000) >> 32);
@@ -606,8 +606,8 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
uint8_t cipher[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t plain[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t rckey[13] = {0x00, 0x00, 0x00, 0x00, 0x00, // <- RC4 Key
0x00, 0x00, 0x00, 0x00, 0x00, // <- MI
0x00, 0x00, 0x00}; // <- MI cont.
0x00, 0x00, 0x00, 0x00, 0x00, // <- MI
0x00, 0x00, 0x00}; // <- MI cont.
//easier to manually load up rather than make a loop
rckey[0] = ((state->R & 0xFF00000000) >> 32);
@@ -811,21 +811,21 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
//DMR RC4, Slot 2
if (state->currentslot == 1 && state->payload_algidR == 0x21 && state->RR != 0)
{
uint8_t cipher[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t plain[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t rckey[9] = {0x00, 0x00, 0x00, 0x00, 0x00, // <- RC4 Key
0x00, 0x00, 0x00, 0x00}; // <- MI
uint8_t cipher[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t plain[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t rckey[9] = {0x00, 0x00, 0x00, 0x00, 0x00, // <- RC4 Key
0x00, 0x00, 0x00, 0x00}; // <- MI
//easier to manually load up rather than make a loop
rckey[0] = ((state->RR & 0xFF00000000) >> 32);
rckey[1] = ((state->RR & 0xFF000000) >> 24);
rckey[2] = ((state->RR & 0xFF0000) >> 16);
rckey[3] = ((state->RR & 0xFF00) >> 8);
rckey[4] = ((state->RR & 0xFF) >> 0);
rckey[5] = ((state->payload_miR & 0xFF000000) >> 24);
rckey[6] = ((state->payload_miR & 0xFF0000) >> 16);
rckey[7] = ((state->payload_miR & 0xFF00) >> 8);
rckey[8] = ((state->payload_miR & 0xFF) >> 0);
//easier to manually load up rather than make a loop
rckey[0] = ((state->RR & 0xFF00000000) >> 32);
rckey[1] = ((state->RR & 0xFF000000) >> 24);
rckey[2] = ((state->RR & 0xFF0000) >> 16);
rckey[3] = ((state->RR & 0xFF00) >> 8);
rckey[4] = ((state->RR & 0xFF) >> 0);
rckey[5] = ((state->payload_miR & 0xFF000000) >> 24);
rckey[6] = ((state->payload_miR & 0xFF0000) >> 16);
rckey[7] = ((state->payload_miR & 0xFF00) >> 8);
rckey[8] = ((state->payload_miR & 0xFF) >> 0);
// if (opts->payload == 1)
// {
@@ -891,8 +891,8 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
uint8_t cipher[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t plain[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t rckey[13] = {0x00, 0x00, 0x00, 0x00, 0x00, // <- RC4 Key
0x00, 0x00, 0x00, 0x00, 0x00, // <- MI
0x00, 0x00, 0x00}; // <- MI cont.
0x00, 0x00, 0x00, 0x00, 0x00, // <- MI
0x00, 0x00, 0x00}; // <- MI cont.
//easier to manually load up rather than make a loop
rckey[0] = ((state->RR & 0xFF00000000) >> 32);
@@ -1047,30 +1047,35 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
}
//end reverse mute test
#ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
//OSS Specific Voice Preemption if dual voices on TDMA and one slot has preference over the other
if (opts->slot_preference == 1 && opts->audio_out_type == 5 && opts->audio_out == 1 && (state->dmrburstR == 16 || state->dmrburstR == 21) )
{
opts->audio_out = 0;
preempt = 1;
if (opts->payload == 0)
fprintf (stderr, " *MUTED*");
}
#endif
//No more Slot Pre-emption...ever
// #ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
// //OSS Specific Voice Preemption if dual voices on TDMA and one slot has preference over the other
// if (opts->slot_preference == 1 && opts->audio_out_type == 5 && opts->audio_out == 1 && (state->dmrburstR == 16 || state->dmrburstR == 21) )
// {
// opts->audio_out = 0;
// preempt = 1;
// if (opts->payload == 0)
// fprintf (stderr, " *MUTED*");
// }
// #endif
state->debug_audio_errors += state->errs2 + state->errs;
if (state->dmr_encL == 0 || opts->dmr_mute_encL == 0)
{
if (opts->audio_out == 1)
if (opts->audio_out == 1 && opts->floating_point == 0 ) //&& opts->pulse_digi_rate_out == 8000
{
processAudio(opts, state);
}
if (opts->audio_out == 1)
{
playSynthesizedVoice (opts, state);
}
// if (opts->audio_out == 1)
// {
// playSynthesizedVoice (opts, state);
// }
}
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
}
if (opts->dmr_stereo == 1 && state->currentslot == 1)
@@ -1118,46 +1123,55 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
}
//end reverse mute test
#ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
//OSS Specific Voice Preemption if dual voices on TDMA and one slot has preference over the other
if (opts->slot_preference == 0 && opts->audio_out_type == 5 && opts->audio_out == 1 && (state->dmrburstL == 16 || state->dmrburstL == 21) )
{
opts->audio_out = 0;
preempt = 1;
if (opts->payload == 0)
fprintf (stderr, " *MUTED*");
}
#endif
// #ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
// //OSS Specific Voice Preemption if dual voices on TDMA and one slot has preference over the other
// if (opts->slot_preference == 0 && opts->audio_out_type == 5 && opts->audio_out == 1 && (state->dmrburstL == 16 || state->dmrburstL == 21) )
// {
// opts->audio_out = 0;
// preempt = 1;
// if (opts->payload == 0)
// fprintf (stderr, " *MUTED*");
// }
// #endif
state->debug_audio_errorsR += state->errs2R + state->errsR;
if (state->dmr_encR == 0 || opts->dmr_mute_encR == 0)
{
if (opts->audio_out == 1)
if (opts->audio_out == 1 && opts->floating_point == 0 ) //&& opts->pulse_digi_rate_out == 8000
{
processAudioR(opts, state);
}
if (opts->audio_out == 1)
{
playSynthesizedVoiceR (opts, state);
}
// if (opts->audio_out == 1)
// {
// playSynthesizedVoiceR (opts, state);
// }
}
memcpy (state->f_r, state->audio_out_temp_bufR, sizeof(state->f_r));
// playSynthesizedVoiceFR (opts, state); //Float Right
}
//if using anything but DMR Stereo, borrowing state->dmr_encL to signal enc or clear for other types
if (opts->dmr_mono == 0 && opts->dmr_stereo == 0 && (opts->unmute_encrypted_p25 == 1 || state->dmr_encL == 0) )
{
state->debug_audio_errors += state->errs2 + state->errs;
if (opts->audio_out == 1)
if (opts->audio_out == 1 && opts->floating_point == 0 ) //&& opts->pulse_digi_rate_out == 8000
{
processAudio(opts, state);
}
if (opts->audio_out == 1)
{
playSynthesizedVoice (opts, state);
}
// if (opts->audio_out == 1)
// {
// 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

@@ -9,6 +9,8 @@
* 2022-08 DSD-FME Florida Man Edition
*-----------------------------------------------------------------------------*/
//TODO: Simulate Tone by playing AMBE FF32D2D2D2D880 x 4 on call alert (NXDN Foreign Lady Chirp on End)
#include "dsd.h"
#include "git_ver.h"
@@ -2251,10 +2253,10 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (i == 5) printw (" %s ", "Aero Build");
if (i == 6) printw (" v2.1c (20230720) \n");
#elif ZDEV_BUILD
if (i == 5) printw (" %s ", "zDEV3 Build");
if (i == 5) printw (" %s ", "Audio WIP ");
if (i == 6) printw (" %s \n", GIT_TAG);
#else
if (i == 5) printw (" %s ", "zDEV3 Build");
if (i == 5) printw (" %s ", "Audio WIP");
if (i == 6) printw (" %s \n", GIT_TAG);
#endif
else printw ("\n");
@@ -2269,11 +2271,11 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
printw ("--Input Output----------------------------------------------------------------\n");
if (opts->audio_in_type == 0)
{
printw ("| Pulse Audio Input: [%2i] kHz [%i] Channel\n", opts->pulse_digi_rate_in/1000, opts->pulse_digi_in_channels);
printw ("| Pulse Audio Input: %i kHz; %i Channel;\n", opts->pulse_digi_rate_in/1000, opts->pulse_digi_in_channels);
}
if (opts->audio_in_type == 5)
{
printw ("| OSS Audio Input: [%2i] kHz [1] Channel\n", SAMPLE_RATE_IN/1000);
printw ("| OSS Audio Input: %i kHz; 1 Channel;\n", SAMPLE_RATE_IN/1000);
}
if (opts->audio_in_type == 4)
{
@@ -2311,14 +2313,17 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
}
if (opts->audio_out_type == 0)
{
printw ("| Pulse Audio Output: [%2i] kHz [%i] Channel", opts->pulse_digi_rate_out/1000, opts->pulse_digi_out_channels);
if (state->audio_smoothing == 1) printw (" - Smoothing On");
printw ("| Pulse Audio Output: %i kHz; %i Channel; Auto Gain: %.1f;", opts->pulse_digi_rate_out/1000, opts->pulse_digi_out_channels, state->aout_gain*2);
if (state->audio_smoothing == 1 && opts->floating_point == 0) printw (" Smoothing On;"); //only on short
if (opts->floating_point == 1) printw (" Floating Point;");
printw (" \n");
}
if (opts->audio_out_type == 5)
{
printw ("| OSS Audio Output: [%2i] kHz [1] Channel", SAMPLE_RATE_OUT/1000);
if (state->audio_smoothing == 1) printw (" - Smoothing On");
printw ("| OSS Audio Output: %i kHz; %d Channel; Auto Gain %.1f;", SAMPLE_RATE_OUT/1000, opts->pulse_digi_out_channels, state->aout_gain*2);
if (state->audio_smoothing == 1 && opts->floating_point == 0) printw (" Smoothing On;"); //nly on short
if (opts->floating_point == 1) printw (" Floating Point;");
printw (" \n");
}
if (opts->monitor_input_audio == 1)
@@ -2784,7 +2789,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
}
else if (lls == 0 || lls == 1) //P1
{
printw ("P25 P1 - [%05llX][%03llX][%03llX] RFSS: [%lld] SITE: [%lld] ", state->p2_wacn, state->p2_sysid, state->p2_cc, state->p2_rfssid, state->p2_siteid);
printw ("P25p1 - [%05llX][%03llX][%03llX] RFSS: [%lld] SITE: [%lld] ", state->p2_wacn, state->p2_sysid, state->p2_cc, state->p2_rfssid, state->p2_siteid);
if (state->p25_cc_freq != 0)
{
printw ("Freq: %.06lf MHz", (double)state->p25_cc_freq/1000000);
@@ -2792,7 +2797,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
}
else if (lls == 35 || lls == 36) //P2
{
printw ("P25 P2 - [%05llX][%03llX][%03llX] RFSS: [%lld] SITE: [%lld] ", state->p2_wacn, state->p2_sysid, state->p2_cc, state->p2_rfssid, state->p2_siteid);
printw ("P25p2 - [%05llX][%03llX][%03llX] RFSS: [%lld] SITE: [%lld] ", state->p2_wacn, state->p2_sysid, state->p2_cc, state->p2_rfssid, state->p2_siteid);
if (state->p2_wacn == 0 || state->p2_sysid == 0 || state->p2_cc == 0)
{
attron(COLOR_PAIR(2));
@@ -2834,11 +2839,11 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
printw ("%s | ", state->call_string[0]);
printw ("%s ", DMRBusrtTypes[state->dmrburstL]);
#ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
//
if (opts->slot_preference == 1 && opts->audio_out_type == 5 && opts->audio_out == 1 && ( state->dmrburstL == 16 || state->dmrburstL == 21) && (state->dmrburstR == 16 || state->dmrburstR == 21)) printw ("*M*");
//
#endif
// #ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
// //
// if (opts->slot_preference == 1 && opts->audio_out_type == 5 && opts->audio_out == 1 && ( state->dmrburstL == 16 || state->dmrburstL == 21) && (state->dmrburstR == 16 || state->dmrburstR == 21)) printw ("*M*");
// //
// #endif
printw ("\n");
@@ -3037,11 +3042,11 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
//THIS IS THE NEW ONE
printw ("%s | ", state->call_string[1]);
printw ("%s ", DMRBusrtTypes[state->dmrburstR]);
#ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
//
if (opts->slot_preference == 0 && opts->audio_out_type == 5 && opts->audio_out == 1 && ( state->dmrburstL == 16 || state->dmrburstL == 21) && (state->dmrburstR == 16 || state->dmrburstR == 21) ) printw ("*M*");
//
#endif
// #ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
// //
// if (opts->slot_preference == 0 && opts->audio_out_type == 5 && opts->audio_out == 1 && ( state->dmrburstL == 16 || state->dmrburstL == 21) && (state->dmrburstR == 16 || state->dmrburstR == 21) ) printw ("*M*");
// //
// #endif
printw ("\n");
printw ("| V XTRA | "); //10 spaces
@@ -3484,6 +3489,24 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
ncursesMenu (opts, state); //just a quick test
}
if (c == 43) //+ key, increment aout_gain
{
if (state->aout_gain < 50)
state->aout_gain++;
//probably won't use aout_gainR with new short and float systems
if (state->aout_gainR < 50)
state->aout_gainR++;
}
if (c == 45) //- key, decrement aout_gain
{
if (state->aout_gain > 0)
state->aout_gain--;
//probably won't use aout_gainR with new short and float systems
if (state->aout_gainR > 0)
state->aout_gainR--;
}
if (c == 122) //'z' key, toggle payload to console
{
if (opts->payload == 1) opts->payload = 0;

View File

@@ -279,4 +279,44 @@ void rtl_udp_tune(dsd_opts * opts, dsd_state * state, long int frequency)
sendto(handle, data, 5, 0, (const struct sockaddr * ) & address, sizeof(struct sockaddr_in));
close (handle); //close socket after sending.
}
}
// int udp_sock_con(dsd_opts * opts, dsd_state * state)
// {
// UNUSED(state);
// UNUSED(opts);
// int handle, err; //convert handle and address to state variables
// handle = err = 0;
// unsigned short udp_port = 9999;
// struct sockaddr_in address;
// handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
// if (handle != 0)
// {
// fprintf (stderr, " UDP Socket Error \n");
// return (handle);
// }
// memset((char * ) & address, 0, sizeof(address));
// address.sin_family = AF_INET;
// err = address.sin_addr.s_addr = inet_addr("127.0.0.1"); //make user configurable later
// if (err != 0)
// {
// fprintf (stderr, " UDP inet_addr Error \n");
// return (err);
// }
// address.sin_port = htons(udp_port);
// if (err != 0)
// {
// fprintf (stderr, " UDP htons Error \n");
// return (err);
// }
// // close (handle); //close socket after sending. //leave open for the blaster
// }
// int udp_sock_send(dsd_opts * opts, dsd_state * state, short samp[320])
// {
// UNUSED(state);
// UNUSED(opts);
// sendto(handle, samp, 320, 0, (const struct sockaddr * ) & address, sizeof(struct sockaddr_in));
// }

259
src/dsd_upsample2.c Normal file
View File

@@ -0,0 +1,259 @@
#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
}

304
src/m17.c
View File

@@ -204,9 +204,8 @@ int M17processLICH(dsd_state * state, dsd_opts * opts, uint8_t lich_bits[96])
uint8_t temp[96];
bool g[4];
//for testing bit arrangement vs the crc code
uint8_t bs[240];
memset(bs, 1, sizeof(bs));
uint8_t lich_counter = 0;
uint8_t lich_reserve = 0;
uint16_t crc_cmp = 0;
uint16_t crc_ext = 0;
@@ -228,12 +227,12 @@ int M17processLICH(dsd_state * state, dsd_opts * opts, uint8_t lich_bits[96])
if(g[i] == FALSE) err = -1;
for (j = 0; j < 12; j++)
lich_decoded[i*12+j] = lich[i][j];
lich_decoded[i*12+j] = lich[i][j];
}
uint8_t lich_counter = (uint8_t)ConvertBitIntoBytes(&lich_decoded[40], 3); //lich_cunt
uint8_t lich_reserve = (uint8_t)ConvertBitIntoBytes(&lich_decoded[43], 5); //lich_reserved
lich_counter = (uint8_t)ConvertBitIntoBytes(&lich_decoded[40], 3); //lich_cnt
lich_reserve = (uint8_t)ConvertBitIntoBytes(&lich_decoded[43], 5); //lich_reserved
if (err == 0)
fprintf (stderr, "LC: %d/6 ", lich_counter+1);
@@ -291,14 +290,186 @@ int M17processLICH(dsd_state * state, dsd_opts * opts, uint8_t lich_bits[96])
return err;
}
// void M17processCodec2_1600(dsd_opts * opts, dsd_state * state, uint8_t payload[128])
// {
// int i;
// unsigned char voice1[8];
// unsigned char voice2[8];
// for (i = 0; i < 8; i++)
// {
// voice1[i] = (unsigned char)ConvertBitIntoBytes(&payload[i*8+0], 8);
// voice2[i] = (unsigned char)ConvertBitIntoBytes(&payload[i*8+64], 8);
// }
// //TODO: Add some decryption methods
// if (state->m17_enc != 0)
// {
// //process scrambler or AES-CTR decryption
// //(no AES-CTR right now, Scrambler should be easy enough)
// }
// if (opts->payload == 1)
// {
// fprintf (stderr, "\n CODEC2: ");
// for (i = 0; i < 8; i++)
// fprintf (stderr, "%02X", voice1[i]);
// fprintf (stderr, " (1600)");
// fprintf (stderr, "\n A_DATA: "); //arbitrary data
// for (i = 0; i < 8; i++)
// fprintf (stderr, "%02X", voice2[i]);
// }
// #ifdef USE_CODEC2
// size_t nsam;
// nsam = 320;
// short samp1[nsam];
// memset (samp1, 0, sizeof(samp1));
// codec2_decode(state->codec2_1600, samp1, voice1);
// if (opts->audio_out_type == 0 && state->m17_enc == 0) //Pulse Audio
// {
// pa_simple_write(opts->pulse_digi_dev_out, samp1, nsam*2, NULL);
// }
// if (opts->audio_out_type == 5 && state->m17_enc == 0) //OSS
// {
// write (opts->audio_out_fd, samp1, nsam*2);
// }
// if (opts->audio_out_type == 1 && state->m17_enc == 0) //STDOUT
// {
// write (opts->audio_out_fd, samp1, nsam*2);
// }
// //WIP: Wav file saving -- still need a way to open/close/label wav files similar to call history
// if(opts->wav_out_f != NULL && state->m17_enc == 0) //WAV
// {
// sf_write_short(opts->wav_out_f, samp1, nsam);
// }
// //TODO: Codec2 Raw file saving
// // if(mbe_out_dir)
// // {
// // }
// #endif
// }
// void M17processCodec2_3200(dsd_opts * opts, dsd_state * state, uint8_t payload[128])
// {
// int i;
// unsigned char voice1[8];
// unsigned char voice2[8];
// for (i = 0; i < 8; i++)
// {
// voice1[i] = (unsigned char)ConvertBitIntoBytes(&payload[i*8+0], 8);
// voice2[i] = (unsigned char)ConvertBitIntoBytes(&payload[i*8+64], 8);
// }
// //TODO: Add some decryption methods
// if (state->m17_enc != 0)
// {
// //process scrambler or AES-CTR decryption
// //(no AES-CTR right now, Scrambler should be easy enough)
// }
// if (opts->payload == 1)
// {
// fprintf (stderr, "\n CODEC2: ");
// for (i = 0; i < 8; i++)
// fprintf (stderr, "%02X", voice1[i]);
// fprintf (stderr, " (3200)");
// fprintf (stderr, "\n CODEC2: ");
// for (i = 0; i < 8; i++)
// fprintf (stderr, "%02X", voice2[i]);
// fprintf (stderr, " (3200)");
// }
// #ifdef USE_CODEC2
// size_t nsam;
// nsam = 160;
// short samp1[nsam];
// short samp2[nsam];
// memset (samp1, 0, sizeof(samp1));
// memset (samp2, 0, sizeof(samp2));
// short upsamp[nsam*6]; //having more than one causes a memory overflow issue
// // short upsamp3[nsam*6]; //having more than one causes a memory overflow issue
// short out[6];
// short prev;
// int j;
// memset (upsamp, 0, sizeof(upsamp));
// memset (out, 0, sizeof(out));
// //Still thinking codec2_decode causes a memory overflow
// codec2_decode(state->codec2_3200, samp1, voice1);
// codec2_decode(state->codec2_3200, samp2, voice2);
// if (opts->audio_out_type == 0 && state->m17_enc == 0) //Pulse Audio
// {
// pa_simple_write(opts->pulse_digi_dev_out, samp1, nsam*2, NULL);
// pa_simple_write(opts->pulse_digi_dev_out, samp2, nsam*2, NULL);
// }
// if (opts->audio_out_type == 5 && state->m17_enc == 0) //OSS
// {
// // write (opts->audio_out_fd, samp1, nsam*2);
// // write (opts->audio_out_fd, samp2, nsam*2);
// //upsample to 48k and then play
// prev = samp1[0];
// for (i = 0; i < 160; i++)
// {
// upsampleS (samp1[i], prev, out);
// for (j = 0; j < 6; j++) upsamp[(i*6)+j] = out[j];
// }
// write (opts->audio_out_fd, upsamp, nsam*2*6);
// prev = samp2[0];
// for (i = 0; i < 160; i++)
// {
// upsampleS (samp2[i], prev, out);
// for (j = 0; j < 6; j++) upsamp[(i*6)+j] = out[j];
// }
// write (opts->audio_out_fd, upsamp, nsam*2*6);
// }
// if (opts->audio_out_type == 1 && state->m17_enc == 0) //STDOUT
// {
// write (opts->audio_out_fd, samp1, nsam*2);
// write (opts->audio_out_fd, samp2, nsam*2);
// }
// //WIP: Wav file saving -- still need a way to open/close/label wav files similar to call history
// if(opts->wav_out_f != NULL && state->m17_enc == 0) //WAV
// {
// sf_write_short(opts->wav_out_f, samp1, nsam);
// sf_write_short(opts->wav_out_f, samp2, nsam);
// }
// //TODO: Codec2 Raw file saving
// // if(mbe_out_dir)
// // {
// // }
// #endif
// }
void M17processCodec2_1600(dsd_opts * opts, dsd_state * state, uint8_t payload[128])
{
//If payload is the same from the stream in this mode, I suppose we could use this area to parse
//or send off the remaining data to be handled or decoded , or just print out the raw data bytes
int i;
unsigned char voice1[8]; //codec2_bytes_per_frame
unsigned char voice1[8];
unsigned char voice2[8];
for (i = 0; i < 8; i++)
@@ -321,42 +492,53 @@ void M17processCodec2_1600(dsd_opts * opts, dsd_state * state, uint8_t payload[1
fprintf (stderr, "%02X", voice1[i]);
fprintf (stderr, " (1600)");
fprintf (stderr, "\n LSDATA: "); //low speed data
fprintf (stderr, "\n A_DATA: "); //arbitrary data
for (i = 0; i < 8; i++)
fprintf (stderr, "%02X", voice2[i]);
}
#ifdef USE_CODEC2
size_t nsam;
nsam = 320; //codec2_samples_per_frame(state->codec2_1600);
short samp1[nsam];
// short samp2[nsam];
memset (samp1, 0, sizeof(samp1));
// memset (samp2, 0, sizeof(samp2));
nsam = 320;
//converted to using allocated memory pointers to prevent the overflow issues
short * samp1 = malloc (sizeof(short) * nsam);
short * upsamp = malloc (sizeof(short) * nsam * 6);
short * out = malloc (sizeof(short) * 6);
short prev;
int j;
codec2_decode(state->codec2_1600, samp1, voice1);
// codec2_decode(state->codec2_1600, samp2, voice2);
if (opts->audio_out_type == 0 && state->m17_enc == 0)
if (opts->audio_out_type == 0 && state->m17_enc == 0) //Pulse Audio
{
pa_simple_write(opts->pulse_digi_dev_out, samp1, nsam*2, NULL);
// pa_simple_write(opts->pulse_digi_dev_out, samp2, nsam*2, NULL);
}
if (opts->audio_out_type == 5 && state->m17_enc == 0)
if (opts->audio_out_type == 5 && state->m17_enc == 0) //OSS
{
// write (opts->audio_out_fd, samp1, nsam*2);
//upsample to 48k and then play
prev = samp1[0];
for (i = 0; i < 160; i++)
{
upsampleS (samp1[i], prev, out);
for (j = 0; j < 6; j++) upsamp[(i*6)+j] = out[j];
}
write (opts->audio_out_fd, upsamp, nsam*2*6);
}
if (opts->audio_out_type == 1 && state->m17_enc == 0) //STDOUT
{
write (opts->audio_out_fd, samp1, nsam*2);
// write (opts->audio_out_fd, samp2, nsam*2);
}
//WIP: Wav file saving -- still need a way to open/close/label wav files similar to call history
if(opts->wav_out_f != NULL && state->m17_enc == 0)
if(opts->wav_out_f != NULL && state->m17_enc == 0) //WAV
{
sf_write_short(opts->wav_out_f, samp1, nsam);
// sf_write_short(opts->wav_out_f, samp2, nsam);
}
//TODO: Codec2 Raw file saving
@@ -365,6 +547,10 @@ void M17processCodec2_1600(dsd_opts * opts, dsd_state * state, uint8_t payload[1
// }
free (samp1);
free (upsamp);
free (out);
#endif
}
@@ -372,7 +558,7 @@ void M17processCodec2_1600(dsd_opts * opts, dsd_state * state, uint8_t payload[1
void M17processCodec2_3200(dsd_opts * opts, dsd_state * state, uint8_t payload[128])
{
int i;
unsigned char voice1[8]; //codec2_bytes_per_frame
unsigned char voice1[8];
unsigned char voice2[8];
for (i = 0; i < 8; i++)
@@ -403,32 +589,55 @@ void M17processCodec2_3200(dsd_opts * opts, dsd_state * state, uint8_t payload[1
#ifdef USE_CODEC2
size_t nsam;
nsam = 160; //codec2_samples_per_frame(state->codec2_3200);
short samp1[nsam];
short samp2[nsam];
memset (samp1, 0, sizeof(samp1));
memset (samp2, 0, sizeof(samp2));
nsam = 160;
//converted to using allocated memory pointers to prevent the overflow issues
short * samp1 = malloc (sizeof(short) * nsam);
short * samp2 = malloc (sizeof(short) * nsam);
short * upsamp = malloc (sizeof(short) * nsam * 6);
short * out = malloc (sizeof(short) * 6);
short prev;
int j;
codec2_decode(state->codec2_3200, samp1, voice1);
codec2_decode(state->codec2_3200, samp2, voice2);
if (opts->audio_out_type == 0 && state->m17_enc == 0)
if (opts->audio_out_type == 0 && state->m17_enc == 0) //Pulse Audio
{
pa_simple_write(opts->pulse_digi_dev_out, samp1, nsam*2, NULL);
pa_simple_write(opts->pulse_digi_dev_out, samp2, nsam*2, NULL);
}
if (opts->audio_out_type == 5 && state->m17_enc == 0)
if (opts->audio_out_type == 5 && state->m17_enc == 0) //OSS
{
// write (opts->audio_out_fd, samp1, nsam*2);
// write (opts->audio_out_fd, samp2, nsam*2);
//upsample to 48k and then play
prev = samp1[0];
for (i = 0; i < 160; i++)
{
upsampleS (samp1[i], prev, out);
for (j = 0; j < 6; j++) upsamp[(i*6)+j] = out[j];
}
write (opts->audio_out_fd, upsamp, nsam*2*6);
prev = samp2[0];
for (i = 0; i < 160; i++)
{
upsampleS (samp2[i], prev, out);
for (j = 0; j < 6; j++) upsamp[(i*6)+j] = out[j];
}
write (opts->audio_out_fd, upsamp, nsam*2*6);
}
if (opts->audio_out_type == 1 && state->m17_enc == 0) //STDOUT
{
write (opts->audio_out_fd, samp1, nsam*2);
write (opts->audio_out_fd, samp2, nsam*2);
}
//WIP: Wav file saving -- still need a way to open/close/label wav files similar to call history
if(opts->wav_out_f != NULL && state->m17_enc == 0)
if(opts->wav_out_f != NULL && state->m17_enc == 0) //WAV
{
sf_write_short(opts->wav_out_f, samp1, nsam);
sf_write_short(opts->wav_out_f, samp2, nsam);
@@ -440,6 +649,11 @@ void M17processCodec2_3200(dsd_opts * opts, dsd_state * state, uint8_t payload[1
// }
free (samp1);
free (samp2);
free (upsamp);
free (out);
#endif
}
@@ -618,11 +832,11 @@ void processM17LSF(dsd_opts * opts, dsd_state * state)
//NOTE2: Even with the preamble detection and LSF sync, we still get bad decode on this
int i, j, k, x;
uint8_t dbuf[384]; //384-bit frame - 16-bit (8 symbol) sync pattern (184 dibits)
uint8_t m17_rnd_bits[500]; //368 bits that are still scrambled (randomized)
uint8_t m17_int_bits[500]; //368 bits that are still interleaved
uint8_t m17_bits[500]; //368 bits that have been de-interleaved and de-scramble
uint8_t m17_depunc[500]; //488 bits after depuncturing
uint8_t dbuf[184]; //384-bit frame - 16-bit (8 symbol) sync pattern (184 dibits)
uint8_t m17_rnd_bits[368]; //368 bits that are still scrambled (randomized)
uint8_t m17_int_bits[368]; //368 bits that are still interleaved
uint8_t m17_bits[368]; //368 bits that have been de-interleaved and de-scramble
uint8_t m17_depunc[488]; //488 bits after depuncturing
memset (dbuf, 0, sizeof(dbuf));
memset (m17_rnd_bits, 0, sizeof(m17_rnd_bits));
@@ -659,7 +873,7 @@ void processM17LSF(dsd_opts * opts, dsd_state * state)
for (i = 0; i < 488; i++)
{
if (p1[k++] == 1) m17_depunc[x++] = m17_bits[j++];
else m17_depunc[x++] = 1;
else m17_depunc[x++] = 0;
if (k == 61) k = 0; //61 -- should reset 8 times againt the array
@@ -669,11 +883,11 @@ void processM17LSF(dsd_opts * opts, dsd_state * state)
// fprintf (stderr, "K = %d; J = %d; X = %d", k, j, x);
//setup the convolutional decoder
uint8_t temp[500];
uint8_t temp[488];
uint8_t s0;
uint8_t s1;
uint8_t m_data[32];
uint8_t trellis_buf[400];
uint8_t m_data[30];
uint8_t trellis_buf[244];
memset (trellis_buf, 0, sizeof(trellis_buf));
memset (temp, 0, sizeof (temp));
memset (m_data, 0, sizeof (m_data));

View File

@@ -89,6 +89,13 @@ void nxdn_voice (dsd_opts * opts, dsd_state * state, int voice, uint8_t dbuf[182
}
processMbeFrame (opts, state, NULL, ambe_fr, NULL);
memcpy (state->f_l, state->audio_out_temp_buf, sizeof(state->f_l));
if (opts->floating_point == 0)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 1)
playSynthesizedVoiceFM(opts, state);
}
if (opts->payload == 1)

View File

@@ -59,12 +59,29 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
state->debug_prefix_2 = '0';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
// IMBE 2
#ifdef TRACE_DSD
state->debug_prefix_2 = '1';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
// Read data after IMBE 2
read_and_correct_hex_word (opts, state, &(hex_data[11][0]), &status_count, analog_signal_array, &analog_signal_index);
read_and_correct_hex_word (opts, state, &(hex_data[10][0]), &status_count, analog_signal_array, &analog_signal_index);
@@ -77,6 +94,15 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
state->debug_prefix_2 = '2';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
// Read data after IMBE 3
read_and_correct_hex_word (opts, state, &(hex_data[ 7][0]), &status_count, analog_signal_array, &analog_signal_index);
read_and_correct_hex_word (opts, state, &(hex_data[ 6][0]), &status_count, analog_signal_array, &analog_signal_index);
@@ -89,6 +115,15 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
state->debug_prefix_2 = '3';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
// Read data after IMBE 4
read_and_correct_hex_word (opts, state, &(hex_data[ 3][0]), &status_count, analog_signal_array, &analog_signal_index);
read_and_correct_hex_word (opts, state, &(hex_data[ 2][0]), &status_count, analog_signal_array, &analog_signal_index);
@@ -101,6 +136,15 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
state->debug_prefix_2 = '4';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
// Read data after IMBE 5
read_and_correct_hex_word (opts, state, &(hex_parity[11][0]), &status_count, analog_signal_array, &analog_signal_index);
read_and_correct_hex_word (opts, state, &(hex_parity[10][0]), &status_count, analog_signal_array, &analog_signal_index);
@@ -113,6 +157,15 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
state->debug_prefix_2 = '5';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
// Read data after IMBE 6
read_and_correct_hex_word (opts, state, &(hex_parity[ 7][0]), &status_count, analog_signal_array, &analog_signal_index);
read_and_correct_hex_word (opts, state, &(hex_parity[ 6][0]), &status_count, analog_signal_array, &analog_signal_index);
@@ -125,6 +178,15 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
state->debug_prefix_2 = '6';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
// Read data after IMBE 7
read_and_correct_hex_word (opts, state, &(hex_parity[ 3][0]), &status_count, analog_signal_array, &analog_signal_index);
read_and_correct_hex_word (opts, state, &(hex_parity[ 2][0]), &status_count, analog_signal_array, &analog_signal_index);
@@ -137,6 +199,14 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
state->debug_prefix_2 = '7';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
// Read data after IMBE 8: LSD (low speed data)
{
@@ -180,6 +250,14 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
state->debug_prefix_2 = '8';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
if (opts->errorbars == 1)
{

View File

@@ -63,12 +63,29 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
state->debug_prefix_2 = '0';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
// IMBE 2
#ifdef TRACE_DSD
state->debug_prefix_2 = '1';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
// Read data after IMBE 2
read_and_correct_hex_word (opts, state, &(hex_data[15][0]), &status_count, analog_signal_array, &analog_signal_index);
read_and_correct_hex_word (opts, state, &(hex_data[14][0]), &status_count, analog_signal_array, &analog_signal_index);
@@ -81,6 +98,15 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
state->debug_prefix_2 = '2';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
// Read data after IMBE 3
read_and_correct_hex_word (opts, state, &(hex_data[11][0]), &status_count, analog_signal_array, &analog_signal_index);
read_and_correct_hex_word (opts, state, &(hex_data[10][0]), &status_count, analog_signal_array, &analog_signal_index);
@@ -93,6 +119,15 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
state->debug_prefix_2 = '3';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
// Read data after IMBE 4
read_and_correct_hex_word (opts, state, &(hex_data[ 7][0]), &status_count, analog_signal_array, &analog_signal_index);
read_and_correct_hex_word (opts, state, &(hex_data[ 6][0]), &status_count, analog_signal_array, &analog_signal_index);
@@ -105,6 +140,15 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
state->debug_prefix_2 = '4';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
// Read data after IMBE 5
read_and_correct_hex_word (opts, state, &(hex_data[ 3][0]), &status_count, analog_signal_array, &analog_signal_index);
read_and_correct_hex_word (opts, state, &(hex_data[ 2][0]), &status_count, analog_signal_array, &analog_signal_index);
@@ -117,6 +161,15 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
state->debug_prefix_2 = '5';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
// Read data after IMBE 6
read_and_correct_hex_word (opts, state, &(hex_parity[ 7][0]), &status_count, analog_signal_array, &analog_signal_index);
read_and_correct_hex_word (opts, state, &(hex_parity[ 6][0]), &status_count, analog_signal_array, &analog_signal_index);
@@ -129,6 +182,13 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
state->debug_prefix_2 = '6';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
// Read data after IMBE 7
read_and_correct_hex_word (opts, state, &(hex_parity[ 3][0]), &status_count, analog_signal_array, &analog_signal_index);
read_and_correct_hex_word (opts, state, &(hex_parity[ 2][0]), &status_count, analog_signal_array, &analog_signal_index);
@@ -141,6 +201,15 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
state->debug_prefix_2 = '7';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
// Read data after IMBE 8: LSD (low speed data)
{
char lsd[8];
@@ -183,6 +252,14 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
state->debug_prefix_2 = '8';
#endif
process_IMBE (opts, state, &status_count);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if (opts->floating_point == 0 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if (opts->floating_point == 1 && opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
//set vc counter to 0
state->p25vc = 0;

View File

@@ -480,20 +480,71 @@ void process_4V (dsd_opts * opts, dsd_state * state)
fprintf (stderr, "\n");
}
#ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
//Cygwin OSS Slot Preference Pre-emption shim
if (opts->audio_out_type == 5)
{
//set to 21 for MBE OSS shim to preempt audio
if (state->currentslot == 0) state->dmrburstL = 21;
else state->dmrburstR = 21;
}
#endif
// #ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
// //Cygwin OSS Slot Preference Pre-emption shim
// if (opts->audio_out_type == 5)
// {
// //set to 21 for MBE OSS shim to preempt audio
// if (state->currentslot == 0) state->dmrburstL = 21;
// else state->dmrburstR = 21;
// }
// #endif
processMbeFrame (opts, state, NULL, ambe_fr1, NULL);
if(state->currentslot == 0)
{
memcpy(state->f_l4[0], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[0], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[0], state->s_lu, sizeof(state->s_lu));
}
else
{
memcpy(state->f_r4[0], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR));
memcpy(state->s_r4[0], state->s_r, sizeof(state->s_r));
memcpy(state->s_r4u[0], state->s_ru, sizeof(state->s_ru));
}
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
if(state->currentslot == 0)
{
memcpy(state->f_l4[1], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[1], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[1], state->s_lu, sizeof(state->s_lu));
}
else
{
memcpy(state->f_r4[1], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR));
memcpy(state->s_r4[1], state->s_r, sizeof(state->s_r));
memcpy(state->s_r4u[1], state->s_ru, sizeof(state->s_ru));
}
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
if(state->currentslot == 0)
{
memcpy(state->f_l4[2], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[2], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[2], state->s_lu, sizeof(state->s_lu));
}
else
{
memcpy(state->f_r4[2], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR));
memcpy(state->s_r4[2], state->s_r, sizeof(state->s_r));
memcpy(state->s_r4u[2], state->s_ru, sizeof(state->s_ru));
}
processMbeFrame (opts, state, NULL, ambe_fr4, NULL);
if(state->currentslot == 0)
{
memcpy(state->f_l4[3], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[3], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[3], state->s_lu, sizeof(state->s_lu));
}
else
{
memcpy(state->f_r4[3], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR));
memcpy(state->s_r4[3], state->s_r, sizeof(state->s_r));
memcpy(state->s_r4u[3], state->s_ru, sizeof(state->s_ru));
}
}
@@ -647,18 +698,44 @@ void process_2V (dsd_opts * opts, dsd_state * state)
fprintf (stderr, "\n");
}
#ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
//Cygwin OSS Slot Preference Pre-emption shim
if (opts->audio_out_type == 5)
{
//set to 21 for MBE OSS shim to preempt audio
if (state->currentslot == 0) state->dmrburstL = 21;
else state->dmrburstR = 21;
}
#endif
// #ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
// //Cygwin OSS Slot Preference Pre-emption shim
// if (opts->audio_out_type == 5)
// {
// //set to 21 for MBE OSS shim to preempt audio
// if (state->currentslot == 0) state->dmrburstL = 21;
// else state->dmrburstR = 21;
// }
// #endif
processMbeFrame (opts, state, NULL, ambe_fr1, NULL);
if(state->currentslot == 0)
{
memcpy(state->f_l4[0], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[0], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[0], state->s_lu, sizeof(state->s_lu));
}
else
{
memcpy(state->f_r4[0], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR));
memcpy(state->s_r4[0], state->s_r, sizeof(state->s_r));
memcpy(state->s_r4u[0], state->s_ru, sizeof(state->s_ru));
}
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
if(state->currentslot == 0)
{
memcpy(state->f_l4[1], state->audio_out_temp_buf, sizeof(state->audio_out_temp_buf));
memcpy(state->s_l4[1], state->s_l, sizeof(state->s_l));
memcpy(state->s_l4u[1], state->s_lu, sizeof(state->s_lu));
}
else
{
memcpy(state->f_r4[1], state->audio_out_temp_bufR, sizeof(state->audio_out_temp_bufR));
memcpy(state->s_r4[1], state->s_r, sizeof(state->s_r));
memcpy(state->s_r4u[1], state->s_ru, sizeof(state->s_ru));
}
process_ESS(opts, state);
@@ -696,7 +773,7 @@ void process_P2_DUID (dsd_opts * opts, dsd_state * state)
for (ts_counter = 0; ts_counter < 4; ts_counter++) //12
{
int sacch = 0;
p2_duid[0] = p2bit[0+(ts_counter*360)];
p2_duid[1] = p2bit[1+(ts_counter*360)];
p2_duid[2] = p2bit[74+(ts_counter*360)];
@@ -706,7 +783,7 @@ void process_P2_DUID (dsd_opts * opts, dsd_state * state)
p2_duid[6] = p2bit[318+(ts_counter*360)];
p2_duid[7] = p2bit[319+(ts_counter*360)];
//process p2_duid with (8,4,4) encoding/decoding
//process p2_duid with (8,4,4) encoding/decoding (hamming?)
int p2_duid_complete = 0;
for (int i = 0; i < 8; i++)
{
@@ -738,7 +815,11 @@ void process_P2_DUID (dsd_opts * opts, dsd_state * state)
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_fR == NULL)) openMbeOutFileR (opts, state);
}
}
else fprintf (stderr, "VCH S ");
else
{
sacch = 1;
fprintf (stderr, "VCH S ");
}
//check to see when last voice activity occurred in order to allow tuning on phase 2
//mac_signal or mac_idle when no more voice activity on current channel
@@ -843,6 +924,19 @@ void process_P2_DUID (dsd_opts * opts, dsd_state * state)
//add 360 bits to each counter
vc_counter = vc_counter + 360;
//WIP: The skip issue was fixed with this check and also with a check to play the extra samples on a 2V
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)
{
@@ -886,6 +980,7 @@ void processP2 (dsd_opts * opts, dsd_state * state)
//process DUID will run through all collected frames and handle them appropriately
process_P2_DUID (opts, state);
state->dmr_stereo = 0;
state->p2_is_lcch = 0;

View File

@@ -729,6 +729,32 @@ void ysf_ehr (dsd_opts * opts, dsd_state * state, uint8_t dbuf[180], int start,
processMbeFrame (opts, state, NULL, ambe_fr, NULL);
if (opts->floating_point == 0)
{
// processAudio(opts, state); //needed here? -- nothign to test it with
if (opts->wav_out_f != NULL)
writeSynthesizedVoice (opts, state);
if (opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if(opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
}
if (opts->floating_point == 1) //float audio is really quiet now (look into it)
{
memcpy (state->f_l, state->audio_out_temp_buf, sizeof(state->f_l));
if (opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if(opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
}
}
if (opts->payload == 1)
@@ -986,18 +1012,37 @@ void processYSF(dsd_opts * opts, dsd_state * state)
state->errs2 = vech_bits[103]; //should be zero, but if it isn't, then its an error
state->debug_audio_errors += state->errs2;
mbe_processAmbe2450Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str,
ambe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
if (opts->payload == 1)
PrintAMBEData (opts, state, ambe_d);
processAudio(opts, state);
if (opts->wav_out_f != NULL)
writeSynthesizedVoice (opts, state);
if (opts->floating_point == 0)
{
processAudio(opts, state);
playSynthesizedVoice (opts, state);
if (opts->wav_out_f != NULL)
writeSynthesizedVoice (opts, state);
if (opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if(opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
}
if (opts->floating_point == 1)
{
memcpy (state->f_l, state->audio_out_temp_buf, sizeof(state->f_l));
if (opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if(opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
}
}
@@ -1094,6 +1139,32 @@ void processYSF(dsd_opts * opts, dsd_state * state)
processMbeFrame(opts, state, imbe_fr, NULL, NULL);
state->synctype = st;
if (opts->floating_point == 0)
{
// processAudio(opts, state); //needed here? -- seems to be running from within mbelib
if (opts->wav_out_f != NULL)
writeSynthesizedVoice (opts, state);
if (opts->pulse_digi_out_channels == 1)
playSynthesizedVoice(opts, state);
if(opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceSS(opts, state);
}
if (opts->floating_point == 1) //float audio is really quiet now (look into it)
{
memcpy (state->f_l, state->audio_out_temp_buf, sizeof(state->f_l));
if (opts->pulse_digi_out_channels == 1)
playSynthesizedVoiceFM(opts, state);
if(opts->pulse_digi_out_channels == 2)
playSynthesizedVoiceFS(opts, state);
}
}
if (ft == 1 && fn == 0)