2012-07-24 4 views
3

AudioQueue 서비스를 사용하여 내 앱에서 오디오를 재생하고 있습니다. 여러 오디오 파일을 함께 재생해야합니다. 지금 내가하는 일은 파일을 재생하는 데 필요한만큼의 오디오 대기열을 만듭니다. 나는. 두 개의 오디오 파일에 대해 두 개의 오디오 대기열을 만들고 동시에 오디오 믹싱 효과를 시작합니다.iPhone에서 오디오 믹싱 : 조언이 필요합니다.

기본적으로 나는 이것을 "우아하게"하는 방법을 알고 싶습니다.

Audio Unit 서비스 및 해당 MixerHost 예를 알고 있으므로이 옵션을 제안하지 마십시오. 오디오 대기열 서비스만을 사용하여 사운드 믹싱을 독점적으로 수행해야합니다.

답변

1
- (void) setUpAndAddAudioAtPath:(NSURL*)assetURL toComposition:(AVMutableComposition *)composition { 

    AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil]; 

    AVMutableCompositionTrack *track = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
    AVAssetTrack *sourceAudioTrack = [[songAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 

    NSError *error = nil; 
    BOOL ok = NO; 

    CMTime startTime = CMTimeMakeWithSeconds(0, 1); 
    CMTime trackDuration = songAsset.duration; 
    CMTime longestTime = CMTimeMake(848896, 44100); //(19.24 seconds) 
    CMTimeRange tRange = CMTimeRangeMake(startTime, trackDuration); 

    //Set Volume 
    AVMutableAudioMixInputParameters *trackMix = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:track]; 
    [trackMix setVolume:0.8f atTime:startTime]; 
    [audioMixParams addObject:trackMix]; 

    //Insert audio into track 
    ok = [track insertTimeRange:tRange ofTrack:sourceAudioTrack atTime:CMTimeMake(0, 44100) error:&error]; 
} 


- (BOOL) exportAudio { 

    if (defaultSoundPath == nil || recordingSoundPath == nil) { 

     [actvityIdicatiorView stopAnimating]; 
     [actvityIdicatiorView setHidden:YES]; 


     UIAlertView *alertView=[[UIAlertView alloc]initWithTitle:@"Select Sound" message:@"Both Sound is selected" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil]; 
     [alertView show]; 
     return NO; 



    } 

    AVMutableComposition *composition = [AVMutableComposition composition]; 
    if (audioMixParams) { 
     [audioMixParams release]; 
     audioMixParams=nil; 
    } 
    audioMixParams = [[NSMutableArray alloc] initWithObjects:nil]; 

    //Add Audio Tracks to Composition 

    NSString *sourceA= [[NSBundle mainBundle] pathForResource:@"Beach Soundscape" ofType:@"mp3"]; 

    //NSString *URLPath1 = pathToYourAudioFile1; 

    NSURL *assetURL1 = [NSURL fileURLWithPath:sourceA]; 
    [self setUpAndAddAudioAtPath:assetURL1 toComposition:composition]; 

    NSString *sourceB = [[NSBundle mainBundle] pathForResource:@"DrumsMonoSTP" ofType:@"aif"]; 
    // NSString *URLPath2 = pathToYourAudioFile2; 
    NSURL *assetURL2 = [NSURL fileURLWithPath:sourceB]; 
    [self setUpAndAddAudioAtPath:assetURL2 toComposition:composition]; 

    AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix]; 
    audioMix.inputParameters = [NSArray arrayWithArray:audioMixParams]; 

    //If you need to query what formats you can export to, here's a way to find out 
    NSLog (@"compatible presets for songAsset: %@", 
      [AVAssetExportSession exportPresetsCompatibleWithAsset:composition]); 

    AVAssetExportSession *exporter = [[AVAssetExportSession alloc] 
             initWithAsset: composition 
             presetName: AVAssetExportPresetAppleM4A]; 


    exporter.audioMix = audioMix; 
    exporter.outputFileType = @"com.apple.m4a-audio"; 

    // NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    // 
    // NSString *fileName = @"someFilename"; 

    //NSString *exportFile = [[paths objectAtIndex:0] stringByAppendingFormat: @"/%@.m4a", fileName]; 

    mixingSoundPath= [[self mixingSoundFolder] stringByAppendingFormat: @"/Mixing%@.m4a", [self dateString]]; 
    [mixingSoundPath retain]; 

    // set up export 
    //myDeleteFile(exportFile); 
    NSURL *exportURL = [NSURL fileURLWithPath:mixingSoundPath]; 
    exporter.outputURL = exportURL; 

    static BOOL isComplete; 

    // do the export 
    [exporter exportAsynchronouslyWithCompletionHandler:^{ 

     int exportStatus = exporter.status; 

     NSLog(@"exporter.......%i",exportStatus); 


     switch (exportStatus) { 

      case AVAssetExportSessionStatusFailed: 
       // NSError *exportError =exporter.error; 
       isComplete=NO; 
       NSLog (@"AVAssetExportSessionStatusFailed"); 


       NSLog (@"Error == %@", exporter.error); 
       break; 

      case AVAssetExportSessionStatusCompleted: 
       [self mixingDidFinshing]; 

       isComplete=YES; 
       break; 
      case AVAssetExportSessionStatusUnknown: 
       NSLog (@"AVAssetExportSessionStatusUnknown"); 
       isComplete=NO; 

       break; 
      case AVAssetExportSessionStatusExporting: 
       isComplete=NO; 

       NSLog (@"AVAssetExportSessionStatusExporting"); 

       break; 
      case AVAssetExportSessionStatusCancelled: 
       isComplete=NO; 

       NSLog (@"AVAssetExportSessionStatusCancelled"); 

       break; 
      case AVAssetExportSessionStatusWaiting: 
       isComplete=NO; 

       NSLog (@"AVAssetExportSessionStatusWaiting"); 

       break; 
      default: 
       NSLog (@"didn't get export status"); 
       isComplete=NO; 
       break; 
     } 


    }]; 

    return isComplete; 

}