Я пытаюсь добиться плавного воспроизведения звука для приложения, которое должно воспроизводить сэмплы в быстрой последовательности. Я надеялся, что Cocos2d и CocosDenshion сделают это возможным, поскольку AVAudioPlayer не работает из-за проблем с задержкой, но у меня все еще возникают проблемы - эмулируемые здесь 16-ые ноты в конечном итоге звучат качающимися.
Я собираюсь пойти с RemoteIO или что-то в этом роде? Какой самый простой способ получить точную синхронизацию воспроизведения звуков в iOS, который мне понадобится для проекта?
Или использование CDAudioEngine playSound: функция - не самый эффективный способ, которым я мог бы заниматься с CocosDenshion?
Для загрузки двигателя:
[CDAudioManager sharedManager];
while ([CDAudioManager sharedManagerState] != kAMStateInitialised) {
[NSThread sleepForTimeInterval:0.1];
NSLog(@"Not init yet...");
}
CDSoundEngine *sse = [CDAudioManager sharedManager].soundEngine;
NSArray *defs = [NSArray arrayWithObjects:
[NSNumber numberWithInt:16],nil];
[sse defineSourceGroups:defs];
[[CDAudioManager sharedManager].soundEngine setSourceGroupNonInterruptible:0 isNonInterruptible:TRUE];
NSLog(@"Loading sound: %i",[sse loadBuffer:1 filePath:@"bass drum.wav"]);
[[CDAudioManager sharedManager] setResignBehavior:kAMRBStopPlay autoHandle:YES];
[[CDAudioManager sharedManager] setMode:(kAMM_MediaPlayback)];
Код потока для проверки воспроизведения (в основном пример приложения Metronome, отредактированный для использования воспроизведения CocosDenshion):
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Give the sound thread high priority to keep the timing steady.
[NSThread setThreadPriority:1.0];
BOOL continuePlaying = YES;
CDSoundEngine *sse = [CDAudioManager sharedManager].soundEngine;
while (continuePlaying) { // Loop until cancelled.
// An autorelease pool to prevent the build-up of temporary objects.
NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];
[sse playSound:1 sourceGroupId:0 pitch:1.0f pan:0.0f gain:1.0f loop:NO];
withObject:nil waitUntilDone:NO];
NSDate *curtainTime = [[NSDate alloc] initWithTimeIntervalSinceNow:0.125f];
NSDate *currentTime = [[NSDate alloc] init];
// Wake up periodically to see if we've been cancelled.
while (continuePlaying && ([currentTime compare:curtainTime] != NSOrderedDescending)) {
if ([soundPlayerThread isCancelled] == YES) {
continuePlaying = NO;
}
[NSThread sleepForTimeInterval:0.005];
[currentTime release];
currentTime = [[NSDate alloc] init];
}
[curtainTime release];
[currentTime release];
[loopPool drain];
}
[pool drain];