我正在写一些代码,打算采取一个波文件,并写出来和音频跟踪在模式流。这是一个最低可行的测试,使音频跟踪流模式工作。
但是,一旦我向AudioTrack写入一些音频缓冲区,然后调用play(),getPlaybackHeadPosition()方法将持续返回0。
编辑:如果我忽略可用的帧检查,只是不断地向AudioTrack写入缓冲区,write方法返回0(在第一个缓冲区写入之后),表示它只是没有再写入任何音频。看来这首音轨不想开始播放了。
我的代码正确启动了音频曲目。play方法没有抛出任何异常,所以我不确定出了什么问题。
当单步执行代码时,我端上的所有东西都是我预期的那样,所以我在想,不知怎么的,我把音频曲目配置错了。
我在一个模拟器上运行,但我不认为这是一个问题。
我正在使用的WavFile类是一个经过审查的类,我已经在许多Java项目中启动并可靠地运行了它,它经过测试可以很好地工作。
请注意下面的日志写入,这是较大代码块中的一个片段。此日志写入从未命中。。。
if (headPosition > 0)
Log.e("headPosition is greater than zero!!");
..
public static void writeToAudioTrackStream(final WavFile wave)
{
Log.e("writeToAudioTrackStream");
Thread thread = new Thread()
{
public void run()
{
try {
final float[] data = wave.getData();
int format = -1;
if (wave.getChannel() == 1)
format = AudioFormat.CHANNEL_OUT_MONO;
else if (wave.getChannel() == 2)
format = AudioFormat.CHANNEL_OUT_STEREO;
else
throw new RuntimeException("writeToAudioTrackStatic() - unsupported number of channels value = "+wave.getChannel());
final int bufferSizeInFrames = 2048;
final int bytesPerSmp = wave.getBytesPerSmp();
final int bufferSizeInBytes = bufferSizeInFrames * bytesPerSmp * wave.getChannel();
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, wave.getSmpRate(),
format,
AudioFormat.ENCODING_PCM_FLOAT,
bufferSizeInBytes,
AudioTrack.MODE_STREAM);
int index = 0;
float[] buffer = new float[bufferSizeInFrames * wave.getChannel()];
boolean started = false;
int framesWritten = 0;
while (index < data.length) {
// calculate the available space in the buffer
int headPosition = audioTrack.getPlaybackHeadPosition();
if (headPosition > 0)
Log.e("headPosition is greater than zero!!");
int framesInBuffer = framesWritten - headPosition;
int availableFrames = bufferSizeInFrames - framesInBuffer;
// once the buffer has no space, the prime is done, so start playing
if (availableFrames == 0) {
if (!started) {
audioTrack.play();
started = true;
}
continue;
}
int endOffset = availableFrames * wave.getChannel();
for (int i = 0; i < endOffset; i++)
buffer[i] = data[index + i];
int samplesWritten = audioTrack.write(buffer , 0 , endOffset , AudioTrack.WRITE_BLOCKING);
// could return error values
if (samplesWritten < 0)
throw new RuntimeException("AudioTrack write error.");
framesWritten += samplesWritten / wave.getChannel();
index = endOffset;
}
}
catch (Exception e) {
Log.e(e.toString());
}
}
};
thread.start();
}