Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // ViewController.m
- // Mic Recording
- //
- // Created by Thorsten Wolfer on 03.02.12.
- // Copyright (c) 2012 malivo. All rights reserved.
- //
- #import "ViewController.h"
- #import <CoreAudio/CoreAudioTypes.h>
- #define kOutputBus 0
- #define kInputBus 1
- #define kSampleRate 44100
- #import <Foundation/Foundation.h>
- #import <AudioToolbox/AudioToolbox.h>
- #import <AVFoundation/AVAudioSession.h>
- #import "AudioUnit/AudioUnit.h"
- @interface ViewController () {
- AudioComponentInstance mAudioUnit;
- ExtAudioFileRef mAudioFileRef;
- }
- -(void) initializeOutputUnit;
- static OSStatus recordingCallback (void * inRefCon,
- AudioUnitRenderActionFlags * ioActionFlags,
- const AudioTimeStamp * inTimeStamp,
- UInt32 inBusNumber,
- UInt32 inNumberFrames,
- AudioBufferList * ioData);
- -(void)stopRecording:(NSTimer*)theTimer;
- @end
- @implementation ViewController
- - (void)didReceiveMemoryWarning
- {
- [super didReceiveMemoryWarning];
- // Release any cached data, images, etc that aren't in use.
- }
- #pragma mark Core Audio
- static void CheckError(OSStatus error, const char *operation)
- {
- if (error == noErr) return;
- char errorString[20];
- // See if it appears to be a 4-char-code *(UInt32 *)(errorString + 1) =
- CFSwapInt32HostToBig(error);
- if (isprint(errorString[1]) && isprint(errorString[2]) &&
- isprint(errorString[3]) && isprint(errorString[4])) {
- errorString[0] = errorString[5] = '\''; errorString[6] = '\0';
- }
- else {
- // No, format it as an integer sprintf(errorString, "%d", (int)error);
- fprintf(stderr, "Error: %s (%s)\n", operation, errorString);
- }
- }
- - (void)stopRecording:(NSTimer*)theTimer
- {
- printf("\nstopRecording\n");
- AudioOutputUnitStop(mAudioUnit);
- AudioUnitUninitialize(mAudioUnit);
- OSStatus status = ExtAudioFileDispose(mAudioFileRef);
- printf("OSStatus(ExtAudioFileDispose): %ld\n", status);
- }
- - (void) initializeOutputUnit
- {
- OSStatus status;
- // Describe audio component
- AudioComponentDescription desc;
- desc.componentType = kAudioUnitType_Output;
- desc.componentSubType = kAudioUnitSubType_RemoteIO;
- desc.componentFlags = 0;
- desc.componentFlagsMask = 0;
- desc.componentManufacturer = kAudioUnitManufacturer_Apple;
- // Get component
- AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc);
- // Get audio units
- status = AudioComponentInstanceNew(inputComponent, &mAudioUnit);
- // Enable IO for recording
- UInt32 flag = 1;
- status = AudioUnitSetProperty(mAudioUnit,
- kAudioOutputUnitProperty_EnableIO,
- kAudioUnitScope_Input,
- kInputBus,
- &flag,
- sizeof(flag));
- // Enable IO for playback
- status = AudioUnitSetProperty(mAudioUnit,
- kAudioOutputUnitProperty_EnableIO,
- kAudioUnitScope_Output,
- kOutputBus,
- &flag,
- sizeof(flag));
- // Describe format
- AudioStreamBasicDescription audioFormat={0};
- audioFormat.mSampleRate = kSampleRate;
- audioFormat.mFormatID = kAudioFormatLinearPCM;
- audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
- audioFormat.mFramesPerPacket = 1;
- audioFormat.mChannelsPerFrame = 1;
- audioFormat.mBitsPerChannel = 16;
- audioFormat.mBytesPerPacket = 2;
- audioFormat.mBytesPerFrame = 2;
- // Apply format
- status = AudioUnitSetProperty(mAudioUnit,
- kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Output,
- kInputBus,
- &audioFormat,
- sizeof(audioFormat));
- status = AudioUnitSetProperty(mAudioUnit,
- kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Input,
- kOutputBus,
- &audioFormat,
- sizeof(audioFormat));
- // Set input callback
- AURenderCallbackStruct callbackStruct;
- callbackStruct.inputProc = recordingCallback;
- callbackStruct.inputProcRefCon = (__bridge void *)self;
- status = AudioUnitSetProperty(mAudioUnit,
- kAudioOutputUnitProperty_SetInputCallback,
- kAudioUnitScope_Global,
- kInputBus,
- &callbackStruct,
- sizeof(callbackStruct));
- // Disable buffer allocation for the recorder (optional - do this if we want to pass in our own)
- flag = 0;
- status = AudioUnitSetProperty(mAudioUnit,
- kAudioUnitProperty_ShouldAllocateBuffer,
- kAudioUnitScope_Output,
- kInputBus,
- &flag,
- sizeof(flag));
- // On initialise le fichier audio
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- NSString *documentsDirectory = [paths objectAtIndex:0];
- NSString *destinationFilePath = [[NSString alloc] initWithFormat: @"%@/output.caf", documentsDirectory];
- NSLog(@">>> %@\n", destinationFilePath);
- CFURLRef destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (__bridge CFStringRef)destinationFilePath, kCFURLPOSIXPathStyle, false);
- OSStatus setupErr = ExtAudioFileCreateWithURL(destinationURL, kAudioFileCAFType, &audioFormat, NULL, kAudioFileFlags_EraseFile, &mAudioFileRef);
- CFRelease(destinationURL);
- NSAssert(setupErr == noErr, @"Couldn't create file for writing");
- setupErr = ExtAudioFileSetProperty(mAudioFileRef, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &audioFormat);
- NSAssert(setupErr == noErr, @"Couldn't create file for format");
- setupErr = ExtAudioFileWriteAsync(mAudioFileRef, 0, NULL);
- NSAssert(setupErr == noErr, @"Couldn't initialize write buffers for audio file");
- CheckError(AudioUnitInitialize(mAudioUnit), "AudioUnitInitialize");
- CheckError(AudioOutputUnitStart(mAudioUnit), "AudioOutputUnitStart");
- [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(stopRecording:) userInfo:nil repeats:NO];
- }
- static void printAudioUnitRenderActionFlags(AudioUnitRenderActionFlags * ioActionFlags)
- {
- if (*ioActionFlags == 0) {
- printf("AudioUnitRenderActionFlags(%lu) ", *ioActionFlags);
- return;
- }
- printf("AudioUnitRenderActionFlags(%lu): ", *ioActionFlags);
- if (*ioActionFlags & kAudioUnitRenderAction_PreRender) printf("kAudioUnitRenderAction_PreRender ");
- if (*ioActionFlags & kAudioUnitRenderAction_PostRender) printf("kAudioUnitRenderAction_PostRender ");
- if (*ioActionFlags & kAudioUnitRenderAction_OutputIsSilence) printf("kAudioUnitRenderAction_OutputIsSilence ");
- if (*ioActionFlags & kAudioOfflineUnitRenderAction_Preflight) printf("kAudioOfflineUnitRenderAction_Prefli ght ");
- if (*ioActionFlags & kAudioOfflineUnitRenderAction_Render) printf("kAudioOfflineUnitRenderAction_Render");
- if (*ioActionFlags & kAudioOfflineUnitRenderAction_Complete) printf("kAudioOfflineUnitRenderAction_Complete ");
- if (*ioActionFlags & kAudioUnitRenderAction_PostRenderError) printf("kAudioUnitRenderAction_PostRenderError ");
- if (*ioActionFlags & kAudioUnitRenderAction_DoNotCheckRenderArgs) printf("kAudioUnitRenderAction_DoNotCheckRenderArgs ");
- }
- static OSStatus recordingCallback (void * inRefCon,
- AudioUnitRenderActionFlags * ioActionFlags,
- const AudioTimeStamp * inTimeStamp,
- UInt32 inBusNumber,
- UInt32 inNumberFrames,
- AudioBufferList * ioData)
- {
- double timeInSeconds = inTimeStamp->mSampleTime / kSampleRate;
- printf("\n%fs inBusNumber: %lu inNumberFrames: %lu ", timeInSeconds, inBusNumber, inNumberFrames);
- printAudioUnitRenderActionFlags(ioActionFlags);
- AudioBufferList bufferList;
- SInt16 samples[inNumberFrames]; // A large enough size to not have to worry about buffer overrun
- memset (&samples, 0, sizeof (samples));
- bufferList.mNumberBuffers = 1;
- bufferList.mBuffers[0].mData = samples;
- bufferList.mBuffers[0].mNumberChannels = 1;
- bufferList.mBuffers[0].mDataByteSize = inNumberFrames*sizeof(SInt16);
- ViewController* THIS = THIS = (__bridge ViewController *)inRefCon;
- OSStatus status;
- status = AudioUnitRender(THIS->mAudioUnit,
- ioActionFlags,
- inTimeStamp,
- kInputBus,
- inNumberFrames,
- &bufferList);
- if (noErr != status) {
- printf("AudioUnitRender error: %ld", status);
- return noErr;
- }
- // Now, we have the samples we just read sitting in buffers in bufferList
- ExtAudioFileWriteAsync(THIS->mAudioFileRef, inNumberFrames, &bufferList);
- return noErr;
- }
- #pragma mark - View lifecycle
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // Do any additional setup after loading the view, typically from a nib.
- [self initializeOutputUnit];
- }
- - (void)viewDidUnload
- {
- [super viewDidUnload];
- // Release any retained subviews of the main view.
- // e.g. self.myOutlet = nil;
- }
- - (void)viewWillAppear:(BOOL)animated
- {
- [super viewWillAppear:animated];
- }
- - (void)viewDidAppear:(BOOL)animated
- {
- [super viewDidAppear:animated];
- }
- - (void)viewWillDisappear:(BOOL)animated
- {
- [super viewWillDisappear:animated];
- }
- - (void)viewDidDisappear:(BOOL)animated
- {
- [super viewDidDisappear:animated];
- }
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
- {
- // Return YES for supported orientations
- return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
- }
- @end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement