Question

I've been trying to make this small piece of code work for the past hours. It is meant to be a minimal working AudioTrack example, since I have found that many examples are quiet complicated.

private void playSound() {
    // AudioTrack definition
    int mBufferSize = AudioTrack.getMinBufferSize(44100,
                        AudioFormat.CHANNEL_OUT_MONO,    
                        AudioFormat.ENCODING_PCM_8BIT);

    mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100,
                        AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_8BIT,
                        mBufferSize, AudioTrack.MODE_STREAM);

     // Sine wave
     double[] mSound = new double[4410];
     short[] mBuffer = new short[4410];
     for (int i = 0; i < mSound.length; i++) {
         mSound[i] = Math.sin((2.0*Math.PI * 440.0/44100.0*(double)i));
         mBuffer[i] = (short) (mSound[i]*Short.MAX_VALUE);
     }

     mAudioTrack.setStereoVolume(0.1f, 0.1f);
     mAudioTrack.play();

     mAudioTrack.write(mBuffer, 0, mSound.length);
     mAudioTrack.stop();
     mAudioTrack.release();

}

When I call the function playSound(), I only get a short buzz that doesn't sound like a pure sine wave at all. I have tried different sampling rates, ranging from 8000Hz to 44100Hz, as well as different buffer sizes.

Exporting the content of mBuffer shows that the sine wave is correctly generated. It also plays correctly if I play it with Matlab, although the pitch is too high.

Is there something I'm not doing correctly? Also, if I try a 16bit encoding, I get no sound at all.

Was it helpful?

Solution

Stick to ENCODING_PCM_16BIT instead of ENCODING_PCM_8BIT (as stated in the documentation, it's not guaranteed to be supported by devices).

Adjust your volume to maximum (1.0f or use getMaxVolume()) on left and right channel, instead of 0.1f (which is really low amplitude).

Increase your buffer from 4410 (which is only 100ms of playing) to 2*44100 (which should represent 2 seconds of playing).

OTHER TIPS

You should call play() AFTER write(). Your code as it stands, will play rubbish.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top