我正在开发一个 Android 应用程序,我想播放一些短的声音(~ 2 秒)。我尝试过 Soundpool,但它并不适合我,因为它无法检查声音是否已经在播放。所以我决定使用 AudioTrack。
它工作得很好,但大多数时候,当它开始播放声音时,会发出“咔嗒”声。我检查了我的音频文件,它们是干净的。
我在流模式下使用音轨。我发现静态模式更适合短声音,但经过多次搜索后我仍然不明白如何使其工作。我还读到,点击噪音可能是由 wav 文件的标头引起的,因此如果我使用setPlaybackHeadPosition(int positionInFrames)函数跳过此标头(应该仅在静态模式下工作),声音可能会消失
这是我的代码(所以问题是开始时的滴答声)
int minBufferSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
audioTrack.play();
int i = 0;
int bufferSize = 2048; //don't really know which value to put
audioTrack.setPlaybackRate(88200);
byte [] buffer = new byte[bufferSize];
//there we open the wav file >
InputStream inputStream = getResources().openRawResource(R.raw.abordage);
try {
while((i = inputStream.read(buffer)) != -1)
audioTrack.write(buffer, 0, i);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
有人有办法避免这种噪音吗?我尝试过这个,有时有效,但并非每次都有效。有人可以告诉我如何实现音轨MODE_STATIC吗?谢谢
最后,经过大量实验,我让它在没有点击噪音的情况下工作。这是我的代码(不幸的是,我无法读取 inputStream 的大小,因为该getChannel().size()方法仅适用于 FileInputStream 类型)
try{
long totalAudioLen = 0;
InputStream inputStream = getResources().openRawResource(R.raw.abordage); // open the file
totalAudioLen = inputStream.available();
byte[] rawBytes = new byte[(int)totalAudioLen];
AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC,
44100,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
(int)totalAudioLen,
AudioTrack.MODE_STATIC);
int offset = 0;
int numRead = 0;
track.setPlaybackHeadPosition(100); // IMPORTANT to skip the click
while (offset < rawBytes.length
&& (numRead=inputStream.read(rawBytes, offset, rawBytes.length-offset)) >= 0) {
offset += numRead;
} //don't really know why it works, it reads the file
track.write(rawBytes, 0, (int)totalAudioLen); //write it in the buffer?
track.play(); // launch the play
track.setPlaybackRate(88200);
inputStream.close();
}
catch (FileNotFoundException e) {
Log.e(TAG, "Error loading audio to bytes", e);
} catch (IOException e) {
Log.e(TAG, "Error loading audio to bytes", e);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Error loading audio to bytes", e);
}
Run Code Online (Sandbox Code Playgroud)
因此,跳过点击噪音的解决方案是使用MODE_STATIC和setPlaybackHeadPosition函数来跳过音频文件的开头(这可能是标题或我不知道是什么)。我希望这部分代码会对某人有所帮助,我花了太多时间试图找到静态模式代码示例,而没有找到加载原始资源的方法。
编辑:在各种设备上测试此解决方案后,它们似乎仍然有咔哒声。
| 归档时间: |
|
| 查看次数: |
4559 次 |
| 最近记录: |