Advertisement
Guest User

Untitled

a guest
Jun 5th, 2012
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #import <Foundation/Foundation.h>
  2. #import <CoreServices/CoreServices.h>
  3. #import <AudioUnit/AudioUnit.h>
  4. #import <AudioToolBox/AudioToolBox.h>
  5.  
  6. typedef struct
  7. {
  8.     AudioUnit *unit;
  9.     NSMutableArray *buffers;
  10.     AudioStreamBasicDescription *asbd;
  11.     size_t tmpBufferSize;
  12.     void *tmpBuffer;
  13. } sharedData;
  14.  
  15. static int end;
  16.  
  17. static void signalHandler(int sig)
  18. {
  19.     fprintf(stderr,"stopping\n");
  20.     end = 1;
  21. }
  22.  
  23. static OSStatus inputProc(
  24.                    void *inRefCon,
  25.                    AudioUnitRenderActionFlags *ioActionFlags,
  26.                    const AudioTimeStamp *inTimeStamp,
  27.                    UInt32 inBusNumber,
  28.                    UInt32 inNumberFrames,
  29.                    AudioBufferList * ioData)
  30. {
  31.     OSStatus err = noErr;
  32.     AudioBufferList list;
  33.     sharedData *sharedData = inRefCon;
  34.     list.mNumberBuffers = 1;
  35.     list.mBuffers[0].mNumberChannels = sharedData->asbd->mChannelsPerFrame;
  36.     list.mBuffers[0].mDataByteSize = sharedData->asbd->mBytesPerFrame*inNumberFrames;
  37.     if(sharedData->tmpBufferSize < list.mBuffers[0].mDataByteSize) {
  38.         sharedData->tmpBuffer = (unsigned char *)realloc(sharedData->tmpBuffer,list.mBuffers[0].mDataByteSize);
  39.         sharedData->tmpBufferSize = list.mBuffers[0].mDataByteSize;
  40.     }
  41.     list.mBuffers[0].mData = sharedData->tmpBuffer;
  42.    
  43.     err = AudioUnitRender(*sharedData->unit,
  44.                           ioActionFlags,
  45.                           inTimeStamp,
  46.                           inBusNumber,
  47.                           inNumberFrames,
  48.                           &list);
  49.    
  50.     if(err == noErr) {
  51.         NSData *data = [[NSData alloc] initWithBytes:list.mBuffers[0].mData length:list.mBuffers[0].mDataByteSize];
  52.         @synchronized(sharedData->buffers) {
  53.             [sharedData->buffers addObject:data];
  54.         }
  55.         [data release];
  56.     }
  57.    
  58.     return err;
  59. }
  60.  
  61. int main(void)
  62. {
  63.     AudioUnit inputUnit;
  64.     AudioStreamBasicDescription inFormat, outFormat;
  65.     ComponentDescription desc;
  66.     Component comp;
  67.     AURenderCallbackStruct  inCallback;
  68.     UInt32 enableIO;
  69.     UInt32 size=0;
  70.     OSStatus    err ;
  71.     AudioDeviceID inputDevice;
  72.     sharedData sharedData;
  73.     ExtAudioFileRef file;
  74.     FSRef dirFSRef;
  75.    
  76.     /* Open AUHAL for input */
  77.     desc.componentType = kAudioUnitType_Output;
  78.     desc.componentSubType = kAudioUnitSubType_HALOutput;
  79.     desc.componentManufacturer = kAudioUnitManufacturer_Apple;
  80.     desc.componentFlags = 0;
  81.     desc.componentFlagsMask = 0;
  82.     comp = FindNextComponent(NULL, &desc);
  83.     if (comp == NULL) {
  84.         fprintf(stderr, "can't find HAL output unit\n");
  85.         return -1;
  86.     }
  87.    
  88.     err = OpenAComponent(comp, &inputUnit);
  89.     if (err)  {
  90.         fprintf(stderr, "can't open HAL output unit\n");
  91.         return -1;
  92.     }
  93.    
  94.     /* Configure AUHAL */
  95.     err = AudioUnitInitialize(inputUnit);
  96.     if(err != noErr) {
  97.         fprintf(stderr, "AudioUnitInitialize failed.\n");
  98.         CloseComponent(inputUnit);
  99.         return -1;
  100.     }
  101.    
  102.     enableIO = 1;
  103.     AudioUnitSetProperty(inputUnit,
  104.                          kAudioOutputUnitProperty_EnableIO,
  105.                          kAudioUnitScope_Input,
  106.                          1,
  107.                          &enableIO,
  108.                          sizeof(enableIO));
  109.    
  110.     enableIO = 0;
  111.     AudioUnitSetProperty(inputUnit,
  112.                          kAudioOutputUnitProperty_EnableIO,
  113.                          kAudioUnitScope_Output,
  114.                          0,
  115.                          &enableIO,
  116.                          sizeof(enableIO));
  117.    
  118.     /* Get default input device */
  119.     size = sizeof(AudioDeviceID);
  120.     err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
  121.                                    &size,
  122.                                    &inputDevice);
  123.     if (err)  {
  124.         fprintf(stderr, "can't get default input device\n");
  125.         CloseComponent(inputUnit);
  126.         return -1;
  127.     }
  128.    
  129.     size = 100;
  130.     char buf[100];
  131.     err = AudioDeviceGetProperty(inputDevice, 0, false, kAudioDevicePropertyDeviceName, &size, buf);
  132.     fprintf(stderr,"Device: %s\n",buf);
  133.    
  134.     err = AudioUnitSetProperty(inputUnit,
  135.                                kAudioOutputUnitProperty_CurrentDevice,
  136.                                kAudioUnitScope_Global,
  137.                                0,
  138.                                &inputDevice,
  139.                                sizeof(inputDevice));
  140.     if (err)  {
  141.         fprintf(stderr, "can't set default input device\n");
  142.         CloseComponent(inputUnit);
  143.         return -1;
  144.     }
  145.    
  146.     /* Setup input/output format */
  147.     size = sizeof(AudioStreamBasicDescription);
  148.     err = AudioUnitGetProperty(inputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &inFormat, &size);
  149.     if(err != noErr) {
  150.         fprintf(stderr, "AudioUnitGetProperty(input format) failed.\n");
  151.         CloseComponent(inputUnit);
  152.         return -1;
  153.     }
  154.     err = AudioUnitSetProperty(inputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &inFormat, sizeof(AudioStreamBasicDescription));
  155.     if(err != noErr) {
  156.         fprintf(stderr, "AudioUnitSetProperty(input format) failed.\n");
  157.         CloseComponent(inputUnit);
  158.         return -1;
  159.     }
  160.    
  161.     /* Setup callback */
  162.     memset(&sharedData,0,sizeof(sharedData));
  163.     sharedData.unit = &inputUnit;
  164.     sharedData.buffers = [[NSMutableArray alloc] init];
  165.     sharedData.asbd = &inFormat;
  166.     memset(&inCallback, 0, sizeof(AURenderCallbackStruct));
  167.     inCallback.inputProc = inputProc;
  168.     inCallback.inputProcRefCon = &sharedData;
  169.     err = AudioUnitSetProperty (inputUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &inCallback, sizeof(AURenderCallbackStruct));
  170.     if(err != noErr) {
  171.         fprintf(stderr, "AudioUnitSetProperty(input) failed.\n");
  172.         CloseComponent(inputUnit);
  173.         return -1;
  174.     }
  175.    
  176.     /* Setup output codec */
  177.     memset(&outFormat,0,sizeof(AudioStreamBasicDescription));
  178.     outFormat.mFormatID = kAudioFormatAppleLossless;
  179.     outFormat.mBitsPerChannel = 16;
  180.     outFormat.mFormatFlags = kAppleLosslessFormatFlag_16BitSourceData;
  181.     outFormat.mSampleRate = inFormat.mSampleRate;
  182.     outFormat.mChannelsPerFrame = inFormat.mChannelsPerFrame;
  183.    
  184.     FSPathMakeRef((UInt8*)realpath(".",NULL) ,&dirFSRef,NULL);
  185.     remove("recording.m4a");
  186.     if(ExtAudioFileCreateNew(&dirFSRef, CFSTR("recording.m4a"), kAudioFileM4AType, &outFormat, NULL, &file) != noErr)
  187.     {
  188.         fprintf(stderr, "ExtAudioFileCreateNew failed.\n");
  189.         CloseComponent(inputUnit);
  190.         return -1;
  191.     }
  192.    
  193.     if(ExtAudioFileSetProperty(file, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &inFormat) != noErr) {
  194.         fprintf(stderr, "ExtAudioFileSetProperty failed.\n");
  195.         CloseComponent(inputUnit);
  196.         ExtAudioFileDispose(file);
  197.         return -1;
  198.     }
  199.    
  200.     /* register signal handler */
  201.     signal(SIGINT, signalHandler);
  202.     signal(SIGHUP, signalHandler);
  203.    
  204.     /* start recording */
  205.     AudioOutputUnitStart(inputUnit);
  206.    
  207.     while(!end)
  208.     {
  209.         NSArray *buffers = nil;
  210.         @synchronized(sharedData.buffers) {
  211.             if([sharedData.buffers count]) {
  212.                 buffers = [[NSArray alloc] initWithArray:sharedData.buffers];
  213.                 [sharedData.buffers removeAllObjects];
  214.             }
  215.         }
  216.         if(buffers) {
  217.             int i;
  218.             AudioBufferList list;
  219.             for(i=0;i<[buffers count];i++) {
  220.                 list.mNumberBuffers = 1;
  221.                 list.mBuffers[0].mNumberChannels = inFormat.mChannelsPerFrame;
  222.                 list.mBuffers[0].mDataByteSize = [[buffers objectAtIndex:i] length];
  223.                 list.mBuffers[0].mData = (void *)[[buffers objectAtIndex:i] bytes];
  224.                 if((err = ExtAudioFileWrite(file, list.mBuffers[0].mDataByteSize/inFormat.mBytesPerFrame, &list)) != noErr) {
  225.                     fprintf(stderr, "ExtAudioFileWrite failed.\n");
  226.                     goto last;
  227.                 }
  228.             }
  229.            
  230.             [buffers release];
  231.         }
  232.         else {
  233.             usleep(10000);
  234.         }
  235.     }
  236.    
  237.   last:
  238.     AudioOutputUnitStop(inputUnit);
  239.     CloseComponent(inputUnit);
  240.     ExtAudioFileDispose(file);
  241.    
  242.     return 0;
  243. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement