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 class IoException : public Exception {
00134 };
00135 
00136 class IoExceptionFailedLoad : public IoException {
00137 };
00138 
00139 class IoExceptionSourceNotFound : public IoExceptionFailedLoad {
00140 };
00141     
00142 class IoExceptionUnsupportedDataType : public IoException {
00143 };
00144 
00145 class IoExceptionUnsupportedDataFormat : public IoException {
00146 };
00147 
00148 struct IoRegistrar {
00149     typedef SourceRef (*SourceCreationFunc)( DataSourceRef );
00150 
00151     static SourceRef    createSource( DataSourceRef dataSource, std::string extension );
00152     
00153     static void     registerSourceType( std::string extension, SourceCreationFunc func, int32_t priority = 2 );
00154     static void     registerSourceGeneric( SourceCreationFunc func, int32_t priority = 2 );
00155     
00156   private:
00157     
00158     struct Inst {
00159         void    registerSourceType( std::string extension, SourceCreationFunc func, int32_t priority );
00160         void    registerSourceGeneric( SourceCreationFunc func, int32_t priority );
00161     
00162         SourceRef   createSource( DataSourceRef dataSource, std::string extension );
00163         
00164         std::map<std::string, std::multimap<int32_t,SourceCreationFunc> >   mSources;
00165         std::map<int32_t, SourceCreationFunc>                               mGenericSources;
00166     };
00167     
00168     static IoRegistrar::Inst*   instance();
00169     
00170     friend class Io;
00171 };
00172 
00174 SourceRef   load( const std::string &path, std::string extension = "" );
00176 SourceRef   load( DataSourceRef dataSource, std::string extension = "" );
00177 
00178 template<typename T>
00179 struct IoRegistrant {
00180     IoRegistrant() {
00181         (void) register_object;
00182     }
00183   private:
00184     struct exec_register {
00185         exec_register() {
00186             T::registerSelf();
00187         }
00188     };
00189     
00190     static exec_register register_object;
00191 };
00192 
00193 template<typename D> typename IoRegistrant<D>::exec_register IoRegistrant<D>::register_object;
00194 
00195 #define REGISTER_AUDIOIO( TYPE ) \
00196 struct IoRegisterT##TYPE : public IoRegistrant<TYPE> { \
00197     IoRegisterT##TYPE() : IoRegistrant<TYPE>() {} \
00198 };
00199 
00200 }} // namespace
00201