Repeated use of Envelopes eventually causes java.lang.NullPointerException
Hello,
I'm getting the following console error after intermittent intervals when using the processing.sound library. The sound cuts out, but the sketch continues to run.
Error
java.lang.NullPointerException
at com.jsyn.ports.InputMixingBlockPart.getValues(Unknown Source)
at com.jsyn.ports.UnitBlockPort.getValues(Unknown Source)
at com.jsyn.unitgen.SineOscillator.generate(Unknown Source)
at com.jsyn.unitgen.UnitGenerator.pullData(Unknown Source)
at com.jsyn.ports.PortBlockPart.pullData(Unknown Source)
at com.jsyn.ports.UnitInputPort.pullData(Unknown Source)
at com.jsyn.unitgen.UnitGenerator.pullData(Unknown Source)
at com.jsyn.ports.PortBlockPart.pullData(Unknown Source)
at com.jsyn.ports.UnitInputPort.pullData(Unknown Source)
at com.jsyn.unitgen.UnitGenerator.pullData(Unknown Source)
at com.jsyn.ports.PortBlockPart.pullData(Unknown Source)
at com.jsyn.ports.UnitInputPort.pullData(Unknown Source)
at com.jsyn.unitgen.UnitGenerator.pullData(Unknown Source)
at com.jsyn.ports.PortBlockPart.pullData(Unknown Source)
at com.jsyn.ports.UnitInputPort.pullData(Unknown Source)
at com.jsyn.unitgen.UnitGenerator.pullData(Unknown Source)
at com.jsyn.engine.SynthesisEngine.synthesizeBuffer(Unknown Source)
at com.jsyn.engine.SynthesisEngine.generateNextBuffer(Unknown Source)
at com.jsyn.engine.SynthesisEngine$EngineThread.run(Unknown Source)
I have not had a chance to test for long periods on another OS, but will do as soon as possible.
Setup
| OS | macOS 10.13.6 |
|---|---|
| Processing | 3.5.3 |
| SoundLibrary | 2.1.0 |
Code
//------------------------------------------------------------------------------------
import processing.sound.*;
//------------------------------------------------------------------------------------
int[] note = {96, 93, 91, 89, 86, 84, 81, 79, 77, 74, 72, 69, 67, 65, 62, 60};
Env[] env;
SinOsc[] sine;
float attackTime = 0.004;
float sustainTime = 0.004;
float sustainLevel = 0.5;
float releaseTime = 0.7;
int beat = 0;
int framesPerBeat = 7;
//------------------------------------------------------------------------------------
void setup()
{
background(0);
sine = new SinOsc[note.length];
env = new Env[note.length];
for (int i = 0; i < note.length; ++i)
{
sine[i] = new SinOsc(this);
sine[i].freq(midi2Hz(note[i]));
sine[i].amp(0.303);
env[i] = new Env(this);
}
}
//------------------------------------------------------------------------------------
void draw()
{
if (frameCount % framesPerBeat == 0)
{
env[beat].play(sine[beat], attackTime, sustainTime, sustainLevel, releaseTime);
beat++;
beat %= note.length;
}
}
//------------------------------------------------------------------------------------
float midi2Hz(int midiNoteNumber)
{
return pow(2, float(midiNoteNumber - 69)/12.0) * 440.0f;
}
Thank you for the detailed report!
I'm not sure why that particular exception is thrown but I think this might have to do with the fact that envelope re-use is not properly implemented yet under the hood, which means that repeated invocation of envelopes can actually become a burden on the program memory. Approximately how long (or approximately how many enveloper triggers) into running does the sketch stop playing?
Just looking back at the code the fix would have to go in here, I wonder if simply making sure that the player object is removed from the synthesis engine after it's finished might already do the trick: https://github.com/processing/processing-sound/blob/9c250cb7f4f279837c1b5cbaba118a0d866379bd/src/processing/sound/Env.java#L35-L54
Approximately how long (or approximately how many enveloper triggers) into running does the sketch stop playing?
Sadly, the exception is thrown at fairly random intervals. I have had it occur anywhere between a couple of minutes to just under an hour, but never longer.
I'll see if I can knock up a soak test script that will report back the number of envelope trigger and the running time.
That would be great, thanks, it sounds like maybe the issue lies somewhere else after all...