Cinder

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