discuss-gnuradio
[Top][All Lists]
Advanced

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

Re: [Discuss-gnuradio] problem with audio extraction in NTSC


From: Achilleas Anastasopoulos
Subject: Re: [Discuss-gnuradio] problem with audio extraction in NTSC
Date: Wed, 16 Feb 2005 13:20:56 -0500
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)


I deactivated the three fftscopes that I had and now
it works fine. The voice distortion was because the CPU
could not handle the load. It is amazing how much CPU
power the fftscopes consume...

Thanks for the help
Achilleas


Eric Blossom wrote:
On Tue, Feb 15, 2005 at 07:59:45PM -0500, Achilleas Anastasopoulos wrote:

Dear all,

I am working on extracting the audio FM signal from the NTSC
signal, and experimenting with the data file

ntsc-short-complex-baseband-8MS.dat

The idea seems simple: recenter the audio carrier to 0 frequency,
LPF and decimate and then do standard fm demod.
This is done in the attached file.

Unfortunately, although I hear something like

"winter storm will still going to stick around..."

the signal seems highly distorted as if the audio
carrier is very unstable.
I tried to fix this by tracking the video carrier,
but the problem gets worse.

One possible reason for this is that the local oscilator used to generate the IQ signal is not stable, which unfortunately cannot be fixed...

Can someone verify this problem and/or suggest any solution.

Thanks
Achilleas


This code is known to work with that file...

#!/usr/bin/env python

from gnuradio import gr, eng_notation
from gnuradio import audio
from gnuradio.eng_option import eng_option
from optparse import OptionParser
import sys
import math


#
# return a gr.flow_graph
#
def build_graph (filename, repeat):
    fm_demod_gain = 1100.0/32768.0
    volume = 1.0
input_rate = 8e6
    cfir_decimation = 25
    audio_decimation = 10

    quad_rate = input_rate / cfir_decimation   # 320 kHz
    audio_rate = quad_rate / audio_decimation  # 32 kHz

    fg = gr.flow_graph ()
# file contains complex shorts
    # output: short
    src = gr.file_source (gr.sizeof_short, filename, repeat)

    # deinterleave the shorts and convert them to complex
    # input: short; output: complex
    deinterleaver = gr.interleaved_short_to_complex ()
# Select only the FM audio channel.
    # It's located at +2.75MHz

    offset_freq = -2.75e6

    channel_coeffs = \
      gr.firdes.low_pass (1.0,          # gain
                          input_rate,   # sampling rate
                          200e3,        # low pass cutoff freq
                          200e3,        # width of trans. band
                          gr.firdes.WIN_HAMMING)

    # input: complex; output: complex
    channel_filter = \
      gr.freq_xlating_fir_filter_ccf (cfir_decimation,
                                      channel_coeffs,
                                      offset_freq,
                                      input_rate)
    print len (channel_coeffs)

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

    # compute FIR filter taps for audio filter
    width_of_transition_band = audio_rate / 32
    audio_coeffs = gr.firdes.low_pass (1.0,            # 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_decimation, audio_coeffs)

    # sound card as final sink
    audio_sink = audio.sink (int (audio_rate))

    # now wire it all together
    fg.connect (src, deinterleaver)
    fg.connect (deinterleaver, channel_filter)
    fg.connect (channel_filter, fm_demod)
    fg.connect (fm_demod, audio_filter)
    fg.connect (audio_filter, audio_sink)
return fg


def main ():
    parser = OptionParser (option_class=eng_option)
    parser.add_option ("-i", "--input", type="string",
                       default="ch4.dat", help="read data from FILENAME")
    parser.add_option ("-R", "--repeat", action="store_true", default=False)
    (options, args) = parser.parse_args ()

    fg = build_graph (options.input, options.repeat)

    fg.start ()        # fork thread(s) and return
    raw_input ('Press Enter to quit: ')
    fg.stop ()

if __name__ == '__main__':
    main ()





reply via email to

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