implement NTSC_PAL;
include "ntsc_pal.m";
include "draw.m";
draw : Draw;
include "math.m";
math : Math;
include "sys.m";
sys: Sys;
include "../ppm_dv/ppm_dv.m";
ppmdv : PPM_dv;
Sequence, Pixel, Samples : import ppmdv;
include "../fft/short_fft.m";
fft : FFT;
Complexes : import fft;
C_from_file : import fft;
fft_dir : con "/usr/m/water_fft";
sample_size : con 128;
sample_power : int;
higher_power(x: int) : int
{
pwr := 1;
m := 0;
while(pwr < x) {
m++;
pwr = pwr << 1;
if(m > 100) return -1;
}
return m;
}
fft_pixel(fd : ref Sys->FD, s : ref Sequence, start_frame : big, x, y, rgb : int) : ref Sys->FD
{
cs := fft->C_from_ints(s.frame_pixel(start_frame, sample_size, x, y, rgb), real s.maxvalue);
cs.fft(1, sample_power);
return cs.save(fd, fft_dir, start_frame, x, y);
}
generate_ffts(directory : string, start_frame, end_frame : big) : ref Sequence
{
s := ppmdv->new_sequence(directory);
# for(x := 0; x < s.width; x++) {
# for( y:= 0; y < s.height; y++) {
for(x := 103; x < 150; x++) {
for( y:= 116; y < 150; y++) {
for(frame := start_frame; frame < end_frame; frame++) {
sys->print("x %d y%d frame %bd\n", x, y, frame);
fd := fft_pixel(nil, s, frame, x, y, 'R');
fft_pixel(fd, s, frame, x, y, 'G');
fft_pixel(fd, s, frame, x, y, 'B');
}
}
}
return s;
}
interpolate_ffts(frame : big, x,y, rgb : int, r : real) : ref Complexes
{
case rgb {
'R' => rgb = Rp;
'G' => rgb = Gp;
'B' => rgb = Bp;
}
lowc := C_from_file(sys->sprint("%s/%bd.%d-%d.fft", fft_dir, frame, x, y), 3, rgb);
highc := C_from_file(sys->sprint("%s/%bd.%d-%d.fft", fft_dir, frame + big 1, x, y), 3, rgb);
lowc.interpolate(highc, r);
return lowc;
}
resample(srcdir : string, src_start, src_end : big, targdir : string, trg_start, trg_end : big)
{
s := generate_ffts(srcdir, src_start, src_end);
sys->print("%s", s.info());
nums := big 1 + src_end - src_start;
numt := big 1 + trg_end - trg_start;
st := 1.0 / real nums;
tt := 1.0 / real numt;
r := tt / st;
sys->print("r %f\n", r); # 25 / 30 src_speed / trg_speed
for(tf := big 0; tf < numt; tf++) {
sf := real tf * r;
s1 := int math->floor(sf);
r2 := sf - real s1;
r1 := 1.0 - r2;
for(x:=0; x < s.width; x++) {
for( y := 0; y < s.height; y++) {
cr := interpolate_ffts(src_start + big s1, x, y, 'R', r1);
cg := interpolate_ffts(src_start + big s1, x, y, 'G', r1);
cb := interpolate_ffts(src_start + big s1, x, y, 'B', r1);
}
}
break;
}
}
test1() {
start_frame := big 100;
s := ppmdv->new_sequence("/usr/m/water_pal");
s.width = 1; s.height = 1; sys->print("one pixel only 0,0\n");
ints := s.frame_pixel(start_frame, sample_size, 0, 0, 'R');
cs := fft->C_from_ints(ints, real s.maxvalue);
cs.print("x", "y");
fd := cs.save(nil, fft_dir, start_frame, 0, 0); # r only !
if(fd == nil) {
sys->print("NOT SAVED\n");
} else {
sys->print("SAVED / NOW LOAD\n");
cl := C_from_file("/usr/m/water_fft/100.0-0.fft", 1, 0);
cl.print("x'", "y'");
}
}
test2() {
start_frame := big 100;
s := ppmdv->new_sequence("/usr/m/water_pal");
s.width = 1; s.height = 1; sys->print("one pixel only 0,0\n");
ints := s.frame_pixel(start_frame, sample_size, 0, 0, 'R');
cs := fft->C_from_ints(ints, real s.maxvalue);
cs.print("x", "y");
cs.fft(1, sample_power);
cs.print("f", "a");
fd := cs.save(nil, fft_dir, start_frame, 0, 0); # r only !
if(fd == nil) {
sys->print("NOT SAVED\n");
} else {
sys->print("SAVED\n");
cs.fft(-1, sample_power);
cs.print("x'", "y'");
sys->print("NOW LOAD\n");
cl := C_from_file("/usr/m/water_fft/100.0-0.fft", 1, 0);
cl.print("f", "a");
cl.fft(-1, sample_power);
cl.print("x", "y");
}
}
sample_ffts(seq : ref Sequence, s : ref Samples, low_ffts : ref Complexes, low_f, high_f : big, r : real) : (ref Complexes, ref Complexes)
{
high_ffts : ref Complexes;
if(high_f == low_f) {
high_ffts = low_ffts;
} else {
s.advance_to(seq, big high_f);
high_ffts = fft->C_from_reals(s.in_sequence());
high_ffts.fft(1, sample_power);
low_ffts.interpolate(high_ffts, real high_f - r);
}
return (low_ffts, high_ffts);
}
pal_to_ntsc(seq : ref Sequence, pal_startframe, pal_endframe : big)
{
src_fps := 25.0;
target_fps := 29.97;
ratio := src_fps / target_fps;
ntsc_frames := big (ratio * (real pal_endframe - real pal_startframe));
ntsc := ref Sequence(0, "/usr/m/water_ntsc", ntsc_frames, seq.width, seq.height, seq.maxvalue, seq.bpp);
pixel := Pixel(big 0, 0, 0, 0, 0);
w := chan of ref Pixel;
spread := big 8;
midpixel := 4;
spawn(ppmdv->write_to_pixel(ntsc, w));
for(pixel.x = 0; pixel.x < seq.width; pixel.x++)
for(pixel.y = 0; pixel.y < seq.height; pixel.y++)
for(pixel.channel = 0; pixel.channel < 3; pixel.channel++) {
pixel.frame = pal_startframe;
samples := seq.sample_set(pixel.frame - spread, pixel.frame + spread, pixel.x, pixel.y, pixel.channel);
smp := samples.in_sequence();
pixel.v = int (real ntsc.maxvalue * smp[midpixel]);
w <-= ref pixel;
# eliminated for testing
if(0) {
low_ffts : ref Complexes;
result : ref Complexes;
high_f : big;
low_f : big;
for(r := ratio; pixel.frame++ < pal_startframe + ntsc_frames; r += ratio) {
low_f = big math->floor(r);
if(low_f != high_f) {
samples.advance_to(seq, big low_f);
low_ffts = fft->C_from_reals(samples.in_sequence());
low_ffts.fft(1, sample_power);
}
high_f = big math->ceil(r);
(result, low_ffts) = sample_ffts(seq, samples, low_ffts, low_f, high_f, r);
result.fft(-1, sample_power);
smp = samples.in_sequence();
pixel.v = int (real seq.maxvalue * smp[midpixel]);
w <-= ref pixel;
}
w <- = nil;
}
}
}
init(nil: ref Draw->Context, nil: list of string)
{
draw = load Draw Draw->PATH;
sys = load Sys Sys->PATH;
math = load Math Math->PATH;
ppmdv = load PPM_dv "../ppm_dv/ppm_dv.dis";
ppmdv->init(nil, nil);
sample_power = higher_power(sample_size);
fft = load FFT "/usr/m/fft/short_fft.dis";
fft->init(nil, nil);
# test2();
s := ppmdv->new_sequence("/usr/m/water_pal");
s.scan();
pal_to_ntsc(s, big 100, big 125);
# generate_ffts("/usr/m/water_pal", big 199, big 200);
# resample("/usr/m/water_pal", big 100, big 125, "/usr/m/water_ntsc", big 100, big 130);
sys->print("whee\n");
}
# Put Limbo ntsc_pal
# rm /usr/m/water_fft/*
|