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/PcmBuffer.h"
00028 
00029 #include <map>
00030 #include <string>
00031 
00032 #if defined(CINDER_COCOA)
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 Target>        TargetRef;
00043 typedef shared_ptr<class Loader>        LoaderRef;
00044 
00045 class Io {
00046  public:
00047     typedef enum DataType { UINT8, INT8, UINT16, INT16, UINT32, INT32, FLOAT32, DATA_UNKNOWN } DataType;
00048     
00050     int32_t         getSampleRate() const { return mSampleRate; }
00052     int16_t         getChannelCount() const { return mChannelCount; }
00054     int16_t         getBitsPerSample() const { return mBitsPerSample; }
00056     int16_t         getBlockAlign() const { return mBlockAlign; }
00058     DataType        getDataType() const { return mDataType; }
00060     bool            isInterleaved() const { return mIsInterleaved; }
00062     bool            isPcm() const { return mIsPcm; }
00064     bool            isFloat() const { return ( mDataType == FLOAT32 ); }
00066     bool            isBigEndian() const { return mIsBigEndian; }
00067     
00068  protected:
00069 #if defined(CINDER_COCOA)
00070     static void loadFromCaAudioStreamBasicDescription( Io * anIo, const AudioStreamBasicDescription * audioDescription );
00071 #endif
00072     Io() 
00073         : mSampleRate( 0 ), mChannelCount( 0 ), mBitsPerSample( 0 ), mBlockAlign( 0 ), mDataType( DATA_UNKNOWN ), 
00074             mIsInterleaved( true ), mIsPcm( false ), mIsBigEndian( false )
00075     {}
00076     
00077     int32_t         mSampleRate;
00078     int16_t         mChannelCount;
00079     int16_t         mBitsPerSample; //Significant Bits Per Sample
00080     int16_t         mBlockAlign; //BytesPerSample
00081     DataType        mDataType;
00082     bool            mIsInterleaved;
00083     bool            mIsPcm;
00084     bool            mIsBigEndian;
00085     
00086 #if defined(CINDER_COCOA)
00087     //TODO: fix this
00088     uint32_t    mNativeFormatId;
00089     uint32_t    mNativeFormatFlags;
00090     uint32_t    mBytesPerPacket;
00091     uint32_t    mFramesPerPacket;
00092     uint32_t    mBytesPerFrame;
00093 #endif
00094 };
00095 
00096 class Target : public Io {
00097  public:
00098     virtual ~Target() {}
00099  protected:
00100     Target() {}
00101 };
00102 
00103 class Source : public Io {
00104  public:
00105     virtual ~Source() {}
00106     virtual LoaderRef createLoader( Target *target ) { return LoaderRef(); }
00107     
00108     virtual double getDuration() const = 0;
00109  protected:
00110     
00111 };
00112 
00113 #if defined(CINDER_MSW)
00114     typedef HRESULT (*LoaderDataCallback)( void * audioData, uint32_t dataSize, void * track, uint64_t sampleTime, uint32_t sampleDuration );
00115 #endif
00116 
00117 class Loader {
00118  public:
00119     virtual ~Loader() {}
00120     virtual uint32_t getOptimalBufferSize() const { return 0; };
00121 
00122     virtual void loadData( BufferList *ioData ) = 0;
00123     virtual uint64_t getSampleOffset() const = 0;
00124     virtual void setSampleOffset( uint64_t anOffset ) = 0;
00125  protected:
00126 #if defined(CINDER_COCOA)
00127     static void fillBufferListFromCaBufferList( BufferList * aBufferList, const AudioBufferList * caBufferList );
00128     static shared_ptr<AudioBufferList> createCaBufferList( const BufferList * caBufferList );
00129 #endif
00130  
00131     Loader() {}
00132 };
00133 
00134 class IoException : public Exception {
00135 };
00136 
00137 class IoExceptionFailedLoad : public IoException {
00138 };
00139 
00140 class IoExceptionSourceNotFound : public IoExceptionFailedLoad {
00141 };
00142     
00143 class IoExceptionUnsupportedDataType : public IoException {
00144 };
00145 
00146 class IoExceptionUnsupportedDataFormat : public IoException {
00147 };
00148 
00149 struct IoRegistrar {
00150     typedef SourceRef (*SourceCreationFunc)( DataSourceRef );
00151 
00152     static SourceRef    createSource( DataSourceRef dataSource, std::string extension );
00153     
00154     static void     registerSourceType( std::string extension, SourceCreationFunc func, int32_t priority = 2 );
00155     static void     registerSourceGeneric( SourceCreationFunc func, int32_t priority = 2 );
00156     
00157   private:
00158     
00159     struct Inst {
00160         void    registerSourceType( std::string extension, SourceCreationFunc func, int32_t priority );
00161         void    registerSourceGeneric( SourceCreationFunc func, int32_t priority );
00162     
00163         SourceRef   createSource( DataSourceRef dataSource, std::string extension );
00164         
00165         std::map<std::string, std::multimap<int32_t,SourceCreationFunc> >   mSources;
00166         std::map<int32_t, SourceCreationFunc>                               mGenericSources;
00167     };
00168     
00169     static IoRegistrar::Inst*   instance();
00170     
00171     friend class Io;
00172 };
00173 
00175 SourceRef   load( const std::string &path, std::string extension = "" );
00177 SourceRef   load( DataSourceRef dataSource, std::string extension = "" );
00178 
00179 template<typename T>
00180 struct IoRegistrant {
00181     IoRegistrant() {
00182         (void) register_object;
00183     }
00184   private:
00185     struct exec_register {
00186         exec_register() {
00187             T::registerSelf();
00188         }
00189     };
00190     
00191     static exec_register register_object;
00192 };
00193 
00194 template<typename D> typename IoRegistrant<D>::exec_register IoRegistrant<D>::register_object;
00195 
00196 #define REGISTER_AUDIOIO( TYPE ) \
00197 struct IoRegisterT##TYPE : public IoRegistrant<TYPE> { \
00198     IoRegisterT##TYPE() : IoRegistrant<TYPE>() {} \
00199 };
00200 
00201 }} // namespace
00202