AudioTrack - 如何知道声音何时开始/结束?

mik*_*eli 8 android marker audiotrack

我正在使用音频轨道以流模式播放不同的声音.我想知道是否有办法知道每个声音的生命/结束时间.

我像这样创建音轨:

AudioTrack tmpAudioTrack = new AudioTrack(
        STREAM_TYPE, 
        SAMPLE_RATE, 
        CHANNEL_CONFIG_TYPE, 
            AUDIO_FORMAT_TYPE, 
        getOptimalBufferSize(), 
        AUDIO_TRACK_MODE);'
Run Code Online (Sandbox Code Playgroud)

并在后台线程中启动它:

backround_thread = new Thread(new MyRunnable(aTrack));
    backround_thread.start();   
Run Code Online (Sandbox Code Playgroud)

我在runnable中写出这样的每个声音:

byte generatedSnd[] = new byte[2 * beepSamples];
<code for filling the buffer with sound here>
int bytesWritten = track.write(generatedSnd, 0, generatedSnd.length);
Run Code Online (Sandbox Code Playgroud)

可以使用任何AudioTrack API,如setNotificationMarkerPosition,setLoopPoints或setPositionNotificationPeriod来完成此操作吗?它们是如何工作的?

每个声音可以是不同的持续时间.我认为这是关键.

我不完全理解这些API的文档.每个框架是否与样本相同?如何为每个声音的开始/结束位置指定标记?

谢谢,

mik*_*eli 15

这是我发现的:

对我而言,帧是样本 - 声音的持续时间乘以采样率.

要使用AudioTrack.setPositionNotificationPeriod,您需要传递一定数量的样本.这意味着如果您传递200个样本,则每200个样本将调用一次回调,并且会重复.

tmpAudioTrack.setPositionNotificationPeriod(duration * sampleRate);
Run Code Online (Sandbox Code Playgroud)

要使用.setNotificationMarkerPosition,您还要传递一定数量的样本.但是,这是绝对的,而不是像期间API那样相关.因此,如果您想确定声音何时结束,则传递样本量(总声道持续时间*sampleRate).

tmpAudioTrack.setNotificationMarkerPosition(duration * sampleRate);
Run Code Online (Sandbox Code Playgroud)

但是,如果你已经在你的音轨中间播放,并且想要添加一个标记,那么你将被叫回来让我们说从现在开始3秒,那么你需要添加音轨的当前播放头,就像这个:(你的持续时间是3秒)

tmpAudioTrack.setNotificationMarkerPosition(tmpAudioTrack.getPlaybackHeadPosition() + (duration * sampleRate));
Run Code Online (Sandbox Code Playgroud)

这是您注册期间和标记通知的方式:

tmpAudioTrack.setPlaybackPositionUpdateListener(new OnPlaybackPositionUpdateListener(){

    @Override
    public void onMarkerReached(AudioTrack arg0) {

    }

    @Override
    public void onPeriodicNotification(AudioTrack arg0) {

    }

});
Run Code Online (Sandbox Code Playgroud)