2012-07-24 52 views
3

我使用AudioQueue服务在我的应用中播放音频。 我需要一起播放几个音频文件。我现在所做的只是创建尽可能多的音频队列来播放文件。即我为两个音频文件创建了两个音频队列,并同时启动它们以实现音频混合效果。在iPhone上混音:需要建议

所以基本上我想知道这是一个“优雅”的做法。

请注意,我知道音频单元服务及其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; 

}