@@ -49,16 +49,17 @@ namespace dsp::demod {
4949 audioFirTaps = taps::lowPass (15000.0 , 4000.0 , _samplerate);
5050 alFir.init (NULL , audioFirTaps);
5151 arFir.init (NULL , audioFirTaps);
52+ xlator.init (NULL , -57000.0 , samplerate);
5253 rdsResamp.init (NULL , samplerate, 5000.0 );
5354
5455 lmr = buffer::alloc<float >(STREAM_BUFFER_SIZE);
5556 l = buffer::alloc<float >(STREAM_BUFFER_SIZE);
5657 r = buffer::alloc<float >(STREAM_BUFFER_SIZE);
5758
5859 lprDelay.out .free ();
59- lmrDelay.out .free ();
6060 arFir.out .free ();
6161 alFir.out .free ();
62+ xlator.out .free ();
6263 rdsResamp.out .free ();
6364
6465 base_type::init (in);
@@ -92,6 +93,7 @@ namespace dsp::demod {
9293 alFir.setTaps (audioFirTaps);
9394 arFir.setTaps (audioFirTaps);
9495
96+ xlator.setOffset (-57000.0 , samplerate);
9597 rdsResamp.setInSamplerate (samplerate);
9698
9799 reset ();
@@ -139,7 +141,7 @@ namespace dsp::demod {
139141 base_type::tempStart ();
140142 }
141143
142- inline int process (int count, complex_t * in, stereo_t * out, int & rdsOutCount, float * rdsout = NULL ) {
144+ inline int process (int count, complex_t * in, stereo_t * out, int & rdsOutCount, complex_t * rdsout = NULL ) {
143145 // Demodulate
144146 demod.process (count, in, demod.out .writeBuf );
145147 if (_stereo) {
@@ -152,24 +154,24 @@ namespace dsp::demod {
152154
153155 // Delay
154156 lprDelay.process (count, demod.out .writeBuf , demod.out .writeBuf );
155- lmrDelay.process (count, rtoc.out .writeBuf , rtoc .out .writeBuf );
157+ lmrDelay.process (count, rtoc.out .writeBuf , lmrDelay .out .writeBuf );
156158
157159 // conjugate PLL output to down convert twice the L-R signal
158160 math::Conjugate::process (count, pilotPLL.out .writeBuf , pilotPLL.out .writeBuf );
159- math::Multiply<dsp::complex_t >::process (count, rtoc .out .writeBuf , pilotPLL.out .writeBuf , rtoc .out .writeBuf );
160- math::Multiply<dsp::complex_t >::process (count, rtoc .out .writeBuf , pilotPLL.out .writeBuf , rtoc .out .writeBuf );
161+ math::Multiply<dsp::complex_t >::process (count, lmrDelay .out .writeBuf , pilotPLL.out .writeBuf , lmrDelay .out .writeBuf );
162+ math::Multiply<dsp::complex_t >::process (count, lmrDelay .out .writeBuf , pilotPLL.out .writeBuf , lmrDelay .out .writeBuf );
161163
162164 // Do RDS demod
163165 if (_rdsOut) {
164- // Since the PLL output is no longer needed after this, use it as the output
165- math::Multiply<dsp:: complex_t >:: process (count, rtoc.out .writeBuf , pilotPLL. out . writeBuf , pilotPLL .out .writeBuf );
166- convert::ComplexToReal::process (count, pilotPLL. out . writeBuf , rdsout);
167- volk_32f_s32f_multiply_32f (rdsout, rdsout, 100.0 , count);
168- rdsOutCount = rdsResamp.process (count, rdsout , rdsout);
166+ // Translate to 0Hz
167+ xlator. process (count, rtoc.out .writeBuf , rtoc .out .writeBuf );
168+
169+ // Resample to the output samplerate
170+ rdsOutCount = rdsResamp.process (count, rtoc. out . writeBuf , rdsout);
169171 }
170172
171173 // Convert output back to real for further processing
172- convert::ComplexToReal::process (count, rtoc .out .writeBuf , lmr);
174+ convert::ComplexToReal::process (count, lmrDelay .out .writeBuf , lmr);
173175
174176 // Amplify by 2x
175177 volk_32f_s32f_multiply_32f (lmr, lmr, 2 .0f , count);
@@ -193,24 +195,11 @@ namespace dsp::demod {
193195 // Convert to complex
194196 rtoc.process (count, demod.out .writeBuf , rtoc.out .writeBuf );
195197
196- // Filter out pilot and run through PLL
197- pilotFir.process (count, rtoc.out .writeBuf , pilotFir.out .writeBuf );
198- pilotPLL.process (count, pilotFir.out .writeBuf , pilotPLL.out .writeBuf );
199-
200- // Delay
201- lprDelay.process (count, demod.out .writeBuf , demod.out .writeBuf );
202- lmrDelay.process (count, rtoc.out .writeBuf , rtoc.out .writeBuf );
203-
204- // conjugate PLL output to down convert twice the L-R signal
205- math::Conjugate::process (count, pilotPLL.out .writeBuf , pilotPLL.out .writeBuf );
206- math::Multiply<dsp::complex_t >::process (count, rtoc.out .writeBuf , pilotPLL.out .writeBuf , rtoc.out .writeBuf );
207- math::Multiply<dsp::complex_t >::process (count, rtoc.out .writeBuf , pilotPLL.out .writeBuf , rtoc.out .writeBuf );
208-
209- // Since the PLL output is no longer needed after this, use it as the output
210- math::Multiply<dsp::complex_t >::process (count, rtoc.out .writeBuf , pilotPLL.out .writeBuf , pilotPLL.out .writeBuf );
211- convert::ComplexToReal::process (count, pilotPLL.out .writeBuf , rdsout);
212- volk_32f_s32f_multiply_32f (rdsout, rdsout, 100.0 , count);
213- rdsOutCount = rdsResamp.process (count, rdsout, rdsout);
198+ // Translate to 0Hz
199+ xlator.process (count, rtoc.out .writeBuf , rtoc.out .writeBuf );
200+
201+ // Resample to the output samplerate
202+ rdsOutCount = rdsResamp.process (count, rtoc.out .writeBuf , rdsout);
214203 }
215204
216205 // Filter if needed
@@ -240,7 +229,7 @@ namespace dsp::demod {
240229 return count;
241230 }
242231
243- stream<float > rdsOut;
232+ stream<complex_t > rdsOut;
244233
245234 protected:
246235 double _deviation;
@@ -253,13 +242,14 @@ namespace dsp::demod {
253242 tap<complex_t > pilotFirTaps;
254243 filter::FIR<complex_t , complex_t > pilotFir;
255244 convert::RealToComplex rtoc;
245+ channel::FrequencyXlator xlator;
256246 loop::PLL pilotPLL;
257247 math::Delay<float > lprDelay;
258248 math::Delay<complex_t > lmrDelay;
259249 tap<float > audioFirTaps;
260250 filter::FIR<float , float > arFir;
261251 filter::FIR<float , float > alFir;
262- multirate::RationalResampler<float > rdsResamp;
252+ multirate::RationalResampler<dsp:: complex_t > rdsResamp;
263253
264254 float * lmr;
265255 float * l;
0 commit comments