Android AudioTrack播放.wav文件,只获得白噪声

时间:2021-01-16 19:45:16

When I play a file with the following code:

当我使用以下代码播放文件时:

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();

}

The only thing I hear is static, white noise. I've checked that my .wav file has the same properties (samplerate,bitrate). I don't have to much knowledge about raw audio data(PCM), so I was wondering if anyone could see what's wrong with my code.

我听到的唯一的东西是静电,白噪声。我检查过我的.wav文件具有相同的属性(samplerate,bitrate)。我不太了解原始音频数据(PCM),所以我想知道是否有人能看到我的代码有什么问题。

3 个解决方案

#1


7  

from your code i can see that you just read data from the wav file and just import them to the AudioTrack. Wav files have a small header as you can see here https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ So you have to skip the header and point your file descriptor at the right place where the actual audio data are.

从您的代码中我可以看到您只是从wav文件中读取数据并将它们导入AudioTrack。 Wav文件有一个小标题,你可以在这里看到https://ccrma.stanford.edu/courses/422/projects/WaveFormat/所以你必须跳过标题并将文件描述符指向实际音频数据的正确位置是。

Also when you playing an audio file and you are dealing with byte operations you should take care of the Endianess. Take a look here Using AudioTrack in Android to play a WAV file

此外,当您播放音频文件并处理字节操作时,您应该处理Endianess。看看这里在Android中使用AudioTrack播放WAV文件

Below my code (some checks and the WAV header skip are missing) that works in both Nexus One and Galaxy S with a wav file with frequency 8000Hz and 16 bit encoding.

在我的代码下面(一些检查和WAV标题跳过丢失)在Nexus One和Galaxy S中均可使用频率为8000Hz和16位编码的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();
    }       
}

#2


-1  

That looks WAY more complicated than what I did. I played sounds using this. I think .wav files would work just as well.

这看起来比我做的更复杂。我用这个播放了声音。我认为.wav文件也可以正常工作。

MediaPlayer mpPlayProgram = new MediaPlayer();
mpPlayProgram.setDataSource("/sdcard/file.mp3");
mpPlayProgram.prepare();
mpPlayProgram.start();
mpPlayProgram.release();

For static resources, it's even easier:

对于静态资源,它甚至更容易:

MediaPlayer mpStart = MediaPlayer.create(this, resID);
mpStart.start();
mpStart.release();

#3


-1  

If you have saved file in wav format and want to play it using AudioTrack then follow this code:

如果您以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);

#1


7  

from your code i can see that you just read data from the wav file and just import them to the AudioTrack. Wav files have a small header as you can see here https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ So you have to skip the header and point your file descriptor at the right place where the actual audio data are.

从您的代码中我可以看到您只是从wav文件中读取数据并将它们导入AudioTrack。 Wav文件有一个小标题,你可以在这里看到https://ccrma.stanford.edu/courses/422/projects/WaveFormat/所以你必须跳过标题并将文件描述符指向实际音频数据的正确位置是。

Also when you playing an audio file and you are dealing with byte operations you should take care of the Endianess. Take a look here Using AudioTrack in Android to play a WAV file

此外,当您播放音频文件并处理字节操作时,您应该处理Endianess。看看这里在Android中使用AudioTrack播放WAV文件

Below my code (some checks and the WAV header skip are missing) that works in both Nexus One and Galaxy S with a wav file with frequency 8000Hz and 16 bit encoding.

在我的代码下面(一些检查和WAV标题跳过丢失)在Nexus One和Galaxy S中均可使用频率为8000Hz和16位编码的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();
    }       
}

#2


-1  

That looks WAY more complicated than what I did. I played sounds using this. I think .wav files would work just as well.

这看起来比我做的更复杂。我用这个播放了声音。我认为.wav文件也可以正常工作。

MediaPlayer mpPlayProgram = new MediaPlayer();
mpPlayProgram.setDataSource("/sdcard/file.mp3");
mpPlayProgram.prepare();
mpPlayProgram.start();
mpPlayProgram.release();

For static resources, it's even easier:

对于静态资源,它甚至更容易:

MediaPlayer mpStart = MediaPlayer.create(this, resID);
mpStart.start();
mpStart.release();

#3


-1  

If you have saved file in wav format and want to play it using AudioTrack then follow this code:

如果您以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);