javaaudiomemory-managementjfugue

Reimplementing the "ToneMatrix" audio toy


There is a really cool audio "toy" called ToneMatrix. I would like to reimplement it as a Java applet. I've tried using JFugue's player.play with individual notes for sound and Thread.sleep for timing, but the results are horrible.

JFugue stops responding after the 17th (yes, really, I counted) invocation of player.play and Thread.sleep is too irregular to deliver a good rhythm.

What would you recommend instead? Basically, I'm looking for a simple way to generate single notes of sound on the fly. So a fraction of a second before the sound is due to play, I need to be able to look at the data and tell the audio library what notes to play. (Multiple notes in harmony are likely.)


Solution

  • My guess is you're forgetting to turn the notes off in JFugue, or there's a bug which is forgetting to stop playing the notes once started.

    Using MIDI is a pretty easy way to do what you're talking about. Here's a bit of a hodgepodge of useful methods in the midi package that will get you started:

    Synthesizer synth = MidiSystem.getSynthesizer();
    synth.open();
    MidiChannel midiChannel = synth.getChannels()[0];
    midiChannel.allNotesOff();
    currentInstrument = synth.getAvailableInstruments()[index];
    System.out.println("Switching instrument to #" + index + ": " + currentInstrument.getName());
    synth.loadInstrument(currentInstrument);
    midiChannel.programChange(currentInstrument.getPatch().getBank(), currentInstrument.getPatch().getProgram());
    midiChannel.noteOn(noteNumber, velocity);
    midiChannel.noteOff(noteNumber);