[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Discuss-gnuradio] bug in wfm_rcv_pll and fix, who has stereo FM specs
From: |
Martin Dvh |
Subject: |
[Discuss-gnuradio] bug in wfm_rcv_pll and fix, who has stereo FM specs/info and noise and gain issues |
Date: |
Sun, 17 Jun 2007 17:14:13 +0200 |
User-agent: |
Debian Thunderbird 1.0.2 (X11/20070113) |
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)