Hi, I found a nasty bug in the wfm_rcv_pll.py code. The pilot tone pll should return the recovered carrier, For this you should use gr.pll_refout_cc, not gr.pll_carriertracking_cc. pll_carriertracking returns the input transformed to baseband using the recovered carrier. pll_refout returns the recovered carrier.
With the fixed code I now actually get stereo. (Before you would get a kind of attenuated, distorted, spectrum inverted stereo) I tested it with a stereo-coder I wrote in gnuradio, and now I seem to actually get stereo seperation. (stereo modulater is attached) But now I do get a lot of noise when decoding stereo. I also don't quite understand why double side band suppressed carrier Left-Right audio is attenuated and needs a factor 20 for gain. (It seems to be correct or at least close) The code comments say 10 dB The actual code uses a factor 20 which corresponds to 20 *log10(20)= 26 dB. This 26 dB seems to be quite accurate, but where is this number based on? can you give me a link to more info or the stereo FM specs on this. # Pick off the double side band suppressed carrier Left-Right audio. It is attenuated 10 dB so apply 10 dB gain stereo_dsbsc_filter_coeffs = gr.firdes.complex_band_pass(20.0, Greetings, Martin fix for wrong pll is below: --- gnuradio-core/src/python/gnuradio/blksimpl/wfm_rcv_pll.py 2007-06-11 18:12:55.000000000 +0200 +++ gnuradio-core/src/python/gnuradio/blksimpl/wfm_rcv_pll_fixed.py 2007-06-17 08:07:43.000000000 +0200 @@ -131,8 +131,8 @@ max_freq = -2.0*math.pi*18990/audio_rate; min_freq = -2.0*math.pi*19010/audio_rate; - self.stereo_carrier_pll_recovery = gr.pll_carriertracking_cc(alpha,beta,max_freq,min_freq); - self.stereo_carrier_pll_recovery.squelch_enable(False); + self.stereo_carrier_pll_recovery = gr.pll_refout_cc(alpha,beta,max_freq,min_freq); + #self.stereo_carrier_pll_recovery.squelch_enable(False) #pll_refout does not have squelch yet, so disabled for now # set up mixer (multiplier) to get the L-R signal at baseband
import math from gnuradio import gr, optfir from gnuradio.blksimpl.fm_emph import fm_preemph class wfm_tx_stereo(gr.hier_block): def __init__(self, fg, input_rate, freq_tone_left=1.0e3,level_tone_left=1.0,freq_tone_right=3.0e3, level_tone_right=1.0,tau=75e-6, max_dev=75e3): """ Wide Band FM Stereo test Transmitter. Generates a 1kHz tone on left and 3 kHz tone on right channel and produces a single stereo FM modulated complex baseband output. Stereo seperation can be tested by setting one of the tone_levels to zero @param fg: flow graph @param input_rate: sample rate of audio stream and output_stream >= 55k @type input_rate: integer @param freq_tone_left: frequency of test tone on left channel in the range [0.0,15.0e3] (0 to 15 kHz) @type freq_tone_left: float @param level_tone_left: level of test tone on left channel in the range [0.0, 1.0] @type level_tone_left: float @param freq_tone_right:frequency of test tone on right channel in the range [0,15e3] (0 to 15 kHz) @type freq_tone_right: float @param level_tone_right: level of test tone on right channel in the range [0.0, 1.0] @type freq_tone_right: float @param tau: preemphasis time constant (default 75e-6) This is not used yet (not implemented yet) @type tau: float @param max_dev: maximum deviation in Hz (default 75e3) @type max_dev: float """ self.input_rate=input_rate self.interpolation=1 #must be 1 for now self.mod_rate=self.input_rate*self.interpolation #do_interp = self.input_rate != self.mod_rate # #if do_interp: # interp_taps = optfir.low_pass (interpolation, # gain # self.mod_rate, # Fs # 16000, # passband cutoff # 18000, # stopband cutoff # 0.1, # passband ripple dB # 60) # stopband atten dB # # print "len(interp_taps) =", len(interp_taps) # self.interpolator = gr.interp_fir_filter_fcc (interpolation, interp_taps) #if do_interp: # self.input_fc=self.interpolator #else: # self.input_fc=gr.float_to_complex() #self.preemph = fm_preemph (fg, self.mod_rate, tau=tau) #fm_preemph cannot be used yet because the fm_preemph block is not implemented yet, it is just a stub k = 2 * math.pi * max_dev / self.mod_rate self.modulator = gr.frequency_modulator_fc (k) self.pilot_c=gr.sig_source_c(self.mod_rate,gr.GR_SIN_WAVE ,19.0e3,1.0,0.0) self.pilotx2_cc=gr.multiply_cc() self.pilot_gain_cc=gr.multiply_const_cc(1.0/20.0)#/40.0) self.lplusr_ff=gr.add_ff() self.lplusr_gain_ff=gr.multiply_const_ff(1.0/10.0) #1.0 self.lplusr_fc=gr.float_to_complex() self.lminr_ff=gr.sub_ff() self.lminr_gain_ff=gr.multiply_const_ff(1.0/10.0) self.lminr_fc=gr.float_to_complex() self.input_l_f=gr.sig_source_f(self.mod_rate,gr.GR_SIN_WAVE ,freq_tone_left,0.5*level_tone_left,0.0) self.input_r_f=gr.sig_source_f(self.mod_rate,gr.GR_SIN_WAVE ,freq_tone_right,0.5*level_tone_right,0.0) self.dsbsc_gen_cc=gr.multiply_cc() self.baseband_cc=gr.add_cc() self.baseband_cf=gr.complex_to_float() fg.connect(self.input_l_f,(self.lplusr_ff,0)) fg.connect(self.input_r_f,(self.lplusr_ff,1)) fg.connect(self.input_l_f,(self.lminr_ff,0)) fg.connect(self.input_r_f,(self.lminr_ff,1)) fg.connect(self.lminr_ff,self.lminr_gain_ff,self.lminr_fc,(self.dsbsc_gen_cc,0)) fg.connect(self.pilot_c,(self.pilotx2_cc,0)) fg.connect(self.pilot_c,(self.pilotx2_cc,1)) fg.connect(self.pilotx2_cc,(self.dsbsc_gen_cc,1)) fg.connect(self.dsbsc_gen_cc,(self.baseband_cc,0)) fg.connect(self.pilot_c,self.pilot_gain_cc,(self.baseband_cc,1)) nullsink=gr.null_sink(gr.sizeof_float) fg.connect(self.lplusr_ff,nullsink) fg.connect(self.lplusr_ff,self.lplusr_gain_ff,self.lplusr_fc,(self.baseband_cc,2)) fg.connect(self.baseband_cc,self.baseband_cf) fg.connect(self.baseband_cf, self.modulator) gr.hier_block.__init__(self, fg, None, self.modulator)
_______________________________________________ Discuss-gnuradio mailing list Discuss-gnuradio@gnu.org http://lists.gnu.org/mailman/listinfo/discuss-gnuradio