0

Currently I'm learning Processing using the Sparkfun Guide to Processing. Great book so far! But now I'm stuck with a tutorial in chapter 11: recording audio using the Minim library.

Using the code below, as explained in the book, I get a Null Pointer Exception when trying to record a sample by pressing left or right. I would love to know what's wrong here. I'm having trouble working it out. I'm sure it's something totally simple, but I just can't see it. There is some sample code to download for this chapter, but this particular sketch is not included.

Thanks for your help!

Here's the null pointer code (edited to include some lines that I did not include prior as they didn't seem to be causing the sketch to crash):

==== JavaSound Minim Error ====
==== Error obtaining new output stream:/Users/*edited full path*/soundboard/data/right.wav (No such file or directory)

==== JavaSound Minim Error ====
==== Error obtaining new output stream: /Users/*edited full path*/soundboard/data/left.wav (No such file or directory)

java.lang.NullPointerException

at ddf.minim.javasound.JSStreamingSampleRecorder.samples(JSStreamingSampleRecorder.java:177)
at ddf.minim.SignalSplitter.samples(SignalSplitter.java:112)
at ddf.minim.javasound.JSAudioOutput.run(JSAudioOutput.java:84)

And here's the code I'm using for the sketch:

import ddf.minim.*;

Minim minim;
AudioInput mic;
AudioRecorder left;
AudioRecorder right;
AudioSample Pright;
AudioSample Pleft;

void setup(){
  size(800,900);
  minim = new Minim(this);
  mic = minim.getLineIn();
  right = minim.createRecorder(mic,"data/right.wav");
  left = minim.createRecorder(mic, "data/left.wav");
};

void draw(){

};

void keyPressed(){

  //begin left record
  if(keyCode == LEFT){
    if(left.isRecording()){
      left.endRecord();
      left.save();
    }
    else{
      left.beginRecord();
    };
  };

  //begin right record
  if(keyCode == RIGHT){
    if(right.isRecording()){
      right.endRecord();
      right.save();
    }
    else{
      right.beginRecord();
    };
  };

  //play the right sample
  if(keyCode == UP){
    Pright = minim.loadSample("right.wav");
    Pright.trigger();
  };

  //play the left sample
  if(keyCode == DOWN){
    Pleft = minim.loadSample("left.wav");
    Pleft.trigger();
  };

};
Rob Peart
  • 1
  • 1
  • Can you post your full stack trace? We need to know which line of your sketch throws the NPE. It looks like you might have cut that part off when you copied the stack trace. – Kevin Workman Apr 01 '16 at 14:44
  • Let me take a wild guess. Pright = minim.loadSample("right.wav"); this line can't find the sound file because you didn't give the full path? – Max Apr 01 '16 at 14:54
  • @Max This is Processing. It has a sketch directory, and you don't normally give it full paths. – Kevin Workman Apr 01 '16 at 15:01
  • @KevinWorkman Thanks for the response. I have edited the question to include all the information in the console window. The ===JavaSound Minim Error=== parts didn't seem to be causing the crash, so didn't include. BTW your responses to other questions have been very helpful to me while learning Processing, and for that I'm very thankful. Cheers! – Rob Peart Apr 02 '16 at 02:25
  • @Dazak Thanks very much for that very helpful link. I'm going to spend some time with it so I can fully understand, but it looks like it may very well solve my problem. I'll come back once I have it figured out. Cheers! – Rob Peart Apr 02 '16 at 02:27

1 Answers1

0

OK so after a bit of fiddling about, I managed to work this one out. Thanks for the prompts in the comments on my question, they spurred me on to investigate further.

In the book, it asks you to start this as a new sketch. However, when you start a new sketch, Processing does not automatically create a 'data' folder. A data folder seems only to be created when you add files to the sketch through Sketch > Add file.

void setup(){
  size(800,900);
  minim = new Minim(this);
  mic = minim.getLineIn();
  right = minim.createRecorder(mic,"data/right.wav");
  left = minim.createRecorder(mic, "data/left.wav");
};

In the above code, the 'right' and 'left' objects had nowhere to save the .wav files to. I manually added a data folder, and hey-presto, it works.

Another error came up once I had that working:

  //play the right sample
  if(keyCode == UP){
    Pright = minim.loadSample("right.wav");
    Pright.trigger();
  };

  //play the left sample
  if(keyCode == DOWN){
    Pleft = minim.loadSample("left.wav");
    Pleft.trigger();
  };

If you press UP or DOWN before you have recorded your sample, then the program crashes because there is no file to play. The addition of a boolean enabled me to write a more specific 'if' statement, causing the program to only attempt to play the file if one had been recorded.

See the full code below. I hope others that are learning Processing through this particular book find this helpful. Many thanks for all your help.

import ddf.minim.*;

Minim minim;
AudioInput mic;
AudioRecorder left;
AudioRecorder right;
AudioSample Pright;
AudioSample Pleft;
boolean leftRecorded;
boolean rightRecorded;

void setup(){
  size(800,900);
  minim = new Minim(this);
  mic = minim.getLineIn();
  right = minim.createRecorder(mic,"data/right.wav");
  left = minim.createRecorder(mic, "data/left.wav");
};

void draw(){
;
};

void keyPressed(){

  //begin left record
  if(keyCode == LEFT){
    if(left.isRecording()){
      left.endRecord();
      left.save();
      leftRecorded = true;
    }
    else{
      left.beginRecord();
    };
  };

  //begin right record
  if(keyCode == RIGHT){
    if(right.isRecording()){
      right.endRecord();
      right.save();
      rightRecorded = true;
    }
    else{
      right.beginRecord();
    };
  };

  //play the right sample
  if(keyCode == UP && rightRecorded){
    Pright = minim.loadSample("right.wav");
    Pright.trigger();
  };

  //play the left sample
  if(keyCode == DOWN && leftRecorded){
    Pleft = minim.loadSample("left.wav");
    Pleft.trigger();
  };

};
Rob Peart
  • 1
  • 1