mirror of
https://github.com/jfdelnero/rf-tools.git
synced 2024-11-21 11:21:47 -05:00
Working black & white TV transmitter (PAL-L / SECAM timings and polarity by default - No Audio).
This commit is contained in:
parent
fafd7fa578
commit
03193173f3
@ -24,14 +24,17 @@ endif
|
|||||||
ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN)
|
ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
EXEC=broadcast_fm rf_jammer
|
EXEC=broadcast_tv broadcast_fm rf_jammer
|
||||||
|
|
||||||
all: $(EXEC)
|
all: $(EXEC)
|
||||||
|
|
||||||
broadcast_fm: broadcast_fm.o rds.o rds_stream_dump.o wave.o modulator.o FIR_Audio_Filter_Filter.o FM_Baseband_Filter.o AudioPreemphasis_Filter.o FIR_RDS_Passband_Filter.o hxcmod.o rand_gen.o
|
broadcast_fm: broadcast_fm.o rds.o rds_stream_dump.o wave.o modulator.o FIR_Audio_Filter_Filter.o FM_Baseband_Filter.o AudioPreemphasis_Filter.o FIR_RDS_Passband_Filter.o hxcmod.o rand_gen.o
|
||||||
$(CC) -o $@ $^ $(LDFLAGS)
|
$(CC) -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
rf_jammer: rf_jammer.o wave.o modulator.o rand_gen.o
|
broadcast_tv: broadcast_tv.o composite.o wave.o modulator.o bmp_file.o
|
||||||
|
$(CC) -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
|
rf_jammer: rf_jammer.o wave.o modulator.o rand_gen.o composite.o
|
||||||
$(CC) -o $@ $^ $(LDFLAGS)
|
$(CC) -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
broadcast_fm.o: ../src/broadcast_fm/broadcast_fm.c
|
broadcast_fm.o: ../src/broadcast_fm/broadcast_fm.c
|
||||||
@ -70,9 +73,18 @@ AudioPreemphasis_Filter.o: ../src/broadcast_fm/fir_filters/AudioPreemphasis_Filt
|
|||||||
hxcmod.o: ../src/common/hxcmod/hxcmod.c
|
hxcmod.o: ../src/common/hxcmod/hxcmod.c
|
||||||
$(CC) -o $@ -c $< $(CFLAGS)
|
$(CC) -o $@ -c $< $(CFLAGS)
|
||||||
|
|
||||||
|
bmp_file.o: ../src/common/bmp_file.c
|
||||||
|
$(CC) -o $@ -c $< $(CFLAGS)
|
||||||
|
|
||||||
rand_gen.o: ../src/common/rand_gen.c
|
rand_gen.o: ../src/common/rand_gen.c
|
||||||
$(CC) -o $@ -c $< $(CFLAGS)
|
$(CC) -o $@ -c $< $(CFLAGS)
|
||||||
|
|
||||||
|
composite.o: ../src/broadcast_tv/composite.c
|
||||||
|
$(CC) -o $@ -c $< $(CFLAGS)
|
||||||
|
|
||||||
|
broadcast_tv.o: ../src/broadcast_tv/broadcast_tv.c
|
||||||
|
$(CC) -o $@ -c $< $(CFLAGS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf *.o
|
rm -rf *.o
|
||||||
rm -rf *.so
|
rm -rf *.so
|
||||||
|
255
src/broadcast_tv/broadcast_tv.c
Normal file
255
src/broadcast_tv/broadcast_tv.c
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-----------H----H--X----X-----CCCCC----22222----0000-----0000------11----------//
|
||||||
|
//----------H----H----X-X-----C--------------2---0----0---0----0--1--1-----------//
|
||||||
|
//---------HHHHHH-----X------C----------22222---0----0---0----0-----1------------//
|
||||||
|
//--------H----H----X--X----C----------2-------0----0---0----0-----1-------------//
|
||||||
|
//-------H----H---X-----X---CCCCC-----222222----0000-----0000----1111------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//----------------------------------------------------- http://hxc2001.free.fr --//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// File : broadcast_tv.c
|
||||||
|
// Contains: a broadcast TV modulator
|
||||||
|
//
|
||||||
|
// This file is part of rf-tools.
|
||||||
|
//
|
||||||
|
// Written by: Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// Copyright (C) 2023 Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// You are free to do what you want with this code.
|
||||||
|
// A credit is always appreciated if you use it into your product :)
|
||||||
|
//
|
||||||
|
// Change History (most recent first):
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disclaimer / Legal warning : Radio spectrum and the law
|
||||||
|
//
|
||||||
|
// In most countries the use of any radio transmitting device is required to be
|
||||||
|
// either licensed or specifically exempted from licensing under the local regulator.
|
||||||
|
// Other than as used in accordance with a licence (or exemption),
|
||||||
|
// the use of radio equipment is illegal.
|
||||||
|
//
|
||||||
|
// So take care to limit the emitting range and power when testing this software !
|
||||||
|
//
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "wave.h"
|
||||||
|
|
||||||
|
#include "modulator.h"
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include "composite.h"
|
||||||
|
|
||||||
|
#include "bmp_file.h"
|
||||||
|
|
||||||
|
#define IQ_SAMPLE_RATE 16000000
|
||||||
|
|
||||||
|
#define IF_FREQ 0
|
||||||
|
|
||||||
|
#define BUFFER_SAMPLES_SIZE (1024*8)
|
||||||
|
|
||||||
|
#define printf(fmt...) do { \
|
||||||
|
if(!stdoutmode) \
|
||||||
|
fprintf(stdout, fmt); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
int stdoutmode;
|
||||||
|
|
||||||
|
int isOption(int argc, char* argv[],char * paramtosearch,char * argtoparam)
|
||||||
|
{
|
||||||
|
int param=1;
|
||||||
|
int i,j;
|
||||||
|
|
||||||
|
char option[512];
|
||||||
|
|
||||||
|
memset(option,0,512);
|
||||||
|
while(param<=argc)
|
||||||
|
{
|
||||||
|
if(argv[param])
|
||||||
|
{
|
||||||
|
if(argv[param][0]=='-')
|
||||||
|
{
|
||||||
|
memset(option,0,512);
|
||||||
|
|
||||||
|
j=0;
|
||||||
|
i=1;
|
||||||
|
while( argv[param][i] && argv[param][i]!=':')
|
||||||
|
{
|
||||||
|
option[j]=argv[param][i];
|
||||||
|
i++;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !strcmp(option,paramtosearch) )
|
||||||
|
{
|
||||||
|
if(argtoparam)
|
||||||
|
{
|
||||||
|
if(argv[param][i]==':')
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
j=0;
|
||||||
|
while( argv[param][i] )
|
||||||
|
{
|
||||||
|
argtoparam[j]=argv[param][i];
|
||||||
|
i++;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
argtoparam[j]=0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
param++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printhelp(char* argv[])
|
||||||
|
{
|
||||||
|
printf("Options:\n");
|
||||||
|
printf(" -stdout \t\t\t: IQ stream send to stdout\n");
|
||||||
|
printf(" -bmp_file:[BMPFILE.BMP]\t: BMP image file to display\n");
|
||||||
|
printf(" -generate \t\t\t: Generate the video IQ stream\n");
|
||||||
|
printf(" -help \t\t\t: This help\n\n");
|
||||||
|
printf("Example : 525MHz TV broadcasting with an hackrf (currently B&W with PAL-L/SECAM timings and polarity)\n./broadcast_tv -generate -stdout -bmp_file:Philips_PM5544.bmp | hackrf_transfer -f 525000000 -t - -x 47 -a 1 -s 16000000\n");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
unsigned int i,j;
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
char filename[512];
|
||||||
|
|
||||||
|
wave_io * wave1,*wave2;
|
||||||
|
|
||||||
|
double video_buf[BUFFER_SAMPLES_SIZE];
|
||||||
|
composite_state vid_stat;
|
||||||
|
int16_t subcarriers_dbg_wave_buf[BUFFER_SAMPLES_SIZE];
|
||||||
|
uint16_t iq_wave_buf[ BUFFER_SAMPLES_SIZE];
|
||||||
|
|
||||||
|
iq_wave_gen iqgen;
|
||||||
|
bitmap_data bmp_data;
|
||||||
|
|
||||||
|
stdoutmode = 0;
|
||||||
|
|
||||||
|
if(isOption(argc,argv,"stdout",NULL)>0)
|
||||||
|
{
|
||||||
|
stdoutmode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!stdoutmode)
|
||||||
|
{
|
||||||
|
printf("broadcast_tv v0.0.1.1\n");
|
||||||
|
printf("Copyright (C) 2023 Jean-Francois DEL NERO\n");
|
||||||
|
printf("This program comes with ABSOLUTELY NO WARRANTY\n");
|
||||||
|
printf("This is free software, and you are welcome to redistribute it\n");
|
||||||
|
printf("under certain conditions;\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// help option...
|
||||||
|
if(isOption(argc,argv,"help",0)>0)
|
||||||
|
{
|
||||||
|
printhelp(argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(filename,0,sizeof(filename));
|
||||||
|
|
||||||
|
if(isOption(argc,argv,"bmp_file",(char*)&filename)>0)
|
||||||
|
{
|
||||||
|
printf("Input file : %s\n",filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&bmp_data,0,sizeof(bmp_data));
|
||||||
|
if(strlen(filename))
|
||||||
|
{
|
||||||
|
ret = bmp_load(filename,&bmp_data);
|
||||||
|
if( ret >= 0)
|
||||||
|
{
|
||||||
|
printf("BMP file loaded successfully\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("BMP load error %d\n",ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isOption(argc,argv,"generate",0)>0)
|
||||||
|
{
|
||||||
|
// IQ Modulator
|
||||||
|
iqgen.phase = 0;
|
||||||
|
iqgen.Frequency = IF_FREQ;
|
||||||
|
iqgen.Amplitude = 127;
|
||||||
|
iqgen.sample_rate = IQ_SAMPLE_RATE;
|
||||||
|
|
||||||
|
init_composite(&vid_stat, 16000000, 768, 576,bmp_data.data);
|
||||||
|
|
||||||
|
if(stdoutmode)
|
||||||
|
{
|
||||||
|
// stdout / stream mode : IQ are outputed to the stdout -> use a pipe to hackrf_transfer
|
||||||
|
wave1 = create_wave(NULL,iqgen.sample_rate,WAVE_FILE_FORMAT_RAW_8BITS_IQ);
|
||||||
|
wave2 = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// file mode : create iq + wav files
|
||||||
|
wave1 = create_wave("broadcast_tv.iq",iqgen.sample_rate,WAVE_FILE_FORMAT_RAW_8BITS_IQ);
|
||||||
|
wave2 = create_wave("broadcast_tv.wav",16000000,WAVE_FILE_FORMAT_WAV_16BITS_MONO);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0;i<1024*16*2 || stdoutmode;i++)
|
||||||
|
{
|
||||||
|
gen_video_signal(&vid_stat, (double*)&video_buf, BUFFER_SAMPLES_SIZE);
|
||||||
|
for(j=0;j<BUFFER_SAMPLES_SIZE;j++)
|
||||||
|
{
|
||||||
|
subcarriers_dbg_wave_buf[j] = (int)((video_buf[j]/(double)100) * (double)32767);
|
||||||
|
|
||||||
|
iqgen.Amplitude = ((double)video_buf[j]);
|
||||||
|
iq_wave_buf[j] = get_next_iq(&iqgen);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_wave(wave1, &iq_wave_buf,BUFFER_SAMPLES_SIZE);
|
||||||
|
write_wave(wave2, &subcarriers_dbg_wave_buf,BUFFER_SAMPLES_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
close_wave(wave1);
|
||||||
|
close_wave(wave2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( (isOption(argc,argv,"help",0)<=0) &&
|
||||||
|
(isOption(argc,argv,"generate",0)<=0)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
printhelp(argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -32,10 +32,14 @@
|
|||||||
|
|
||||||
#define EQUALIZING_PULSE_LEN 2.35
|
#define EQUALIZING_PULSE_LEN 2.35
|
||||||
#define LINE_PULSE_LEN 4.7
|
#define LINE_PULSE_LEN 4.7
|
||||||
#define ASSERTED_LEVEL 10
|
#define ASSERTED_LEVEL 0
|
||||||
#define DEASSERTED_LEVEL 100
|
#define DEASSERTED_LEVEL 40
|
||||||
|
#define COMPOSITE_LINE_PERIOD_US 64
|
||||||
|
|
||||||
// PAL timings
|
// PAL / Secam : 768 x 576
|
||||||
|
// NTSC : 720 x 480 (Old : 640 x 480)
|
||||||
|
|
||||||
|
// PAL-L timings
|
||||||
pulses_state vertical_blanking[]=
|
pulses_state vertical_blanking[]=
|
||||||
{
|
{
|
||||||
// First sequence of equalizing pulses
|
// First sequence of equalizing pulses
|
||||||
@ -45,8 +49,11 @@ pulses_state vertical_blanking[]=
|
|||||||
// Duration of second sequence of equalizing pulses
|
// Duration of second sequence of equalizing pulses
|
||||||
{ 5, ASSERTED_LEVEL, DEASSERTED_LEVEL, EQUALIZING_PULSE_LEN/(double)1E6 ,((COMPOSITE_LINE_PERIOD_US/2)/(double)1E6),0},
|
{ 5, ASSERTED_LEVEL, DEASSERTED_LEVEL, EQUALIZING_PULSE_LEN/(double)1E6 ,((COMPOSITE_LINE_PERIOD_US/2)/(double)1E6),0},
|
||||||
|
|
||||||
// Lines (6 > 310)
|
// Blank Lines (6 > 23)
|
||||||
{305, ASSERTED_LEVEL, DEASSERTED_LEVEL, LINE_PULSE_LEN/(double)1E6 ,((COMPOSITE_LINE_PERIOD_US)/(double)1E6),0},
|
{18, ASSERTED_LEVEL, DEASSERTED_LEVEL, LINE_PULSE_LEN/(double)1E6 ,((COMPOSITE_LINE_PERIOD_US)/(double)1E6),0},
|
||||||
|
|
||||||
|
// Lines (24 > 310)
|
||||||
|
{287, ASSERTED_LEVEL, DEASSERTED_LEVEL, LINE_PULSE_LEN/(double)1E6 ,((COMPOSITE_LINE_PERIOD_US)/(double)1E6),1},
|
||||||
|
|
||||||
// First sequence of equalizing pulses
|
// First sequence of equalizing pulses
|
||||||
{ 5, ASSERTED_LEVEL, DEASSERTED_LEVEL, EQUALIZING_PULSE_LEN/(double)1E6 ,((COMPOSITE_LINE_PERIOD_US/2)/(double)1E6),0},
|
{ 5, ASSERTED_LEVEL, DEASSERTED_LEVEL, EQUALIZING_PULSE_LEN/(double)1E6 ,((COMPOSITE_LINE_PERIOD_US/2)/(double)1E6),0},
|
||||||
@ -58,8 +65,11 @@ pulses_state vertical_blanking[]=
|
|||||||
// -- end of line 318
|
// -- end of line 318
|
||||||
{ 1, DEASSERTED_LEVEL, DEASSERTED_LEVEL, 0 ,(COMPOSITE_LINE_PERIOD_US/2)/(double)1E6,0},
|
{ 1, DEASSERTED_LEVEL, DEASSERTED_LEVEL, 0 ,(COMPOSITE_LINE_PERIOD_US/2)/(double)1E6,0},
|
||||||
|
|
||||||
// Lines (319 > 622)
|
// Blank Lines (319 > 335)
|
||||||
{304, ASSERTED_LEVEL, DEASSERTED_LEVEL, LINE_PULSE_LEN/(double)1E6 ,(COMPOSITE_LINE_PERIOD_US)/(double)1E6,0},
|
{17, ASSERTED_LEVEL, DEASSERTED_LEVEL, LINE_PULSE_LEN/(double)1E6 ,(COMPOSITE_LINE_PERIOD_US)/(double)1E6,0},
|
||||||
|
|
||||||
|
// Lines (336 > 622)
|
||||||
|
{287, ASSERTED_LEVEL, DEASSERTED_LEVEL, LINE_PULSE_LEN/(double)1E6 ,(COMPOSITE_LINE_PERIOD_US)/(double)1E6,3},
|
||||||
|
|
||||||
// Line 623 - (half)
|
// Line 623 - (half)
|
||||||
{ 1, ASSERTED_LEVEL, DEASSERTED_LEVEL, LINE_PULSE_LEN/(double)1E6 ,((COMPOSITE_LINE_PERIOD_US)/2)/(double)1E6,0},
|
{ 1, ASSERTED_LEVEL, DEASSERTED_LEVEL, LINE_PULSE_LEN/(double)1E6 ,((COMPOSITE_LINE_PERIOD_US)/2)/(double)1E6,0},
|
||||||
@ -69,16 +79,57 @@ pulses_state vertical_blanking[]=
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void init_composite(composite_state * state, int sample_rate, int x_res, int y_res)
|
void init_composite(composite_state * state, int sample_rate, int x_res, int y_res, uint32_t * bmp)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
state->sample_period = (double)1 / (double)sample_rate;
|
state->sample_period = (double)1 / (double)sample_rate;
|
||||||
|
|
||||||
state->buf_x_res = x_res;
|
state->buf_x_res = x_res;
|
||||||
state->buf_y_res = y_res;
|
state->buf_y_res = y_res;
|
||||||
|
|
||||||
state->video_buffer = malloc( x_res * y_res * sizeof(uint32_t) );
|
state->video_buffer = bmp;
|
||||||
if(state->video_buffer)
|
|
||||||
memset(state->video_buffer,0,x_res * y_res * sizeof(uint32_t) );
|
if(!state->video_buffer)
|
||||||
|
{
|
||||||
|
state->video_buffer = malloc( x_res * y_res * sizeof(uint32_t) );
|
||||||
|
if(state->video_buffer)
|
||||||
|
{
|
||||||
|
memset(state->video_buffer,0,x_res * y_res * sizeof(uint32_t) );
|
||||||
|
|
||||||
|
// Basic Mire test init
|
||||||
|
|
||||||
|
for(i=0;i<x_res;i++)
|
||||||
|
state->video_buffer[i] = 0xFFFFFF;
|
||||||
|
|
||||||
|
for(i=0;i<x_res;i++)
|
||||||
|
state->video_buffer[((y_res-1)*x_res) + i] = 0xFFFFFF;
|
||||||
|
|
||||||
|
for(i=0;i<y_res;i++)
|
||||||
|
state->video_buffer[((i)*x_res)] = 0xFFFFFF;
|
||||||
|
|
||||||
|
for(i=0;i<y_res;i++)
|
||||||
|
state->video_buffer[((i)*x_res) + (x_res - 1)] = 0xFFFFFF;
|
||||||
|
|
||||||
|
for(i=0;i<x_res/2;i++)
|
||||||
|
{
|
||||||
|
state->video_buffer[(x_res/4) + (((y_res/4)-1)*x_res) + i] = 0xFFFFFF;
|
||||||
|
state->video_buffer[(x_res/4) + (((y_res/4)-1)*x_res) + i + x_res] = 0xFFFFFF;
|
||||||
|
|
||||||
|
state->video_buffer[(x_res/4) + (((y_res - (y_res/4))-1)*x_res) + i] = 0xFFFFFF;
|
||||||
|
state->video_buffer[(x_res/4) + (((y_res - (y_res/4))-1)*x_res) + i + x_res] = 0xFFFFFF;
|
||||||
|
|
||||||
|
state->video_buffer[(x_res/4) + (((y_res - (y_res/2))-1)*x_res) + i] = 0x6F6F6F;
|
||||||
|
state->video_buffer[(x_res/4) + (((y_res - (y_res/2))-1)*x_res) + i + x_res] = 0x6F6F6F;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=y_res/4;i<(y_res - (y_res/4));i++)
|
||||||
|
{
|
||||||
|
state->video_buffer[(x_res/4) + ((i)*x_res)] = 0xFFFFFF;
|
||||||
|
state->video_buffer[(x_res/4) + ((i)*x_res) + (x_res/4)] = 0x6F6F6F;
|
||||||
|
state->video_buffer[(x_res/2) + ((i)*x_res) + (x_res/4)] = 0xFFFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
state->step_index = 0;
|
state->step_index = 0;
|
||||||
state->cur_state_time = 0;
|
state->cur_state_time = 0;
|
||||||
@ -86,7 +137,7 @@ void init_composite(composite_state * state, int sample_rate, int x_res, int y_r
|
|||||||
|
|
||||||
void gen_video_signal(composite_state * state, double * vid_signal, int buf_size)
|
void gen_video_signal(composite_state * state, double * vid_signal, int buf_size)
|
||||||
{
|
{
|
||||||
int i;
|
int i,xpos;
|
||||||
double value;
|
double value;
|
||||||
|
|
||||||
value = 0;
|
value = 0;
|
||||||
@ -98,6 +149,11 @@ void gen_video_signal(composite_state * state, double * vid_signal, int buf_size
|
|||||||
state->cur_state_time = 0;
|
state->cur_state_time = 0;
|
||||||
state->repeat_cnt++;
|
state->repeat_cnt++;
|
||||||
|
|
||||||
|
if(vertical_blanking[state->step_index].type & 1)
|
||||||
|
state->cur_line_index++;
|
||||||
|
else
|
||||||
|
state->cur_line_index = 0;
|
||||||
|
|
||||||
if( state->repeat_cnt >= vertical_blanking[state->step_index].repeat )
|
if( state->repeat_cnt >= vertical_blanking[state->step_index].repeat )
|
||||||
{
|
{
|
||||||
state->repeat_cnt = 0;
|
state->repeat_cnt = 0;
|
||||||
@ -119,6 +175,35 @@ void gen_video_signal(composite_state * state, double * vid_signal, int buf_size
|
|||||||
value = vertical_blanking[state->step_index].start_val;
|
value = vertical_blanking[state->step_index].start_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(vertical_blanking[state->step_index].type & 1)
|
||||||
|
{
|
||||||
|
if(state->cur_state_time >= vertical_blanking[state->step_index].first_duration)
|
||||||
|
{
|
||||||
|
if(state->cur_state_time >= vertical_blanking[state->step_index].first_duration + ((3.5+4.7)/(double)1E6))
|
||||||
|
{
|
||||||
|
// Stream pixels line
|
||||||
|
if(state->cur_state_time <= vertical_blanking[state->step_index].first_duration + ((3.5+4.7)/(double)1E6) + (45.6/(double)1E6) )
|
||||||
|
{
|
||||||
|
xpos = ((state->cur_state_time - ( vertical_blanking[state->step_index].first_duration + ((3.5+4.7)/(double)1E6) )) / (45.6/(double)1E6)) * state->buf_x_res;
|
||||||
|
|
||||||
|
value = vertical_blanking[state->step_index].end_val;
|
||||||
|
value += ((double)((state->video_buffer[(state->cur_line_index * state->buf_x_res * 2) + ( state->buf_x_res * (((vertical_blanking[state->step_index].type>>1)^1)&1)) + xpos] & 0xFF)) * ((double)((double)100.0 - vertical_blanking[state->step_index].end_val)/(double)256));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = vertical_blanking[state->step_index].end_val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO : Color Burst
|
||||||
|
value = vertical_blanking[state->step_index].end_val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
state->cur_line_index = 0;
|
||||||
|
|
||||||
vid_signal[i] = value;
|
vid_signal[i] = value;
|
||||||
|
|
||||||
state->cur_state_time += state->sample_period;
|
state->cur_state_time += state->sample_period;
|
||||||
|
@ -24,8 +24,6 @@
|
|||||||
// Change History (most recent first):
|
// Change History (most recent first):
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define COMPOSITE_LINE_PERIOD_US 64.0
|
|
||||||
|
|
||||||
typedef struct composite_state_
|
typedef struct composite_state_
|
||||||
{
|
{
|
||||||
double sample_period;
|
double sample_period;
|
||||||
@ -35,6 +33,7 @@ typedef struct composite_state_
|
|||||||
|
|
||||||
uint32_t * video_buffer;
|
uint32_t * video_buffer;
|
||||||
|
|
||||||
|
int cur_line_index;
|
||||||
int step_index;
|
int step_index;
|
||||||
int repeat_cnt;
|
int repeat_cnt;
|
||||||
|
|
||||||
@ -53,5 +52,5 @@ typedef struct pulses_state_
|
|||||||
}pulses_state;
|
}pulses_state;
|
||||||
|
|
||||||
|
|
||||||
void init_composite(composite_state * state, int sample_rate, int x_res, int y_res);
|
void init_composite(composite_state * state, int sample_rate, int x_res, int y_res, uint32_t * bmp);
|
||||||
void gen_video_signal(composite_state * state, double * vid_signal, int buf_size);
|
void gen_video_signal(composite_state * state, double * vid_signal, int buf_size);
|
||||||
|
Loading…
Reference in New Issue
Block a user