Java midi音量控制将无法正常工作

前端之家收集整理的这篇文章主要介绍了Java midi音量控制将无法正常工作前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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

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

这里!有一个SSCCE:

  1. import java.io.*;
  2. import javax.sound.midi.*;
  3. import java.net.URL;
  4. public class MidiSSCCE {
  5. public static void main(String[] args)
  6. {
  7. // creates the midi player and sets up its sequencer and synthesizer.
  8. MidiPlayer midiP = new MidiPlayer();
  9. double volume = 1.0;
  10. // loads a midi from a url into the sequencer,but doesn't start playing it yet.
  11. midiP.load("http://www.vgmusic.com/music/computer/microsoft/windows/touhou_6_stage3_boss.mid",true);
  12. // set the midi to loop indefinitely.
  13. midiP.loop(-1);
  14. // start playing the midi.
  15. midiP.play(true);
  16. // while loop changes the volume of the midi while it is playing.
  17. while(true) {
  18. midiP.setVolume(volume);
  19. try { Thread.sleep(300); } catch(Exception e) {}
  20. volume -= 0.1;
  21. if(volume < 0) volume += 1.0;
  22. }
  23. }
  24. }
  25. /**
  26. * MidiPlayer
  27. * author: Stephen Lindberg
  28. * Last modified: Oct 14,2011
  29. *
  30. * A class that allows midi files to be loaded and played.
  31. **/
  32. class MidiPlayer {
  33. private Sequence seq;
  34. private Sequencer seqr;
  35. private Synthesizer synth;
  36. private Receiver receiver;
  37. private File midiFile;
  38. private String midiID;
  39. private boolean loaded;
  40. private boolean usingHardwareSoundbank;
  41. // CONSTRUCTORS
  42. public MidiPlayer() {
  43. loaded = false;
  44. try {
  45. // obtain the sequencer and synthesizer.
  46. seqr = MidiSystem.getSequencer();
  47. synth = MidiSystem.getSynthesizer();
  48. // print the user's midi device info
  49. System.out.println("Setting up Midi Player...");
  50. System.out.println("MidiDeviceInfo: ");
  51. for(MidiDevice.Info info : MidiSystem.getMidiDeviceInfo()) {
  52. System.out.println("\t" + info.getName() + ": " +info.getDescription());
  53. }
  54. System.out.println();
  55. // obtain the soundbank and receiver.
  56. Soundbank soundbank = synth.getDefaultSoundbank();
  57. if(soundbank == null) {
  58. receiver = MidiSystem.getReceiver();
  59. usingHardwareSoundbank = true;
  60. System.out.println("using hardware soundbank");
  61. }
  62. else {
  63. synth.loadAllInstruments(soundbank);
  64. receiver = synth.getReceiver();
  65. usingHardwareSoundbank = false;
  66. System.out.println("using default software soundbank:" + soundbank);
  67. }
  68. seqr.getTransmitter().setReceiver(receiver);
  69. }
  70. catch(Exception e) {
  71. System.out.println("MIDI error: I just don't know what went wrong! 6_9");
  72. }
  73. }
  74. // DATA METHODS
  75. /**
  76. * load(String fileName)
  77. * loads a midi file into this MidiPlayer.
  78. * Preconditions: fileName is the name of the midi file to be loaded.
  79. * Postconditions: fileName is loaded and is ready to be played.
  80. **/
  81. public void load(String fileName,boolean isOnline) {
  82. this.unload();
  83. try {
  84. URL midiURL;
  85. if(isOnline) midiURL = new URL(fileName);
  86. else midiURL = getClass().getClassLoader().getResource(fileName);
  87. seq = MidiSystem.getSequence(midiURL);
  88. seqr.open();
  89. synth.open();
  90. // load our sequence into the sequencer.
  91. seqr.setSequence(seq);
  92. loaded = true;
  93. }
  94. catch(IOException ioe) {
  95. System.out.println("MIDI error: Problem occured while reading " + midiFile.getName() + ".");
  96. }
  97. catch(InvalidMidiDataException imde) {
  98. System.out.println("MIDI error: " + midiFile.getName() + " is not a valid MIDI file or is unreadable.");
  99. }
  100. catch(Exception e) {
  101. System.out.println("MIDI error: I just don't know what went wrong! 6_9");
  102. }
  103. }
  104. /**
  105. * unload()
  106. * Unloads the current midi from the MidiPlayer and releases its resources from memory.
  107. **/
  108. public void unload() {
  109. this.stop();
  110. seqr.close();
  111. synth.close();
  112. midiFile = null;
  113. loaded = false;
  114. }
  115. // OTHER METHODS
  116. /**
  117. * play(boolean reset)
  118. * plays the currently loaded midi.
  119. * Preconditions: reset tells our midi whether or nor to begin playing from the start of the midi file's current loop start point.
  120. * Postconditions: If reset is true,then the loaded midi begins playing from its loop start point (default 0).
  121. * If reset is false,then the loaded midi resumes playing from its current position.
  122. **/
  123. public void play(boolean reset) {
  124. if(reset) seqr.setTickPosition(seqr.getLoopStartPoint());
  125. seqr.start();
  126. }
  127. /**
  128. * stop()
  129. * Pauses the current midi if it was playing.
  130. **/
  131. public void stop() {
  132. if(seqr.isOpen()) seqr.stop();
  133. }
  134. /**
  135. * isRunning()
  136. * Returns true if the current midi is playing. Returns false otherwise.
  137. **/
  138. public boolean isRunning() {
  139. return seqr.isRunning();
  140. }
  141. /**
  142. * loop(int times)
  143. * Sets the current midi to loop from start to finish a specific number of times.
  144. * Preconditions: times is the number of times we want our midi to loop.
  145. * Postconditions: The current midi is set to loop times times.
  146. * If times = -1,the current midi will be set to loop infinitely.
  147. **/
  148. public void loop(int times)
  149. {
  150. loop(times,-1);
  151. }
  152. /**
  153. * loop(int times)
  154. * Sets the current midi to loop from a specified start point to a specified end point a specific number of times.
  155. * Preconditions: times is the number of times we want our midi to loop.
  156. * start is our loop's start point in ticks.
  157. * end is our loop's end point in ticks.
  158. * Postconditions: The current midi is set to loop from tick start to tick end times times.
  159. * If times = -1,the current midi will be set to loop infinitely.
  160. **/
  161. public void loop(int times,long start,long end) {
  162. if(start < 0) start = 0;
  163. if(end > seqr.getSequence().getTickLength() || end <= 0) end = seqr.getSequence().getTickLength();
  164. if(start >= end && end != -1) start = end-1;
  165. seqr.setLoopStartPoint(start);
  166. seqr.setLoopEndPoint(end);
  167. if(times == -1) seqr.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
  168. else seqr.setLoopCount(times);
  169. }
  170. public void setVolume(double vol) {
  171. System.out.println("Midi volume change request: " + vol);
  172. try {
  173. if(usingHardwareSoundbank) {
  174. ShortMessage volumeMessage = new ShortMessage();
  175. for ( int i = 0; i < 16; i++ ) {
  176. volumeMessage.setMessage( ShortMessage.CONTROL_CHANGE,i,7,(int)(vol*127) );
  177. receiver.send( volumeMessage,-1 );
  178. }
  179. }
  180. else {
  181. MidiChannel[] channels = synth.getChannels();
  182. for( int c = 0; c < channels.length; c++ ) {
  183. if(channels[c] != null) channels[c].controlChange( 7,(int)( vol*127) );
  184. }
  185. }
  186. }
  187. catch ( Exception e ) {
  188. e.printStackTrace();
  189. }
  190. }
  191. }

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

http://www.java2s.com/Code/Java/Development-Class/SettingtheVolumeofPlayingMidiAudio.htm

How to controll the MIDI channel’s volume

https://forums.oracle.com/forums/thread.jspa?messageID=5389030

MIDI Song with CC

http://www.codezealot.org/archives/27

http://www.exampledepot.com/egs/javax.sound.midi/Volume.html

最佳答案
我正在努力解决控制声音方面的这些问题,并且我找到了一个可以改变音量的代码.不幸的是,我无法理解它,但是你的代码中的某些东西与我见过的东西不同.也许它可以帮助你.
尝试更改线路

  1. seqr = MidiSystem.getSequencer();

对于

  1. seqr = MidiSystem.getSequencer(false);

也许它会帮助你,我相信使用“假”序列器将连接到接收器,而不是合成器,然后当你将消息发送到接收器设置音量时它将起作用.

猜你在找的Java相关文章