float getNextSample(){ float impact = osc[0]->getNextSample(); impact += osc[1]->getNextSample(); impact += osc[2]->getNextSample(); float body = impact; impact = bp->process(impact); impact *= eg[0]->getNextSample(); body = hp->process(body); body *= eg[1]->getNextSample(); return impact + body; }
ZoelzerMultiFilterPatch(){ registerParameter(PARAMETER_A, "Mode"); registerParameter(PARAMETER_B, "Frequency"); registerParameter(PARAMETER_C, "Resonance"); registerParameter(PARAMETER_D, "Gain"); previous.setCoefficents(coeffs); }
DubDelayPatch() { registerParameter(PARAMETER_A, "Time"); registerParameter(PARAMETER_B, "Feedback"); registerParameter(PARAMETER_C, "Tone"); registerParameter(PARAMETER_D, "Wet"); delayBuffer = CircularBuffer::create(REQUEST_BUFFER_SIZE); highpass = BiquadFilter::create(1); highpass->setHighPass(40/(getSampleRate()/2), FilterStage::BUTTERWORTH_Q); // dc filter }
FormantManager::FormantManager(int num_formants) : ProcessorRouter(0, 0) { Bypass* audio_input = new Bypass(); cr::Bypass* reset_input = new cr::Bypass(); registerInput(audio_input->input(), kAudio); registerInput(reset_input->input(), kReset); addProcessor(audio_input); addProcessor(reset_input); VariableAdd* total = new VariableAdd(num_formants); for (int i = 0; i < num_formants; ++i) { BiquadFilter* formant = new BiquadFilter(); formant->plug(audio_input, BiquadFilter::kAudio); formant->plug(reset_input, BiquadFilter::kReset); formants_.push_back(formant); addProcessor(formant); total->plugNext(formant); } addProcessor(total); registerOutput(total->output()); }
BiquadFilterTestPatch(){ registerParameter(PARAMETER_A, "Cutoff"); registerParameter(PARAMETER_B, "Resonance"); int stages=3; filter=BiquadFilter::create(stages); float cutoff=0.2; float resonance=2; //test setLowPass FloatArray coefficients=FloatArray::create(5*stages); FloatArray states=FloatArray::create(2*stages); FilterStage stage(coefficients, states); filter->setLowPass(cutoff, resonance); stage.setLowPass(cutoff, resonance); for(int k=0; k<stages; k++){ for(int n=0; n<5; n++){ float filterC=filter->getFilterStage(k).getCoefficients()[n]; float stageC=stage.getCoefficients()[n]; ASSERT(filterC==stageC, "Coefficients not initialized"); //check that filter coefficients are properly initialized } } int signalLength=100; FloatArray x=FloatArray::create(signalLength); FloatArray x1=FloatArray::create(signalLength); FloatArray y=FloatArray::create(signalLength); FloatArray y1=FloatArray::create(signalLength); x.noise(); x1.copyFrom(x); filter->process(x1, y1, x1.getSize()); //manually compute the filter float b0=filter->getFilterStage(0).getCoefficients()[0]; float b1=filter->getFilterStage(0).getCoefficients()[1]; float b2=filter->getFilterStage(0).getCoefficients()[2]; float a1=filter->getFilterStage(0).getCoefficients()[3]; float a2=filter->getFilterStage(0).getCoefficients()[4]; for(int n=0; n<stages; n++){ float d1=0; float d2=0; for(int n=0; n<x.getSize(); n++){ //manually apply filter, one stage y[n] = b0 * x[n] + d1; d1 = b1 * x[n] + a1 * y[n] + d2; d2 = b2 * x[n] + a2 * y[n]; } x.copyFrom(y); //copy the output to the input for the next iteration. INEFFICIENT } //done with the filter for(int n=0; n<x.getSize(); n++){ // ASSERT(abs(y[n]-y1[n])<0.0001, "");//BiquadFilter.process(FloatArray, FloatArray) result"); //TODO: fails for non-arm } FloatArray::destroy(x); FloatArray::destroy(x1); FloatArray::destroy(y); FloatArray::destroy(y1); debugMessage("All tests passed"); }
float getNextSample(){ float vca1 = sine->getNextSample(); vca1 += chirp->getNextSample(); vca1 *= env1->getNextSample(); float vca2 = 0.0f; vca2 += impulse->getNextSample(); // vca2 += filter->process(noise->getNextSample()); // vca2 *= env2->getNextSample(); vca2 += noise->getNextSample(); vca2 = filter->process(vca2); vca2 *= env2->getNextSample(); float sample = vca1*(1.0-balance) + vca2*balance; return sample; }
DrumVoice(float sr) : fs(sr) { // env = new AdsrEnvelope(sr); // env = FloatArray::create(1024); // for(int i=0; i<env.getSize(); ++i) // env[i] = expf(-M_E*i/env.getSize()); snare = 0; balance = 0.2; sine = new SineOscillator(sr); chirp = new ChirpOscillator(sr); impulse = new ImpulseOscillator(); env1 = new ExponentialDecayEnvelope(sr); env2 = new ExponentialDecayEnvelope(sr); noise = new PinkNoiseOscillator(); filter = BiquadFilter::create(1); filter->setLowPass(0.6, FilterStage::BUTTERWORTH_Q); }
void processAudio(AudioBuffer &buffer) { float feedback, wet, _delayTime, _tone, delaySamples; _delayTime = getParameterValue(PARAMETER_A); feedback = 2*getParameterValue(PARAMETER_B)+0.01; _tone = getParameterValue(PARAMETER_C); wet = getParameterValue(PARAMETER_D); tone = 0.05*_tone + 0.95*tone; tf.setTone(tone); FloatArray buf = buffer.getSamples(LEFT_CHANNEL); highpass->process(buf); for (int i = 0 ; i < buffer.getSize(); i++) { delayTime = 0.01*_delayTime + 0.99*delayTime; delaySamples = delayTime * (delayBuffer->getSize()-1); buf[i] = dist(tf.processSample(buf[i] + (wet * delayBuffer->read(delaySamples)))); // delayBuffer->write(dist(tf.processSample(feedback * buf[i],0))); delayBuffer->write(feedback * buf[i]); } }
void setSnap(float s){ snare = s; balance = s*0.5; filter->setLowPass(0.25+balance, FilterStage::BUTTERWORTH_Q); }
void processAudio(AudioBuffer &buffer){ int mode = getParameterValue(PARAMETER_A)*ZOELZER_MODES; float omega = (M_PI/2 - 0.01)*getParameterValue(PARAMETER_B) + 0.00001; // Frequency float K = tan(omega); float Q = getParameterValue(PARAMETER_C) * 10 + 0.1; // Resonance float gain = getParameterValue(PARAMETER_D); float V = abs(gain-0.5)*60 + 1; // Gain float norm; /* coeffs[b0, b1, b2, a1, a2] */ switch(mode){ case ZOELZER_LOWPASS_FILTER_MODE: norm = 1 / (1 + K / Q + K * K); coeffs[0] = K * K * norm; coeffs[1] = 2 * coeffs[0]; coeffs[2] = coeffs[0]; coeffs[3] = 2 * (K * K - 1) * norm; coeffs[4] = (1 - K / Q + K * K) * norm; break; case ZOELZER_HIGHPASS_FILTER_MODE: norm = 1 / (1 + K / Q + K * K); coeffs[0] = 1 * norm; coeffs[1] = -2 * coeffs[0]; coeffs[2] = coeffs[0]; coeffs[3] = 2 * (K * K - 1) * norm; coeffs[4] = (1 - K / Q + K * K) * norm; break; case ZOELZER_BANDPASS_FILTER_MODE: norm = 1 / (1 + K / Q + K * K); coeffs[0] = K / Q * norm; coeffs[1] = 0; coeffs[2] = -coeffs[0]; coeffs[3] = 2 * (K * K - 1) * norm; coeffs[4] = (1 - K / Q + K * K) * norm; break; case ZOELZER_NOTCH_FILTER_MODE: norm = 1 / (1 + K / Q + K * K); coeffs[0] = (1 + K * K) * norm; coeffs[1] = 2 * (K * K - 1) * norm; coeffs[2] = coeffs[0]; coeffs[3] = coeffs[1]; coeffs[4] = (1 - K / Q + K * K) * norm; break; case ZOELZER_PEAK_FILTER_MODE: if (gain >= 0.5) { norm = 1 / (1 + 1/Q * K + K * K); coeffs[0] = (1 + V/Q * K + K * K) * norm; coeffs[1] = 2 * (K * K - 1) * norm; coeffs[2] = (1 - V/Q * K + K * K) * norm; coeffs[3] = coeffs[1]; coeffs[4] = (1 - 1/Q * K + K * K) * norm; } else { norm = 1 / (1 + V/Q * K + K * K); coeffs[0] = (1 + 1/Q * K + K * K) * norm; coeffs[1] = 2 * (K * K - 1) * norm; coeffs[2] = (1 - 1/Q * K + K * K) * norm; coeffs[3] = coeffs[1]; coeffs[4] = (1 - V/Q * K + K * K) * norm; } break; case ZOELZER_LOWSHELF_FILTER_MODE: if (gain >= 0.5) { norm = 1 / (1 + M_SQRT2 * K + K * K); coeffs[0] = (1 + sqrt(2*V) * K + V * K * K) * norm; coeffs[1] = 2 * (V * K * K - 1) * norm; coeffs[2] = (1 - sqrt(2*V) * K + V * K * K) * norm; coeffs[3] = 2 * (K * K - 1) * norm; coeffs[4] = (1 - M_SQRT2 * K + K * K) * norm; } else { norm = 1 / (1 + sqrt(2*V) * K + V * K * K); coeffs[0] = (1 + M_SQRT2 * K + K * K) * norm; coeffs[1] = 2 * (K * K - 1) * norm; coeffs[2] = (1 - M_SQRT2 * K + K * K) * norm; coeffs[3] = 2 * (V * K * K - 1) * norm; coeffs[4] = (1 - sqrt(2*V) * K + V * K * K) * norm; } break; case ZOELZER_HIGHSHELF_FILTER_MODE: if (gain >= 0.5) { norm = 1 / (1 + M_SQRT2 * K + K * K); coeffs[0] = (V + sqrt(2*V) * K + K * K) * norm; coeffs[1] = 2 * (K * K - V) * norm; coeffs[2] = (V - sqrt(2*V) * K + K * K) * norm; coeffs[3] = 2 * (K * K - 1) * norm; coeffs[4] = (1 - M_SQRT2 * K + K * K) * norm; } else { norm = 1 / (V + sqrt(2*V) * K + K * K); coeffs[0] = (1 + M_SQRT2 * K + K * K) * norm; coeffs[1] = 2 * (K * K - 1) * norm; coeffs[2] = (1 - M_SQRT2 * K + K * K) * norm; coeffs[3] = 2 * (K * K - V) * norm; coeffs[4] = (V - sqrt(2*V) * K + K * K) * norm; } break; } int size = buffer.getSize(); float* samples = buffer.getSamples(0); float buf[size]; previous.process(samples, buf, size); previous.setCoefficents(coeffs); filter.setCoefficents(coeffs); filter.process(samples, size); for(int i=0; i<size; ++i){ float xfade = (float)i/(float)size; samples[i] = buf[i]*(1.0f-xfade) + samples[i]*xfade; } }
void setFilter(float f){ bp->setBandPass(f, FilterStage::BUTTERWORTH_Q); hp->setHighPass(f, FilterStage::BUTTERWORTH_Q); }
static void readMaxLevelsFilteringWithColour (AudioFormatReader &reader, BiquadFilter &filterLow, BiquadFilter &filterLowMid, BiquadFilter &filterHighMid, BiquadFilter &filterHigh, int64 startSampleInFile, int64 numSamples, float& lowestLeft, float& highestLeft, float& lowestRight, float& highestRight, Colour &colourLeft, Colour &colourRight) { if (numSamples <= 0) { lowestLeft = 0; lowestRight = 0; highestLeft = 0; highestRight = 0; colourLeft = Colours::white; colourRight = Colours::white; return; } const int bufferSize = (int) jmin (numSamples, (int64) 4096); HeapBlock<int> tempSpace (bufferSize * 2 + 64); // const int heapBlockSize = bufferSize * 2 + 64; // int tempSpace[heapBlockSize]; int* tempBuffer[3]; tempBuffer[0] = &tempSpace[0];//tempSpace.getData(); tempBuffer[1] = &tempSpace[bufferSize];//tempSpace.getData() + bufferSize; tempBuffer[2] = 0; // HeapBlock<int> filteredBlock (bufferSize * 4); // int* filteredArray[4] = {filteredBlock.getData(), // filteredBlock.getData()+bufferSize, // filteredBlock.getData()+(bufferSize*2), // filteredBlock.getData()+(bufferSize*3)}; const int filteredBlockSize = bufferSize * 4; HeapBlock<int> filteredBlock (filteredBlockSize); //int filteredBlock[filteredBlockSize]; int* filteredArray[4] = {&filteredBlock[0], &filteredBlock[bufferSize], &filteredBlock[bufferSize * 2], &filteredBlock[bufferSize * 3]}; float avgLow = 0.0f, avgMid = 0.0f, avgHigh = 0.0f; if (reader.usesFloatingPointData) { float lmin = 1.0e6f; float lmax = -lmin; float rmin = lmin; float rmax = lmax; while (numSamples > 0) { const int numToDo = (int) jmin (numSamples, (int64) bufferSize); reader.read (tempBuffer, 2, startSampleInFile, numToDo, false); // copy samples to buffers ready to be filtered memcpy(filteredArray[0], tempBuffer[0], sizeof(int)*numToDo); memcpy(filteredArray[1], tempBuffer[0], sizeof(int)*numToDo); memcpy(filteredArray[2], tempBuffer[0], sizeof(int)*numToDo); memcpy(filteredArray[3], tempBuffer[0], sizeof(int)*numToDo); // filter buffers filterLow.processSamples (reinterpret_cast<float*> (filteredArray[0]), numToDo); filterLowMid.processSamples (reinterpret_cast<float*> (filteredArray[1]), numToDo); filterHighMid.processSamples (reinterpret_cast<float*> (filteredArray[2]), numToDo); filterHigh.processSamples (reinterpret_cast<float*> (filteredArray[3]), numToDo); // calculate colour for (int i = 0; i < numToDo; i++) { // avgLow += fabsf((reinterpret_cast<float*>(filteredArray[0]))[i]); // avgMid += fabsf((reinterpret_cast<float*>(filteredArray[1]))[i]); // avgHigh += fabsf((reinterpret_cast<float*>(filteredArray[2]))[i]); float low = fabsf((reinterpret_cast<float*> (filteredArray[0]))[i]); float mid = (fabsf((reinterpret_cast<float*> (filteredArray[1]))[i]) + fabsf((reinterpret_cast<float*>(filteredArray[2]))[i])); float high = fabsf((reinterpret_cast<float*> (filteredArray[3]))[i]); if (low > avgLow) { avgLow = low; } if (mid > avgMid) { avgMid = mid; } if (high > avgHigh) { avgHigh = high; } } numSamples -= numToDo; startSampleInFile += numToDo; float bufMin, bufMax; findMinAndMax (reinterpret_cast<float*> (tempBuffer[0]), numToDo, bufMin, bufMax); lmin = jmin (lmin, bufMin); lmax = jmax (lmax, bufMax); if (reader.numChannels > 1) { findMinAndMax (reinterpret_cast<float*> (tempBuffer[1]), numToDo, bufMin, bufMax); rmin = jmin (rmin, bufMin); rmax = jmax (rmax, bufMax); } } if (reader.numChannels <= 1) { rmax = lmax; rmin = lmin; } lowestLeft = lmin; highestLeft = lmax; lowestRight = rmin; highestRight = rmax; // avgLow = (avgLow / numToAverage); // avgMid = (avgMid / numToAverage); // avgHigh = (avgHigh / numToAverage); } else { int lmax = std::numeric_limits<int>::min(); int lmin = std::numeric_limits<int>::max(); int rmax = std::numeric_limits<int>::min(); int rmin = std::numeric_limits<int>::max(); while (numSamples > 0) { const int numToDo = (int) jmin (numSamples, (int64) bufferSize); if (! reader.read (tempBuffer, 2, startSampleInFile, numToDo, false)) break; // copy samples to buffers ready to be filtered memcpy (filteredArray[0], tempBuffer[0], sizeof (int) * numToDo); memcpy (filteredArray[1], tempBuffer[0], sizeof (int) * numToDo); memcpy (filteredArray[2], tempBuffer[0], sizeof (int) * numToDo); memcpy (filteredArray[3], tempBuffer[0], sizeof (int) * numToDo); // filter buffers filterLow.processSamples((filteredArray[0]), numToDo); filterLowMid.processSamples((filteredArray[1]), numToDo); filterHighMid.processSamples((filteredArray[2]), numToDo); filterHigh.processSamples((filteredArray[3]), numToDo); // calculate colour for (int i = 0; i < numToDo; i++) { // avgLow += abs(((filteredArray[0]))[i]); // avgMid += abs(((filteredArray[1]))[i]); // avgHigh += abs(((filteredArray[2]))[i]); int low = abs(filteredArray[0][i]); int mid = (abs(filteredArray[1][i]) + abs(filteredArray[2][i])); int high = abs(filteredArray[3][i]); if (low > avgLow) { avgLow = (float) low; } if (mid > avgMid) { avgMid = (float) mid; } if (high > avgHigh) { avgHigh = (float) high; } } numSamples -= numToDo; startSampleInFile += numToDo; for (int j = reader.numChannels; --j >= 0;) { int bufMin, bufMax; findMinAndMax (tempBuffer[j], numToDo, bufMin, bufMax); if (j == 0) { lmax = jmax (lmax, bufMax); lmin = jmin (lmin, bufMin); } else { rmax = jmax (rmax, bufMax); rmin = jmin (rmin, bufMin); } } } if (reader.numChannels <= 1) { rmax = lmax; rmin = lmin; } lowestLeft = lmin / (float) std::numeric_limits<int>::max(); highestLeft = lmax / (float) std::numeric_limits<int>::max(); lowestRight = rmin / (float) std::numeric_limits<int>::max(); highestRight = rmax / (float) std::numeric_limits<int>::max(); // avgLow = (avgLow / numToAverage) / (float) std::numeric_limits<int>::max(); // avgMid = (avgMid / numToAverage) / (float) std::numeric_limits<int>::max(); // avgHigh = (avgHigh / numToAverage) / (float) std::numeric_limits<int>::max(); avgLow = avgLow / (float) ::std::numeric_limits<int>::max(); avgMid = avgMid / (float) ::std::numeric_limits<int>::max(); avgHigh = avgHigh / (float) ::std::numeric_limits<int>::max(); } uint8 maxSize = ::std::numeric_limits<uint8>::max(); colourLeft = Colour::fromRGB((uint8) (avgLow * maxSize), (uint8) (avgMid * maxSize * 0.66f), (uint8) (avgHigh * maxSize * 0.33f)); colourRight = colourLeft; }