Android AudioTrack播放.wav文件,仅获得白噪声
当我播放带有以下代码的文件时:Android AudioTrack播放.wav文件,仅获得白噪声,android,audio,bytearray,inputstream,pcm,Android,Audio,Bytearray,Inputstream,Pcm,当我播放带有以下代码的文件时: private void PlayAudioFileViaAudioTrack(int ResId) throws IOException { int intSize = android.media.AudioTrack.getMinBufferSize(11025, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT); AudioTrack at =
private void PlayAudioFileViaAudioTrack(int ResId) throws IOException {
int intSize = android.media.AudioTrack.getMinBufferSize(11025, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 11025, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, intSize,
AudioTrack.MODE_STREAM);
int count = 256 * 1024; // 256 kb
byte[] byteData = null;
byteData = new byte[(int) count];
InputStream in = null;
AssetFileDescriptor fd = null;
fd = mResources.openRawResourceFd(ResId);
in = mResources.openRawResource(ResId);
int bytesRead = 0, amount = 0;
int size = (int) fd.getLength();
at.play();
while (bytesRead < size) {
amount = in.read(byteData, 0, count);
if (amount != -1) {
at.write(byteData, 0, amount);
}
}
in.close();
at.stop();
at.release();
}
private void PlayAudioFileViaAudioTrack(int-ResId)引发IOException{
int intSize=android.media.AudioTrack.getMinBufferSize(11025,AudioFormat.CHANNEL\u配置\u单声道,AudioFormat.ENCODING\u PCM\u 16位);
AudioTrack at=新的AudioTrack(AudioManager.STREAM_MUSIC,11025,AudioFormat.CHANNEL_CONFIGURATION_MONO,AudioFormat.ENCODING_PCM_16BIT,intSize,
音频跟踪模式(音频流);
int count=256*1024;//256 kb
字节[]字节数据=null;
byteData=新字节[(int)计数];
InputStream in=null;
AssetFileDescriptor fd=null;
fd=mResources.openrawsourcefd(ResId);
in=mResources.openrawsources(ResId);
int bytesRead=0,amount=0;
int size=(int)fd.getLength();
at.play();
while(字节读取<大小){
金额=单位读取(字节数据,0,计数);
如果(金额!=-1){
at.write(字节数据,0,金额);
}
}
in.close();
at.stop();
at.release();
}
我唯一听到的是静态的白噪音。我已经检查了我的.wav文件是否具有相同的属性(samplerate、bitrate)。我对原始音频数据(PCM)不太了解,所以我想知道是否有人能看出我的代码有什么问题。这看起来比我做的要复杂得多。我用这个播放声音。我认为.wav文件也可以工作
MediaPlayer mpPlayProgram = new MediaPlayer();
mpPlayProgram.setDataSource("/sdcard/file.mp3");
mpPlayProgram.prepare();
mpPlayProgram.start();
mpPlayProgram.release();
对于静态资源,它更容易:
MediaPlayer mpStart = MediaPlayer.create(this, resID);
mpStart.start();
mpStart.release();
从您的代码中,我可以看到您只是从wav文件中读取数据,然后将其导入到AudioTrack。Wav文件有一个小的头,你可以在这里看到,所以你必须跳过头,并指出你的文件描述符在正确的地方,实际的音频数据 此外,当您播放音频文件和处理字节操作时,您应该注意尾数。看看这里 下面是我在Nexus One和Galaxy S中使用频率为8000Hz和16位编码的WAV文件的代码(缺少一些检查和WAV头跳过)
public void playWav(){
int minBufferSize = AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
int bufferSize = 512;
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
String filepath = Environment.getExternalStorageDirectory().getAbsolutePath();
int i = 0;
byte[] s = new byte[bufferSize];
try {
FileInputStream fin = new FileInputStream(filepath + "/REFERENCE.wav");
DataInputStream dis = new DataInputStream(fin);
at.play();
while((i = dis.read(s, 0, bufferSize)) > -1){
at.write(s, 0, i);
}
at.stop();
at.release();
dis.close();
fin.close();
} catch (FileNotFoundException e) {
// TODO
e.printStackTrace();
} catch (IOException e) {
// TODO
e.printStackTrace();
}
}
如果您已将文件保存为wav格式,并希望使用AudioTrack播放该文件,请遵循以下代码:
File file=new File(Environment.getExternalStorageDirectory()+"/AudioRecorder/fahim.wav");
InputStream is;
DataInputStream dis = null ;
BufferedInputStream bis;
try
{
is = new FileInputStream(file);
bis = new BufferedInputStream(is, 8000);
dis = new DataInputStream(bis); // Create a DataInputStream to read the audio data from the saved file
}
catch (FileNotFoundException e1)
{
ShowToast("fILE NOT FOUND:"+e1.getMessage());
}
int i = 0; // Read the file into the "music" array
music=new byte[(int) file.length()];
try
{
while (dis.available() > 0)
{
music[i] = dis.readByte(); // This assignment does not reverse the order
i++;
}
}
catch (IOException e)
{
ShowToast("I/O Exception:"+e.getMessage());
}
try {dis.close();} catch (IOException e) {e.printStackTrace();}
int minBufferSize = AudioTrack.getMinBufferSize(11025, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 11025, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
at.play();
ShowToast("size:"+music.length);
//*/
at.write(music, 0, music.length);
我没有使用MediaPlayer类,因为它的级别非常高。我用的是AudioTrack,它更适合我做的事情。标题只够播放几毫秒的声音,之后应该会正常播放。你能给我解释一下“照顾好Endianess”是什么意思吗?哦,对不起,我弄错了Endianess。我以为你读的数据是短的,但你读的是字节,所以endianess在这里不是问题。为了确保这一点,我编写了一个小程序(我可以提供源代码),读取.wav文件并将其写入AudioTrack。它在我的手机上正常播放wav文件。也许您在AudioTrack构造函数中的配置参数可能是错误的。您是否检查了wav文件的属性?也许它有不同的采样频率或编码。嗯,很奇怪。。。我在第一次回答时添加了我的代码。正如你所看到的,我处理AudioTrack的方式是一样的。唯一的区别是文件的打开和读取。向logcat添加一些调试消息,以查看这些操作是否出错。我建议再做两个实验:1)尝试调零缓冲区并写入它-在这种情况下,必须不存在白噪声;2) 试着扭转短路(即强制endian转换)@Manos:Nice代码。是否可以将字节[]s更改为短[]s?因为我想从那个数据计算RMS,但它只对short[]类型正确。谢谢