00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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;
00079 int16_t mBlockAlign;
00080 DataType mDataType;
00081 bool mIsInterleaved;
00082 bool mIsPcm;
00083 bool mIsBigEndian;
00084
00085 #if defined(CINDER_COCOA)
00086
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 }}
00184