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 <CoreAudio/AudioHardware.h> 28#include <AudioToolbox/AudioToolbox.h> 29#include <AudioUnit/AudioUnit.h> 30#include <map> 31#include <libkern/OSAtomic.h> 32 33#include "oalImp.h" 34#include "oalRingBuffer.h" 35#include "CAStreamBasicDescription.h" 36#include "CABufferList.h" 37 38#define LOG_CAPTUREDEVICE_VERBOSE 0 39 40// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 41// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 42// OALCaptureDevices 43// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 44// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 45 46#pragma mark _____OALCaptureDevice_____ 47class OALCaptureDevice 48{ 49#pragma mark __________ Public_Class_Members 50 public: 51 52 OALCaptureDevice(const char* inDeviceName, uintptr_t inSelfToken, UInt32 inSampleRate, UInt32 inFormat, UInt32 inBufferSize); 53 ~OALCaptureDevice(); 54 55 void StartCapture(); 56 void StopCapture(); 57 58 OSStatus GetFrames(UInt32 inFrameCount, UInt8* inBuffer); 59 UInt32 AvailableFrames(); 60 void SetError(ALenum errorCode); 61 ALenum GetError(); 62 63 // we need to mark the capture device if it is being used to prevent deletion from another thread 64 void SetInUseFlag() { OSAtomicIncrement32Barrier(&mInUseFlag); } 65 void ClearInUseFlag() { OSAtomicDecrement32Barrier(&mInUseFlag); } 66 volatile int32_t IsInUse() { return mInUseFlag; } 67 68#pragma mark __________ Private_Class_Members 69 70 private: 71#if LOG_CAPTUREDEVICE_VERBOSE 72 uintptr_t mSelfToken; 73#endif 74 ALenum mCurrentError; 75 bool mCaptureOn; 76 SInt64 mStoreSampleTime; // increment on each read in the input proc, and pass to the ring buffer class when writing, reset on each stop 77 SInt64 mFetchSampleTime; // increment on each read in the input proc, and pass to the ring buffer class when writing, reset on each stop 78 AudioUnit mInputUnit; 79 CAStreamBasicDescription mNativeFormat; 80 CAStreamBasicDescription mRequestedFormat; 81 CAStreamBasicDescription mOutputFormat; 82 OALRingBuffer* mRingBuffer; // the ring buffer 83 UInt8* mBufferData; 84 AudioConverterRef mAudioConverter; 85 Float64 mSampleRateRatio; 86 UInt32 mRequestedRingFrames; 87 CABufferList* mAudioInputPtrs; 88 volatile int32_t mInUseFlag; // flag to indicate the device is currently being used by one or more threads 89 90 void InitializeAU (const char* inDeviceName); 91 static OSStatus InputProc( void * inRefCon, 92 AudioUnitRenderActionFlags *ioActionFlags, 93 const AudioTimeStamp * inTimeStamp, 94 UInt32 inBusNumber, 95 UInt32 inNumberFrames, 96 AudioBufferList * ioData); 97 98 static OSStatus ACComplexInputDataProc (AudioConverterRef inAudioConverter, 99 UInt32 *ioNumberDataPackets, 100 AudioBufferList *ioData, 101 AudioStreamPacketDescription **outDataPacketDescription, 102 void* inUserData); 103 104}; 105 106// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 107#pragma mark _____OALCaptureDeviceMap_____ 108// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 109class OALCaptureDeviceMap : std::multimap<uintptr_t, OALCaptureDevice*, std::less<uintptr_t> > { 110public: 111 112 void Add (const uintptr_t inDeviceToken, OALCaptureDevice **inDevice) { 113 iterator it = upper_bound(inDeviceToken); 114 insert(it, value_type (inDeviceToken, *inDevice)); 115 } 116 117 OALCaptureDevice* Get(uintptr_t inDeviceToken) { 118 iterator it = find(inDeviceToken); 119 if (it != end()) 120 return ((*it).second); 121 return (NULL); 122 } 123 124 void Remove (const uintptr_t inDeviceToken) { 125 iterator it = find(inDeviceToken); 126 if (it != end()) 127 erase(it); 128 } 129 130 UInt32 Size () const { return size(); } 131 bool Empty () const { return empty(); } 132}; 133 134 135#endif 136