0

単純なサウンドを生成するコードの機能を確立しようとして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

また、音が出ません。 それが重要な場合、OSは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);}    
}
4

1 に答える 1

1

20 ミリ秒は短い時間です。もっと長い期間試しましたか?出口をプログラムする前に、最後にもう少しスリープする必要があるかもしれません。

を実行するsynth.close()と、サウンド カードからサウンド出力が得られなくなります。ソフトシンセのレイテンシーと楽器のエコーのために、閉じる前に余分な時間が必要になる場合があります。

synth.getLatency()待ち時間はマイクロ秒単位で取得できます。Thread.sleep()シンセを閉じる前に、少なくともこの時間は必要になる場合があります 。

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

ただし、楽器のエコーに時間を追加すると、突然のカットオフではなく、より良いサウンドが得られます。

于 2015-08-05T06:16:07.247 に答える