?? adin_mic_darwin_coreaudio.c
字號:
/** * @file adin_mic_darwin_coreaudio.c * * <JA> * @brief adin microphone library for CoreAudio API * * by Masatomo Hashimoto <m.hashimoto@aist.go.jp> * * Tested on Mac OS X v10.3.9 and v10.4.1 * * このプログラムは· * 迫惟乖蠟恕客 緩度禱窖另圭甫墊疥 攫鼠禱窖甫墊嬸嚏 * ユビキタスソフトウェアグル〖プ * より捏丁されましたˉ * </JA> * * <EN> * @brief adin microphone library for CoreAudio API * * by Masatomo Hashimoto <m.hashimoto@aist.go.jp> * * Tested on Mac OS X v10.3.9 and v10.4.1 * * This file has been contributed from the Ubiquitous Software Group, * Information Technology Research Institute, AIST. * * </EN> * * @author Masatomo Hashimoto * @date Wed Oct 12 11:31:27 2005 * * $Revision: 1.2 $ * *//* * adin_mic_darwin_coreaudio.c * * adin microphone library for CoreAudio API * * by Masatomo Hashimoto <m.hashimoto@aist.go.jp> * * Tested on Mac OS X v10.3.9 and v10.4.1 * *//* $Id: adin_mic_darwin_coreaudio.c,v 1.2 2007/12/18 08:45:50 sumomo Exp $ */#include <CoreAudio/CoreAudio.h>#include <AudioUnit/AudioUnit.h>#include <AudioUnit/AudioOutputUnit.h>#include <AudioToolbox/AudioConverter.h>#include <pthread.h>#include <stdio.h>#define DEVICE_NAME_LEN 128#define BUF_SAMPLES 4096static UInt32 ConvQuality = kAudioConverterQuality_Medium;typedef SInt16 Sample;static UInt32 BytesPerSample = sizeof(Sample);#define BITS_PER_BYTE 8static AudioDeviceID InputDeviceID;static AudioUnit InputUnit;static AudioConverterRef Converter;static pthread_mutex_t MutexInput;static pthread_cond_t CondInput;static bool CoreAudioRecordStarted = FALSE;static bool CoreAudioHasInputDevice = FALSE;static bool CoreAudioInit = FALSE;static UInt32 NumSamplesAvailable = 0;static UInt32 InputDeviceBufferSamples = 0;static UInt32 InputBytesPerPacket = 0;static UInt32 InputFramesPerPacket = 0;static UInt32 InputSamplesPerPacket = 0;static UInt32 OutputBitsPerChannel = 0;static UInt32 OutputBytesPerPacket = 0;static UInt32 OutputSamplesPerPacket = 0;static AudioBufferList* BufList;static AudioBufferList BufListBackup;static AudioBufferList* BufListConverted;#ifndef booleantypedef unsigned char boolean;#endifstatic void printStreamInfo(AudioStreamBasicDescription* desc) { jlog("Stat: adin_darwin: ----- details of stream -----\n"); jlog("Stat: adin_darwin: sample rate: %f\n", desc->mSampleRate); jlog("Stat: adin_darwin: format flags: %s%s%s%s%s%s%s\n", desc->mFormatFlags & kAudioFormatFlagIsFloat ? "[float]" : "", desc->mFormatFlags & kAudioFormatFlagIsBigEndian ? "[big endian]" : "", desc->mFormatFlags & kAudioFormatFlagIsSignedInteger ? "[signed integer]" : "", desc->mFormatFlags & kAudioFormatFlagIsPacked ? "[packed]" : "", desc->mFormatFlags & kAudioFormatFlagIsAlignedHigh ? "[aligned high]" : "", desc->mFormatFlags & kAudioFormatFlagIsNonInterleaved ? "[non interleaved]" : "", desc->mFormatFlags & kAudioFormatFlagsAreAllClear ? "[all clear]" : "" ); jlog("Stat: adin_darwin: bytes per packet: %d\n", desc->mBytesPerPacket); jlog("Stat: adin_darwin: frames per packet: %d\n", desc->mFramesPerPacket); jlog("Stat: adin_darwin: bytes per frame: %d\n", desc->mBytesPerFrame); jlog("Stat: adin_darwin: channels per frame: %d\n", desc->mChannelsPerFrame); jlog("Stat: adin_darwin: bits per channel: %d\n", desc->mBitsPerChannel); jlog("Stat: adin_darwin: -----------------------------------\n");}static void printAudioBuffer(AudioBuffer* buf) { int sz = buf->mDataByteSize / BytesPerSample; int i; Sample* p = (Sample*)(buf->mData); for (i = 0; i < sz; i++) { printf("%d ", p[i]); }}static AudioBufferList* allocateAudioBufferList(UInt32 data_bytes, UInt32 nsamples, UInt32 nchan) { AudioBufferList* bufl;#ifdef DEBUG jlog("Stat: adin_darwin: allocateAudioBufferList: data_bytes:%d nsamples:%d nchan:%d\n", data_bytes, nsamples, nchan);#endif bufl = (AudioBufferList*)(malloc(sizeof(AudioBufferList))); if(bufl == NULL) { jlog("Erorr: adin_darwin: allocateAudioBufferList: failed\n"); return NULL; } bufl->mNumberBuffers = nchan; int i; for (i = 0; i < nchan; i++) { bufl->mBuffers[i].mNumberChannels = nchan; bufl->mBuffers[i].mDataByteSize = data_bytes * nsamples; bufl->mBuffers[i].mData = malloc(data_bytes * nsamples); if(bufl->mBuffers[i].mData == NULL) { jlog("Erorr: adin_darwin: allocateAudioBufferList: malloc for mBuffers[%d] failed\n", i); return NULL; } } return bufl;}/* gives input data for Converter */static OSStatus ConvInputProc(AudioConverterRef inConv, UInt32* ioNumDataPackets, AudioBufferList* ioData, // to be filled AudioStreamPacketDescription** outDataPacketDesc, void* inUserData){ int i; UInt32 nPacketsRequired = *ioNumDataPackets; UInt32 nBytesProvided = 0; UInt32 nBytesRequired; UInt32 n; pthread_mutex_lock(&MutexInput);#ifdef DEBUG jlog("Stat: adin_darwin: ConvInputProc: required %d packets\n", nPacketsRequired);#endif while(NumSamplesAvailable == 0){ pthread_cond_wait(&CondInput, &MutexInput); } for(i = 0; i < BufList->mNumberBuffers; i++) { n = BufList->mBuffers[i].mDataByteSize; if (nBytesProvided != 0 && nBytesProvided != n) { jlog("Warning: adin_darwin: buffer size mismatch\n"); } nBytesProvided = n; }#ifdef DEBUG jlog("Stat: adin_darwin: ConvInputProc: %d bytes in buffer\n", nBytesProvided);#endif for(i = 0; i < BufList->mNumberBuffers; i++) { ioData->mBuffers[i].mNumberChannels = BufList->mBuffers[i].mNumberChannels; nBytesRequired = nPacketsRequired * InputBytesPerPacket; if(nBytesRequired < nBytesProvided) { ioData->mBuffers[i].mData = BufList->mBuffers[i].mData; ioData->mBuffers[i].mDataByteSize = nBytesRequired; BufList->mBuffers[i].mData += nBytesRequired; BufList->mBuffers[i].mDataByteSize = nBytesProvided - nBytesRequired; } else { ioData->mBuffers[i].mData = BufList->mBuffers[i].mData; ioData->mBuffers[i].mDataByteSize = nBytesProvided; BufList->mBuffers[i].mData = BufListBackup.mBuffers[i].mData; } } *ioNumDataPackets = ioData->mBuffers[0].mDataByteSize / InputBytesPerPacket;#ifdef DEBUG jlog("Stat: adin_darwin: ConvInputProc: provided %d packets\n", *ioNumDataPackets);#endif NumSamplesAvailable = nBytesProvided / BytesPerSample - *ioNumDataPackets * InputSamplesPerPacket;#ifdef DEBUG jlog("Stat: adin_darwin: ConvInputProc: %d samples available\n", NumSamplesAvailable);#endif pthread_mutex_unlock(&MutexInput); return noErr;}/* called when input data are available (an AURenderCallback) */static OSStatus InputProc(void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList* ioData // null ){ OSStatus status = noErr; int i; pthread_mutex_lock(&MutexInput); if (NumSamplesAvailable == 0) { status = AudioUnitRender(InputUnit, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, BufList); NumSamplesAvailable = BufList->mBuffers[0].mDataByteSize / InputBytesPerPacket;#ifdef DEBUG printAudioBuffer(BufList->mBuffers);#endif } pthread_mutex_unlock(&MutexInput); pthread_cond_signal(&CondInput); /* jlog("Stat: adin_darwin: InputProc: %d bytes filled (BufList)\n", BufList->mBuffers[0].mDataByteSize); */ return status;}/* initialize default sound device */boolean adin_mic_standby(int sfreq, void* dummy) { OSStatus status; UInt32 propertySize; char deviceName[DEVICE_NAME_LEN]; struct AudioStreamBasicDescription inDesc; int err; jlog("Stat: adin_darwin: sample rate = %d\n", sfreq); if (CoreAudioInit) return TRUE; Component halout; ComponentDescription haloutDesc; haloutDesc.componentType = kAudioUnitType_Output; haloutDesc.componentSubType = kAudioUnitSubType_HALOutput; haloutDesc.componentManufacturer = kAudioUnitManufacturer_Apple; haloutDesc.componentFlags = 0; haloutDesc.componentFlagsMask = 0; halout = FindNextComponent(NULL, &haloutDesc); if(halout == NULL) { jlog("Error: adin_darwin: no HALOutput component found\n"); return FALSE; } OpenAComponent(halout, &InputUnit); UInt32 enableIO; enableIO = 1; status = AudioUnitSetProperty(InputUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO)); if (status != noErr) { jlog("Error: adin_darwin: cannot set InputUnit's EnableIO(Input)\n"); return FALSE; } enableIO = 0; status = AudioUnitSetProperty(InputUnit, kAudioOutputUnitProperty_EnableIO,
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -