2012-09-07 237 views
7

我正在使用音频轨道以流模式播放不同的声音。 我想知道是否有方法知道每个声音的生命/结束时间。AudioTrack - 如何知道声音何时开始/结束?

我创建的音轨是这样的:

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或se tPositionNotificationPeriod完成此任务吗?他们是如何工作的?

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

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

谢谢,

+0

至少有人知道setNotificationMarkerPosition和setPositionNotificationPeriod之间的区别吗? – mikemeli

回答

12

这就是我所发现的。

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

要使用AudioTrack setPositionNotificationPeriod,您需要传递一定数量的样本。意思是如果你通过200个样本,回调将被称为每200个样本,经常性的。

tmpAudioTrack.setPositionNotificationPeriod(duration * sampleRate); 

要使用setNotificationMarkerPosition,还需要传递一定数量的样本。但是,这是绝对的,并不像期间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) { 

    } 

});