4 Reads from a file and generates PAL TV pictures in black and white
5 which can be displayed using ImageMagick or realtime using gr-video-sdl
6 (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)
7 Can also use usrp directly as capture source, but then you need a higher decimation factor (64)
8 and thus get a lower horizontal resulution.
9 There is no synchronisation yet. The sync blocks are in development but not yet in cvs.
13 from gnuradio import gr, eng_notation
14 from gnuradio import audio
15 from gnuradio import usrp
16 from gnuradio.eng_option import eng_option
17 from optparse import OptionParser
21 from gnuradio import video_sdl
23 print "FYI: gr-video-sdl is not installed"
24 print "realtime \"sdl\" video output window will not be available"
27 class my_graph(gr.flow_graph):
30 gr.flow_graph.__init__(self)
32 usage="%prog: [options] output_filename. \n Special output_filename \"sdl\" will use video_sink_sdl as realtime output window. " \
33 "You then need to have gr-video-sdl installed. \n" \
34 "Make sure your input capture file containes interleaved shorts not complex floats"
35 parser = OptionParser(option_class=eng_option, usage=usage)
36 parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0),
37 help="select USRP Rx side A or B (default=A)")
38 parser.add_option("-c", "--contrast", type="eng_float", default=1.0,
39 help="set contrast (default is 1.0)")
40 parser.add_option("-b", "--brightness", type="eng_float", default=0.0,
41 help="set brightness (default is 0)")
42 parser.add_option("-d", "--decim", type="int", default=8,
43 help="set fgpa decimation rate to DECIM [default=%default]")
44 parser.add_option("-i", "--in-filename", type="string", default=None,
45 help="Use input file as source. samples must be interleaved shorts \n " +
46 "Use usrp_rx_file.py or usrp_rx_cfile.py --output-shorts. \n"
47 "Special name \"usrp\" results in realtime capturing and processing using usrp. \n" +
48 "You then probably need a decimation factor of 64 or higher.")
49 parser.add_option("-f", "--freq", type="eng_float", default=None,
50 help="set frequency to FREQ.\nNote that the frequency of the video carrier is not at the middle of the TV channel", metavar="FREQ")
51 parser.add_option("-g", "--gain", type="eng_float", default=None,
52 help="set gain in dB (default is midpoint)")
53 parser.add_option("-p", "--pal", action="store_true", default=False,
54 help="PAL video format (this is the default)")
55 parser.add_option("-n", "--ntsc", action="store_true", default=False,
56 help="NTSC video format")
57 parser.add_option("-r", "--repeat", action="store_false", default=True,
58 help="repeat in_file in a loop")
59 parser.add_option("-8", "--width-8", action="store_true", default=False,
60 help="Enable 8-bit samples across USB")
61 parser.add_option("-N", "--nframes", type="eng_float", default=None,
62 help="number of frames to collect [default=+inf]")
63 parser.add_option( "--no-hb", action="store_true", default=False,
64 help="don't use halfband filter in usrp")
65 (options, args) = parser.parse_args ()
66 if not (len(args) == 1):
68 sys.stderr.write('You must specify the output. FILENAME or sdl \n');
73 if options.in_filename is None:
75 sys.stderr.write('You must specify the input -i FILENAME or -i usrp\n');
78 if not (filename=="sdl"):
81 if not (options.in_filename=="usrp"):
82 self.filesource = gr.file_source(gr.sizeof_short,options.in_filename,options.repeat) # file is data source, capture with usr_rx_csfile.py
83 self.istoc = gr.interleaved_short_to_complex()
84 self.connect(self.filesource,self.istoc)
88 if options.freq is None:
90 sys.stderr.write('You must specify the frequency with -f FREQ\n');
92 if abs(options.freq) < 1e6:
94 if options.no_hb or (options.decim<8):
95 self.fpga_filename="std_4rx_0tx.rbf" #contains 4 Rx paths without halfbands and 0 tx paths
97 self.fpga_filename="std_2rxhb_2tx.rbf" # contains 2 Rx paths with halfband filters and 2 tx paths (the default)
100 self.u = usrp.source_c(decim_rate=options.decim,fpga_filename=self.fpga_filename)
105 format = self.u.make_format(sample_width, sample_shift)
106 r = self.u.set_format(format)
107 self.adc_rate=self.u.adc_freq()
108 if options.rx_subdev_spec is None:
109 options.rx_subdev_spec = usrp.pick_rx_subdevice(self.u)
110 self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
111 # determine the daughterboard subdevice we're using
112 self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
113 print "Using RX d'board %s" % (self.subdev.side_and_name(),)
115 if options.gain is None:
116 # if no gain was specified, use the mid-point in dB
117 g = self.subdev.gain_range()
118 options.gain = float(g[0]+g[1])/2
119 self.subdev.set_gain(options.gain)
121 r = self.u.tune(0, self.subdev, options.freq)
123 sys.stderr.write('Failed to set frequency\n')
126 input_rate = self.adc_rate / options.decim
127 print "video sample rate %s" % (eng_notation.num_to_str(input_rate))
129 self.agc=gr.agc_cc(1e-7,1.0,1.0) #1e-7
130 self.am_demod = gr.complex_to_mag ()
131 self.set_blacklevel=gr.add_const_ff(options.brightness +255.0)
132 self.invert_and_scale = gr.multiply_const_ff (-options.contrast *128.0*255.0/(200.0))
133 self.f2uc=gr.float_to_uchar()
135 # sdl window as final sink
136 if not (options.pal or options.ntsc):
137 options.pal=True #set default to PAL
139 lines_per_frame=625.0
143 lines_per_frame=525.0
144 frames_per_sec=29.97002997
146 width=int(input_rate/(lines_per_frame*frames_per_sec))
147 height=int(lines_per_frame)
150 #Here comes the tv screen, you have to build and install gr-video-sdl for this (subproject of gnuradio, only in cvs for now)
152 video_sink = video_sdl.sink_uc ( frames_per_sec, width, height,0,show_width,height)
154 print "gr-video-sdl is not installed"
155 print "realtime \"sdl\" video output window is not available"
159 print "You can use the imagemagick display tool to show the resulting imagesequence"
160 print "use the following line to show the demodulated TV-signal:"
161 print "display -depth 8 -size " +str(width)+ "x" + str(height) + " gray:" +filename
162 print "(Use the spacebar to advance to next frames)"
163 file_sink=gr.file_sink(gr.sizeof_char, filename)
166 if options.nframes is None:
167 self.connect(self.src, self.agc)
169 self.head = gr.head(gr.sizeof_gr_complex, int(options.nframes*width*height))
170 self.connect(self.src, self.head, self.agc)
172 self.connect (self.agc,self.am_demod,self.invert_and_scale, self.set_blacklevel,self.f2uc,self.dst)
175 if __name__ == '__main__':
178 except KeyboardInterrupt: