예제 #1
0
void OscilGen::convert2sine(int magtype)
{
    REALTYPE mag[MAX_AD_HARMONICS], phase[MAX_AD_HARMONICS];
    REALTYPE oscil[OSCIL_SIZE];
    FFTFREQS freqs;
    newFFTFREQS(&freqs, OSCIL_SIZE / 2);

    get(oscil, -1.0);
    FFTwrapper *fft = new FFTwrapper(OSCIL_SIZE);
    fft->smps2freqs(oscil, freqs);
    delete (fft);

    REALTYPE max = 0.0;

    mag[0]   = 0;
    phase[0] = 0;
    for(int i = 0; i < MAX_AD_HARMONICS; i++) {
        mag[i]   = sqrt(pow(freqs.s[i + 1], 2) + pow(freqs.c[i + 1], 2.0));
        phase[i] = atan2(freqs.c[i + 1], freqs.s[i + 1]);
        if(max < mag[i])
            max = mag[i];
    }
    if(max < 0.00001)
        max = 1.0;

    defaults();

    for(int i = 0; i < MAX_AD_HARMONICS - 1; i++) {
        REALTYPE newmag   = mag[i] / max;
        REALTYPE newphase = phase[i];

        Phmag[i]   = (int) ((newmag) * 64.0) + 64;

        Phphase[i] = 64 - (int) (64.0 * newphase / PI);
        if(Phphase[i] > 127)
            Phphase[i] = 127;

        if(Phmag[i] == 64)
            Phphase[i] = 64;
    }
    deleteFFTFREQS(&freqs);
    prepare();
}
예제 #2
0
void OscilGen::convert2sine()
{
    float  mag[MAX_AD_HARMONICS], phase[MAX_AD_HARMONICS];
    float  oscil[synth.oscilsize];
    fft_t *freqs = new fft_t[synth.oscilsize / 2];
    get(oscil, -1.0f);
    FFTwrapper *fft = new FFTwrapper(synth.oscilsize);
    fft->smps2freqs(oscil, freqs);
    delete (fft);

    normalize(freqs, synth.oscilsize);

    mag[0]   = 0;
    phase[0] = 0;
    for(int i = 0; i < MAX_AD_HARMONICS; ++i) {
        mag[i]   = abs(freqs, i + 1);
        phase[i] = arg(freqs, i + 1);
    }

    defaults();

    for(int i = 0; i < MAX_AD_HARMONICS - 1; ++i) {
        float newmag   = mag[i];
        float newphase = phase[i];

        Phmag[i] = (int) ((newmag) * 63.0f) + 64;

        Phphase[i] = 64 - (int) (64.0f * newphase / PI);
        if(Phphase[i] > 127)
            Phphase[i] = 127;

        if(Phmag[i] == 64)
            Phphase[i] = 64;
    }
    delete[] freqs;
    prepare();
}
예제 #3
0
//Requires
// - Pquality.samplesize
// - Pquality.basenote
// - Pquality.oct
// - Pquality.smpoct
// - spectrum at various frequencies (oodles of data)
void PADnoteParameters::sampleGenerator(PADnoteParameters::callback cb,
        std::function<bool()> do_abort)
{
    const int samplesize   = (((int) 1) << (Pquality.samplesize + 14));
    const int spectrumsize = samplesize / 2;
    float    *spectrum     = new float[spectrumsize];
    const int profilesize = 512;
    float     profile[profilesize];


    const float bwadjust = getprofile(profile, profilesize);
    float basefreq = 65.406f * powf(2.0f, Pquality.basenote / 2);
    if(Pquality.basenote % 2 == 1)
        basefreq *= 1.5f;

    int samplemax = Pquality.oct + 1;
    int smpoct    = Pquality.smpoct;
    if(Pquality.smpoct == 5)
        smpoct = 6;
    if(Pquality.smpoct == 6)
        smpoct = 12;
    if(smpoct != 0)
        samplemax *= smpoct;
    else
        samplemax = samplemax / 2 + 1;
    if(samplemax == 0)
        samplemax = 1;

    //prepare a BIG FFT
    FFTwrapper *fft      = new FFTwrapper(samplesize);
    fft_t      *fftfreqs = new fft_t[samplesize / 2];

    //this is used to compute frequency relation to the base frequency
    float adj[samplemax];
    for(int nsample = 0; nsample < samplemax; ++nsample)
        adj[nsample] = (Pquality.oct + 1.0f) * (float)nsample / samplemax;
    for(int nsample = 0; nsample < samplemax; ++nsample) {
        if(do_abort())
            goto exit;
        const float basefreqadjust =
            powf(2.0f, adj[nsample] - adj[samplemax - 1] * 0.5f);

        if(Pmode == 0)
            generatespectrum_bandwidthMode(spectrum,
                                           spectrumsize,
                                           basefreq * basefreqadjust,
                                           profile,
                                           profilesize,
                                           bwadjust);
        else
            generatespectrum_otherModes(spectrum, spectrumsize,
                                        basefreq * basefreqadjust);

        //the last samples contains the first samples
        //(used for linear/cubic interpolation)
        const int extra_samples = 5;
        PADnoteParameters::Sample newsample;
        newsample.smp = new float[samplesize + extra_samples];

        newsample.smp[0] = 0.0f;
        for(int i = 1; i < spectrumsize; ++i) //randomize the phases
            fftfreqs[i] = FFTpolar(spectrum[i], (float)RND * 2 * PI);
        //that's all; here is the only ifft for the whole sample;
        //no windows are used ;-)
        fft->freqs2smps(fftfreqs, newsample.smp);


        //normalize(rms)
        float rms = 0.0f;
        for(int i = 0; i < samplesize; ++i)
            rms += newsample.smp[i] * newsample.smp[i];
        rms = sqrt(rms);
        if(rms < 0.000001f)
            rms = 1.0f;
        rms *= sqrt(262144.0f / samplesize);//262144=2^18
        for(int i = 0; i < samplesize; ++i)
            newsample.smp[i] *= 1.0f / rms * 50.0f;

        //prepare extra samples used by the linear or cubic interpolation
        for(int i = 0; i < extra_samples; ++i)
            newsample.smp[i + samplesize] = newsample.smp[i];

        //yield new sample
        newsample.size     = samplesize;
        newsample.basefreq = basefreq * basefreqadjust;
        cb(nsample, newsample);
    }
exit:

    //Cleanup
    delete (fft);
    delete[] fftfreqs;
    delete[] spectrum;
}
예제 #4
0
// Applies the parameters (i.e. computes all the samples, based on parameters);
void PADnoteParameters::applyparameters(bool islocked)
{
    const int samplesize = (((int)1) << (Pquality.samplesize + 14));
    int spectrumsize = samplesize / 2;
    float spectrum[spectrumsize];
    int profilesize = 512;
    float profile[profilesize];

    float bwadjust = getprofile(profile, profilesize);
//    for (int i=0;i<profilesize;i++) profile[i]*=profile[i];
    float basefreq = 65.406f * powf(2.0f, Pquality.basenote / 2);
    if (Pquality.basenote %2 == 1)
        basefreq *= 1.5;

    int samplemax = Pquality.oct + 1;
    int smpoct = Pquality.smpoct;
    if (Pquality.smpoct == 5)
        smpoct = 6;
    if (Pquality.smpoct == 6)
        smpoct = 12;
    if (smpoct != 0)
        samplemax *= smpoct;
    else
        samplemax = samplemax / 2 + 1;
    if (samplemax == 0)
        samplemax = 1;

    // prepare a BIG FFT stuff
    FFTwrapper *fft = new FFTwrapper(samplesize);
    FFTFREQS fftfreqs;
    FFTwrapper::newFFTFREQS(&fftfreqs, samplesize / 2);

    float adj[samplemax]; // this is used to compute frequency relation to the base frequency
    for (int nsample = 0; nsample < samplemax; ++nsample)
        adj[nsample] = (Pquality.oct + 1.0f) * (float)nsample / samplemax;
    for (int nsample = 0; nsample < samplemax; ++nsample)
    {
        float tmp = adj[nsample] - adj[samplemax - 1] * 0.5f;
        float basefreqadjust = powf(2.0f, tmp);

        if (Pmode == 0)
            generatespectrum_bandwidthMode(spectrum, spectrumsize,
                                           basefreq * basefreqadjust, profile,
                                           profilesize, bwadjust);
        else
            generatespectrum_otherModes(spectrum, spectrumsize,
                                        basefreq * basefreqadjust, profile,
                                        profilesize, bwadjust);

        const int extra_samples = 5; // the last samples contains the first
                                     // samples (used for linear/cubic interpolation)
        newsample.smp = new float[samplesize + extra_samples];

        newsample.smp[0] = 0.0;
        for (int i = 1; i < spectrumsize; ++i)
        {   // randomize the phases
            float phase = synth->numRandom() * 6.29f;
            fftfreqs.c[i] = spectrum[i] * cosf(phase);
            fftfreqs.s[i] = spectrum[i] * sinf(phase);
        }
        fft->freqs2smps(&fftfreqs, newsample.smp);
        // that's all; here is the only ifft for the whole sample; no windows are used ;-)

        // normalize(rms)
        float rms = 0.0;
        for (int i = 0; i < samplesize; ++i)
            rms += newsample.smp[i] * newsample.smp[i];
        rms = sqrtf(rms);
        if (rms < 0.000001)
            rms = 1.0;
        rms *= sqrtf(262144.0f / samplesize);
        for (int i = 0; i < samplesize; ++i)
            newsample.smp[i] *= 1.0f / rms * 50.0f;

        // prepare extra samples used by the linear or cubic interpolation
        for (int i = 0; i < extra_samples; ++i)
            newsample.smp[i + samplesize] = newsample.smp[i];

        // replace the current sample with the new computed sample
        if (!islocked)
            synth->actionLock(lockmute);
        deletesample(nsample);
        sample[nsample].smp = newsample.smp;
        sample[nsample].size = samplesize;
        sample[nsample].basefreq = basefreq * basefreqadjust;
        if (!islocked)
            synth->actionLock(unlock);
        newsample.smp = NULL;
    }
    delete fft;
    FFTwrapper::deleteFFTFREQS(&fftfreqs);

    // delete the additional samples that might exists and are not useful
    if (!islocked)
        synth->actionLock(lockmute);
    for (int i = samplemax; i < PAD_MAX_SAMPLES; ++i)
        deletesample(i);
    if (!islocked)
        synth->actionLock(unlock);
}