java - java midi 测试代码中不播放简单的声音

标签 java audio midi javasound javax.sound.midi

我正在尝试建立 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);}    
}

最佳答案

20 毫秒是很短的时间。您是否尝试过更长的持续时间?在程序退出之前,您可能还需要在最后多睡一会儿。

当您执行synth.close()时,您将不会再从声卡获得任何声音输出。在关闭软合成器延迟和乐器回声之前,您可能需要留出额外的时间。

延迟可以通过 synth.getLatency() 检索,以微秒为单位。在关闭合成器之前,您可能需要至少 Thread.sleep() 这段时间。

...
Thread.sleep(TimeUnit.MICROSECONDS.toMillis(synth.getLatency()));
synth.close();

但是增加一些乐器回声的时间会产生更好的声音,而不是突然中断。

关于java - java midi 测试代码中不播放简单的声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31821425/

相关文章:

java - 如何增加Android音频流的数量?

python - 如何通过 Python 套接字播放 mp3 文件?

html - Google文字语音转换始终显示404(未找到)

java - 在 Java 中从 Receiver 获取 midi 消息

c++ - 阅读更多 midi 数据

java - 如何构建并返回包含数组中元素的字符串?

Java:用哈希值替换字符串的所有匹配子字符串

Java Obscured混淆

midi - 使用 DirectMusic 播放单个音符

Java JNI “symbol lookup error” 当依赖共享库包含符号