views:

161

answers:

2

I'm working with Android, trying to make my AudioTrack application play a Windows .wav file (Tada.wav). Frankly, it shouldn't be this hard, but I'm hearing a lot of strange stuff. The file is saved on my phone's mini SD card and reading the contents doesn't seem to be a problem, but when I play the file (with parameters I'm only PRETTY SURE are right), I get a few seconds of white noise before the sound seems to resolve itself into something that just may be right.

I have successfully recorded and played my own voice back on the phone -- I created a .pcm file according to the directions in this example:

http://emeadev.blogspot.com/2009/09/raw-audio-manipulation-in-android.html

(without the backwards masking)...

Anybody got some suggestions or awareness of an example on the web for playing a .wav file on an Android??

Thanks, R.

A: 

Are you skipping the first 44 bytes of the file before you dump the rest of the file's data into the buffer? The first 44 bytes are the WAVE header and they would sound like random noise if you tried to play them.

Also, are you sure you are creating the AudioTrack with the same properties as the WAVE you are trying to play (sample rate, bit rate, number of channels, etc)? Windows actually does a good job of giving this information to you in the File Properties page: alt text

Aaron C
I have tried every combination of skipping the header and not that I can think of -- without much luck. The white noise sound lasts MUCH longer than 44 bites worth. Tada.wav is a 168 kByte file, so "playing" the header should barely be noticeable, right?
Rich
Correct, the file header would generate garbage for a very short time. Are you sure you are creating the AudioTrack with the same properties as the WAVE you are trying to play (sample rate, bit rate, number of channels, etc)?
Aaron C
I have a hex editor and I sure think I'm getting the numbers out of the header properly. I'm kind of surprised I haven't been able to find a wav file analyzer of some sort on the Internet. I'm stumped, AND Windows Media player can certainly play the file...
Rich
Window's file Properties page actually does a good job of giving this information to you, if you want to sanity check your values.
Aaron C
+2  A: 

I stumbled on the answer (frankly, by trying &^@! I didn't think would work), in case anybody's interested... In my original code (which is derived from the example in the link in the original post), the data is read from the file like so:

    InputStream             is  = new FileInputStream       (file);
    BufferedInputStream     bis = new BufferedInputStream   (is, 8000);
    DataInputStream         dis = new DataInputStream       (bis);      //  Create a DataInputStream to read the audio data from the saved file

    int i = 0;                                                          //  Read the file into the "music" array
    while (dis.available() > 0)
    {
        music[i] = dis.readShort();                                     //  This assignment does not reverse the order
        i++;
    }

    dis.close();                                                        //  Close the input stream

In this version, music[] is array of SHORTS. So, the readShort() method would seem to make sense here, since the data is 16-bit PCM... However, on the Android that seems to be the problem. I changed that code to the following:

    InputStream             is  = new FileInputStream       (file);
    BufferedInputStream     bis = new BufferedInputStream   (is, 8000);
    DataInputStream         dis = new DataInputStream       (bis);      //  Create a DataInputStream to read the audio data from the saved file

    int i = 0;                                                          //  Read the file into the "music" array
    while (dis.available() > 0)
    {
        music[i] = dis.readByte();                                      //  This assignment does not reverse the order
        i++;
    }

    dis.close();                                                        //  Close the input stream

In this version, music[] is an array of BYTES. I'm still telling the AudioTrack that it's 16-bit PCM data, and my Android doesn't seem to have a problem with writing an array of bytes into an AudioTrack thus configured... Anyway, it finally sounds right, so if anyone else wants to play Windows sounds on their Android, for some reason, that's the solution. Ah, Endianness......

R.

Rich
This should be the accepted answer, since it answers the question. ;)
gary comtois
I could've sworn I left a "Thank You, Gary" right here, but it's not here now... Thank you, Gary!!
Rich