Cinder

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

include/cinder/audio/OutputImplAudioUnit.h

Go to the documentation of this file.
00001 /*
00002  Copyright (c) 2009, The Barbarian Group
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/audio/Output.h"
00026 #include <CoreAudio/CoreAudioTypes.h>
00027 #include <AudioUnit/AudioUnit.h>
00028 #include <AudioToolbox/AUGraph.h>
00029 #include <boost/thread/mutex.hpp>
00030 #include <stack>
00031 
00032 namespace cinder { namespace audio {
00033 
00034 class OutputImplAudioUnit;
00035 
00036 class TargetOutputImplAudioUnit : public Target {
00037   public: 
00038     static std::shared_ptr<TargetOutputImplAudioUnit> createRef( const OutputImplAudioUnit *aOutput ){ return std::shared_ptr<TargetOutputImplAudioUnit>( new TargetOutputImplAudioUnit( aOutput ) );  };
00039     ~TargetOutputImplAudioUnit() {}
00040   private:
00041     TargetOutputImplAudioUnit( const OutputImplAudioUnit *aOutput );
00042     
00043     //uint64_t                      mPacketOffset;
00044     //AudioStreamPacketDescription  * mCurrentPacketDescriptions;
00045 };
00046 
00047 class OutputImplAudioUnit : public OutputImpl {
00048   public:
00049     OutputImplAudioUnit();
00050     ~OutputImplAudioUnit();
00051     
00052     TrackRef    addTrack( SourceRef source, bool autoplay );
00053     void        removeTrack( TrackId trackId );
00054     
00055     void setVolume( float aVolume );
00056     float getVolume() const;
00057     
00058     //TargetRef getTarget();
00059   protected:
00060     TrackId                         availableTrackId() { 
00061                                         if( mAvailableBuses.size() < 1 ) return -1;
00062                                         TrackId bus = mAvailableBuses.top(); 
00063                                         mAvailableBuses.pop(); return bus; 
00064                                     }
00065   private:
00066   
00067     static const uint32_t           sDefaultNumberBuses;
00068     std::stack<TrackId>             mAvailableBuses;
00069     uint32_t                        mNumberBuses;
00070 #if defined(CINDER_MAC)
00071     AudioDeviceID                   mOutputDeviceId;
00072 #endif
00073     AUGraph                         mGraph;
00074     AUNode                          mMixerNode;
00075     AUNode                          mOutputNode;
00076     AudioUnit                       mOutputUnit;
00077     AudioUnit                       mMixerUnit;
00078     AudioStreamBasicDescription     * mPlayerDescription;
00079     
00080     class Track : public cinder::audio::Track
00081     {
00082       public:
00083         Track( SourceRef source, OutputImplAudioUnit * output );
00084         ~Track();
00085         void play();
00086         void stop();
00087         bool isPlaying() const { return mIsPlaying; } 
00088         
00089         TrackId getTrackId() const { return mInputBus; }
00090         
00091         void setVolume( float aVolume );
00092         float getVolume() const;
00093         
00094         double getTime() const { return ( mLoader->getSampleOffset() / (double)mSource->getSampleRate() ); }
00095         void setTime( double aTime );
00096         
00097         bool isLooping() const { return mIsLooping; }
00098         void setLooping( bool isLooping ) { mIsLooping = isLooping; }
00099         
00100         void enablePcmBuffering( bool isBuffering ) { mIsPcmBuffering = isBuffering; }
00101         bool isPcmBuffering() { return mIsPcmBuffering; }
00102         
00103         PcmBuffer32fRef getPcmBuffer();
00104       private:
00105         static OSStatus renderCallback( void * audioLoader, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData );
00106         static OSStatus renderNotifyCallback( void * audioTrack, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData );
00107         
00108         void createPcmBuffer();
00109         
00110         SourceRef       mSource;
00111         std::shared_ptr<TargetOutputImplAudioUnit> mTarget;
00112         OutputImplAudioUnit * mOutput;
00113         TrackId         mInputBus;
00114         LoaderRef       mLoader;
00115         bool            mIsPlaying;
00116         bool            mIsLooping;
00117         bool            mIsPcmBuffering;
00118         
00119         PcmBuffer32fRef mLoadingPcmBuffer;
00120         PcmBuffer32fRef mLoadedPcmBuffer;
00121         boost::mutex    mPcmBufferMutex;
00122     };
00123     
00124     std::map<TrackId,std::shared_ptr<OutputImplAudioUnit::Track> >  mTracks;
00125     
00126     friend class TargetOutputImplAudioUnit;
00127 };
00128 
00129 }} //namespace