TAAE2 input doesn't record any sound

edited April 2016

I'm trying to record the mic input while I'm playing a backing track and save the mic input in a .wav file.

The backing track plays fine but the problem is that when I try to play the recorded file with iExplorer (I open it with MPlayerX), the file is of the length of the record but I don't ear any sound when I play it...

Here is my code, I used the singleton architecture for my AudioController. In my Swift code I first call the init method, then playCurrentTrack, then startRecording and then stopRecording.

#import "AudioManager.h"
#import "Project-Swift.h"
@import AVFoundation;

@implementation AudioManager

#pragma mark Singleton Methods

+ (id)defaultAudioManager {
    static AudioManager *defaultAudioManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        defaultAudioManager = [[self alloc] init];
    });
    return defaultAudioManager;
}

- (id)init {
    if ( !(self = [super init]) ) return nil;
    self.renderer = [AERenderer new];
    self.output = [[AEAudioUnitOutput alloc] initWithRenderer:self.renderer];
    self.recorderValue = [AEManagedValue new];
    _isRecording = NO;
    [self startAudioController];

    return self;
}

- (void)dealloc {

}

- (BOOL)startAudioController {
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:NULL];

    return [self.output start:NULL];
}

- (void)stopAudioController {
    return [self.output stop];
}

- (void)playCurrentTrack:(BOOL)loop atTime:(int)time track:(Track *)currentTrack {
    self.currentTrack = currentTrack;
    self.currentTrackModule = [[AEAudioFilePlayerModule alloc] initWithRenderer:self.renderer
                                                                            URL:currentTrack.fileURL
                                                                          error:NULL];
    self.currentTrackModule.loop = loop;
    [self.currentTrackModule playAtTime:time];
    AEAudioFilePlayerModule *currentTrackModule = self.currentTrackModule;
    AEAudioUnitInputModule *input = self.output.inputModule;
    AEManagedValue *recorderValue = self.recorderValue;

    self.renderer.block = ^(const AERenderContext *context) {

        AEModuleProcess(currentTrackModule, context);
        AEModuleProcess(input, context);

        __unsafe_unretained AEFileRecorderModule *recorder = (__bridge AEFileRecorderModule *)AEManagedValueGetValue(recorderValue);
        if (recorder) {
            AEModuleProcess(recorder, context);
        }

        AEBufferStackMixToBufferList(context->stack, 0, 0, YES, context->output);
    };
}

- (void)startRecording {
    NSLog(@"AudioManager: starting recording");

    _isRecording = YES;

    AEFileRecorderModule * recorder =
    [[AEFileRecorderModule alloc] initWithRenderer:self.output.renderer
                                               URL:[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
                                                                                           inDomains:NSUserDomainMask].firstObject
                                                    URLByAppendingPathComponent:@"Recording.wav"]
                                              type:kAudioFileWAVEType
                                             error:NULL];

    [recorder beginRecordingAtTime:0];
    self.recorderValue.objectValue = recorder;
}

- (void)stopRecording {
    NSLog(@"AudioManager: finishing recording");

    _isRecording = NO;
    [(AEFileRecorderModule*)self.recorderValue.objectValue stopRecordingAtTime:0
                                                               completionBlock:^{
                                                                   self.recorderValue.objectValue = nil;
                                                               }];
}

- (Track *)getCurrentTrack {
    return self.currentTrack;
}

@end

Comments

  • edited April 2016

    Hey @YoanGJ. The problem is you're using two generator modules, which each push a buffer, then using the recorder which grabs the top buffer only. So after here:

            AEModuleProcess(currentTrackModule, context);
            AEModuleProcess(input, context);
    

    You've got 2 buffers on the stack: the audio from currentTrackModule, and the audio from input. Then when you call:

            __unsafe_unretained AEFileRecorderModule *recorder = (__bridge AEFileRecorderModule *)AEManagedValueGetValue(recorderValue);
            if (recorder) {
                AEModuleProcess(recorder, context);
            }
    

    The recorder grabs the top buffer, which is the input only. You probably want to mix the buffers first:

    AEModuleProcess(currentTrackModule, context);
    AEModuleProcess(input, context);
    
    // Mix 2 buffers, so that the buffer on top is a mix of the two
    AEBufferStackMix(context->stack, 2);
    
    __unsafe_unretained AEFileRecorderModule *recorder = (__bridge AEFileRecorderModule *)AEManagedValueGetValue(recorderValue);
    if (recorder) {
        AEModuleProcess(recorder, context);
    }
    
  • Thank's @Michael ! So here with the mix of buffers I only got the currentTrackModule buffer recorded to my file.
    Again the input buffer is not recorded :/
    And I don't want the currentTrackModule buffer to be recorded in my file, only the input, that's why I choose to not mix buffers

  • Okay so my problem was apparently a conflict between my camera session and TAAE2, if I allow the option MixWithOthers that works !

  • Ah, yep, that'll do it =)

Sign In or Register to comment.