Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Repeated use of Envelopes eventually causes java.lang.NullPointerException #29

Closed
mhamilt opened this issue Apr 25, 2019 · 3 comments
Closed
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@mhamilt
Copy link

mhamilt commented Apr 25, 2019

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;
}
@kevinstadler
Copy link
Collaborator

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:

// TODO re-use player from fixed or dynamic pool
VariableRateMonoReader player = new VariableRateMonoReader();
// this would make sense to me but breaks the envelope for some reason
// input.amplitude.disconnectAll();
player.output.connect(input.amplitude);
Engine.getEngine().add(player);
player.dataQueue.queue(env);
if (!input.isPlaying()) {
input.play();
}
// disconnect player from amplitude port after finished and set amplitude to 0
TimeStamp envFinished = Engine.getEngine().synth.createTimeStamp().makeRelative(attackTime + sustainTime + releaseTime);
player.output.disconnect(0, input.amplitude, 0, envFinished);
// TODO better: trigger unit stop() so that isPlaying() is set to false as well?
input.amplitude.set(0, envFinished);
}

@kevinstadler kevinstadler self-assigned this Apr 30, 2019
@kevinstadler kevinstadler added bug Something isn't working help wanted Extra attention is needed labels Apr 30, 2019
@kevinstadler kevinstadler removed their assignment Apr 30, 2019
@kevinstadler kevinstadler changed the title java.lang.NullPointerException using processing.sound Repeated use of Envelopes eventually causes java.lang.NullPointerException Apr 30, 2019
@mhamilt
Copy link
Author

mhamilt commented Apr 30, 2019

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.

@kevinstadler
Copy link
Collaborator

That would be great, thanks, it sounds like maybe the issue lies somewhere else after all...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants