ãµãŠã³ããæ±ããšããç¹ã§ã¯ãAppleã¯ç«¶åä»ç€Ÿãããå ãè¡ã£ãŠãããããã¯å¶ç¶ã§ã¯ãããŸããã å瀟ã¯ããã©ãã¯ã®åçãé²é³ãåŠçã®ããã®åªããããŒã«ãæäŸããŠããŸãã ããã«ãããAppStoreã«ã¯ããªãŒãã£ãªã³ã³ãã³ããšäœããã®åœ¢ã§æ©èœããèšå€§ãªæ°ã®ã¢ããªã±ãŒã·ã§ã³ã衚瀺ãããŸãã ãããã«ã¯ãåªãããµãŠã³ããæã€ãã¬ãŒã€ãŒïŒ Vox ïŒããšãã§ã¯ãã®ç·šéããã³é©çšçšã®ããŒã«ãåãããªãŒãã£ãªãšãã£ã¿ãŒïŒ Sound Editor ïŒãé³å£°å€æŽã¢ããªã±ãŒã·ã§ã³ïŒ Voicy Helium ïŒã察å¿ãããµãŠã³ããããªãæ£ç¢ºã«æš¡å£ãã楜åšã®ããŸããŸãªã·ãã¥ã¬ãŒã¿ãŒïŒ Virtuoso Piano ïŒãå«ãŸããŸããããã«ã¯DJã€ã³ã¹ãã¬ãŒã·ã§ã³ã®ã·ãã¥ã¬ãŒã¿ãŒïŒ X Djing ïŒã

Appleã¯ããªãŒãã£ãªãæäœããããã«ãããã€ãã®ããŒã«ãçµã¿åãããAVFoundationãã¬ãŒã ã¯ãŒã¯ãæäŸããŠããŸãã ããšãã°ãAVAudioPlayerã¯åäžã®ãã©ãã¯ãåçããããã«äœ¿çšãããAVAudioRecorderã¯ãã€ã¯ããã®é³ãé²é³ããããã«äœ¿çšãããŸãã ãããŠããããã®ã¯ã©ã¹ãæäŸããæ©èœã®ã¿ãå¿ èŠãªå Žåã¯ããããã䜿çšããŠãã ããã ãšãã§ã¯ããé©çšããããè€æ°ã®ãã©ãã¯ãåæã«åçããããããã¯ã¹ãããããªãŒãã£ãªã®åŠçãç·šéãè¡ã£ãããç¹å®ã®ãªãŒãã£ãªããŒãã®åºåãããµãŠã³ããé²é³ãããããå¿ èŠãããå Žåã¯ã AVAudioEngineã圹ç«ã¡ãŸãã äœãããããã®ã¯ã©ã¹ã¯ãã©ãã¯ã«ãšãã§ã¯ãããããèœåã«æ¹ãããŸãã ã€ã³ã©ã€ã¶ãŒãšé³å£°ãå€æŽããæ©èœãåããå€ãã®ã¢ããªã±ãŒã·ã§ã³ã¯ããããã®å¹æã«åºã¥ããŠæ§ç¯ãããŠããŸãã ããã«ãAppleã¯éçºè ãç¬èªã®ãšãã§ã¯ãããµãŠã³ããžã§ãã¬ãŒã¿ãŒãããã³ã€ã³ã¹ãã¥ã«ã¡ã³ããäœæã§ããããã«ããŸãã
äž»ãªèŠçŽ ãšãã®é¢ä¿
ã¡ã€ã³ã®AVAudioEngineãšã³ãžã³ããå§ããŸãããã ãã®ãšã³ãžã³ã¯ããªãŒãã£ãªä¿¡å·ãçæããã³åŠçãããªãŒãã£ãªå ¥åããã³åºåãè¡šããªãŒãã£ãªããŒãæ¥ç¶ã®ã°ã«ãŒãã§ãã æãŸããçµæãéæããããã«ç¹å®ã®æ¹æ³ã§é 眮ããããªãŒãã£ãªããŒãã®å³ãšããŠèª¬æããããšãã§ããŸãã ã€ãŸããAVAudioEngineã¯ããã€ã¯ãåè·¯ïŒãã®å Žåã¯ãªãŒãã£ãªããŒãïŒãé 眮ããããã¶ãŒããŒãã§ãããšèšããŸãã
ããã©ã«ãã§ã¯ããšã³ãžã³ã¯ãªãŒãã£ãªããã€ã¹ã«æ¥ç¶ããããªã¢ã«ã¿ã€ã ã§èªåçã«ã¬ã³ããªã³ã°ãããŸãã ãŸããæåã¢ãŒãã§åäœããããã«æ§æããããšãã§ããŸããã€ãŸããããã€ã¹ã«æ¥ç¶ããã«ãã¯ã©ã€ã¢ã³ãããã®èŠæ±ã«å¿çããŠãéåžžã¯ãªã¢ââã«ã¿ã€ã ã§ããŸãã¯ããã«é«éã«ã¬ã³ããªã³ã°ããŸãã
ãã®ã¯ã©ã¹ã䜿çšããå Žåããã¹ãŠã®æäœãæ£ããå®è¡ãããããã«ãç¹å®ã®é åºã§åæåãšã¡ãœãããå®è¡ããå¿ èŠããããŸãã ã¢ã€ãã ã«å¯Ÿããäžé£ã®ã¢ã¯ã·ã§ã³ã¯æ¬¡ã®ãšããã§ãã
- ãŸãããªãŒãã£ãªã»ãã·ã§ã³AVAudioSessionãèšå®ããŸãã
- ãšã³ãžã³ãäœæããŸãã
- AVAudioNodeããŒããåå¥ã«äœæããŸãã
- ããŒãããšã³ãžã³ã«æ¥ç¶ããŸãïŒæ¥ç¶ïŒã
- ããŒãå士ãæ¥ç¶ããŸãïŒæ¥ç¶ããŸãïŒã
- ãšã³ãžã³ãå§åããŸãã
1.ãªãŒãã£ãªã»ãã·ã§ã³ã®ã»ããã¢ãã
ãªãŒãã£ãªã»ãã·ã§ã³ãèšå®ããªããšãã¢ããªã±ãŒã·ã§ã³ãæ£åžžã«åäœããªãã£ãããé³å£°ããŸã£ããèãããªãã£ããããŸãã æ§ææé ã®å ·äœçãªãªã¹ãã¯ããšã³ãžã³ãã¢ããªã±ãŒã·ã§ã³ã§å®è¡ããæ©èœïŒèšé²ãåçããŸãã¯ãã®äž¡æ¹ïŒã«ãã£ãŠç°ãªããŸãã 次ã®äŸã§ã¯ããªãŒãã£ãªã»ãã·ã§ã³ãåçã®ã¿ã«èšå®ããŸãã
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; [[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil]; [[AVAudioSession sharedInstance] setActive:YES error:nil];
é²é³çšã«èšå®ããã«ã¯ãã«ããŽãªAVAudioSessionCategoryRecordãèšå®ããå¿ èŠããããŸãã ãã¹ãŠã®ã«ããŽãªã¯ãã¡ãããå ¥æã§ããŸã ã
2.ãšã³ãžã³ã®äœæ
ãã®ãšã³ãžã³ãæ©èœããã«ã¯ãAVFoundationãã¬ãŒã ã¯ãŒã¯ãã€ã³ããŒãããŠã¯ã©ã¹ãåæåããå¿ èŠããããŸãã
#import <AVFoundation/AVFoundation.h>
åæåã¯æ¬¡ã®ãšããã§ãã
AVAudioEngine *engine = [[AVAudioEngine alloc] init];
3.ããŒãã®äœæ
AVAudioEngineã¯ãããã«æ¥ç¶ãããŠããAVAudioNodeã¯ã©ã¹ã®ããŸããŸãªåã¯ã©ã¹ã§åäœããŸãã ããŒãã«ã¯å ¥åãã¹ãšåºåãã¹ããããæ¥ç¶ãã€ã³ããšèŠãªãããšãã§ããŸãã ããšãã°ããšãã§ã¯ãã«ã¯éåžž1ã€ã®å ¥åãã¹ãš1ã€ã®åºåãã¹ããããŸãã ãã¹ã«ã¯ãAudioStreamBasicDescriptionã®åœ¢åŒã§è¡šç€ºããã圢åŒããã ããµã³ããªã³ã°åšæ³¢æ°ããã£ãã«æ°ãªã©ã®ãã©ã¡ãŒã¿ãŒãå«ãŸããŸãã ããŒãéã®æ¥ç¶ãäœæããããšãã»ãšãã©ã®å Žåããããã®åœ¢åŒã¯äžèŽããã¯ãã§ãããäŸå€ããããŸãã
ãªãŒãã£ãªããŒãã®åã¿ã€ããåå¥ã«æ€èšããŠãã ããã
ãªãŒãã£ãªããŒãã®æãäžè¬çãªã¿ã€ãã¯AVAudioPlayerNodeã§ãã ååã瀺ãããã«ããã®çš®é¡ã¯ãªãŒãã£ãªã®åçã«äœ¿çšãããŸãã ããŒãã¯ãæå®ãããAVAudioBufferãã¥ãŒãããã¡ãŒãŸãã¯AVAudioFileã«ãã£ãŠéããããªãŒãã£ãªãã¡ã€ã«ã®ã»ã°ã¡ã³ããããµãŠã³ããåçããŸãã ãããã¡ãšã»ã°ã¡ã³ãã¯ãç¹å®ã®ãã€ã³ãã§åçããããã«ã¹ã±ãžã¥ãŒã«ããããšããåã®ã»ã°ã¡ã³ãã®çŽåŸã«åçããããšãã§ããŸãã
åæåãšåçã®äŸïŒ
AVAudioPlayerNode *playerNode = [[AVAudioPlayerNode alloc] init]; ⊠NSURL *url = [[NSBundle mainBundle] URLForResource:@"sample" withExtension:@"wav"]; AVAudioFile *audioFile = [[AVAudioFile alloc] initForReading:url error:nil]; [playerNode scheduleFile:audioFile atTime:0 completionHandler:nil]; [playerNode play];
次ã«ãAVAudioNodeã¯ã©ã¹ã®åã§ãããAVAudioUnitã¯ã©ã¹ã«ã€ããŠèããŸãã AVAudioUnitEffectïŒAVAudioUnitã®åã¯ã©ã¹ïŒã¯ããšãã§ã¯ãã¯ã©ã¹ã®å±ã¯ã©ã¹ãšããŠæ©èœããŸãã æãäžè¬çã«äœ¿çšããããšãã§ã¯ãã¯ãAVAudioUnitEQïŒã€ã³ã©ã€ã¶ãŒïŒãAVAudioUnitDelayïŒé 延ïŒãAVAudioUnitReverbïŒãšã³ãŒå¹æïŒãããã³AVAudioUnitTimePitchïŒå éãŸãã¯æžéå¹æããããïŒã§ãã ããããã«ããµãŠã³ããå€æŽããã³åŠçããããã®ç¬èªã®èšå®ã»ããããããŸãã
é 延å¹æã®äŸã«å¯Ÿããå¹æã®åæåãšèª¿æŽïŒ
AVAudioUnitDelay *delay = [[AVAudioUnitDelay alloc] init]; delay.delayTime = 1.0f;// , 0 2
次ã®ããŒãAVAudioMixerNodeã¯ãããã·ã³ã°ã«äœ¿çšãããŸãã å³å¯ã«1ã€ã®å ¥åããŒããæã€ä»ã®ããŒããšã¯ç°ãªãããããµãŒã«ã¯è€æ°ã®å ¥åããŒããå«ããããšãã§ããŸãã ããã§ã¯ããã¬ãŒã€ãŒããŒãããšãã§ã¯ãããŒããšã€ã³ã©ã€ã¶ãŒãšçµã¿åãããŠãããŒãåºåãæ¢ã«AVAudioOutputNodeã«æ¥ç¶ãããŠãæçµçãªãµãŠã³ããåºåã§ããŸãã
ãããµãŒãšåºåããŒããåæåããäŸïŒ
AVAudioMixerNode *mixerNode = [[AVAudioMixerNode alloc] init]; AVAudioOutputNode *outputNode = engine.outputNode;
4.ãšã³ãžã³ãžã®ããŒãã®æ¥ç¶
ãã ããããŒãã宣èšããã ãã§ã¯æ©èœããŸããã ãšã³ãžã³ã«æ¥ç¶ããå ¥åºåãã¹ãä»ããŠä»ã®ããŒãã«æ¥ç¶ããå¿ èŠããããŸãã ãã®ãšã³ãžã³ã¯ãèµ·åæã«ããŒãã®åçãªæ¥ç¶ãåæãåé€ãããããªå¶éä»ãã§ãµããŒãããŸãã
- ãã¹ãŠã®åçåæ¥ç¶ã¯ããããµãŒããŒãã®åã§çºçããå¿ èŠããããŸãã
- éåžžããšãã§ã¯ããåé€ãããšãé£æ¥ããããŒããèªåçã«çµåãããŸãããå ¥åãã£ãã«ãšåºåãã£ãã«ã®æ°ãç°ãªãããŒããŸãã¯ãããµãŒãåé€ãããšãã°ã©ããç Žæããå¯èœæ§ããããŸãã
ããŒãããšã³ãžã³ã«æ¥ç¶ããã«ã¯ãattachNodeïŒãã¡ãœããã䜿çšããããšã³ãžã³ãããã¿ããããã«ã¯ãdetachNodeïŒãã䜿çšãããŸãã
[engine attachNode:playerNode]; [engine detachNode:delay];
5.ããŒãå士ã®æ¥ç¶
æ¥ç¶ããããã¹ãŠã®ããŒãã¯ããµãŠã³ãåºåã®ããã«å ±éã®åè·¯ã«æ¥ç¶ããå¿ èŠããããŸãã æ¥ç¶ã¯ãåºåããå 容ã«ãã£ãŠç°ãªããŸãã ãšãã§ã¯ããå¿ èŠã§ã-ãšãã§ã¯ãããŒãããã¬ãŒã€ãŒããŒãã«æ¥ç¶ãã2ã€ã®ãã©ãã¯ãçµåããå¿ èŠããããŸã-2ã€ã®ãã¬ãŒã€ãŒããŒãããããµãŒã«æ¥ç¶ããŸãã ãŸãã¯ã2ã€ã®åå¥ã®ãã©ãã¯ãå¿ èŠãªå ŽåããããŸãã1ã€ã¯ã¯ãªã¢ãªãµãŠã³ãã§ããã1ã€ã¯åŠçæžã¿ã®ãµãŠã³ãã§ãã æ¥ç¶é åºã¯ããã»ã©éèŠã§ã¯ãããŸããããæ¥ç¶ã·ãŒã±ã³ã¹ã¯æçµçã«ã¡ã€ã³ãããµãŒã«æ¥ç¶ããã¡ã€ã³ãããµãŒã¯ãªãŒãã£ãªåºåããŒãã«æ¥ç¶ããå¿ èŠããããŸãã äŸå€ã¯å ¥åããŒãã§ããããã¯éåžžããã€ã¯ããã®é²é³ã«äœ¿çšãããŸãã
å³ãšã³ãŒãã®åœ¢åŒã§äŸã瀺ããŸãã
1ïŒå¹æã®ãããã¬ã€ã€ãŒ

[engine connect:playerNode to:delay format:nil]; [engine connect:delay to:reverb format:nil]; [engine connect:reverb to:engine.mainMixerNode format:nil]; [engine connect:engine.mainMixerNode to:outputNode format:nil]; [engine prepare];
2ïŒ2人ã®ãã¬ãŒã€ãŒããã®ãã¡ã®1人ããµãŠã³ããåŠçãã

[engine connect:player1 to:eq format:nil]; [engine connect:eq to:pitch format:nil]; [engine connect:pitch to:mixerNode fromBus:0 toBus:0 format:nil]; [engine connect:player2 to:mixerNode fromBus:0 toBus:1 format:nil]; [engine connect:mixerNode to:outputNode format:nil]; [engine prepare];
3ïŒ4人ã®ãã¬ãŒã€ãŒããã¡2人ã¯ã€ã³ã©ã€ã¶ãŒã«ãã£ãŠåŠçãããŸã

[engine connect:player1 to:mixer1 fromBus:0 toBus:0 format:nil]; [engine connect:player2 to:mixer1 fromBus:0 toBus:1 format:nil]; [engine connect:mixer1 to:eq format:nil]; [engine connect:eq to:engine.mainMixerNode fromBus:0 toBus:0 format:nil]; [engine connect:player3 to: engine.mainMixerNode fromBus:0 toBus:1 format:nil]; [engine connect:player4 to: engine.mainMixerNode fromBus:0 toBus:2 format:nil]; [engine connect:engine.mainMixerNode to:engine.outputNode format:nil]; [engine prepare];
ãšã³ãžã³ãæäœããããã«å¿ èŠãªãã¹ãŠã®æé ãæ€èšããã®ã§ããããã®ãã¹ãŠã®ã¢ã¯ã·ã§ã³ãäžç·ã«ç¢ºèªããå®è¡ããå¿ èŠãããé åºãããããæ³åããããã®å°ããªäŸãäœæããŸãã AVAudioEngineãšã³ãžã³ã§èª¿æŽå¯èœãªäœåãäžåãé«åã®ã€ã³ã©ã€ã¶ãŒãåãããã¬ãŒã€ãŒãäœæããäŸã次ã«ç€ºããŸãã
- (instancetype)init { self = [super init]; if (self) { [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; [[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil]; [[AVAudioSession sharedInstance] setActive:YES error:nil]; engine = [[AVAudioEngine alloc] init]; playerNode = [[AVAudioPlayerNode alloc] init]; AVAudioMixerNode *mixerNode = engine.mainMixerNode; AVAudioOutputNode *outputNode = engine.outputNode; AVAudioUnitEQ *eq = [[AVAudioUnitEQ alloc] initWithNumberOfBands:3]; eq.bands[0].filterType = AVAudioUnitEQFilterTypeParametric; eq.bands[0].frequency = 100.f; eq.bands[1].filterType = AVAudioUnitEQFilterTypeParametric; eq.bands[1].frequency = 1000.f; eq.bands[2].filterType = AVAudioUnitEQFilterTypeParametric; eq.bands[2].frequency = 10000.f; [engine attachNode:playerNode]; [engine attachNode:eq]; [engine connect:playerNode to:eq format:nil]; [engine connect:eq to:engine.mainMixerNode format:nil]; [engine connect:engine.mainMixerNode to:engine.outputNode format:nil]; [engine prepare]; if (!engine.isRunning) { [engine startAndReturnError:nil]; } } return self; }
ããŠãåçæ¹æ³ã®äŸïŒ
-(void)playFromURL:(NSURL *)url { AVAudioFile *audioFile = [[AVAudioFile alloc] initForReading:url error:nil]; [playerNode scheduleFile:audioFile atTime:0 completionHandler:nil]; [playerNode play]; }
èµ·ããããåé¡
AVAudioEngineã䜿çšããŠéçºããå Žåã¯ãã¢ããªã±ãŒã·ã§ã³ãæ£åžžã«åäœããªããã¯ã©ãã·ã¥ããåå ã«ãªãããšãå¿ããªãã§ãã ããã
1.ãªãŒãã£ãªã»ãã·ã§ã³ãšåçåã®èµ·åã®ç¢ºèª
åçããåã«ãåžžã«ãªãŒãã£ãªã»ãã·ã§ã³ãèšå®ããå¿ èŠããããŸããäœããã®çç±ã§ãã¢ããªã±ãŒã·ã§ã³ã®äœ¿çšäžã«ã«ããŽãªããªã»ãããŸãã¯å€æŽãããå ŽåããããŸãã ãŸããåçããåã«ããšã³ãžã³ãåæ¢ããŠããå¯èœæ§ãããããïŒããšãã°ãåããšã³ãžã³ã®å¥ã®ã¢ããªã±ãŒã·ã§ã³ã«åãæ¿ããçµæãšããŠïŒããšã³ãžã³ãå®è¡ãããŠãããã©ããã確èªããå¿ èŠããããŸãã ããããªããšãã¢ããªã±ãŒã·ã§ã³ãã¯ã©ãã·ã¥ãããªã¹ã¯ããããŸãã
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; [[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil]; [[AVAudioSession sharedInstance] setActive:YES error:nil]; if (!engine.isRunning) { [engine startAndReturnError:nil]; }
2.ãããã»ããã®åãæ¿ã
ãã1ã€ã®éèŠãªãã€ã³ãã¯ãããããã©ã³ãŸãã¯Bluetoothãããã»ããã®æ¥ç¶/åæã§ãã åæã«ããšã³ãžã³ãåæ¢ããé »ç¹ã«åçããããã©ãã¯ã®åçãåæ¢ããŸãã ãããã£ãŠããAVAudioSessionRouteChangeNotificationããšããéç¥ãåãåããªãã¶ãŒããŒãè¿œå ããããšã§ããã®ç¬éãæãã䟡å€ããããŸãã ã»ã¬ã¯ã¿ãŒã§ããªãŒãã£ãªã»ãã·ã§ã³ãèšå®ãããšã³ãžã³ãåèµ·åããå¿ èŠããããŸãã
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChangeListenerCallback:) name:AVAudioSessionRouteChangeNotification object:nil];
ãããã«
ãã®èšäºã§ã¯ãAVAudioEngineã«ç²Ÿéãããã®æäœæ¹æ³ã®ãã€ã³ããèŠãŠãããã€ãã®ç°¡åãªäŸã瀺ããŸããã ããã¯Appleã®æŠåšåº«ã«ããåªããããŒã«ã§ãããããã䜿çšãããšãè€éãã®çšåºŠãããŸããŸã§ãããçšåºŠãµãŠã³ããåŠçããå€ãã®èå³æ·±ãã¢ããªã±ãŒã·ã§ã³ãäœæã§ããŸãã