Go to the documentation of this file.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/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;
00082 int16_t mBlockAlign;
00083 DataType mDataType;
00084 bool mIsInterleaved;
00085 bool mIsPcm;
00086 bool mIsBigEndian;
00087
00088 #if defined(CINDER_COCOA)
00089
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 }}
00204