discuss-gnuradio
[Top][All Lists]
Advanced

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

Re: [Discuss-gnuradio] Synchronise Signal for TV reception


From: Martin Dvh
Subject: Re: [Discuss-gnuradio] Synchronise Signal for TV reception
Date: Tue, 27 Dec 2005 01:18:51 +0100
User-agent: Debian Thunderbird 1.0.2 (X11/20051002)

kelvin loi wrote:
> Hi Martin,
> Have you combined 2 fields (odd and even fields) into
> 1 frame in your tv_sync block? If yes, could you
> specify which part of it? If no, how to do that in GNU
> radio? I could not find any part that does the
> combination.
No, I don't combine the two fields yet.

To do this in gnuradio you would have to write a deinterleaver.
You could maybe get away with using standard blocks if you just want the most 
simple deinterlever.

A simple deinterleaver would do:
pseudocode:
first line of output=first line for even field
second line of output=first line of odd field
third line of output=second line of even field
fourth line of output=second line of odd field

and so on.
(I am not sure if odd or even is the first field, I always forget)

Using standard gnuradio blocks you could try something like this in python:

parser = OptionParser(option_class=eng_option)
parser.add_option("-s", "--sampling-freq", type="eng_float", default=None,
                          help="set sampling frequency to SAMPLING_FREQ", 
metavar="SAMPLING_FREQ")
parser.add_option("-p", "--pal", action="store_true", default=False,
                          help="Use PAL resolution")
parser.add_option("-n", "--ntsc", action="store_true", default=False,
                          help="Use NTSC resolution")
(options, args) = parser.parse_args()
if len(args) != 0:
  parser.print_help()
  sys.exit(1)

demod_rate=options.sampling_freq
if(options.pal):
  fieldlength=demod_rate/50
  linelength=(demod_rate/25)/625
  nlinesperfield=625/2
elif(options.ntsc):
  fieldsize=demod_rate/60
  linelength=(demod_rate/30)/525
  nlinesperfield=525/2
else:
  print "use --pal or --ntsc"
  sys.exit(1)

fg = gr.flow_graph ()
src = gr.file_source(gr.sizeof_char, options.input_filename)

sync=gr.tv_sync(demod_rate,0)
samples_to_fields=gr.serial_to_parallel (gr.sizeof_char,fieldlength)
separate_odd_and_even_fields=gr.deinterleave    (fieldlength)

field_to_lines_odd=gr.parallel_to_serial        
(gr.sizeof_char*linelength,nlinesperfield) #This is not completely correct 
because nlinesperfield is
not a whole number
field_to_lines_even=gr.parallel_to_serial       
(gr.sizeof_char*linelength,nlinesperfield) #This is not completely correct 
because nlinesperfield is
not a whole number

combine_odd_and_even_lines=gr.interleave        (gr.sizeof_char*linelength)
lines_to_samples=gr.parallel_to_serial          (gr.sizeof_char,linelength)
dst=gr.file_sink(gr.sizeof_char,options.output_filename)  #Not really needed 
for a filesink but usefull if you want to do more postprocessing
        

fg.connect( src,sync,samples_to_fields,separate_odd_and_even_fields)
fg.connect ((separate_odd_and_even_fields,0),field_to_lines_even)
fg.connect ((separate_odd_and_even_fields,1),field_to_lines_odd)
fg.connect(field_to_lines_even,(combine_odd_and_even_lines,0))
fg.connect(field_to_lines_odd,(combine_odd_and_even_lines,1))
fg.connect(combine_odd_and_even_lines,lines_to_samples,dst)

fg.run()


Note that this is not a complete working example.
(I just typed it from the top of my head)

The above code won't work yet because the number of lines in a field is not a 
whole number.
(312.5 for PAL and 262.5 for NTSC)
Also this code does not look if you are starting with an odd or an even field, 
so the lines could be swapped.

I hope this helps,

Greetings,
Martin


