I'm writing a simple MIDI player to teach myself how to use the javax.sound.midi package. So far, I have a basic program that can play, pause, stop, open a new MIDI sequence, and display file information (name and length in minutes:seconds). I'm having a hard time getting the volume control to work, though.
I have googled extensively on this. The conventional wisdom seems to be that you control MIDI volume by instantiating and opening a Sequencer, instantiating and opening a Synthesizer, binding the Synthesizer to the Sequencer via a Transmitter/Receiver pair, setting your Sequence, starting your Sequencer, and collecting the MidiChannels via a call to the Synthesizer, then doing a controlChange of controller #7 (major volume control) on each channel. It's easier to see what's going on by looking at the code; this method should turn all channels on the synthesizer down to zero:
The effect of this code is that the volume of the playing synthesizer is indeed lowered, but not silenced. This is driving me up the wall; I'm not a MIDI guru, so I don't know what I'm missing, and reading the specs isn't helping. Some caveats:
1) Apparently, MIDI controller 39 is another volume controller (the least significant 7 bits of the volume control for the channel) but when you reset controller 7, you also zero out controller 39.
2) I have tried rearranging the instructions in the above code, to see if I was doing something in the wrong order. Nothing helped.
3) I tried setting controller 7 to -1, thinking that maybe MIDI works differently on my machine than everywhere else in the universe. It raised the volume to the maximum value, an earsplitting 127.
4) It's almost as if there are two sound-generating elements here, the Synthesizer I'm using and something else which the Synthesizer can't touch. Calls to setMute() and allNotesOff() don't work, either.
5) Another way to make this work is to go into the Sequence and change the volume of every single MidiMessage individually. I won't do this, it's too slow. I want my volume to change in real time, as the user drags the volume slider up and down.
6) Another caveat: I did the obvious check. I added the following code, which checks each channel's controller #7, to the above:
...and each channel is indeed set to zero.
Any ideas? Thanks!
[ December 31, 2004: Message edited by: Greg Donahue ]