Cinder

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

include/cinder/audio/Io.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/Cinder.h"
00026 #include "cinder/DataSource.h"
00027 #include "cinder/audio/Buffer.h"
00028 
00029 #include <map>
00030 #include <string>
00031 
00032 #if defined(CINDER_MAC)
00033     #include <AudioToolbox/AudioFile.h>
00034 #elif defined(CINDER_MSW)
00035     #include <windows.h>
00036     #include <mmsystem.h> 
00037 #endif
00038 
00039 namespace cinder { namespace audio {
00040 
00041 typedef shared_ptr<class Source>        SourceRef;
00042 typedef shared_ptr<class Loader>        LoaderRef;
00043 
00044 class Io {
00045  public:
00046     typedef enum DataType { UINT8, INT8, UINT16, INT16, UINT32, INT32, FLOAT32, DATA_UNKNOWN } DataType;
00047     
00049     int32_t         getSampleRate() const { return mSampleRate; }
00051     int16_t         getChannelCount() const { return mChannelCount; }
00053     int16_t         getBitsPerSample() const { return mBitsPerSample; }
00055     int16_t         getBlockAlign() const { return mBlockAlign; }
00057     DataType        getDataType() const { return mDataType; }
00059     bool            isInterleaved() const { return mIsInterleaved; }
00061     bool            isPcm() const { return mIsPcm; }
00063     bool            isFloat() const { return ( mDataType == FLOAT32 ); }
00065     bool            isBigEndian() const { return mIsBigEndian; }
00066     
00067  protected:
00068 #if defined(CINDER_COCOA)
00069     static void loadFromCaAudioStreamBasicDescription( Io * anIo, const AudioStreamBasicDescription * audioDescription );
00070 #endif
00071     Io() 
00072         : mSampleRate( 0 ), mChannelCount( 0 ), mBitsPerSample( 0 ), mBlockAlign( 0 ), mDataType( DATA_UNKNOWN ), 
00073             mIsInterleaved( true ), mIsPcm( false ), mIsBigEndian( false )
00074     {}
00075     
00076     int32_t         mSampleRate;
00077     int16_t         mChannelCount;
00078     int16_t         mBitsPerSample; //Significant Bits Per Sample
00079     int16_t         mBlockAlign; //BytesPerSample
00080     DataType        mDataType;
00081     bool            mIsInterleaved;
00082     bool            mIsPcm;
00083     bool            mIsBigEndian;
00084     
00085 #if defined(CINDER_COCOA)
00086     //TODO: fix this
00087     uint32_t    mNativeFormatId;
00088     uint32_t    mNativeFormatFlags;
00089     uint32_t    mBytesPerPacket;
00090     uint32_t    mFramesPerPacket;
00091     uint32_t    mBytesPerFrame;
00092 #endif
00093 };
00094 
00095 class Target : public Io {
00096  public:
00097     virtual ~Target() {}
00098  protected:
00099     Target() {}
00100 };
00101 
00102 class Source : public Io {
00103  public:
00104     virtual ~Source() {}
00105     virtual LoaderRef getLoader( Target *target ) { return LoaderRef(); }
00106     
00107     virtual double getDuration() const = 0;
00108  protected:
00109     
00110 };
00111 
00112 #if defined(CINDER_MSW)
00113     typedef HRESULT (*LoaderDataCallback)( void * audioData, uint32_t dataSize, void * track, uint64_t sampleTime, uint32_t sampleDuration );
00114 #endif
00115 
00116 class Loader {
00117  public:
00118     virtual ~Loader() {}
00119     virtual uint32_t getOptimalBufferSize() const { return 0; };
00120 
00121     virtual void loadData( uint32_t *ioSampleCount, BufferList *ioData ) = 0;
00122     virtual uint64_t getSampleOffset() const = 0;
00123     virtual void setSampleOffset( uint64_t anOffset ) = 0;
00124  protected:
00125 #if defined(CINDER_COCOA)
00126     static void fillBufferListFromCaBufferList( BufferList * aBufferList, const AudioBufferList * caBufferList );
00127     static shared_ptr<AudioBufferList> createCaBufferList( const BufferList * caBufferList );
00128 #endif
00129  
00130     Loader() {}
00131 };
00132 
00133 struct IoRegistrar {
00134     typedef SourceRef (*SourceCreationFunc)( DataSourceRef );
00135 
00136     static SourceRef    createSource( DataSourceRef dataSource, std::string extension );
00137     
00138     static void     registerSourceType( std::string extension, SourceCreationFunc func, int32_t priority = 2 );
00139     
00140   private:
00141     
00142     struct Inst {
00143         void    registerSourceType( std::string extension, SourceCreationFunc func, int32_t priority );
00144     
00145         SourceRef   createSource( DataSourceRef dataSource, std::string extension );
00146         
00147         std::map<std::string, std::multimap<int32_t,SourceCreationFunc> >   mSources;
00148         std::map<int32_t, SourceCreationFunc>                               mGenericSources;
00149     };
00150     
00151     static IoRegistrar::Inst*   instance();
00152     
00153     friend class Io;
00154 };
00155 
00157 SourceRef   load( const std::string &path, std::string extension = "" );
00159 SourceRef   load( DataSourceRef dataSource, std::string extension = "" );
00160 
00161 template<typename T>
00162 struct IoRegistrant {
00163     IoRegistrant() {
00164         (void) register_object;
00165     }
00166   private:
00167     struct exec_register {
00168         exec_register() {
00169             T::registerSelf();
00170         }
00171     };
00172     
00173     static exec_register register_object;
00174 };
00175 
00176 template<typename D> typename IoRegistrant<D>::exec_register IoRegistrant<D>::register_object;
00177 
00178 #define REGISTER_AUDIOIO( TYPE ) \
00179 struct IoRegisterT##TYPE : public IoRegistrant<TYPE> { \
00180     IoRegisterT##TYPE() : IoRegistrant<TYPE>() {} \
00181 };
00182 
00183 }} // namespace
00184