im following this tutorial Build a MIDI synthesiser - JUCE to make a synth. i got it to work following the tutorial but whated to add idfferent waves such as a square wave i thought this would be easy using a osilator class since i can use a lambda function for creating the wave i want simply.
so i tried it and it didnt work so i went along with the AudioProgrammers https://www.youtube.com/watch?v=AfrAWH5i-pQ&list=PLLgJJsrdwhPwJimt5vtHtNmu63OucmPck&index=3 tutorial which uses oscillators but in a plugin instead of an audio app.
so i’ve frnkensteind the two togther as far as i see reasonable but sound wont come out. im hitting the rendernext lock funtion in the audiovoice object and the buffer has stuff in it but i dont know why no sound is being produced.
#include "SineWaveVoice.h"
#include "SineWaveSound.h"
SineWaveVoice::SineWaveVoice(){}
void SineWaveVoice::PrepareToPlay(int samplesPerBlockExpected, double sampleRate, int numChannels)
{
adsr.setSampleRate(sampleRate);
spec.numChannels = numChannels;
spec.sampleRate = sampleRate;
spec.maximumBlockSize = samplesPerBlockExpected;
sineOsc.prepare(spec);
gain.prepare(spec);
//sineOsc.setFrequency(juce::MidiMessage::getMidiNoteInHertz(midiNoteNumber));
sineOsc.setFrequency(220);
gain.setGainLinear(0.1f);
isPrepared = true;
}
bool SineWaveVoice::canPlaySound(juce::SynthesiserSound* sound)
{
return dynamic_cast<SineWaveSound*> (sound) != nullptr;
}
void SineWaveVoice::startNote(int midiNoteNumber, float velocity, juce::SynthesiserSound*, int)
{
}
void SineWaveVoice::renderNextBlock(juce::AudioSampleBuffer& outputBuffer, int startSample, int numSamples)
{
jassert(isPrepared);
juce::dsp::AudioBlock<float> block{ outputBuffer };
sineOsc.process(juce::dsp::ProcessContextReplacing<float>(block));
gain.process(juce::dsp::ProcessContextReplacing<float>(block));
adsr.applyEnvelopeToBuffer(outputBuffer, startSample, numSamples);
}
void SineWaveVoice::stopNote(float, bool allowTailOff)
{
clearCurrentNote();
}
#include "synthAudioSource.h"
#include "sineWaveSound.h"
#include "sineWaveVoice.h"
synthAudioSource::synthAudioSource(juce::MidiKeyboardState& keyState) : keyboardState(keyState)
{
for (auto i = 0; i < 4; ++i)
synth.addVoice(new SineWaveVoice());
synth.addSound(new SineWaveSound());
}
void synthAudioSource::setUsingSineWaveSound()
{
synth.clearSounds();
}
void synthAudioSource::prepareToPlay(int samplesPerBlockExpected, double sampleRate)
{
synth.setCurrentPlaybackSampleRate(sampleRate);
midiCollector.reset(sampleRate);
for (int i{}; i < synth.getNumVoices(); ++i) {
if (auto voice = dynamic_cast<SineWaveVoice*>(synth.getVoice(i)))
{
voice->PrepareToPlay(samplesPerBlockExpected, sampleRate, 2);
}
}
}
void synthAudioSource::releaseResources()
{
}
void synthAudioSource::getNextAudioBlock(const juce::AudioSourceChannelInfo& bufferToFill)
{
bufferToFill.clearActiveBufferRegion();
juce::MidiBuffer incomingMidi;
midiCollector.removeNextBlockOfMessages(incomingMidi, bufferToFill.numSamples);
keyboardState.processNextMidiBuffer(incomingMidi, bufferToFill.startSample, bufferToFill.numSamples, true);
synth.renderNextBlock(*bufferToFill.buffer, incomingMidi, bufferToFill.startSample, bufferToFill.numSamples);
}
juce::MidiMessageCollector* synthAudioSource::getMidiCollector()
{
return &midiCollector;
}
#include "SineWaveSound.h"
SineWaveSound::SineWaveSound(){}
bool SineWaveSound::appliesToNote(int) { return true; }
bool SineWaveSound::appliesToChannel(int) { return true; }
#include "MainComponent.h"
//==============================================================================
MainComponent::MainComponent() : keyboardComponent(keyboardState, juce::MidiKeyboardComponent::horizontalKeyboard),
synthAudioSource(keyboardState)
{
//midi keyboard
addAndMakeVisible(keyboardComponent);
setSize (200, 200);
setAudioChannels (0, 2);
}
MainComponent::~MainComponent()
{
shutdownAudio();
}
//==============================================================================
void MainComponent::prepareToPlay (int samplesPerBlockExpected, double sampleRate)
{
synthAudioSource.prepareToPlay(samplesPerBlockExpected, sampleRate);
}
void MainComponent::getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill)
{
synthAudioSource.getNextAudioBlock(bufferToFill);
}
void MainComponent::releaseResources()
{
synthAudioSource.releaseResources();
}
//==============================================================================
void MainComponent::paint (juce::Graphics& g)
{}
void MainComponent::resized()
{
keyboardComponent.setBounds(10, 40, getWidth() - 20, getHeight() - 50);
}
void MainComponent::timerCallback()
{
keyboardComponent.grabKeyboardFocus();
stopTimer();
}
sorry its a alot of code any guidence or critisism you give is appreaciated
