Android - MediaPlayer/SoundPool 性能?
Posted
技术标签:
【中文标题】Android - MediaPlayer/SoundPool 性能?【英文标题】:Android - MediaPlayer/SoundPool performance? 【发布时间】:2015-07-02 09:13:47 【问题描述】:我是 android 新手,我已经构建了一个 16-Step-Pattern-Sequencer。我已经用 MediaPlayer 做到了这一点,但是当应该同时播放 1 个以上的声音时,它都会变慢:/ .. 所以我尝试了相同的 SoundPool(标记为已弃用),但这里出现了相同的效果,也是。。
它是这样构建的: - 每一步,我检查是否设置了一个音符..如果是..播放声音 - 16-Step-Loop 在一个线程中运行
经过长时间的测试,似乎第一次运行(所有 16 步)都以正常速度运行。随着第二次运行的开始,根据需要播放的声音量,一切都变慢了.. :/
我可以尝试其他解决方案吗?
编辑:
这是我的音序器的代码
初始化:
soundPool = new SoundPool(32, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener()
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status)
loaded = true;
);
soundID_kick_1 = soundPool.load(this, R.raw.kick1, 1);
soundID_kick_2 = soundPool.load(this, R.raw.kick2, 1);
soundID_kick_3 = soundPool.load(this, R.raw.kick3, 1);
soundID_kick_4 = soundPool.load(this, R.raw.kick4, 1);
soundID_kick_5 = soundPool.load(this, R.raw.kick5, 1);
soundID_kick_6 = soundPool.load(this, R.raw.kick6, 1);
soundID_kick_7 = soundPool.load(this, R.raw.kick7, 1);
soundID_kick_8 = soundPool.load(this, R.raw.kick8, 1);
soundID_hh_1 = soundPool.load(this, R.raw.hh1, 2);
soundID_hh_2 = soundPool.load(this, R.raw.hh2, 2);
soundID_hh_3 = soundPool.load(this, R.raw.hh3, 2);
soundID_hh_4 = soundPool.load(this, R.raw.hh4, 2);
soundID_hh_5 = soundPool.load(this, R.raw.hh5, 2);
soundID_hh_6 = soundPool.load(this, R.raw.hh6, 2);
soundID_hh_7 = soundPool.load(this, R.raw.hh7, 2);
soundID_hh_8 = soundPool.load(this, R.raw.hh8, 2);
soundID_sd_1 = soundPool.load(this, R.raw.sd1, 3);
soundID_sd_2 = soundPool.load(this, R.raw.sd2, 3);
soundID_sd_3 = soundPool.load(this, R.raw.sd3, 3);
soundID_sd_4 = soundPool.load(this, R.raw.sd4, 3);
soundID_sd_5 = soundPool.load(this, R.raw.sd5, 3);
soundID_sd_6 = soundPool.load(this, R.raw.sd6, 3);
soundID_sd_7 = soundPool.load(this, R.raw.sd7, 3);
soundID_sd_8 = soundPool.load(this, R.raw.sd8, 3);
soundID_snd_1 = soundPool.load(this, R.raw.snd1, 4);
soundID_snd_2 = soundPool.load(this, R.raw.snd2, 4);
soundID_snd_3 = soundPool.load(this, R.raw.snd3, 4);
soundID_snd_4 = soundPool.load(this, R.raw.snd4, 4);
soundID_snd_5 = soundPool.load(this, R.raw.snd5, 4);
soundID_snd_6 = soundPool.load(this, R.raw.snd6, 4);
soundID_snd_7 = soundPool.load(this, R.raw.snd7, 4);
soundID_snd_8 = soundPool.load(this, R.raw.snd8, 4);
稍后当点击 seqPlay 时,sequencer 运行:
private View.OnClickListener seqPlay = new View.OnClickListener()
public void onClick(View v)
btn_seq_play = (ImageButton)findViewById(R.id.btn_seq_play);
Thread seq_thread = new Thread(new Runnable()
@Override
public void run()
// Do loop while seq_status==true
while(seq_status)
for (int i = 0; i <= 15; i++)
// Play Kicks if set
Log.i("Durchlauf Kicks" + i, "seqKick_status[i] " + seqKick_status[i]);
if (seqKick_status[i] != 0 && !mute_kick_status)
switch (seqKick_status[i])
case 1:
soundPool.play(soundID_kick_1, volKick[i], volKick[i], 1, 0, 1f);
break;
case 2:
soundPool.play(soundID_kick_2, volKick[i], volKick[i], 1, 0, 1f);
break;
case 3:
soundPool.play(soundID_kick_3, volKick[i], volKick[i], 1, 0, 1f);
break;
case 4:
soundPool.play(soundID_kick_4, volKick[i], volKick[i], 1, 0, 1f);
break;
case 5:
soundPool.play(soundID_kick_5, volKick[i], volKick[i], 1, 0, 1f);
break;
case 6:
soundPool.play(soundID_kick_6, volKick[i], volKick[i], 1, 0, 1f);
break;
case 7:
soundPool.play(soundID_kick_7, volKick[i], volKick[i], 1, 0, 1f);
break;
case 8:
soundPool.play(soundID_kick_8, volKick[i], volKick[i], 1, 0, 1f);
break;
// Play HH if set
Log.i("Durchlauf HH" + i, "seqHH_status[i] " + seqHH_status[i]);
if (seqHH_status[i] != 0 && !mute_hh_status)
switch (seqHH_status[i])
case 1:
soundPool.play(soundID_hh_1, volHH[i], volHH[i], 1, 0, 1f);
break;
case 2:
soundPool.play(soundID_hh_2, volHH[i], volHH[i], 1, 0, 1f);
break;
case 3:
soundPool.play(soundID_hh_3, volHH[i], volHH[i], 1, 0, 1f);
break;
case 4:
soundPool.play(soundID_hh_4, volHH[i], volHH[i], 1, 0, 1f);
break;
case 5:
soundPool.play(soundID_hh_5, volHH[i], volHH[i], 1, 0, 1f);
break;
case 6:
soundPool.play(soundID_hh_6, volHH[i], volHH[i], 1, 0, 1f);
break;
case 7:
soundPool.play(soundID_hh_7, volHH[i], volHH[i], 1, 0, 1f);
break;
case 8:
soundPool.play(soundID_hh_8, volHH[i], volHH[i], 1, 0, 1f);
break;
// Play SD if set
Log.i("Durchlauf SD" + i, "seqSD_status[i] " + seqSD_status[i]);
if (seqSD_status[i] != 0 && !mute_sd_status)
switch (seqSD_status[i])
case 1:
soundPool.play(soundID_sd_1, volSD[i], volSD[i], 1, 0, 1f);
break;
case 2:
soundPool.play(soundID_sd_2, volSD[i], volSD[i], 1, 0, 1f);
break;
case 3:
soundPool.play(soundID_sd_3, volSD[i], volSD[i], 1, 0, 1f);
break;
case 4:
soundPool.play(soundID_sd_4, volSD[i], volSD[i], 1, 0, 1f);
break;
case 5:
soundPool.play(soundID_sd_5, volSD[i], volSD[i], 1, 0, 1f);
break;
case 6:
soundPool.play(soundID_sd_6, volSD[i], volSD[i], 1, 0, 1f);
break;
case 7:
soundPool.play(soundID_sd_7, volSD[i], volSD[i], 1, 0, 1f);
break;
case 8:
soundPool.play(soundID_sd_8, volSD[i], volSD[i], 1, 0, 1f);
break;
// Play SND if set
Log.i("Durchlauf SND" + i, "seqSND_status[i] " + seqSND_status[i]);
if (seqSND_status[i] != 0 && !mute_snd_status)
switch (seqSND_status[i])
case 1:
soundPool.play(soundID_snd_1, volSND[i], volSND[i], 1, 0, 1f);
break;
case 2:
soundPool.play(soundID_snd_2, volSND[i], volSND[i], 1, 0, 1f);
break;
case 3:
soundPool.play(soundID_snd_3, volSND[i], volSND[i], 1, 0, 1f);
break;
case 4:
soundPool.play(soundID_snd_4, volSND[i], volSND[i], 1, 0, 1f);
break;
case 5:
soundPool.play(soundID_snd_5, volSND[i], volSND[i], 1, 0, 1f);
break;
case 6:
soundPool.play(soundID_snd_6, volSND[i], volSND[i], 1, 0, 1f);
break;
case 7:
soundPool.play(soundID_snd_7, volSND[i], volSND[i], 1, 0, 1f);
break;
case 8:
soundPool.play(soundID_snd_8, volSND[i], volSND[i], 1, 0, 1f);
break;
try
Thread.sleep(100);
catch (InterruptedException e)
e.printStackTrace();
);
// KICK-SEQ
if(seq_status)
btn_seq_play.setBackgroundResource(R.drawable.play);
seq_status = false;
seq_thread.interrupt();
else
btn_seq_play.setBackgroundResource(R.drawable.stop);
seq_status = true;
seq_thread.start();
;
【问题讨论】:
【参考方案1】:取决于音频文件的长度。 长音乐文件不太大以至于可以保存在内存中,适合媒体播放器。 0.02-5秒的短音:soundprool
还有用于流文件的 Audiotrack,但实现起来有点复杂。
试试这个......或者向我们展示代码的关键部分,也许你搞砸了,或者喜欢从主线程中进行调用或类似的事情
编辑:我的代码建议:
private View.OnClickListener seqPlay = new View.OnClickListener()
public void onClick(View v)
btn_seq_play = (ImageButton)findViewById(R.id.btn_seq_play);
if(!seq_Status)
Thread seq_thread = new Thread(new Runnable()
@Override
public void run()
// Do loop while seq_status==true
...
btn_seq_play.setBackgroundResource(R.drawable.stop);
seq_Thread.start();
else
btn_seq_play.setBackgroundResource(R.drawable.play);
seq_Status=!seq_Status;
现在你的线程将在下次他到达 while 循环的开头并检查 seq_Status 是否已更改为 false 时以 100 毫秒的最大反应死亡......我认为这样做是可以的
你可以在他睡觉之前做一个 if 来检查 seq_Status 是否已经改变,以便在它睡觉之前捕捉它
【讨论】:
您好,来自柏林; ) 你能提供你的隔音的初始化吗?你告诉他使用多少最大流量。 Hey Ilja :) .. 我对上面的线程进行了初始化.. 共有 32 个样本可以设置为 4 个音序器轨道(每个 8 个样本) 好的,我看到没有错误代码...除了您认为您的声音已加载是理所当然的,但好吧,此时这并不重要,只要您确定每个声音都已加载...我通常为每个声音设置一个布尔值,如果声音已正确加载,但没关系,如果您播放与媒体播放器不同的是未加载的声音,则声音池不介意...。贬值仅从 Android L 开始所以不要介意(谷歌得到了使用生成器而不是构造函数的想法)....尽管如此我没有解决您的问题的代码到目前为止看起来不错 一件事....当您加载声音时...在文档中是否说优先级标志(最后一个参数)应该设置为 1 以便将来可兼容并且它没有效果atm 还是感谢您查看我的问题和我的代码 ;)以上是关于Android - MediaPlayer/SoundPool 性能?的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )