On Monday, January 23, 2017 00:32:40 Frank Neumann wrote: > Just summarizing, for clarity sake: With these 2 changes applied, the issue > is gone (of course this is not a fix yet):
@Grigor, @Andreas: are you still around on this list? Maybe you can comment as well, because I am not very familiar with the SignalUnitRack stuff of the SFZ engine. I had a look at this issue described by Frank. It is a bug in the SignalUnitRack handling. In very short, the following would fix the issue Frank encountered with his SFZ file: Index: src/engines/common/SignalUnit.cpp =================================================================== --- src/engines/common/SignalUnit.cpp (revision 3099) +++ src/engines/common/SignalUnit.cpp (working copy) @@ -25,6 +25,6 @@ namespace LinuxSampler { bool SignalUnit::DelayStage() { - return (DelayTrigger() >= pRack->GetCurrentStep()); + return (DelayTrigger() > pRack->GetCurrentStep()); } } // namespace LinuxSampler But, and there is a big "but", that short patch would just cure the symptom in Frank's particular case, as far as I can see it, the bug would still be triggered in other scenarios (more complex SFZ files) though. So here is a more detailed description about this issue: The SFZ engine is calling: pSignalUnitRack->GetEndpointUnit()->GetVolume() inside of method AbstractVoice::Synthesize() to get the current volume factor to be applied for the voice in the current audio (sub)fragment. Since Frank's sfz file is very simple (no volume modulators), that GetVolume() call would always return 1.0f (neutral volume factor), except of one case: at the very beginning of the life time of each voice (that is when pVoice->Pos == 0.0) that GetVolume() call returns 0.0f instead. And that is wrong. GetVolume() does return 0.0f at the very beginning of a voice's life time, because EndPointUnit::GetVolume() calls suVolEG.GetLevel() [SfzSignalUnitRack.cpp, line 617], which is implemented like this [SfzSignalUnitRack.h, line 165]: virtual float GetLevel() { return DelayStage() ? 0 : EG.getLevel(); } Now in Frank's case, it is simply a bug to assume that it would be in a delay stage at the beginning of the voice's life time and the short patch above would fix it. But apart from Frank's case, simply returning 0 here looks odd to me. As I said, I am not familiar with the SignalUnitRack code base, but intuitively I would rather expect the GetLevel() implementation either a) to always return EG.getLevel() (even in delay stage) or b) to return an "identity element" in delay stage instead, which depends on whether that result is going to be used in a mathematical add operation (in which case the identity element is 0) or rather in a mathematical multiply operation (in which case the identity element is 1). Thoughts? Am I missing something? CU Christian ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot _______________________________________________ Linuxsampler-devel mailing list Linuxsampler-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxsampler-devel