2012-08-02 96 views
6

我有一个使用文件播放器音频单元播放,暂停和停止音频文件的程序。我完成这个任务的方式是初始化文件播放器音频单元以在零位播放文件,然后当用户按下暂停按钮时,停止AUGraph,捕获当前位置,然后将该位置用作起始位置当用户按下播放按钮时。一切都按照它应该的方式工作,但是我每隔3到4次打一个停顿然后弹奏,这首歌开始播放一半到整整一秒,然后我停下来。在IOS核心音频中,如何找到文件播放器音频单元的当前播放头位置?

我不明白为什么会发生这种情况,你们有没有任何想法?这里是我的代码的简化版本。

//initialize AUGraph and File player Audio unit 
... 
... 
... 

//Start AUGraph 
... 
... 
... 

// pause playback 
- (void) pauseAUGraph { 

//first stop the AuGrpah 
     result = AUGraphStop (processingGraph); 

// get current play head position   
     AudioTimeStamp ts; 
     UInt32 size = sizeof(ts); 

     result = AudioUnitGetProperty(filePlayerUnit, 
             kAudioUnitProperty_CurrentPlayTime, kAudioUnitScope_Global, 0, &ts, 
             &size); 
     //save our play head position for use later 
     //must add it to itself to take care of multiple presses of the pause button 
     sampleFrameSavedPosition = sampleFrameSavedPosition + ts.mSampleTime; 


     //this stops the file player unit from playing 
     AudioUnitReset(filePlayerUnit, kAudioUnitScope_Global, 0); 
     NSLog (@"AudioUnitReset - stopped file player from playing"); 

    //all done  
} 


// Stop playback 

- (void) stopAUGraph { 
     // lets set the play head to zero, so that when we restart, we restart at the beginning of the file. 

      sampleFrameSavedPosition = 0; 
     //ok now that we saved the current pleayhead position, lets stop the AUGraph 
     result = AUGraphStop (processingGraph); 
} 
+0

音频文件是什么格式? – 2013-05-09 18:25:05

+0

他们是m4a文件。 – Beleg 2013-05-09 21:40:22

+0

好吧,我不是音频压缩方面的专家,但是文件往往会被压缩成块,而当您寻找它时,可能会到最近的块而不是实际的位置。如果我遇到任何更明确的问题,我会发布一个答案。 – 2013-05-10 07:35:13

回答

0

这可能是由于舍入你的代码的问题:

例如,如果你每次按下暂停键,你的计时器将在0.5/4秒钟内你的实际暂停时间之前记录,你仍然会看到期望的结果。但重复四次后,您创建的空间量是0.5/4倍,这是您似乎正在经历的一秒半。

因此,我会仔细关注您使用的对象类型,并确保它们不会不适当地圆角。尝试使用double float作为您的采样时间,试图缓解该问题!

希望这是明确的和有益的! :)

+0

我正在使用float64将audioTimeStamp.mSampletime存储到sampleFrameSavedPosition中,因此不应该有任何舍入错误。我注意到,当我通过设置ScheduledAudioFileRegion.mStartFrame来启动AuGraph时,ScheduledAudioFileRegion.mStartFrame是一个UInt32而不是一个float64,当我测试我的程序并打印mSampleTime的值时,它总是一个整数,所以它不应该母校。 – Beleg 2013-05-08 01:24:23

+0

然后在理论上,如果你所有的类型都是整数,它甚至不应该输出一个分数。你是否每次都尝试输出头部位置,看看它是否加起来? – wayway 2013-05-08 14:08:10

1

可能你应该使用数据包计数,而不是时间戳,因为你只是想暂停和播放音乐,而不是显示时间信息。

有关使用此方法的示例,请参阅BufferedAudioPlayer

+0

所以你建议使用rendercallback而不是文件播放器的音频单元和计数包而不是使用时间戳?今晚我会试一试。 – Beleg 2013-05-13 12:22:14

+0

是的。我在多个项目中成功地使用了它。 Audiograph(https://github.com/tkzic/audiograph)是另一个采用相同方法的例子。该项目也带有一本很好的手册。 – Totoro 2013-05-14 01:19:53