void VAOscillator::fillBufferTriangle(AudioBuffer<float>& buffer, AudioBuffer<float>& phaseModBuffer, AudioBuffer<float>& volumeModBuffer, AudioBuffer<float>& pitchModBuffer) { if(isActive) { float* const data = buffer.getWritePointer(0); float const *phaseMod = phaseModBuffer.getReadPointer(0); float const *volMod = volumeModBuffer.getReadPointer(0); float const *pitchMod = pitchModBuffer.getReadPointer(0); for(int sampleIndex = 0; sampleIndex < buffer.getNumSamples(); sampleIndex++) { double phase = currentPhase + phaseModAmp * phaseMod[sampleIndex]; while (phase < 0) { phase += 2 * double_Pi; } while (phase > 2 * double_Pi) { phase -= 2 * double_Pi; } currentPhase += 2 * double_Pi * ((currentFrequency * (pitchMod[sampleIndex] + 2.0))/currentSampleRate); if(currentPhase > 2 * double_Pi) { currentPhase -= 2 * double_Pi; } if(phase < double_Pi) { data[sampleIndex] = (float)((2 * phase)/double_Pi - 1); } else { data[sampleIndex] = (float)((3 - 2 * phase/double_Pi)); } //the 0.000026 is kind of a magic number i didnt calculate it just found it by trying out data[sampleIndex] += (float)(0.000026 * currentFrequency * getTriRes(phase, currentFrequency)); if(phase < double_Pi) { data[sampleIndex] -= (float)(0.000026 * currentFrequency * getTriRes(phase + double_Pi, currentFrequency)); } else if(phase >= double_Pi) { data[sampleIndex] -= (float)(0.000026 * currentFrequency * getTriRes(phase - double_Pi, currentFrequency)); } data[sampleIndex] *= (float)std::abs(0.5 * (volMod[sampleIndex] + 1)); } } else { buffer.clear(); } }// end triangle
void NoiseOscillator::fillBufferNoise(AudioBuffer<float> &buffer) { float* const data = buffer.getWritePointer(0); for(int sampleIndex = 0; sampleIndex < buffer.getNumSamples(); sampleIndex++) { data[sampleIndex] = (2 * rand.nextFloat()) - 1; } }
void VAOscillator::fillBufferSine(AudioBuffer<float>& buffer, AudioBuffer<float>& phaseModBuffer, AudioBuffer<float>& volumeModBuffer, AudioBuffer<float>& pitchModBuffer, Array<int>& midiOns)// add midi buffer and know channel with control Voltage { if(isActive) { float* const data = buffer.getWritePointer(0); float const *phaseMod = phaseModBuffer.getReadPointer(0); float const *volMod = volumeModBuffer.getReadPointer(0); float const *pitchMod = pitchModBuffer.getReadPointer(0); for(int sampleIndex = 0; sampleIndex < buffer.getNumSamples(); sampleIndex++) { //check if this is the best i can do if(midiOns.size() != 0) { if(sampleIndex == midiOns[0]) { resetPhase(); midiOns.remove(0); } } double phase = currentPhase + phaseModAmp * phaseMod[sampleIndex] + currentPhaseOffset; while (phase < 0) { phase += 2 * double_Pi; } while (phase > 2 * double_Pi) { phase -= 2 * double_Pi; } data[sampleIndex] = static_cast<float>(sin(phase) * std::abs(0.5 * (volMod[sampleIndex] + 1))); currentPhase += 2 * double_Pi * ((currentFrequency * (pitchMod[sampleIndex] + 2.0))/currentSampleRate); if(currentPhase > 2 * double_Pi) { currentPhase -= 2 * double_Pi; } } } else { buffer.clear(); } }// end sine
void VAOscillator::fillBufferFallingSaw(AudioBuffer<float>& buffer, AudioBuffer<float>& phaseModBuffer, AudioBuffer<float>& volumeModBuffer, AudioBuffer<float>& pitchModBuffer) { if(isActive) { fillBufferRisingSaw(buffer, phaseModBuffer, volumeModBuffer, pitchModBuffer); float* const data = buffer.getWritePointer(0); for(int sampleIndex = 0; sampleIndex < buffer.getNumSamples(); sampleIndex++) { data[sampleIndex] *= -1; } } else { buffer.clear(); } }// end falling Saw
void VAOscillator::fillBufferRisingSaw(AudioBuffer<float>& buffer, AudioBuffer<float>& phaseModBuffer, AudioBuffer<float>& volumeModBuffer, AudioBuffer<float>& pitchModBuffer) { if(isActive) { float* const data = buffer.getWritePointer(0); float const *phaseMod = phaseModBuffer.getReadPointer(0); float const *volMod = volumeModBuffer.getReadPointer(0); float const *pitchMod = pitchModBuffer.getReadPointer(0); //write momentary phase values into the buffer for(int sampleIndex = 0; sampleIndex < buffer.getNumSamples(); sampleIndex++) { double phase = currentPhase + phaseModAmp * phaseMod[sampleIndex]; while (phase < 0) { phase += 2 * double_Pi; } while (phase > 2 * double_Pi) { phase -= 2 * double_Pi; } currentPhase += 2 * double_Pi * ((currentFrequency * (pitchMod[sampleIndex] + 2.0))/currentSampleRate); if(currentPhase > 2 * double_Pi) { currentPhase -= 2 * double_Pi; } data[sampleIndex] = (float)((2 * phase)/(2 * double_Pi) - 1); data[sampleIndex] += getBlep(phase , currentFrequency);// i have to watch out here because actually currentFrequency is not valid for this calculation data[sampleIndex] *= std::abs(0.5f * (volMod[sampleIndex] + 1)); } } else { buffer.clear(); } }// end rising Saw
Result Upsampler::upsample(AudioBuffer<float> const &inputBuffer, int const inputChannel, AudioBuffer<float> &outputBuffer_, int const outputChannel, int &outputSampleCount_) { int outputSamplesNeeded = roundDoubleToInt( (outputSampleRate * inputBuffer.getNumSamples())/ inputSampleRate); if (outputBuffer_.getNumSamples() < outputSamplesNeeded) return Result::fail("Output buffer too small"); //DBG("upsample inputSampleCount:" << inputSampleCount); if (nullptr == resampler) return Result::fail("No resampler object"); // // Clear the resample and pump some initial zeros into it // resampler->clear(); #if 0 int preloadSamples = resampler->getInLenBeforeOutStart(MAX_RESAMPLER_INPUT_SAMPLES); inputBlockBuffer.clear(MAX_RESAMPLER_INPUT_SAMPLES); while (preloadSamples > 0) { int count = jmin((int)MAX_RESAMPLER_INPUT_SAMPLES, preloadSamples); double* outputBlock = nullptr; resampler->process(inputBlockBuffer, count, outputBlock); preloadSamples -= count; } #endif // // Flush the output buffer // outputBuffer_.clear(); // // Do the actual upsample // outputSampleCount_ = 0; int inputSampleCount = inputBuffer.getNumSamples(); const float * source = inputBuffer.getReadPointer(inputChannel); while (inputSampleCount > 0) { // // Convert float to double // int inputConvertCount = jmin(inputSampleCount, (int)MAX_RESAMPLER_INPUT_SAMPLES); for (int i = 0; i < inputConvertCount; ++i) { inputBlockBuffer[i] = *source; source++; } inputSampleCount -= inputConvertCount; // // Run the SRC // double* outputBlock = nullptr; int outputBlockSampleCount = resampler->process(inputBlockBuffer, inputConvertCount, outputBlock); int outputSpaceRemaining = outputBuffer_.getNumSamples() - outputSampleCount_; int outputCopyCount = jmin( outputSpaceRemaining, outputBlockSampleCount); float *destination = outputBuffer_.getWritePointer(outputChannel, outputSampleCount_); for (int i = 0; i < outputCopyCount; ++i) { *destination = (float)outputBlock[i]; destination++; } outputSampleCount_ += outputCopyCount; } // // Keep filling the output buffer // inputBlockBuffer.clear(MAX_RESAMPLER_INPUT_SAMPLES); while (outputSampleCount_ < outputBuffer_.getNumSamples()) { // // Run the SRC // double* outputBlock = nullptr; int outputBlockSampleCount = resampler->process(inputBlockBuffer, MAX_RESAMPLER_INPUT_SAMPLES, outputBlock); int outputSpaceRemaining = outputBuffer_.getNumSamples() - outputSampleCount_; int outputCopyCount = jmin( outputSpaceRemaining, outputBlockSampleCount); float *destination = outputBuffer_.getWritePointer(outputChannel, outputSampleCount_); for (int i = 0; i < outputCopyCount; ++i) { *destination = (float)outputBlock[i]; destination++; } outputSampleCount_ += outputCopyCount; } //DBG(" outputSampleCount:" << outputSampleCount); return Result::ok(); }