2012-08-02 94 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