我想在iPhone上編程一個簡單的音頻音序器,但我無法獲得準確的時間。最後幾天,我嘗試了所有可能的iPhone音頻技術,從AudioServicesPlaySystemSound和AVAudioPlayer以及OpenAL到AudioQueues。如何在iphone上編寫實時精確的音頻音序器?
在我上次的嘗試中,我嘗試了使用openAL的CocosDenshion聲音引擎,並允許將聲音加載到多個緩衝區,然後在需要時播放它們。這是基本的代碼:
初始化:
int channelGroups[1];
channelGroups[0] = 8;
soundEngine = [[CDSoundEngine alloc] init:channelGroups channelGroupTotal:1];
int i=0;
for(NSString *soundName in [NSArray arrayWithObjects:@"base1", @"snare1", @"hihat1", @"dit", @"snare", nil])
{
[soundEngine loadBuffer:i fileName:soundName fileType:@"wav"];
i++;
}
[NSTimer scheduledTimerWithTimeInterval:0.14 target:self selector:@selector(drumLoop:) userInfo:nil repeats:YES];
在我創建聲音引擎的初始化,加載一些聲音,不同的緩衝區,然後用的NSTimer建立序循環。
音頻迴路:
- (void)drumLoop:(NSTimer *)timer
{
for(int track=0; track<4; track++)
{
unsigned char note=pattern[track][step];
if(note)
[soundEngine playSound:note-1 channelGroupId:0 pitch:1.0f pan:.5 gain:1.0 loop:NO];
}
if(++step>=16)
step=0;
}
這就是它和它的作品,因爲它應該,但時間是不穩固和不穩定。一旦發生其他事情(例如在視圖中繪製),它就會失去同步。
據我瞭解聲音引擎和openAL緩衝區加載(在init代碼中),然後準備立即開始與alSourcePlay(source);
- 所以問題可能與NSTimer?
現在,在appstore中有數十個音序器應用程序,它們具有準確的時序。胃內變焦和繪圖完成後,即使在180 bpm時,「idrum」也有完美的穩定拍子。所以必須有一個解決方案。
有人有什麼想法嗎?
感謝您提前提供任何幫助!
最好的問候,
Walchy
謝謝您的回答。它讓我更進一步,但不幸的是沒有達到目標。下面是我做的:
nextBeat=[[NSDate alloc] initWithTimeIntervalSinceNow:0.1];
[NSThread detachNewThreadSelector:@selector(drumLoop:) toTarget:self withObject:nil];
在初始化我店下一個節拍的時間,並創建一個新的線程。
- (void)drumLoop:(id)info
{
[NSThread setThreadPriority:1.0];
while(1)
{
for(int track=0; track<4; track++)
{
unsigned char note=pattern[track][step];
if(note)
[soundEngine playSound:note-1 channelGroupId:0 pitch:1.0f pan:.5 gain:1.0 loop:NO];
}
if(++step>=16)
step=0;
NSDate *newNextBeat=[[NSDate alloc] initWithTimeInterval:0.1 sinceDate:nextBeat];
[nextBeat release];
nextBeat=newNextBeat;
[NSThread sleepUntilDate:nextBeat];
}
}
在順序循環中,我將線程優先級設置爲儘可能高,並進入無限循環。在播放聲音之後,我計算下一個節拍的下一個絕對時間,並將線程發送到睡眠直到這個時間。
再次這個工作,它比我沒有NSThread嘗試更穩定,但它仍然搖搖欲墜,如果發生其他事情,特別是GUI的東西。
有沒有辦法通過iphone上的NSThread獲得實時響應?
最好的問候,
Walchy
我覺得@Walchy現在出去吃午飯......不知道哪他最終選擇這樣做的方式? – 2014-10-17 04:14:40
不幸的是,我不能發佈示例代碼,但對於應用商店中的Playback應用,我們使用回調來提供從文件中讀取的音頻數據。每個文件都具有相同的音頻特徵,所以爲了提供精確的時序,我們只是跳到音頻文件數據中的那個採樣點。它超級準確(下載應用程序並獲得當天的免費遊戲)。我們可以循環部分並跳轉到文件中的部分,同時一次播放20個以上的曲目(尚未達到曲目限制)。 – 2015-10-29 17:49:07