【发布时间】:2014-11-15 09:02:04
【问题描述】:
这个问题困扰了我一段时间。我正在尝试使用 Tarsos DSP 对我正在为 Android 开发的项目执行一些基本的信号处理。音频来自 44.1k、16 位立体声的标准 WAV 文件。当我使用使用 Android 的 AudioTrack 输出声音的 AudioProcessor 设置和运行 Tarsos AudioDispatcher 时,我得到静态或播放速度过快的音频。
这是设置音频调度程序的代码
public void Play(String source, double startTime, final double endTime){
InputStream wavStream;
try {
wavStream = new FileInputStream(source);
UniversalAudioInputStream audioStream = new UniversalAudioInputStream(wavStream, audioFormat);
dispatcher = new AudioDispatcher(audioStream, bufferSize, overLap);
AndroidAudioPlayer player = new AndroidAudioPlayer(audioFormat, buffersize);
dispatcher.addAudioProcessor(player);
dispatcher.skip(startTime);
new Thread(new Runnable() {
@Override
public void run() {
while (dispatcher.secondsProcessed() < endTime) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
dispatcher.stop();
}
}).start();
dispatcher.run();
try {
audioStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}catch (FileNotFoundException e){e.printStackTrace();}
}
我注意到的一件事是,如果我让 AudioDispatcher 运行整个 WAV 文件,它会报告处理的总秒数比 WAV 文件标题中指示的要长,这使得方法设置的开始和结束时间不准确,但仍在范围内(通常)。 (为什么会这样?)**
这是实现 Tarsos AudioProcessor 的 AndroidAudioPlayer 的代码:
public class AndroidAudioPlayer implements AudioProcessor {
private AudioTrack audioTrack;
AndroidAudioPlayer(TarsosDSPAudioFormat audioFormat, int bufferSize){
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
(int)audioFormat.getSampleRate(),
AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSize,
AudioTrack.MODE_STREAM);
}
@Override
public boolean process(AudioEvent audioEvent){
short[] shorts = new short[audioEvent.getBufferSize() / 2];
ByteBuffer.wrap(audioEvent.getByteBuffer()).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
audioTrack.write(shorts, 0, shorts.length);
audioTrack.play();
return true;
}
@Override
public void processingFinished(){}
}
我编写了另一个音频处理器,它使用 AudioDispatcher 使用 JavaZoom 从 WAV 文件中写入剪辑,这也会产生静态或不正确的音频。但是,当我使用 InputStream 和 JavaZoom 从 WAV 文件编写剪辑时,它有时可以正常工作或产生静态,我假设这是因为我依赖 Tarsos 的方法错误地设置了 startTime 和 stopTime 变量。任何见解将不胜感激。
在调用上述方法之前,我首先调用了一个方法,该方法在同一个 WAV 文件上使用 AudioDispatcher 与 Oscilloscope 和 ComplexOnsetDetector 音频处理器来生成波形视图并用开始的时间码填充数组。 audioFormat 变量是这样创建的:TarsosDSPAudioFormat audioFormat = new TarsosDSPAudioFormat(sampleRate, 16, 2, false, false);,采样率是从 WAV 文件中读取的,我检查过它是否正确读取。 *缓冲区大小为 1024,重叠为 512,我尝试使用所有这些值。
我已将缓冲区大小更改为 64kb,并将重叠更改为 32kb。当音频播放时,它听起来几乎是正确的,只是有点跳跃。但是,它有时仍然只播放静态,无论我使用多长的 WAV 文件,AudioDispatcher 报告它是 315 秒长*。
**我已经解决了这个问题。我正在加载一个由 JavaZoom MP3 转换器创建的 WAV 文件,该文件不断覆盖文件而不先删除它。我认为 Tarsos 使用文件长度来确定播放长度是不正确的,因为没有删除就被覆盖了。删除文件先解决问题。
我只需要弄清楚为什么音频在播放过程中会跳过,有时只是静态播放,然后我想我可以继续了。
【问题讨论】:
-
现在是什么状态?
-
我从来没有用 Tarsos 解决过这个问题。相反,我自己进行了处理。 Tarsos 的 github 上有很多活动,所以那里可能有一些答案。
标签: java android audio signal-processing audiotrack