我正在尝试建立javax.sound.midi
代码生成简单声音的能力,以便我可以设置为开始处理更复杂的MIDI代码。但是下面的代码并没有产生声音。代码示例只有大约50行,来自Web示例,它应该只是开箱即用。但是,当我运行程序时,它在控制台中产生以下错误消息:
Synthesizer: com.sun.media.sound.SoftSynthesizer@682a0b20
Aug 04, 2015 5:03:20 PM java.util.prefs.WindowsPreferences <init>
WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.
MidiChannel: com.sun.media.sound.SoftChannelProxy@6e2c9341
此外,没有声音生成。操作系统是Windows 8.1,如果这很重要。
导致此错误的原因是什么?如何更改下面的小代码部分以使其播放简单的声音?
以下是完整的~50行代码抛出上述输出:
package main;
import javax.sound.midi.*;
public class MidiMain {
private static boolean DEBUG = true;
public static void main(String[] args){
/** The MIDI channel to use for playing the note. */
int nChannelNumber = 1;
int nNoteNumber = 20; // MIDI key number
int nVelocity = 20;
/* Time between note on and note off event in milliseconds. Note that on most systems, the
* best resolution you can expect are 10 ms.*/
int nDuration = 20;
nNoteNumber = Math.min(127, Math.max(0, nNoteNumber));
nVelocity = Math.min(127, Math.max(0, nVelocity));
nDuration = Math.max(0, nDuration);
/* We need a synthesizer to play the note on. Here, we simply request the default synthesizer. */
Synthesizer synth = null;
try { synth = MidiSystem.getSynthesizer();}
catch (MidiUnavailableException e){
e.printStackTrace();
System.exit(1);
}
if (DEBUG) out("Synthesizer: " + synth);
/* Of course, we have to open the synthesizer to produce any sound for us. */
try {synth.open();}
catch (MidiUnavailableException e){
e.printStackTrace();
System.exit(1);
}
/* Turn the note on on MIDI channel 1. (Index zero means MIDI channel 1) */
MidiChannel[] channels = synth.getChannels();
MidiChannel channel = channels[nChannelNumber];
if (DEBUG) out("MidiChannel: " + channel);
channel.noteOn(nNoteNumber, nVelocity);
/* Wait for the specified amount of time (the duration of the note). */
try {Thread.sleep(nDuration);}
catch (InterruptedException e){e.printStackTrace();}
/* Turn the note off. */
channel.noteOff(nNoteNumber);
/* Close the synthesizer. */
synth.close();
}
private static void out(String strMessage){ System.out.println(strMessage);}
}
答案 0 :(得分:1)
20毫秒是很短的时间。你尝试过更长的时间吗?在编程退出之前,您可能还需要更多睡眠。
当您执行synth.close()
时,您无法从声卡中获得更多声音输出。在关闭软合成延迟和仪器回声之前,您可能需要留出额外的时间。
延迟可以通过synth.getLatency()
检索,并且以微秒为单位。在关闭合成器之前,您可能希望Thread.sleep()
至少达到这段时间。
...
Thread.sleep(TimeUnit.MICROSECONDS.toMillis(synth.getLatency()));
synth.close();
但是为乐器回声添加一些时间会产生更好的声音,而不是突然切断。