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, 20 Dec 2005 19:27:12 +0100
User-agent: Debian Thunderbird 1.0.2 (X11/20051002)

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

> 





reply via email to

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