source: GTP/trunk/App/Demos/Geom/Demo_LodManager/audiere.h @ 1794

Revision 1794, 43.2 KB checked in by gumbau, 18 years ago (diff)
Line 
1/**
2 * @file
3 *
4 * Audiere Sound System
5 * Version 1.9.4
6 * (c) 2001-2003 Chad Austin
7 *
8 * This API uses principles explained at
9 * http://aegisknight.org/cppinterface.html
10 *
11 * This code licensed under the terms of the LGPL.  See doc/license.txt.
12 *
13 *
14 * Note: When compiling this header in gcc, you may want to use the
15 * -Wno-non-virtual-dtor flag to get rid of those annoying "class has
16 * virtual functions but no virtual destructor" warnings.
17 *
18 * This file is structured as follows:
19 * - includes, macro definitions, other general setup
20 * - interface definitions
21 * - DLL-safe entry points (not for general use)
22 * - inline functions that use those entry points
23 */
24
25#ifndef AUDIERE_H
26#define AUDIERE_H
27
28
29#include <vector>
30#include <string>
31
32#ifdef _MSC_VER
33#pragma warning(disable : 4786)
34#endif
35
36
37#ifndef __cplusplus
38  #error Audiere requires C++
39#endif
40
41
42// DLLs in Windows should use the standard (Pascal) calling convention
43#ifndef ADR_CALL
44  #if defined(WIN32) || defined(_WIN32)
45    #define ADR_CALL __stdcall
46  #else
47    #define ADR_CALL
48  #endif
49#endif
50
51// Export functions from the DLL
52#ifndef ADR_DECL
53#  if defined(WIN32) || defined(_WIN32)
54#    ifdef AUDIERE_EXPORTS
55#      define ADR_DECL __declspec(dllexport)
56#    else
57#      define ADR_DECL __declspec(dllimport)
58#    endif
59#  else
60#    define ADR_DECL
61#  endif
62#endif
63
64
65
66#define ADR_FUNCTION(ret) extern "C" ADR_DECL ret ADR_CALL
67#define ADR_METHOD(ret) virtual ret ADR_CALL
68
69
70namespace audiere {
71
72  class RefCounted {
73  protected:
74    /**
75     * Protected so users of refcounted classes don't use std::auto_ptr
76     * or the delete operator.
77     *
78     * Interfaces that derive from RefCounted should define an inline,
79     * empty, protected destructor as well.
80     */
81    ~RefCounted() { }
82
83  public:
84    /**
85     * Add a reference to the internal reference count.
86     */
87    ADR_METHOD(void) ref() = 0;
88
89    /**
90     * Remove a reference from the internal reference count.  When this
91     * reaches 0, the object is destroyed.
92     */
93    ADR_METHOD(void) unref() = 0;
94  };
95
96
97  template<typename T>
98  class RefPtr {
99  public:
100    RefPtr(T* ptr = 0) {
101      m_ptr = 0;
102      *this = ptr;
103    }
104
105    RefPtr(const RefPtr<T>& ptr) {
106      m_ptr = 0;
107      *this = ptr;
108    }
109
110    ~RefPtr() {
111      if (m_ptr) {
112        m_ptr->unref();
113        m_ptr = 0;
114      }
115    }
116 
117    RefPtr<T>& operator=(T* ptr) {
118      if (ptr != m_ptr) {
119        if (m_ptr) {
120          m_ptr->unref();
121        }
122        m_ptr = ptr;
123        if (m_ptr) {
124          m_ptr->ref();
125        }
126      }
127      return *this;
128    }
129
130    RefPtr<T>& operator=(const RefPtr<T>& ptr) {
131      *this = ptr.m_ptr;
132      return *this;
133    }
134
135    T* operator->() const {
136      return m_ptr;
137    }
138
139    T& operator*() const {
140      return *m_ptr;
141    }
142
143    operator bool() const {
144      return (m_ptr != 0);
145    }
146
147    T* get() const {
148      return m_ptr;
149    }
150
151  private:
152    T* m_ptr;
153  };
154
155
156  template<typename T, typename U>
157  bool operator==(const RefPtr<T>& a, const RefPtr<U>& b) {
158      return (a.get() == b.get());
159  }
160
161  template<typename T>
162  bool operator==(const RefPtr<T>& a, const T* b) {
163      return (a.get() == b);
164  }
165
166  template<typename T>
167  bool operator==(const T* a, const RefPtr<T>& b) {
168      return (a == b.get());
169  }
170 
171
172  template<typename T, typename U>
173  bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b) {
174      return (a.get() != b.get());
175  }
176
177  template<typename T>
178  bool operator!=(const RefPtr<T>& a, const T* b) {
179      return (a.get() != b);
180  }
181
182  template<typename T>
183  bool operator!=(const T* a, const RefPtr<T>& b) {
184      return (a != b.get());
185  }
186
187
188  /**
189   * A basic implementation of the RefCounted interface.  Derive
190   * your implementations from RefImplementation<YourInterface>.
191   */
192  template<class Interface>
193  class RefImplementation : public Interface {
194  protected:
195    RefImplementation() {
196      m_ref_count = 0;
197    }
198
199    /**
200     * So the implementation can put its destruction logic in the destructor,
201     * as natural C++ code does.
202     */
203    virtual ~RefImplementation() { }
204
205  public:
206    void ADR_CALL ref() {
207      ++m_ref_count;
208    }
209
210    void ADR_CALL unref() {
211      if (--m_ref_count == 0) {
212        delete this;
213      }
214    }
215
216  private:
217    int m_ref_count;
218  };
219
220
221  /**
222   * Represents a random-access file, usually stored on a disk.  Files
223   * are always binary: that is, they do no end-of-line
224   * transformations.  File objects are roughly analogous to ANSI C
225   * FILE* objects.
226   *
227   * This interface is not synchronized.
228   */
229  class File : public RefCounted {
230  protected:
231    ~File() { }
232
233  public:
234    /**
235     * The different ways you can seek within a file.
236     */
237    enum SeekMode {
238      BEGIN,
239      CURRENT,
240      END,
241    };
242
243    /**
244     * Read size bytes from the file, storing them in buffer.
245     *
246     * @param buffer  buffer to read into
247     * @param size    number of bytes to read
248     *
249     * @return  number of bytes successfully read
250     */
251    ADR_METHOD(int) read(void* buffer, int size) = 0;
252
253    /**
254     * Jump to a new position in the file, using the specified seek
255     * mode.  Remember: if mode is END, the position must be negative,
256     * to seek backwards from the end of the file into its contents.
257     * If the seek fails, the current position is undefined.
258     *
259     * @param position  position relative to the mode
260     * @param mode      where to seek from in the file
261     *
262     * @return  true on success, false otherwise
263     */
264    ADR_METHOD(bool) seek(int position, SeekMode mode) = 0;
265
266    /**
267     * Get current position within the file.
268     *
269     * @return  current position
270     */
271    ADR_METHOD(int) tell() = 0;
272  };
273  typedef RefPtr<File> FilePtr;
274
275
276  /// Storage formats for sample data.
277  enum SampleFormat {
278    SF_U8,  ///< unsigned 8-bit integer [0,255]
279    SF_S16, ///< signed 16-bit integer in host endianness [-32768,32767]
280  };
281
282
283  /// Supported audio file formats.
284  enum FileFormat {
285    FF_AUTODETECT,
286    FF_WAV,
287    FF_OGG,
288    FF_FLAC,
289    FF_MP3,
290    FF_MOD,
291    FF_AIFF,
292    FF_SPEEX,
293  };
294
295
296  /**
297   * Source of raw PCM samples.  Sample sources have an intrinsic format
298   * (@see SampleFormat), sample rate, and number of channels.  They can
299   * be read from or reset.
300   *
301   * Some sample sources are seekable.  Seekable sources have two additional
302   * properties: length and position.  Length is read-only.
303   *
304   * This interface is not synchronized.
305   */
306  class SampleSource : public RefCounted {
307  protected:
308    ~SampleSource() { }
309
310  public:
311    /**
312     * Retrieve the number of channels, sample rate, and sample format of
313     * the sample source.
314     */
315    ADR_METHOD(void) getFormat(
316      int& channel_count,
317      int& sample_rate,
318      SampleFormat& sample_format) = 0;
319
320    /**
321     * Read frame_count samples into buffer.  buffer must be at least
322     * |frame_count * GetSampleSize(format) * channel_count| bytes long.
323     *
324     * @param frame_count  number of frames to read
325     * @param buffer       buffer to store samples in
326     *
327     * @return  number of frames actually read
328     */
329    ADR_METHOD(int) read(int frame_count, void* buffer) = 0;
330
331    /**
332     * Reset the sample source.  This has the same effect as setPosition(0)
333     * on a seekable source.  On an unseekable source, it resets all internal
334     * state to the way it was when the source was first created.
335     */
336    ADR_METHOD(void) reset() = 0;
337
338    /**
339     * @return  true if the stream is seekable, false otherwise
340     */
341    ADR_METHOD(bool) isSeekable() = 0;
342
343    /**
344     * @return  number of frames in the stream, or 0 if the stream is not
345     *          seekable
346     */
347    ADR_METHOD(int) getLength() = 0;
348   
349    /**
350     * Sets the current position within the sample source.  If the stream
351     * is not seekable, this method does nothing.
352     *
353     * @param position  current position in frames
354     */
355    ADR_METHOD(void) setPosition(int position) = 0;
356
357    /**
358     * Returns the current position within the sample source.
359     *
360     * @return  current position in frames
361     */
362    ADR_METHOD(int) getPosition() = 0;
363
364    /**
365     * @return  true if the sample source is set to repeat
366     */
367    ADR_METHOD(bool) getRepeat() = 0;
368
369    /**
370     * Sets whether the sample source should repeat or not.  Note that not
371     * all sample sources repeat by starting again at the beginning of the
372     * sound.  For example MOD files can contain embedded loop points.
373     *
374     * @param repeat  true if the source should repeat, false otherwise
375     */
376    ADR_METHOD(void) setRepeat(bool repeat) = 0;
377
378    /// Returns number of metadata tags present in this sample source.
379    ADR_METHOD(int) getTagCount() = 0;
380
381    /**
382     * Returns the key of the i'th tag in the source.  If the tag is
383     * "author=me", the key is "author".
384     */
385    virtual const char* ADR_CALL getTagKey(int i) = 0;
386
387    /**
388     * Returns the value of the i'th tag in the source.  If the tag is
389     * "author=me", the value is "me".
390     */
391    virtual const char* ADR_CALL getTagValue(int i) = 0;
392
393    /**
394     * Returns the type of the i'th tag in the source.  The type is where
395     * the tag comes from, i.e. "ID3v1", "ID3v2", or "vorbis".
396     */
397    virtual const char* ADR_CALL getTagType(int i) = 0;
398  };
399  typedef RefPtr<SampleSource> SampleSourcePtr;
400
401
402  /**
403   * LoopPointSource is a wrapper around another SampleSource, providing
404   * custom loop behavior.  LoopPointSource maintains a set of links
405   * within the sample stream and whenever the location of one of the links
406   * (i.e. a loop point) is reached, the stream jumps to that link's target.
407   * Each loop point maintains a count.  Every time a loop point comes into
408   * effect, the count is decremented.  Once it reaches zero, that loop point
409   * is temporarily disabled.  If a count is not a positive value, it
410   * cannot be disabled.  Calling reset() resets all counts to their initial
411   * values.
412   *
413   * Loop points only take effect when repeating has been enabled via the
414   * setRepeat() method.
415   *
416   * Loop points are stored in sorted order by their location.  Each one
417   * has an index based on its location within the list.  A loop point's
418   * index will change if another is added before it.
419   *
420   * There is always one implicit loop point after the last sample that
421   * points back to the first.  That way, this class's default looping
422   * behavior is the same as a standard SampleSource.  This loop point
423   * does not show up in the list.
424   */
425  class LoopPointSource : public SampleSource {
426  protected:
427    ~LoopPointSource() { }
428
429  public:
430    /**
431     * Adds a loop point to the stream.  If a loop point at 'location'
432     * already exists, the new one replaces it.  Location and target are
433     * clamped to the actual length of the stream.
434     *
435     * @param location   frame where loop occurs
436     * @param target     frame to jump to after loop point is hit
437     * @param loopCount  number of times to execute this jump.
438     */
439    ADR_METHOD(void) addLoopPoint(
440      int location, int target, int loopCount) = 0;
441
442    /**
443     * Removes the loop point at index 'index' from the stream.
444     *
445     * @param index  index of the loop point to remove
446     */
447    ADR_METHOD(void) removeLoopPoint(int index) = 0;
448
449    /**
450     * Returns the number of loop points in this stream.
451     */
452    ADR_METHOD(int) getLoopPointCount() = 0;
453
454    /**
455     * Retrieves information about a specific loop point.
456     *
457     * @param index      index of the loop point
458     * @param location   frame where loop occurs
459     * @param target     loop point's target frame
460     * @param loopCount  number of times to loop from this particular point
461     *
462     * @return  true if the index is valid and information is returned
463     */
464    ADR_METHOD(bool) getLoopPoint(
465      int index, int& location, int& target, int& loopCount) = 0;
466  };
467  typedef RefPtr<LoopPointSource> LoopPointSourcePtr;
468
469
470  /**
471   * A connection to an audio device.  Multiple output streams are
472   * mixed by the audio device to produce the final waveform that the
473   * user hears.
474   *
475   * Each output stream can be independently played and stopped.  They
476   * also each have a volume from 0.0 (silence) to 1.0 (maximum volume).
477   */
478  class OutputStream : public RefCounted {
479  protected:
480    ~OutputStream() { }
481
482  public:
483    /**
484     * Start playback of the output stream.  If the stream is already
485     * playing, this does nothing.
486     */
487    ADR_METHOD(void) play() = 0;
488
489    /**
490     * Stop playback of the output stream.  If the stream is already
491     * stopped, this does nothing.
492     */
493    ADR_METHOD(void) stop() = 0;
494
495    /**
496     * @return  true if the output stream is playing, false otherwise
497     */
498    ADR_METHOD(bool) isPlaying() = 0;
499
500    /**
501     * Reset the sample source or buffer to the beginning. On seekable
502     * streams, this operation is equivalent to setPosition(0).
503     *
504     * On some output streams, this operation can be moderately slow, as up to
505     * several seconds of PCM buffer must be refilled.
506     */
507    ADR_METHOD(void) reset() = 0;
508
509    /**
510     * Set whether the output stream should repeat.
511     *
512     * @param repeat  true if the stream should repeat, false otherwise
513     */
514    ADR_METHOD(void) setRepeat(bool repeat) = 0;
515
516    /**
517     * @return  true if the stream is repeating
518     */
519    ADR_METHOD(bool) getRepeat() = 0;
520
521    /**
522     * Sets the stream's volume.
523     *
524     * @param  volume  0.0 = silence, 1.0 = maximum volume (default)
525     */
526    ADR_METHOD(void) setVolume(float volume) = 0;
527
528    /**
529     * Gets the current volume.
530     *
531     * @return  current volume of the output stream
532     */
533    ADR_METHOD(float) getVolume() = 0;
534
535    /**
536     * Set current pan.
537     *
538     * @param pan  -1.0 = left, 0.0 = center (default), 1.0 = right
539     */
540    ADR_METHOD(void) setPan(float pan) = 0;
541
542    /**
543     * Get current pan.
544     */
545    ADR_METHOD(float) getPan() = 0;
546
547    /**
548     * Set current pitch shift.
549     *
550     * @param shift  can range from 0.5 to 2.0.  default is 1.0.
551     */
552    ADR_METHOD(void) setPitchShift(float shift) = 0;
553
554    /**
555     * Get current pitch shift.  Defaults to 1.0.
556     */
557    ADR_METHOD(float) getPitchShift() = 0;
558
559    /**
560     * @return  true if the stream is seekable, false otherwise
561     */
562    ADR_METHOD(bool) isSeekable() = 0;
563
564    /**
565     * @return  number of frames in the stream, or 0 if the stream is not
566     *          seekable
567     */
568    ADR_METHOD(int) getLength() = 0;
569   
570    /**
571     * Sets the current position within the sample source.  If the stream
572     * is not seekable, this method does nothing.
573     *
574     * @param position  current position in frames
575     */
576    ADR_METHOD(void) setPosition(int position) = 0;
577
578    /**
579     * Returns the current position within the sample source.
580     *
581     * @return  current position in frames
582     */
583    ADR_METHOD(int) getPosition() = 0;
584  };
585  typedef RefPtr<OutputStream> OutputStreamPtr;
586
587
588  /// An integral code representing a specific type of event.
589  enum EventType {
590    ET_STOP, ///< See StopEvent and StopCallback
591  };
592
593
594  /// Base interface for event-specific data passed to callbacks.
595  class Event : public RefCounted {
596  protected:
597    ~Event() { }
598
599  public:
600    /// Returns the EventType code for this event.
601    ADR_METHOD(EventType) getType() = 0;
602  };
603  typedef RefPtr<Event> EventPtr;
604
605
606  /**
607   * An event object that gets passed to implementations of StopCallback
608   * when a stream has stopped playing.
609   */
610  class StopEvent : public Event {
611  protected:
612    ~StopEvent() { }
613
614  public:
615    EventType ADR_CALL getType() { return ET_STOP; }
616
617    /// A code representing the reason the stream stopped playback.
618    enum Reason {
619      STOP_CALLED,  ///< stop() was called from an external source.
620      STREAM_ENDED, ///< The stream reached its end.
621    };
622
623    /**
624     * @return Pointer to the OutputStream that stopped playback.
625     */
626    ADR_METHOD(OutputStream*) getOutputStream() = 0;
627
628    /**
629     * @return Reason for the stop event.
630     */
631    ADR_METHOD(Reason) getReason() = 0;
632  };
633  typedef RefPtr<StopEvent> StopEventPtr;
634
635
636  /**
637   * Base interface for all callbacks.  See specific callback implementations
638   * for descriptions.
639   */ 
640  class Callback : public RefCounted {
641  protected:
642    ~Callback() { }
643
644  public:
645    /**
646     * Returns the event type that this callback knows how to handle.
647     */
648    ADR_METHOD(EventType) getType() = 0;
649
650    /**
651     * Actually executes the callback with event-specific data.  This is
652     * only called if event->getType() == this->getType().
653     */
654    ADR_METHOD(void) call(Event* event) = 0;
655  };
656  typedef RefPtr<Callback> CallbackPtr;
657
658 
659  /**
660   * To listen for stream stopped events on a device, implement this interface
661   * and call registerStopCallback() on the device, passing your
662   * implementation.  streamStopped() will be called whenever a stream on that
663   * device stops playback.
664   *
665   * WARNING: StopCallback is called from another thread.  Make sure your
666   * callback is thread-safe.
667   */
668  class StopCallback : public Callback {
669  protected:
670    ~StopCallback() { }
671
672  public:
673    EventType ADR_CALL getType() { return ET_STOP; }
674    void ADR_CALL call(Event* event) {
675      streamStopped(static_cast<StopEvent*>(event));
676    }
677
678    /**
679     * Called when a stream has stopped.
680     *
681     * @param event  Information pertaining to the event.
682     */
683    ADR_METHOD(void) streamStopped(StopEvent* event) = 0;
684  };
685  typedef RefPtr<StopCallback> StopCallbackPtr;
686
687
688  /**
689   * AudioDevice represents a device on the system which is capable
690   * of opening and mixing multiple output streams.  In Windows,
691   * DirectSound is such a device.
692   *
693   * This interface is synchronized.  update() and openStream() may
694   * be called on different threads.
695   */
696  class AudioDevice : public RefCounted {
697  protected:
698    ~AudioDevice() { }
699
700  public:
701    /**
702     * Tell the device to do any internal state updates.  Some devices
703     * update on an internal thread.  If that is the case, this method
704     * does nothing.
705     */
706    ADR_METHOD(void) update() = 0;
707
708    /**
709     * Open an output stream with a given sample source.  If the sample
710     * source ever runs out of data, the output stream automatically stops
711     * itself.
712     *
713     * The output stream takes ownership of the sample source, even if
714     * opening the output stream fails (in which case the source is
715     * immediately deleted).
716     *
717     * @param  source  the source used to feed the output stream with samples
718     *
719     * @return  new output stream if successful, 0 if failure
720     */
721    ADR_METHOD(OutputStream*) openStream(SampleSource* source) = 0;
722
723    /**
724     * Open a single buffer with the specified PCM data.  This is sometimes
725     * more efficient than streaming and works on a larger variety of audio
726     * devices.  In some implementations, this may download the audio data
727     * to the sound card's memory itself.
728     *
729     * @param samples  Buffer containing sample data.  openBuffer() does
730     *                 not take ownership of the memory.  The application
731     *                 is responsible for freeing it.  There must be at
732     *                 least |frame_count * channel_count *
733     *                 GetSampleSize(sample_format)| bytes in the buffer.
734     *
735     * @param frame_count  Number of frames in the buffer.
736     *
737     * @param channel_count  Number of audio channels.  1 = mono, 2 = stereo.
738     *
739     * @param sample_rate  Number of samples per second.
740     *
741     * @param sample_format  Format of samples in buffer.
742     *
743     * @return  new output stream if successful, 0 if failure
744     */
745    ADR_METHOD(OutputStream*) openBuffer(
746      void* samples,
747      int frame_count,
748      int channel_count,
749      int sample_rate,
750      SampleFormat sample_format) = 0;
751
752    /**
753     * Gets the name of the audio device.  For example "directsound" or "oss".
754     *
755     * @return name of audio device
756     */
757    ADR_METHOD(const char*) getName() = 0;
758
759    /**
760     * Registers 'callback' to receive events.  Callbacks can be
761     * registered multiple times.
762     */
763    ADR_METHOD(void) registerCallback(Callback* callback) = 0;
764   
765    /**
766     * Unregisters 'callback' once.  If it is registered multiple times,
767     * each unregisterStopCallback call unregisters one of the instances.
768     */
769    ADR_METHOD(void) unregisterCallback(Callback* callback) = 0;
770
771    /// Clears all of the callbacks from the device.
772    ADR_METHOD(void) clearCallbacks() = 0;
773  };
774  typedef RefPtr<AudioDevice> AudioDevicePtr;
775
776
777  /**
778   * A readonly sample container which can open sample streams as iterators
779   * through the buffer.  This is commonly used in cases where a very large
780   * sound effect is loaded once into memory and then streamed several times
781   * to the audio device.  This is more efficient memory-wise than loading
782   * the effect multiple times.
783   *
784   * @see CreateSampleBuffer
785   */
786  class SampleBuffer : public RefCounted {
787  protected:
788    ~SampleBuffer() { }
789
790  public:
791
792    /**
793     * Return the format of the sample data in the sample buffer.
794     * @see SampleSource::getFormat
795     */
796    ADR_METHOD(void) getFormat(
797      int& channel_count,
798      int& sample_rate,
799      SampleFormat& sample_format) = 0;
800
801    /**
802     * Get the length of the sample buffer in frames.
803     */
804    ADR_METHOD(int) getLength() = 0;
805
806    /**
807     * Get a readonly pointer to the samples contained within the buffer.  The
808     * buffer is |channel_count * frame_count * GetSampleSize(sample_format)|
809     * bytes long.
810     */
811    virtual const void* ADR_CALL getSamples() = 0;
812
813    /**
814     * Open a seekable sample source using the samples contained in the
815     * buffer.
816     */
817    ADR_METHOD(SampleSource*) openStream() = 0;
818  };
819  typedef RefPtr<SampleBuffer> SampleBufferPtr;
820
821
822  /**
823   * Defines the type of SoundEffect objects.  @see SoundEffect
824   */
825  enum SoundEffectType {
826    SINGLE,
827    MULTIPLE,
828  };
829
830
831  /**
832   * SoundEffect is a convenience class which provides a simple
833   * mechanism for basic sound playback.  There are two types of sound
834   * effects: SINGLE and MULTIPLE.  SINGLE sound effects only allow
835   * the sound to be played once at a time.  MULTIPLE sound effects
836   * always open a new stream to the audio device for each time it is
837   * played (cleaning up or reusing old streams if possible).
838   */
839  class SoundEffect : public RefCounted {
840  protected:
841    ~SoundEffect() { }
842
843  public:
844    /**
845     * Trigger playback of the sound.  If the SoundEffect is of type
846     * SINGLE, this plays the sound if it isn't playing yet, and
847     * starts it again if it is.  If the SoundEffect is of type
848     * MULTIPLE, play() simply starts playing the sound again.
849     */
850    ADR_METHOD(void) play() = 0;
851
852    /**
853     * If the sound is of type SINGLE, stop the sound.  If it is of
854     * type MULTIPLE, stop all playing instances of the sound.
855     */
856    ADR_METHOD(void) stop() = 0;
857
858    /**
859     * Sets the sound's volume.
860     *
861     * @param  volume  0.0 = silence, 1.0 = maximum volume (default)
862     */
863    ADR_METHOD(void) setVolume(float volume) = 0;
864
865    /**
866     * Gets the current volume.
867     *
868     * @return  current volume of the output stream
869     */
870    ADR_METHOD(float) getVolume() = 0;
871
872    /**
873     * Set current pan.
874     *
875     * @param pan  -1.0 = left, 0.0 = center (default), 1.0 = right
876     */
877    ADR_METHOD(void) setPan(float pan) = 0;
878
879    /**
880     * Get current pan.
881     */
882    ADR_METHOD(float) getPan() = 0;
883
884    /**
885     * Set current pitch shift.
886     *
887     * @param shift  can range from 0.5 to 2.0.  default is 1.0.
888     */
889    ADR_METHOD(void) setPitchShift(float shift) = 0;
890
891    /**
892     * Get current pitch shift.  Defaults to 1.0.
893     */
894    ADR_METHOD(float) getPitchShift() = 0;
895  };
896  typedef RefPtr<SoundEffect> SoundEffectPtr;
897
898
899  /**
900   * Represents a device capable of playing CD audio. Internally, this
901   * uses the MCI subsystem in windows and libcdaudio on other platforms.
902   * MCI subsystem: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_multimedia_command_strings.asp
903   * libcdaudio: http://cdcd.undergrid.net/libcdaudio/
904   */
905  class CDDevice : public RefCounted {
906  protected:
907    virtual ~CDDevice() { }
908
909  public:
910    /**
911     * Returns the name of this CD Device, often just the device name
912     * it was created with.
913     */
914    virtual const char* ADR_CALL getName() = 0;
915
916    /**
917     * Returns the number of audio tracks on the disc.
918     */
919    ADR_METHOD(int) getTrackCount() = 0;
920
921    /**
922     * Starts playback of the given track. If another track was
923     * already playing, the previous track is stopped.  IMPORTANT: Tracks are
924     * indexed from 0 to getTrackCount() - 1.
925     */
926    ADR_METHOD(void) play(int track) = 0;
927
928    /**
929     * Stops the playback, if the playback was already stopped, this
930     * does nothing.
931     */
932    ADR_METHOD(void) stop() = 0;
933   
934    /**
935     * pauses playback of the track that is currently playing (if any)
936     * This does nothing if no track is playing
937     */
938    ADR_METHOD(void) pause() = 0;
939
940    /**
941     * Resumes playback of the track that is currently paused (if any).
942     * This does nothing if no track is paused.
943     */
944    ADR_METHOD(void) resume() = 0;
945
946    /**
947     * Returns true if the CD is currently playing a sound, this could
948     * be through us, or through some other program.
949     */
950    ADR_METHOD(bool) isPlaying() = 0;
951
952    /**
953     * Returns true if the drive contains a cd. This might be slow
954     * on some systems, use with care.
955     */
956    ADR_METHOD(bool) containsCD() = 0;
957
958    /// Returns true if the door is open.
959    ADR_METHOD(bool) isDoorOpen() = 0;
960
961    /// Opens this device's door.
962    ADR_METHOD(void) openDoor() = 0;
963
964    /// Closes this device's door.
965    ADR_METHOD(void) closeDoor() = 0;
966  };
967  typedef RefPtr<CDDevice> CDDevicePtr;
968
969
970  /**
971   * An opened MIDI song that can be played, stopped, and seeked within.
972   * Uses MCI under Windows and is not supported in other platforms.
973   */
974  class MIDIStream : public RefCounted {
975  protected:
976    virtual ~MIDIStream() { }
977
978  public:
979    /**
980     * Begins playback of the song and does nothing if the song is already
981     * playing.
982     */
983    ADR_METHOD(void) play() = 0;
984
985    /// Stops playback of the song and seeks to the beginning.
986    ADR_METHOD(void) stop() = 0;
987
988    /**
989     * Stops playback of the song and does not change its current position.
990     * A subsequent play() will resume the song where it left off.
991     */
992    ADR_METHOD(void) pause() = 0;
993
994    /// Returns true if the song is currently playing, false otherwise.
995    ADR_METHOD(bool) isPlaying() = 0;
996
997    /// Returns the length of the song in milliseconds.
998    ADR_METHOD(int) getLength() = 0;
999
1000    /// Returns the current position of the song in milliseconds.
1001    ADR_METHOD(int) getPosition() = 0;
1002
1003    /// Sets the current position of the song.
1004    ADR_METHOD(void) setPosition(int position) = 0;
1005
1006    /// Returns true if this song is set to repeat.
1007    ADR_METHOD(bool) getRepeat() = 0;
1008
1009    /// Sets whether the song should repeat on completion.  Defaults to false.
1010    ADR_METHOD(void) setRepeat(bool repeat) = 0;
1011  };
1012  typedef RefPtr<MIDIStream> MIDIStreamPtr;
1013
1014
1015  /**
1016   * A MIDIDevice must be instantiated in order to open MIDIStreams.
1017   */
1018  class MIDIDevice : public RefCounted {
1019  protected:
1020    virtual ~MIDIDevice() { }
1021
1022  public:
1023    /**
1024     * Returns the name of the device.
1025     */
1026    ADR_METHOD(const char*) getName() = 0;
1027
1028    /**
1029     * openStream() creates and returns a new MIDIStream object from the
1030     * file with the specified name, which then can be queried and played.
1031     * This method returns NULL if the stream cannot be opened.
1032     *
1033     * Note: MCI subsystem limitations do not allow loading MIDIStream
1034     * objects from an audiere File implementation.  This may be addressed
1035     * in future versions of this API.
1036     */
1037    ADR_METHOD(MIDIStream*) openStream(const char* filename) = 0;
1038  };
1039  typedef RefPtr<MIDIDevice> MIDIDevicePtr;
1040
1041
1042  /// PRIVATE API - for internal use only
1043  namespace hidden {
1044
1045    // these are extern "C" so we don't mangle the names
1046
1047    ADR_FUNCTION(const char*) AdrGetVersion();
1048
1049    /**
1050     * Returns a formatted string that lists the file formats that Audiere
1051     * supports.  This function is DLL-safe.
1052     *
1053     * It is formatted in the following way:
1054     *
1055     * description1:ext1,ext2,ext3;description2:ext1,ext2,ext3
1056     */
1057    ADR_FUNCTION(const char*) AdrGetSupportedFileFormats();
1058
1059    /**
1060     * Returns a formatted string that lists the audio devices Audiere
1061     * supports.  This function is DLL-safe.
1062     *
1063     * It is formatted in the following way:
1064     *
1065     * name1:description1;name2:description2;...
1066     */
1067    ADR_FUNCTION(const char*) AdrGetSupportedAudioDevices();
1068
1069    ADR_FUNCTION(int) AdrGetSampleSize(SampleFormat format);
1070
1071    ADR_FUNCTION(AudioDevice*) AdrOpenDevice(
1072      const char* name,
1073      const char* parameters);
1074
1075    ADR_FUNCTION(SampleSource*) AdrOpenSampleSource(
1076      const char* filename,
1077      FileFormat file_format);
1078    ADR_FUNCTION(SampleSource*) AdrOpenSampleSourceFromFile(
1079      File* file,
1080      FileFormat file_format);
1081    ADR_FUNCTION(SampleSource*) AdrCreateTone(double frequency);
1082    ADR_FUNCTION(SampleSource*) AdrCreateSquareWave(double frequency);
1083    ADR_FUNCTION(SampleSource*) AdrCreateWhiteNoise();
1084    ADR_FUNCTION(SampleSource*) AdrCreatePinkNoise();
1085
1086    ADR_FUNCTION(LoopPointSource*) AdrCreateLoopPointSource(
1087      SampleSource* source);
1088
1089    ADR_FUNCTION(OutputStream*) AdrOpenSound(
1090      AudioDevice* device,
1091      SampleSource* source,
1092      bool streaming);
1093
1094    ADR_FUNCTION(SampleBuffer*) AdrCreateSampleBuffer(
1095      void* samples,
1096      int frame_count,
1097      int channel_count,
1098      int sample_rate,
1099      SampleFormat sample_format);
1100    ADR_FUNCTION(SampleBuffer*) AdrCreateSampleBufferFromSource(
1101      SampleSource* source);
1102
1103    ADR_FUNCTION(SoundEffect*) AdrOpenSoundEffect(
1104      AudioDevice* device,
1105      SampleSource* source,
1106      SoundEffectType type);
1107
1108    ADR_FUNCTION(File*) AdrOpenFile(
1109      const char* name,
1110      bool writeable);
1111
1112    ADR_FUNCTION(File*) AdrCreateMemoryFile(
1113      const void* buffer,
1114      int size);
1115
1116    ADR_FUNCTION(const char*) AdrEnumerateCDDevices();
1117
1118    ADR_FUNCTION(CDDevice*) AdrOpenCDDevice(
1119      const char* name);  // Parameters?
1120
1121    ADR_FUNCTION(MIDIDevice*) AdrOpenMIDIDevice(
1122      const char* name);  // Parameters?
1123  }
1124
1125
1126
1127
1128  /*-------- PUBLIC API FUNCTIONS --------*/
1129
1130
1131  /**
1132   * Returns the Audiere version string.
1133   *
1134   * @return  Audiere version information
1135   */
1136  inline const char* GetVersion() {
1137    return hidden::AdrGetVersion();
1138  }
1139
1140
1141  inline void SplitString(
1142    std::vector<std::string>& out,
1143    const char* in,
1144    char delim)
1145  {
1146    out.clear();
1147    while (*in) {
1148      const char* next = strchr(in, delim);
1149      if (next) {
1150        out.push_back(std::string(in, next));
1151      } else {
1152        out.push_back(in);
1153      }
1154
1155      in = (next ? next + 1 : "");
1156    }
1157  }
1158
1159
1160  /// Describes a file format that Audiere supports.
1161  struct FileFormatDesc {
1162    /// Short description of format, such as "MP3 Files" or "Mod Files"
1163    std::string description;
1164
1165    /// List of support extensions, such as {"mod", "it", "xm"}
1166    std::vector<std::string> extensions;
1167  };
1168
1169  /// Populates a vector of FileFormatDesc structs.
1170  inline void GetSupportedFileFormats(std::vector<FileFormatDesc>& formats) {
1171    std::vector<std::string> descriptions;
1172    SplitString(descriptions, hidden::AdrGetSupportedFileFormats(), ';');
1173
1174    formats.resize(descriptions.size());
1175    for (unsigned i = 0; i < descriptions.size(); ++i) {
1176      const char* d = descriptions[i].c_str();
1177      const char* colon = strchr(d, ':');
1178      formats[i].description.assign(d, colon);
1179
1180      SplitString(formats[i].extensions, colon + 1, ',');
1181    }
1182  }
1183
1184
1185  /// Describes a supported audio device.
1186  struct AudioDeviceDesc {
1187    /// Name of device, i.e. "directsound", "winmm", or "oss"
1188    std::string name;
1189
1190    // Textual description of device.
1191    std::string description;
1192  };
1193
1194  /// Populates a vector of AudioDeviceDesc structs.
1195  inline void GetSupportedAudioDevices(std::vector<AudioDeviceDesc>& devices) {
1196    std::vector<std::string> descriptions;
1197    SplitString(descriptions, hidden::AdrGetSupportedAudioDevices(), ';');
1198
1199    devices.resize(descriptions.size());
1200    for (unsigned i = 0; i < descriptions.size(); ++i) {
1201      std::vector<std::string> d;
1202      SplitString(d, descriptions[i].c_str(), ':');
1203      devices[i].name        = d[0];
1204      devices[i].description = d[1];
1205    }
1206  }
1207
1208
1209  /**
1210   * Get the size of a sample in a specific sample format.
1211   * This is commonly used to determine how many bytes a chunk of
1212   * PCM data will take.
1213   *
1214   * @return  Number of bytes a single sample in the specified format
1215   *          takes.
1216   */
1217  inline int GetSampleSize(SampleFormat format) {
1218    return hidden::AdrGetSampleSize(format);
1219  }
1220
1221  /**
1222   * Open a new audio device. If name or parameters are not specified,
1223   * defaults are used. Each platform has its own set of audio devices.
1224   * Every platform supports the "null" audio device.
1225   *
1226   * @param  name  name of audio device that should be used
1227   * @param  parameters  comma delimited list of audio-device parameters;
1228   *                     for example, "buffer=100,rate=44100"
1229   *
1230   * @return  new audio device object if OpenDevice succeeds, and 0 in case
1231   *          of failure
1232   */
1233  inline AudioDevice* OpenDevice(
1234    const char* name = 0,
1235    const char* parameters = 0)
1236  {
1237    return hidden::AdrOpenDevice(name, parameters);
1238  }
1239
1240  /**
1241   * Create a streaming sample source from a sound file.  This factory simply
1242   * opens a default file from the system filesystem and calls
1243   * OpenSampleSource(File*).
1244   *
1245   * @see OpenSampleSource(File*)
1246   */
1247  inline SampleSource* OpenSampleSource(
1248    const char* filename,
1249    FileFormat file_format = FF_AUTODETECT)
1250  {
1251    return hidden::AdrOpenSampleSource(filename, file_format);
1252  }
1253
1254  /**
1255   * Opens a sample source from the specified file object.  If the sound file
1256   * cannot be opened, this factory function returns 0.
1257   *
1258   * @note  Some sound files support seeking, while some don't.
1259   *
1260   * @param file         File object from which to open the decoder
1261   * @param file_format  Format of the file to load.  If FF_AUTODETECT,
1262   *                     Audiere will try opening the file in each format.
1263   *
1264   * @return  new SampleSource if OpenSampleSource succeeds, 0 otherwise
1265   */
1266  inline SampleSource* OpenSampleSource(
1267    const FilePtr& file,
1268    FileFormat file_format = FF_AUTODETECT)
1269  {
1270    return hidden::AdrOpenSampleSourceFromFile(file.get(), file_format);
1271  }
1272
1273  /**
1274   * Create a tone sample source with the specified frequency.
1275   *
1276   * @param  frequency  Frequency of the tone in Hz.
1277   *
1278   * @return  tone sample source
1279   */
1280  inline SampleSource* CreateTone(double frequency) {
1281    return hidden::AdrCreateTone(frequency);
1282  }
1283
1284  /**
1285   * Create a square wave with the specified frequency.
1286   *
1287   * @param  frequency  Frequency of the wave in Hz.
1288   *
1289   * @return  wave sample source
1290   */
1291  inline SampleSource* CreateSquareWave(double frequency) {
1292    return hidden::AdrCreateSquareWave(frequency);
1293  }
1294
1295  /**
1296   * Create a white noise sample source.  White noise is just random
1297   * data.
1298   *
1299   * @return  white noise sample source
1300   */
1301  inline SampleSource* CreateWhiteNoise() {
1302    return hidden::AdrCreateWhiteNoise();
1303  }
1304
1305  /**
1306   * Create a pink noise sample source.  Pink noise is noise with equal
1307   * power distribution among octaves (logarithmic), not frequencies.
1308   *
1309   * @return  pink noise sample source
1310   */
1311  inline SampleSource* CreatePinkNoise() {
1312    return hidden::AdrCreatePinkNoise();
1313  }
1314
1315  /**
1316   * Create a LoopPointSource from a SampleSource.  The SampleSource must
1317   * be seekable.  If it isn't, or the source isn't valid, this function
1318   * returns 0.
1319   */
1320  inline LoopPointSource* CreateLoopPointSource(
1321    const SampleSourcePtr& source)
1322  {
1323    return hidden::AdrCreateLoopPointSource(source.get());
1324  }
1325
1326  /**
1327   * Creates a LoopPointSource from a source loaded from a file.
1328   */
1329  inline LoopPointSource* CreateLoopPointSource(
1330    const char* filename,
1331    FileFormat file_format = FF_AUTODETECT)
1332  {
1333    return CreateLoopPointSource(OpenSampleSource(filename, file_format));
1334  }
1335
1336  /**
1337   * Creates a LoopPointSource from a source loaded from a file.
1338   */
1339  inline LoopPointSource* CreateLoopPointSource(
1340    const FilePtr& file,
1341    FileFormat file_format = FF_AUTODETECT)
1342  {
1343    return CreateLoopPointSource(OpenSampleSource(file, file_format));
1344  }
1345
1346  /**
1347   * Try to open a sound buffer using the specified AudioDevice and
1348   * sample source.  If the specified sample source is seekable, it
1349   * loads it into memory and uses AudioDevice::openBuffer to create
1350   * the output stream.  If the stream is not seekable, it uses
1351   * AudioDevice::openStream to create the output stream.  This means
1352   * that certain file types must always be streamed, and therefore,
1353   * OpenSound will hold on to the file object.  If you must guarantee
1354   * that the file on disk is no longer referenced, you must create
1355   * your own memory file implementation and load your data into that
1356   * before calling OpenSound.
1357   *
1358   * @param device  AudioDevice in which to open the output stream.
1359   *
1360   * @param source  SampleSource used to generate samples for the sound
1361   *                object.  OpenSound takes ownership of source, even
1362   *                if it returns 0.  (In that case, OpenSound immediately
1363   *                deletes the SampleSource.)
1364   *
1365   * @param streaming  If false or unspecified, OpenSound attempts to
1366   *                   open the entire sound into memory.  Otherwise, it
1367   *                   streams the sound from the file.
1368   *
1369   * @return  new output stream if successful, 0 otherwise
1370   */
1371  inline OutputStream* OpenSound(
1372    const AudioDevicePtr& device,
1373    const SampleSourcePtr& source,
1374    bool streaming = false)
1375  {
1376    return hidden::AdrOpenSound(device.get(), source.get(), streaming);
1377  }
1378
1379  /**
1380   * Calls OpenSound(AudioDevice*, SampleSource*) with a sample source
1381   * created via OpenSampleSource(const char*).
1382   */
1383  inline OutputStream* OpenSound(
1384    const AudioDevicePtr& device,
1385    const char* filename,
1386    bool streaming = false,
1387    FileFormat file_format = FF_AUTODETECT)
1388  {
1389    SampleSource* source = OpenSampleSource(filename, file_format);
1390    return OpenSound(device, source, streaming);
1391  }
1392
1393  /**
1394   * Calls OpenSound(AudioDevice*, SampleSource*) with a sample source
1395   * created via OpenSampleSource(File* file).
1396   */
1397  inline OutputStream* OpenSound(
1398    const AudioDevicePtr& device,
1399    const FilePtr& file,
1400    bool streaming = false,
1401    FileFormat file_format = FF_AUTODETECT)
1402  {
1403    SampleSource* source = OpenSampleSource(file, file_format);
1404    return OpenSound(device, source, streaming);
1405  }
1406
1407  /**
1408   * Create a SampleBuffer object using the specified samples and formats.
1409   *
1410   * @param samples  Pointer to a buffer of samples used to initialize the
1411   *                 new object.  If this is 0, the sample buffer contains
1412   *                 just silence.
1413   *
1414   * @param frame_count  Size of the sample buffer in frames.
1415   *
1416   * @param channel_count  Number of channels in each frame.
1417   *
1418   * @param sample_rate  Sample rate in Hz.
1419   *
1420   * @param sample_format  Format of each sample.  @see SampleFormat.
1421   *
1422   * @return  new SampleBuffer object
1423   */
1424  inline SampleBuffer* CreateSampleBuffer(
1425    void* samples,
1426    int frame_count,
1427    int channel_count,
1428    int sample_rate,
1429    SampleFormat sample_format)
1430  {
1431    return hidden::AdrCreateSampleBuffer(
1432      samples, frame_count,
1433      channel_count, sample_rate, sample_format);
1434  }
1435
1436  /**
1437   * Create a SampleBuffer object from a SampleSource.
1438   *
1439   * @param source  Seekable sample source used to create the buffer.
1440   *                If the source is not seekable, then the function
1441   *                fails.
1442   *
1443   * @return  new sample buffer if success, 0 otherwise
1444   */
1445  inline SampleBuffer* CreateSampleBuffer(const SampleSourcePtr& source) {
1446    return hidden::AdrCreateSampleBufferFromSource(source.get());
1447  }
1448
1449  /**
1450   * Open a SoundEffect object from the given sample source and sound
1451   * effect type.  @see SoundEffect
1452   *
1453   * @param device  AudioDevice on which the sound is played.
1454   *
1455   * @param source  The sample source used to feed the sound effect
1456   *                with data.
1457   *
1458   * @param type  The type of the sound effect.  If type is MULTIPLE,
1459   *              the source must be seekable.
1460   *
1461   * @return  new SoundEffect object if successful, 0 otherwise
1462   */
1463  inline SoundEffect* OpenSoundEffect(
1464    const AudioDevicePtr& device,
1465    const SampleSourcePtr& source,
1466    SoundEffectType type)
1467  {
1468    return hidden::AdrOpenSoundEffect(device.get(), source.get(), type);
1469  }
1470
1471  /**
1472   * Calls OpenSoundEffect(AudioDevice*, SampleSource*,
1473   * SoundEffectType) with a sample source created from the filename.
1474   */
1475  inline SoundEffect* OpenSoundEffect(
1476    const AudioDevicePtr& device,
1477    const char* filename,
1478    SoundEffectType type,
1479    FileFormat file_format = FF_AUTODETECT)
1480  {
1481    SampleSource* source = OpenSampleSource(filename, file_format);
1482    return OpenSoundEffect(device, source, type);
1483  }
1484
1485  /**
1486   * Calls OpenSoundEffect(AudioDevice*, SampleSource*,
1487   * SoundEffectType) with a sample source created from the file.
1488   */
1489  inline SoundEffect* OpenSoundEffect(
1490    const AudioDevicePtr& device,
1491    const FilePtr& file,
1492    SoundEffectType type,
1493    FileFormat file_format = FF_AUTODETECT)
1494  {
1495    SampleSource* source = OpenSampleSource(file, file_format);
1496    return OpenSoundEffect(device, source, type);
1497  }
1498
1499  /**
1500   * Opens a default file implementation from the local filesystem.
1501   *
1502   * @param filename   The name of the file on the local filesystem.
1503   * @param writeable  Whether the writing to the file is allowed.
1504   */
1505  inline File* OpenFile(const char* filename, bool writeable) {
1506    return hidden::AdrOpenFile(filename, writeable);
1507  }
1508
1509  /**
1510   * Creates a File implementation that reads from a buffer in memory.
1511   * It stores a copy of the buffer that is passed in.
1512   *
1513   * The File object does <i>not</i> take ownership of the memory buffer.
1514   * When the file is destroyed, it will not free the memory.
1515   *
1516   * @param buffer  Pointer to the beginning of the data.
1517   * @param size    Size of the buffer in bytes.
1518   *
1519   * @return  0 if size is non-zero and buffer is null. Otherwise,
1520   *          returns a valid File object.
1521   */
1522  inline File* CreateMemoryFile(const void* buffer, int size) {
1523    return hidden::AdrCreateMemoryFile(buffer, size);
1524  }
1525
1526  /**
1527   * Generates a list of available CD device names.
1528   *
1529   * @param devices A vector of strings to be filled.
1530   */
1531  inline void EnumerateCDDevices(std::vector<std::string>& devices) {
1532    const char* d = hidden::AdrEnumerateCDDevices();
1533    while (d && *d) {
1534      devices.push_back(d);
1535      d += strlen(d) + 1;
1536    }
1537  }
1538
1539  /**
1540   * Opens the specified CD playback device.
1541   *
1542   * @param device  The filesystem device to be played.
1543   *                e.g. Linux: "/dev/cdrom", Windows: "D:"
1544   *
1545   * @return  0 if opening device failed, valid CDDrive object otherwise.
1546   */
1547  inline CDDevice* OpenCDDevice(const char* device) {
1548    return hidden::AdrOpenCDDevice(device);
1549  }
1550
1551  /**
1552   * Opens the specified MIDI synthesizer device.
1553   *
1554   * @param device  The name of the device.  Unused for now.
1555   *
1556   * @return  0 if opening device failed, valid MIDIDevice object otherwise.
1557   */
1558  inline MIDIDevice* OpenMIDIDevice(const char* device) {
1559    return hidden::AdrOpenMIDIDevice(device);
1560  }
1561
1562}
1563
1564
1565#endif
Note: See TracBrowser for help on using the repository browser.