java midi没有声音_Java midi音量控制将无法正常工作

我一直试图让Midi音量控制在MidiPlayer课程中工作很长一段时间.我已经在stackoverflow和整个互联网上搜索了完成此操作的示例,但我尝试的任何东西似乎都没有用.音量保持不变!它没有像我想要的那样改变.

我在Windows 7专业版上运行Java 1.6.0_32.

这里!有一个SSCCE:

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 < 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 < 0) start = 0;

if(end > seqr.getSequence().getTickLength() || end <= 0) end = seqr.getSequence().getTickLength();

if(start >= end && 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 < 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 < channels.length; c++ ) {

if(channels[c] != null) channels[c].controlChange( 7, (int)( vol*127) );

}

}

}

catch ( Exception e ) {

e.printStackTrace();

}

}

}

我在以下来源尝试了一些例子但没有成功:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值