3 # Copyright 2005,2006,2007 Free Software Foundation, Inc.
5 # This file is part of GNU Radio
7 # GNU Radio is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3, or (at your option)
12 # GNU Radio is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with GNU Radio; see the file COPYING. If not, write to
19 # the Free Software Foundation, Inc., 51 Franklin Street,
20 # Boston, MA 02110-1301, USA.
24 Reads from a file and generates PAL TV pictures in black and white
25 which can be displayed using ImageMagick or realtime using gr-video-sdl
26 (To capture the input file Use usrp_rx_file.py, or use usrp_rx_cfile.py --output-shorts if you have a recent enough usrp_rx_cfile.py)
27 Can also use usrp directly as capture source, but then you need a higher decimation factor (64)
28 and thus get a lower horizontal resulution.
29 There is no synchronisation yet. The sync blocks are in development but not yet in cvs.
33 from gnuradio import gr, eng_notation
34 from gnuradio import audio
35 from gnuradio import usrp
36 from gnuradio.eng_option import eng_option
37 from optparse import OptionParser
41 from gnuradio import video_sdl
43 print "FYI: gr-video-sdl is not installed"
44 print "realtime \"sdl\" video output window will not be available"
47 class my_top_block(gr.top_block):
50 gr.top_block.__init__(self)
52 usage="%prog: [options] output_filename. \n Special output_filename \"sdl\" will use video_sink_sdl as realtime output window. " \
53 "You then need to have gr-video-sdl installed. \n" \
54 "Make sure your input capture file containes interleaved shorts not complex floats"
55 parser = OptionParser(option_class=eng_option, usage=usage)
56 parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0),
57 help="select USRP Rx side A or B (default=A)")
58 parser.add_option("-c", "--contrast", type="eng_float", default=1.0,
59 help="set contrast (default is 1.0)")
60 parser.add_option("-b", "--brightness", type="eng_float", default=0.0,
61 help="set brightness (default is 0)")
62 parser.add_option("-d", "--decim", type="int", default=8,
63 help="set fgpa decimation rate to DECIM [default=%default]")
64 parser.add_option("-i", "--in-filename", type="string", default=None,
65 help="Use input file as source. samples must be interleaved shorts \n " +
66 "Use usrp_rx_file.py or usrp_rx_cfile.py --output-shorts. \n"
67 "Special name \"usrp\" results in realtime capturing and processing using usrp. \n" +
68 "You then probably need a decimation factor of 64 or higher.")
69 parser.add_option("-f", "--freq", type="eng_float", default=None,
70 help="set frequency to FREQ.\nNote that the frequency of the video carrier is not at the middle of the TV channel", metavar="FREQ")
71 parser.add_option("-g", "--gain", type="eng_float", default=None,
72 help="set gain in dB (default is midpoint)")
73 parser.add_option("-p", "--pal", action="store_true", default=False,
74 help="PAL video format (this is the default)")
75 parser.add_option("-n", "--ntsc", action="store_true", default=False,
76 help="NTSC video format")
77 parser.add_option("-r", "--repeat", action="store_false", default=True,
78 help="repeat in_file in a loop")
79 parser.add_option("-8", "--width-8", action="store_true", default=False,
80 help="Enable 8-bit samples across USB")
81 parser.add_option("-N", "--nframes", type="eng_float", default=None,
82 help="number of frames to collect [default=+inf]")
83 parser.add_option( "--no-hb", action="store_true", default=False,
84 help="don't use halfband filter in usrp")
85 (options, args) = parser.parse_args ()
86 if not (len(args) == 1):
88 sys.stderr.write('You must specify the output. FILENAME or sdl \n');
93 if options.in_filename is None:
95 sys.stderr.write('You must specify the input -i FILENAME or -i usrp\n');
98 if not (filename=="sdl"):
101 if not (options.in_filename=="usrp"):
102 self.filesource = gr.file_source(gr.sizeof_short,options.in_filename,options.repeat) # file is data source, capture with usr_rx_csfile.py
103 self.istoc = gr.interleaved_short_to_complex()
104 self.connect(self.filesource,self.istoc)
108 if options.freq is None:
110 sys.stderr.write('You must specify the frequency with -f FREQ\n');
112 if abs(options.freq) < 1e6:
114 if options.no_hb or (options.decim<8):
115 self.fpga_filename="std_4rx_0tx.rbf" #contains 4 Rx paths without halfbands and 0 tx paths
117 self.fpga_filename="std_2rxhb_2tx.rbf" # contains 2 Rx paths with halfband filters and 2 tx paths (the default)
120 self.u = usrp.source_c(decim_rate=options.decim,fpga_filename=self.fpga_filename)
125 format = self.u.make_format(sample_width, sample_shift)
126 r = self.u.set_format(format)
127 self.adc_rate=self.u.adc_freq()
128 if options.rx_subdev_spec is None:
129 options.rx_subdev_spec = usrp.pick_rx_subdevice(self.u)
130 self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
131 # determine the daughterboard subdevice we're using
132 self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
133 print "Using RX d'board %s" % (self.subdev.side_and_name(),)
135 if options.gain is None:
136 # if no gain was specified, use the mid-point in dB
137 g = self.subdev.gain_range()
138 options.gain = float(g[0]+g[1])/2
139 self.subdev.set_gain(options.gain)
141 r = self.u.tune(0, self.subdev, options.freq)
143 sys.stderr.write('Failed to set frequency\n')
146 input_rate = self.adc_rate / options.decim
147 print "video sample rate %s" % (eng_notation.num_to_str(input_rate))
149 self.agc=gr.agc_cc(1e-7,1.0,1.0) #1e-7
150 self.am_demod = gr.complex_to_mag ()
151 self.set_blacklevel=gr.add_const_ff(options.brightness +255.0)
152 self.invert_and_scale = gr.multiply_const_ff (-options.contrast *128.0*255.0/(200.0))
153 self.f2uc=gr.float_to_uchar()
155 # sdl window as final sink
156 if not (options.pal or options.ntsc):
157 options.pal=True #set default to PAL
159 lines_per_frame=625.0
163 lines_per_frame=525.0
164 frames_per_sec=29.97002997
166 width=int(input_rate/(lines_per_frame*frames_per_sec))
167 height=int(lines_per_frame)
170 #Here comes the tv screen, you have to build and install gr-video-sdl for this (subproject of gnuradio, only in cvs for now)
172 video_sink = video_sdl.sink_uc ( frames_per_sec, width, height,0,show_width,height)
174 print "gr-video-sdl is not installed"
175 print "realtime \"sdl\" video output window is not available"
179 print "You can use the imagemagick display tool to show the resulting imagesequence"
180 print "use the following line to show the demodulated TV-signal:"
181 print "display -depth 8 -size " +str(width)+ "x" + str(height) + " gray:" +filename
182 print "(Use the spacebar to advance to next frames)"
183 file_sink=gr.file_sink(gr.sizeof_char, filename)
186 if options.nframes is None:
187 self.connect(self.src, self.agc)
189 self.head = gr.head(gr.sizeof_gr_complex, int(options.nframes*width*height))
190 self.connect(self.src, self.head, self.agc)
192 self.connect (self.agc,self.am_demod,self.invert_and_scale, self.set_blacklevel,self.f2uc,self.dst)
195 if __name__ == '__main__':
198 except KeyboardInterrupt: