0

ファイルを再生するためにjavax.sound.sampledとを使用しています。オーディオ入力ストリームを分析して、曲の開始時と終了時を判断しようとしています (MP3 の最初と最後のオーディオ レベルに基づいて)。4 分の曲の実際の音楽は 3 分 55 秒しかなく、残りは無音である可能性があるため、これを判断しています。JLayerMP3

ストリーム内のゼロ以外の最初と最後のバイトを見つけることで、この情報を特定できると思いました。

問題:問題は、バッファ サイズを調整すると、ゼロ以外の最初のバイトの位置が変わることです。これはなぜですか?バッファサイズに関係なく一定のままであるべきではありませんか?

たとえば、バッファ サイズが 16 の場合、startFrame は 17 番目のバイトに対応します。バッファ サイズが 64 の場合、startFrame は 65 番目のバイトに対応します。

コードは次のとおりです。

        byte[] buffer;
        int pos = 0;
        short silenceThreshold = 1;

        startFrame = 0;
        endFrame = -1;

        boolean startFrameSet = false;

        buffer = new byte[16];
        byte prevVal = 0;
        for (int n = 0; n != -1; n = audioInputStream.read(buffer, 0,
                buffer.length)) {

            for (int i = 0; i < buffer.length; i++) {
                if (buffer[i] >= silenceThreshold || buffer[i] <= -silenceThreshold) {
                    // Is not silent
                    if (!startFrameSet) {
                        startFrame = (pos * buffer.length) + i;
                        startFrameSet = true;
                    }
                } else {
                    // Silence
                    // If the previous value is > 0 or < 0, set endFrame
                    if (prevVal >= silenceThreshold || prevVal <= silenceThreshold) {
                        endFrame = (pos * buffer.length) + i;
                    }
                }
                prevVal = buffer[i];
            }

            pos++;
        }

        //If last byte is not within silence threshold (song doesn't end in silence).
        if (prevVal >= silenceThreshold || prevVal <= silenceThreshold) {
            // last frame is not silent
            endFrame = -1;
        }

オーディオ入力ストリームとオーディオが一般的にどのように機能するかを誤解していると思います。

4

1 に答える 1

2

外側のforループは、ループの最初のパスでオーディオ入力ストリームから読み取られません

 for (int n = 0; n != -1; n = audioInputStream.read(buffer, 0,
            buffer.length)) {

次と同等です。

int n = 0;
while (n != -1) {
    // Inner loop

    n = audioInputStream.read(buffer, 0, buffer.length);
}

したがって、最初のループでは、バッファは からのゼロで初期化された配列ですnew byte[16]

読み取りによってバッファ全体が満たされると想定しないでください。読み取りによって返された値を使用してください。

于 2013-09-07T09:18:54.670 に答える