This is driving me nuts... I spent HOURS trying to do this without success :(
I have subclassed SamplerVoice and SamplerSound and that works fine (I can play my own sounds w/o any problem using those new classes).
I even used FM sounds (subclassing SynthesiserVoice and SynthesiserSound the same way it's done in JuceDemo) playing simultaneously with sampled sounds with no problem. The problem started when tried to override the SamplerVoice::renderNextBlock method in my new voice class (called WaveVoice).
Clearly I must be doing somehthing wrong. Could someone out there give me a direction ? please ? I'm desperate...
Here is what I have done:
/** Wavetable synth sound */
class WaveSound : public SamplerSound
{
public:
WaveSound (const String& soundName,
AudioFormatReader& source,
const BigInteger& notes,
const int midiNoteForNormalPitch,
const double attackTimeSecs,
const double releaseTimeSecs,
const double maxSampleLengthSeconds) :
SamplerSound (soundName, source, notes, midiNoteForNormalPitch, attackTimeSecs, releaseTimeSecs, maxSampleLengthSeconds)
{
... Same code as for SamplerSound constructor
}
String name;
ScopedPointer<AudioSampleBuffer> data;
double sourceSampleRate;
BigInteger midiNotes;
int length, attackSamples, releaseSamples;
int midiRootNote;
};
//==============================================================================
/** Wavetable synth voice */
class WaveVoice : public SamplerVoice
{
public:
WaveVoice()
: pitchRatio (0.0),
sourceSamplePosition (0.0),
lgain (0.0f), rgain (0.0f),
attackReleaseLevel (0), attackDelta (0), releaseDelta (0),
isInAttack (false), isInRelease (false)
{
}
//==============================================================================
void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples)
{
if (WaveSound* playingSound = static_cast <WaveSound*> (getCurrentlyPlayingSound().get()))
{ ... Same code as in SamplerVoice::renderNextBlock
}
}
Your WaveVoice class probably needs to override "canPlaySound(SynthesiserSound* sound)" so the synthesiser knows what sounds the voice is able to play.
It looks like you're redefining all of SamplerSound's fields which doesn't seem right. Are you certain you want to be doing that? Also having a copy of SamplerSound's constructor code in your subclass's constructor doesn't seem like the right thing to be doing either.
Thanks... but it still does not work. And frankly I don't understand why it would need this. The SamplerVoice::canPlaySound should do the work, shouldn't it ?
The weird thing is that if I just rename my renderNextBlock to something else (i.e. I don't use it) , it works (I can hear the sounds). So the rest of the code looks ok.
Thank you but the code shown here is just for testing purpose and minimize the changes to see where it doesn't work. Shouldn't hurt though. Or am I missing something ?
Obviously when I get this to work I will modify the code and the variables.
Hi Phil. I know this was 7 years ago so it’s a long shot, but can you give any more info on what methods you copied and from which superclasses? I’ve got the same issue where I cannot get the audio to pass through the rendernextblock function, even though I’ve copied the code as is from the base samplervoice class, and also samplersound. Like you, I can get the derived classes to work but when I override rendernextblock it stops. I’m actually trying to find a way to pan individual voices in the synth and find it odd that this convoluted method is the way to go, but I’m stumped and there doesn’t seem to be any other posts apart from the odd one or two where people have struggled like me. Thanks to you and anyone else who may be able to give me a nudge in the right direction.
Your best bet to get properly working custom behavior/processing is to inherit from SynthesiserVoice, not from SamplerVoice, as that isn’t really designed to be inherited from. You should also do your own class for the sound part, by inheriting from SynthesiserSound and not from SamplerSound.
The documentation should really clarify that about SamplerSound/SamplerVoice and/or the classes should be marked in the code as “final”.
Oh really? I know that the samplervoice and samplersound inherit from the synth classes so that would make sense. Thanks mate, that’s given me something to think about.
Just thought I’d come back to say that you were absolutely right. Don’t know why I didn’t think to do that in the first place, but I’ve now derived from the synth classes and used the code from the samplervoice/sound classes to help me set it up and get it running. Thanks again.