8

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

我像这样创建音轨:

AudioTrack tmpAudioTrack = new AudioTrack(
        STREAM_TYPE, 
        SAMPLE_RATE, 
        CHANNEL_CONFIG_TYPE, 
            AUDIO_FORMAT_TYPE, 
        getOptimalBufferSize(), 
        AUDIO_TRACK_MODE);'

并在后台线程中启动它:

backround_thread = new Thread(new MyRunnable(aTrack));
    backround_thread.start();   

我在可运行文件中写出这样的每个声音:

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

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

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

我不完全理解这些 API 的文档。每一帧都与样本相同吗?如何为每个声音的开始/结束位置指定一个标记?

谢谢,

4

1 回答 1

18

这是我发现的:

对我来说,帧就是样本——声音的持续时间乘以采样率。

要使用 AudioTrack.setPositionNotificationPeriod,您需要传递一定数量的样本。这意味着如果您传递 200 个样本,回调将每 200 个样本被调用一次,循环。

tmpAudioTrack.setPositionNotificationPeriod(duration * sampleRate);

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

tmpAudioTrack.setNotificationMarkerPosition(duration * sampleRate);

但是,如果你已经在播放,在你的音轨中间,并且想要添加一个标记以便你会在 3 秒后被回调,那么你需要添加音轨的当前播放头,比如这个:(你的持续时间是 3 秒)

tmpAudioTrack.setNotificationMarkerPosition(tmpAudioTrack.getPlaybackHeadPosition() + (duration * sampleRate));

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

tmpAudioTrack.setPlaybackPositionUpdateListener(new OnPlaybackPositionUpdateListener(){

    @Override
    public void onMarkerReached(AudioTrack arg0) {

    }

    @Override
    public void onPeriodicNotification(AudioTrack arg0) {

    }

});
于 2012-09-11T23:29:06.877 回答