From 2aa2bc444c769643e41cae5f17339cef91455e34 Mon Sep 17 00:00:00 2001 From: boblark Date: Fri, 3 Feb 2023 19:00:46 -0800 Subject: [PATCH] Correct sample rate entry and add overall gain control --- RadioIQMixer_F32.cpp | 12 +++++++----- RadioIQMixer_F32.h | 17 ++++++++++++----- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/RadioIQMixer_F32.cpp b/RadioIQMixer_F32.cpp index 1bb0c42..5e08a64 100644 --- a/RadioIQMixer_F32.cpp +++ b/RadioIQMixer_F32.cpp @@ -73,6 +73,7 @@ void RadioIQMixer_F32::update(void) { } // doSimple has amplitude (-1, 1) and sin/cos differ by 90.00 degrees. + // Also no block gain, gainOut. Rev 2023 if (doSimple) { for (i=0; i < block_size; i++) { phaseS += phaseIncrement; @@ -93,9 +94,9 @@ void RadioIQMixer_F32::update(void) { b = sinTable512_f32[index+1]; /* deltaPhase will be the same as used for sin */ if(twoChannel) - blockOut_q->data[i] = blockIn1->data[i]*(a + (b-a)*deltaPhase); + blockOut_q->data[i] = gainOut * blockIn1->data[i]*(a + (b-a)*deltaPhase); else - blockOut_q->data[i] = blockIn0->data[i]*(a + (b-a)*deltaPhase); + blockOut_q->data[i] = gainOut * blockIn0->data[i]*(a + (b-a)*deltaPhase); } } else { // Do a more flexible update, i.e., not doSimple @@ -109,7 +110,7 @@ void RadioIQMixer_F32::update(void) { b = sinTable512_f32[index+1]; // We now have a sine value, so multiply with the input data and save // Linear interpolate sine and multiply with the input and amplitude (about 1.0) - blockOut_i->data[i] = amplitude_pk * blockIn0->data[i] * (a + (b-a)*deltaPhase); + blockOut_i->data[i] = gainOut * amplitude_pk * blockIn0->data[i] * (a + (b-a)*deltaPhase); /* Shift forward phaseS_C and get cos. First, the calculation of index of the table */ phaseC = phaseS + phaseS_C; @@ -121,11 +122,12 @@ void RadioIQMixer_F32::update(void) { b = sinTable512_f32[index+1]; // Same as sin, but leave amplitude of LO at +/- 1.0 if(twoChannel) - blockOut_q->data[i] = blockIn1->data[i]*(a + (b-a)*deltaPhase); + blockOut_q->data[i] = gainOut * blockIn1->data[i]*(a + (b-a)*deltaPhase); else - blockOut_q->data[i] = blockIn0->data[i]*(a + (b-a)*deltaPhase); + blockOut_q->data[i] = gainOut * blockIn0->data[i]*(a + (b-a)*deltaPhase); } } + AudioStream_F32::release(blockIn0); // Done with this if(twoChannel) AudioStream_F32::release(blockIn1); diff --git a/RadioIQMixer_F32.h b/RadioIQMixer_F32.h index 2f06bea..ad48cb9 100644 --- a/RadioIQMixer_F32.h +++ b/RadioIQMixer_F32.h @@ -21,7 +21,8 @@ * * The amplitudeC(a) allows balancing of I and Q channels. * - * The output levels are 0.5 times the input level. + * The output levels are 0.5 times the input level, unless adjusted by + * gainOut(g). * * Status: Tested in doSimple==1 * Tested in FineFreqShift_OA.ino, T3.6 and T4.0 @@ -37,12 +38,15 @@ * void useSimple(bool s) Faster if 1, but no phase/amplitude adjustment * void setSampleRate_Hz(float32_t fs_Hz) Allows dynamic sample rate change for this function * void useTwoChannel(bool 2Ch) Uses 2 input cannels, I & Q, if true. Apr 2021 + * void setGainOut(float32_t gainO) Sets gain after mixers. Often a value of 2.0 makes the + * block lossless. For both doSimple and not doSimple. * - * Time: T3.6 For an update of a 128 sample block, doSimple=1, 46 microseconds - * T4.0 For an update of a 128 sample block, doSimple=1, 20 microseconds + * Time: T3.6 For an update of a 128 sample block, doSimple=true, 46 microseconds + * T4.0 For an update of a 128 sample block, doSimple=true, 20 microseconds * * Rev Apr2021 Allowed for 2-channel I-Q input. Defaults to 1 Channel. "real." * Rev 30Jan23 Corrected setSampleRate_Hz(sr) to do so! RSL + * Rev 2 Feb 2023 Added gainOut, with or without doSimple. RSL */ #ifndef _radioIQMixer_f32_h @@ -123,6 +127,10 @@ public: return; } + void setGainOut(float32_t _gainO) { // Rev 2023 + gainOut = _gainO; + } + void setSampleRate_Hz(float32_t fs_Hz) { sample_rate_Hz = fs_Hz; // Added 30Jan23 RSL // Check freq range @@ -145,11 +153,10 @@ private: float32_t amplitude_pk = 1.0f; float32_t sample_rate_Hz = AUDIO_SAMPLE_RATE_EXACT; float32_t phaseIncrement = 512.00f * freq /sample_rate_Hz; + float32_t gainOut = 1.0f; uint16_t block_size = AUDIO_BLOCK_SAMPLES; uint16_t errorPrintIQM = 0; // Normally off bool doSimple = true; bool twoChannel = false; // Activates 2 channels for I-Q input }; - #endif -