simplify playback of audio without AudioPlayer

The additional thread to feed the AudioTrack was unnecessary.
Because the AudioTrack API is blocking when data is written,
and internally it buffers data, writing the data as soon
as it is received from the network leads to better playback
performance. It is also much simpler.
This commit is contained in:
Branden Archer
2016-01-01 01:09:31 -05:00
parent 07892afea1
commit bd2726370f
2 changed files with 12 additions and 92 deletions

View File

@@ -1,67 +0,0 @@
/**
* This file is part of the Protect Baby Monitor.
*
* Protect Baby Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Protect Baby Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Protect Baby Monitor. If not, see <http://www.gnu.org/licenses/>.
*/
package protect.babymonitor;
import java.util.concurrent.BlockingQueue;
import android.media.AudioTrack;
import android.util.Log;
public class AudioPlayer implements Runnable
{
final String TAG = "BabyMonitor";
private final AudioTrack _audioTrack;
private final BlockingQueue<byte[]> _queue;
public AudioPlayer(AudioTrack audioTrack, BlockingQueue<byte[]> queue)
{
_audioTrack = audioTrack;
_queue = queue;
}
@Override
public void run()
{
Log.i(TAG, "Audio player thread started");
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
_audioTrack.play();
try
{
while(Thread.currentThread().isInterrupted() == false)
{
byte [] data = _queue.take();
int written = _audioTrack.write(data, 0, data.length);
if(written != data.length)
{
Log.i(TAG, "Did not write bytes: " + (data.length - written));
}
}
}
catch (InterruptedException e)
{
}
Log.i(TAG, "Audio player thread stopping");
_audioTrack.stop();
}
}

View File

@@ -20,9 +20,6 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.Socket; import java.net.Socket;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import android.app.Activity; import android.app.Activity;
import android.media.AudioFormat; import android.media.AudioFormat;
@@ -58,43 +55,33 @@ public class ListenActivity extends Activity
bufferSize, bufferSize,
AudioTrack.MODE_STREAM); AudioTrack.MODE_STREAM);
final BlockingQueue<byte[]> queue = new LinkedBlockingQueue<byte[]>(1 /*max samples queued*/);
AudioPlayer audioPlayer = new AudioPlayer(audioTrack, queue);
Thread playThread = new Thread(audioPlayer);
playThread.start();
setVolumeControlStream(AudioManager.STREAM_MUSIC); setVolumeControlStream(AudioManager.STREAM_MUSIC);
InputStream is = socket.getInputStream(); InputStream is = socket.getInputStream();
int read = 0; int read = 0;
while(socket.isConnected() && read != -1 && Thread.currentThread().isInterrupted() == false) audioTrack.play();
try
{ {
byte [] buffer = new byte[bufferSize*2]; byte [] buffer = new byte[bufferSize*2];
while(socket.isConnected() && read != -1 && Thread.currentThread().isInterrupted() == false)
{
read = is.read(buffer); read = is.read(buffer);
if(read > 0) if(read > 0)
{ {
if(read < buffer.length) audioTrack.write(buffer, 0, read);
}
}
}
finally
{ {
buffer = Arrays.copyOf(buffer, read); audioTrack.stop();
}
try
{
queue.add(buffer);
}
catch(IllegalStateException e)
{
Log.i(TAG, "Buffer full, dropping data");
}
}
}
playThread.interrupt();
socket.close(); socket.close();
} }
}
@Override @Override
protected void onCreate(Bundle savedInstanceState) protected void onCreate(Bundle savedInstanceState)