1

FloatBuffer毎秒数回呼び出される 1024 のフロートを含む着信オーディオ データを取得するコールバックがあります。しかしAudioInputStream、私のシステムはそれらでのみ動作するため、が必要です。

float を 16bit PCM isgned オーディオ データに変換することは問題ではありませんが、そこから InputStream を作成することはできません。AudioInputStream コンストラクターは既知の長さのデータのみを受け入れますが、一定のストリームがあります。AudioSystem.getAudioInputStreamオーディオ データを含む PipedInputStream をフィードすると、「java.io.IOException: mark/reset not supported」がスローされます。

何か案は?


これが私の現在のコードです:

Jack jack = Jack.getInstance();
JackClient client = jack.openClient("Test", EnumSet.noneOf(JackOptions.class), EnumSet.noneOf(JackStatus.class));
JackPort in = client.registerPort("in", JackPortType.AUDIO, EnumSet.of(JackPortFlags.JackPortIsInput));

PipedInputStream pin = new PipedInputStream(1024 * 1024 * 1024);
PipedOutputStream pout = new PipedOutputStream(pin);
client.setProcessCallback(new JackProcessCallback() {
public boolean process(JackClient client, int nframes) {
    FloatBuffer inData = in.getFloatBuffer();
    byte[] buffer = new byte[inData.capacity() * 2];
    for (int i = 0; i < inData.capacity(); i++) {
        int sample = Math.round(inData.get(i) * 32767);
        buffer[i * 2] = (byte) sample;
        buffer[i * 2 + 1] = (byte) (sample >> 8);
    }
    try {
        pout.write(buffer, 0, buffer.length);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return true;
}
});
client.activate();
client.transportStart();

Thread.sleep(10000);
client.transportStop();
client.close();

AudioInputStream audio = AudioSystem.getAudioInputStream(new BufferedInputStream(pin, 1024 * 1024 * 1024));
AudioSystem.write(audio, Type.WAVE, new File("test.wav"));

JnaJack ライブラリを使用しますが、データがどこから来るかは問題ではありません。ちなみに、バイトへの変換は問題ありません。そのデータを a に直接書き込むと、SourceDataLine正しく動作します。しかし、私はデータが必要 AudioInputStreamです。

4

1 に答える 1

1

AudioSystem.getAudioInputStream は、サポートされているAudioFileFormatに準拠するストリームを想定しています。つまり、既知の型に準拠している必要があります。ドキュメントから:

ストリームは、有効なオーディオ ファイル データを指している必要があります。

また、そのドキュメントから:

このメソッドの実装では、複数のパーサーがストリームを調べて、それをサポートしているかどうかを判断する必要がある場合があります。これらのパーサーは、ストリームをマークし、ストリームをサポートしているかどうかを判断するのに十分なデータを読み取り、ストリームの読み取りポインターを元の位置にリセットできる必要があります。入力ストリームがこれらの操作をサポートしていない場合、このメソッドは失敗してIOException.

3 つの引数のコンストラクターを使用して、独自の AudioInputStream を作成できます。長さが不明な場合は、AudioSystem.NOT_SPECIFIEDとして指定できます。イライラすることに、コンストラクターのドキュメントもクラスのドキュメントもこれについて言及していませんが、他のコンストラクターのドキュメントには記載されています。

于 2018-04-10T21:38:06.203 に答える