discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Discuss-gnuradio] NTSC Audio Demodulation


From: Thom Rainwater
Subject: [Discuss-gnuradio] NTSC Audio Demodulation
Date: Mon, 13 Jun 2005 13:08:32 -0400

I am using the below code to demodulate the Audio Component of the
NTSC signal. The math seems to be correct, but when I run the code I
do not get what I expect. This may be because I am using a FM antenna
to capture the NTSC signal. Is it possible that the FM antenna is the
problem and not the code? I don't have access to a TV antenna at
present so am wondering if this could solve the problem. Does anybody
see any glaring problems with the code, or could someone who has
access to TV antenna run the code and let me know if it works. The
input that the code uses is the video carrier (e.g. 67.25 == video
carrier, 71.75 == audio carrier==> user inputs 67.25)

Thanks

Thom Rainwater



#!/usr/bin/env python

from gnuradio import gr, eng_notation
from gnuradio import audio
from gnuradio import usrp1
from gnuradio import blks
from gnuradio import tv_rx
from gnuradio import tv_rx_audio
from gnuradio.eng_option import eng_option
from gnuradio.wxgui import stdgui, fftsink, slider, fftsink
from gnuradio.blksimpl.fm_emph import fm_deemph
from optparse import OptionParser
import sys
import math
import wx


class tv_rx_graph (stdgui.gui_flow_graph):
    def __init__(self,frame,panel,vbox,argv):
        stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv)

        self.frame = frame
        self.panel = panel

        # Get RF_freq from user
        RF_freq = parseargs(argv[1:])
        
        adc_rate = 64e6
        usrp_decim = 8
        if_rate = adc_rate / usrp_decim         # 8 MHz
        cfir_decim = 25
        quad_rate = if_rate / cfir_decim        # 320 kHz
        audio_decim = 10
        audio_rate = quad_rate / audio_decim    # 32 kHz
        
        # usrp is data source
        src = usrp1.source_c (0, usrp_decim, 1, 0xf0f0f0f2, 0)
        which_side = 1
                
        dboard = tv_rx.tv_rx (src,which_side)
        dboard.set_gain(44) 
        
        (success, actual_freq) = dboard.set_freq(RF_freq)
        
        assert success
        IF_freq = -5.75e6 - RF_freq + actual_freq - 1.75e6 
        src.set_rx_freq (0, IF_freq)
        #==========AUDIO DEMODULATION==========
        
        volume = 20
        max_dev = 75e3
        fm_demod_gain = quad_rate/(2*math.pi*max_dev)
        audio_offset_freq = -2.75e6
        
        xlating_coeffs = \
          gr.firdes.low_pass (1.0,              # gain
                              if_rate,          # sampling rate
                              250e3,            # low pass cutoff freq
                              200e3,            # width of trans. band
                              gr.firdes.WIN_HAMMING)

        # input: complex; output: complex
        xlating_filter = \
          gr.freq_xlating_fir_filter_ccf (cfir_decim,
                                          xlating_coeffs,
                                          audio_offset_freq,
                                          if_rate)
        
        print len (xlating_coeffs)

        # input: complex; output: float
        fm_demod = gr.quadrature_demod_cf (fm_demod_gain)

        # deemphasis
        deemph = fm_deemph (self,quad_rate)     

        # compute FIR filter taps for audio filter
        width_of_transition_band = audio_rate / 32
        audio_coeffs = gr.firdes.low_pass (volume,            # gain
                                           quad_rate,         # sampling rate
                                           audio_rate/2 -
width_of_transition_band,
                                           width_of_transition_band,
                                           gr.firdes.WIN_HAMMING)

        # input: float; output: float
        audio_filter = gr.fir_filter_fff (audio_decim, audio_coeffs)

        # sound card as final sink
        audio_sink = audio.sink (int (audio_rate))
        
        # now wire it all together
        self.connect ( src, xlating_filter )
        self.connect ( xlating_filter, fm_demod )
        self.connect ( fm_demod, deemph )
        self.connect ( deemph, audio_filter )
        self.connect ( audio_filter, audio_sink )
                
        #==========END AUDIO DEMODULATION==========        
 
        # FFT Window for Signal Pre Demodulation
        if 1:
            pre_demod, fft_win1 = \
                       fftsink.make_fft_sink_c (self, panel, "Incoming
Composite Signal",
                                                512, if_rate, -20, 45)
            self.connect (src, pre_demod)
            vbox.Add (fft_win1, 4, wx.EXPAND)
        
        if 1:
            post_translat, fft_win2 = \
                         fftsink.make_fft_sink_c (self, panel,
"Translated Audio Carrrier",
                                                  512, quad_rate, -20, 30)
            self.connect (xlating_filter, post_translat)
            vbox.Add (fft_win2, 4, wx.EXPAND)
        
        if 1:
            post_deemph, fft_win3 = \
                         fftsink.make_fft_sink_f (self, panel, "Post Deemph",
                                                  512, quad_rate, -60, 20)
            self.connect (deemph, post_deemph)
            vbox.Add (fft_win3, 4, wx.EXPAND)

        if 1:
            post_filt, fft_win4 = \
                       fftsink.make_fft_sink_f (self, panel, "Post Filter", 
                                                512, audio_rate, -60, 20)
            self.connect (audio_filter, post_filt)
            vbox.Add (fft_win4, 4, wx.EXPAND)

def parseargs (args):
    nargs = len (args)
    if nargs == 1:
        freq = float (args[0]) * 1e6   
    else:
        sys.stderr.write ('usage: wfm_rcv freq\n')
        sys.exit (1)

    return freq

if __name__ == '__main__':
    app = stdgui.stdapp (tv_rx_graph, "WFM RX")
    app.MainLoop ()




reply via email to

[Prev in Thread] Current Thread [Next in Thread]