我正在尝试将2个单声道音频文件写入单个2声道文件,其中第一个音频文件转到左声道,第二个音频文件转到右声道。 我将AVAudioEngine类与标准混音器一起使用,但这会混合2个音频文件并在左右声道中写入相同的内容。 这是我使用的代码:
//
// ViewController.m
// StereoMixer
//
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
extern void CheckError(NSError *error);
@interface ViewController ()
@property(nonatomic, strong) AVAudioEngine *engine;
@end
@implementation ViewController
-(void)viewDidLoad {
[super viewDidLoad];
NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *outputFile = [docsDir stringByAppendingPathComponent:@"output.caf"];
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
[self mergeAudioFilePath1:[bundlePath stringByAppendingPathComponent:@"1.m4a"]
audioFilePath2:[bundlePath stringByAppendingPathComponent:@"2.m4a"]
outputFilePath:outputFile];
}
-(void)mergeAudioFilePath1:(NSString *)audioFilePath1 audioFilePath2:(NSString *)audioFilePath2 outputFilePath:(NSString *)outputFilePath {
_engine = [[AVAudioEngine alloc] init];
AVAudioFormat *stereoFormat = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:44100 channels:2];
NSError *error = nil;
AVAudioMixerNode *mainMixer = _engine.mainMixerNode;
AVAudioFile *audioFile1 = [[AVAudioFile alloc] initForReading:[NSURL fileURLWithPath:audioFilePath1] error:&error];
CheckError(error);
AVAudioFile *audioFile2 = [[AVAudioFile alloc] initForReading:[NSURL fileURLWithPath:audioFilePath2] error:&error];
CheckError(error);
AVAudioPlayerNode *player1 = [[AVAudioPlayerNode alloc] init];
AVAudioPlayerNode *player2 = [[AVAudioPlayerNode alloc] init];
[_engine attachNode:player1];
[_engine attachNode:player2];
stereoFormat = [mainMixer outputFormatForBus:0];
[_engine connect:player1 to:mainMixer fromBus:0 toBus:0 format:audioFile1.processingFormat];
[_engine connect:player2 to:mainMixer fromBus:0 toBus:1 format:audioFile2.processingFormat];
[_engine connect:mainMixer to:_engine.outputNode format:stereoFormat];
[[NSFileManager defaultManager] removeItemAtPath:outputFilePath error:&error];
AVAudioFile *outputFile = [[AVAudioFile alloc] initForWriting:[NSURL fileURLWithPath:outputFilePath]
settings:[_engine.inputNode inputFormatForBus:0].settings
error:&error];
CheckError(error);
if (![_engine startAndReturnError:&error]) {
NSLog(@"Error in [engine startAndReturnError:&error]");
}
[mainMixer installTapOnBus:0 bufferSize:4096 format:[mainMixer outputFormatForBus:0] block:^(AVAudioPCMBuffer *buffer, AVAudioTime *when) {
NSError *error;
BOOL success;
NSLog(@"writing");
if ((outputFile.length < audioFile1.length) || (outputFile.length < audioFile2.length)) {
success = [outputFile writeFromBuffer:buffer error:&error];
NSAssert(success, @"error writing buffer data to file, %@", [error localizedDescription]);
if (error) {
NSLog(@"writebuffererror =%@",error);
}
} else {
[mainMixer removeTapOnBus:0];
NSLog(@"done");
}
}];
[player1 scheduleFile:audioFile1 atTime:nil completionHandler:nil];
[player2 scheduleFile:audioFile2 atTime:nil completionHandler:nil];
[player1 play];
[player2 play];
}
@end
void CheckError(NSError *error) {
if (error == nil) return;
// NSLog(@"Error: %@", error);
NSError *newError = [NSError errorWithDomain:NSOSStatusErrorDomain
code:error.code
userInfo:nil];
NSLog(@"Error: %@", [newError description]);
}
有什么想法吗?