diff --git a/Source/Helmholtz.cpp b/Source/Helmholtz.cpp index 459185b..cfee5a6 100644 --- a/Source/Helmholtz.cpp +++ b/Source/Helmholtz.cpp @@ -45,11 +45,13 @@ void Helmholtz::iosamples(const t_float* in, t_float* out, int size) int mask = framesize - 1; int outindex = 0; - // call analysis function when it is time - if (!(timeindex & (framesize / overlap - 1))) analyzeframe(); + while (size--) { + // call analysis function when it is time + if (!(timeindex & (framesize / overlap - 1))) analyzeframe(); + inputbuf[timeindex++] = *in++; //out[outindex++] = processbuf[timeindex++]; timeindex &= mask; diff --git a/Source/Helmholtz.h b/Source/Helmholtz.h index b3910be..16c07e0 100644 --- a/Source/Helmholtz.h +++ b/Source/Helmholtz.h @@ -50,8 +50,8 @@ against another DSP framework, you need to define t_float, and you need to include Ron Mayer's fft or similar functionality. */ #include "mayer_fft.h" -#define REALFFT mayer_realfft -#define REALIFFT mayer_realifft +#define REALFFT fft.realfft +#define REALIFFT fft.realifft /***********************************************************************/ @@ -104,6 +104,7 @@ private: t_float fidelity; t_float biasfactor; t_float minrms; + MayerFFT fft; }; #endif // #ifndef Helmholtz_H \ No newline at end of file diff --git a/Source/Shifter.cpp b/Source/Shifter.cpp index c85af84..f0f7a78 100644 --- a/Source/Shifter.cpp +++ b/Source/Shifter.cpp @@ -28,10 +28,10 @@ void Shifter::Init(float samplerate, int samplesPerBlock) { sample_rate_ = samplerate; blocksize = samplesPerBlock; - out_midi_smoother.SetFrameTime((float)samplesPerBlock / samplerate); + out_midi_smoother.SetFrameTime((float)256 / samplerate); volume = 1; helm.setframesize(1024); - helm.setoverlap(1); + helm.setoverlap(2); for (int i = 0; i < MAX_VOICES; ++i) { voices[i].Init(samplerate); @@ -46,18 +46,21 @@ void Shifter::Init(float samplerate, int samplesPerBlock) for (int i = 0; i < 8192; ++i) { cos_lookup[i] = cos(2 * PI_F * i / 8192.0); } + in_period = 0; } void Shifter::Process(const float* const* in, float** out, size_t size) { - DetectPitch(in, out, size); - SetRates(); - // for (size_t i = 0; i < size; ++i) { - // out[0][i] = 0; - // } - GetSamples(out, in[0], size); + for (size_t i = 0; i < size; i += 256) { + size_t offset = i; + size_t lefover_size = std::min((size_t)256, size - i); + DetectPitch(in, out, lefover_size, offset); + SetRates(); + GetSamples(out, in[0], lefover_size, offset); + } + //for (size_t i = 0; i < size; ++i) //{ // // out[0][i] = osc.Process(); @@ -78,7 +81,7 @@ float findMedian(float a, float b, float c) { } -void Shifter::DetectPitch(const float* const* in, float** out, size_t size) +void Shifter::DetectPitch(const float* const* in, float** out, size_t size, size_t offset) { // detect current pitch // pitch_detect.update(in[0], size); @@ -97,16 +100,16 @@ void Shifter::DetectPitch(const float* const* in, float** out, size_t size) // current_pitch = findMedian(last_freqs[0], last_freqs[1], last_freqs[2]); // in_period = 1.0 / current_pitch * 48000; - helm.iosamples(in[0], out[0], size); + helm.iosamples(in[0]+offset, out[0]+offset, size); float period = helm.getperiod(); float fidel = helm.getfidelity(); //DBG("frequency: " << 48000 / period << " fidel: " << fidel); // Adjustable filter amount (0.0f = no filtering, 1.0f = max filtering) - static float in_period_filter_amount = 0.5f; // You can expose this as a parameter + const float in_period_filter_amount = 0.5f; // You can expose this as a parameter if (fidel > 0.95) { - // Smoothly filter in_period changes + // Smoothly filter in_`period changes in_period = in_period * in_period_filter_amount + period * (1.0f - in_period_filter_amount); } float in_freq = sample_rate_ / in_period; @@ -201,7 +204,7 @@ void Shifter::AddInterpolatedFrame(int voice, int max_index, float resampling_pe } } -void Shifter::GetSamples(float** output, const float* input, size_t size) +void Shifter::GetSamples(float** output, const float* input, size_t size, size_t offset) { if (freeze_needs_copy) { freeze_needs_copy = false; @@ -273,13 +276,13 @@ void Shifter::GetSamples(float** output, const float* input, size_t size) //add input samples - in_buffer[in_playhead] = input[i]; + in_buffer[in_playhead] = input[i+offset]; //output samples, set to 0 for (int ch = 0; ch < 2; ++ch) { - output[ch][i] = out_buffer[ch][out_playhead]; + output[ch][i+offset] = out_buffer[ch][out_playhead]; if (!enable_autotune) { - output[ch][i] += input[i] * melody_mix; + output[ch][i+offset] += input[i+offset] * melody_mix; } out_buffer[ch][out_playhead] = 0; } diff --git a/Source/Shifter.h b/Source/Shifter.h index d8597f7..13fd1b2 100644 --- a/Source/Shifter.h +++ b/Source/Shifter.h @@ -84,6 +84,7 @@ public: PcorrPrev = 60.0f; PtargPrev = 60; depth = 1.0f; + inputPrev = 0; } void SetFrameTime(float frame_time) { dt = frame_time; @@ -167,9 +168,9 @@ public: ShifterVoice freeze_voices[MAX_VOICES]; private: - void DetectPitch(const float* const* in, float** out, size_t size); + void DetectPitch(const float* const* in, float** out, size_t size, size_t offset); void SetRates(); - void GetSamples(float** output, const float* input, size_t size); + void GetSamples(float** output, const float* input, size_t size, size_t offset); float GetOutputEnvelopePeriod(int out_voice); float GetOutputEnvelopePeriodFreeze(int freeze_voice); int GetPeakIndex(); diff --git a/Source/mayer_fft.cpp b/Source/mayer_fft.cpp index f96f952..7379e72 100644 --- a/Source/mayer_fft.cpp +++ b/Source/mayer_fft.cpp @@ -52,6 +52,8 @@ http://crca.ucsd.edu/~msp/software.html */ * of work. -msp */ +#include "mayer_fft.h" + #define REAL float #define GOOD_TRIG @@ -62,8 +64,7 @@ http://crca.ucsd.edu/~msp/software.html */ #if defined(GOOD_TRIG) #define FHT_SWAP(a,b,t) {(t)=(a);(a)=(b);(b)=(t);} -#define TRIG_VARS \ - int t_lam=0; + #define TRIG_INIT(k,c,s) \ { \ int i; \ @@ -92,133 +93,21 @@ http://crca.ucsd.edu/~msp/software.html */ #define TRIG_RESET(k,c,s) #endif -#if defined(FAST_TRIG) -#define TRIG_VARS \ - REAL t_c,t_s; -#define TRIG_INIT(k,c,s) \ - { \ - t_c = costab[k]; \ - t_s = sintab[k]; \ - c = 1; \ - s = 0; \ - } -#define TRIG_NEXT(k,c,s) \ - { \ - REAL t = c; \ - c = t*t_c - s*t_s; \ - s = t*t_s + s*t_c; \ - } -#define TRIG_RESET(k,c,s) -#endif -static REAL halsec[20] = -{ - 0, - 0, - .54119610014619698439972320536638942006107206337801, - .50979557910415916894193980398784391368261849190893, - .50241928618815570551167011928012092247859337193963, - .50060299823519630134550410676638239611758632599591, - .50015063602065098821477101271097658495974913010340, - .50003765191554772296778139077905492847503165398345, - .50000941253588775676512870469186533538523133757983, - .50000235310628608051401267171204408939326297376426, - .50000058827484117879868526730916804925780637276181, - .50000014706860214875463798283871198206179118093251, - .50000003676714377807315864400643020315103490883972, - .50000000919178552207366560348853455333939112569380, - .50000000229794635411562887767906868558991922348920, - .50000000057448658687873302235147272458812263401372 -}; -static REAL costab[20] = -{ - .00000000000000000000000000000000000000000000000000, - .70710678118654752440084436210484903928483593768847, - .92387953251128675612818318939678828682241662586364, - .98078528040323044912618223613423903697393373089333, - .99518472667219688624483695310947992157547486872985, - .99879545620517239271477160475910069444320361470461, - .99969881869620422011576564966617219685006108125772, - .99992470183914454092164649119638322435060646880221, - .99998117528260114265699043772856771617391725094433, - .99999529380957617151158012570011989955298763362218, - .99999882345170190992902571017152601904826792288976, - .99999970586288221916022821773876567711626389934930, - .99999992646571785114473148070738785694820115568892, - .99999998161642929380834691540290971450507605124278, - .99999999540410731289097193313960614895889430318945, - .99999999885102682756267330779455410840053741619428 -}; -static REAL sintab[20] = -{ - 1.0000000000000000000000000000000000000000000000000, - .70710678118654752440084436210484903928483593768846, - .38268343236508977172845998403039886676134456248561, - .19509032201612826784828486847702224092769161775195, - .09801714032956060199419556388864184586113667316749, - .04906767432741801425495497694268265831474536302574, - .02454122852291228803173452945928292506546611923944, - .01227153828571992607940826195100321214037231959176, - .00613588464915447535964023459037258091705788631738, - .00306795676296597627014536549091984251894461021344, - .00153398018628476561230369715026407907995486457522, - .00076699031874270452693856835794857664314091945205, - .00038349518757139558907246168118138126339502603495, - .00019174759731070330743990956198900093346887403385, - .00009587379909597734587051721097647635118706561284, - .00004793689960306688454900399049465887274686668768 -}; -static REAL coswrk[20] = -{ - .00000000000000000000000000000000000000000000000000, - .70710678118654752440084436210484903928483593768847, - .92387953251128675612818318939678828682241662586364, - .98078528040323044912618223613423903697393373089333, - .99518472667219688624483695310947992157547486872985, - .99879545620517239271477160475910069444320361470461, - .99969881869620422011576564966617219685006108125772, - .99992470183914454092164649119638322435060646880221, - .99998117528260114265699043772856771617391725094433, - .99999529380957617151158012570011989955298763362218, - .99999882345170190992902571017152601904826792288976, - .99999970586288221916022821773876567711626389934930, - .99999992646571785114473148070738785694820115568892, - .99999998161642929380834691540290971450507605124278, - .99999999540410731289097193313960614895889430318945, - .99999999885102682756267330779455410840053741619428 -}; -static REAL sinwrk[20] = -{ - 1.0000000000000000000000000000000000000000000000000, - .70710678118654752440084436210484903928483593768846, - .38268343236508977172845998403039886676134456248561, - .19509032201612826784828486847702224092769161775195, - .09801714032956060199419556388864184586113667316749, - .04906767432741801425495497694268265831474536302574, - .02454122852291228803173452945928292506546611923944, - .01227153828571992607940826195100321214037231959176, - .00613588464915447535964023459037258091705788631738, - .00306795676296597627014536549091984251894461021344, - .00153398018628476561230369715026407907995486457522, - .00076699031874270452693856835794857664314091945205, - .00038349518757139558907246168118138126339502603495, - .00019174759731070330743990956198900093346887403385, - .00009587379909597734587051721097647635118706561284, - .00004793689960306688454900399049465887274686668768 -}; + #define SQRT2_2 0.70710678118654752440084436210484 #define SQRT2 2*0.70710678118654752440084436210484 -void mayer_fht(REAL* fz, int n) +void MayerFFT::fht(REAL* fz, int n) { /* REAL a,b; REAL c1,s1,s2,c2,s3,c3,s4,c4; REAL f0,g0,f1,g1,f2,g2,f3,g3; */ int k, k1, k2, k3, k4, kx; REAL* fi, * fn, * gi; - TRIG_VARS; + int t_lam = 0; for (k1 = 1, k2 = 0; k1 < n; k1++) { @@ -360,42 +249,42 @@ void mayer_fht(REAL* fz, int n) } while (k4 < n); } -void mayer_fft(int n, REAL* real, REAL* imag) -{ - REAL a, b, c, d; - REAL q, r, s, t; - int i, j, k; - for (i = 1, j = n - 1, k = n / 2; i < k; i++, j--) { - a = real[i]; b = real[j]; q = a + b; r = a - b; - c = imag[i]; d = imag[j]; s = c + d; t = c - d; - real[i] = (q + t) * .5; real[j] = (q - t) * .5; - imag[i] = (s - r) * .5; imag[j] = (s + r) * .5; - } - mayer_fht(real, n); - mayer_fht(imag, n); -} +//void mayer_fft(int n, REAL* real, REAL* imag) +//{ +// REAL a, b, c, d; +// REAL q, r, s, t; +// int i, j, k; +// for (i = 1, j = n - 1, k = n / 2; i < k; i++, j--) { +// a = real[i]; b = real[j]; q = a + b; r = a - b; +// c = imag[i]; d = imag[j]; s = c + d; t = c - d; +// real[i] = (q + t) * .5; real[j] = (q - t) * .5; +// imag[i] = (s - r) * .5; imag[j] = (s + r) * .5; +// } +// mayer_fht(real, n); +// mayer_fht(imag, n); +//} +// +//void mayer_ifft(int n, REAL* real, REAL* imag) +//{ +// REAL a, b, c, d; +// REAL q, r, s, t; +// int i, j, k; +// mayer_fht(real, n); +// mayer_fht(imag, n); +// for (i = 1, j = n - 1, k = n / 2; i < k; i++, j--) { +// a = real[i]; b = real[j]; q = a + b; r = a - b; +// c = imag[i]; d = imag[j]; s = c + d; t = c - d; +// imag[i] = (s + r) * 0.5; imag[j] = (s - r) * 0.5; +// real[i] = (q - t) * 0.5; real[j] = (q + t) * 0.5; +// } +//} -void mayer_ifft(int n, REAL* real, REAL* imag) -{ - REAL a, b, c, d; - REAL q, r, s, t; - int i, j, k; - mayer_fht(real, n); - mayer_fht(imag, n); - for (i = 1, j = n - 1, k = n / 2; i < k; i++, j--) { - a = real[i]; b = real[j]; q = a + b; r = a - b; - c = imag[i]; d = imag[j]; s = c + d; t = c - d; - imag[i] = (s + r) * 0.5; imag[j] = (s - r) * 0.5; - real[i] = (q - t) * 0.5; real[j] = (q + t) * 0.5; - } -} - -void mayer_realfft(int n, REAL* real) +void MayerFFT::realfft(int n, REAL* real) { REAL a, b; int i, j, k; - mayer_fht(real, n); + fht(real, n); for (i = 1, j = n - 1, k = n / 2; i < k; i++, j--) { a = real[i]; b = real[j]; @@ -404,7 +293,7 @@ void mayer_realfft(int n, REAL* real) } } -void mayer_realifft(int n, REAL* real) +void MayerFFT::realifft(int n, REAL* real) { REAL a, b; int i, j, k; @@ -415,5 +304,5 @@ void mayer_realifft(int n, REAL* real) real[j] = (a - b); real[i] = (a + b); } - mayer_fht(real, n); + fht(real, n); } \ No newline at end of file diff --git a/Source/mayer_fft.h b/Source/mayer_fft.h index 067133b..6ef71a2 100644 --- a/Source/mayer_fft.h +++ b/Source/mayer_fft.h @@ -3,7 +3,114 @@ #define REAL float -void mayer_realfft(int n, REAL* real); -void mayer_realifft(int n, REAL* real); +//void mayer_realfft(int n, REAL* real); +//void mayer_realifft(int n, REAL* real); +class MayerFFT { +public: + void realfft(int n, REAL* real); + void realifft(int n, REAL* real); + + MayerFFT() :halsec{ + 0, + 0, + .54119610014619698439972320536638942006107206337801, + .50979557910415916894193980398784391368261849190893, + .50241928618815570551167011928012092247859337193963, + .50060299823519630134550410676638239611758632599591, + .50015063602065098821477101271097658495974913010340, + .50003765191554772296778139077905492847503165398345, + .50000941253588775676512870469186533538523133757983, + .50000235310628608051401267171204408939326297376426, + .50000058827484117879868526730916804925780637276181, + .50000014706860214875463798283871198206179118093251, + .50000003676714377807315864400643020315103490883972, + .50000000919178552207366560348853455333939112569380, + .50000000229794635411562887767906868558991922348920, + .50000000057448658687873302235147272458812263401372 + }, + costab{ + .00000000000000000000000000000000000000000000000000, + .70710678118654752440084436210484903928483593768847, + .92387953251128675612818318939678828682241662586364, + .98078528040323044912618223613423903697393373089333, + .99518472667219688624483695310947992157547486872985, + .99879545620517239271477160475910069444320361470461, + .99969881869620422011576564966617219685006108125772, + .99992470183914454092164649119638322435060646880221, + .99998117528260114265699043772856771617391725094433, + .99999529380957617151158012570011989955298763362218, + .99999882345170190992902571017152601904826792288976, + .99999970586288221916022821773876567711626389934930, + .99999992646571785114473148070738785694820115568892, + .99999998161642929380834691540290971450507605124278, + .99999999540410731289097193313960614895889430318945, + .99999999885102682756267330779455410840053741619428 + }, + sintab{ + 1.0000000000000000000000000000000000000000000000000, + .70710678118654752440084436210484903928483593768846, + .38268343236508977172845998403039886676134456248561, + .19509032201612826784828486847702224092769161775195, + .09801714032956060199419556388864184586113667316749, + .04906767432741801425495497694268265831474536302574, + .02454122852291228803173452945928292506546611923944, + .01227153828571992607940826195100321214037231959176, + .00613588464915447535964023459037258091705788631738, + .00306795676296597627014536549091984251894461021344, + .00153398018628476561230369715026407907995486457522, + .00076699031874270452693856835794857664314091945205, + .00038349518757139558907246168118138126339502603495, + .00019174759731070330743990956198900093346887403385, + .00009587379909597734587051721097647635118706561284, + .00004793689960306688454900399049465887274686668768 + }, + coswrk{ + .00000000000000000000000000000000000000000000000000, + .70710678118654752440084436210484903928483593768847, + .92387953251128675612818318939678828682241662586364, + .98078528040323044912618223613423903697393373089333, + .99518472667219688624483695310947992157547486872985, + .99879545620517239271477160475910069444320361470461, + .99969881869620422011576564966617219685006108125772, + .99992470183914454092164649119638322435060646880221, + .99998117528260114265699043772856771617391725094433, + .99999529380957617151158012570011989955298763362218, + .99999882345170190992902571017152601904826792288976, + .99999970586288221916022821773876567711626389934930, + .99999992646571785114473148070738785694820115568892, + .99999998161642929380834691540290971450507605124278, + .99999999540410731289097193313960614895889430318945, + .99999999885102682756267330779455410840053741619428 + }, + sinwrk{ + 1.0000000000000000000000000000000000000000000000000, + .70710678118654752440084436210484903928483593768846, + .38268343236508977172845998403039886676134456248561, + .19509032201612826784828486847702224092769161775195, + .09801714032956060199419556388864184586113667316749, + .04906767432741801425495497694268265831474536302574, + .02454122852291228803173452945928292506546611923944, + .01227153828571992607940826195100321214037231959176, + .00613588464915447535964023459037258091705788631738, + .00306795676296597627014536549091984251894461021344, + .00153398018628476561230369715026407907995486457522, + .00076699031874270452693856835794857664314091945205, + .00038349518757139558907246168118138126339502603495, + .00019174759731070330743990956198900093346887403385, + .00009587379909597734587051721097647635118706561284, + .00004793689960306688454900399049465887274686668768 + } + + { + } +private: + + void fht(REAL* fz, int n); + REAL halsec[20]; + REAL costab[20]; + REAL sintab[20]; + REAL coswrk[20]; + REAL sinwrk[20]; +}; #endif \ No newline at end of file