I am programming for Android 2.1. Could you help me with the following problem?
I have three files, and the overall goal is to play sound with the audiotrack buffer. I get pretty desperate here because I tried everything and still there is no sound coming out of my speakers (while the android integrated media player has no problems playing sounds through the emulator).
Source:
A class of audio player that implements an audio track. He will receive a buffer that contains sound.
public AudioPlayer(int sampleRate, int channelConfiguration, int audioFormat) throws ProjectException { minBufferSize = AudioTrack.getMinBufferSize(sampleRate, channelConfiguration, audioFormat); audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, channelConfiguration, audioFormat, minBufferSize, AudioTrack.MODE_STREAM); if(audioTrack == null) throw new ProjectException("Erreur lors de l'instantiation de AudioTrack"); audioTrack.setStereoVolume((float)1.0, (float)1.0); } @Override public void addToQueue(short[] buffer) { audioTrack.write(buffer, 0, buffer.length*Short.SIZE); if(!isPlaying ) { audioTrack.play(); isPlaying = true; } }
The model class that I use to fill the buffer. Usually it loads the sound from a file, but here it just uses a simulator (440 Hz) for debugging.
Buffer sizes are selected very poorly; usually the first buffer size should be 6615, and then 4410. This again is for debugging only.
public void onTimeChange() { if(begin) { //First fill about 300ms begin = false; short[][] buffer = new short[channels][numFramesBegin]; //numFramesBegin is for example 10000 //For debugging only buffer[0] is useful fillSimulatedBuffer(buffer, framesRead); framesRead += numFramesBegin; audioPlayer.addToQueue(buffer[0]); } else { try { short[][] buffer = new short[channels][numFrames]; //Afterwards fill like 200ms fillSimulatedBuffer(buffer, framesRead); framesRead += numFrames; audioPlayer.addToQueue(buffer[0]); } catch (Exception e) { e.printStackTrace(); } } } private short simulator(int time, short amplitude) { //a pure A (frequency=440) //this is probably wrong due to sampling rate, but 44 and 4400 won't work either return (short)(amplitude*((short)(Math.sin((double)(simulatorFrequency*time))))); } private void fillSimulatedBuffer(short[][] buffer, int offset) { for(int i = 0; i < buffer[0].length; i++) buffer[0][i] = simulator(offset + i, amplitude); }
A timeTask class that calls model.ontimechange () every 200 ms.
public class ReadMusic extends TimerTask { private final Model model; public ReadMusic(Model model) { this.model = model; } @Override public void run() { System.out.println("Task run"); model.onTimeChange(); } }
What debugging showed me:
- timeTask works fine, it does its job;
- Buffer values seem coherent, and the buffer size is larger than minBufSize;
- Playback status of audio tracks "playing"
- The model function does not exclude exceptions.
Any ideas would be greatly appreciated!