Hi
Sorry i’m new to all this, do you just want me to copy and paste some of the code into this, because the programs spread over a number of files. I’m currently rebuilding a new project that just plays the metronome and i’m still getting the same problem, its almost like the sound generator relies on something else and that i keep removing it. I’ll paste in my sound generating file and see what you think…
#include “MetronomeSoundGenerator.h”
SineWaveVoice::SineWaveVoice()
: angleDelta (0.0),
tailOff (0.0)
{
}
bool SineWaveVoice::canPlaySound (SynthesiserSound* sound)
{
return dynamic_cast <SineWaveSound*> (sound) != 0;
}
void SineWaveVoice::startNote (const int midiNoteNumber, const float velocity,
SynthesiserSound* sound, const int currentPitchWheelPosition)
{
currentAngle = 0.0;
level = velocity * 0.15;
tailOff = 0.0;
double cyclesPerSecond = MidiMessage::getMidiNoteInHertz (midiNoteNumber);
double cyclesPerSample = cyclesPerSecond / getSampleRate();
angleDelta = cyclesPerSample * 2.0 * double_Pi;
}
void SineWaveVoice::stopNote (const bool allowTailOff)
{
if (allowTailOff)
{
// start a tail-off by setting this flag. The render callback will pick up on
// this and do a fade out, calling clearCurrentNote() when it’s finished.
if (tailOff == 0.0) // we only need to begin a tail-off if it's not already doing so - the
// stopNote method could be called more than once.
tailOff = 1.0;
}
else
{
// we're being told to stop playing immediately, so reset everything..
clearCurrentNote();
angleDelta = 0.0;
}
}
void SineWaveVoice::renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples)
{
if (angleDelta != 0.0)
{
if (tailOff > 0)
{
while (–numSamples >= 0)
{
const float currentSample = (float) (sin (currentAngle) * level * tailOff);
for (int i = outputBuffer.getNumChannels(); --i >= 0;)
*outputBuffer.getSampleData (i, startSample) += currentSample;
currentAngle += angleDelta;
++startSample;
tailOff *= 0.99;
if (tailOff <= 0.005)
{
clearCurrentNote();
angleDelta = 0.0;
break;
}
}
}
else
{
while (--numSamples >= 0)
{
const float currentSample = (float) (sin (currentAngle) * level);
for (int i = outputBuffer.getNumChannels(); --i >= 0;)
*outputBuffer.getSampleData (i, startSample) += currentSample;
currentAngle += angleDelta;
++startSample;
}
}
}
}
void SineWaveVoice::pitchWheelMoved (const int newValue){}
void SineWaveVoice::controllerMoved (const int controllerNumber,
const int newValue){}
MetronomeSoundGenerator::MetronomeSoundGenerator(AudioDeviceManager& audioDeviceManager_)
: audioDeviceManager (audioDeviceManager_), Thread(“Click End”)
{
audioSourcePlayer = new AudioSourcePlayer;
audioSourcePlayer->setSource (this);
audioSourcePlayer->setGain(1.0);
synth = new Synthesiser;
midiCollector = new MidiMessageCollector;
for (int i = 4; --i >= 0;)
{
synth->addVoice (new SineWaveVoice()); // These voices will play our custom sine-wave sounds..
//synth.addVoice (new SamplerVoice()); // and these ones play the sampled sounds
}
// and add some sounds for them to play...
synth->addSound (new SineWaveSound());
audioDeviceManager.addAudioCallback (audioSourcePlayer);
}
MetronomeSoundGenerator::~MetronomeSoundGenerator()
{
audioSourcePlayer->setSource (0);
audioDeviceManager.removeAudioCallback (audioSourcePlayer);
deleteAndZero(audioSourcePlayer);
deleteAndZero(synth);
deleteAndZero(midiCollector);
}
void MetronomeSoundGenerator::startClick (int midiNoteNumber)
{
synth->noteOn (1, midiNoteNumber, 1);
startThread(1);
}
void MetronomeSoundGenerator::stopClick (int midiNoteNumber)
{
synth->noteOff (1, midiNoteNumber, false);
}
void MetronomeSoundGenerator::prepareToPlay (int samplesPerBlockExpected,
double sampleRate)
{
midiCollector->reset (sampleRate);
synth->setCurrentPlaybackSampleRate (sampleRate);
}
void MetronomeSoundGenerator::releaseResources()
{
}
void MetronomeSoundGenerator::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill)
{
// the synth always adds its output to the audio buffer, so we have to clear it
// first…
bufferToFill.clearActiveBufferRegion();
// fill a midi buffer with incoming messages from the midi input.
MidiBuffer incomingMidi;
midiCollector->removeNextBlockOfMessages (incomingMidi, bufferToFill.numSamples);
// and now get the synth to process the midi events and generate its output.
synth->renderNextBlock (*bufferToFill.buffer, incomingMidi, 0, bufferToFill.numSamples);
}
void MetronomeSoundGenerator::run()
{
wait(100);
stopClick(100);
stopClick(85);
}
Thanks