> Thank you very much for your
> explaination.
> 
> Cheers,
> kelvin 
> 
> 
> 
> --- Martin Dvh <address@hidden> wrote:
> 
> 
>>Hi kelvin,
>>kelvin loi wrote:
>>
>>>Hi ALL,
>>>Martin! I have seen your tv_sync block. Could i
>>
>>ask
>>
>>>you how actually you did that? It is a bit
>>
>>difficult
>>
>>>for me to understand the code.
>>
>>I will try to explain a bit:
>>
>>Conventions:
>>usec    microseconds
>>length        samples
>>vsubsynclength        length in samples of the sync pulses
>>during vsync, for PAL there are 5 subsync pulses
>>vsynclength   length in samples of the total period
>>where the vsubsyncs occur.
>>d_initial_fieldsize   This is the expected field_size.
>>This is constant and only determined during
>>initialisation. This is the exact size of the
>>fields output
>>d_fieldsize           This is the found field_size
>>
>>In find_initial_fielddata() I look for the start and
>>end of vsync pulses
>>I use two integrators with hysteresis (max_synclevel
>>is greater then min_nosynclevel)
>>
>>To determine the start of vsync:
>>synclength+=(in[counter]<=max_synclevel)?+1:-1;
>>This is an integrator which looks if the input
>>signal is below the max_synclevel treshold.
>>During a sync, as long as the majority of samples
>>are below max_synclevel, synclength will increase.
>>After the end of the sync pulse most samples will be
>>below max_synclevel and the sync_length will
>>decrease slowly to zero.
>>It actually is just a low-pass filter for the sync
>>pulse.
>>As the vsync pulses are much longer then the hsync
>>pulses, synclength will reach much higher values
>>during a vsync.
>>So:
>>if(synclength>(unsigned int)min_vsync_length)
>>{
>>      //We found the start of a vsync
>>      vsyncstart_found=true;
>>      vsyncstart[nvsyncs]=last_before_sync+1;//This sync
>>started the last time synclength was zero
>>      synclength=0;//reset variables
>>      nosynclength=0;//Reset variables
>>}
>>      
>>
>>To determine the end of vsync:
>>nosynclength+=(in[counter]>min_nosynclevel)?+1:-1;
>>This is another integrator which does just the
>>opposite. This one will increase if you are not
>>within a sync and decrease if you are.
>>So:
>>if(nosynclength>(unsigned int)max_novsync_length)
>>{
>>      //We found the end of a sync
>>      int current_vsyncend=last_before_nosync+1;//this
>>sync ended the last time nosynclength was zero
>>      if (vsyncstart_found &&
>>(current_vsyncend-vsyncstart[nvsyncs])<
>>max_vsynclength)
>>      {
>>              //The sync was long enough so this was the end of
>>a vsync
>>              vsync_found=true;
>>              vsyncend[nvsyncs]=current_vsyncend;//remember this
>>vsync_end
>>              nvsyncs++;//increase the number of vsyncs found
>>      
>>
> 
> counter+=linelength*(norm_linesinfield-3-max_lines_jitter);//PAL
> 
>>vsynclines=2.5
>>                             //Go to the next
>>position where we expect a vsync
>>
>>              nosynclength=0;//Reset variables
>>              synclength=0;//Reset variables
>>              if(max_nvsyncs==nvsyncs)
>>                break;
>>      }
>>}
>>
>>If we found vsyncs we have to calculte the start and
>>end of the field and of the first hsync from the
>>position of the vsyncs.
>>if(vsync_found)
>>{
>>
>>
> 
> field_start=vsyncstart[0]+vsyncstart_start_to_field_start;
> 
>>
> active_videostart=vsyncstart[0]+vsyncstart_start_to_active_videostart;
> 
>>}
>>....
>>....
>>      const int
>>
> 
> first_hsync_min_start=vsyncstart[0]+min_vsyncstart_to_first_hsyncstart;
> 
>>      const int
>>
> 
> first_hsync_max_end=vsyncstart[0]+max_vsyncstart_to_first_hsync_end;
> 
>>Now you can use a similar scheme to get get the
>>hsync pulses.
>>I only detrmined the position of the first hsync
>>pulse to determine if this is an even or an odd
>>field.
>>(I am not sure this code is 100% accurate)
>>
>>In general_work() I call find_initial_fielddata() to
>>determine the position of the field_start.
>>I output fields/frames at exactly the expected
>>field_size
>>So I skip samples untill the input is at a
>>field_start.
>>Then I copy the field to the output and wait for the
>>next field_start.
>>
>>I use d_nsample_in_initial_field to keep track where
>>we are, because noutput_items can be smaller then a
>>whole field.
>>
>>
>>
>>
>>>I have seen Prateek Dayal's thesis as well. He
>>>detected the sync signal by using correlation
>>>(unfortunately is in MATLAB :( ). But how to
>>
>>implement
>>
>>>that in GNURADIO? I am just started to  do PAL TV
>>>reception. I have got some clear B/W pictures at
>>
>>this
>>
>>>moment. So please give some guidance. Thanks
>>
>>You can find correlation algorithms on the net.
>>From the top of my head I think a basic example
>>would be:
>>
>>function1 and function2 are the functions you want
>>to correlate and out is an array with the results.
>>
>>float out[searchlength];
>>
>>myCorrelate(int start, int end, int searchlength,
>>float *out)
>>{
>>
>>memset(out,0,searchlength);
>>for(int x=0;x<searchlength;x++)
>>for(int i=start;i<end;i++)
>>    out[x]+=function1(i+x)*function2(i);
>>
>>)
>>
>>Correlation is quite computationally intensive.
>>This is why a opted for another way.
>>There are however resemblances between my code and a
>>real correlation
>>if you define
>>function1(int position)
>>{
>>  return (in[position]<=max_synclevel)?+1:-1;
>>}
>>and
>>function2(int position)
>>{
>>  return (position>vsync_start) &&
>>position<vsync_end):+1:-1;
>>}
>>
>>Then the myCorrelation function will return an array
>>with a peak where the found sync_start is.
>>The difference is that my code doesn't compute all
>>possible values but stops when the value is high
>>enough.
>>if(synclength>(unsigned int)min_vsync_length)
>>
>>I also do not do a multiply between function1 and
>>function2 but use logic for this
>>Further do I use only a small searchspace, I only
>>look for the syncs where I actually expect them.
>>
>>A real correlation would use
>>function1(int position)
>>{
>>  return in[position];
>>}
>>
>>function2(int position)
>>{
>>  return (position>vsync_start) &&
>>
> position<vsync_end):exact_vsync_level:average_video_level;
> 
>>    //(in stead of average_video_level you could use
>>blanking_level or black_level)
>>}
>>
>>I hope this helps
>>
>>greetings,
>>Martin
>>
> 
> === message truncated ===
> 
> 
> Send instant messages to your online friends http://uk.messenger.yahoo.com 
> 





reply via email to

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