Julius 4.2
libsent/src/adin/adin_mic_darwin_coreaudio.c
説明を見る。
00001 
00036 /*
00037  * adin_mic_darwin_coreaudio.c
00038  *
00039  * adin microphone library for CoreAudio API
00040  *
00041  * by Masatomo Hashimoto <m.hashimoto@aist.go.jp>
00042  *
00043  * Tested on Mac OS X v10.3.9 and v10.4.1
00044  *
00045  */
00046 
00047 /* $Id: adin_mic_darwin_coreaudio.c,v 1.6 2009/12/08 01:49:21 sumomo Exp $ */
00048 
00049 #include <CoreAudio/CoreAudio.h>
00050 #include <AudioUnit/AudioUnit.h>
00051 #include <AudioUnit/AudioOutputUnit.h>
00052 #include <AudioToolbox/AudioConverter.h>
00053 #include <CoreServices/CoreServices.h>
00054 #include <pthread.h>
00055 #include <stdio.h>
00056 
00057 #define DEVICE_NAME_LEN 128
00058 #define BUF_SAMPLES 4096
00059 
00060 static UInt32 ConvQuality = kAudioConverterQuality_Medium;
00061 
00062 typedef SInt16 Sample;
00063 static UInt32 BytesPerSample = sizeof(Sample);
00064 
00065 #define BITS_PER_BYTE 8
00066 
00067 static AudioDeviceID InputDeviceID;
00068 static AudioUnit InputUnit;
00069 static AudioConverterRef Converter;
00070 
00071 static pthread_mutex_t MutexInput;
00072 static pthread_cond_t CondInput;
00073 
00074 static bool CoreAudioRecordStarted = FALSE;
00075 static bool CoreAudioHasInputDevice = FALSE;
00076 static bool CoreAudioInit = FALSE;
00077 
00078 static UInt32 NumSamplesAvailable = 0;
00079 
00080 static UInt32 InputDeviceBufferSamples = 0;
00081 static UInt32 InputBytesPerPacket = 0;
00082 static UInt32 InputFramesPerPacket = 0;
00083 static UInt32 InputSamplesPerPacket = 0;
00084 static UInt32 OutputBitsPerChannel = 0;
00085 static UInt32 OutputBytesPerPacket = 0;
00086 static UInt32 OutputSamplesPerPacket = 0;
00087 
00088 static AudioBufferList* BufList;
00089 static AudioBufferList BufListBackup;
00090 static AudioBufferList* BufListConverted;
00091 
00092 static char deviceName[DEVICE_NAME_LEN];
00093 
00094 #ifndef boolean
00095 typedef unsigned char boolean;
00096 #endif
00097 
00098 static void printStreamInfo(AudioStreamBasicDescription* desc) {
00099   jlog("Stat: adin_darwin: ----- details of stream -----\n");
00100   jlog("Stat: adin_darwin: sample rate: %f\n", desc->mSampleRate);
00101   jlog("Stat: adin_darwin: format flags: %s%s%s%s%s%s%s\n", 
00102            desc->mFormatFlags & kAudioFormatFlagIsFloat ? 
00103            "[float]" : "",
00104            desc->mFormatFlags & kAudioFormatFlagIsBigEndian ? 
00105            "[big endian]" : "",
00106            desc->mFormatFlags & kAudioFormatFlagIsSignedInteger ? 
00107            "[signed integer]" : "",
00108            desc->mFormatFlags & kAudioFormatFlagIsPacked ? 
00109            "[packed]" : "",
00110            desc->mFormatFlags & kAudioFormatFlagIsAlignedHigh ? 
00111            "[aligned high]" : "",
00112            desc->mFormatFlags & kAudioFormatFlagIsNonInterleaved ? 
00113            "[non interleaved]" : "",
00114            desc->mFormatFlags & kAudioFormatFlagsAreAllClear ? 
00115            "[all clear]" : ""
00116            );
00117   jlog("Stat: adin_darwin: bytes per packet: %d\n", desc->mBytesPerPacket);
00118   jlog("Stat: adin_darwin: frames per packet: %d\n", desc->mFramesPerPacket);
00119   jlog("Stat: adin_darwin: bytes per frame: %d\n", desc->mBytesPerFrame);
00120   jlog("Stat: adin_darwin: channels per frame: %d\n", desc->mChannelsPerFrame);
00121   jlog("Stat: adin_darwin: bits per channel: %d\n", desc->mBitsPerChannel);
00122   jlog("Stat: adin_darwin: -----------------------------------\n");
00123 }
00124 
00125 static void printAudioBuffer(AudioBuffer* buf) {
00126   int sz = buf->mDataByteSize / BytesPerSample;
00127   int i;
00128   Sample* p = (Sample*)(buf->mData);
00129   for (i = 0; i < sz; i++) {
00130     printf("%d ", p[i]);
00131   }
00132 }
00133 
00134 static AudioBufferList* 
00135 allocateAudioBufferList(UInt32 data_bytes, UInt32 nsamples, UInt32 nchan) {
00136 
00137   AudioBufferList* bufl;
00138 
00139 #ifdef DEBUG
00140   jlog("Stat: adin_darwin: allocateAudioBufferList: data_bytes:%d nsamples:%d nchan:%d\n",
00141            data_bytes, nsamples, nchan);
00142 #endif
00143 
00144   bufl = (AudioBufferList*)(malloc(sizeof(AudioBufferList)));
00145 
00146   if(bufl == NULL) {
00147     jlog("Erorr: adin_darwin: allocateAudioBufferList: failed\n");
00148     return NULL;
00149   }
00150 
00151   bufl->mNumberBuffers = nchan;
00152 
00153   int i;
00154   for (i = 0; i < nchan; i++) {
00155     bufl->mBuffers[i].mNumberChannels = nchan;
00156     bufl->mBuffers[i].mDataByteSize = data_bytes * nsamples;
00157     bufl->mBuffers[i].mData = malloc(data_bytes * nsamples);
00158     
00159     if(bufl->mBuffers[i].mData == NULL) {
00160       jlog("Erorr: adin_darwin: allocateAudioBufferList: malloc for mBuffers[%d] failed\n", i);
00161       return NULL;
00162     }
00163   }
00164   return bufl;
00165 }
00166 
00167 /* gives input data for Converter */
00168 static OSStatus 
00169 ConvInputProc(AudioConverterRef inConv,
00170               UInt32* ioNumDataPackets,
00171               AudioBufferList* ioData, // to be filled
00172               AudioStreamPacketDescription** outDataPacketDesc,
00173               void* inUserData)
00174 {
00175   int i;
00176   UInt32 nPacketsRequired = *ioNumDataPackets;
00177   UInt32 nBytesProvided = 0;
00178   UInt32 nBytesRequired;
00179   UInt32 n;
00180   
00181   pthread_mutex_lock(&MutexInput);
00182 
00183 #ifdef DEBUG
00184   jlog("Stat: adin_darwin: ConvInputProc: required %d packets\n", nPacketsRequired);
00185 #endif
00186 
00187   while(NumSamplesAvailable == 0){
00188     pthread_cond_wait(&CondInput, &MutexInput);
00189   }
00190 
00191   for(i = 0; i < BufList->mNumberBuffers; i++) {
00192     n = BufList->mBuffers[i].mDataByteSize;
00193     if (nBytesProvided != 0 && nBytesProvided != n) {
00194       jlog("Warning: adin_darwin: buffer size mismatch\n");
00195     }
00196     nBytesProvided = n;
00197   }
00198 
00199 #ifdef DEBUG
00200   jlog("Stat: adin_darwin: ConvInputProc: %d bytes in buffer\n", nBytesProvided);
00201 #endif
00202 
00203   for(i = 0; i < BufList->mNumberBuffers; i++) {
00204     ioData->mBuffers[i].mNumberChannels = 
00205       BufList->mBuffers[i].mNumberChannels;
00206 
00207     nBytesRequired = nPacketsRequired * InputBytesPerPacket;
00208 
00209     if(nBytesRequired < nBytesProvided) {
00210       ioData->mBuffers[i].mData = BufList->mBuffers[i].mData;
00211       ioData->mBuffers[i].mDataByteSize = nBytesRequired;
00212       BufList->mBuffers[i].mData += nBytesRequired;
00213       BufList->mBuffers[i].mDataByteSize = nBytesProvided - nBytesRequired;
00214     } else {
00215       ioData->mBuffers[i].mData = BufList->mBuffers[i].mData;
00216       ioData->mBuffers[i].mDataByteSize = nBytesProvided;
00217       
00218       BufList->mBuffers[i].mData = BufListBackup.mBuffers[i].mData;
00219 
00220     }
00221 
00222   }
00223 
00224   *ioNumDataPackets = ioData->mBuffers[0].mDataByteSize / InputBytesPerPacket;
00225 
00226 #ifdef DEBUG
00227   jlog("Stat: adin_darwin: ConvInputProc: provided %d packets\n", *ioNumDataPackets);
00228 #endif
00229 
00230   NumSamplesAvailable = 
00231     nBytesProvided / BytesPerSample - *ioNumDataPackets * InputSamplesPerPacket;
00232 
00233 #ifdef DEBUG
00234   jlog("Stat: adin_darwin: ConvInputProc: %d samples available\n", NumSamplesAvailable);
00235 #endif
00236 
00237   pthread_mutex_unlock(&MutexInput);
00238 
00239   return noErr;
00240 }
00241 
00242 
00243 /* called when input data are available (an AURenderCallback) */
00244 static OSStatus 
00245 InputProc(void* inRefCon,
00246           AudioUnitRenderActionFlags* ioActionFlags,
00247           const AudioTimeStamp* inTimeStamp,
00248           UInt32 inBusNumber,
00249           UInt32 inNumberFrames,
00250           AudioBufferList* ioData // null
00251           )
00252 {
00253   OSStatus status = noErr;
00254   int i;
00255 
00256   pthread_mutex_lock(&MutexInput);
00257 
00258   if (NumSamplesAvailable == 0) {
00259 
00260     status = AudioUnitRender(InputUnit,
00261                              ioActionFlags,
00262                              inTimeStamp,
00263                              inBusNumber,
00264                              inNumberFrames,
00265                              BufList);
00266     NumSamplesAvailable = 
00267       BufList->mBuffers[0].mDataByteSize / InputBytesPerPacket;
00268 
00269 #ifdef DEBUG
00270     printAudioBuffer(BufList->mBuffers);
00271 #endif
00272   }
00273 
00274   pthread_mutex_unlock(&MutexInput);
00275   
00276   pthread_cond_signal(&CondInput);
00277 
00278   /*
00279   jlog("Stat: adin_darwin: InputProc: %d bytes filled (BufList)\n", 
00280           BufList->mBuffers[0].mDataByteSize);
00281   */
00282 
00283   return status;
00284 }
00285 
00286 
00287 /* initialize default sound device */
00288 boolean adin_mic_standby(int sfreq, void* dummy) {
00289   OSStatus status;
00290   UInt32 propertySize;
00291   struct AudioStreamBasicDescription inDesc;
00292   int err;
00293 
00294   jlog("Stat: adin_darwin: sample rate = %d\n", sfreq);
00295 
00296   if (CoreAudioInit) 
00297     return TRUE;
00298 
00299 #ifdef MAC_OS_X_VERSION_10_6
00300   AudioComponent halout;
00301   AudioComponentDescription haloutDesc;
00302 #else
00303   Component halout;
00304   ComponentDescription haloutDesc;
00305 #endif
00306    
00307   haloutDesc.componentType = kAudioUnitType_Output;
00308   haloutDesc.componentSubType = kAudioUnitSubType_HALOutput;
00309   haloutDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
00310   haloutDesc.componentFlags = 0;
00311   haloutDesc.componentFlagsMask = 0;
00312   halout = FindNextComponent(NULL, &haloutDesc);
00313 
00314   if(halout == NULL) {
00315     jlog("Error: adin_darwin: no HALOutput component found\n");
00316     return FALSE;
00317   }
00318 
00319   OpenAComponent(halout, &InputUnit);
00320 
00321   UInt32 enableIO;
00322   
00323   enableIO = 1;
00324   status = AudioUnitSetProperty(InputUnit, 
00325                                 kAudioOutputUnitProperty_EnableIO,
00326                                 kAudioUnitScope_Input,
00327                                 1,
00328                                 &enableIO,
00329                                 sizeof(enableIO));
00330     if (status != noErr) {
00331       jlog("Error: adin_darwin: cannot set InputUnit's EnableIO(Input)\n");
00332       return FALSE;
00333     }
00334 
00335   enableIO = 0;
00336   status = AudioUnitSetProperty(InputUnit, 
00337                                 kAudioOutputUnitProperty_EnableIO,
00338                                 kAudioUnitScope_Output,
00339                                 0,
00340                                 &enableIO,
00341                                 sizeof(enableIO));
00342     if (status != noErr) {
00343       jlog("Error: adin_darwin: cannot set InputUnit's EnableIO(Output)\n");
00344       return FALSE;
00345     }
00346 
00347 
00348   /* get default input device */
00349   propertySize = sizeof(InputDeviceID);
00350   status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
00351                                     &propertySize,
00352                                     &InputDeviceID);
00353   if (status != noErr) {
00354     jlog("Error: adin_darwin: cannot get default input device\n");
00355     return FALSE;
00356   }
00357 
00358   if (InputDeviceID == kAudioDeviceUnknown) {
00359     jlog("Error: adin_darwin: no available input device found\n");
00360     return FALSE;
00361 
00362   } else {
00363 
00364     CoreAudioHasInputDevice = TRUE;
00365 
00366     /* get input device name */
00367     propertySize = sizeof(char) * DEVICE_NAME_LEN;
00368     status = AudioDeviceGetProperty(InputDeviceID,
00369                                     1,
00370                                     1,
00371                                     kAudioDevicePropertyDeviceName,
00372                                     &propertySize,
00373                                     deviceName);
00374     if (status != noErr) {
00375       jlog("Error: adin_darwin: cannot get device name\n");
00376       return FALSE;
00377     }
00378 
00379     status = AudioUnitSetProperty(InputUnit,
00380                                   kAudioOutputUnitProperty_CurrentDevice,
00381                                   kAudioUnitScope_Global,
00382                                   0,
00383                                   &InputDeviceID,
00384                                   sizeof(InputDeviceID));
00385 
00386     if (status != noErr) {
00387       jlog("Error: adin_darwin: cannot bind default input device to AudioUnit\n");
00388       return FALSE;
00389     }
00390 
00391     /* get input device's format */
00392     propertySize = sizeof(inDesc);
00393     status = AudioDeviceGetProperty(InputDeviceID,
00394                                     1,
00395                                     1,
00396                                     kAudioDevicePropertyStreamFormat,
00397                                     &propertySize,
00398                                     &inDesc);
00399     if (status != noErr) {
00400       jlog("Error: adin_darwin: cannot get input device's stream format\n");
00401       return FALSE;
00402     }
00403 
00404     /* get input device's buffer frame size */
00405     UInt32 bufferFrameSize;
00406     propertySize = sizeof(bufferFrameSize);
00407     status = AudioDeviceGetProperty(InputDeviceID,
00408                                     1,
00409                                     1,
00410                                     kAudioDevicePropertyBufferFrameSize,
00411                                     &propertySize,
00412                                     &bufferFrameSize);
00413     if (status != noErr) {
00414       jlog("Error: adin_darwin: cannot get input device's buffer frame size\n");
00415       return FALSE;
00416     }
00417 
00418     jlog("Stat: adin_darwin: using device \"%s\" for input\n", deviceName);
00419     jlog("Stat: adin_darwin: sample rate %f\n\t%ld channels\n\t%ld-bit sample\n",
00420             inDesc.mSampleRate,
00421             inDesc.mChannelsPerFrame,
00422             inDesc.mBitsPerChannel);
00423 
00424     jlog("Stat: adin_darwin: %d buffer frames\n", bufferFrameSize);
00425 
00426 
00427     printStreamInfo(&inDesc);
00428 
00429     UInt32 formatFlagEndian = 
00430       inDesc.mFormatFlags & kAudioFormatFlagIsBigEndian;
00431 
00432     inDesc.mFormatFlags = 
00433       kAudioFormatFlagIsSignedInteger | 
00434       kAudioFormatFlagIsPacked | 
00435       formatFlagEndian;
00436 
00437     inDesc.mBytesPerPacket = BytesPerSample;
00438     inDesc.mFramesPerPacket = 1;
00439     inDesc.mBytesPerFrame = BytesPerSample;
00440     inDesc.mChannelsPerFrame = 1;
00441     inDesc.mBitsPerChannel = BytesPerSample * BITS_PER_BYTE;
00442 
00443     printStreamInfo(&inDesc);
00444 
00445     propertySize = sizeof(inDesc);
00446     status = AudioUnitSetProperty(InputUnit, 
00447                                   kAudioUnitProperty_StreamFormat,
00448                                   kAudioUnitScope_Output,
00449                                   1,
00450                                   &inDesc,
00451                                   propertySize
00452                                   );
00453     if (status != noErr) {
00454       jlog("Error: adin_darwin: cannot set InputUnit's stream format\n");
00455       return FALSE;
00456     }
00457 
00458     InputBytesPerPacket = inDesc.mBytesPerPacket;
00459     InputFramesPerPacket = inDesc.mFramesPerPacket;
00460     InputSamplesPerPacket = InputBytesPerPacket / BytesPerSample;
00461 
00462     InputDeviceBufferSamples = 
00463       bufferFrameSize * InputSamplesPerPacket * InputFramesPerPacket;
00464 
00465     jlog("Stat: adin_darwin: input device's buffer size (# of samples): %d\n", 
00466              InputDeviceBufferSamples);
00467 
00468     AudioStreamBasicDescription outDesc;
00469     outDesc.mSampleRate = sfreq;
00470     outDesc.mFormatID = kAudioFormatLinearPCM;
00471     outDesc.mFormatFlags = 
00472       kAudioFormatFlagIsSignedInteger | 
00473       kAudioFormatFlagIsPacked | 
00474       formatFlagEndian;
00475     outDesc.mBytesPerPacket = BytesPerSample;
00476     outDesc.mFramesPerPacket = 1;
00477     outDesc.mBytesPerFrame = BytesPerSample;
00478     outDesc.mChannelsPerFrame = 1;
00479     outDesc.mBitsPerChannel = BytesPerSample * BITS_PER_BYTE;
00480 
00481     printStreamInfo(&outDesc);
00482 
00483     OutputBitsPerChannel = outDesc.mBitsPerChannel;
00484     OutputBytesPerPacket = outDesc.mBytesPerPacket;
00485 
00486     OutputSamplesPerPacket = (OutputBitsPerChannel / BITS_PER_BYTE) / OutputBytesPerPacket;
00487 
00488     status = AudioConverterNew(&inDesc, &outDesc, &Converter);
00489     if (status != noErr){
00490       jlog("Error: adin_darwin: cannot create audio converter\n");
00491       return FALSE;
00492     }
00493 
00494     /*
00495     UInt32 nChan = inDesc.mChannelsPerFrame;
00496     int i;
00497 
00498     if (inDesc.mFormatFlags & kAudioFormatFlagIsNonInterleaved && nChan > 1) {
00499       UInt32 chmap[nChan];
00500       for (i = 0; i < nChan; i++)
00501         chmap[i] = 0;
00502 
00503       status = AudioConverterSetProperty(Converter, 
00504                                          kAudioConverterChannelMap,
00505                                          sizeof(chmap), chmap);
00506       if (status != noErr){
00507         jlog("cannot set audio converter's channel map\n");
00508         return FALSE;
00509       }
00510     }
00511     */
00512 
00513     status = 
00514       AudioConverterSetProperty(Converter, 
00515                                 kAudioConverterSampleRateConverterQuality,
00516                                 sizeof(ConvQuality), &ConvQuality);
00517     if (status != noErr){
00518       jlog("Error: adin_darwin: cannot set audio converter quality\n");
00519       return FALSE;
00520     }
00521 
00522 
00523     //jlog("Stat: adin_darwin: audio converter generated\n");
00524 
00525     /* allocate buffers */
00526     BufList = allocateAudioBufferList(inDesc.mBitsPerChannel / BITS_PER_BYTE, 
00527                                       InputDeviceBufferSamples, 1);
00528     if (BufList == NULL) return FALSE;
00529 
00530     BufListBackup.mNumberBuffers = BufList->mNumberBuffers;
00531 
00532     BufListBackup.mBuffers[0].mNumberChannels = 1;
00533     BufListBackup.mBuffers[0].mDataByteSize = 
00534       BufList->mBuffers[0].mDataByteSize;
00535     BufListBackup.mBuffers[0].mData = BufList->mBuffers[0].mData;
00536 
00537     BufListConverted = allocateAudioBufferList(BytesPerSample, BUF_SAMPLES, 1);
00538     if (BufListConverted == NULL) return FALSE;
00539     //jlog("Stat: adin_darwin: buffers allocated\n");
00540 
00541     err = pthread_mutex_init(&MutexInput, NULL);
00542     if (err) {
00543       jlog("Error: adin_darwin: cannot init mutex\n");
00544       return FALSE;
00545     }
00546     err = pthread_cond_init(&CondInput, NULL);
00547     if (err) {
00548       jlog("Error: adin_darwin: cannot init condition variable\n");
00549       return FALSE;
00550     }
00551 
00552     /* register the callback */
00553     AURenderCallbackStruct input;
00554     input.inputProc = InputProc; // an AURenderCallback
00555     input.inputProcRefCon = 0;
00556     AudioUnitSetProperty(InputUnit,
00557                          kAudioOutputUnitProperty_SetInputCallback,
00558                          kAudioUnitScope_Global,
00559                          0,
00560                          &input,
00561                          sizeof(input));
00562 
00563     status = AudioUnitInitialize(InputUnit);
00564     if (status != noErr){
00565       jlog("Error: adin_darwin: InputUnit initialize failed\n");
00566       return FALSE;
00567     }
00568 
00569   }
00570 
00571   CoreAudioInit = TRUE;
00572 
00573   jlog("Stat: adin_darwin: CoreAudio: initialized\n");
00574 
00575   return TRUE;
00576 }
00577 
00578 boolean adin_mic_begin(char *pathname){ return TRUE; }
00579 boolean adin_mic_end(){ return TRUE; }
00580 
00581 int adin_mic_read(void *buffer, int nsamples) {
00582   OSStatus status;
00583 
00584 #ifdef DEBUG
00585   jlog("Stat: adin_darwin: read: %d samples required\n", nsamples);
00586 #endif
00587 
00588   if (!CoreAudioHasInputDevice) 
00589     return -1;
00590 
00591   if (!CoreAudioRecordStarted) {
00592     status = AudioOutputUnitStart(InputUnit);
00593     CoreAudioRecordStarted = TRUE;
00594   }
00595   
00596   UInt32 capacity = BUF_SAMPLES * OutputSamplesPerPacket;
00597   UInt32 npackets = nsamples * OutputSamplesPerPacket;
00598 
00599   UInt32 numDataPacketsNeeded;
00600 
00601   Sample* inputDataBuf = (Sample*)(BufListConverted->mBuffers[0].mData);
00602 
00603   numDataPacketsNeeded = npackets < capacity ? npackets : capacity;
00604 
00605 #ifdef DEBUG
00606   jlog("Stat: adin_darwin: numDataPacketsNeeded=%d\n", numDataPacketsNeeded);
00607 #endif
00608 
00609   status = AudioConverterFillComplexBuffer(Converter, 
00610                                            ConvInputProc, 
00611                                            NULL, // user data
00612                                            &numDataPacketsNeeded, 
00613                                            BufListConverted, 
00614                                            NULL // packet description
00615                                            );
00616   if (status != noErr) {
00617     jlog("Error: adin_darwin: AudioConverterFillComplexBuffer: failed\n");
00618     return -1;
00619   }
00620 
00621 #ifdef DEBUG
00622   jlog("Stat: adin_darwin: %d bytes filled (BufListConverted)\n", 
00623            BufListConverted->mBuffers[0].mDataByteSize);
00624 #endif
00625 
00626   int providedSamples = numDataPacketsNeeded / OutputSamplesPerPacket;
00627 
00628   pthread_mutex_lock(&MutexInput);
00629 
00630 #ifdef DEBUG
00631   jlog("Stat: adin_darwin: provided samples: %d\n", providedSamples);
00632 #endif
00633 
00634   Sample* dst_data = (Sample*)buffer;
00635 
00636   int i;
00637 
00638   int count = 0;
00639 
00640   for (i = 0; i < providedSamples; i++) {
00641     dst_data[i] = inputDataBuf[i];
00642     if (dst_data[i] == 0) count++;
00643   }
00644 
00645   //jlog("Stat: adin_darwin: %d zero samples\n", count);
00646 
00647 
00648   pthread_mutex_unlock(&MutexInput);
00649 
00650 #ifdef DEBUG
00651   jlog("Stat: adindarwin: EXIT: %d samples provided\n", providedSamples);
00652 #endif
00653 
00654   return providedSamples;
00655 }
00656 
00657 void adin_mic_pause() {
00658   OSStatus status;
00659 
00660   if (CoreAudioHasInputDevice && CoreAudioRecordStarted) {
00661     status = AudioOutputUnitStop(InputUnit);
00662     CoreAudioRecordStarted = FALSE;
00663   }
00664   return;
00665 }
00666 
00674 char *
00675 adin_mic_input_name()
00676 {
00677   return(deviceName);
00678 }