1/********************************************************************************************************************************** 2* 3* OpenAL cross platform audio library 4* Copyright (c) 2005, Apple Computer, Inc. All rights reserved. 5* 6* Redistribution and use in source and binary forms, with or without modification, are permitted provided 7* that the following conditions are met: 8* 9* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 11* disclaimer in the documentation and/or other materials provided with the distribution. 12* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its contributors may be used to endorse or promote 13* products derived from this software without specific prior written permission. 14* 15* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 17* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 18* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 19* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 20* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 21* 22**********************************************************************************************************************************/ 23 24#ifndef __OAL_CAPTURE_DEVICE__ 25#define __OAL_CAPTURE_DEVICE__ 26 27#include "oalImp.h" 28#include "CAStreamBasicDescription.h" 29#include "CABufferList.h" 30 31#include <CoreAudio/AudioHardware.h> 32#include <AudioToolbox/AudioToolbox.h> 33#include <AudioUnit/AudioUnit.h> 34#include <map> 35#include <libkern/OSAtomic.h> 36 37#define LOG_CAPTUREDEVICE_VERBOSE 0 38 39// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 40// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 41// OALCaptureDevices 42// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 43// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 44 45#pragma mark _____OALCaptureDevice_____ 46class OALCaptureDevice 47{ 48#pragma mark __________ Public_Class_Members 49 public: 50 51 OALCaptureDevice(const char* inDeviceName, uintptr_t inSelfToken, UInt32 inSampleRate, UInt32 inFormat, UInt32 inBufferSize); 52 ~OALCaptureDevice(); 53 54 void StartCapture(); 55 void StopCapture(); 56 57 OSStatus GetFrames(UInt32 inFrameCount, UInt8* inBuffer); 58 UInt32 AvailableFrames(); 59 void SetError(ALenum errorCode); 60 ALenum GetError(); 61 62 // we need to mark the capture device if it is being used to prevent deletion from another thread 63 void SetInUseFlag() { OSAtomicIncrement32Barrier(&mInUseFlag); } 64 void ClearInUseFlag() { OSAtomicDecrement32Barrier(&mInUseFlag); } 65 volatile int32_t IsInUse() { return mInUseFlag; } 66 67#pragma mark __________ Private_Class_Members 68 69 private: 70#if LOG_CAPTUREDEVICE_VERBOSE 71 uintptr_t mSelfToken; 72#endif 73 ALenum mCurrentError; 74 bool mCaptureOn; 75 SInt64 mStoreSampleTime; // increment on each read in the input proc, and pass to the ring buffer class when writing, reset on each stop 76 SInt64 mFetchSampleTime; // increment on each read in the input proc, and pass to the ring buffer class when writing, reset on each stop 77 AudioUnit mInputUnit; 78 CAStreamBasicDescription mNativeFormat; 79 CAStreamBasicDescription mRequestedFormat; 80 CAStreamBasicDescription mOutputFormat; 81 OALRingBuffer* mRingBuffer; // the ring buffer 82 UInt8* mBufferData; 83 AudioConverterRef mAudioConverter; 84 Float64 mSampleRateRatio; 85 UInt32 mRequestedRingFrames; 86 CABufferList* mAudioInputPtrs; 87 volatile int32_t mInUseFlag; // flag to indicate the device is currently being used by one or more threads 88 89 void InitializeAU (const char* inDeviceName); 90 static OSStatus InputProc( void * inRefCon, 91 AudioUnitRenderActionFlags *ioActionFlags, 92 const AudioTimeStamp * inTimeStamp, 93 UInt32 inBusNumber, 94 UInt32 inNumberFrames, 95 AudioBufferList * ioData); 96 97 static OSStatus ACComplexInputDataProc (AudioConverterRef inAudioConverter, 98 UInt32 *ioNumberDataPackets, 99 AudioBufferList *ioData, 100 AudioStreamPacketDescription **outDataPacketDescription, 101 void* inUserData); 102 103}; 104 105// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 106#pragma mark _____OALCaptureDeviceMap_____ 107// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 108class OALCaptureDeviceMap : std::multimap<uintptr_t, OALCaptureDevice*, std::less<uintptr_t> > { 109public: 110 111 void Add (const uintptr_t inDeviceToken, OALCaptureDevice **inDevice) { 112 iterator it = upper_bound(inDeviceToken); 113 insert(it, value_type (inDeviceToken, *inDevice)); 114 } 115 116 OALCaptureDevice* Get(uintptr_t inDeviceToken) { 117 iterator it = find(inDeviceToken); 118 if (it != end()) 119 return ((*it).second); 120 return (NULL); 121 } 122 123 void Remove (const uintptr_t inDeviceToken) { 124 iterator it = find(inDeviceToken); 125 if (it != end()) 126 erase(it); 127 } 128 129 UInt32 Size () const { return size(); } 130 bool Empty () const { return empty(); } 131}; 132 133 134#endif 135