diff -Naur gramofile-1.6-old/bplaysrc/sndfunc.c gramofile-1.6/bplaysrc/sndfunc.c --- gramofile-1.6-old/bplaysrc/sndfunc.c 2000-03-27 23:40:01.000000000 +0200 +++ gramofile-1.6/bplaysrc/sndfunc.c 2004-05-12 09:20:51.000000000 +0200 @@ -22,6 +22,7 @@ /* Globals */ int audio, abuf_size, fmt_mask; +int audio_recorder; /* Prototypes */ void sync_audio(void); @@ -36,6 +37,7 @@ void init_sound(int recorder) { /* Attempt to open the audio device */ + audio_recorder = recorder; audio = open(AUDIO, (recorder)? O_RDONLY : O_WRONLY); if (audio == -1) ErrDie(AUDIO); @@ -76,6 +78,9 @@ void sync_audio(void) { + /* at least Linux' via82cxxx_audio-driver reports error */ + /* when trying to SNDCTL_DSP_SYNC in O_RDONLY mode */ if (ioctl (audio, SNDCTL_DSP_SYNC, NULL) < 0) + if (!audio_recorder) ErrDie(AUDIO); } diff -Naur gramofile-1.6-old/dirfilemenu.h gramofile-1.6/dirfilemenu.h --- gramofile-1.6-old/dirfilemenu.h 2000-03-28 23:07:26.000000000 +0200 +++ gramofile-1.6/dirfilemenu.h 2004-05-12 09:20:51.000000000 +0200 @@ -21,4 +21,12 @@ 1 if dir, then new complete dirname in dirfile */ +/* + * Used to define the file menus used in various places + */ +#define DIR_FILEMENU_WIDTH 70 +#define DIR_FILEMENU_HEIGHT 12 +#define DIR_FILEMENU_X 5 +#define DIR_FILEMENU_Y 3 + #endif /* HAVE_DIRFILEMENU_H */ diff -Naur gramofile-1.6-old/endian.h gramofile-1.6/endian.h --- gramofile-1.6-old/endian.h 2000-03-28 23:07:26.000000000 +0200 +++ gramofile-1.6/endian.h 2004-05-12 09:20:51.000000000 +0200 @@ -8,4 +8,10 @@ extern u_long SwapFourBytes (u_long); extern sample_t SwapSample (sample_t); +/* macro to swap endianness of values in a sample_t with */ +/* a few 32-bit operations -- very fast */ +#define SWAPSAMPLEREF(s) *((uint32_t *)(s)) = \ + ((*((uint32_t *)(s)) & 0xff00ff00) >> 8) | \ + ((*((uint32_t *)(s)) & 0x00ff00ff) << 8) + #endif diff -Naur gramofile-1.6-old/endian.h~ gramofile-1.6/endian.h~ --- gramofile-1.6-old/endian.h~ 1970-01-01 01:00:00.000000000 +0100 +++ gramofile-1.6/endian.h~ 2000-03-28 23:07:26.000000000 +0200 @@ -0,0 +1,11 @@ +/* Header file for endian.c */ +/* Joshua Weage gte855f@prism.gatech.edu */ + +#ifndef _GETBIG +#define _GETBIG 1 + +extern u_short SwapTwoBytes (u_short); +extern u_long SwapFourBytes (u_long); +extern sample_t SwapSample (sample_t); + +#endif diff -Naur gramofile-1.6-old/Makefile gramofile-1.6/Makefile --- gramofile-1.6-old/Makefile 2000-03-28 22:23:58.000000000 +0200 +++ gramofile-1.6/Makefile 2004-05-12 09:20:51.000000000 +0200 @@ -7,7 +7,8 @@ signpr_general.c signpr_median.c signpr_filtmenu.c signpr_wav.c \ secshms.c playwav.c signpr_cmf.c signpr_mean.c signpr_doubmed.c \ splashscr.c tracksplit.c tracksplit_filenm.c \ - tracksplit_parammenu.c signpr_cmf2.c signpr_rms.c signpr_copy.c \ + tracksplit_parammenu.c signpr_cmf2.c signpr_cmf3.c \ + signpr_rms.c signpr_copy.c \ signpr_exper.c endian.c signpr_mono.c signpr_l1fit.c OBJS = $(SRCS:.c=.o) @@ -19,21 +20,21 @@ ########## CHOOSE YOUR ARCHITECTURE: (NOTE: also see bplaysrc/Makefile!) # For Linux (and maybe others), use these: -CFLAGS = -Wall -O2 -DTURBO_MEDIAN -DTURBO_BUFFER +CFLAGS = -Wall -O4 -funroll-loops -DTURBO_MEDIAN -DTURBO_BUFFER DEPS = $(OBJS) makebplay -LIBS = -lncurses -lm +LIBS = -lncurses -lrfftw -lfftw -lm COPY_A = -a # For FreeBSD (and maybe others), use these: #CFLAGS = -Wall -O2 -DTURBO_MEDIAN -DTURBO_BUFFER #DEPS = $(OBJS) makebplay -#LIBS = -lncurses -lm +#LIBS = -lncurses -lrfftw -lfftw -lm #COPY_A = -p # For IRIX (and maybe others), use these: #CFLAGS = -Wall -O2 -DTURBO_MEDIAN -DTURBO_BUFFER -DSWAP_ENDIAN -DOLD_CURSES #DEPS = $(OBJS) -#LIBS = -lcurses -lm +#LIBS = -lcurses -lrfftw -lfftw -lm #COPY_A = -a ########## diff -Naur gramofile-1.6-old/Makefile~ gramofile-1.6/Makefile~ --- gramofile-1.6-old/Makefile~ 1970-01-01 01:00:00.000000000 +0100 +++ gramofile-1.6/Makefile~ 2004-05-12 09:20:51.000000000 +0200 @@ -0,0 +1,79 @@ +PROG = gramofile + +SRCS = boxes.c buttons.c checkfile.c dirfilemenu.c errorwindow.c \ + gramofile.c mainmenu.c reclp_filenm.c reclp_main.c scrollmenu.c \ + stringinput.c textwindow.c yesnowindow.c clrscr.c helpline.c \ + signpr_main.c signpr_infilenm.c signpr_outfilenm.c \ + signpr_general.c signpr_median.c signpr_filtmenu.c signpr_wav.c \ + secshms.c playwav.c signpr_cmf.c signpr_mean.c signpr_doubmed.c \ + splashscr.c tracksplit.c tracksplit_filenm.c \ + tracksplit_parammenu.c signpr_cmf2.c signpr_rms.c signpr_copy.c \ + signpr_exper.c endian.c signpr_mono.c signpr_l1fit.c + +OBJS = $(SRCS:.c=.o) +SHELL = /bin/sh + +CC = gcc +LDFLAGS = + +########## CHOOSE YOUR ARCHITECTURE: (NOTE: also see bplaysrc/Makefile!) + +# For Linux (and maybe others), use these: +CFLAGS = -Wall -O4 -funroll-loops -DTURBO_MEDIAN -DTURBO_BUFFER +DEPS = $(OBJS) makebplay +LIBS = -lncurses -lm +COPY_A = -a + +# For FreeBSD (and maybe others), use these: +#CFLAGS = -Wall -O2 -DTURBO_MEDIAN -DTURBO_BUFFER +#DEPS = $(OBJS) makebplay +#LIBS = -lncurses -lm +#COPY_A = -p + +# For IRIX (and maybe others), use these: +#CFLAGS = -Wall -O2 -DTURBO_MEDIAN -DTURBO_BUFFER -DSWAP_ENDIAN -DOLD_CURSES +#DEPS = $(OBJS) +#LIBS = -lcurses -lm +#COPY_A = -a + +########## + + +$(PROG): $(DEPS) + $(CC) $(LDFLAGS) $(OBJS) -o $(PROG) $(LIBS) + @echo '' + @echo '' + @echo '' + @echo " If you're one of those that didn't read the README, please do so now." + @echo '' + +makebplay: yesnowindow.o boxes.o buttons.o textwindow.o errorwindow.o \ + clrscr.o secshms.o + $(MAKE) -C bplaysrc + -rm bplay_gramo brec_gramo + cp $(COPY_A) bplaysrc/bplay ./bplay_gramo + ln -s bplay_gramo brec_gramo + +.PHONY: clean +clean: + $(MAKE) -C bplaysrc clean + -rm -f gramofile bplay_gramo brec_gramo *.o *.d *~ + +.PHONY: indent +indent: + indent *.c *.h + +#%.d: %.c - according to 'info make', doesn't work +# $(SHELL) -ec '$(CC) -MM $(CPPFLAGS) $< \ +# | sed '\''s/\($*\)\.o[ :]*/\1 $@/g'\'' > $@' +# +# 'some.o: some.c other.h' ==> 'some some.dsome.c other.h' + +%.d: %.c + $(SHELL) -ec '$(CC) -MM $(CPPFLAGS) $< \ + | sed '\''s/\($*\)\.o/& $@/g'\'' > $@' +# +# 'some.o: some.c other.h' ==> 'some.o some.d: some.c other.h' => OK + +include $(SRCS:.c=.d) + diff -Naur gramofile-1.6-old/playwav.c gramofile-1.6/playwav.c --- gramofile-1.6-old/playwav.c 2000-03-28 23:07:25.000000000 +0200 +++ gramofile-1.6/playwav.c 2004-05-12 09:20:51.000000000 +0200 @@ -44,11 +44,11 @@ case FILE_EXISTS: if (usebeginendtime) - sprintf (shellcmd, "bplay_gramo -S -s 44100 -b 16 -J %ld -T %ld %s", + sprintf (shellcmd, "bplay_gramo -S -s 44100 -b 16 -J %ld -T %ld \"%s\"", (long) (begintime * 44100), (long) ((endtime - begintime) * 44100), filename); else - sprintf (shellcmd, "bplay_gramo -S -s 44100 -b 16 %s", filename); + sprintf (shellcmd, "bplay_gramo -S -s 44100 -b 16 \"%s\"", filename); /* defaults for raw files (but no -r, so .wav's supply their own parameters) - you can even listen to executables in CD quality (: */ @@ -188,10 +188,10 @@ " Back to main menu. TAB: Next field", " Play the specified (part of the) sound file. TAB: Next field"}; - dirfilelist.y = 3; - dirfilelist.x = 5; - dirfilelist.h = 12; - dirfilelist.w = 32; + dirfilelist.y = DIR_FILEMENU_Y; + dirfilelist.x = DIR_FILEMENU_X; + dirfilelist.h = DIR_FILEMENU_HEIGHT; + dirfilelist.w = DIR_FILEMENU_WIDTH; dirfilelist.firstonscreen = 0; dirfilemenu (startdir, &dirfilelist); dirfilelist.selected = dirfilelist.last_of_1st_part + 1; @@ -771,11 +771,11 @@ def_prog_mode (); /* save terminal state */ if (usebeginendtime) - sprintf (shellcmd, "bplay_gramo -S -s 44100 -b 16 -J %ld -T %ld %s", + sprintf (shellcmd, "bplay_gramo -S -s 44100 -b 16 -J %ld -T %ld \"%s\"", (long) (begintime * 44100), (long) ((endtime - begintime) * 44100), filename); else - sprintf (shellcmd, "bplay_gramo -S -s 44100 -b 16 %s", filename); + sprintf (shellcmd, "bplay_gramo -S -s 44100 -b 16 \"%s\"", filename); /* defaults for raw files (but no -r, so .wav's supply their own parameters */ diff -Naur gramofile-1.6-old/reclp_filenm.c gramofile-1.6/reclp_filenm.c --- gramofile-1.6-old/reclp_filenm.c 2000-03-28 23:07:25.000000000 +0200 +++ gramofile-1.6/reclp_filenm.c 2004-05-12 09:20:51.000000000 +0200 @@ -56,10 +56,10 @@ " Start `xmixer' to adjust recording volumes. TAB: Next field", " Start recording in the specified sound file. TAB: Next field"}; - dirfilelist.y = 3; - dirfilelist.x = 5; - dirfilelist.h = 12; - dirfilelist.w = 32; + dirfilelist.y = DIR_FILEMENU_Y; + dirfilelist.x = DIR_FILEMENU_X; + dirfilelist.h = DIR_FILEMENU_HEIGHT; + dirfilelist.w = DIR_FILEMENU_WIDTH; dirfilelist.firstonscreen = 0; dirfilemenu (startdir, &dirfilelist); dirfilelist.selected = dirfilelist.last_of_1st_part + 1; diff -Naur gramofile-1.6-old/reclp_main.c gramofile-1.6/reclp_main.c --- gramofile-1.6-old/reclp_main.c 2000-03-28 23:07:25.000000000 +0200 +++ gramofile-1.6/reclp_main.c 2004-05-12 09:20:51.000000000 +0200 @@ -30,7 +30,7 @@ def_prog_mode (); /* save terminal state */ - sprintf (shellcmd, "brec_gramo -S -s 44100 -b 16 -t 6000 -w %s", + sprintf (shellcmd, "brec_gramo -S -s 44100 -b 16 -t 6000 -w \"%s\"", filename); system (shellcmd); diff -Naur gramofile-1.6-old/signpr_cmf2.c gramofile-1.6/signpr_cmf2.c --- gramofile-1.6-old/signpr_cmf2.c 2000-03-28 23:07:25.000000000 +0200 +++ gramofile-1.6/signpr_cmf2.c 2004-05-12 09:20:51.000000000 +0200 @@ -646,19 +646,25 @@ /* Should be /64, but the signal is extremely soft, so divide by less to get more quantization levels (more accurate) */ - sum.left /= 10; - sum.right /= 10; + sum.left /= 4; + sum.right /= 4; #endif - if (sum.left < 32767) - sample.left = sum.left; - else + if (sum.left > 32767) sample.left = 32767; - - if (sum.right < 32767) - sample.right = sum.right; + else if (sum.left < -32768) + sample.left = -32768; else + sample.left = sum.left; + + + if (sum.right > 32767) sample.right = 32767; + else if (sum.right < -32768) + sample.right = -32768; + else + sample.right = sum.right; + return sample; } @@ -762,6 +768,9 @@ b_t.left; if (i > 32767) i = 32767; + else if (i < -32768) + i = -32768; + returnval.left = i; i = (labs (w_t.right - b_t.right) * 1000) @@ -769,6 +778,8 @@ b_t.right; if (i > 32767) i = 32767; + else if (i < -32768) + i = -32768; returnval.right = i; return returnval; diff -Naur gramofile-1.6-old/signpr_cmf3.c gramofile-1.6/signpr_cmf3.c --- gramofile-1.6-old/signpr_cmf3.c 1970-01-01 01:00:00.000000000 +0100 +++ gramofile-1.6/signpr_cmf3.c 2004-05-12 09:20:51.000000000 +0200 @@ -0,0 +1,1085 @@ +/* Conditional Median Filter - Better Version + * Using fft and eliminating high frequencies + * to fill over the ticks. + * + * Copyright (C) 1998 J.A. Bezemer + * 2001 S.J. Tappin + * + * Licensed under the terms of the GNU General Public License. + * ABSOLUTELY NO WARRANTY. + * See the file `COPYING' in this directory. + */ + +/* Remove the `dont' to get the gate instead of the normal output - useful + for verifying properties. */ +#define dontVIEW_INTERNALS + +/* Choose the highpass filter: */ +#define noSECOND_ORDER +#define FOURTH_ORDER +#define noSIXTH_ORDER + +#define noDEBUGFILE + +#include "signpr_cmf3.h" +#include "signpr_general.h" +#include "signpr_l1fit.h" +#include "errorwindow.h" +#include "stringinput.h" +#include "buttons.h" +#include "clrscr.h" +#include "boxes.h" +#include "helpline.h" +#include "yesnowindow.h" +#include +#include +#include +#ifndef OLD_CURSES +#include +#else +#include +#endif + +#ifdef DEBUGFILE +static FILE *debugf=NULL; +#endif + +#ifndef M_PIl +# define M_PIl 3.1415926535897932384626433832795029L /* pi */ +#endif + +void +cond_median3_param_defaults (parampointer_t parampointer) +{ + parampointer->postlength2 = 4; + parampointer->prelength2 = 4; + parampointer->postlength3 = 5; + parampointer->prelength3 = 5; + parampointer->postlength4 = 256; + parampointer->prelength4 = 255; + + parampointer->int1 = 12; + parampointer->int2 = 9; /* This could be derived from + postlength4 and prelength4, + but it's messy */ +#if defined (SECOND_ORDER) + parampointer->long1 = 1000; /* Threshold to detect precise tick length. */ + parampointer->long2 = 2500; /* Must be above this to be a tick. */ +#elif defined (FOURTH_ORDER) + parampointer->long1 = 2000; + parampointer->long2 = 8500; +#elif defined (SIXTH_ORDER) + parampointer->long1 = 1500; + parampointer->long2 = 7500; +#else +#error A Highpass version must be defined (signpr_cmf3.c) +#endif + +} + + +#ifdef FOURTH_ORDER +#undef SIGNPR_CMF3_PARAMSCR_HEADERTEXT +#define SIGNPR_CMF3_PARAMSCR_HEADERTEXT "CMF IIF [FOURTH ORDER] - Parameters" +#endif + +#ifdef SIXTH_ORDER +#undef SIGNPR_CMF3_PARAMSCR_HEADERTEXT +#define SIGNPR_CMF3_PARAMSCR_HEADERTEXT "CMF IIF [SIXTH ORDER] - Parameters" +#endif + +void +cond_median3_param_screen (parampointer_t parampointer) +{ + stringinput_t rmslengthstr, rmflengthstr, decimatestr, threshold1str; + stringinput_t threshold2str, fftstr; + button_t ok_button, cancel_button, defaults_button; + int dont_stop = TRUE; + int focus = 0; + int in_ch; + int i; + long helplong; + + char *helplines[9] = + { + " ^: less ticks detected. v: not all of tick interpolated. ", + " ^: bad following of dynamics. v: less ticks detected. ", + " ^: bad following of dynamics. v: less ticks detected. ", + " ^: detected tick length too short v: detected tick length longer. ", + " ^: only strong ticks detected. v: music-ticks also filtered out. ", + " ^: Slower interpolation v: possible problems with long ticks ", + " Discard changes. ", + " Reset default values. ", + " Accept changes. "}; + + rmslengthstr.maxlen = 500; + rmslengthstr.string = (char *) malloc (rmslengthstr.maxlen * + sizeof (char)); + sprintf (rmslengthstr.string, "%ld", parampointer->prelength2 + + parampointer->postlength2 + 1); + rmslengthstr.y = 6; + rmslengthstr.x = 59; + rmslengthstr.w = 19; + rmslengthstr.cursorpos = strlen (rmslengthstr.string); + rmslengthstr.firstcharonscreen = 0; + + rmflengthstr.maxlen = 500; + rmflengthstr.string = (char *) malloc (rmflengthstr.maxlen * + sizeof (char)); + sprintf (rmflengthstr.string, "%ld", parampointer->prelength3 + + parampointer->postlength3 + 1); + rmflengthstr.y = 8; + rmflengthstr.x = 59; + rmflengthstr.w = 19; + rmflengthstr.cursorpos = strlen (rmflengthstr.string); + rmflengthstr.firstcharonscreen = 0; + + decimatestr.maxlen = 500; + decimatestr.string = (char *) malloc (decimatestr.maxlen * + sizeof (char)); + sprintf (decimatestr.string, "%d", parampointer->int1); + decimatestr.y = 10; + decimatestr.x = 59; + decimatestr.w = 19; + decimatestr.cursorpos = strlen (decimatestr.string); + decimatestr.firstcharonscreen = 0; + + threshold1str.maxlen = 500; + threshold1str.string = (char *) malloc (threshold1str.maxlen * + sizeof (char)); + sprintf (threshold1str.string, "%ld", parampointer->long1); + threshold1str.y = 12; + threshold1str.x = 59; + threshold1str.w = 19; + threshold1str.cursorpos = strlen (threshold1str.string); + threshold1str.firstcharonscreen = 0; + + threshold2str.maxlen = 500; + threshold2str.string = (char *) malloc (threshold2str.maxlen * + sizeof (char)); + sprintf (threshold2str.string, "%ld", parampointer->long2); + threshold2str.y = 14; + threshold2str.x = 59; + threshold2str.w = 19; + threshold2str.cursorpos = strlen (threshold2str.string); + threshold2str.firstcharonscreen = 0; + + fftstr.maxlen = 500; + fftstr.string = (char *) malloc (fftstr.maxlen * + sizeof (char)); + sprintf (fftstr.string, "%d", parampointer->int2); + fftstr.y = 16; + fftstr.x = 59; + fftstr.w = 19; + fftstr.cursorpos = strlen (fftstr.string); + fftstr.firstcharonscreen = 0; + + + ok_button.text = " OK "; + ok_button.y = 20; + ok_button.x = 71; + ok_button.selected = FALSE; + + cancel_button.text = " Cancel "; + cancel_button.y = 20; + cancel_button.x = 5; + cancel_button.selected = FALSE; + + defaults_button.text = " Defaults "; + defaults_button.y = 20; + defaults_button.x = 36; + defaults_button.selected = FALSE; + + clearscreen (SIGNPR_CMF3_PARAMSCR_HEADERTEXT); + + do + { + header (SIGNPR_CMF3_PARAMSCR_HEADERTEXT); + + if (focus == 6) + cancel_button.selected = TRUE; + else + cancel_button.selected = FALSE; + + if (focus == 7) + defaults_button.selected = TRUE; + else + defaults_button.selected = FALSE; + + if (focus == 8) + ok_button.selected = TRUE; + else + ok_button.selected = FALSE; + + mvprintw (3, 2, + "See also the Signproc.txt file for the meaning of the parameters."); + + stringinput_display (&rmslengthstr); + mvprintw (rmslengthstr.y, 2, + "Length of the RMS operation (samples):"); + + stringinput_display (&rmflengthstr); + mvprintw (rmflengthstr.y, 2, + "Length of the recursive median operation (samples):"); + + stringinput_display (&decimatestr); + mvprintw (decimatestr.y, 2, + "Decimation factor for the recursive median:"); + + stringinput_display (&threshold1str); + mvprintw (threshold1str.y, 2, + "Fine threshold for tick start/end (thousandths):"); + + stringinput_display (&threshold2str); + mvprintw (threshold2str.y, 2, + "Threshold for detection of tick presence (thousandths):"); + + stringinput_display (&fftstr); + mvprintw (fftstr.y, 2, + "Length for fft to interpolate (2^n):"); + + button_display (&cancel_button); + mybox (cancel_button.y - 1, cancel_button.x - 1, + 3, strlen (cancel_button.text) + 2); + button_display (&defaults_button); + mybox (defaults_button.y - 1, defaults_button.x - 1, + 3, strlen (defaults_button.text) + 2); + button_display (&ok_button); + mybox (ok_button.y - 1, ok_button.x - 1, + 3, strlen (ok_button.text) + 2); + + helpline (helplines[focus]); + + switch (focus) + { + case 0: + stringinput_display (&rmslengthstr); + break; + case 1: + stringinput_display (&rmflengthstr); + break; + case 2: + stringinput_display (&decimatestr); + break; + case 3: + stringinput_display (&threshold1str); + break; + case 4: + stringinput_display (&threshold2str); + break; + case 5: + stringinput_display (&fftstr); + break; + default: + move (0, 79); + } + + refresh (); + + in_ch = getch (); + + switch (focus) + { + case 0: /* rmslengthstr */ + stringinput_stdkeys (in_ch, &rmslengthstr); + switch (in_ch) + { + case KEY_ENTER: + case 13: + i = sscanf (rmslengthstr.string, "%li", &helplong); + if (i < 1 || helplong < 1 || helplong % 2 == 0) + error_window ("A whole, odd number, greater than 0, must \ +be specified."); + else + focus++; + break; + + case KEY_UP: + focus--; + break; + case KEY_DOWN: + focus++; + break; + } + break; + + case 1: /* rmflengthstr */ + stringinput_stdkeys (in_ch, &rmflengthstr); + switch (in_ch) + { + case KEY_ENTER: + case 13: + i = sscanf (rmflengthstr.string, "%li", &helplong); + if (i < 1 || helplong < 1 || helplong % 2 == 0) + error_window ("A whole, odd number, greater than 0, must \ +be specified."); + else + focus++; + break; + + case KEY_UP: + focus--; + break; + case KEY_DOWN: + focus++; + break; + } + break; + + case 2: /* decimatestr */ + stringinput_stdkeys (in_ch, &decimatestr); + switch (in_ch) + { + case KEY_ENTER: + case 13: + i = sscanf (decimatestr.string, "%li", &helplong); + if (i < 1 || helplong < 1) + error_window ("A whole number, greater than 0, must \ +be specified."); + else + focus++; + break; + + case KEY_UP: + focus--; + break; + case KEY_DOWN: + focus++; + break; + } + break; + + case 3: /* threshold1str */ + stringinput_stdkeys (in_ch, &threshold1str); + switch (in_ch) + { + case KEY_ENTER: + case 13: + i = sscanf (threshold1str.string, "%li", &helplong); + if (i < 1 || helplong < 1) + error_window ("A whole, positive number must be specified."); + else + focus++; + break; + + case KEY_UP: + focus--; + break; + case KEY_DOWN: + focus++; + break; + } + break; + + case 4: /* threshold2str */ + stringinput_stdkeys (in_ch, &threshold2str); + switch (in_ch) + { + case KEY_ENTER: + case 13: + i = sscanf (threshold2str.string, "%li", &helplong); + if (i < 1 || helplong < 1) + error_window ("A whole, positive number must be specified."); + else + focus++; + break; + + case KEY_UP: + focus--; + break; + case KEY_DOWN: + focus++; + break; + } + break; + + case 5: /* fft length */ + stringinput_stdkeys (in_ch, &fftstr); + switch (in_ch) + { + case KEY_ENTER: + case 13: + i = sscanf (fftstr.string, "%li", &helplong); + if (i < 1 || helplong > 12 || helplong < 6) + error_window ("A number between 6 and 12 must be specified."); + else + focus = 8; + break; + + case KEY_UP: + focus--; + break; + case KEY_DOWN: + focus++; + break; + } + break; + + case 6: /* Cancel */ + switch (in_ch) + { + case KEY_ENTER: + case 13: + dont_stop = FALSE; + break; + + case KEY_LEFT: + case KEY_UP: + focus--; + break; + case KEY_RIGHT: + case KEY_DOWN: + focus++; + break; + } + break; + + case 7: /* Defaults */ + switch (in_ch) + { + case KEY_ENTER: + case 13: + if (yesno_window ("Restore default parameters?", " Yes ", + " No ", 0)) + { + cond_median3_param_defaults (parampointer); + dont_stop = FALSE; + } + break; + + case KEY_LEFT: + case KEY_UP: + focus--; + break; + case KEY_RIGHT: + case KEY_DOWN: + focus++; + break; + } + break; + + case 8: /* OK */ + switch (in_ch) + { + case KEY_ENTER: + case 13: + + i = sscanf (rmslengthstr.string, "%li", &helplong); + if (i < 1 || helplong < 1 || helplong % 2 == 0) + { + error_window ("A whole, odd number, greater than 0, must \ +be specified as RMS length."); + rmslengthstr.cursorpos = + strlen (rmslengthstr.string); + focus = 0; + break; + } + + parampointer->prelength2 = (helplong - 1) / 2; + parampointer->postlength2 = (helplong - 1) / 2; + + i = sscanf (rmflengthstr.string, "%li", &helplong); + if (i < 1 || helplong < 1 || helplong % 2 == 0) + { + error_window ("A whole, odd number, greater than 0, must \ +be specified as length of the recursive median."); + rmflengthstr.cursorpos = + strlen (rmflengthstr.string); + focus = 1; + break; + } + + parampointer->prelength3 = (helplong - 1) / 2; + parampointer->postlength3 = (helplong - 1) / 2; + + i = sscanf (decimatestr.string, "%li", &helplong); + if (i < 1 || helplong < 1) + { + error_window ("A whole number, greater than 0, must \ +be specified as decimation factor."); + decimatestr.cursorpos = + strlen (decimatestr.string); + focus = 2; + break; + } + + parampointer->int1 = helplong; + + i = sscanf (threshold1str.string, "%li", &helplong); + if (i < 1 || helplong < 1) + { + error_window ("A whole, positive number must be \ +specified as threshold."); + threshold1str.cursorpos = + strlen (threshold1str.string); + focus = 3; + break; + } + + parampointer->long1 = helplong; + + i = sscanf (threshold2str.string, "%li", &helplong); + if (i < 1 || helplong < 1000) + { + error_window ("A whole, positive number must be \ +specified as threshold."); + threshold2str.cursorpos = + strlen (threshold2str.string); + focus = 4; + break; + } + + parampointer->long2 = helplong; + + i = sscanf (fftstr.string, "%li", &helplong); + if (i < 1 || helplong > 12 || helplong < 6) { + error_window ("A number between 6 and 12 must be specified \ +as fft length"); + fftstr.cursorpos = strlen(fftstr.string); + focus = 5; + break; + } + + parampointer->int2 = helplong; + parampointer->prelength4 = 1; + for (i=1; i < parampointer->int2; i++) parampointer->prelength4 *= 2; + parampointer->postlength4 = parampointer->prelength4-1; + + dont_stop = FALSE; + break; + + case KEY_LEFT: + case KEY_UP: + focus--; + break; + case KEY_RIGHT: + case KEY_DOWN: + focus++; + break; + } + break; + } + + if (in_ch == 9) /* TAB */ + focus++; + + if (in_ch == 27) + dont_stop = FALSE; + + if (focus > 8) + focus = 0; + if (focus < 0) + focus = 8; + } + while (dont_stop); + + free (rmslengthstr.string); + free (rmflengthstr.string); + free (decimatestr.string); + free (threshold1str.string); + free (threshold2str.string); +} + +void +init_cond_median3_filter (int filterno, parampointer_t parampointer) +{ + long total_post; + long total_pre; + long l; + + total_post = parampointer->postlength4 + parampointer->prelength4 + 1 + 4; + /* +1+4=+5 : for highpass, max. 11th order */ + + total_pre = parampointer->postlength4 + parampointer->prelength4 + 1; + l = parampointer->prelength4 + parampointer->prelength3 * + parampointer->int1 + parampointer->prelength2 + 5; + /* + 5 : for highpass, max. 11th order */ + if (l > total_pre) + total_pre = l; + + parampointer->buffer = init_buffer (total_post, total_pre); + parampointer->buffer2 = init_buffer (parampointer->postlength2, + parampointer->prelength2); + parampointer->buffer3 = init_buffer (parampointer->postlength3, + parampointer->prelength3 * parampointer->int1); + parampointer->buffer4 = init_buffer (parampointer->postlength4, + parampointer->prelength4); + + parampointer->filterno = filterno; + + /* Set up the FFT plans here. Since we expect to do lots of FFTs, + we take the time to MEASURE the best way to do them [SJT] */ + + parampointer->planf = rfftw_create_plan(parampointer->postlength4 + + parampointer->prelength4 + 1, + FFTW_REAL_TO_COMPLEX, + FFTW_MEASURE); + parampointer->planr = rfftw_create_plan(parampointer->postlength4 + + parampointer->prelength4 + 1, + FFTW_COMPLEX_TO_REAL, + FFTW_MEASURE); + +#ifdef DEBUGFILE + debugf = fopen("./gram.txt","w"); +#endif + + +} + + +void +delete_cond_median3_filter (parampointer_t parampointer) +{ + delete_buffer (¶mpointer->buffer); + delete_buffer (¶mpointer->buffer2); + delete_buffer (¶mpointer->buffer3); + delete_buffer (¶mpointer->buffer4); + + rfftw_destroy_plan(parampointer->planf); + rfftw_destroy_plan(parampointer->planr); + +#ifdef DEBUGFILE + fclose(debugf); +#endif +} + + +sample_t +cond_median3_highpass (long offset, long offset_zero, + parampointer_t parampointer) +{ + sample_t sample; + longsample_t sum; + + offset += offset_zero; /* middle for highpass filter in + 'big buffer' */ + sum.left = 0; + sum.right = 0; + +#if defined (SECOND_ORDER) +#define notTEST_DAVE_PLATT +#ifndef TEST_DAVE_PLATT + /* Original: */ + sample = get_from_buffer (¶mpointer->buffer, offset - 1); + sum.left += sample.left; + sum.right += sample.right; + sample = get_from_buffer (¶mpointer->buffer, offset); + sum.left -= 2 * (long) sample.left; + sum.right -= 2 * (long) sample.right; + sample = get_from_buffer (¶mpointer->buffer, offset + 1); + sum.left += sample.left; + sum.right += sample.right; + + sum.left /= 4; + sum.right /= 4; +#else /* TEST_DAVE_PLATT */ + /* Testing, suggested by Dave Platt. Invert phase of one channel, then + do tick detection using the sum signal. This is because most ticks + are out-of-phase signals. I've not really tested this - it might + require other settings for thresholds etc. + Note: implemented for second_order only! */ + sample = get_from_buffer (¶mpointer->buffer, offset - 1); + sum.left += sample.left; + sum.left -= sample.right; + sample = get_from_buffer (¶mpointer->buffer, offset); + sum.left -= 2 * (long) sample.left; + sum.left += 2 * (long) sample.right; + sample = get_from_buffer (¶mpointer->buffer, offset + 1); + sum.left += sample.left; + sum.left -= sample.right; + + /* just in case L/R: 32000/-32000 -32000/32000 32000/-32000 : */ + sum.left /= 8; + sum.right = sum.left; +#endif /* TEST_DAVE_PLATT */ + +#elif defined (FOURTH_ORDER) + sample = get_from_buffer (¶mpointer->buffer, offset - 2); + sum.left += sample.left; + sum.right += sample.right; + sample = get_from_buffer (¶mpointer->buffer, offset - 1); + sum.left -= 4 * (long) sample.left; + sum.right -= 4 * (long) sample.right; + sample = get_from_buffer (¶mpointer->buffer, offset); + sum.left += 6 * (long) sample.left; + sum.right += 6 * (long) sample.right; + sample = get_from_buffer (¶mpointer->buffer, offset + 1); + sum.left -= 4 * (long) sample.left; + sum.right -= 4 * (long) sample.right; + sample = get_from_buffer (¶mpointer->buffer, offset + 2); + sum.left += sample.left; + sum.right += sample.right; + + sum.left /= 4; + sum.right /= 4; + +#elif defined (SIXTH_ORDER) + sample = get_from_buffer (¶mpointer->buffer, offset - 3); + sum.left -= sample.left; + sum.right -= sample.right; + sample = get_from_buffer (¶mpointer->buffer, offset - 2); + sum.left += 6 * (long) sample.left; + sum.right += 6 * (long) sample.right; + sample = get_from_buffer (¶mpointer->buffer, offset - 1); + sum.left -= 15 * (long) sample.left; + sum.right -= 15 * (long) sample.right; + sample = get_from_buffer (¶mpointer->buffer, offset); + sum.left += 20 * (long) sample.left; + sum.right += 20 * (long) sample.right; + sample = get_from_buffer (¶mpointer->buffer, offset + 1); + sum.left -= 15 * (long) sample.left; + sum.right -= 15 * (long) sample.right; + sample = get_from_buffer (¶mpointer->buffer, offset + 2); + sum.left += 6 * (long) sample.left; + sum.right += 6 * (long) sample.right; + sample = get_from_buffer (¶mpointer->buffer, offset + 3); + sum.left -= sample.left; + sum.right -= sample.right; + + /* Should be /64, but the signal is extremely soft, so divide by less to + get more quantization levels (more accurate) */ + sum.left /= 4; + sum.right /= 4; +#endif + + if (sum.left > 32767) + sample.left = 32767; + else if (sum.left < -32768) + sample.left = -32768; + else + sample.left = sum.left; + + + if (sum.right > 32767) + sample.right = 32767; + else if (sum.right < -32768) + sample.right = -32768; + else + sample.right = sum.right; + + + return sample; +} + +fillfuncpointer_t cond_median3_highpass_pointer = cond_median3_highpass; + +sample_t +cond_median3_rms (long offset, long offset_zero, + parampointer_t parampointer) +{ + sample_t sample; + doublesample_t doublesample; + doublesample_t sum; + long i; + + advance_current_pos_custom (¶mpointer->buffer2, + cond_median3_highpass_pointer, + offset + offset_zero, + parampointer); + + sum.left = 0; + sum.right = 0; + + for (i = -parampointer->postlength2; i <= parampointer->prelength2; + i++) + { + sample = get_from_buffer (¶mpointer->buffer2, i); + doublesample.left = sample.left; + doublesample.right = sample.right; + sum.left += doublesample.left * doublesample.left; + sum.right += doublesample.right * doublesample.right; + } + + sum.left /= (parampointer->postlength2 + + parampointer->prelength2 + 1); + sum.right /= (parampointer->postlength2 + + parampointer->prelength2 + 1); + + sample.left = sqrt (sum.left + 1); + sample.right = sqrt (sum.right + 1); + + return sample; +} + +fillfuncpointer_t cond_median3_rms_pointer = cond_median3_rms; + +sample_t +cond_median3_gate (long offset, long offset_zero, + parampointer_t parampointer) +/* Well, not a `gate' any more - just (w[t]-b[t])/b[t], comparision to + make the real gate is done later. */ +{ + sample_t sample; + sample_t w_t; + sample_t b_t; + sample_t returnval; + signed short list1[parampointer->postlength3 + + parampointer->prelength3 * parampointer->int1 + 1]; + signed short list2[parampointer->postlength3 + + parampointer->prelength3 * parampointer->int1 + 1]; + long i, j; + + advance_current_pos_custom (¶mpointer->buffer3, + cond_median3_rms_pointer, + offset + offset_zero, + parampointer); + + w_t = get_from_buffer (¶mpointer->buffer3, 0); + + /* The RMF Filter */ + + for (i = 0; i < parampointer->postlength3; i++) + { + sample = get_from_buffer (¶mpointer->buffer3, + i - parampointer->postlength3); + list1[i] = sample.left; + list2[i] = sample.right; + } + + j = i; + + for (; i <= parampointer->postlength3 + + parampointer->prelength3 * parampointer->int1; + i += parampointer->int1) + { + sample = get_from_buffer (¶mpointer->buffer3, + i - parampointer->postlength3); + list1[j] = sample.left; + list2[j] = sample.right; + j++; + } + + b_t.left = median (list1, j); + b_t.right = median (list2, j); + + put_in_buffer (¶mpointer->buffer3, 0, b_t); + + + i = (labs (w_t.left - b_t.left) * 1000) + / + b_t.left; + if (i > 32767) + i = 32767; + else if (i < -32768) + i = -32768; + + returnval.left = i; + + i = (labs (w_t.right - b_t.right) * 1000) + / + b_t.right; + if (i > 32767) + i = 32767; + else if (i < -32768) + i = -32768; + returnval.right = i; + + return returnval; +} + +fillfuncpointer_t cond_median3_gate_pointer = cond_median3_gate; + +sample_t +cond_median3_filter (parampointer_t parampointer) +{ + sample_t sample, gate, returnval; + /* Length of the fft we'll do to get the smoothed interpolate */ + + fftw_real list3[parampointer->postlength4 + + parampointer->prelength4 + 1]; + fftw_real list4[parampointer->postlength4 + + parampointer->prelength4 + 1]; + + long fft_l = parampointer->postlength4 + parampointer->prelength4 + 1; + long i; + int toleft, toright, nfreq; + signed short maxval; + + advance_current_pos (¶mpointer->buffer, parampointer->filterno); + + advance_current_pos_custom (¶mpointer->buffer4, + cond_median3_gate_pointer, + 0, + parampointer); + + gate = get_from_buffer (¶mpointer->buffer4, 0); + +#ifdef VIEW_INTERNALS + returnval.left = 0; + returnval.right = 0; +#else + /* 'Default' value - unchanged if there is no tick */ + returnval = get_from_buffer (¶mpointer->buffer, 0); +#endif + + if (gate.left > parampointer->long1) + { + maxval = gate.left; + + toleft = -1; + sample.left = 0; + do + { + toleft++; + if (toleft < parampointer->postlength4) + { + sample = get_from_buffer (¶mpointer->buffer4, -toleft - 1); + if (sample.left > maxval) + /* if so, the `while' will continue anyway, so maxval may + be adjusted here already (if necessary) */ + maxval = sample.left; + } + } + while (toleft < parampointer->postlength4 && + sample.left > parampointer->long1); + + toright = -1; + sample.left = 0; + do + { + toright++; + if (toright < parampointer->prelength4) + { + sample = get_from_buffer (¶mpointer->buffer4, toright + 1); + if (sample.left > maxval) + /* if so, the `while' will continue anyway, so maxval may + be adjusted here already (if necessary) */ + maxval = sample.left; + } + } + while (toright < parampointer->prelength4 && + sample.left > parampointer->long1); + + /* only interpolate if there really is a tick */ + if (maxval > parampointer->long2) + { + +#ifdef VIEW_INTERNALS + returnval.left = (toright + toleft + 1) * 500; +#else + + /* Use a HANNING window here for the time being; note that + the FFT is centred at the middle of the tick not at the + point we are interpolating. */ + for (i = 0; i < fft_l; i++) + { + list3[i] = get_from_buffer(¶mpointer->buffer, + i - parampointer->prelength4 + + (toright - toleft + 1)/2).left * + (2.-cos(2.*M_PIl*(double) i/ ((double) fft_l - 1.)))/2.; + } + rfftw_one(parampointer->planf, list3, list4); + nfreq=floor((double) fft_l/(double) (2*(toleft+toright+1))); + for (i = 2*nfreq; i <= fft_l - 2*nfreq; i++) list4[i] = 0.; + for (i = nfreq; i<2*nfreq && i< fft_l/2; i++) { + list4[i] *= (1. - (double) (i-nfreq)/ (double) nfreq); + list4[fft_l-i] *= (1. - (double) (i-nfreq)/ (double) nfreq); + } + rfftw_one(parampointer->planr, list4, list3); + returnval.left = (signed short) (list3[parampointer->prelength4 - + (toright - toleft + 1)/2]/ + (double) fft_l); + + /* DON'T ASK !!! -- I have NO idea why I have to MULTIPLY by + the hanning window here. Everything sensible says DIVIDE, but + multiply works, divide doesn't */ + + returnval.left *= (2.-cos(2.*M_PIl*(double) ((toright - toleft + 1)/2) / + ((double) fft_l - 1.)))/2.; +#ifdef DEBUGFILE + fprintf(debugf, "L: %ld %d %ld %ld\n", + fft_l, (toleft+toright+1), nfreq, + fft_l-nfreq); +#endif + +#endif + } + } + + if (gate.right > parampointer->long1) + { + maxval = gate.right; + + toleft = -1; + sample.right = 0; + do + { + toleft++; + if (toleft < parampointer->postlength4) + { + sample = get_from_buffer (¶mpointer->buffer4, -toleft - 1); + if (sample.right > maxval) + /* if so, the `while' will continue anyway, so maxval may + be adjusted here already (if necessary) */ + maxval = sample.right; + } + } + while (toleft < parampointer->postlength4 && + sample.right > parampointer->long1); + + toright = -1; + sample.right = 0; + do + { + toright++; + if (toright < parampointer->prelength4) + { + sample = get_from_buffer (¶mpointer->buffer4, toright + 1); + if (sample.right > maxval) + /* if so, the `while' will continue anyway, so maxval may + be adjusted here already (if necessary) */ + maxval = sample.right; + } + } + while (toright < parampointer->prelength4 && + sample.right > parampointer->long1); + + /* only interpolate if there really is a tick */ + if (maxval > parampointer->long2) + { + +#ifdef VIEW_INTERNALS + returnval.right = (toright + toleft + 1) * 500; +#else + /* Use a HANNING window here for the time being; note that + the FFT is centred at the middle of the tick not at the + point we are interpolating. */ + for (i = 0; i < fft_l; i++) + { + list3[i] = get_from_buffer(¶mpointer->buffer, + i - parampointer->prelength4 + + (toright - toleft + 1)/2).right * + (2.-cos(2.*M_PIl*(double) i/ ((double) fft_l - 1.)))/2.; + } + rfftw_one(parampointer->planf, list3, list4); + + nfreq=floor((double) fft_l/(double) (2*(toleft+toright+1))); + for (i = 2*nfreq; i <= fft_l - 2*nfreq; i++) list4[i] = 0.; + for (i = nfreq; i<2*nfreq && iplanr, list4, list3); + returnval.right = (signed short) (list3[parampointer->prelength4 - + (toright - toleft + 1)/2]/ + (double) fft_l) ; + + /* DON'T ASK !!! -- I have NO idea why I have to MULTIPLY by + the hanning window here. Everything sensible says DIVIDE, but + multiply works, divide doesn't */ + + returnval.right *= (2.-cos(2.*M_PIl*(double) ((toright - toleft + 1)/2) / + ((double) fft_l - 1.)))/2.; +#ifdef DEBUGFILE + fprintf(debugf, "R: %ld %d %ld %ld\n", + fft_l, (toleft+toright+1), nfreq, + fft_l - nfreq); +#endif + +#endif + } + } + + return returnval; +} diff -Naur gramofile-1.6-old/signpr_cmf3.h gramofile-1.6/signpr_cmf3.h --- gramofile-1.6-old/signpr_cmf3.h 1970-01-01 01:00:00.000000000 +0100 +++ gramofile-1.6/signpr_cmf3.h 2004-05-12 09:20:51.000000000 +0200 @@ -0,0 +1,29 @@ +/* Simple Median Filter - Better Version - Header + + * Copyright (C) 1998 J.A. Bezemer + * + * Licensed under the terms of the GNU General Public License. + * ABSOLUTELY NO WARRANTY. + * See the file `COPYING' in this directory. + */ + +#ifndef HAVE_SIGNPR_CMF3_H +#define HAVE_SIGNPR_CMF3_H + + +#include "signpr_general.h" + +#define SIGNPR_CMF3_PARAMSCR_HEADERTEXT "Conditional Median Filter IIF - Parameters" + +void cond_median3_param_defaults (parampointer_t parampointer); + +void cond_median3_param_screen (parampointer_t parampointer); + +void init_cond_median3_filter (int filterno, parampointer_t parampointer); + +void delete_cond_median3_filter (parampointer_t parampointer); + +sample_t cond_median3_filter (parampointer_t parampointer); + + +#endif /* HAVE_SIGNPR_CMF3_H */ diff -Naur gramofile-1.6-old/SIGNPR_CMF3.TXT gramofile-1.6/SIGNPR_CMF3.TXT --- gramofile-1.6-old/SIGNPR_CMF3.TXT 1970-01-01 01:00:00.000000000 +0100 +++ gramofile-1.6/SIGNPR_CMF3.TXT 2004-05-12 09:20:51.000000000 +0200 @@ -0,0 +1,42 @@ +SIGNPR_CMF3 +=========== + +James Tappin: April 2001 + +Signpr_cmf3 is a modification of signpr_cmf2, which uses a +frequency-domain method to fill in the ticks. + +Why?: Because although cmf2 does an excellent job of detecting ticks, +it makes a horrid mess of interpolating those that are close the peak +of a sound wave (a situation which occurs very often on some 78's -- +indeed on some of my record the majority of the clicks are on peaks) +and the resulting sound can then be worse than the original. + +What to do?: Since cmf2 does a very good job of picking out ticks that +bit is unchanged, my goal here was to find a way that would smooth over +the tick without cutting off more-or-less a half-cycle of the sound +wave. Since the tick is located at the peak, and zeroth (the original +cmf2) or first (FANCY_FILL) order interpolation will cut off the peak +and thus cause an acoustically unpleasant breakup of the +sound. Therefore I have here attempted to take a FFT of a region around +the tick then exclude frequencies corresponding to features of the +length of the tick or smaller. In the present version this is done by +setting the components above this frequency to zero. + +Problems: It's slow -- If I could see a way to do 1 fft per tick rather +than 1 fft per interpolated point it could go much quicker, but I don't +see that this can be done within the gramofile buffers framework. + +What does it need: The fft's are done using the "fastest fourier +transform in the west" http://www.fftw.org/ which attempts to find an +optimum way of doing the fft for the architecture and the size of the +transform. In order to hold the fft plans and the length of the fft, 3 +new fields are added to the parampointer variable. + +Settings: The tick identification algorithm is identical with that used +in cmf2 and the settings are therefore the same. The choice of fft +length is determined as: Too large a value will slow the computation +(remember fft is an n log(n) process), while too small a value results +in a poor smoothing as the side lobes of the tick are have a larger +effect on the values. The default is 2^9 (512). + diff -Naur gramofile-1.6-old/signpr_filtmenu.c gramofile-1.6/signpr_filtmenu.c --- gramofile-1.6-old/signpr_filtmenu.c 2000-03-28 23:07:25.000000000 +0200 +++ gramofile-1.6/signpr_filtmenu.c 2004-05-12 09:20:51.000000000 +0200 @@ -17,6 +17,7 @@ #include "stringinput.h" #include "secshms.h" #include +#include #include #ifndef OLD_CURSES #include @@ -31,19 +32,36 @@ char **helptexts, scrollmenu_t * selectedfilts, int *usetracktimes, int *usebeginendtime, - double *begintime, double *endtime) + double *begintime, double *endtime, + int *adjustframes, long *framesize) /* Returns 0: canceled, 1: PrevScreen, 2: NextScreen */ { +#define FILTLIST_FOCUS 0 +#define SELFILTS_FOCUS 1 +#define BEGINTIME_FOCUS 6 +#define ENDTIME_FOCUS 7 +#define PREV_FOCUS 8 +#define NEXT_FOCUS 10 +#define CANCEL_FOCUS 9 +#define TRACKTIME_FOCUS 2 +#define BEGINEND_FOCUS 5 +#define ADJUSTFRAMES_FOCUS 3 +#define FRAMESIZE_FOCUS 4 +#define NUM_WIDGETS 11 + button_t next_button, cancel_button, prev_button; button_t beginend_check, tracktimes_check; stringinput_t begintimestring, endtimestring; + stringinput_t framesizestring; + button_t adjustframes_check; int dont_stop = TRUE; int returnval = 0; - int focus = 0; + int focus = FILTLIST_FOCUS; int in_ch; int i; double tempdouble = 0; char tempstring[250]; + long templong = 0; char *emptyhelpline = " TAB: Next field"; @@ -51,11 +69,13 @@ int maxhelplength = 62; char helphelpline[100]; - char *helplines[9] = + char *helplines[11] = { " Enter: Add selected filter. TAB: Next field", " Enter: Parameters U/D: Move R/Del: Delete TAB: Next field", " Use the .tracks file to split tracks. TAB: Next field", + " Adjust track lengths to frame size multiples TAB: Next field", + " Enter frame size for length adjustment TAB: Next field", " Process only the specified part of the sound. TAB: Next field", " Enter begin time of part to be processed. TAB: Next field", " Enter end time of part to be processed. TAB: Next field", @@ -82,7 +102,6 @@ selectedfilts->firstonscreen = 0; selectedfilts->selected = 0; - begintimestring.maxlen = 500; begintimestring.string = (char *) malloc ( begintimestring.maxlen * sizeof (char)); @@ -128,6 +147,21 @@ beginend_check.x = 42; beginend_check.selected = FALSE; + adjustframes_check.text = ""; + adjustframes_check.y = 17; + adjustframes_check.x = 4; + adjustframes_check.selected = FALSE; + + framesizestring.maxlen = 500; + framesizestring.string = (char *) malloc ( + framesizestring.maxlen * sizeof (char)); + sprintf( framesizestring.string, "%ld", *framesize ); + framesizestring.y = 18; + framesizestring.x = 21; + framesizestring.w = 8; + framesizestring.cursorpos = strlen (framesizestring.string); + framesizestring.firstcharonscreen = 0; + clearscreen (SIGNPR_FILTMENU_HEADERTEXT); do @@ -144,33 +178,43 @@ else beginend_check.text = "[ ] Use begin and end times"; - if (focus == 2) + if (*adjustframes) + adjustframes_check.text = "[X] Adjust to whole frames"; + else + adjustframes_check.text = "[ ] Adjust to whole frames"; + + if (focus == TRACKTIME_FOCUS) tracktimes_check.selected = TRUE; else tracktimes_check.selected = FALSE; - if (focus == 3) + if (focus == BEGINEND_FOCUS) beginend_check.selected = TRUE; else beginend_check.selected = FALSE; - if (focus == 6) + if (focus == ADJUSTFRAMES_FOCUS) + adjustframes_check.selected = TRUE; + else + adjustframes_check.selected = FALSE; + + if (focus == PREV_FOCUS) prev_button.selected = TRUE; else prev_button.selected = FALSE; - if (focus == 7) + if (focus == CANCEL_FOCUS) cancel_button.selected = TRUE; else cancel_button.selected = FALSE; - if (focus == 8) + if (focus == NEXT_FOCUS) next_button.selected = TRUE; else next_button.selected = FALSE; - filtlist->hasfocus = (focus == 0); - selectedfilts->hasfocus = (focus == 1); + filtlist->hasfocus = (focus == FILTLIST_FOCUS); + selectedfilts->hasfocus = (focus == SELFILTS_FOCUS); scrollmenu_display (filtlist); mybox (filtlist->y - 1, filtlist->x - 1, @@ -192,6 +236,10 @@ mvprintw (endtimestring.y, endtimestring.x - 12, "End time :"); + stringinput_display( &framesizestring ); + mvprintw (framesizestring.y, framesizestring.x - 12, + "Frame size:" ); + button_display (&prev_button); mybox (prev_button.y - 1, prev_button.x - 1, 3, strlen (prev_button.text) + 2); @@ -204,8 +252,9 @@ button_display (&tracktimes_check); button_display (&beginend_check); + button_display (&adjustframes_check); - if (focus == 0) + if (focus == FILTLIST_FOCUS) { strcpy (helphelpline, emptyhelpline); @@ -222,10 +271,12 @@ else helpline (helplines[focus]); - if (focus == 4) + if (focus == BEGINTIME_FOCUS) stringinput_display (&begintimestring); - else if (focus == 5) + else if (focus == ENDTIME_FOCUS) stringinput_display (&endtimestring); + else if (focus == FRAMESIZE_FOCUS) + stringinput_display (&framesizestring); else move (0, 79); @@ -235,7 +286,7 @@ switch (focus) { - case 0: /* filtlist */ + case FILTLIST_FOCUS: if (scrollmenu_stdkeys (in_ch, filtlist) >= 0) { if (selectedfilts->number < MAX_FILTERS) @@ -270,7 +321,7 @@ } break; - case 1: /* selectedfilts */ + case SELFILTS_FOCUS: if (scrollmenu_stdkeys (in_ch, selectedfilts) >= 0) { if (number_of_filters > 0) @@ -372,7 +423,7 @@ } break; - case 2: /* Use tracksplitting data */ + case TRACKTIME_FOCUS: switch (in_ch) { case KEY_ENTER: @@ -396,7 +447,29 @@ } break; - case 3: /* Use begin/end times */ + case ADJUSTFRAMES_FOCUS: + switch (in_ch) + { + case KEY_ENTER: + case 13: + case ' ': + case 'x': + case 'X': + *adjustframes = 1 - *adjustframes; + break; + + case KEY_LEFT: + case KEY_UP: + focus--; + break; + case KEY_RIGHT: + case KEY_DOWN: + focus++; + break; + } + break; + + case BEGINEND_FOCUS: switch (in_ch) { case KEY_ENTER: @@ -420,7 +493,7 @@ } break; - case 4: /* begin time */ + case BEGINTIME_FOCUS: stringinput_stdkeys (in_ch, &begintimestring); switch (in_ch) { @@ -453,7 +526,7 @@ } break; - case 5: /* end time */ + case ENDTIME_FOCUS: stringinput_stdkeys (in_ch, &endtimestring); switch (in_ch) { @@ -473,7 +546,7 @@ fsec2hmsf (tempdouble, endtimestring.string); endtimestring.cursorpos = strlen (endtimestring.string); - focus = 8; + focus = NEXT_FOCUS; } break; @@ -487,7 +560,39 @@ break; - case 6: /* < Previous */ + case FRAMESIZE_FOCUS: + stringinput_stdkeys( in_ch, &framesizestring ); + switch (in_ch){ + case KEY_ENTER: + case 13: + templong = atol( framesizestring.string ); + if (templong < 1){ + error_window( "Enter a whole number greater than 0, preferably\ + a multiple of 588." ); + framesizestring.cursorpos = strlen( framesizestring.string ); + }else{ + if (templong % 588 != 0) + error_window( "Warning: You may insist on this value, but \ +it's not a multiple of 588." ); + else + focus++; + *framesize = templong; + sprintf( framesizestring.string, "%ld", templong ); + framesizestring.cursorpos = strlen( framesizestring.string ); + } + break; + + case KEY_UP: + focus--; + break; + case KEY_DOWN: + focus++; + break; + } + break; + + + case PREV_FOCUS: if (in_ch == KEY_ENTER || in_ch == 13) { returnval = 1; @@ -507,7 +612,7 @@ } break; - case 7: /* Cancel */ + case CANCEL_FOCUS: if (in_ch == KEY_ENTER || in_ch == 13) { returnval = 0; @@ -527,13 +632,13 @@ } break; - case 8: /* Next > */ + case NEXT_FOCUS: if (in_ch == KEY_ENTER || in_ch == 13) { if (number_of_filters < 1) { error_window ("No filters have been selected."); - focus = 0; + focus = FILTLIST_FOCUS; break; } @@ -544,7 +649,7 @@ minutes:seconds.fractions, for example 0:04:26.740"); begintimestring.cursorpos = strlen (begintimestring.string); - focus = 4; + focus = BEGINTIME_FOCUS; break; } @@ -557,7 +662,7 @@ minutes:seconds.fractions, for example 0:04:26.740"); endtimestring.cursorpos = strlen (endtimestring.string); - focus = 5; + focus = ENDTIME_FOCUS; break; } @@ -572,10 +677,23 @@ fsec2hmsf (*endtime, endtimestring.string); endtimestring.cursorpos = strlen (endtimestring.string); - focus = 4; + focus = BEGINTIME_FOCUS; break; } + templong = atol( framesizestring.string ); + if (templong < 1){ + error_window( "Enter a whole number greater than 0, preferably a multiple of 588." ); + framesizestring.cursorpos = strlen( framesizestring.string ); + focus = FRAMESIZE_FOCUS; + break; + } + if (templong % 588 != 0){ + error_window( "Warning: This value is not a multiple of 588." ); + } + *framesize = templong; + + returnval = 2; dont_stop = FALSE; } @@ -601,10 +719,10 @@ if (in_ch == 27) dont_stop = FALSE; - if (focus > 8) - focus -= 9; + if (focus >= NUM_WIDGETS) + focus -= NUM_WIDGETS; if (focus < 0) - focus += 9; + focus += NUM_WIDGETS; } while (dont_stop); diff -Naur gramofile-1.6-old/signpr_filtmenu.h gramofile-1.6/signpr_filtmenu.h --- gramofile-1.6-old/signpr_filtmenu.h 2000-03-28 23:07:26.000000000 +0200 +++ gramofile-1.6/signpr_filtmenu.h 2004-05-12 09:20:51.000000000 +0200 @@ -27,7 +27,8 @@ char **helptexts, scrollmenu_t * selectedfilts, int *usetracktimes, int *usebeginendtime, - double *begintime, double *endtime); + double *begintime, double *endtime, + int *adjustframes, long *framesize); #endif /* HAVE_SIGNPR_FILTMENU_H */ diff -Naur gramofile-1.6-old/signpr_general.c gramofile-1.6/signpr_general.c --- gramofile-1.6-old/signpr_general.c 2000-03-28 23:07:26.000000000 +0200 +++ gramofile-1.6/signpr_general.c 2004-05-12 09:20:51.000000000 +0200 @@ -14,6 +14,7 @@ #include "signpr_wav.h" #include "signpr_cmf.h" #include "signpr_cmf2.h" +#include "signpr_cmf3.h" #include "signpr_mean.h" #include "signpr_doubmed.h" #include "signpr_rms.h" @@ -511,6 +512,13 @@ add_to_filterlist (filtlist, filtnumbers, helptexts, + COND_MEDIAN3_FILTER, + COND_MEDIAN3_NAME, + COND_MEDIAN3_HELPTEXT); + + add_to_filterlist (filtlist, + filtnumbers, + helptexts, EXPERIMENT_FILTER, EXPERIMENT_NAME, EXPERIMENT_HELPTEXT); @@ -559,6 +567,10 @@ return monoize_filter (parampointerarray[filterno]); break; + case COND_MEDIAN3_FILTER: + return cond_median3_filter (parampointerarray[filterno]); + break; + case EXPERIMENT_FILTER: return experiment_filter (parampointerarray[filterno]); break; @@ -615,6 +627,10 @@ init_monoize_filter (i, parampointerarray[i]); break; + case COND_MEDIAN3_FILTER: + init_cond_median3_filter (i, parampointerarray[i]); + break; + case EXPERIMENT_FILTER: init_experiment_filter (i, parampointerarray[i]); break; @@ -671,6 +687,10 @@ delete_monoize_filter (parampointerarray[i]); break; + case COND_MEDIAN3_FILTER: + delete_cond_median3_filter (parampointerarray[i]); + break; + case EXPERIMENT_FILTER: delete_experiment_filter (parampointerarray[i]); break; @@ -724,6 +744,10 @@ monoize_param_defaults (parampointer); break; + case COND_MEDIAN3_FILTER: + cond_median3_param_defaults (parampointer); + break; + case EXPERIMENT_FILTER: experiment_param_defaults (parampointer); break; @@ -777,6 +801,10 @@ monoize_param_screen (parampointer); break; + case COND_MEDIAN3_FILTER: + cond_median3_param_screen (parampointer); + break; + case EXPERIMENT_FILTER: experiment_param_screen (parampointer); break; diff -Naur gramofile-1.6-old/signpr_general.h gramofile-1.6/signpr_general.h --- gramofile-1.6-old/signpr_general.h 2000-03-28 23:07:26.000000000 +0200 +++ gramofile-1.6/signpr_general.h 2004-05-12 09:20:51.000000000 +0200 @@ -13,6 +13,9 @@ #include "scrollmenu.h" +/* This has to be here, otherwise the FFT interpolating filter + can't keep its plans [SJT] */ +#include /* SAMPLES */ @@ -70,9 +73,12 @@ signed short *sslist1; signed short *sslist2; - int int1; + int int1, int2; long long1; long long2; + + rfftw_plan planf, planr; + } param_t; @@ -221,7 +227,12 @@ #define MONOIZE_HELPTEXT \ "Average left & right signals." -#define EXPERIMENT_FILTER 9 +#define COND_MEDIAN3_FILTER 9 +#define COND_MEDIAN3_NAME "Conditional Median Filter IIF" +#define COND_MEDIAN3_HELPTEXT \ +"Remove ticks while not changing rest of signal - Using freq domain interp." + +#define EXPERIMENT_FILTER 10 #define EXPERIMENT_NAME "Experimenting Filter" #define EXPERIMENT_HELPTEXT \ "The filter YOU are experimenting with (in signpr_exper.c)" diff -Naur gramofile-1.6-old/signpr_infilenm.c gramofile-1.6/signpr_infilenm.c --- gramofile-1.6-old/signpr_infilenm.c 2000-03-28 23:07:26.000000000 +0200 +++ gramofile-1.6/signpr_infilenm.c 2004-05-12 09:20:51.000000000 +0200 @@ -54,10 +54,10 @@ " Back to main menu. TAB: Next field", " To Signal Processing - Filter Selection. TAB: Next field"}; - dirfilelist.y = 3; - dirfilelist.x = 5; - dirfilelist.h = 12; - dirfilelist.w = 32; + dirfilelist.y = DIR_FILEMENU_Y; + dirfilelist.x = DIR_FILEMENU_X; + dirfilelist.h = DIR_FILEMENU_HEIGHT; + dirfilelist.w = DIR_FILEMENU_WIDTH; dirfilelist.firstonscreen = 0; dirfilemenu (startdir, &dirfilelist); dirfilelist.selected = dirfilelist.last_of_1st_part + 1; diff -Naur gramofile-1.6-old/signpr_main.c gramofile-1.6/signpr_main.c --- gramofile-1.6-old/signpr_main.c 2000-03-28 23:07:26.000000000 +0200 +++ gramofile-1.6/signpr_main.c 2004-05-12 09:20:51.000000000 +0200 @@ -33,7 +33,8 @@ scrollmenu_t * filtlist, int *filtnumbers, char **helptexts, scrollmenu_t * selectedfilts, int *usetracktimes, int *usebeginendtime, - double *begintime, double *endtime) + double *begintime, double *endtime, + int *adjustframes, long *framesize) { int currscreen = 0; int options_ready = 0; @@ -80,7 +81,8 @@ switch (signproc_select_filters (filtlist, filtnumbers, helptexts, selectedfilts, usetracktimes, - usebeginendtime, begintime, endtime)) + usebeginendtime, begintime, endtime, + adjustframes, framesize )) /* 0: Cancel, 1: PreviousScreen, 2: NextScreen/Start */ @@ -283,6 +285,8 @@ static char *selectedfilts_items[MAX_FILTERS]; static int usebeginendtime = 0, usetracktimes = 1; static double begintime = 0, endtime = 0; + static int adjustframes = 0; + static long framesize = 588; /* 1/75 sec. @ 44.1 khz */ struct stat buf; int i; @@ -291,7 +295,6 @@ beginendsample_t tracktimes[100]; /* max. 99 tracks: 1 (!) - 99 */ int number_of_tracks; - if (first_entry) { filtlist.items = filtlist_items; /* malloc also works :) */ @@ -323,7 +326,8 @@ if (!signproc_get_options (startdir, infilename, outfilename, &filtlist, filtnumbers, helptexts, &selectedfilts, - &usetracktimes, &usebeginendtime, &begintime, &endtime)) + &usetracktimes, &usebeginendtime, &begintime, &endtime, + &adjustframes, &framesize)) return; strcpy (baseoutfilename, outfilename); @@ -384,7 +388,11 @@ /* calculate #samples for this track */ tracksize_samples = tracktimes[i].end - tracktimes[i].begin + 1; - + if (adjustframes){ + tracksize_samples -= tracksize_samples % framesize; + /* set minimum length = 1 frame */ + if ( !tracksize_samples ) tracksize_samples = framesize; + } /* seek to beginsample */ if (!seeksamplesource (tracktimes[i].begin)) { diff -Naur gramofile-1.6-old/signpr_main.h gramofile-1.6/signpr_main.h --- gramofile-1.6-old/signpr_main.h 2000-03-28 23:07:26.000000000 +0200 +++ gramofile-1.6/signpr_main.h 2004-05-12 09:20:51.000000000 +0200 @@ -26,7 +26,8 @@ scrollmenu_t * filtlist, int *filtnumbers, char **helptexts, scrollmenu_t * selectedfilts, int *usetracktimes, int *usebeginendtime, - double *begintime, double *endtime); + double *begintime, double *endtime, + int *adjustframes, long *framesize); int load_track_times (char *filename, beginendsample_t * tracktimes, int *number_of_tracks); diff -Naur gramofile-1.6-old/signpr_outfilenm.c gramofile-1.6/signpr_outfilenm.c --- gramofile-1.6-old/signpr_outfilenm.c 2000-03-28 23:07:26.000000000 +0200 +++ gramofile-1.6/signpr_outfilenm.c 2004-05-12 09:20:51.000000000 +0200 @@ -55,10 +55,10 @@ " Back to main menu. TAB: Next field", " Start processing the signal. TAB: Next field"}; - dirfilelist.y = 3; - dirfilelist.x = 5; - dirfilelist.h = 12; - dirfilelist.w = 32; + dirfilelist.y = DIR_FILEMENU_Y; + dirfilelist.x = DIR_FILEMENU_X; + dirfilelist.h = DIR_FILEMENU_HEIGHT; + dirfilelist.w = DIR_FILEMENU_WIDTH; dirfilelist.firstonscreen = 0; dirfilemenu (startdir, &dirfilelist); dirfilelist.selected = dirfilelist.last_of_1st_part + 1; diff -Naur gramofile-1.6-old/signpr_wav.c gramofile-1.6/signpr_wav.c --- gramofile-1.6-old/signpr_wav.c 2000-03-28 23:07:26.000000000 +0200 +++ gramofile-1.6/signpr_wav.c 2004-05-12 09:20:51.000000000 +0200 @@ -22,6 +22,8 @@ /* ----- SOURCE & READING -------------------------------------------------- */ FILE *sourcefile; +int num_read_samples_buffered = 0; +sample_t readsamplebuffer[44100]; int openwavsource (char *filename) @@ -106,6 +108,7 @@ } /* Well, everything seems to be OK */ + num_read_samples_buffered = 0; return 1; } @@ -113,6 +116,7 @@ closewavsource () { fclose (sourcefile); + num_read_samples_buffered = 0; } int @@ -121,6 +125,9 @@ { struct stat buf; + /* throw away buffer on fseek */ + num_read_samples_buffered = 0; + if (fstat (fileno (sourcefile), &buf)) return 0; @@ -135,22 +142,28 @@ sample_t readsamplesource () -{ - sample_t sample; - - if (fread (&sample, 1, 4, sourcefile) != 4) - { - /* reading after end of file - this just happens when using - pre-read buffers! */ - sample.left = 0; - sample.right = 0; - } +{ + /* millions of calls to fread sure slow things down.... buffer it a little */ + static int i; + + if (i >= num_read_samples_buffered) + { + num_read_samples_buffered = fread(readsamplebuffer, 4, sizeof(readsamplebuffer)/4, sourcefile); + i = 0; + if (!num_read_samples_buffered) + { + /* reading after end of file - this just happens when using + pre-read buffers! */ + readsamplebuffer[0].left = 0; + readsamplebuffer[0].right = 0; + return readsamplebuffer[0]; + } + } #ifdef SWAP_ENDIAN - sample = SwapSample (sample); + SWAPSAMPLEREF (readsamplebuffer+i); #endif - - return sample; + return readsamplebuffer[i++]; } @@ -158,6 +171,8 @@ FILE *destfile; int destfileispipe; /* remember open() - - -> close() */ +int num_write_samples_buffered = 0; +sample_t writesamplebuffer[44100]; int openwavdest (char *filename, long bcount) @@ -216,12 +231,20 @@ fwrite (&header, sizeof (header), 1, destfile); + num_write_samples_buffered = 0; /* just in case */ return 1; } +void flushwritebuffer() +{ + fwrite(writesamplebuffer, 4 * num_write_samples_buffered, 1, destfile); + num_write_samples_buffered = 0; +} + void closewavdest () { + flushwritebuffer(); if (destfileispipe) pclose (destfile); else @@ -233,8 +256,9 @@ { #ifdef SWAP_ENDIAN - sample = SwapSample (sample); + SWAPSAMPLEREF(&sample); #endif - - fwrite (&sample, 4, 1, destfile); + if (num_write_samples_buffered == (sizeof (writesamplebuffer) / 4)) + flushwritebuffer(); + writesamplebuffer[num_write_samples_buffered++] = sample; } diff -Naur gramofile-1.6-old/tracksplit_filenm.c gramofile-1.6/tracksplit_filenm.c --- gramofile-1.6-old/tracksplit_filenm.c 2000-03-28 23:07:26.000000000 +0200 +++ gramofile-1.6/tracksplit_filenm.c 2004-05-12 09:20:51.000000000 +0200 @@ -54,10 +54,10 @@ " Back to main menu. TAB: Next field", " To Track Splitting - Parameters. TAB: Next field"}; - dirfilelist.y = 3; - dirfilelist.x = 5; - dirfilelist.h = 12; - dirfilelist.w = 32; + dirfilelist.y = DIR_FILEMENU_Y; + dirfilelist.x = DIR_FILEMENU_X; + dirfilelist.h = DIR_FILEMENU_HEIGHT; + dirfilelist.w = DIR_FILEMENU_WIDTH; dirfilelist.firstonscreen = 0; dirfilemenu (startdir, &dirfilelist); dirfilelist.selected = dirfilelist.last_of_1st_part + 1;