Santhosh
Santhosh

Reputation: 11774

audiotrack: playing noise for a raw pcm 16bit wav file

I am trying to play a wav file of size 230mb and 20 min whose properties are as below:

ffmpeg -i 1.wav

Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s

I am learning how to use audiotrack.

I found two solutions to play this audio play using audiotrack.

Solution 1: the following plays the audio

int frequency = 44100;
int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

int bufferSize = AudioTrack.getMinBufferSize(frequency, channelConfiguration,audioEncoding);

AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequency,
        channelConfiguration, audioEncoding, bufferSize,
        AudioTrack.MODE_STREAM);

int count = 0;
byte[] data = new byte[bufferSize];
try{
    FileInputStream fileInputStream = new FileInputStream(listMusicFiles.get(0).listmusicfiles_fullfilepath);
    DataInputStream dataInputStream = new DataInputStream(fileInputStream);
    audioTrack.play();

    while((count = dataInputStream.read(data, 0, bufferSize)) > -1){
        audioTrack.write(data, 0, count);
    }

    audioTrack.stop();
    audioTrack.release();
    dataInputStream.close();
    fileInputStream.close();
}
catch (FileNotFoundException e){
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

Second Solution: Playing noise

int frequency = 44100;
int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

int bufferSize = AudioTrack.getMinBufferSize(frequency, channelConfiguration,audioEncoding);

short[] audiodata = new short[bufferSize];

try {

    DataInputStream dis = new DataInputStream(
            new BufferedInputStream(new FileInputStream(
                    listMusicFiles.get(0).listmusicfiles_fullfilepath)));

    AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequency,
            channelConfiguration, audioEncoding, bufferSize,
            AudioTrack.MODE_STREAM);

    audioTrack.play();

    while (dis.available() > 0) {
        int i = 0;
        while (dis.available() > 0 && i < audiodata.length) {
            audiodata[i] = dis.readShort();
            i++;
        }
        audioTrack.write(audiodata, 0, audiodata.length);
    }

    dis.close();
} catch (Throwable t) {
    Log.e("AudioTrack", "Playback Failed");
}

I am new to short sample and byte samples. I tried to understand but it not so easy.

I could understand the first solution is using byte sample and the second solution is using short samples.

So why is the second solution not working.

Upvotes: 0

Views: 1289

Answers (1)

Reaz Murshed
Reaz Murshed

Reputation: 24211

The default size of a short type is two bytes. You might have a look at this documentation as well.

The audio track has a recommended buffer size and sample rate which can be found using the way suggested here in this answer. Please have a look.

However, it is important to play the audio using the recommended sample rate which is 44100 Hz in your case and the recommended buffer size that you get using the following code segment.

AudioTrack.getMinBufferSize(frequency, channelConfiguration, audioEncoding) 

In your implementation with short array, the buffer size is doubled and hence its creating noises in case of playing the audio. I would suggest, you might consider changing the buffer size by dividing the size by two in your implementation using short.

short[] audiodata = new short[(int) bufferSize / 2];

Hope you have understood the problem.

Upvotes: 0

Related Questions