55*
66* License: MIT License. Use at your own risk.
77*/
8+ // Update notes are in radioCWModulator_F32.h
89
910#include " radioCWModulator_F32.h"
1011#include " sinTable512_f32.h"
1112
1213void radioCWModulator_F32::update (void ) {
13- float32_t keyData[128 ]; // CW key down and up, 0.0f and 1.0f
14- float32_t modulateCW[128 ]; // Storage for data to modulate sine wave
14+
15+ if (!enableXmit)
16+ return ;
17+
18+ float32_t circTemp[64 ]; // Storage for data from Gaussian
19+ uint16_t tempIndex;
1520 uint16_t index, i;
1621 float32_t a, b;
1722 audio_block_f32_t *blockOut;
18-
23+ int32_t circIndexSave24;
1924 blockOut = AudioStream_F32::allocate_f32 (); // Output block
2025 if (!blockOut) return ;
2126
@@ -25,19 +30,24 @@ void radioCWModulator_F32::update(void) {
2530
2631 // We always generate CW at 12 ksps. The number of data points in this
2732 // generation varies to provide 128 output output points after
28- // interpolation to 48 or 96 ksps.
29- for (i=0 ; i<nSamplesPerUpdate; i++)
33+ // interpolation to 24, 48 or 96 ksps. So for each update(), we generate
34+ // 128 points if sample rate is 12 ksps and 32 if it is 48 ksps, etc. The
35+ // remainder are filled in by interpolation, below.
36+ for (i=0 ; i<nSamplesPerUpdate; i++)
3037 {
31- timeMsF += timeSamplesMs;
38+ // Code is generated at 12 ksps, so always increment by 1000mSec/12000:
39+ timeMsF += 0.0833333 ; // in milliSec
3240 timeMsI = (uint32_t )(0.5 + timeMsF);
33-
34- if (!enableXmit) // Just leave the key up and no new characters
41+ if (manualCW)
3542 {
36- levelCW = 0 .0f ;
37- goto noXmit;
43+ if (keyDown)
44+ levelCW = 1 .0f ;
45+ else
46+ levelCW = 0 .0f ;
47+ goto noAuto;
3848 }
3949
40- switch (stateCW)
50+ switch (stateCW) // Sort out the automatic keying
4151 {
4252 case IDLE_CW:
4353 timeMsF = 0 .0f ;
@@ -164,44 +174,67 @@ void radioCWModulator_F32::update(void) {
164174 break ;
165175 }
166176 } // end switch
167- noXmit :
168- keyData [i] = levelCW;
169- } // end, over all 128 times
177+ noAuto :
178+ dataBuf12 [i] = levelCW; // A float, 128 to 16 of them, starting at i=0
179+ } // end, over all 128 to 16 times
170180
171- arm_fir_f32 (&GaussLPFInst, keyData, keyData, nSamplesPerUpdate);
181+ if (sampleRate == SR_12KSPS)
182+ // Do anti-key-click shaping of the 0.0 and 1.0 values.
183+ arm_fir_f32 (&GaussLPFInst, dataBuf12, dataBuf12, 128 );
184+ else
185+ // Use dataBuf12A for FIR output, 64, 32, or 16 points
186+ arm_fir_f32 (&GaussLPFInst, dataBuf12, dataBuf12A, nSamplesPerUpdate);
172187
173- // INTERPOLATE - Interpolate here to support higher sample rates,
174- // while using the same spectral LPF. To this point we have 128, 32
175- // or 16 "active" data points for 12, 48, or 96ksps.
176- //
177- // 0 1 2 3 4 5 6 7 8 9 i
178- // 0 0 0 0 1 1 1 1 2 2 i/4
179- // t 0 0 0 t 0 0 0 t 0 i==4*(i/4)
180- //
181- if (nSample > 1 ) // Only needs interpolation if >1
188+ // For SR_12KSPS there is no interpolation
189+
190+ /* INTERPOLATE - Interpolate here to support higher sample rates,
191+ while using the same spectral LPF. To this point we have 64, 32
192+ or 16 "active" data points for 24, 48, or 96ksps, in dataBuf12A[].
193+ */
194+ if (sampleRate == SR_24KSPS)
182195 {
183- for (i=0 ; i<128 ; i++)
184- {
185- if ( i==(nSample*(1 /nSample)) )
186- modulateCW[i]= keyData[i/nSample];
187- else
188- modulateCW[i] = 0 .0f ;
189- }
190- arm_fir_f32 (&interpolateLPFInst, modulateCW, keyData, 128 );
196+ for (int kk=0 ; kk<64 ; kk++) dataBuf12A[kk] *= 2 .0f ;
197+ arm_fir_interpolate_f32 (&interp12_24Inst, dataBuf12A, dataBuf24, 64 );
198+ }
199+ else if (sampleRate == SR_48KSPS)
200+ {
201+ for (int kk=0 ; kk<32 ; kk++) dataBuf12A[kk] *= 4 .0f ;
202+ arm_fir_interpolate_f32 (&interp12_24Inst, dataBuf12A, dataBuf24, 32 );
203+ arm_fir_interpolate_f32 (&interp24_48Inst, dataBuf24, dataBuf48, 64 );
204+ }
205+ else if (sampleRate == SR_96KSPS)
206+ {
207+ for (int kk=0 ; kk<16 ; kk++) dataBuf12A[kk] *= 8 .0f ;
208+ arm_fir_interpolate_f32 (&interp12_24Inst, dataBuf12A, dataBuf24, 16 );
209+ arm_fir_interpolate_f32 (&interp24_48Inst, dataBuf24, dataBuf48, 32 );
210+ arm_fir_interpolate_f32 (&interp48_96Inst, dataBuf48, dataBuf96, 64 );
191211 }
192212
193- // Interpolation is done , now amplitude modulate CW onto a sine wave.
194- for (i=0 ; i < 128 ; i++)
213+ // Interpolation is complete , now amplitude modulate CW onto a sine wave.
214+ for (i=0 ; i < 128 ; i++) // Always 128 modulation signals
195215 {
216+ float32_t vOut;
217+ if (sampleRate == SR_12KSPS)
218+ vOut = dataBuf12[i];
219+ else if (sampleRate == SR_24KSPS)
220+ vOut = dataBuf24[i];
221+ else if (sampleRate == SR_48KSPS)
222+ vOut = dataBuf48[i];
223+ else if (sampleRate == SR_96KSPS)
224+ vOut = dataBuf96[i];
225+
196226 phaseS += phaseIncrement;
197227 if (phaseS > 512 .0f ) phaseS -= 512 .0f ;
198228 index = (uint16_t ) phaseS;
199229 float32_t deltaPhase = phaseS - (float32_t )index;
200230 // Read two nearest values of input value from the sine table
201231 a = sinTable512_f32[index];
202232 b = sinTable512_f32[index+1 ];
203- blockOut->data [i] = magnitude*keyData[i] *(a+(b-a)*deltaPhase);
233+ blockOut->data [i] = magnitude*vOut *(a+(b-a)*deltaPhase);
204234 }
205235 AudioStream_F32::transmit (blockOut);
206236 AudioStream_F32::release (blockOut);
207- }
237+ } // End update()
238+
239+
240+
0 commit comments