Monophonic adsr retrigger and getting rid of discontinuity in waveform
- KVRAF
- 15258 posts since 8 Mar, 2005 from Utrecht, Holland
Cross-fade the old triggered note with the new one.
Or first do a 0.001 sec fade off before starting a new note.
Or first do a 0.001 sec fade off before starting a new note.
We are the KVR collective. Resistance is futile. You will be assimilated.
My MusicCalc is served over https!!
My MusicCalc is served over https!!
-
- KVRAF
- 7400 posts since 17 Feb, 2005
Use two voices and flip-flop (crossfade) between them. But watch out for fast note repetitions (3 fast notes for example), as you will have to restart one voice regardless of discontinuity.
-
- KVRist
- Topic Starter
- 58 posts since 6 Sep, 2015
Thanks but I was able to do it by saving the last value of the oscillator before the new note and adding or subtracting it from the main output until it was zero. So it was sort of cross fading i guess? I got it looking like this in case your curious
-
- KVRAF
- 7400 posts since 17 Feb, 2005
That does get rid of the discontinuity, but it can also make low frequency noise. What if the signal in question was at 1000hz and on a crest during the retrigger? If you fade from that crest at a rate much much lower than what's in the signal, you will have generated a signal at that low frequency.
-
- KVRist
- Topic Starter
- 58 posts since 6 Sep, 2015
I made the the two voices but I'm not sure how to flip flop/cross fade without the voices become added together do you have any hints as to how to actually crossfade the voices?
-
- KVRAF
- 7400 posts since 17 Feb, 2005
I would have to see the code in question. It should be an easy problem to solve, since you basically have two voices, each with an amp envelope controlled by one midi event. Build some decision-making logic around the voices which is based on the midi signal, don't try to build the logic into the voice structure.Marvinh wrote:I made the the two voices but I'm not sure how to flip flop/cross fade without the voices become added together do you have any hints as to how to actually crossfade the voices?
-
- KVRist
- Topic Starter
- 58 posts since 6 Sep, 2015
I literally just had to flip flop the voices while crossfading it works pretty well thank you!
Code: Select all
while (--frames >= 0)
{
update();
if(v==0){
o = env->process(vs[v].estate)*osc->process(vs[v].ostate)
+env->process(vs[1].estate)*osc->process(vs[1].ostate)*cf;
}else{
o = env->process(vs[v].estate)*osc->process(vs[v].ostate)
+env->process(vs[0].estate)*osc->process(vs[0].ostate)*cf;
}
if(cf>=.000125){
cf-=.000125;
}else{
cf = 0.0;
}
*out1++ = o;
*out2++ = o;
}
if (frame<sampleFrames) //next note on/off
{
VstInt32 note = notes[event++];
VstInt32 vel = notes[event++];
if(vel>0){
cf = 1.0;
o = 0.0;
}
noteOn(note, vel);
}
/////for the voices in noteOn(note,vel)
v ^= 1;
-
- KVRAF
- 7400 posts since 17 Feb, 2005
This part..
It's a bad habit to re-declare vars that are used often, especially in tight loops. It's better to declare them once on function entry.
So if note repetition presents a problem, you have two options, use more voices, or use a shorter crossfade time.
Code: Select all
if (frame<sampleFrames) //next note on/off
{
VstInt32 note = notes[event++];
VstInt32 vel = notes[event++];
So if note repetition presents a problem, you have two options, use more voices, or use a shorter crossfade time.
-
- KVRAF
- 7400 posts since 17 Feb, 2005
Is this for a sample player? I was just thinking that, for synths, mono retrigger logic could be designed into the oscillator itself. By doing that, it would be possible to control the signal parameters to provide a more natural transition.