Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/213.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java AudioTrack中的播放结束检测不起作用_Java_Android_Audio_Audiotrack - Fatal编程技术网

Java AudioTrack中的播放结束检测不起作用

Java AudioTrack中的播放结束检测不起作用,java,android,audio,audiotrack,Java,Android,Audio,Audiotrack,这是我正在使用的代码: void playSound(){ final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length, AudioTrack.MO

这是我正在使用的代码:

void playSound(){
    final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
            sampleRate, AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length,
            AudioTrack.MODE_STATIC);
    // audioTrack.setNotificationMarkerPosition(generatedSnd.length/2);
    audioTrack.setNotificationMarkerPosition(1);
    audioTrack.setPlaybackPositionUpdateListener(new AudioTrack.OnPlaybackPositionUpdateListener() {
        @Override
        public void onPeriodicNotification(AudioTrack track) {
            // nothing to do
        }

        @Override
        public void onMarkerReached(AudioTrack track) {
            // Log.d(LOG_TAG, "Audio track end of file reached...");
            // messageHandler.sendMessage(messageHandler.obtainMessage(PLAYBACK_END_REACHED));
            Log.d("MY LOG", "Audio track end of file reached...");
            bitPatternValTextView.setText("End of play");
        }
    });
    audioTrack.write(generatedSnd, 0, generatedSnd.length);
    audioTrack.play();
}  
playSound()
函数在内部定义

公共类不活动扩展了ActionBarActivity{…}

我的假设是,当音轨的播放达到第N个音频样本时(每个N是一个短的或2个字节),然后
AudioTrack.setNotificationMarkerPosition(N)
将导致调用
onMarkerReached(音频曲目)
。然而,正如我的示例代码所示,我尝试了
generatedSnd.length/2
(generatedSnd[]是一个包含我要播放的音频样本的字节数组)以及使用小常量值,如1、10或20,并且
onMarkerReached()
在这些情况下似乎都不会被调用。这里出了什么问题,我该如何解决?我想在当前音轨播放完毕后能够播放另一个声音。playSound()函数本身将在线程中调用(与UI线程分离)

下面是我获取代码的来源:

其他参考资料:


回答可能太迟了,但这对我来说很有效。我也没有得到markerreached()回调。 我只是将静态流的大小增加了很多。可能不适用于模式_流或不同的缓冲区大小。适用于我需要的所有缓冲区大小,对于我的用例来说,缓冲区大小最多只有10秒。 尝试更改代码中的这一行,看看会发生什么:

int magic_number = 1000; // try with different values. Maybe make it 10% of generatedSnd.length?
final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
        sampleRate, AudioFormat.CHANNEL_OUT_MONO,
        AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length,
        AudioTrack.MODE_STATIC + magic_number);

您应该使用setNotificationMarkerPosition而不是1来表示文件长度的帧数。顺便说一句,它应该是一个很大的数字。1只是一个测试数字,如果它起作用,我应该在日志中看到一些通知。如果你使用单独的线程,尝试MODE_STREAM,并在循环中馈送AudioTrack,直到dataok结束,这似乎是可行的,但为什么它不适用于静态?馈送AudioTrack是什么意思?我在generatedSnd阵列中有我需要生成的所有音频样本,我认为最好以静态方式播放所有内容