AudioTrack in streaming mode MODE_STREAMING
16,743
Here is short example that works for me:
public class Internal extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void onPlayClicked(View v)
{
start();
}
public void onStopClicked(View v)
{
stop();
}
boolean m_stop = false;
AudioTrack m_audioTrack;
Thread m_noiseThread;
Runnable m_noiseGenerator = new Runnable()
{
public void run()
{
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
/* 8000 bytes per second, 1000 bytes = 125 ms */
byte [] noiseData = new byte[1000];
Random rnd = new Random();
while(!m_stop)
{
rnd.nextBytes(noiseData);
m_audioTrack.write(noiseData, 0, noiseData.length);
}
}
};
void start()
{
m_stop = false;
/* 8000 bytes per second*/
m_audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_8BIT, 8000 /* 1 second buffer */,
AudioTrack.MODE_STREAM);
m_audioTrack.play();
m_noiseThread = new Thread(m_noiseGenerator);
m_noiseThread.start();
}
void stop()
{
m_stop = true;
m_audioTrack.stop();
}
}
Author by
Raffaele
"Always be the worst guy in every band you’re in" "Eventually you realize you have no idea what you are doing and you do what you should have done in the 1st place - read papers" "...because Jon Skeet doesn't achieve badges, badges achieve Jon Skeet"
Updated on July 18, 2022Comments
-
Raffaele almost 2 years
I need to stream PCM data generated at runtime. So I have a thread with a loop
public void run() { while(...) { mAudioTrack.write(getPCM(), ...); } }
Unfortunately this doesn't work. It seems it doesn't depend on AudioTrack buffer size. I want it to be very small to simulate sort of low latency behaviour (150 ms) so the user can dinamically change the PCM picked by getPCM()
int bufferSize = 0.150 * sampleRate * channels * bitsPerSample / 8;
However, I tried to increase the buffer size up to 100k with no result
-
Raffaele almost 13 yearsDon't know what you mean. I cannot hear anything
-
inazaruk almost 13 yearsThis code works on two devices (both Samsung though). Check your LogCat logs, it should print all the details about
AudioTrack
. -
Raffaele almost 13 yearsSure, I had to add a call to start() upon activity creation. Then it's a mistery it doesn't work with actual PCM data. Now I'm going to test with a machine-generated A 440hz sound
-
Raffaele almost 13 yearsSure, your code definetly solves the problem (in theory). Now I have to understand what's wrong with my code
-
Raffaele almost 13 years@inazaruk How would you measure the average write delay? I modified your code a bit to play a fixed sound, and configured AudioTrack with a small buffer, so you can hear the underrunning. Here you are the code and the eclipse proj
-
inazaruk almost 13 yearsI'm not sure I understood your question. What do you mean under write delay? How long it takes to play your buffer of X bytes?
-
inazaruk almost 13 yearsOh, I got it. You do not need to put
Thread.Sleep
in writerAudioTrack
thread. TheAudioTracker.write
is blocking. It will only return, when there is free space in its buffer (size of which is specified in its constructor). So you shouldn't worry about buffer overflow and just removeSleep
method from writer thread.