简体   繁体   中英

Multiple AudioTracks, Single Thread or Multiple?

In my application, I will be creating multiple Audio Tracks, some of which will need to play simultaneously. I'm going to use MODE_STREAM and write data in as the app runs. Sounds are going to be dynamically generated, which is why I use Audio Track as opposed to anything else. I have 4 options, I believe:

  1. AsyncTask
  2. One UI thread and one thread that manages all the AudioTrack playing
  3. One UI thread and one thread for each AudioTrack
  4. One UI thread and a Thread Pool

Which of the four methods would be the best way to manage multiple AudioTracks?

I think Thread Pool is the way to go, but I'm not positive as I haven't actually used it.

Any advice would be greatly appreciated

For simplicity, I was just creating a new thread every time I played an AudioTrack.

But, regardless it really doesn't matter. I found that when trying to play more than one AudioTrack at a time, there's a crackling/choppy sound. I believe this is just an issue with the Android system, not with my app.

As of API level 9 (gingerbread) I can apply a session id to an audio track, which I believe would let me play it with SoundPool, which should make the playing of multiple AudioTracks at once much smoother.

Right now, due to how many users are still on 2.2 and the fact that I don't have a gingerbread device, I will put this project aside until later.

Create an AsyncTask for every AudioTrack, and execute them with an Excecutor (on my Android 4.4, only the first task will be executed, if no Excecutor is used). Here is an example of streaming a microphone signal to AudioTrack and a audio file stream to an other AudioTrack in parallel.

/** Task for streaming file recording to speaker. */
private class PlayerTask extends AsyncTask<Null, Null, Null> {
    private short[] buffer;
    private int bufferSize;
    private final AudioTrack audioTrack;
    ...
    @Override
    protected Null doInBackground(final Null... params) {
        ...
        while (!isCancelled()) {
            audioTrack.write(buffer, 0, bufferSize);
        }
        ...
    }
}

/** Task for streaming microphone to speaker. */
private class MicTask extends AsyncTask<Null, Null, Null> {
    private short[] buffer;
    private int bufferSize;
    private final AudioTrack audioTrack;
    ...
    @Override
    protected Null doInBackground(final Null... params) {
        ...
        while (!isCancelled()) {
            audioTrack.write(buffer, 0, bufferSize);
        }
        ...
    }
}

/** On the UI-thread starting both tasks in parallel to hear
    both sources on the speaker. **/
PlayerTask playerTask = new PlayerTask();
playerTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new Null());

MicTask micTask = new MicTask();
micTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new Null());

我认为你最好的选择是AsyncTask。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM