Android 多音轨,单线程还是多线程?
在我的应用程序中,我将创建多个音频曲目,其中一些需要同时播放。我将使用Android 多音轨,单线程还是多线程?,android,multithreading,audio,threadpool,Android,Multithreading,Audio,Threadpool,在我的应用程序中,我将创建多个音频曲目,其中一些需要同时播放。我将使用MODE\u STREAM并在应用程序运行时写入数据。声音是动态生成的,这就是为什么我使用音轨而不是其他任何东西。 我有4个选择,我相信: 异步任务 一个UI线程和一个管理所有音轨播放的线程 一个UI线程和一个音频跟踪线程 一个UI线程和一个 四种方法中哪一种是管理多个音频曲目的最佳方法 我认为线程池是一个不错的选择,但我并不乐观,因为我还没有真正使用过它 如果您有任何建议,我将不胜感激。我认为您最好选择AsyncTask。为
MODE\u STREAM
并在应用程序运行时写入数据。声音是动态生成的,这就是为什么我使用音轨而不是其他任何东西。
我有4个选择,我相信:
如果您有任何建议,我将不胜感激。我认为您最好选择AsyncTask。为简单起见,我只是在每次播放音轨时创建一个新线程 但是,不管怎样,这真的不重要。我发现,当试图一次播放多首音轨时,会出现噼啪声/起伏声。我相信这只是安卓系统的问题,而不是我的应用程序 从API level 9(gingerbread)开始,我可以将会话id应用于音频曲目,我相信这将使我能够使用SoundPool播放它,这将使同时播放多个音频曲目更加流畅
现在,由于有多少用户仍然使用2.2,而且我没有姜饼设备,我将把这个项目搁置到以后。为每个音轨创建一个异步任务,并使用EXECUTOR执行它们(在我的Android 4.4上,如果没有使用EXECUTOR,只会执行第一个任务)。 下面是一个将麦克风信号流传输到AudioTrack的示例,以及将音频文件流并行传输到其他AudioTrack的示例
/** 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());
/**用于将流文件录制到扬声器的任务*/
私有类PlayerTask扩展异步任务{
专用短[]缓冲区;
私有int缓冲区大小;
私人最终音轨;
...
@凌驾
受保护的空doInBackground(最终空…参数){
...
而(!isCancelled()){
audioTrack.write(缓冲区,0,缓冲区大小);
}
...
}
}
/**将麦克风流式传输到扬声器的任务*/
私有类MicTask扩展了AsyncTask{
专用短[]缓冲区;
私有int缓冲区大小;
私人最终音轨;
...
@凌驾
受保护的空doInBackground(最终空…参数){
...
而(!isCancelled()){
audioTrack.write(缓冲区,0,缓冲区大小);
}
...
}
}
/**在UI线程上并行启动两个任务以听到
这两个来源都是关于演讲者的**/
PlayerTask PlayerTask=新的PlayerTask();
playerTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,new Null());
MicTask MicTask=新的MicTask();
micTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,new Null());
我关心的是AsyncTask创建了一个工作线程,如果一个工作线程上运行了4个音频曲目,这可能会使它们阻塞整个线程吗?另一个问题是AsyncTask每个文档只能执行一次任务。那么,我是否能够通过onTouch事件动态更改音轨信息?我目前还缺乏使用AsyncTask的经验,因为我发布的一个应用程序不需要它。您可以通过调用“AsyncTask task=new AsyncTask();task.execute()多次执行该任务;好的,谢谢。但这仍然会为重复创建任务带来很多不必要的开销,不是吗?你是用哪种方式实现的?@burakk我在应用程序上从来没有走远,因为(至少在当时),Android的音频延迟很糟糕(而且我没有经验).如果我现在这样做,我会有一个后台线程,因为从不同线程同时处理音频是一个愚蠢的想法。而且,我认为使用一个AudioTrack
并正确设置数据(频率和其他)如果你对Android音频开发感兴趣,请访问columbia.edu,谢谢你的快速回复。我已经开发了一个可以同时播放两个流的应用程序。我有两个服务,每个服务在一个单独的线程中实例化一个音轨。正如我所问的在我的SO问题中,我想知道处理两个以上的流的最佳方式是什么。我不想为每个流编写服务。我不是音频或硬件I/o方面的专家,但我相信,当你添加流时,你会增加拥塞,这可能会导致意外/不想要的结果。不过,我可能错了。我将接受一个lo如果你明天还没有得到答案的话,可以在你的Q。