Java midi音量控制赢得';行不通
很长一段时间以来,我一直试图让midi音量控制在midi播放器类中工作。我在stackoverflow和整个互联网上搜索了实现这一点的例子,但我尝试过的任何东西似乎都不起作用。音量保持不变!它不会像我希望的那样改变 我正在Windows7 professional上运行Java1.6.032 这里!拥有SSCCE:Java midi音量控制赢得';行不通,java,midi,javasound,Java,Midi,Javasound,很长一段时间以来,我一直试图让midi音量控制在midi播放器类中工作。我在stackoverflow和整个互联网上搜索了实现这一点的例子,但我尝试过的任何东西似乎都不起作用。音量保持不变!它不会像我希望的那样改变 我正在Windows7 professional上运行Java1.6.032 这里!拥有SSCCE: import java.io.*; import javax.sound.midi.*; import java.net.URL; public class Mid
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();
}
}
}
import java.io.*;
导入javax.sound.midi.*;
导入java.net.URL;
公共类MIDISSCE{
公共静态void main(字符串[]args)
{
//创建midi播放器并设置其音序器和合成器。
MidiPlayer midiP=新的MidiPlayer();
双体积=1.0;
//将midi从url加载到sequencer中,但尚未开始播放。
midiP.load(“http://www.vgmusic.com/music/computer/microsoft/windows/touhou_6_stage3_boss.mid“,对);
//将midi设置为无限循环。
midiP.loop(-1);
//开始演奏midi。
midiP播放(正确);
//while loop可在midi播放时更改其音量。
while(true){
midiP.设置音量(音量);
试试{Thread.sleep(300);}catch(异常e){}
体积-=0.1;
如果(体积<0)体积+=1.0;
}
}
}
/**
*MIDI播放器
*作者:斯蒂芬·林德伯格
*最后修改日期:2011年10月14日
*
*允许加载和播放midi文件的类。
**/
类MIDI播放器{
私有序列seq;
专用序列器;
专用合成器合成器;
专用接收机;
私有文件;
私有字符串MIDID;
私有布尔加载;
私有布尔使用硬件undbank;
//建设者
公共MIDI播放器(){
加载=错误;
试一试{
//获取音序器和合成器。
seqr=MidiSystem.getSequencer();
synth=MidiSystem.getSynthesizer();
//打印用户的midi设备信息
System.out.println(“设置Midi播放器…”);
System.out.println(“middeviceinfo:”);
对于(MidiDevice.Info:MidiSystem.getMidiDeviceInfo()){
System.out.println(“\t”+info.getName()+”:“+info.getDescription());
}
System.out.println();
//获取声音库和接收器。
Soundbank Soundbank=synth.getDefaultSoundbank();
if(soundbank==null){
receiver=MidiSystem.getReceiver();
使用硬件Undbank=true;
System.out.println(“使用硬件声音库”);
}
否则{
合成负载仪器(声库);
receiver=synth.getReceiver();
使用硬件Undbank=false;
System.out.println(“使用默认软件soundbank:+soundbank”);
}
seqr.getTransmitter().setReceiver(接收器);
}
捕获(例外e){
System.out.println(“MIDI错误:我只是不知道出了什么问题!6_9”);
}
}
//数据方法
/**
*加载(字符串文件名)
*将midi文件加载到此midi播放器。
*前提条件:fileName是要加载的midi文件的名称。
*后置条件:文件名已加载并准备好播放。
**/
公共无效加载(字符串文件名,布尔isOnline){
这个。unload();
试一试{
URL-midiURL;
if(isOnline)midiURL=新URL(文件名);
else midiURL=getClass().getClassLoader().getResource(文件名);
seq=MidiSystem.getSequence(midiURL);
seqr.open();
synth.open();
//将我们的序列加载到序列器中。
顺序设置顺序(顺序);
加载=真;
}
捕获(ioe异常ioe){
System.out.println(“MIDI错误:读取“+midiFile.getName()+”时出现问题”);
}
捕获(InvalidMidiDataException imde){
System.out.println(“MIDI错误:“+MIDI文件.getName()+”不是有效的MIDI文件或不可读。”);
}
捕获(例外e){
System.out.println(“MIDI错误:我只是不知道出了什么问题!6_9”);
}
}
/**
*卸载()
*从midi播放器中卸载当前midi,并从内存中释放其资源。
**/
公众假期{
这个。停止();
seqr.close();
synth.close();
midiFile=null;
加载=错误;
}
//其他方法
/**
*播放(布尔重置)
*播放当前加载的midi。
*前提条件:重置告诉我们的midi是否从midi文件当前循环起点开始播放。
*后置条件:如果重置为真,则加载的midi从其循环起点开始播放(默认为0)。
*如果重置为false,则加载的midi将从其当前位置恢复播放。
**/
公共无效播放(布尔重置){
如果(重置)seqr.setTickPosition(seqr.getLoopStartPoint());
seqr.start();
}
/**
*停止()
*暂停正在播放的当前midi。
**/
公共停车场(){
如果(seqr.isOpen())seqr.stop();
}
/**
*isRunning()
*如果当前midi正在播放,则返回true。否则返回false。
**/
公共布尔值正在运行(){
返回seqr.isRunning();
}
/**
*循环(整数倍)
*将当前midi设置为从开始到结束循环特定次数。
*前提条件:times是我们希望midi循环的次数。
*后置条件:当前midi设置为循环次数。
*如果时间=-1,则当前midi将设置为无限循环。
**/
公共无效循环(整数倍)
{
循环(次数,0,-1);
}
/**
*
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) );
}
}
// Very important!
seqr.setSequence(seq);
}
catch ( Exception e ) {
e.printStackTrace();
}
}
seqr = MidiSystem.getSequencer();
seqr = MidiSystem.getSequencer(false);