【问题标题】:Android - MediaPlayer/SoundPool performance?Android - MediaPlayer/SoundPool 性能?
【发布时间】: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();
        }
    }
};

【问题讨论】:

    标签: android performance android-mediaplayer soundpool


    【解决方案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
    • 还是感谢您查看我的问题和我的代码 ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多