diff options
Diffstat (limited to 'audio-soft/gramofile/tappin3b.patch')
-rw-r--r-- | audio-soft/gramofile/tappin3b.patch | 1392 |
1 files changed, 1392 insertions, 0 deletions
diff --git a/audio-soft/gramofile/tappin3b.patch b/audio-soft/gramofile/tappin3b.patch new file mode 100644 index 0000000000..dd3e558b6c --- /dev/null +++ b/audio-soft/gramofile/tappin3b.patch @@ -0,0 +1,1392 @@ +diff -c -N gramofile-1.6/Makefile gramofile-1.6-sjt/Makefile +*** gramofile-1.6/Makefile Tue Mar 28 21:23:58 2000 +--- gramofile-1.6-sjt/Makefile Sun Apr 22 09:32:22 2001 +*************** +*** 7,13 **** + 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) +--- 7,14 ---- + 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_cmf3.c \ +! signpr_rms.c signpr_copy.c \ + signpr_exper.c endian.c signpr_mono.c signpr_l1fit.c + + OBJS = $(SRCS:.c=.o) +*************** +*** 21,39 **** + # For Linux (and maybe others), use these: + CFLAGS = -Wall -O2 -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 + + ########## +--- 22,40 ---- + # For Linux (and maybe others), use these: + CFLAGS = -Wall -O2 -DTURBO_MEDIAN -DTURBO_BUFFER + DEPS = $(OBJS) makebplay +! 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 -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 -lrfftw -lfftw -lm + #COPY_A = -a + + ########## +diff -c -N gramofile-1.6/SIGNPR_CMF3.TXT gramofile-1.6-sjt/SIGNPR_CMF3.TXT +*** gramofile-1.6/SIGNPR_CMF3.TXT Thu Jan 1 01:00:00 1970 +--- gramofile-1.6-sjt/SIGNPR_CMF3.TXT Sun Apr 22 17:21:03 2001 +*************** +*** 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). ++ +Common subdirectories: gramofile-1.6/bplaysrc and gramofile-1.6-sjt/bplaysrc +diff -c -N gramofile-1.6/signpr_cmf3.c gramofile-1.6-sjt/signpr_cmf3.c +*** gramofile-1.6/signpr_cmf3.c Thu Jan 1 01:00:00 1970 +--- gramofile-1.6-sjt/signpr_cmf3.c Wed May 9 19:48:43 2001 +*************** +*** 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 <stdlib.h> ++ #include <stdio.h> ++ #include <math.h> ++ #ifndef OLD_CURSES ++ #include <ncurses.h> ++ #else ++ #include <curses.h> ++ #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 && 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.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 -c -N gramofile-1.6/signpr_cmf3.h gramofile-1.6-sjt/signpr_cmf3.h +*** gramofile-1.6/signpr_cmf3.h Thu Jan 1 01:00:00 1970 +--- gramofile-1.6-sjt/signpr_cmf3.h Sat Apr 21 14:33:47 2001 +*************** +*** 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 -c -N gramofile-1.6/signpr_general.c gramofile-1.6-sjt/signpr_general.c +*** gramofile-1.6/signpr_general.c Tue Mar 28 22:07:26 2000 +--- gramofile-1.6-sjt/signpr_general.c Sun Apr 22 09:33:24 2001 +*************** +*** 14,19 **** +--- 14,20 ---- + #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,516 **** +--- 512,524 ---- + 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,564 **** +--- 567,576 ---- + 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,620 **** +--- 627,636 ---- + 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,676 **** +--- 687,696 ---- + 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,729 **** +--- 744,753 ---- + monoize_param_defaults (parampointer); + break; + ++ case COND_MEDIAN3_FILTER: ++ cond_median3_param_defaults (parampointer); ++ break; ++ + case EXPERIMENT_FILTER: + experiment_param_defaults (parampointer); + break; +*************** +*** 775,780 **** +--- 799,808 ---- + + case MONOIZE_FILTER: + monoize_param_screen (parampointer); ++ break; ++ ++ case COND_MEDIAN3_FILTER: ++ cond_median3_param_screen (parampointer); + break; + + case EXPERIMENT_FILTER: +diff -c -N gramofile-1.6/signpr_general.h gramofile-1.6-sjt/signpr_general.h +*** gramofile-1.6/signpr_general.h Tue Mar 28 22:07:26 2000 +--- gramofile-1.6-sjt/signpr_general.h Sun Apr 22 09:30:47 2001 +*************** +*** 13,18 **** +--- 13,21 ---- + + #include "scrollmenu.h" + ++ /* This has to be here, otherwise the FFT interpolating filter ++ can't keep its plans [SJT] */ ++ #include <rfftw.h> + + /* SAMPLES */ + +*************** +*** 70,78 **** + signed short *sslist1; + signed short *sslist2; + +! int int1; + long long1; + long long2; + } + param_t; + +--- 73,84 ---- + signed short *sslist1; + signed short *sslist2; + +! int int1, int2; + long long1; + long long2; ++ ++ rfftw_plan planf, planr; ++ + } + param_t; + +*************** +*** 221,227 **** + #define MONOIZE_HELPTEXT \ + "Average left & right signals." + +! #define EXPERIMENT_FILTER 9 + #define EXPERIMENT_NAME "Experimenting Filter" + #define EXPERIMENT_HELPTEXT \ + "The filter YOU are experimenting with (in signpr_exper.c)" +--- 227,238 ---- + #define MONOIZE_HELPTEXT \ + "Average left & right signals." + +! #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)" |