Changeset 4536

Show
Ignore:
Timestamp:
12/07/09 23:28:40 (4 years ago)
Author:
piers
Message:

Fixed driver to work on [snow] Leopard - Based on Doug's patch from ticket #180.
The driver still only works with 8KHz and there's some parts of it that produce
deprecated messages on Snow Leopard. Ideally it needs more work to use Core Audio
format conversion and probably just use AudioUnit? interface. The current design uses
a combination of oldish low level HAL to capture audio and the defaultOutput AU
for output. One could use the AUHAL as a basis for a new design....

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • rat/trunk/auddev_macosx.c

    r3983 r4536  
    2222#include <AudioToolbox/AudioConverter.h> 
    2323#include <CoreAudio/CoreAudio.h> 
     24#include <CoreServices/CoreServices.h> 
     25 
     26#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) 
     27#import <AudioUnit/AUComponent.h> 
     28#else 
     29#import <AudioUnit/AUNTComponent.h> 
     30#endif 
    2431 
    2532struct device { 
     
    2835        AudioStreamBasicDescription inputStreamBasicDescription_;       // The input stream description 
    2936        AudioStreamBasicDescription mashStreamBasicDescription_;        // The Mash stream description 
    30         AudioUnitInputCallback input;                                   // callback function to privde output data 
     37        AURenderCallbackStruct input;                                   // callback function to privde output data 
    3138        Float32 inputGain_, outputGain_;                                // Input and output volume gain values.  
    3239        audio_format suported_formats[14]; 
    3340        int num_supported_format; 
    3441        AudioDeviceID inputDeviceID_;                                   // The input device ID. 
     42        AudioDeviceIOProcID inputDeviceProcID_; 
    3543}; 
    3644 
     
    138146} 
    139147 
     148// Takes audio input from Mic and passes it to Rat media for transmission 
    140149static OSStatus  
     150//AudioDeviceIOProc 
    141151audioIOProc(AudioDeviceID inDevice, const AudioTimeStamp* inNow,  
    142152            const AudioBufferList* inInputData, const AudioTimeStamp* inInputTime,  
     
    219229 
    220230static OSStatus  
    221 outputRenderer(void *inRefCon, AudioUnitRenderActionFlags inActionFlags, const AudioTimeStamp *inTimeStamp,  
    222                UInt32 inBusNumber, AudioBuffer *ioData)  
    223 { 
    224         int i; 
    225         SInt16* ip = (SInt16*)ioData->mData; 
     231outputRenderer(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp,  
     232               UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)  
     233{ 
     234        unsigned int i, j; 
    226235 
    227236        UNUSED(inRefCon); 
    228         UNUSED(inActionFlags); 
     237        UNUSED(ioActionFlags); 
    229238        UNUSED(inTimeStamp); 
    230239        UNUSED(inBusNumber); 
    231  
    232         int requestedFrames = ioData->mDataByteSize / devices[add].mashStreamBasicDescription_.mBytesPerFrame; 
    233         //int requestedFrames = ioData->mDataByteSize / 2; 
     240        UNUSED(inNumberFrames); 
     241 
    234242        int zeroIndex = outputReadIndex_ - 1; 
    235243        if (zeroIndex == -1) zeroIndex = writeBufferSize_ - 1; 
    236244 
    237         //printf("req frames: %d\tDataByteSize %d\ndev: %d\n",requestedFrames, ioData->mDataByteSize, devices[add].mashStreamBasicDescription_.mBytesPerFrame); 
    238         //printf("outputRender:\n"); 
    239         for (i = 0; i < requestedFrames; i++) 
    240         { 
    241                 // Copy the requested amount of data into the output buffer. 
    242                 //if (muteOutput_) 
    243                 //{      
    244                         //ip[i] = 0; 
    245                         //outputReadIndex_++; 
    246                 //} 
    247                 //else 
    248                 //{ 
    249                         //*ip++ = 10000; 
    250                         ip[i] = writeBuffer_[outputReadIndex_]; 
    251                         //memcpy(ip + i, writeBuffer_ + outputReadIndex_, 2); 
    252                         outputReadIndex_++; 
    253  
    254                         //printf("%d\n", ip[i]); 
    255                         //printf("outputReadIndex: %d\n",outputReadIndex_); 
    256                         //printf("%d",*(ip + i)); 
    257                 //}; 
    258         //       Zero out the previous frames to avoid replaying the contents of the ring buffer. 
    259                  writeBuffer_[zeroIndex--] = 0; 
    260         //       Wrap around the indices if necessary. 
    261                 if (zeroIndex == -1) zeroIndex = writeBufferSize_ - 1; 
    262                 if (outputReadIndex_ == writeBufferSize_) outputReadIndex_ = 0; 
     245    for (i = 0; i < ioData->mNumberBuffers; i++) { 
     246                SInt16* ip = (SInt16*)ioData->mBuffers[i].mData; 
     247         
     248                unsigned int requestedFrames = ioData->mBuffers[i].mDataByteSize / devices[add].mashStreamBasicDescription_.mBytesPerFrame; 
     249                //int requestedFrames = ioData->mBuffers[i].mDataByteSize / 2; 
     250 
     251                //printf("req frames: %d\tDataByteSize %d\ndev: %d\n",requestedFrames, ioData->mDataByteSize, devices[add].mashStreamBasicDescription_.mBytesPerFrame); 
     252                //printf("outputRender:\n"); 
     253                for (j = 0; j < requestedFrames; j++) 
     254                { 
     255                        // Copy the requested amount of data into the output buffer. 
     256                        //if (muteOutput_) 
     257                        //{      
     258                                //ip[j] = 0; 
     259                                //outputReadIndex_++; 
     260                        //} 
     261                        //else 
     262                        //{ 
     263                                //*ip++ = 10000; 
     264                                ip[j] = writeBuffer_[outputReadIndex_]; 
     265                                //memcpy(ip + j, writeBuffer_ + outputReadIndex_, 2); 
     266                                outputReadIndex_++; 
     267 
     268                                //printf("%d\n", ip[j]); 
     269                                //printf("outputReadIndex: %d\n",outputReadIndex_); 
     270                                //printf("%d",*(ip + j)); 
     271                        //}; 
     272                        //       Zero out the previous frames to avoid replaying the contents of the ring buffer. 
     273                        writeBuffer_[zeroIndex--] = 0; 
     274                        //       Wrap around the indices if necessary. 
     275                        if (zeroIndex == -1) zeroIndex = writeBufferSize_ - 1; 
     276                        if (outputReadIndex_ == writeBufferSize_) outputReadIndex_ = 0; 
     277                }; 
    263278        }; 
    264         //printf("write data: \n"); 
    265         //for (i = 0; i < blksize_; i++) 
    266         //printf("\n");  
    267279 
    268280 
     
    284296}; 
    285297 
    286 int  macosx_audio_open(audio_desc_t ad, audio_format* ifmt, audio_format *ofmt) 
     298int macosx_audio_open(audio_desc_t ad, audio_format* ifmt, audio_format *ofmt) 
    287299{ 
    288300        OSStatus err = noErr; 
     
    348360        err = AudioDeviceSetProperty(devices[ad].inputDeviceID_, NULL, inChannel, IsInput, 
    349361                                kAudioDevicePropertyNominalSampleRate, theSize, &theAnswer); 
    350          
     362 
     363        if (err != noErr) { 
     364                debug_msg("error AudioDeviceSetProperty\n"); 
     365                return 0; 
     366        } 
     367        debug_msg("Sample rate, %f\n", theAnswer); 
     368#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) 
     369        err = AudioDeviceCreateIOProcID(devices[ad].inputDeviceID_, audioIOProc, (void*)NULL, &devices[ad].inputDeviceProcID_); 
     370        if (err != noErr) { 
     371                debug_msg("error AudioDeviceCreateIOProcID, %s\n", GetMacOSStatusCommentString(err)); 
     372                return 0; 
     373        } 
     374        err = OpenADefaultComponent(kAudioUnitType_Output, kAudioUnitSubType_DefaultOutput, &(devices[ad].outputUnit_)); 
     375        // The HAL AU maybe a better way to in the future... 
     376        //err = OpenADefaultComponent(kAudioUnitType_Output, kAudioUnitSubType_HALOutput, &(devices[ad].outputUnit_)); 
     377        if (err != noErr) { 
     378                debug_msg("error OpenADefaultComponent\n"); 
     379                return 0; 
     380        } 
     381#else 
    351382        // Register the AudioDeviceIOProc. 
    352         err = AudioDeviceAddIOProc(devices[ad].inputDeviceID_, audioIOProc,NULL); 
    353         if (err != noErr) { 
    354                 debug_msg("error AudioDeviceAddIOProc"); 
     383        err = AudioDeviceAddIOProc(devices[ad].inputDeviceID_, audioIOProc, NULL); 
     384        if (err != noErr) { 
     385                debug_msg("error AudioDeviceAddIOProc\n"); 
    355386                return 0; 
    356387        } 
    357388        err = OpenDefaultAudioOutput(&(devices[ad].outputUnit_)); 
    358389        if (err != noErr) { 
    359                 debug_msg("error OpenDefaultAudioOutput"); 
    360                 return 0; 
    361         } 
    362         err = AudioUnitInitialize(devices[ad].outputUnit_); 
    363         if (err != noErr) { 
    364                 debug_msg("error AudioUnitInitialize"); 
    365                 return 0; 
    366         } 
     390                debug_msg("error OpenDefaultAudioOutput\n"); 
     391                return 0; 
     392        } 
     393#endif 
    367394        // Register a callback function to provide output data to the unit. 
    368395        devices[ad].input.inputProc = outputRenderer; 
    369396        devices[ad].input.inputProcRefCon = 0; 
    370         err = AudioUnitSetProperty(devices[ad].outputUnit_, kAudioUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &(devices[ad].input), sizeof(devices[ad].input)); 
    371  
    372         if (err != noErr) { 
    373                 debug_msg("error AudioUnitSetProperty1"); 
     397        /* These would be needed if HAL used 
     398         * UInt32 enableIO =1;  
     399        err = AudioUnitSetProperty(devices[ad].outputUnit_, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, (const void*)&enableIO, sizeof(UInt32)); 
     400        enableIO=0; 
     401        err = AudioUnitSetProperty(devices[ad].outputUnit_, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, (const void*)&enableIO, sizeof(UInt32)); 
     402        if (err != noErr) { 
     403                debug_msg("error AudioUnitSetProperty EnableIO with error %ld: %s\n", err, GetMacOSStatusErrorString(err)); 
     404                return 0; 
     405        }*/ 
     406#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) 
     407        err = AudioUnitSetProperty(devices[ad].outputUnit_, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, 0, &(devices[ad].input), sizeof(AURenderCallbackStruct)); 
     408#else 
     409        err = AudioUnitSetProperty(devices[ad].outputUnit_, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &(devices[ad].input), sizeof(AURenderCallbackStruct)); 
     410#endif 
     411 
     412        if (err != noErr) { 
     413                debug_msg("error AudioUnitSetProperty1 with error %ld: %s\n", err, GetMacOSStatusErrorString(err)); 
    374414                return 0; 
    375415        } 
     
    444484        //outputWriteIndex_ = -1; 
    445485        // Start audio processing. 
     486        err = AudioUnitInitialize(devices[ad].outputUnit_); 
     487        if (err != noErr) { 
     488                debug_msg("error AudioUnitInitialize\n"); 
     489                return 0; 
     490        } 
    446491        err = AudioDeviceStart(devices[ad].inputDeviceID_, audioIOProc); 
    447492        if (err != noErr) { 
     
    474519        if (err != noErr) fprintf(stderr, "Output device error: AudioOutputUnitStop\n"); 
    475520        // Unregister the AudioDeviceIOProc. 
    476         err = AudioDeviceRemoveIOProc(devices[ad].inputDeviceID_,audioIOProc); 
     521#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MIN_REQUIRED>=MAC_OS_X_VERSION_10_5) 
     522        err = AudioDeviceDestroyIOProcID(devices[ad].inputDeviceID_, devices[ad].inputDeviceProcID_); 
     523        if (err != noErr) fprintf(stderr, "Input device error: AudioDeviceDestroyIOProcID\n"); 
     524#else 
     525        // deprecated in favor of AudioDeviceDestroyIOProcID(); 
     526        err = AudioDeviceRemoveIOProc(devices[ad].inputDeviceID_, audioIOProc); 
    477527        if (err != noErr) fprintf(stderr, "Input device error: AudioDeviceRemoveIOProc\n"); 
     528#endif 
    478529        CloseComponent(devices[ad].outputUnit_); 
    479530        if (readBuffer_ != NULL) free(readBuffer_); readBuffer_ = NULL; 
     
    700751{ 
    701752        UNUSED(ad); 
    702         return (availableInput_ != NULL); 
     753        return (availableInput_ != 0); 
    703754} 
    704755