00001
00025 #ifndef AUDIERE_H
00026 #define AUDIERE_H
00027
00028
00029 #include <vector>
00030 #include <string>
00031
00032 #ifdef _MSC_VER
00033 #pragma warning(disable : 4786)
00034 #endif
00035
00036
00037 #ifndef __cplusplus
00038 #error Audiere requires C++
00039 #endif
00040
00041
00042
00043 #ifndef ADR_CALL
00044 #if defined(WIN32) || defined(_WIN32)
00045 #define ADR_CALL __stdcall
00046 #else
00047 #define ADR_CALL
00048 #endif
00049 #endif
00050
00051
00052 #ifndef ADR_DECL
00053 # if defined(WIN32) || defined(_WIN32)
00054 # ifdef AUDIERE_EXPORTS
00055 # define ADR_DECL __declspec(dllexport)
00056 # else
00057 # define ADR_DECL __declspec(dllimport)
00058 # endif
00059 # else
00060 # define ADR_DECL
00061 # endif
00062 #endif
00063
00064
00065
00066 #define ADR_FUNCTION(ret) extern "C" ADR_DECL ret ADR_CALL
00067 #define ADR_METHOD(ret) virtual ret ADR_CALL
00068
00069
00070 namespace audiere {
00071
00072 class RefCounted {
00073 protected:
00081 ~RefCounted() { }
00082
00083 public:
00087 ADR_METHOD(void) ref() = 0;
00088
00093 ADR_METHOD(void) unref() = 0;
00094 };
00095
00096
00097 template<typename T>
00098 class RefPtr {
00099 public:
00100 RefPtr(T* ptr = 0) {
00101 m_ptr = 0;
00102 *this = ptr;
00103 }
00104
00105 RefPtr(const RefPtr<T>& ptr) {
00106 m_ptr = 0;
00107 *this = ptr;
00108 }
00109
00110 ~RefPtr() {
00111 if (m_ptr) {
00112 m_ptr->unref();
00113 m_ptr = 0;
00114 }
00115 }
00116
00117 RefPtr<T>& operator=(T* ptr) {
00118 if (ptr != m_ptr) {
00119 if (m_ptr) {
00120 m_ptr->unref();
00121 }
00122 m_ptr = ptr;
00123 if (m_ptr) {
00124 m_ptr->ref();
00125 }
00126 }
00127 return *this;
00128 }
00129
00130 RefPtr<T>& operator=(const RefPtr<T>& ptr) {
00131 *this = ptr.m_ptr;
00132 return *this;
00133 }
00134
00135 T* operator->() const {
00136 return m_ptr;
00137 }
00138
00139 T& operator*() const {
00140 return *m_ptr;
00141 }
00142
00143 operator bool() const {
00144 return (m_ptr != 0);
00145 }
00146
00147 T* get() const {
00148 return m_ptr;
00149 }
00150
00151 private:
00152 T* m_ptr;
00153 };
00154
00155
00156 template<typename T, typename U>
00157 bool operator==(const RefPtr<T>& a, const RefPtr<U>& b) {
00158 return (a.get() == b.get());
00159 }
00160
00161 template<typename T>
00162 bool operator==(const RefPtr<T>& a, const T* b) {
00163 return (a.get() == b);
00164 }
00165
00166 template<typename T>
00167 bool operator==(const T* a, const RefPtr<T>& b) {
00168 return (a == b.get());
00169 }
00170
00171
00172 template<typename T, typename U>
00173 bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b) {
00174 return (a.get() != b.get());
00175 }
00176
00177 template<typename T>
00178 bool operator!=(const RefPtr<T>& a, const T* b) {
00179 return (a.get() != b);
00180 }
00181
00182 template<typename T>
00183 bool operator!=(const T* a, const RefPtr<T>& b) {
00184 return (a != b.get());
00185 }
00186
00187
00192 template<class Interface>
00193 class RefImplementation : public Interface {
00194 protected:
00195 RefImplementation() {
00196 m_ref_count = 0;
00197 }
00198
00203 virtual ~RefImplementation() { }
00204
00205 public:
00206 void ADR_CALL ref() {
00207 ++m_ref_count;
00208 }
00209
00210 void ADR_CALL unref() {
00211 if (--m_ref_count == 0) {
00212 delete this;
00213 }
00214 }
00215
00216 private:
00217 int m_ref_count;
00218 };
00219
00220
00229 class File : public RefCounted {
00230 protected:
00231 ~File() { }
00232
00233 public:
00237 enum SeekMode {
00238 BEGIN,
00239 CURRENT,
00240 END,
00241 };
00242
00251 ADR_METHOD(int) read(void* buffer, int size) = 0;
00252
00264 ADR_METHOD(bool) seek(int position, SeekMode mode) = 0;
00265
00271 ADR_METHOD(int) tell() = 0;
00272 };
00273 typedef RefPtr<File> FilePtr;
00274
00275
00277 enum SampleFormat {
00278 SF_U8,
00279 SF_S16,
00280 };
00281
00282
00284 enum FileFormat {
00285 FF_AUTODETECT,
00286 FF_WAV,
00287 FF_OGG,
00288 FF_FLAC,
00289 FF_MP3,
00290 FF_MOD,
00291 FF_AIFF,
00292 FF_SPEEX,
00293 };
00294
00295
00306 class SampleSource : public RefCounted {
00307 protected:
00308 ~SampleSource() { }
00309
00310 public:
00315 ADR_METHOD(void) getFormat(
00316 int& channel_count,
00317 int& sample_rate,
00318 SampleFormat& sample_format) = 0;
00319
00329 ADR_METHOD(int) read(int frame_count, void* buffer) = 0;
00330
00336 ADR_METHOD(void) reset() = 0;
00337
00341 ADR_METHOD(bool) isSeekable() = 0;
00342
00347 ADR_METHOD(int) getLength() = 0;
00348
00355 ADR_METHOD(void) setPosition(int position) = 0;
00356
00362 ADR_METHOD(int) getPosition() = 0;
00363
00367 ADR_METHOD(bool) getRepeat() = 0;
00368
00376 ADR_METHOD(void) setRepeat(bool repeat) = 0;
00377
00379 ADR_METHOD(int) getTagCount() = 0;
00380
00385 virtual const char* ADR_CALL getTagKey(int i) = 0;
00386
00391 virtual const char* ADR_CALL getTagValue(int i) = 0;
00392
00397 virtual const char* ADR_CALL getTagType(int i) = 0;
00398 };
00399 typedef RefPtr<SampleSource> SampleSourcePtr;
00400
00401
00425 class LoopPointSource : public SampleSource {
00426 protected:
00427 ~LoopPointSource() { }
00428
00429 public:
00439 ADR_METHOD(void) addLoopPoint(
00440 int location, int target, int loopCount) = 0;
00441
00447 ADR_METHOD(void) removeLoopPoint(int index) = 0;
00448
00452 ADR_METHOD(int) getLoopPointCount() = 0;
00453
00464 ADR_METHOD(bool) getLoopPoint(
00465 int index, int& location, int& target, int& loopCount) = 0;
00466 };
00467 typedef RefPtr<LoopPointSource> LoopPointSourcePtr;
00468
00469
00478 class OutputStream : public RefCounted {
00479 protected:
00480 ~OutputStream() { }
00481
00482 public:
00487 ADR_METHOD(void) play() = 0;
00488
00493 ADR_METHOD(void) stop() = 0;
00494
00498 ADR_METHOD(bool) isPlaying() = 0;
00499
00507 ADR_METHOD(void) reset() = 0;
00508
00514 ADR_METHOD(void) setRepeat(bool repeat) = 0;
00515
00519 ADR_METHOD(bool) getRepeat() = 0;
00520
00526 ADR_METHOD(void) setVolume(float volume) = 0;
00527
00533 ADR_METHOD(float) getVolume() = 0;
00534
00540 ADR_METHOD(void) setPan(float pan) = 0;
00541
00545 ADR_METHOD(float) getPan() = 0;
00546
00552 ADR_METHOD(void) setPitchShift(float shift) = 0;
00553
00557 ADR_METHOD(float) getPitchShift() = 0;
00558
00562 ADR_METHOD(bool) isSeekable() = 0;
00563
00568 ADR_METHOD(int) getLength() = 0;
00569
00576 ADR_METHOD(void) setPosition(int position) = 0;
00577
00583 ADR_METHOD(int) getPosition() = 0;
00584 };
00585 typedef RefPtr<OutputStream> OutputStreamPtr;
00586
00587
00589 enum EventType {
00590 ET_STOP,
00591 };
00592
00593
00595 class Event : public RefCounted {
00596 protected:
00597 ~Event() { }
00598
00599 public:
00601 ADR_METHOD(EventType) getType() = 0;
00602 };
00603 typedef RefPtr<Event> EventPtr;
00604
00605
00610 class StopEvent : public Event {
00611 protected:
00612 ~StopEvent() { }
00613
00614 public:
00615 EventType ADR_CALL getType() { return ET_STOP; }
00616
00618 enum Reason {
00619 STOP_CALLED,
00620 STREAM_ENDED,
00621 };
00622
00626 ADR_METHOD(OutputStream*) getOutputStream() = 0;
00627
00631 ADR_METHOD(Reason) getReason() = 0;
00632 };
00633 typedef RefPtr<StopEvent> StopEventPtr;
00634
00635
00640 class Callback : public RefCounted {
00641 protected:
00642 ~Callback() { }
00643
00644 public:
00648 ADR_METHOD(EventType) getType() = 0;
00649
00654 ADR_METHOD(void) call(Event* event) = 0;
00655 };
00656 typedef RefPtr<Callback> CallbackPtr;
00657
00658
00668 class StopCallback : public Callback {
00669 protected:
00670 ~StopCallback() { }
00671
00672 public:
00673 EventType ADR_CALL getType() { return ET_STOP; }
00674 void ADR_CALL call(Event* event) {
00675 streamStopped(static_cast<StopEvent*>(event));
00676 }
00677
00683 ADR_METHOD(void) streamStopped(StopEvent* event) = 0;
00684 };
00685 typedef RefPtr<StopCallback> StopCallbackPtr;
00686
00687
00696 class AudioDevice : public RefCounted {
00697 protected:
00698 ~AudioDevice() { }
00699
00700 public:
00706 ADR_METHOD(void) update() = 0;
00707
00721 ADR_METHOD(OutputStream*) openStream(SampleSource* source) = 0;
00722
00745 ADR_METHOD(OutputStream*) openBuffer(
00746 void* samples,
00747 int frame_count,
00748 int channel_count,
00749 int sample_rate,
00750 SampleFormat sample_format) = 0;
00751
00757 ADR_METHOD(const char*) getName() = 0;
00758
00763 ADR_METHOD(void) registerCallback(Callback* callback) = 0;
00764
00769 ADR_METHOD(void) unregisterCallback(Callback* callback) = 0;
00770
00772 ADR_METHOD(void) clearCallbacks() = 0;
00773 };
00774 typedef RefPtr<AudioDevice> AudioDevicePtr;
00775
00776
00786 class SampleBuffer : public RefCounted {
00787 protected:
00788 ~SampleBuffer() { }
00789
00790 public:
00791
00796 ADR_METHOD(void) getFormat(
00797 int& channel_count,
00798 int& sample_rate,
00799 SampleFormat& sample_format) = 0;
00800
00804 ADR_METHOD(int) getLength() = 0;
00805
00811 virtual const void* ADR_CALL getSamples() = 0;
00812
00817 ADR_METHOD(SampleSource*) openStream() = 0;
00818 };
00819 typedef RefPtr<SampleBuffer> SampleBufferPtr;
00820
00821
00825 enum SoundEffectType {
00826 SINGLE,
00827 MULTIPLE,
00828 };
00829
00830
00839 class SoundEffect : public RefCounted {
00840 protected:
00841 ~SoundEffect() { }
00842
00843 public:
00850 ADR_METHOD(void) play() = 0;
00851
00856 ADR_METHOD(void) stop() = 0;
00857
00863 ADR_METHOD(void) setVolume(float volume) = 0;
00864
00870 ADR_METHOD(float) getVolume() = 0;
00871
00877 ADR_METHOD(void) setPan(float pan) = 0;
00878
00882 ADR_METHOD(float) getPan() = 0;
00883
00889 ADR_METHOD(void) setPitchShift(float shift) = 0;
00890
00894 ADR_METHOD(float) getPitchShift() = 0;
00895 };
00896 typedef RefPtr<SoundEffect> SoundEffectPtr;
00897
00898
00905 class CDDevice : public RefCounted {
00906 protected:
00907 virtual ~CDDevice() { }
00908
00909 public:
00914 virtual const char* ADR_CALL getName() = 0;
00915
00919 ADR_METHOD(int) getTrackCount() = 0;
00920
00926 ADR_METHOD(void) play(int track) = 0;
00927
00932 ADR_METHOD(void) stop() = 0;
00933
00938 ADR_METHOD(void) pause() = 0;
00939
00944 ADR_METHOD(void) resume() = 0;
00945
00950 ADR_METHOD(bool) isPlaying() = 0;
00951
00956 ADR_METHOD(bool) containsCD() = 0;
00957
00959 ADR_METHOD(bool) isDoorOpen() = 0;
00960
00962 ADR_METHOD(void) openDoor() = 0;
00963
00965 ADR_METHOD(void) closeDoor() = 0;
00966 };
00967 typedef RefPtr<CDDevice> CDDevicePtr;
00968
00969
00974 class MIDIStream : public RefCounted {
00975 protected:
00976 virtual ~MIDIStream() { }
00977
00978 public:
00983 ADR_METHOD(void) play() = 0;
00984
00986 ADR_METHOD(void) stop() = 0;
00987
00992 ADR_METHOD(void) pause() = 0;
00993
00995 ADR_METHOD(bool) isPlaying() = 0;
00996
00998 ADR_METHOD(int) getLength() = 0;
00999
01001 ADR_METHOD(int) getPosition() = 0;
01002
01004 ADR_METHOD(void) setPosition(int position) = 0;
01005
01007 ADR_METHOD(bool) getRepeat() = 0;
01008
01010 ADR_METHOD(void) setRepeat(bool repeat) = 0;
01011 };
01012 typedef RefPtr<MIDIStream> MIDIStreamPtr;
01013
01014
01018 class MIDIDevice : public RefCounted {
01019 protected:
01020 virtual ~MIDIDevice() { }
01021
01022 public:
01026 ADR_METHOD(const char*) getName() = 0;
01027
01037 ADR_METHOD(MIDIStream*) openStream(const char* filename) = 0;
01038 };
01039 typedef RefPtr<MIDIDevice> MIDIDevicePtr;
01040
01041
01043 namespace hidden {
01044
01045
01046
01047 ADR_FUNCTION(const char*) AdrGetVersion();
01048
01057 ADR_FUNCTION(const char*) AdrGetSupportedFileFormats();
01058
01067 ADR_FUNCTION(const char*) AdrGetSupportedAudioDevices();
01068
01069 ADR_FUNCTION(int) AdrGetSampleSize(SampleFormat format);
01070
01071 ADR_FUNCTION(AudioDevice*) AdrOpenDevice(
01072 const char* name,
01073 const char* parameters);
01074
01075 ADR_FUNCTION(SampleSource*) AdrOpenSampleSource(
01076 const char* filename,
01077 FileFormat file_format);
01078 ADR_FUNCTION(SampleSource*) AdrOpenSampleSourceFromFile(
01079 File* file,
01080 FileFormat file_format);
01081 ADR_FUNCTION(SampleSource*) AdrCreateTone(double frequency);
01082 ADR_FUNCTION(SampleSource*) AdrCreateSquareWave(double frequency);
01083 ADR_FUNCTION(SampleSource*) AdrCreateWhiteNoise();
01084 ADR_FUNCTION(SampleSource*) AdrCreatePinkNoise();
01085
01086 ADR_FUNCTION(LoopPointSource*) AdrCreateLoopPointSource(
01087 SampleSource* source);
01088
01089 ADR_FUNCTION(OutputStream*) AdrOpenSound(
01090 AudioDevice* device,
01091 SampleSource* source,
01092 bool streaming);
01093
01094 ADR_FUNCTION(SampleBuffer*) AdrCreateSampleBuffer(
01095 void* samples,
01096 int frame_count,
01097 int channel_count,
01098 int sample_rate,
01099 SampleFormat sample_format);
01100 ADR_FUNCTION(SampleBuffer*) AdrCreateSampleBufferFromSource(
01101 SampleSource* source);
01102
01103 ADR_FUNCTION(SoundEffect*) AdrOpenSoundEffect(
01104 AudioDevice* device,
01105 SampleSource* source,
01106 SoundEffectType type);
01107
01108 ADR_FUNCTION(File*) AdrOpenFile(
01109 const char* name,
01110 bool writeable);
01111
01112 ADR_FUNCTION(File*) AdrCreateMemoryFile(
01113 const void* buffer,
01114 int size);
01115
01116 ADR_FUNCTION(const char*) AdrEnumerateCDDevices();
01117
01118 ADR_FUNCTION(CDDevice*) AdrOpenCDDevice(
01119 const char* name);
01120
01121 ADR_FUNCTION(MIDIDevice*) AdrOpenMIDIDevice(
01122 const char* name);
01123 }
01124
01125
01126
01127
01128
01129
01130
01136 inline const char* GetVersion() {
01137 return hidden::AdrGetVersion();
01138 }
01139
01140
01141 inline void SplitString(
01142 std::vector<std::string>& out,
01143 const char* in,
01144 char delim)
01145 {
01146 out.clear();
01147 while (*in) {
01148 const char* next = strchr(in, delim);
01149 if (next) {
01150 out.push_back(std::string(in, next));
01151 } else {
01152 out.push_back(in);
01153 }
01154
01155 in = (next ? next + 1 : "");
01156 }
01157 }
01158
01159
01161 struct FileFormatDesc {
01163 std::string description;
01164
01166 std::vector<std::string> extensions;
01167 };
01168
01170 inline void GetSupportedFileFormats(std::vector<FileFormatDesc>& formats) {
01171 std::vector<std::string> descriptions;
01172 SplitString(descriptions, hidden::AdrGetSupportedFileFormats(), ';');
01173
01174 formats.resize(descriptions.size());
01175 for (unsigned i = 0; i < descriptions.size(); ++i) {
01176 const char* d = descriptions[i].c_str();
01177 const char* colon = strchr(d, ':');
01178 formats[i].description.assign(d, colon);
01179
01180 SplitString(formats[i].extensions, colon + 1, ',');
01181 }
01182 }
01183
01184
01186 struct AudioDeviceDesc {
01188 std::string name;
01189
01190
01191 std::string description;
01192 };
01193
01195 inline void GetSupportedAudioDevices(std::vector<AudioDeviceDesc>& devices) {
01196 std::vector<std::string> descriptions;
01197 SplitString(descriptions, hidden::AdrGetSupportedAudioDevices(), ';');
01198
01199 devices.resize(descriptions.size());
01200 for (unsigned i = 0; i < descriptions.size(); ++i) {
01201 std::vector<std::string> d;
01202 SplitString(d, descriptions[i].c_str(), ':');
01203 devices[i].name = d[0];
01204 devices[i].description = d[1];
01205 }
01206 }
01207
01208
01217 inline int GetSampleSize(SampleFormat format) {
01218 return hidden::AdrGetSampleSize(format);
01219 }
01220
01233 inline AudioDevice* OpenDevice(
01234 const char* name = 0,
01235 const char* parameters = 0)
01236 {
01237 return hidden::AdrOpenDevice(name, parameters);
01238 }
01239
01247 inline SampleSource* OpenSampleSource(
01248 const char* filename,
01249 FileFormat file_format = FF_AUTODETECT)
01250 {
01251 return hidden::AdrOpenSampleSource(filename, file_format);
01252 }
01253
01266 inline SampleSource* OpenSampleSource(
01267 const FilePtr& file,
01268 FileFormat file_format = FF_AUTODETECT)
01269 {
01270 return hidden::AdrOpenSampleSourceFromFile(file.get(), file_format);
01271 }
01272
01280 inline SampleSource* CreateTone(double frequency) {
01281 return hidden::AdrCreateTone(frequency);
01282 }
01283
01291 inline SampleSource* CreateSquareWave(double frequency) {
01292 return hidden::AdrCreateSquareWave(frequency);
01293 }
01294
01301 inline SampleSource* CreateWhiteNoise() {
01302 return hidden::AdrCreateWhiteNoise();
01303 }
01304
01311 inline SampleSource* CreatePinkNoise() {
01312 return hidden::AdrCreatePinkNoise();
01313 }
01314
01320 inline LoopPointSource* CreateLoopPointSource(
01321 const SampleSourcePtr& source)
01322 {
01323 return hidden::AdrCreateLoopPointSource(source.get());
01324 }
01325
01329 inline LoopPointSource* CreateLoopPointSource(
01330 const char* filename,
01331 FileFormat file_format = FF_AUTODETECT)
01332 {
01333 return CreateLoopPointSource(OpenSampleSource(filename, file_format));
01334 }
01335
01339 inline LoopPointSource* CreateLoopPointSource(
01340 const FilePtr& file,
01341 FileFormat file_format = FF_AUTODETECT)
01342 {
01343 return CreateLoopPointSource(OpenSampleSource(file, file_format));
01344 }
01345
01371 inline OutputStream* OpenSound(
01372 const AudioDevicePtr& device,
01373 const SampleSourcePtr& source,
01374 bool streaming = false)
01375 {
01376 return hidden::AdrOpenSound(device.get(), source.get(), streaming);
01377 }
01378
01383 inline OutputStream* OpenSound(
01384 const AudioDevicePtr& device,
01385 const char* filename,
01386 bool streaming = false,
01387 FileFormat file_format = FF_AUTODETECT)
01388 {
01389 SampleSource* source = OpenSampleSource(filename, file_format);
01390 return OpenSound(device, source, streaming);
01391 }
01392
01397 inline OutputStream* OpenSound(
01398 const AudioDevicePtr& device,
01399 const FilePtr& file,
01400 bool streaming = false,
01401 FileFormat file_format = FF_AUTODETECT)
01402 {
01403 SampleSource* source = OpenSampleSource(file, file_format);
01404 return OpenSound(device, source, streaming);
01405 }
01406
01424 inline SampleBuffer* CreateSampleBuffer(
01425 void* samples,
01426 int frame_count,
01427 int channel_count,
01428 int sample_rate,
01429 SampleFormat sample_format)
01430 {
01431 return hidden::AdrCreateSampleBuffer(
01432 samples, frame_count,
01433 channel_count, sample_rate, sample_format);
01434 }
01435
01445 inline SampleBuffer* CreateSampleBuffer(const SampleSourcePtr& source) {
01446 return hidden::AdrCreateSampleBufferFromSource(source.get());
01447 }
01448
01463 inline SoundEffect* OpenSoundEffect(
01464 const AudioDevicePtr& device,
01465 const SampleSourcePtr& source,
01466 SoundEffectType type)
01467 {
01468 return hidden::AdrOpenSoundEffect(device.get(), source.get(), type);
01469 }
01470
01475 inline SoundEffect* OpenSoundEffect(
01476 const AudioDevicePtr& device,
01477 const char* filename,
01478 SoundEffectType type,
01479 FileFormat file_format = FF_AUTODETECT)
01480 {
01481 SampleSource* source = OpenSampleSource(filename, file_format);
01482 return OpenSoundEffect(device, source, type);
01483 }
01484
01489 inline SoundEffect* OpenSoundEffect(
01490 const AudioDevicePtr& device,
01491 const FilePtr& file,
01492 SoundEffectType type,
01493 FileFormat file_format = FF_AUTODETECT)
01494 {
01495 SampleSource* source = OpenSampleSource(file, file_format);
01496 return OpenSoundEffect(device, source, type);
01497 }
01498
01505 inline File* OpenFile(const char* filename, bool writeable) {
01506 return hidden::AdrOpenFile(filename, writeable);
01507 }
01508
01522 inline File* CreateMemoryFile(const void* buffer, int size) {
01523 return hidden::AdrCreateMemoryFile(buffer, size);
01524 }
01525
01531 inline void EnumerateCDDevices(std::vector<std::string>& devices) {
01532 const char* d = hidden::AdrEnumerateCDDevices();
01533 while (d && *d) {
01534 devices.push_back(d);
01535 d += strlen(d) + 1;
01536 }
01537 }
01538
01547 inline CDDevice* OpenCDDevice(const char* device) {
01548 return hidden::AdrOpenCDDevice(device);
01549 }
01550
01558 inline MIDIDevice* OpenMIDIDevice(const char* device) {
01559 return hidden::AdrOpenMIDIDevice(device);
01560 }
01561
01562 }
01563
01564
01565 #endif