include/cinder/audio/InputImplAudioUnit.h
Go to the documentation of this file.
00001 /*
00002  Copyright (c) 2010, Cinder
00003  All rights reserved.
00004 
00005  Redistribution and use in source and binary forms, with or without modification, are permitted provided that
00006  the following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and
00009     the following disclaimer.
00010     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
00011     the following disclaimer in the documentation and/or other materials provided with the distribution.
00012 
00013  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00014  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00015  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
00016  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00017  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00018  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00019  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00020  POSSIBILITY OF SUCH DAMAGE.
00021 */
00022 
00023 #pragma once
00024 
00025 #include "cinder/Cinder.h"
00026 #include "cinder/audio/Input.h"
00027 #include "cinder/audio/PcmBuffer.h"
00028 #include "cinder/audio/CircularBuffer.h"
00029 
00030 #include <AudioUnit/AudioUnit.h>
00031 #include <AudioToolbox/AudioToolbox.h>
00032 
00033 #include <vector>
00034 #include <map>
00035 #include <boost/thread/mutex.hpp>
00036 
00037 namespace cinder { namespace audio {
00038 
00039 /*
00040 TODO: 
00041 add support for specifying buffer size
00042 
00043 add support for specifying number of output channels
00044 */
00045 
00046 class InputImplAudioUnit : public InputImpl {
00047  public:
00048     class Device;
00049     
00050  
00051     InputImplAudioUnit( InputDeviceRef aDevice );
00052     ~InputImplAudioUnit();
00053     
00054     void start();
00055     void stop();
00056     PcmBuffer32fRef getPcmBuffer();
00057     bool isCapturing() const { return mIsCapturing; }
00058     
00059     uint32_t getSampleRate() const { return mSampleRate; };
00060     uint16_t getChannelCount() const { return mChannelCount; };
00061     
00062     static const std::vector<InputDeviceRef>&   getDevices( bool forceRefresh );
00063     static InputDeviceRef getDefaultDevice();
00064 #if defined( CINDER_MAC )
00065     class Device : public InputDevice {
00066      public:
00067         Device( AudioDeviceID aDeviceId );
00068         const std::string& getName();
00069         
00070         bool operator==( const Device &rhs ) const {
00071             return ( mDeviceId == rhs.mDeviceId );
00072         }
00073      private:
00074         std::string     mDeviceName;
00075         UInt32          mSafetyOffset;
00076     };
00077 #elif defined( CINDER_COCOA_TOUCH )
00078     //iOS doesn't support audio device enumeration, 
00079     //so this is just a placeholder to represent the defualt device
00080     class Device : public InputDevice {
00081      public:
00082         Device();
00083         const std::string& getName() { return mDeviceName; }
00084         
00085         bool operator==( const Device &rhs ) const {
00086             return true;
00087         }
00088      private:
00089         std::string     mDeviceName;
00090     };
00091 #endif
00092  protected:
00093     static OSStatus inputCallback( void*, AudioUnitRenderActionFlags*, const AudioTimeStamp*, UInt32, UInt32, AudioBufferList* );
00094  
00095     void setup();
00096     
00097     bool                            mIsSetup;
00098     InputDeviceRef                  mDevice;
00099     bool                            mIsCapturing;
00100 #if ! defined( __MAC_OS_X_VERSION_MAX_ALLOWED ) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)
00101     AudioComponentInstance          mInputUnit;
00102 #else
00103     AudioUnit                       mInputUnit;
00104 #endif
00105     AudioBufferList                 * mInputBuffer;
00106     float                           * mInputBufferData;
00107     
00108     std::vector<CircularBuffer<float> *>    mCircularBuffers;
00109     
00110     boost::mutex                    mBufferMutex;
00111     
00112     AudioStreamBasicDescription     mFormatDescription;
00113     uint32_t mSampleRate;
00114     uint16_t mChannelCount;
00115     
00116     static bool                             sDevicesEnumerated;
00117     static std::vector<InputDeviceRef>      sDevices;
00118     //static std::map<InputDevice::DeviceIdentifier, AudioDeviceID> sDeviceIdMap;
00119     //TODO: mask platform specific identifiers (AudioDeviceID) behind a map 
00120     //that maps Cinder InputDevice::DeviceIdentifier to the platform specific identifier
00121 };
00122 
00123 
00124 }} //namespace