/* oversampling */ #include /*stdout*/ #include "defs.h" /*->inst.h (u8,u15x,...)*/ #include "inst.h" /*SampleInfo*/ #include "ovs.h" /*(ovs)*/ #include "mem.h" /*(memSong)*/ /* LPF fc=fs/4 impulse response * Hamming window (N=19) */ static i15x h2[][8] = /* h(n) = */ { /* n = */ /*-7 -5 -3 -1 1 3 5 7*/ { -4, 15, -42, 158, 158, -42, 15, -4} }; /* LPF fc=fs/6 impulse response * Hamming window (N=29) */ static i15x h3[][8] = { /*-10 -7 -4 -1 2 5 8 11*/ { -5, 16, -44, 209, 101, -31, 12, -3}, /*-11 -8 -5 -2 1 4 7 10*/ { -3, 12, -31, 101, 209, -44, 16, -5} }; /* LPF fc=fs/8 impulse response * Hamming window (N=35) */ static i15x h4[][8] = { /*-13 -9 -5 -1 3 7 11 15*/ { -4, 13, -38, 229, 72, -22, 7, -2}, /*-14 -10 -6 -2 2 6 10 14*/ { -3, 13, -40, 158, 158, -40, 13, -3}, /*-15 -11 -7 -3 1 5 9 13*/ { -2, 7, -22, 72, 229, -38, 13, -4} }; static i15x (*hn[])[8] = { h2, h3, h4 }; static SampleInfo sis; static void convolute(i15x mag, i7 *dp) { const u8 *sp0; i15x i,j; for (sp0 = sis.beg; sp0 < sis.end; sp0++) { *dp++ = *sp0 ^ sis.xor; for (i = 0; i < mag-1; i++,dp++) { i15x *hp = hn[mag-2][i]; const u8 *sp = sp0 - 3; i31x sum = 0; for (j = 8; j > 0; j--,sp++,hp++) { if (sp < sis.beg) continue; if (sp >= sis.end) { if (sis.loopBeg) sp = sis.loopBeg; else break; } sum += *hp * (i7)(*sp ^ sis.xor); } sum /= 256; if (sum > 127) sum = 127; else if (sum < -128) sum = -128; *dp = sum; } } } #define ANIM_BACK "%c" #define ANIM_FORE "." #if 0 /* by Jeff Epler */ #define ANIM_BACK "\r%c" #define ANIM_FORE ".oO@Oo. " /* simple */ #define ANIM_BACK "%c" #define ANIM_FORE "." /* bubble */ #define ANIM_BACK "\r%c" #define ANIM_FORE ".oO* " /* pac */ #define ANIM_BACK "\r%c" #define ANIM_FORE "-<(<" /* baton */ #define ANIM_BACK "\r%c" #define ANIM_FORE "-\\|/" /* thinking man */ #define ANIM_BACK "\r(-_-%c)" #define ANIM_FORE " ';," /* twang! */ #define ANIM_BACK "\r%c" #define ANIM_FORE "TYV~" #endif static void perSampleWork(SampleInfo *sip, u16x c4req) { static SampleInfo sid; u8 *dp0; u32x len; i15x mag; mag = c4req / sip->c4spd; if (!mag) return; /* no need to oversampling */ mag++; if (mag > 4) mag = 4; /* currently max = 4x */ sis = *sip; len = sis.end - sis.beg; if (len <= 2) return; /* too short sample */ { static i15x n; printf(ANIM_BACK, ANIM_FORE[n++]); fflush(stdout); n %= sizeof(ANIM_FORE)-1; } dp0 = memSong(len * mag); sid.beg = dp0; sid.end = dp0 + len*mag; convolute(mag, dp0); sid.loopBeg = sis.loopBeg? (sid.beg + (sis.loopBeg - sis.beg)*mag) : NULL; sid.xor = 0; sid.c4spd = sis.c4spd; sid.vol = sis.vol; sid.mag = sis.mag * mag; *sip = sid; } void ovs(i15x insNum, SampleInfo *sip, u16x c4req) { printf("Oversampling..\n"); for (; insNum > 0; insNum--,sip++) perSampleWork(sip, c4req); printf("\rdone.%32s\n", ""); }