[英]How to stop an audio file from looping in Apple's MixerHost Core Audio Example
我有一個應用程序,允許用戶使用音頻單元錄制節拍。 為了實現這一點,我從Apple的MixerHost示例代碼中修改了Mixer類。
目前我的聲音文件循環,我想停止。 我希望用戶能夠在聲音文件通過后保存混音。
循環的原因是inputrendercallback
函數的以下部分的最后一行中的for loop
:
for (UInt32 frameNumber = 0; frameNumber < inNumberFrames; ++frameNumber) {
outSamplesChannelLeft[frameNumber] = dataInLeft[sampleNumber];
if (isStereo) outSamplesChannelRight[frameNumber] = dataInRight[sampleNumber];
sampleNumber++;
// After reaching the end of the sound stored in memory--that is, after
// (frameTotalForSound / inNumberFrames) invocations of this callback--loop back to the
// start of the sound so playback resumes from there.
if (sampleNumber >= frameTotalForSound) sampleNumber = 0;
}
我意識到我需要改變if (sampleNumber >= frameTotalForSound) sampleNumber = 0;
為了告訴回調一旦樣本用盡就停止請求樣本,但是我在調用目標C中的方法比調整這個C-Struct要舒服得多。
有沒有人對如何做到這一點有任何想法?
謝謝。
我只能想象許多人一定遇到過這個音頻文件循環問題,因為MixerHost是Apple提供的少數幾個Core Audio示例之一。
我使用NSNotificationCenter解決了這個問題。 在譴責在C函數中使用Objective C之前,請注意我通過在MixerHost示例中模仿Apple代碼的其他部分來找到此解決方案。 例如,要暫停程序並指示已拔下耳機,或者設備已從底座連接器中移除,Apple會在MixerHostAudio類的audioRouteChangeListenerCallback
使用通知中心:
if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) {
NSLog (@"Audio output device was removed; stopping audio playback.");
NSString *MixerObjectPlaybackStateDidChangeNotification = @"MixerObjectPlaybackStateDidChangeNotification";
[[NSNotificationCenter defaultCenter] postNotificationName: MixerObjectPlaybackStateDidChangeNotification object: audioObject];
我還決定在inputrendercallback
函數中發布通知:
for (UInt32 frameNumber = 0; frameNumber < inNumberFrames; ++frameNumber) {
if (sampleNumber == frameTotalForSound) {
NSString *AudioFileFinishedPlaying = @"AudioFileFinishedPlaying";
[[NSNotificationCenter defaultCenter] postNotificationName: AudioFileFinishedPlaying object: nil];
}
outSamplesChannelLeft[frameNumber] = dataInLeft[sampleNumber];
if (isStereo) outSamplesChannelRight[frameNumber] = dataInRight[sampleNumber];
sampleNumber++;
...
然后我在程序的另一部分中使用addObserver:selector:name:object:
方法來停止循環並執行與我的應用程序密切相關的其他任務。
我希望這有用。 如果有人有更好的解決方案,那么我願意接受它。 謝謝。
您不應在音頻處理或緩沖區回調的內部循環中使用任何Objective C消息。 沒有理由太多的周期開銷。 堅持在C結構中使用內在的C類型。 設置標志變量是可以的。 稍后在回調和內部音頻樣本循環之外進行任何所需的對象消息傳遞。
感謝您發布解決方案,它的工作原理與Apple宣布其他通知的方式並不矛盾。 幾點說明:
如果您要混合多個文件,這將在最短文件到達時停止播放器。
我嘗試了以下代碼(假設inputrendercallback函數的其余部分未更改):
if(sampleNumber> = frameTotalForSound){NSLog(@“Reached the end!”); THIS.stopAUGraph; sampleNumber = 0; //如果有人想再玩一次}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.