• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Tim Cooke
  • Devaka Cooray
Sheriffs:
  • Liutauras Vilda
  • paul wheaton
  • Rob Spoor
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Piet Souris
  • Mikalai Zaikin
Bartenders:
  • Carey Brown
  • Roland Mueller

MIDI volume control difficulties

 
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi there,
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!
-Greg
[ December 31, 2004: Message edited by: Greg Donahue ]
 
Greg Donahue
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Okay, I figured it out.

I looked at the MidiDevices obtained from calling MidiSystem.getMidiDeviceInfo(), and observed that they were all closed. So I knew right away that something was fishy. I guess that calling MidiSystem.getSequencer() and MidiSystem.getSynthesizer() doesn't give you the default objects for those MIDI devices.

To correct the problem, I had to set the sequencer and synthesizer to the default sequencer and synthesizer in the MidiDevice.Info list, rather than using MidiSystem.getSequencer() and MidiSystem.getSynthesizer(). It looks like:



...and that did the trick. Now my volume works perfectly.
-Greg
 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
I tried as you have explained.But I am not able to increase/Decrease the MIDI volume.

Please let me know where I am going wrong.

 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I had the same problems.

Upon investigation I concluded that for me (on Mac OS X, java 1.6.0_33-b03-424-10M3720) MidiSystem.getSynthesizer did *NOT* return the same synthesizer that the sequencer was by default connected to.

The sequencer is already connected to *A* synthesizer. If you do a getSynthesizer and connect it up then your sequencer will drive *TWO* synthesizers. You can test this by calling sequencer.getTransmitters and looping through the list (of transmitters open and in use).

I suggest that this is why setting volume to zero reduces the volume but doesn't shut it off completely!

Of course different java environments might behave differently.

Possible solutiona:

1 (the one I used)

Don't use the synthesizer object because you can't get to it (but see solution 2). Don't use Channels. To control volume use:

receiver = seq.getTransmitters ().iterator ().next ().getReceiver ();
receiver.send (volumeMessage, -1);

This is of course suitable for both software and hardware synth so should simplify the code.

2 (not tested)

Use getSynthesizer and connect transmitter and receiver as lots of sample code tells you, BUT
do something like: seq.getTransmitters ().iterator ().next ().close ()
to shut down the default synthesizer started for you.

Then with any luck you can get the channels and the sample code might work.
 
A sonic boom would certainly ruin a giant souffle. But this tiny ad would protect it:
We need your help - Coderanch server fundraiser
https://coderanch.com/wiki/782867/Coderanch-server-fundraiser
reply
    Bookmark Topic Watch Topic
  • New Topic