次の呼び出しで、jLayer を使用して MP3 データをデコードしています。
SampleBuffer output = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream);
デコードされたデータを返すこの呼び出しは、short[] の配列を返します。
output.getBuffer();
そのメソッドで AudioTrack write() を呼び出すと、ファイルをループするときに正常に再生されます。
at.write(output.getBuffer(), 0, output.getBuffer().length);
ただし、この回答のいずれかの方法を使用して short[] 配列を byte[] 配列に変換すると: https://stackoverflow.com/a/12347176/1176436音が歪んでぎくしゃくします:
at.write(output.getBuffer(), 0, output.getBuffer().length);
になります:
byte[] array = ShortToByte_Twiddle_Method(output.getBuffer());
at.write(array, 0, array.length);
私は何か間違ったことをしていますか?それを修正するにはどうすればよいですか? 残念ながら、私が使用している別のサードパーティ ライブラリのバイト配列に pcm データが必要です。それが重要な場合、ファイルは22kHzであり、これがどのようにインスタンス化されているかです:
at = new AudioTrack(AudioManager.STREAM_MUSIC, 22050, AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT, 10000 /* 10 second buffer */,
AudioTrack.MODE_STREAM);
よろしくお願いします。
編集: これは、AudioTrack 変数をインスタンス化する方法です。したがって、44kHz ファイルの場合、送信される値は 44100 ですが、22kHz ファイルの場合、値は 22050 です。
at = new AudioTrack(AudioManager.STREAM_MUSIC, decoder.getOutputFrequency(),
decoder.getOutputChannels() > 1 ? AudioFormat.CHANNEL_OUT_STEREO : AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, 10000 /* 10 second buffer */,
AudioTrack.MODE_STREAM);
これはデコード方法です:
public byte[] decode(InputStream inputStream, int startMs, int maxMs) throws IOException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024);
float totalMs = 0;
boolean seeking = true;
try {
Bitstream bitstream = new Bitstream(inputStream);
Decoder decoder = new Decoder();
boolean done = false;
while (!done) {
Header frameHeader = bitstream.readFrame();
if (frameHeader == null) {
done = true;
} else {
totalMs += frameHeader.ms_per_frame();
if (totalMs >= startMs) {
seeking = false;
}
if (!seeking) {
// logger.debug("Handling header: " + frameHeader.layer_string());
SampleBuffer output = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream);
short[] pcm = output.getBuffer();
for (short s : pcm) {
outStream.write(s & 0xff);
outStream.write((s >> 8) & 0xff);
}
}
if (totalMs >= (startMs + maxMs)) {
done = true;
}
}
bitstream.closeFrame();
}
return outStream.toByteArray();
} catch (BitstreamException e) {
throw new IOException("Bitstream error: " + e);
} catch (DecoderException e) {
throw new IOException("Decoder error: " + e);
}
}
これがどのように聞こえるかです (数秒待ちます): https://vimeo.com/60951237 (これが実際のファイルです: http://www.tonycuffe.com/mp3/tail%20toddle.mp3 )
編集:賞金を分割したかったのですが、代わりに賞金をビルに与え、受け入れられた回答をニールに与えました。どちらも大変参考になりました。疑問に思っている人のために説明すると、最終的に Sonic のネイティブ コードを書き直したので、プロセスを進めることができました。