Note that there are some explanatory texts on larger screens.

plurals
  1. POJava midi volume control won't work
    primarykey
    data
    text
    <p>I've been trying to get midi volume control to work in a MidiPlayer class for a very long time now. I've searched for examples for accomplishing this here on stackoverflow and all over the Internet, but nothing I try ever seems to work. The volume stays the same! It doesn't change like I want it to.</p> <p>I'm running Java 1.6.0_32 on Windows 7 professional. </p> <p>Here! Have an SSCCE:</p> <pre><code> import java.io.*; import javax.sound.midi.*; import java.net.URL; public class MidiSSCCE { public static void main(String[] args) { // creates the midi player and sets up its sequencer and synthesizer. MidiPlayer midiP = new MidiPlayer(); double volume = 1.0; // loads a midi from a url into the sequencer, but doesn't start playing it yet. midiP.load("http://www.vgmusic.com/music/computer/microsoft/windows/touhou_6_stage3_boss.mid",true); // set the midi to loop indefinitely. midiP.loop(-1); // start playing the midi. midiP.play(true); // while loop changes the volume of the midi while it is playing. while(true) { midiP.setVolume(volume); try { Thread.sleep(300); } catch(Exception e) {} volume -= 0.1; if(volume &lt; 0) volume += 1.0; } } } /** * MidiPlayer * author: Stephen Lindberg * Last modified: Oct 14, 2011 * * A class that allows midi files to be loaded and played. **/ class MidiPlayer { private Sequence seq; private Sequencer seqr; private Synthesizer synth; private Receiver receiver; private File midiFile; private String midiID; private boolean loaded; private boolean usingHardwareSoundbank; // CONSTRUCTORS public MidiPlayer() { loaded = false; try { // obtain the sequencer and synthesizer. seqr = MidiSystem.getSequencer(); synth = MidiSystem.getSynthesizer(); // print the user's midi device info System.out.println("Setting up Midi Player..."); System.out.println("MidiDeviceInfo: "); for(MidiDevice.Info info : MidiSystem.getMidiDeviceInfo()) { System.out.println("\t" + info.getName() + ": " +info.getDescription()); } System.out.println(); // obtain the soundbank and receiver. Soundbank soundbank = synth.getDefaultSoundbank(); if(soundbank == null) { receiver = MidiSystem.getReceiver(); usingHardwareSoundbank = true; System.out.println("using hardware soundbank"); } else { synth.loadAllInstruments(soundbank); receiver = synth.getReceiver(); usingHardwareSoundbank = false; System.out.println("using default software soundbank:" + soundbank); } seqr.getTransmitter().setReceiver(receiver); } catch(Exception e) { System.out.println("MIDI error: I just don't know what went wrong! 6_9"); } } // DATA METHODS /** * load(String fileName) * loads a midi file into this MidiPlayer. * Preconditions: fileName is the name of the midi file to be loaded. * Postconditions: fileName is loaded and is ready to be played. **/ public void load(String fileName, boolean isOnline) { this.unload(); try { URL midiURL; if(isOnline) midiURL = new URL(fileName); else midiURL = getClass().getClassLoader().getResource(fileName); seq = MidiSystem.getSequence(midiURL); seqr.open(); synth.open(); // load our sequence into the sequencer. seqr.setSequence(seq); loaded = true; } catch(IOException ioe) { System.out.println("MIDI error: Problem occured while reading " + midiFile.getName() + "."); } catch(InvalidMidiDataException imde) { System.out.println("MIDI error: " + midiFile.getName() + " is not a valid MIDI file or is unreadable."); } catch(Exception e) { System.out.println("MIDI error: I just don't know what went wrong! 6_9"); } } /** * unload() * Unloads the current midi from the MidiPlayer and releases its resources from memory. **/ public void unload() { this.stop(); seqr.close(); synth.close(); midiFile = null; loaded = false; } // OTHER METHODS /** * play(boolean reset) * plays the currently loaded midi. * Preconditions: reset tells our midi whether or nor to begin playing from the start of the midi file's current loop start point. * Postconditions: If reset is true, then the loaded midi begins playing from its loop start point (default 0). * If reset is false, then the loaded midi resumes playing from its current position. **/ public void play(boolean reset) { if(reset) seqr.setTickPosition(seqr.getLoopStartPoint()); seqr.start(); } /** * stop() * Pauses the current midi if it was playing. **/ public void stop() { if(seqr.isOpen()) seqr.stop(); } /** * isRunning() * Returns true if the current midi is playing. Returns false otherwise. **/ public boolean isRunning() { return seqr.isRunning(); } /** * loop(int times) * Sets the current midi to loop from start to finish a specific number of times. * Preconditions: times is the number of times we want our midi to loop. * Postconditions: The current midi is set to loop times times. * If times = -1, the current midi will be set to loop infinitely. **/ public void loop(int times) { loop(times,0,-1); } /** * loop(int times) * Sets the current midi to loop from a specified start point to a specified end point a specific number of times. * Preconditions: times is the number of times we want our midi to loop. * start is our loop's start point in ticks. * end is our loop's end point in ticks. * Postconditions: The current midi is set to loop from tick start to tick end times times. * If times = -1, the current midi will be set to loop infinitely. **/ public void loop(int times, long start, long end) { if(start &lt; 0) start = 0; if(end &gt; seqr.getSequence().getTickLength() || end &lt;= 0) end = seqr.getSequence().getTickLength(); if(start &gt;= end &amp;&amp; end != -1) start = end-1; seqr.setLoopStartPoint(start); seqr.setLoopEndPoint(end); if(times == -1) seqr.setLoopCount(Sequencer.LOOP_CONTINUOUSLY); else seqr.setLoopCount(times); } public void setVolume(double vol) { System.out.println("Midi volume change request: " + vol); try { if(usingHardwareSoundbank) { ShortMessage volumeMessage = new ShortMessage(); for ( int i = 0; i &lt; 16; i++ ) { volumeMessage.setMessage( ShortMessage.CONTROL_CHANGE, i, 7, (int)(vol*127) ); receiver.send( volumeMessage, -1 ); } } else { MidiChannel[] channels = synth.getChannels(); for( int c = 0; c &lt; channels.length; c++ ) { if(channels[c] != null) channels[c].controlChange( 7, (int)( vol*127) ); } } } catch ( Exception e ) { e.printStackTrace(); } } } </code></pre> <p>I've tried examples at the following sources with no success: </p> <p><a href="http://www.java2s.com/Code/Java/Development-Class/SettingtheVolumeofPlayingMidiAudio.htm" rel="nofollow noreferrer">http://www.java2s.com/Code/Java/Development-Class/SettingtheVolumeofPlayingMidiAudio.htm</a></p> <p><a href="https://stackoverflow.com/questions/8008286/how-to-controll-the-midi-channels-volume">How to controll the MIDI channel&#39;s volume</a></p> <p><a href="https://forums.oracle.com/forums/thread.jspa?messageID=5389030" rel="nofollow noreferrer">https://forums.oracle.com/forums/thread.jspa?messageID=5389030</a></p> <p><a href="https://stackoverflow.com/questions/9108996/midi-song-with-cc">MIDI Song with CC</a></p> <p><a href="http://www.codezealot.org/archives/27" rel="nofollow noreferrer">http://www.codezealot.org/archives/27</a></p> <p><a href="http://www.exampledepot.com/egs/javax.sound.midi/Volume.html" rel="nofollow noreferrer">http://www.exampledepot.com/egs/javax.sound.midi/Volume.html</a></p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload