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/*