[Top][All Lists]
[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
>