/* * Get the spectrum of the oscillator for the UI */ void OscilGen::getspectrum(int n, REALTYPE *spc, int what) { if(n > OSCIL_SIZE / 2) n = OSCIL_SIZE / 2; for(int i = 1; i < n; i++) { if(what == 0) spc[i - 1] = sqrt(oscilFFTfreqs.c[i] * oscilFFTfreqs.c[i] + oscilFFTfreqs.s[i] * oscilFFTfreqs.s[i]); else { if(Pcurrentbasefunc == 0) spc[i - 1] = ((i == 1) ? (1.0) : (0.0)); else spc[i - 1] = sqrt(basefuncFFTfreqs.c[i] * basefuncFFTfreqs.c[i] + basefuncFFTfreqs.s[i] * basefuncFFTfreqs.s[i]); } } if(what == 0) { for(int i = 0; i < n; i++) outoscilFFTfreqs.s[i] = outoscilFFTfreqs.c[i] = spc[i]; for(int i = n; i < OSCIL_SIZE / 2; i++) outoscilFFTfreqs.s[i] = outoscilFFTfreqs.c[i] = 0.0; adaptiveharmonic(outoscilFFTfreqs, 0.0); for(int i = 0; i < n; i++) spc[i] = outoscilFFTfreqs.s[i]; adaptiveharmonicpostprocess(spc, n - 1); } }
/* * Get the spectrum of the oscillator for the UI */ void OscilGen::getspectrum(int n, float *spc, int what) { if(n > synth.oscilsize / 2) n = synth.oscilsize / 2; for(int i = 1; i < n; ++i) { if(what == 0) spc[i - 1] = abs(pendingfreqs, i); else { if(Pcurrentbasefunc == 0) spc[i - 1] = ((i == 1) ? (1.0f) : (0.0f)); else spc[i - 1] = abs(basefuncFFTfreqs, i); } } if(what == 0) { for(int i = 0; i < n; ++i) outoscilFFTfreqs[i] = fft_t(spc[i], spc[i]); memset(outoscilFFTfreqs + n, 0, (synth.oscilsize / 2 - n) * sizeof(fft_t)); adaptiveharmonic(outoscilFFTfreqs, 0.0f); adaptiveharmonicpostprocess(outoscilFFTfreqs, n - 1); for(int i = 0; i < n; ++i) spc[i] = outoscilFFTfreqs[i].imag(); } }
/* * Get the oscillator function */ short int OscilGen::get(REALTYPE *smps, REALTYPE freqHz, int resonance) { int i; int nyquist, outpos; if((oldbasepar != Pbasefuncpar) || (oldbasefunc != Pcurrentbasefunc) || (oldhmagtype != Phmagtype) || (oldwaveshaping != Pwaveshaping) || (oldwaveshapingfunction != Pwaveshapingfunction)) oscilprepared = 0; if(oldfilterpars != Pfiltertype * 256 + Pfilterpar1 + Pfilterpar2 * 65536 + Pfilterbeforews * 16777216) { oscilprepared = 0; oldfilterpars = Pfiltertype * 256 + Pfilterpar1 + Pfilterpar2 * 65536 + Pfilterbeforews * 16777216; } if(oldsapars != Psatype * 256 + Psapar) { oscilprepared = 0; oldsapars = Psatype * 256 + Psapar; } if((oldbasefuncmodulation != Pbasefuncmodulation) || (oldbasefuncmodulationpar1 != Pbasefuncmodulationpar1) || (oldbasefuncmodulationpar2 != Pbasefuncmodulationpar2) || (oldbasefuncmodulationpar3 != Pbasefuncmodulationpar3)) oscilprepared = 0; if((oldmodulation != Pmodulation) || (oldmodulationpar1 != Pmodulationpar1) || (oldmodulationpar2 != Pmodulationpar2) || (oldmodulationpar3 != Pmodulationpar3)) oscilprepared = 0; if(oldharmonicshift != Pharmonicshift + Pharmonicshiftfirst * 256) oscilprepared = 0; if(oscilprepared != 1) prepare(); outpos = (int)((RND * 2.0 - 1.0) * (REALTYPE) OSCIL_SIZE * (Prand - 64.0) / 64.0); outpos = (outpos + 2 * OSCIL_SIZE) % OSCIL_SIZE; for(i = 0; i < OSCIL_SIZE / 2; i++) { outoscilFFTfreqs.c[i] = 0.0; outoscilFFTfreqs.s[i] = 0.0; } nyquist = (int)(0.5 * SAMPLE_RATE / fabs(freqHz)) + 2; if(ADvsPAD) nyquist = (int)(OSCIL_SIZE / 2); if(nyquist > OSCIL_SIZE / 2) nyquist = OSCIL_SIZE / 2; int realnyquist = nyquist; if(Padaptiveharmonics != 0) nyquist = OSCIL_SIZE / 2; for(i = 1; i < nyquist - 1; i++) { outoscilFFTfreqs.c[i] = oscilFFTfreqs.c[i]; outoscilFFTfreqs.s[i] = oscilFFTfreqs.s[i]; } adaptiveharmonic(outoscilFFTfreqs, freqHz); adaptiveharmonicpostprocess(&outoscilFFTfreqs.c[1], OSCIL_SIZE / 2 - 1); adaptiveharmonicpostprocess(&outoscilFFTfreqs.s[1], OSCIL_SIZE / 2 - 1); nyquist = realnyquist; if(Padaptiveharmonics) { //do the antialiasing in the case of adaptive harmonics for(i = nyquist; i < OSCIL_SIZE / 2; i++) { outoscilFFTfreqs.s[i] = 0; outoscilFFTfreqs.c[i] = 0; } } // Randomness (each harmonic), the block type is computed // in ADnote by setting start position according to this setting if((Prand > 64) && (freqHz >= 0.0) && (!ADvsPAD)) { REALTYPE rnd, angle, a, b, c, d; rnd = PI * pow((Prand - 64.0) / 64.0, 2.0); for(i = 1; i < nyquist - 1; i++) { //to Nyquist only for AntiAliasing angle = rnd * i * RND; a = outoscilFFTfreqs.c[i]; b = outoscilFFTfreqs.s[i]; c = cos(angle); d = sin(angle); outoscilFFTfreqs.c[i] = a * c - b * d; outoscilFFTfreqs.s[i] = a * d + b * c; } } //Harmonic Amplitude Randomness if((freqHz > 0.1) && (!ADvsPAD)) { unsigned int realrnd = rand(); srand(randseed); REALTYPE power = Pamprandpower / 127.0; REALTYPE normalize = 1.0 / (1.2 - power); switch(Pamprandtype) { case 1: power = power * 2.0 - 0.5; power = pow(15.0, power); for(i = 1; i < nyquist - 1; i++) { REALTYPE amp = pow(RND, power) * normalize; outoscilFFTfreqs.c[i] *= amp; outoscilFFTfreqs.s[i] *= amp; } break; case 2: power = power * 2.0 - 0.5; power = pow(15.0, power) * 2.0; REALTYPE rndfreq = 2 * PI * RND; for(i = 1; i < nyquist - 1; i++) { REALTYPE amp = pow(fabs(sin(i * rndfreq)), power) * normalize; outoscilFFTfreqs.c[i] *= amp; outoscilFFTfreqs.s[i] *= amp; } break; } srand(realrnd + 1); } if((freqHz > 0.1) && (resonance != 0)) res->applyres(nyquist - 1, outoscilFFTfreqs, freqHz); //Full RMS normalize REALTYPE sum = 0; for(int j = 1; j < OSCIL_SIZE / 2; j++) { REALTYPE term = outoscilFFTfreqs.c[j] * outoscilFFTfreqs.c[j] + outoscilFFTfreqs.s[j] * outoscilFFTfreqs.s[j]; sum += term; } if(sum < 0.000001) sum = 1.0; sum = 1.0 / sqrt(sum); for(int j = 1; j < OSCIL_SIZE / 2; j++) { outoscilFFTfreqs.c[j] *= sum; outoscilFFTfreqs.s[j] *= sum; } if((ADvsPAD) && (freqHz > 0.1)) //in this case the smps will contain the freqs for(i = 1; i < OSCIL_SIZE / 2; i++) smps[i - 1] = sqrt(outoscilFFTfreqs.c[i] * outoscilFFTfreqs.c[i] + outoscilFFTfreqs.s[i] * outoscilFFTfreqs.s[i]); else { fft->freqs2smps(outoscilFFTfreqs, smps); for(i = 0; i < OSCIL_SIZE; i++) smps[i] *= 0.25; //correct the amplitude } if(Prand < 64) return outpos; else return 0; }
/* * Get the oscillator function */ short int OscilGen::get(float *smps, float freqHz, int resonance) { if(needPrepare()) prepare(); fft_t *input = freqHz > 0.0f ? oscilFFTfreqs : pendingfreqs; int outpos = (int)((RND * 2.0f - 1.0f) * synth.oscilsize_f * (Prand - 64.0f) / 64.0f); outpos = (outpos + 2 * synth.oscilsize) % synth.oscilsize; clearAll(outoscilFFTfreqs, synth.oscilsize); int nyquist = (int)(0.5f * synth.samplerate_f / fabs(freqHz)) + 2; if(ADvsPAD) nyquist = (int)(synth.oscilsize / 2); if(nyquist > synth.oscilsize / 2) nyquist = synth.oscilsize / 2; //Process harmonics { int realnyquist = nyquist; if(Padaptiveharmonics != 0) nyquist = synth.oscilsize / 2; for(int i = 1; i < nyquist - 1; ++i) outoscilFFTfreqs[i] = input[i]; adaptiveharmonic(outoscilFFTfreqs, freqHz); adaptiveharmonicpostprocess(&outoscilFFTfreqs[1], synth.oscilsize / 2 - 1); nyquist = realnyquist; } if(Padaptiveharmonics) //do the antialiasing in the case of adaptive harmonics for(int i = nyquist; i < synth.oscilsize / 2; ++i) outoscilFFTfreqs[i] = fft_t(0.0f, 0.0f); // Randomness (each harmonic), the block type is computed // in ADnote by setting start position according to this setting if((Prand > 64) && (freqHz >= 0.0f) && (!ADvsPAD)) { const float rnd = PI * powf((Prand - 64.0f) / 64.0f, 2.0f); for(int i = 1; i < nyquist - 1; ++i) //to Nyquist only for AntiAliasing outoscilFFTfreqs[i] *= FFTpolar<fftw_real>(1.0f, (float)(rnd * i * RND)); } //Harmonic Amplitude Randomness if((freqHz > 0.1f) && (!ADvsPAD)) { unsigned int realrnd = prng(); sprng(randseed); float power = Pamprandpower / 127.0f; float normalize = 1.0f / (1.2f - power); switch(Pamprandtype) { case 1: power = power * 2.0f - 0.5f; power = powf(15.0f, power); for(int i = 1; i < nyquist - 1; ++i) outoscilFFTfreqs[i] *= powf(RND, power) * normalize; break; case 2: power = power * 2.0f - 0.5f; power = powf(15.0f, power) * 2.0f; float rndfreq = 2 * PI * RND; for(int i = 1; i < nyquist - 1; ++i) outoscilFFTfreqs[i] *= powf(fabs(sinf(i * rndfreq)), power) * normalize; break; } sprng(realrnd + 1); } if((freqHz > 0.1f) && (resonance != 0)) res->applyres(nyquist - 1, outoscilFFTfreqs, freqHz); rmsNormalize(outoscilFFTfreqs, synth.oscilsize); if((ADvsPAD) && (freqHz > 0.1f)) //in this case the smps will contain the freqs for(int i = 1; i < synth.oscilsize / 2; ++i) smps[i - 1] = abs(outoscilFFTfreqs, i); else { fft->freqs2smps(outoscilFFTfreqs, smps); for(int i = 0; i < synth.oscilsize; ++i) smps[i] *= 0.25f; //correct the amplitude } if(Prand < 64) return outpos; else return 0; }