gpt4 book ai didi

iphone - 如何在 iPhone 上编写实时准确的音频音序器?

转载 作者:行者123 更新时间:2023-12-03 18:18:27 26 4
gpt4 key购买 nike

我想在 iPhone 上编写一个简单的音频音序器,但我无法获得准确的计时。最近几天,我在 iPhone 上尝试了所有可能的音频技术,从 AudioServicesPlaySystemSound 和 AVAudioPlayer 以及 OpenAL 到 AudioQueues。

在我的最后一次尝试中,我尝试了 CocosDenshion 声音引擎,它使用 openAL 并允许将声音加载到多个缓冲区中,然后在需要时播放它们。这是基本代码:

初始化:

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;

}

就是这样,它按应有的方式工作,但时间不稳定且不稳定。一旦发生其他事情(例如在 View 中绘图),它就会失去同步。

据我了解声音引擎和 openAL,缓冲区已加载(在初始化代码中),然后准备立即使用 alSourcePlay(source); 启动 - 所以问题可能出在 NSTimer 上?

现在应用商店里有几十个声音音序器应用程序,它们都有准确的计时。 I.g.当缩放和绘图完成时,“idrum”即使在 180 bpm 的情况下也具有完美稳定的节拍。所以必须有一个解决方案。

有人知道吗?

感谢您提前提供的任何帮助!

最诚挚的问候,

瓦尔奇

<小时/>

谢谢你的回答。它使我更进一步,但不幸的是没有达到目标。这是我所做的:

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];
}
}

在序列循环中,我将线程优先级设置为尽可能高,并进入无限循环。播放声音后,我计算下一个节拍的下一个绝对时间,并将线程发送到 sleep 状态,直到此时。

这再次有效,并且比我没有 NSThread 的尝试更稳定,但如果发生其他情况,尤其是 GUI 的东西,它仍然不稳定。

有没有办法在 iPhone 上使用 NSThread 获得实时响应?

最诚挚的问候,

瓦尔奇

最佳答案

NSTimer 绝对不能保证它何时触发。它会在运行循环上自行安排触发时间,并且当运行循环到达计时器时,它会查看是否有任何计时器过期。如果是这样,它就会运行它们的选择器。非常适合各种任务;对这个没用。

第一步是您需要将音频处理移至其自己的线程并脱离 UI 线程。对于计时,您可以使用普通的 C 方法构建自己的计时引擎,但我会首先查看 CAAnimation,尤其是 CAMediaTiming。

请记住,Cocoa 中有许多东西被设计为仅在主线程上运行。例如,不要在后台线程上执行任何 UI 工作。一般来说,请仔细阅读文档以了解他们对线程安全的看法。但一般来说,如果线程之间没有大量通信(在我看来,大多数情况下不应该有),那么线程在 Cocoa 中非常容易。看看 NSThread。

关于iphone - 如何在 iPhone 上编写实时准确的音频音序器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/907137/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com