Index: /GTP/trunk/App/Demos/Geom/Demo_LodManager/audiere.h
===================================================================
--- /GTP/trunk/App/Demos/Geom/Demo_LodManager/audiere.h	(revision 1794)
+++ /GTP/trunk/App/Demos/Geom/Demo_LodManager/audiere.h	(revision 1794)
@@ -0,0 +1,1565 @@
+/**
+ * @file
+ *
+ * Audiere Sound System
+ * Version 1.9.4
+ * (c) 2001-2003 Chad Austin
+ *
+ * This API uses principles explained at
+ * http://aegisknight.org/cppinterface.html
+ *
+ * This code licensed under the terms of the LGPL.  See doc/license.txt.
+ *
+ *
+ * Note: When compiling this header in gcc, you may want to use the
+ * -Wno-non-virtual-dtor flag to get rid of those annoying "class has
+ * virtual functions but no virtual destructor" warnings.
+ *
+ * This file is structured as follows:
+ * - includes, macro definitions, other general setup
+ * - interface definitions
+ * - DLL-safe entry points (not for general use)
+ * - inline functions that use those entry points
+ */
+
+#ifndef AUDIERE_H
+#define AUDIERE_H
+
+
+#include <vector>
+#include <string>
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4786)
+#endif
+
+
+#ifndef __cplusplus
+  #error Audiere requires C++
+#endif
+
+
+// DLLs in Windows should use the standard (Pascal) calling convention
+#ifndef ADR_CALL
+  #if defined(WIN32) || defined(_WIN32)
+    #define ADR_CALL __stdcall
+  #else
+    #define ADR_CALL
+  #endif
+#endif
+
+// Export functions from the DLL
+#ifndef ADR_DECL
+#  if defined(WIN32) || defined(_WIN32)
+#    ifdef AUDIERE_EXPORTS
+#      define ADR_DECL __declspec(dllexport)
+#    else
+#      define ADR_DECL __declspec(dllimport)
+#    endif
+#  else
+#    define ADR_DECL
+#  endif
+#endif
+
+
+
+#define ADR_FUNCTION(ret) extern "C" ADR_DECL ret ADR_CALL
+#define ADR_METHOD(ret) virtual ret ADR_CALL
+
+
+namespace audiere {
+
+  class RefCounted {
+  protected:
+    /**
+     * Protected so users of refcounted classes don't use std::auto_ptr
+     * or the delete operator.
+     *
+     * Interfaces that derive from RefCounted should define an inline,
+     * empty, protected destructor as well.
+     */
+    ~RefCounted() { }
+
+  public:
+    /**
+     * Add a reference to the internal reference count.
+     */
+    ADR_METHOD(void) ref() = 0;
+
+    /**
+     * Remove a reference from the internal reference count.  When this
+     * reaches 0, the object is destroyed.
+     */
+    ADR_METHOD(void) unref() = 0;
+  };
+
+
+  template<typename T>
+  class RefPtr {
+  public:
+    RefPtr(T* ptr = 0) {
+      m_ptr = 0;
+      *this = ptr;
+    }
+
+    RefPtr(const RefPtr<T>& ptr) {
+      m_ptr = 0;
+      *this = ptr;
+    }
+
+    ~RefPtr() {
+      if (m_ptr) {
+        m_ptr->unref();
+        m_ptr = 0;
+      }
+    }
+ 
+    RefPtr<T>& operator=(T* ptr) {
+      if (ptr != m_ptr) {
+        if (m_ptr) {
+          m_ptr->unref();
+        }
+        m_ptr = ptr;
+        if (m_ptr) {
+          m_ptr->ref();
+        }
+      }
+      return *this;
+    }
+
+    RefPtr<T>& operator=(const RefPtr<T>& ptr) {
+      *this = ptr.m_ptr;
+      return *this;
+    }
+
+    T* operator->() const {
+      return m_ptr;
+    }
+
+    T& operator*() const {
+      return *m_ptr;
+    }
+
+    operator bool() const {
+      return (m_ptr != 0);
+    }
+
+    T* get() const {
+      return m_ptr;
+    }
+
+  private:
+    T* m_ptr;
+  };
+
+
+  template<typename T, typename U>
+  bool operator==(const RefPtr<T>& a, const RefPtr<U>& b) {
+      return (a.get() == b.get());
+  }
+
+  template<typename T>
+  bool operator==(const RefPtr<T>& a, const T* b) {
+      return (a.get() == b);
+  }
+
+  template<typename T>
+  bool operator==(const T* a, const RefPtr<T>& b) {
+      return (a == b.get());
+  }
+  
+
+  template<typename T, typename U>
+  bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b) {
+      return (a.get() != b.get());
+  }
+
+  template<typename T>
+  bool operator!=(const RefPtr<T>& a, const T* b) {
+      return (a.get() != b);
+  }
+
+  template<typename T>
+  bool operator!=(const T* a, const RefPtr<T>& b) {
+      return (a != b.get());
+  }
+
+
+  /**
+   * A basic implementation of the RefCounted interface.  Derive
+   * your implementations from RefImplementation<YourInterface>.
+   */
+  template<class Interface>
+  class RefImplementation : public Interface {
+  protected:
+    RefImplementation() {
+      m_ref_count = 0;
+    }
+
+    /**
+     * So the implementation can put its destruction logic in the destructor,
+     * as natural C++ code does.
+     */
+    virtual ~RefImplementation() { }
+
+  public:
+    void ADR_CALL ref() {
+      ++m_ref_count;
+    }
+
+    void ADR_CALL unref() {
+      if (--m_ref_count == 0) {
+        delete this;
+      }
+    }
+
+  private:
+    int m_ref_count;
+  };
+
+
+  /**
+   * Represents a random-access file, usually stored on a disk.  Files
+   * are always binary: that is, they do no end-of-line
+   * transformations.  File objects are roughly analogous to ANSI C
+   * FILE* objects.
+   *
+   * This interface is not synchronized.
+   */
+  class File : public RefCounted {
+  protected:
+    ~File() { }
+
+  public:
+    /**
+     * The different ways you can seek within a file.
+     */
+    enum SeekMode {
+      BEGIN,
+      CURRENT,
+      END,
+    };
+
+    /**
+     * Read size bytes from the file, storing them in buffer.
+     *
+     * @param buffer  buffer to read into
+     * @param size    number of bytes to read
+     *
+     * @return  number of bytes successfully read
+     */
+    ADR_METHOD(int) read(void* buffer, int size) = 0;
+
+    /**
+     * Jump to a new position in the file, using the specified seek
+     * mode.  Remember: if mode is END, the position must be negative,
+     * to seek backwards from the end of the file into its contents.
+     * If the seek fails, the current position is undefined.
+     *
+     * @param position  position relative to the mode
+     * @param mode      where to seek from in the file
+     *
+     * @return  true on success, false otherwise
+     */
+    ADR_METHOD(bool) seek(int position, SeekMode mode) = 0;
+
+    /**
+     * Get current position within the file.
+     *
+     * @return  current position
+     */
+    ADR_METHOD(int) tell() = 0;
+  };
+  typedef RefPtr<File> FilePtr;
+
+
+  /// Storage formats for sample data.
+  enum SampleFormat {
+    SF_U8,  ///< unsigned 8-bit integer [0,255]
+    SF_S16, ///< signed 16-bit integer in host endianness [-32768,32767]
+  };
+
+
+  /// Supported audio file formats.
+  enum FileFormat {
+    FF_AUTODETECT,
+    FF_WAV,
+    FF_OGG,
+    FF_FLAC,
+    FF_MP3,
+    FF_MOD,
+    FF_AIFF,
+    FF_SPEEX,
+  };
+
+
+  /**
+   * Source of raw PCM samples.  Sample sources have an intrinsic format
+   * (@see SampleFormat), sample rate, and number of channels.  They can
+   * be read from or reset.
+   *
+   * Some sample sources are seekable.  Seekable sources have two additional
+   * properties: length and position.  Length is read-only.
+   *
+   * This interface is not synchronized.
+   */
+  class SampleSource : public RefCounted {
+  protected:
+    ~SampleSource() { }
+
+  public:
+    /**
+     * Retrieve the number of channels, sample rate, and sample format of
+     * the sample source.
+     */
+    ADR_METHOD(void) getFormat(
+      int& channel_count,
+      int& sample_rate,
+      SampleFormat& sample_format) = 0;
+
+    /**
+     * Read frame_count samples into buffer.  buffer must be at least
+     * |frame_count * GetSampleSize(format) * channel_count| bytes long.
+     *
+     * @param frame_count  number of frames to read
+     * @param buffer       buffer to store samples in
+     *
+     * @return  number of frames actually read
+     */
+    ADR_METHOD(int) read(int frame_count, void* buffer) = 0;
+
+    /**
+     * Reset the sample source.  This has the same effect as setPosition(0)
+     * on a seekable source.  On an unseekable source, it resets all internal
+     * state to the way it was when the source was first created.
+     */
+    ADR_METHOD(void) reset() = 0;
+
+    /**
+     * @return  true if the stream is seekable, false otherwise
+     */
+    ADR_METHOD(bool) isSeekable() = 0;
+
+    /**
+     * @return  number of frames in the stream, or 0 if the stream is not
+     *          seekable
+     */
+    ADR_METHOD(int) getLength() = 0;
+    
+    /**
+     * Sets the current position within the sample source.  If the stream
+     * is not seekable, this method does nothing.
+     *
+     * @param position  current position in frames
+     */
+    ADR_METHOD(void) setPosition(int position) = 0;
+
+    /**
+     * Returns the current position within the sample source.
+     *
+     * @return  current position in frames
+     */
+    ADR_METHOD(int) getPosition() = 0;
+
+    /**
+     * @return  true if the sample source is set to repeat
+     */
+    ADR_METHOD(bool) getRepeat() = 0;
+
+    /**
+     * Sets whether the sample source should repeat or not.  Note that not
+     * all sample sources repeat by starting again at the beginning of the
+     * sound.  For example MOD files can contain embedded loop points.
+     *
+     * @param repeat  true if the source should repeat, false otherwise
+     */
+    ADR_METHOD(void) setRepeat(bool repeat) = 0;
+
+    /// Returns number of metadata tags present in this sample source.
+    ADR_METHOD(int) getTagCount() = 0;
+
+    /**
+     * Returns the key of the i'th tag in the source.  If the tag is
+     * "author=me", the key is "author".
+     */
+    virtual const char* ADR_CALL getTagKey(int i) = 0;
+
+    /**
+     * Returns the value of the i'th tag in the source.  If the tag is
+     * "author=me", the value is "me".
+     */
+    virtual const char* ADR_CALL getTagValue(int i) = 0;
+
+    /**
+     * Returns the type of the i'th tag in the source.  The type is where
+     * the tag comes from, i.e. "ID3v1", "ID3v2", or "vorbis".
+     */
+    virtual const char* ADR_CALL getTagType(int i) = 0;
+  };
+  typedef RefPtr<SampleSource> SampleSourcePtr;
+
+
+  /**
+   * LoopPointSource is a wrapper around another SampleSource, providing
+   * custom loop behavior.  LoopPointSource maintains a set of links
+   * within the sample stream and whenever the location of one of the links
+   * (i.e. a loop point) is reached, the stream jumps to that link's target.
+   * Each loop point maintains a count.  Every time a loop point comes into
+   * effect, the count is decremented.  Once it reaches zero, that loop point
+   * is temporarily disabled.  If a count is not a positive value, it
+   * cannot be disabled.  Calling reset() resets all counts to their initial
+   * values.
+   *
+   * Loop points only take effect when repeating has been enabled via the
+   * setRepeat() method.
+   *
+   * Loop points are stored in sorted order by their location.  Each one
+   * has an index based on its location within the list.  A loop point's
+   * index will change if another is added before it.
+   *
+   * There is always one implicit loop point after the last sample that
+   * points back to the first.  That way, this class's default looping
+   * behavior is the same as a standard SampleSource.  This loop point
+   * does not show up in the list.
+   */
+  class LoopPointSource : public SampleSource {
+  protected:
+    ~LoopPointSource() { }
+
+  public:
+    /**
+     * Adds a loop point to the stream.  If a loop point at 'location'
+     * already exists, the new one replaces it.  Location and target are
+     * clamped to the actual length of the stream.
+     *
+     * @param location   frame where loop occurs
+     * @param target     frame to jump to after loop point is hit
+     * @param loopCount  number of times to execute this jump.
+     */
+    ADR_METHOD(void) addLoopPoint(
+      int location, int target, int loopCount) = 0;
+
+    /**
+     * Removes the loop point at index 'index' from the stream.
+     *
+     * @param index  index of the loop point to remove
+     */
+    ADR_METHOD(void) removeLoopPoint(int index) = 0;
+
+    /**
+     * Returns the number of loop points in this stream.
+     */
+    ADR_METHOD(int) getLoopPointCount() = 0;
+
+    /**
+     * Retrieves information about a specific loop point.
+     *
+     * @param index      index of the loop point
+     * @param location   frame where loop occurs
+     * @param target     loop point's target frame
+     * @param loopCount  number of times to loop from this particular point
+     *
+     * @return  true if the index is valid and information is returned
+     */
+    ADR_METHOD(bool) getLoopPoint(
+      int index, int& location, int& target, int& loopCount) = 0;
+  };
+  typedef RefPtr<LoopPointSource> LoopPointSourcePtr;
+
+
+  /**
+   * A connection to an audio device.  Multiple output streams are
+   * mixed by the audio device to produce the final waveform that the
+   * user hears.
+   *
+   * Each output stream can be independently played and stopped.  They
+   * also each have a volume from 0.0 (silence) to 1.0 (maximum volume).
+   */
+  class OutputStream : public RefCounted {
+  protected:
+    ~OutputStream() { }
+
+  public:
+    /**
+     * Start playback of the output stream.  If the stream is already
+     * playing, this does nothing.
+     */
+    ADR_METHOD(void) play() = 0;
+
+    /**
+     * Stop playback of the output stream.  If the stream is already
+     * stopped, this does nothing.
+     */
+    ADR_METHOD(void) stop() = 0;
+
+    /**
+     * @return  true if the output stream is playing, false otherwise
+     */
+    ADR_METHOD(bool) isPlaying() = 0;
+
+    /**
+     * Reset the sample source or buffer to the beginning. On seekable
+     * streams, this operation is equivalent to setPosition(0).
+     *
+     * On some output streams, this operation can be moderately slow, as up to
+     * several seconds of PCM buffer must be refilled.
+     */
+    ADR_METHOD(void) reset() = 0;
+
+    /**
+     * Set whether the output stream should repeat.
+     *
+     * @param repeat  true if the stream should repeat, false otherwise
+     */
+    ADR_METHOD(void) setRepeat(bool repeat) = 0;
+
+    /**
+     * @return  true if the stream is repeating
+     */
+    ADR_METHOD(bool) getRepeat() = 0;
+
+    /**
+     * Sets the stream's volume.
+     *
+     * @param  volume  0.0 = silence, 1.0 = maximum volume (default)
+     */
+    ADR_METHOD(void) setVolume(float volume) = 0;
+
+    /**
+     * Gets the current volume.
+     *
+     * @return  current volume of the output stream
+     */
+    ADR_METHOD(float) getVolume() = 0;
+
+    /**
+     * Set current pan.
+     *
+     * @param pan  -1.0 = left, 0.0 = center (default), 1.0 = right
+     */
+    ADR_METHOD(void) setPan(float pan) = 0;
+
+    /**
+     * Get current pan.
+     */
+    ADR_METHOD(float) getPan() = 0;
+
+    /**
+     * Set current pitch shift.
+     *
+     * @param shift  can range from 0.5 to 2.0.  default is 1.0.
+     */
+    ADR_METHOD(void) setPitchShift(float shift) = 0;
+
+    /**
+     * Get current pitch shift.  Defaults to 1.0.
+     */
+    ADR_METHOD(float) getPitchShift() = 0;
+
+    /**
+     * @return  true if the stream is seekable, false otherwise
+     */
+    ADR_METHOD(bool) isSeekable() = 0;
+
+    /**
+     * @return  number of frames in the stream, or 0 if the stream is not
+     *          seekable
+     */
+    ADR_METHOD(int) getLength() = 0;
+    
+    /**
+     * Sets the current position within the sample source.  If the stream
+     * is not seekable, this method does nothing.
+     *
+     * @param position  current position in frames
+     */
+    ADR_METHOD(void) setPosition(int position) = 0;
+
+    /**
+     * Returns the current position within the sample source.
+     *
+     * @return  current position in frames
+     */
+    ADR_METHOD(int) getPosition() = 0;
+  };
+  typedef RefPtr<OutputStream> OutputStreamPtr;
+
+
+  /// An integral code representing a specific type of event.
+  enum EventType {
+    ET_STOP, ///< See StopEvent and StopCallback
+  };
+
+
+  /// Base interface for event-specific data passed to callbacks.
+  class Event : public RefCounted {
+  protected:
+    ~Event() { }
+
+  public:
+    /// Returns the EventType code for this event.
+    ADR_METHOD(EventType) getType() = 0;
+  };
+  typedef RefPtr<Event> EventPtr;
+
+
+  /**
+   * An event object that gets passed to implementations of StopCallback
+   * when a stream has stopped playing.
+   */
+  class StopEvent : public Event {
+  protected:
+    ~StopEvent() { }
+
+  public:
+    EventType ADR_CALL getType() { return ET_STOP; }
+
+    /// A code representing the reason the stream stopped playback.
+    enum Reason {
+      STOP_CALLED,  ///< stop() was called from an external source.
+      STREAM_ENDED, ///< The stream reached its end.
+    };
+
+    /**
+     * @return Pointer to the OutputStream that stopped playback.
+     */
+    ADR_METHOD(OutputStream*) getOutputStream() = 0;
+
+    /**
+     * @return Reason for the stop event.
+     */
+    ADR_METHOD(Reason) getReason() = 0;
+  };
+  typedef RefPtr<StopEvent> StopEventPtr;
+
+
+  /**
+   * Base interface for all callbacks.  See specific callback implementations
+   * for descriptions.
+   */  
+  class Callback : public RefCounted {
+  protected:
+    ~Callback() { }
+
+  public:
+    /**
+     * Returns the event type that this callback knows how to handle.
+     */
+    ADR_METHOD(EventType) getType() = 0;
+
+    /**
+     * Actually executes the callback with event-specific data.  This is
+     * only called if event->getType() == this->getType().
+     */
+    ADR_METHOD(void) call(Event* event) = 0;
+  };
+  typedef RefPtr<Callback> CallbackPtr;
+
+  
+  /**
+   * To listen for stream stopped events on a device, implement this interface
+   * and call registerStopCallback() on the device, passing your
+   * implementation.  streamStopped() will be called whenever a stream on that
+   * device stops playback.
+   *
+   * WARNING: StopCallback is called from another thread.  Make sure your
+   * callback is thread-safe.
+   */
+  class StopCallback : public Callback {
+  protected:
+    ~StopCallback() { }
+
+  public:
+    EventType ADR_CALL getType() { return ET_STOP; }
+    void ADR_CALL call(Event* event) {
+      streamStopped(static_cast<StopEvent*>(event));
+    }
+
+    /**
+     * Called when a stream has stopped.
+     *
+     * @param event  Information pertaining to the event.
+     */
+    ADR_METHOD(void) streamStopped(StopEvent* event) = 0;
+  };
+  typedef RefPtr<StopCallback> StopCallbackPtr;
+
+
+  /**
+   * AudioDevice represents a device on the system which is capable
+   * of opening and mixing multiple output streams.  In Windows,
+   * DirectSound is such a device.
+   *
+   * This interface is synchronized.  update() and openStream() may
+   * be called on different threads.
+   */
+  class AudioDevice : public RefCounted {
+  protected:
+    ~AudioDevice() { }
+
+  public:
+    /**
+     * Tell the device to do any internal state updates.  Some devices
+     * update on an internal thread.  If that is the case, this method
+     * does nothing.
+     */
+    ADR_METHOD(void) update() = 0;
+
+    /**
+     * Open an output stream with a given sample source.  If the sample
+     * source ever runs out of data, the output stream automatically stops
+     * itself.
+     *
+     * The output stream takes ownership of the sample source, even if
+     * opening the output stream fails (in which case the source is
+     * immediately deleted).
+     *
+     * @param  source  the source used to feed the output stream with samples
+     *
+     * @return  new output stream if successful, 0 if failure
+     */
+    ADR_METHOD(OutputStream*) openStream(SampleSource* source) = 0;
+
+    /**
+     * Open a single buffer with the specified PCM data.  This is sometimes
+     * more efficient than streaming and works on a larger variety of audio
+     * devices.  In some implementations, this may download the audio data
+     * to the sound card's memory itself.
+     *
+     * @param samples  Buffer containing sample data.  openBuffer() does
+     *                 not take ownership of the memory.  The application
+     *                 is responsible for freeing it.  There must be at
+     *                 least |frame_count * channel_count *
+     *                 GetSampleSize(sample_format)| bytes in the buffer.
+     *
+     * @param frame_count  Number of frames in the buffer.
+     *
+     * @param channel_count  Number of audio channels.  1 = mono, 2 = stereo.
+     *
+     * @param sample_rate  Number of samples per second.
+     *
+     * @param sample_format  Format of samples in buffer.
+     *
+     * @return  new output stream if successful, 0 if failure
+     */
+    ADR_METHOD(OutputStream*) openBuffer(
+      void* samples,
+      int frame_count,
+      int channel_count,
+      int sample_rate,
+      SampleFormat sample_format) = 0;
+
+    /**
+     * Gets the name of the audio device.  For example "directsound" or "oss".
+     *
+     * @return name of audio device
+     */
+    ADR_METHOD(const char*) getName() = 0;
+
+    /**
+     * Registers 'callback' to receive events.  Callbacks can be
+     * registered multiple times.
+     */
+    ADR_METHOD(void) registerCallback(Callback* callback) = 0;
+    
+    /**
+     * Unregisters 'callback' once.  If it is registered multiple times,
+     * each unregisterStopCallback call unregisters one of the instances.
+     */
+    ADR_METHOD(void) unregisterCallback(Callback* callback) = 0;
+
+    /// Clears all of the callbacks from the device.
+    ADR_METHOD(void) clearCallbacks() = 0;
+  };
+  typedef RefPtr<AudioDevice> AudioDevicePtr;
+
+
+  /**
+   * A readonly sample container which can open sample streams as iterators
+   * through the buffer.  This is commonly used in cases where a very large
+   * sound effect is loaded once into memory and then streamed several times
+   * to the audio device.  This is more efficient memory-wise than loading
+   * the effect multiple times.
+   *
+   * @see CreateSampleBuffer
+   */
+  class SampleBuffer : public RefCounted {
+  protected:
+    ~SampleBuffer() { }
+
+  public:
+
+    /**
+     * Return the format of the sample data in the sample buffer.
+     * @see SampleSource::getFormat
+     */
+    ADR_METHOD(void) getFormat(
+      int& channel_count,
+      int& sample_rate,
+      SampleFormat& sample_format) = 0;
+
+    /**
+     * Get the length of the sample buffer in frames.
+     */
+    ADR_METHOD(int) getLength() = 0;
+
+    /**
+     * Get a readonly pointer to the samples contained within the buffer.  The
+     * buffer is |channel_count * frame_count * GetSampleSize(sample_format)|
+     * bytes long.
+     */
+    virtual const void* ADR_CALL getSamples() = 0;
+
+    /**
+     * Open a seekable sample source using the samples contained in the
+     * buffer.
+     */
+    ADR_METHOD(SampleSource*) openStream() = 0;
+  };
+  typedef RefPtr<SampleBuffer> SampleBufferPtr;
+
+
+  /**
+   * Defines the type of SoundEffect objects.  @see SoundEffect
+   */
+  enum SoundEffectType {
+    SINGLE,
+    MULTIPLE,
+  };
+
+
+  /**
+   * SoundEffect is a convenience class which provides a simple
+   * mechanism for basic sound playback.  There are two types of sound
+   * effects: SINGLE and MULTIPLE.  SINGLE sound effects only allow
+   * the sound to be played once at a time.  MULTIPLE sound effects
+   * always open a new stream to the audio device for each time it is
+   * played (cleaning up or reusing old streams if possible).
+   */
+  class SoundEffect : public RefCounted {
+  protected:
+    ~SoundEffect() { }
+
+  public:
+    /**
+     * Trigger playback of the sound.  If the SoundEffect is of type
+     * SINGLE, this plays the sound if it isn't playing yet, and
+     * starts it again if it is.  If the SoundEffect is of type
+     * MULTIPLE, play() simply starts playing the sound again.
+     */
+    ADR_METHOD(void) play() = 0;
+
+    /**
+     * If the sound is of type SINGLE, stop the sound.  If it is of
+     * type MULTIPLE, stop all playing instances of the sound.
+     */
+    ADR_METHOD(void) stop() = 0;
+
+    /**
+     * Sets the sound's volume.
+     *
+     * @param  volume  0.0 = silence, 1.0 = maximum volume (default)
+     */
+    ADR_METHOD(void) setVolume(float volume) = 0;
+
+    /**
+     * Gets the current volume.
+     *
+     * @return  current volume of the output stream
+     */
+    ADR_METHOD(float) getVolume() = 0;
+
+    /**
+     * Set current pan.
+     *
+     * @param pan  -1.0 = left, 0.0 = center (default), 1.0 = right
+     */
+    ADR_METHOD(void) setPan(float pan) = 0;
+
+    /**
+     * Get current pan.
+     */
+    ADR_METHOD(float) getPan() = 0;
+
+    /**
+     * Set current pitch shift.
+     *
+     * @param shift  can range from 0.5 to 2.0.  default is 1.0.
+     */
+    ADR_METHOD(void) setPitchShift(float shift) = 0;
+
+    /**
+     * Get current pitch shift.  Defaults to 1.0.
+     */
+    ADR_METHOD(float) getPitchShift() = 0;
+  };
+  typedef RefPtr<SoundEffect> SoundEffectPtr;
+
+
+  /**
+   * Represents a device capable of playing CD audio. Internally, this
+   * uses the MCI subsystem in windows and libcdaudio on other platforms.
+   * MCI subsystem: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_multimedia_command_strings.asp
+   * libcdaudio: http://cdcd.undergrid.net/libcdaudio/
+   */
+  class CDDevice : public RefCounted {
+  protected:
+    virtual ~CDDevice() { }
+
+  public:
+    /**
+     * Returns the name of this CD Device, often just the device name
+     * it was created with.
+     */
+    virtual const char* ADR_CALL getName() = 0;
+
+    /**
+     * Returns the number of audio tracks on the disc.
+     */
+    ADR_METHOD(int) getTrackCount() = 0;
+
+    /**
+     * Starts playback of the given track. If another track was
+     * already playing, the previous track is stopped.  IMPORTANT: Tracks are
+     * indexed from 0 to getTrackCount() - 1.
+     */
+    ADR_METHOD(void) play(int track) = 0;
+
+    /**
+     * Stops the playback, if the playback was already stopped, this
+     * does nothing.
+     */
+    ADR_METHOD(void) stop() = 0;
+    
+    /**
+     * pauses playback of the track that is currently playing (if any)
+     * This does nothing if no track is playing
+     */
+    ADR_METHOD(void) pause() = 0;
+
+    /**
+     * Resumes playback of the track that is currently paused (if any).
+     * This does nothing if no track is paused.
+     */
+    ADR_METHOD(void) resume() = 0;
+
+    /**
+     * Returns true if the CD is currently playing a sound, this could
+     * be through us, or through some other program.
+     */
+    ADR_METHOD(bool) isPlaying() = 0;
+
+    /**
+     * Returns true if the drive contains a cd. This might be slow
+     * on some systems, use with care.
+     */
+    ADR_METHOD(bool) containsCD() = 0;
+
+    /// Returns true if the door is open.
+    ADR_METHOD(bool) isDoorOpen() = 0;
+
+    /// Opens this device's door.
+    ADR_METHOD(void) openDoor() = 0;
+
+    /// Closes this device's door.
+    ADR_METHOD(void) closeDoor() = 0;
+  };
+  typedef RefPtr<CDDevice> CDDevicePtr;
+
+
+  /**
+   * An opened MIDI song that can be played, stopped, and seeked within.
+   * Uses MCI under Windows and is not supported in other platforms.
+   */
+  class MIDIStream : public RefCounted {
+  protected:
+    virtual ~MIDIStream() { }
+
+  public:
+    /**
+     * Begins playback of the song and does nothing if the song is already
+     * playing.
+     */
+    ADR_METHOD(void) play() = 0;
+
+    /// Stops playback of the song and seeks to the beginning.
+    ADR_METHOD(void) stop() = 0;
+
+    /**
+     * Stops playback of the song and does not change its current position.
+     * A subsequent play() will resume the song where it left off.
+     */
+    ADR_METHOD(void) pause() = 0;
+
+    /// Returns true if the song is currently playing, false otherwise.
+    ADR_METHOD(bool) isPlaying() = 0;
+
+    /// Returns the length of the song in milliseconds.
+    ADR_METHOD(int) getLength() = 0;
+
+    /// Returns the current position of the song in milliseconds.
+    ADR_METHOD(int) getPosition() = 0;
+
+    /// Sets the current position of the song.
+    ADR_METHOD(void) setPosition(int position) = 0;
+
+    /// Returns true if this song is set to repeat.
+    ADR_METHOD(bool) getRepeat() = 0;
+
+    /// Sets whether the song should repeat on completion.  Defaults to false.
+    ADR_METHOD(void) setRepeat(bool repeat) = 0;
+  };
+  typedef RefPtr<MIDIStream> MIDIStreamPtr;
+
+
+  /**
+   * A MIDIDevice must be instantiated in order to open MIDIStreams.
+   */
+  class MIDIDevice : public RefCounted {
+  protected:
+    virtual ~MIDIDevice() { }
+
+  public:
+    /**
+     * Returns the name of the device.
+     */
+    ADR_METHOD(const char*) getName() = 0;
+
+    /**
+     * openStream() creates and returns a new MIDIStream object from the
+     * file with the specified name, which then can be queried and played.
+     * This method returns NULL if the stream cannot be opened.
+     *
+     * Note: MCI subsystem limitations do not allow loading MIDIStream
+     * objects from an audiere File implementation.  This may be addressed
+     * in future versions of this API.
+     */
+    ADR_METHOD(MIDIStream*) openStream(const char* filename) = 0;
+  };
+  typedef RefPtr<MIDIDevice> MIDIDevicePtr;
+
+
+  /// PRIVATE API - for internal use only
+  namespace hidden {
+
+    // these are extern "C" so we don't mangle the names
+
+    ADR_FUNCTION(const char*) AdrGetVersion();
+
+    /**
+     * Returns a formatted string that lists the file formats that Audiere
+     * supports.  This function is DLL-safe.
+     *
+     * It is formatted in the following way:
+     *
+     * description1:ext1,ext2,ext3;description2:ext1,ext2,ext3
+     */
+    ADR_FUNCTION(const char*) AdrGetSupportedFileFormats();
+
+    /**
+     * Returns a formatted string that lists the audio devices Audiere
+     * supports.  This function is DLL-safe.
+     *
+     * It is formatted in the following way:
+     *
+     * name1:description1;name2:description2;...
+     */
+    ADR_FUNCTION(const char*) AdrGetSupportedAudioDevices();
+
+    ADR_FUNCTION(int) AdrGetSampleSize(SampleFormat format);
+
+    ADR_FUNCTION(AudioDevice*) AdrOpenDevice(
+      const char* name,
+      const char* parameters);
+
+    ADR_FUNCTION(SampleSource*) AdrOpenSampleSource(
+      const char* filename,
+      FileFormat file_format);
+    ADR_FUNCTION(SampleSource*) AdrOpenSampleSourceFromFile(
+      File* file,
+      FileFormat file_format);
+    ADR_FUNCTION(SampleSource*) AdrCreateTone(double frequency);
+    ADR_FUNCTION(SampleSource*) AdrCreateSquareWave(double frequency);
+    ADR_FUNCTION(SampleSource*) AdrCreateWhiteNoise();
+    ADR_FUNCTION(SampleSource*) AdrCreatePinkNoise();
+
+    ADR_FUNCTION(LoopPointSource*) AdrCreateLoopPointSource(
+      SampleSource* source);
+
+    ADR_FUNCTION(OutputStream*) AdrOpenSound(
+      AudioDevice* device,
+      SampleSource* source,
+      bool streaming);
+
+    ADR_FUNCTION(SampleBuffer*) AdrCreateSampleBuffer(
+      void* samples,
+      int frame_count,
+      int channel_count,
+      int sample_rate,
+      SampleFormat sample_format);
+    ADR_FUNCTION(SampleBuffer*) AdrCreateSampleBufferFromSource(
+      SampleSource* source);
+
+    ADR_FUNCTION(SoundEffect*) AdrOpenSoundEffect(
+      AudioDevice* device,
+      SampleSource* source,
+      SoundEffectType type);
+
+    ADR_FUNCTION(File*) AdrOpenFile(
+      const char* name,
+      bool writeable);
+
+    ADR_FUNCTION(File*) AdrCreateMemoryFile(
+      const void* buffer,
+      int size);
+
+    ADR_FUNCTION(const char*) AdrEnumerateCDDevices();
+
+    ADR_FUNCTION(CDDevice*) AdrOpenCDDevice(
+      const char* name);  // Parameters?
+
+    ADR_FUNCTION(MIDIDevice*) AdrOpenMIDIDevice(
+      const char* name);  // Parameters?
+  }
+
+
+
+
+  /*-------- PUBLIC API FUNCTIONS --------*/
+
+
+  /**
+   * Returns the Audiere version string.
+   *
+   * @return  Audiere version information
+   */
+  inline const char* GetVersion() {
+    return hidden::AdrGetVersion();
+  }
+
+
+  inline void SplitString(
+    std::vector<std::string>& out,
+    const char* in,
+    char delim)
+  {
+    out.clear();
+    while (*in) {
+      const char* next = strchr(in, delim);
+      if (next) {
+        out.push_back(std::string(in, next));
+      } else {
+        out.push_back(in);
+      }
+
+      in = (next ? next + 1 : "");
+    }
+  }
+
+
+  /// Describes a file format that Audiere supports.
+  struct FileFormatDesc {
+    /// Short description of format, such as "MP3 Files" or "Mod Files"
+    std::string description;
+
+    /// List of support extensions, such as {"mod", "it", "xm"}
+    std::vector<std::string> extensions;
+  };
+
+  /// Populates a vector of FileFormatDesc structs.
+  inline void GetSupportedFileFormats(std::vector<FileFormatDesc>& formats) {
+    std::vector<std::string> descriptions;
+    SplitString(descriptions, hidden::AdrGetSupportedFileFormats(), ';');
+
+    formats.resize(descriptions.size());
+    for (unsigned i = 0; i < descriptions.size(); ++i) {
+      const char* d = descriptions[i].c_str();
+      const char* colon = strchr(d, ':');
+      formats[i].description.assign(d, colon);
+
+      SplitString(formats[i].extensions, colon + 1, ',');
+    }
+  }
+
+
+  /// Describes a supported audio device.
+  struct AudioDeviceDesc {
+    /// Name of device, i.e. "directsound", "winmm", or "oss"
+    std::string name;
+
+    // Textual description of device.
+    std::string description;
+  };
+
+  /// Populates a vector of AudioDeviceDesc structs.
+  inline void GetSupportedAudioDevices(std::vector<AudioDeviceDesc>& devices) {
+    std::vector<std::string> descriptions;
+    SplitString(descriptions, hidden::AdrGetSupportedAudioDevices(), ';');
+
+    devices.resize(descriptions.size());
+    for (unsigned i = 0; i < descriptions.size(); ++i) {
+      std::vector<std::string> d;
+      SplitString(d, descriptions[i].c_str(), ':');
+      devices[i].name        = d[0];
+      devices[i].description = d[1];
+    }
+  }
+
+
+  /**
+   * Get the size of a sample in a specific sample format.
+   * This is commonly used to determine how many bytes a chunk of
+   * PCM data will take.
+   *
+   * @return  Number of bytes a single sample in the specified format
+   *          takes.
+   */
+  inline int GetSampleSize(SampleFormat format) {
+    return hidden::AdrGetSampleSize(format);
+  }
+
+  /**
+   * Open a new audio device. If name or parameters are not specified,
+   * defaults are used. Each platform has its own set of audio devices.
+   * Every platform supports the "null" audio device.
+   *
+   * @param  name  name of audio device that should be used
+   * @param  parameters  comma delimited list of audio-device parameters;
+   *                     for example, "buffer=100,rate=44100"
+   *
+   * @return  new audio device object if OpenDevice succeeds, and 0 in case
+   *          of failure
+   */
+  inline AudioDevice* OpenDevice(
+    const char* name = 0,
+    const char* parameters = 0)
+  {
+    return hidden::AdrOpenDevice(name, parameters);
+  }
+
+  /**
+   * Create a streaming sample source from a sound file.  This factory simply
+   * opens a default file from the system filesystem and calls
+   * OpenSampleSource(File*).
+   *
+   * @see OpenSampleSource(File*)
+   */
+  inline SampleSource* OpenSampleSource(
+    const char* filename,
+    FileFormat file_format = FF_AUTODETECT)
+  {
+    return hidden::AdrOpenSampleSource(filename, file_format);
+  }
+
+  /**
+   * Opens a sample source from the specified file object.  If the sound file
+   * cannot be opened, this factory function returns 0.
+   *
+   * @note  Some sound files support seeking, while some don't.
+   *
+   * @param file         File object from which to open the decoder
+   * @param file_format  Format of the file to load.  If FF_AUTODETECT,
+   *                     Audiere will try opening the file in each format.
+   *
+   * @return  new SampleSource if OpenSampleSource succeeds, 0 otherwise
+   */
+  inline SampleSource* OpenSampleSource(
+    const FilePtr& file,
+    FileFormat file_format = FF_AUTODETECT)
+  {
+    return hidden::AdrOpenSampleSourceFromFile(file.get(), file_format);
+  }
+
+  /**
+   * Create a tone sample source with the specified frequency.
+   *
+   * @param  frequency  Frequency of the tone in Hz.
+   *
+   * @return  tone sample source
+   */
+  inline SampleSource* CreateTone(double frequency) {
+    return hidden::AdrCreateTone(frequency);
+  }
+
+  /**
+   * Create a square wave with the specified frequency.
+   *
+   * @param  frequency  Frequency of the wave in Hz.
+   *
+   * @return  wave sample source
+   */
+  inline SampleSource* CreateSquareWave(double frequency) {
+    return hidden::AdrCreateSquareWave(frequency);
+  }
+
+  /**
+   * Create a white noise sample source.  White noise is just random
+   * data.
+   *
+   * @return  white noise sample source
+   */
+  inline SampleSource* CreateWhiteNoise() {
+    return hidden::AdrCreateWhiteNoise();
+  }
+
+  /**
+   * Create a pink noise sample source.  Pink noise is noise with equal
+   * power distribution among octaves (logarithmic), not frequencies.
+   *
+   * @return  pink noise sample source
+   */
+  inline SampleSource* CreatePinkNoise() {
+    return hidden::AdrCreatePinkNoise();
+  }
+
+  /**
+   * Create a LoopPointSource from a SampleSource.  The SampleSource must
+   * be seekable.  If it isn't, or the source isn't valid, this function
+   * returns 0.
+   */
+  inline LoopPointSource* CreateLoopPointSource(
+    const SampleSourcePtr& source)
+  {
+    return hidden::AdrCreateLoopPointSource(source.get());
+  }
+
+  /**
+   * Creates a LoopPointSource from a source loaded from a file.
+   */
+  inline LoopPointSource* CreateLoopPointSource(
+    const char* filename,
+    FileFormat file_format = FF_AUTODETECT)
+  {
+    return CreateLoopPointSource(OpenSampleSource(filename, file_format));
+  }
+
+  /**
+   * Creates a LoopPointSource from a source loaded from a file.
+   */
+  inline LoopPointSource* CreateLoopPointSource(
+    const FilePtr& file,
+    FileFormat file_format = FF_AUTODETECT)
+  {
+    return CreateLoopPointSource(OpenSampleSource(file, file_format));
+  }
+
+  /**
+   * Try to open a sound buffer using the specified AudioDevice and
+   * sample source.  If the specified sample source is seekable, it
+   * loads it into memory and uses AudioDevice::openBuffer to create
+   * the output stream.  If the stream is not seekable, it uses
+   * AudioDevice::openStream to create the output stream.  This means
+   * that certain file types must always be streamed, and therefore,
+   * OpenSound will hold on to the file object.  If you must guarantee
+   * that the file on disk is no longer referenced, you must create
+   * your own memory file implementation and load your data into that
+   * before calling OpenSound.
+   *
+   * @param device  AudioDevice in which to open the output stream.
+   *
+   * @param source  SampleSource used to generate samples for the sound
+   *                object.  OpenSound takes ownership of source, even
+   *                if it returns 0.  (In that case, OpenSound immediately
+   *                deletes the SampleSource.)
+   *
+   * @param streaming  If false or unspecified, OpenSound attempts to
+   *                   open the entire sound into memory.  Otherwise, it
+   *                   streams the sound from the file.
+   *
+   * @return  new output stream if successful, 0 otherwise
+   */
+  inline OutputStream* OpenSound(
+    const AudioDevicePtr& device,
+    const SampleSourcePtr& source,
+    bool streaming = false)
+  {
+    return hidden::AdrOpenSound(device.get(), source.get(), streaming);
+  }
+
+  /**
+   * Calls OpenSound(AudioDevice*, SampleSource*) with a sample source
+   * created via OpenSampleSource(const char*).
+   */
+  inline OutputStream* OpenSound(
+    const AudioDevicePtr& device,
+    const char* filename,
+    bool streaming = false,
+    FileFormat file_format = FF_AUTODETECT)
+  {
+    SampleSource* source = OpenSampleSource(filename, file_format);
+    return OpenSound(device, source, streaming);
+  }
+
+  /**
+   * Calls OpenSound(AudioDevice*, SampleSource*) with a sample source
+   * created via OpenSampleSource(File* file).
+   */
+  inline OutputStream* OpenSound(
+    const AudioDevicePtr& device,
+    const FilePtr& file,
+    bool streaming = false,
+    FileFormat file_format = FF_AUTODETECT)
+  {
+    SampleSource* source = OpenSampleSource(file, file_format);
+    return OpenSound(device, source, streaming);
+  }
+
+  /**
+   * Create a SampleBuffer object using the specified samples and formats.
+   *
+   * @param samples  Pointer to a buffer of samples used to initialize the
+   *                 new object.  If this is 0, the sample buffer contains
+   *                 just silence.
+   *
+   * @param frame_count  Size of the sample buffer in frames.
+   *
+   * @param channel_count  Number of channels in each frame.
+   *
+   * @param sample_rate  Sample rate in Hz.
+   *
+   * @param sample_format  Format of each sample.  @see SampleFormat.
+   *
+   * @return  new SampleBuffer object
+   */
+  inline SampleBuffer* CreateSampleBuffer(
+    void* samples,
+    int frame_count,
+    int channel_count,
+    int sample_rate,
+    SampleFormat sample_format)
+  {
+    return hidden::AdrCreateSampleBuffer(
+      samples, frame_count,
+      channel_count, sample_rate, sample_format);
+  }
+
+  /**
+   * Create a SampleBuffer object from a SampleSource.
+   *
+   * @param source  Seekable sample source used to create the buffer.
+   *                If the source is not seekable, then the function
+   *                fails.
+   *
+   * @return  new sample buffer if success, 0 otherwise
+   */
+  inline SampleBuffer* CreateSampleBuffer(const SampleSourcePtr& source) {
+    return hidden::AdrCreateSampleBufferFromSource(source.get());
+  }
+
+  /**
+   * Open a SoundEffect object from the given sample source and sound
+   * effect type.  @see SoundEffect
+   *
+   * @param device  AudioDevice on which the sound is played.
+   *
+   * @param source  The sample source used to feed the sound effect
+   *                with data.
+   *
+   * @param type  The type of the sound effect.  If type is MULTIPLE,
+   *              the source must be seekable.
+   *
+   * @return  new SoundEffect object if successful, 0 otherwise
+   */
+  inline SoundEffect* OpenSoundEffect(
+    const AudioDevicePtr& device,
+    const SampleSourcePtr& source,
+    SoundEffectType type)
+  {
+    return hidden::AdrOpenSoundEffect(device.get(), source.get(), type);
+  }
+
+  /**
+   * Calls OpenSoundEffect(AudioDevice*, SampleSource*,
+   * SoundEffectType) with a sample source created from the filename.
+   */
+  inline SoundEffect* OpenSoundEffect(
+    const AudioDevicePtr& device,
+    const char* filename,
+    SoundEffectType type,
+    FileFormat file_format = FF_AUTODETECT)
+  {
+    SampleSource* source = OpenSampleSource(filename, file_format);
+    return OpenSoundEffect(device, source, type);
+  }
+
+  /**
+   * Calls OpenSoundEffect(AudioDevice*, SampleSource*,
+   * SoundEffectType) with a sample source created from the file.
+   */
+  inline SoundEffect* OpenSoundEffect(
+    const AudioDevicePtr& device,
+    const FilePtr& file,
+    SoundEffectType type,
+    FileFormat file_format = FF_AUTODETECT)
+  {
+    SampleSource* source = OpenSampleSource(file, file_format);
+    return OpenSoundEffect(device, source, type);
+  }
+
+  /**
+   * Opens a default file implementation from the local filesystem.
+   *
+   * @param filename   The name of the file on the local filesystem.
+   * @param writeable  Whether the writing to the file is allowed.
+   */
+  inline File* OpenFile(const char* filename, bool writeable) {
+    return hidden::AdrOpenFile(filename, writeable);
+  }
+
+  /**
+   * Creates a File implementation that reads from a buffer in memory.
+   * It stores a copy of the buffer that is passed in.
+   *
+   * The File object does <i>not</i> take ownership of the memory buffer.
+   * When the file is destroyed, it will not free the memory.
+   *
+   * @param buffer  Pointer to the beginning of the data.
+   * @param size    Size of the buffer in bytes.
+   *
+   * @return  0 if size is non-zero and buffer is null. Otherwise,
+   *          returns a valid File object.
+   */
+  inline File* CreateMemoryFile(const void* buffer, int size) {
+    return hidden::AdrCreateMemoryFile(buffer, size);
+  }
+
+  /**
+   * Generates a list of available CD device names.
+   *
+   * @param devices A vector of strings to be filled.
+   */
+  inline void EnumerateCDDevices(std::vector<std::string>& devices) {
+    const char* d = hidden::AdrEnumerateCDDevices();
+    while (d && *d) {
+      devices.push_back(d);
+      d += strlen(d) + 1;
+    }
+  }
+
+  /**
+   * Opens the specified CD playback device.
+   * 
+   * @param device  The filesystem device to be played.
+   *                e.g. Linux: "/dev/cdrom", Windows: "D:"
+   *
+   * @return  0 if opening device failed, valid CDDrive object otherwise.
+   */
+  inline CDDevice* OpenCDDevice(const char* device) {
+    return hidden::AdrOpenCDDevice(device);
+  }
+
+  /**
+   * Opens the specified MIDI synthesizer device.
+   *
+   * @param device  The name of the device.  Unused for now.
+   *
+   * @return  0 if opening device failed, valid MIDIDevice object otherwise.
+   */
+  inline MIDIDevice* OpenMIDIDevice(const char* device) {
+    return hidden::AdrOpenMIDIDevice(device);
+  }
+
+}
+
+
+#endif
Index: P/trunk/App/Demos/Geom/audiere.h
===================================================================
--- /GTP/trunk/App/Demos/Geom/audiere.h	(revision 1791)
+++ 	(revision )
@@ -1,1565 +1,0 @@
-/**
- * @file
- *
- * Audiere Sound System
- * Version 1.9.4
- * (c) 2001-2003 Chad Austin
- *
- * This API uses principles explained at
- * http://aegisknight.org/cppinterface.html
- *
- * This code licensed under the terms of the LGPL.  See doc/license.txt.
- *
- *
- * Note: When compiling this header in gcc, you may want to use the
- * -Wno-non-virtual-dtor flag to get rid of those annoying "class has
- * virtual functions but no virtual destructor" warnings.
- *
- * This file is structured as follows:
- * - includes, macro definitions, other general setup
- * - interface definitions
- * - DLL-safe entry points (not for general use)
- * - inline functions that use those entry points
- */
-
-#ifndef AUDIERE_H
-#define AUDIERE_H
-
-
-#include <vector>
-#include <string>
-
-#ifdef _MSC_VER
-#pragma warning(disable : 4786)
-#endif
-
-
-#ifndef __cplusplus
-  #error Audiere requires C++
-#endif
-
-
-// DLLs in Windows should use the standard (Pascal) calling convention
-#ifndef ADR_CALL
-  #if defined(WIN32) || defined(_WIN32)
-    #define ADR_CALL __stdcall
-  #else
-    #define ADR_CALL
-  #endif
-#endif
-
-// Export functions from the DLL
-#ifndef ADR_DECL
-#  if defined(WIN32) || defined(_WIN32)
-#    ifdef AUDIERE_EXPORTS
-#      define ADR_DECL __declspec(dllexport)
-#    else
-#      define ADR_DECL __declspec(dllimport)
-#    endif
-#  else
-#    define ADR_DECL
-#  endif
-#endif
-
-
-
-#define ADR_FUNCTION(ret) extern "C" ADR_DECL ret ADR_CALL
-#define ADR_METHOD(ret) virtual ret ADR_CALL
-
-
-namespace audiere {
-
-  class RefCounted {
-  protected:
-    /**
-     * Protected so users of refcounted classes don't use std::auto_ptr
-     * or the delete operator.
-     *
-     * Interfaces that derive from RefCounted should define an inline,
-     * empty, protected destructor as well.
-     */
-    ~RefCounted() { }
-
-  public:
-    /**
-     * Add a reference to the internal reference count.
-     */
-    ADR_METHOD(void) ref() = 0;
-
-    /**
-     * Remove a reference from the internal reference count.  When this
-     * reaches 0, the object is destroyed.
-     */
-    ADR_METHOD(void) unref() = 0;
-  };
-
-
-  template<typename T>
-  class RefPtr {
-  public:
-    RefPtr(T* ptr = 0) {
-      m_ptr = 0;
-      *this = ptr;
-    }
-
-    RefPtr(const RefPtr<T>& ptr) {
-      m_ptr = 0;
-      *this = ptr;
-    }
-
-    ~RefPtr() {
-      if (m_ptr) {
-        m_ptr->unref();
-        m_ptr = 0;
-      }
-    }
- 
-    RefPtr<T>& operator=(T* ptr) {
-      if (ptr != m_ptr) {
-        if (m_ptr) {
-          m_ptr->unref();
-        }
-        m_ptr = ptr;
-        if (m_ptr) {
-          m_ptr->ref();
-        }
-      }
-      return *this;
-    }
-
-    RefPtr<T>& operator=(const RefPtr<T>& ptr) {
-      *this = ptr.m_ptr;
-      return *this;
-    }
-
-    T* operator->() const {
-      return m_ptr;
-    }
-
-    T& operator*() const {
-      return *m_ptr;
-    }
-
-    operator bool() const {
-      return (m_ptr != 0);
-    }
-
-    T* get() const {
-      return m_ptr;
-    }
-
-  private:
-    T* m_ptr;
-  };
-
-
-  template<typename T, typename U>
-  bool operator==(const RefPtr<T>& a, const RefPtr<U>& b) {
-      return (a.get() == b.get());
-  }
-
-  template<typename T>
-  bool operator==(const RefPtr<T>& a, const T* b) {
-      return (a.get() == b);
-  }
-
-  template<typename T>
-  bool operator==(const T* a, const RefPtr<T>& b) {
-      return (a == b.get());
-  }
-  
-
-  template<typename T, typename U>
-  bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b) {
-      return (a.get() != b.get());
-  }
-
-  template<typename T>
-  bool operator!=(const RefPtr<T>& a, const T* b) {
-      return (a.get() != b);
-  }
-
-  template<typename T>
-  bool operator!=(const T* a, const RefPtr<T>& b) {
-      return (a != b.get());
-  }
-
-
-  /**
-   * A basic implementation of the RefCounted interface.  Derive
-   * your implementations from RefImplementation<YourInterface>.
-   */
-  template<class Interface>
-  class RefImplementation : public Interface {
-  protected:
-    RefImplementation() {
-      m_ref_count = 0;
-    }
-
-    /**
-     * So the implementation can put its destruction logic in the destructor,
-     * as natural C++ code does.
-     */
-    virtual ~RefImplementation() { }
-
-  public:
-    void ADR_CALL ref() {
-      ++m_ref_count;
-    }
-
-    void ADR_CALL unref() {
-      if (--m_ref_count == 0) {
-        delete this;
-      }
-    }
-
-  private:
-    int m_ref_count;
-  };
-
-
-  /**
-   * Represents a random-access file, usually stored on a disk.  Files
-   * are always binary: that is, they do no end-of-line
-   * transformations.  File objects are roughly analogous to ANSI C
-   * FILE* objects.
-   *
-   * This interface is not synchronized.
-   */
-  class File : public RefCounted {
-  protected:
-    ~File() { }
-
-  public:
-    /**
-     * The different ways you can seek within a file.
-     */
-    enum SeekMode {
-      BEGIN,
-      CURRENT,
-      END,
-    };
-
-    /**
-     * Read size bytes from the file, storing them in buffer.
-     *
-     * @param buffer  buffer to read into
-     * @param size    number of bytes to read
-     *
-     * @return  number of bytes successfully read
-     */
-    ADR_METHOD(int) read(void* buffer, int size) = 0;
-
-    /**
-     * Jump to a new position in the file, using the specified seek
-     * mode.  Remember: if mode is END, the position must be negative,
-     * to seek backwards from the end of the file into its contents.
-     * If the seek fails, the current position is undefined.
-     *
-     * @param position  position relative to the mode
-     * @param mode      where to seek from in the file
-     *
-     * @return  true on success, false otherwise
-     */
-    ADR_METHOD(bool) seek(int position, SeekMode mode) = 0;
-
-    /**
-     * Get current position within the file.
-     *
-     * @return  current position
-     */
-    ADR_METHOD(int) tell() = 0;
-  };
-  typedef RefPtr<File> FilePtr;
-
-
-  /// Storage formats for sample data.
-  enum SampleFormat {
-    SF_U8,  ///< unsigned 8-bit integer [0,255]
-    SF_S16, ///< signed 16-bit integer in host endianness [-32768,32767]
-  };
-
-
-  /// Supported audio file formats.
-  enum FileFormat {
-    FF_AUTODETECT,
-    FF_WAV,
-    FF_OGG,
-    FF_FLAC,
-    FF_MP3,
-    FF_MOD,
-    FF_AIFF,
-    FF_SPEEX,
-  };
-
-
-  /**
-   * Source of raw PCM samples.  Sample sources have an intrinsic format
-   * (@see SampleFormat), sample rate, and number of channels.  They can
-   * be read from or reset.
-   *
-   * Some sample sources are seekable.  Seekable sources have two additional
-   * properties: length and position.  Length is read-only.
-   *
-   * This interface is not synchronized.
-   */
-  class SampleSource : public RefCounted {
-  protected:
-    ~SampleSource() { }
-
-  public:
-    /**
-     * Retrieve the number of channels, sample rate, and sample format of
-     * the sample source.
-     */
-    ADR_METHOD(void) getFormat(
-      int& channel_count,
-      int& sample_rate,
-      SampleFormat& sample_format) = 0;
-
-    /**
-     * Read frame_count samples into buffer.  buffer must be at least
-     * |frame_count * GetSampleSize(format) * channel_count| bytes long.
-     *
-     * @param frame_count  number of frames to read
-     * @param buffer       buffer to store samples in
-     *
-     * @return  number of frames actually read
-     */
-    ADR_METHOD(int) read(int frame_count, void* buffer) = 0;
-
-    /**
-     * Reset the sample source.  This has the same effect as setPosition(0)
-     * on a seekable source.  On an unseekable source, it resets all internal
-     * state to the way it was when the source was first created.
-     */
-    ADR_METHOD(void) reset() = 0;
-
-    /**
-     * @return  true if the stream is seekable, false otherwise
-     */
-    ADR_METHOD(bool) isSeekable() = 0;
-
-    /**
-     * @return  number of frames in the stream, or 0 if the stream is not
-     *          seekable
-     */
-    ADR_METHOD(int) getLength() = 0;
-    
-    /**
-     * Sets the current position within the sample source.  If the stream
-     * is not seekable, this method does nothing.
-     *
-     * @param position  current position in frames
-     */
-    ADR_METHOD(void) setPosition(int position) = 0;
-
-    /**
-     * Returns the current position within the sample source.
-     *
-     * @return  current position in frames
-     */
-    ADR_METHOD(int) getPosition() = 0;
-
-    /**
-     * @return  true if the sample source is set to repeat
-     */
-    ADR_METHOD(bool) getRepeat() = 0;
-
-    /**
-     * Sets whether the sample source should repeat or not.  Note that not
-     * all sample sources repeat by starting again at the beginning of the
-     * sound.  For example MOD files can contain embedded loop points.
-     *
-     * @param repeat  true if the source should repeat, false otherwise
-     */
-    ADR_METHOD(void) setRepeat(bool repeat) = 0;
-
-    /// Returns number of metadata tags present in this sample source.
-    ADR_METHOD(int) getTagCount() = 0;
-
-    /**
-     * Returns the key of the i'th tag in the source.  If the tag is
-     * "author=me", the key is "author".
-     */
-    virtual const char* ADR_CALL getTagKey(int i) = 0;
-
-    /**
-     * Returns the value of the i'th tag in the source.  If the tag is
-     * "author=me", the value is "me".
-     */
-    virtual const char* ADR_CALL getTagValue(int i) = 0;
-
-    /**
-     * Returns the type of the i'th tag in the source.  The type is where
-     * the tag comes from, i.e. "ID3v1", "ID3v2", or "vorbis".
-     */
-    virtual const char* ADR_CALL getTagType(int i) = 0;
-  };
-  typedef RefPtr<SampleSource> SampleSourcePtr;
-
-
-  /**
-   * LoopPointSource is a wrapper around another SampleSource, providing
-   * custom loop behavior.  LoopPointSource maintains a set of links
-   * within the sample stream and whenever the location of one of the links
-   * (i.e. a loop point) is reached, the stream jumps to that link's target.
-   * Each loop point maintains a count.  Every time a loop point comes into
-   * effect, the count is decremented.  Once it reaches zero, that loop point
-   * is temporarily disabled.  If a count is not a positive value, it
-   * cannot be disabled.  Calling reset() resets all counts to their initial
-   * values.
-   *
-   * Loop points only take effect when repeating has been enabled via the
-   * setRepeat() method.
-   *
-   * Loop points are stored in sorted order by their location.  Each one
-   * has an index based on its location within the list.  A loop point's
-   * index will change if another is added before it.
-   *
-   * There is always one implicit loop point after the last sample that
-   * points back to the first.  That way, this class's default looping
-   * behavior is the same as a standard SampleSource.  This loop point
-   * does not show up in the list.
-   */
-  class LoopPointSource : public SampleSource {
-  protected:
-    ~LoopPointSource() { }
-
-  public:
-    /**
-     * Adds a loop point to the stream.  If a loop point at 'location'
-     * already exists, the new one replaces it.  Location and target are
-     * clamped to the actual length of the stream.
-     *
-     * @param location   frame where loop occurs
-     * @param target     frame to jump to after loop point is hit
-     * @param loopCount  number of times to execute this jump.
-     */
-    ADR_METHOD(void) addLoopPoint(
-      int location, int target, int loopCount) = 0;
-
-    /**
-     * Removes the loop point at index 'index' from the stream.
-     *
-     * @param index  index of the loop point to remove
-     */
-    ADR_METHOD(void) removeLoopPoint(int index) = 0;
-
-    /**
-     * Returns the number of loop points in this stream.
-     */
-    ADR_METHOD(int) getLoopPointCount() = 0;
-
-    /**
-     * Retrieves information about a specific loop point.
-     *
-     * @param index      index of the loop point
-     * @param location   frame where loop occurs
-     * @param target     loop point's target frame
-     * @param loopCount  number of times to loop from this particular point
-     *
-     * @return  true if the index is valid and information is returned
-     */
-    ADR_METHOD(bool) getLoopPoint(
-      int index, int& location, int& target, int& loopCount) = 0;
-  };
-  typedef RefPtr<LoopPointSource> LoopPointSourcePtr;
-
-
-  /**
-   * A connection to an audio device.  Multiple output streams are
-   * mixed by the audio device to produce the final waveform that the
-   * user hears.
-   *
-   * Each output stream can be independently played and stopped.  They
-   * also each have a volume from 0.0 (silence) to 1.0 (maximum volume).
-   */
-  class OutputStream : public RefCounted {
-  protected:
-    ~OutputStream() { }
-
-  public:
-    /**
-     * Start playback of the output stream.  If the stream is already
-     * playing, this does nothing.
-     */
-    ADR_METHOD(void) play() = 0;
-
-    /**
-     * Stop playback of the output stream.  If the stream is already
-     * stopped, this does nothing.
-     */
-    ADR_METHOD(void) stop() = 0;
-
-    /**
-     * @return  true if the output stream is playing, false otherwise
-     */
-    ADR_METHOD(bool) isPlaying() = 0;
-
-    /**
-     * Reset the sample source or buffer to the beginning. On seekable
-     * streams, this operation is equivalent to setPosition(0).
-     *
-     * On some output streams, this operation can be moderately slow, as up to
-     * several seconds of PCM buffer must be refilled.
-     */
-    ADR_METHOD(void) reset() = 0;
-
-    /**
-     * Set whether the output stream should repeat.
-     *
-     * @param repeat  true if the stream should repeat, false otherwise
-     */
-    ADR_METHOD(void) setRepeat(bool repeat) = 0;
-
-    /**
-     * @return  true if the stream is repeating
-     */
-    ADR_METHOD(bool) getRepeat() = 0;
-
-    /**
-     * Sets the stream's volume.
-     *
-     * @param  volume  0.0 = silence, 1.0 = maximum volume (default)
-     */
-    ADR_METHOD(void) setVolume(float volume) = 0;
-
-    /**
-     * Gets the current volume.
-     *
-     * @return  current volume of the output stream
-     */
-    ADR_METHOD(float) getVolume() = 0;
-
-    /**
-     * Set current pan.
-     *
-     * @param pan  -1.0 = left, 0.0 = center (default), 1.0 = right
-     */
-    ADR_METHOD(void) setPan(float pan) = 0;
-
-    /**
-     * Get current pan.
-     */
-    ADR_METHOD(float) getPan() = 0;
-
-    /**
-     * Set current pitch shift.
-     *
-     * @param shift  can range from 0.5 to 2.0.  default is 1.0.
-     */
-    ADR_METHOD(void) setPitchShift(float shift) = 0;
-
-    /**
-     * Get current pitch shift.  Defaults to 1.0.
-     */
-    ADR_METHOD(float) getPitchShift() = 0;
-
-    /**
-     * @return  true if the stream is seekable, false otherwise
-     */
-    ADR_METHOD(bool) isSeekable() = 0;
-
-    /**
-     * @return  number of frames in the stream, or 0 if the stream is not
-     *          seekable
-     */
-    ADR_METHOD(int) getLength() = 0;
-    
-    /**
-     * Sets the current position within the sample source.  If the stream
-     * is not seekable, this method does nothing.
-     *
-     * @param position  current position in frames
-     */
-    ADR_METHOD(void) setPosition(int position) = 0;
-
-    /**
-     * Returns the current position within the sample source.
-     *
-     * @return  current position in frames
-     */
-    ADR_METHOD(int) getPosition() = 0;
-  };
-  typedef RefPtr<OutputStream> OutputStreamPtr;
-
-
-  /// An integral code representing a specific type of event.
-  enum EventType {
-    ET_STOP, ///< See StopEvent and StopCallback
-  };
-
-
-  /// Base interface for event-specific data passed to callbacks.
-  class Event : public RefCounted {
-  protected:
-    ~Event() { }
-
-  public:
-    /// Returns the EventType code for this event.
-    ADR_METHOD(EventType) getType() = 0;
-  };
-  typedef RefPtr<Event> EventPtr;
-
-
-  /**
-   * An event object that gets passed to implementations of StopCallback
-   * when a stream has stopped playing.
-   */
-  class StopEvent : public Event {
-  protected:
-    ~StopEvent() { }
-
-  public:
-    EventType ADR_CALL getType() { return ET_STOP; }
-
-    /// A code representing the reason the stream stopped playback.
-    enum Reason {
-      STOP_CALLED,  ///< stop() was called from an external source.
-      STREAM_ENDED, ///< The stream reached its end.
-    };
-
-    /**
-     * @return Pointer to the OutputStream that stopped playback.
-     */
-    ADR_METHOD(OutputStream*) getOutputStream() = 0;
-
-    /**
-     * @return Reason for the stop event.
-     */
-    ADR_METHOD(Reason) getReason() = 0;
-  };
-  typedef RefPtr<StopEvent> StopEventPtr;
-
-
-  /**
-   * Base interface for all callbacks.  See specific callback implementations
-   * for descriptions.
-   */  
-  class Callback : public RefCounted {
-  protected:
-    ~Callback() { }
-
-  public:
-    /**
-     * Returns the event type that this callback knows how to handle.
-     */
-    ADR_METHOD(EventType) getType() = 0;
-
-    /**
-     * Actually executes the callback with event-specific data.  This is
-     * only called if event->getType() == this->getType().
-     */
-    ADR_METHOD(void) call(Event* event) = 0;
-  };
-  typedef RefPtr<Callback> CallbackPtr;
-
-  
-  /**
-   * To listen for stream stopped events on a device, implement this interface
-   * and call registerStopCallback() on the device, passing your
-   * implementation.  streamStopped() will be called whenever a stream on that
-   * device stops playback.
-   *
-   * WARNING: StopCallback is called from another thread.  Make sure your
-   * callback is thread-safe.
-   */
-  class StopCallback : public Callback {
-  protected:
-    ~StopCallback() { }
-
-  public:
-    EventType ADR_CALL getType() { return ET_STOP; }
-    void ADR_CALL call(Event* event) {
-      streamStopped(static_cast<StopEvent*>(event));
-    }
-
-    /**
-     * Called when a stream has stopped.
-     *
-     * @param event  Information pertaining to the event.
-     */
-    ADR_METHOD(void) streamStopped(StopEvent* event) = 0;
-  };
-  typedef RefPtr<StopCallback> StopCallbackPtr;
-
-
-  /**
-   * AudioDevice represents a device on the system which is capable
-   * of opening and mixing multiple output streams.  In Windows,
-   * DirectSound is such a device.
-   *
-   * This interface is synchronized.  update() and openStream() may
-   * be called on different threads.
-   */
-  class AudioDevice : public RefCounted {
-  protected:
-    ~AudioDevice() { }
-
-  public:
-    /**
-     * Tell the device to do any internal state updates.  Some devices
-     * update on an internal thread.  If that is the case, this method
-     * does nothing.
-     */
-    ADR_METHOD(void) update() = 0;
-
-    /**
-     * Open an output stream with a given sample source.  If the sample
-     * source ever runs out of data, the output stream automatically stops
-     * itself.
-     *
-     * The output stream takes ownership of the sample source, even if
-     * opening the output stream fails (in which case the source is
-     * immediately deleted).
-     *
-     * @param  source  the source used to feed the output stream with samples
-     *
-     * @return  new output stream if successful, 0 if failure
-     */
-    ADR_METHOD(OutputStream*) openStream(SampleSource* source) = 0;
-
-    /**
-     * Open a single buffer with the specified PCM data.  This is sometimes
-     * more efficient than streaming and works on a larger variety of audio
-     * devices.  In some implementations, this may download the audio data
-     * to the sound card's memory itself.
-     *
-     * @param samples  Buffer containing sample data.  openBuffer() does
-     *                 not take ownership of the memory.  The application
-     *                 is responsible for freeing it.  There must be at
-     *                 least |frame_count * channel_count *
-     *                 GetSampleSize(sample_format)| bytes in the buffer.
-     *
-     * @param frame_count  Number of frames in the buffer.
-     *
-     * @param channel_count  Number of audio channels.  1 = mono, 2 = stereo.
-     *
-     * @param sample_rate  Number of samples per second.
-     *
-     * @param sample_format  Format of samples in buffer.
-     *
-     * @return  new output stream if successful, 0 if failure
-     */
-    ADR_METHOD(OutputStream*) openBuffer(
-      void* samples,
-      int frame_count,
-      int channel_count,
-      int sample_rate,
-      SampleFormat sample_format) = 0;
-
-    /**
-     * Gets the name of the audio device.  For example "directsound" or "oss".
-     *
-     * @return name of audio device
-     */
-    ADR_METHOD(const char*) getName() = 0;
-
-    /**
-     * Registers 'callback' to receive events.  Callbacks can be
-     * registered multiple times.
-     */
-    ADR_METHOD(void) registerCallback(Callback* callback) = 0;
-    
-    /**
-     * Unregisters 'callback' once.  If it is registered multiple times,
-     * each unregisterStopCallback call unregisters one of the instances.
-     */
-    ADR_METHOD(void) unregisterCallback(Callback* callback) = 0;
-
-    /// Clears all of the callbacks from the device.
-    ADR_METHOD(void) clearCallbacks() = 0;
-  };
-  typedef RefPtr<AudioDevice> AudioDevicePtr;
-
-
-  /**
-   * A readonly sample container which can open sample streams as iterators
-   * through the buffer.  This is commonly used in cases where a very large
-   * sound effect is loaded once into memory and then streamed several times
-   * to the audio device.  This is more efficient memory-wise than loading
-   * the effect multiple times.
-   *
-   * @see CreateSampleBuffer
-   */
-  class SampleBuffer : public RefCounted {
-  protected:
-    ~SampleBuffer() { }
-
-  public:
-
-    /**
-     * Return the format of the sample data in the sample buffer.
-     * @see SampleSource::getFormat
-     */
-    ADR_METHOD(void) getFormat(
-      int& channel_count,
-      int& sample_rate,
-      SampleFormat& sample_format) = 0;
-
-    /**
-     * Get the length of the sample buffer in frames.
-     */
-    ADR_METHOD(int) getLength() = 0;
-
-    /**
-     * Get a readonly pointer to the samples contained within the buffer.  The
-     * buffer is |channel_count * frame_count * GetSampleSize(sample_format)|
-     * bytes long.
-     */
-    virtual const void* ADR_CALL getSamples() = 0;
-
-    /**
-     * Open a seekable sample source using the samples contained in the
-     * buffer.
-     */
-    ADR_METHOD(SampleSource*) openStream() = 0;
-  };
-  typedef RefPtr<SampleBuffer> SampleBufferPtr;
-
-
-  /**
-   * Defines the type of SoundEffect objects.  @see SoundEffect
-   */
-  enum SoundEffectType {
-    SINGLE,
-    MULTIPLE,
-  };
-
-
-  /**
-   * SoundEffect is a convenience class which provides a simple
-   * mechanism for basic sound playback.  There are two types of sound
-   * effects: SINGLE and MULTIPLE.  SINGLE sound effects only allow
-   * the sound to be played once at a time.  MULTIPLE sound effects
-   * always open a new stream to the audio device for each time it is
-   * played (cleaning up or reusing old streams if possible).
-   */
-  class SoundEffect : public RefCounted {
-  protected:
-    ~SoundEffect() { }
-
-  public:
-    /**
-     * Trigger playback of the sound.  If the SoundEffect is of type
-     * SINGLE, this plays the sound if it isn't playing yet, and
-     * starts it again if it is.  If the SoundEffect is of type
-     * MULTIPLE, play() simply starts playing the sound again.
-     */
-    ADR_METHOD(void) play() = 0;
-
-    /**
-     * If the sound is of type SINGLE, stop the sound.  If it is of
-     * type MULTIPLE, stop all playing instances of the sound.
-     */
-    ADR_METHOD(void) stop() = 0;
-
-    /**
-     * Sets the sound's volume.
-     *
-     * @param  volume  0.0 = silence, 1.0 = maximum volume (default)
-     */
-    ADR_METHOD(void) setVolume(float volume) = 0;
-
-    /**
-     * Gets the current volume.
-     *
-     * @return  current volume of the output stream
-     */
-    ADR_METHOD(float) getVolume() = 0;
-
-    /**
-     * Set current pan.
-     *
-     * @param pan  -1.0 = left, 0.0 = center (default), 1.0 = right
-     */
-    ADR_METHOD(void) setPan(float pan) = 0;
-
-    /**
-     * Get current pan.
-     */
-    ADR_METHOD(float) getPan() = 0;
-
-    /**
-     * Set current pitch shift.
-     *
-     * @param shift  can range from 0.5 to 2.0.  default is 1.0.
-     */
-    ADR_METHOD(void) setPitchShift(float shift) = 0;
-
-    /**
-     * Get current pitch shift.  Defaults to 1.0.
-     */
-    ADR_METHOD(float) getPitchShift() = 0;
-  };
-  typedef RefPtr<SoundEffect> SoundEffectPtr;
-
-
-  /**
-   * Represents a device capable of playing CD audio. Internally, this
-   * uses the MCI subsystem in windows and libcdaudio on other platforms.
-   * MCI subsystem: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_multimedia_command_strings.asp
-   * libcdaudio: http://cdcd.undergrid.net/libcdaudio/
-   */
-  class CDDevice : public RefCounted {
-  protected:
-    virtual ~CDDevice() { }
-
-  public:
-    /**
-     * Returns the name of this CD Device, often just the device name
-     * it was created with.
-     */
-    virtual const char* ADR_CALL getName() = 0;
-
-    /**
-     * Returns the number of audio tracks on the disc.
-     */
-    ADR_METHOD(int) getTrackCount() = 0;
-
-    /**
-     * Starts playback of the given track. If another track was
-     * already playing, the previous track is stopped.  IMPORTANT: Tracks are
-     * indexed from 0 to getTrackCount() - 1.
-     */
-    ADR_METHOD(void) play(int track) = 0;
-
-    /**
-     * Stops the playback, if the playback was already stopped, this
-     * does nothing.
-     */
-    ADR_METHOD(void) stop() = 0;
-    
-    /**
-     * pauses playback of the track that is currently playing (if any)
-     * This does nothing if no track is playing
-     */
-    ADR_METHOD(void) pause() = 0;
-
-    /**
-     * Resumes playback of the track that is currently paused (if any).
-     * This does nothing if no track is paused.
-     */
-    ADR_METHOD(void) resume() = 0;
-
-    /**
-     * Returns true if the CD is currently playing a sound, this could
-     * be through us, or through some other program.
-     */
-    ADR_METHOD(bool) isPlaying() = 0;
-
-    /**
-     * Returns true if the drive contains a cd. This might be slow
-     * on some systems, use with care.
-     */
-    ADR_METHOD(bool) containsCD() = 0;
-
-    /// Returns true if the door is open.
-    ADR_METHOD(bool) isDoorOpen() = 0;
-
-    /// Opens this device's door.
-    ADR_METHOD(void) openDoor() = 0;
-
-    /// Closes this device's door.
-    ADR_METHOD(void) closeDoor() = 0;
-  };
-  typedef RefPtr<CDDevice> CDDevicePtr;
-
-
-  /**
-   * An opened MIDI song that can be played, stopped, and seeked within.
-   * Uses MCI under Windows and is not supported in other platforms.
-   */
-  class MIDIStream : public RefCounted {
-  protected:
-    virtual ~MIDIStream() { }
-
-  public:
-    /**
-     * Begins playback of the song and does nothing if the song is already
-     * playing.
-     */
-    ADR_METHOD(void) play() = 0;
-
-    /// Stops playback of the song and seeks to the beginning.
-    ADR_METHOD(void) stop() = 0;
-
-    /**
-     * Stops playback of the song and does not change its current position.
-     * A subsequent play() will resume the song where it left off.
-     */
-    ADR_METHOD(void) pause() = 0;
-
-    /// Returns true if the song is currently playing, false otherwise.
-    ADR_METHOD(bool) isPlaying() = 0;
-
-    /// Returns the length of the song in milliseconds.
-    ADR_METHOD(int) getLength() = 0;
-
-    /// Returns the current position of the song in milliseconds.
-    ADR_METHOD(int) getPosition() = 0;
-
-    /// Sets the current position of the song.
-    ADR_METHOD(void) setPosition(int position) = 0;
-
-    /// Returns true if this song is set to repeat.
-    ADR_METHOD(bool) getRepeat() = 0;
-
-    /// Sets whether the song should repeat on completion.  Defaults to false.
-    ADR_METHOD(void) setRepeat(bool repeat) = 0;
-  };
-  typedef RefPtr<MIDIStream> MIDIStreamPtr;
-
-
-  /**
-   * A MIDIDevice must be instantiated in order to open MIDIStreams.
-   */
-  class MIDIDevice : public RefCounted {
-  protected:
-    virtual ~MIDIDevice() { }
-
-  public:
-    /**
-     * Returns the name of the device.
-     */
-    ADR_METHOD(const char*) getName() = 0;
-
-    /**
-     * openStream() creates and returns a new MIDIStream object from the
-     * file with the specified name, which then can be queried and played.
-     * This method returns NULL if the stream cannot be opened.
-     *
-     * Note: MCI subsystem limitations do not allow loading MIDIStream
-     * objects from an audiere File implementation.  This may be addressed
-     * in future versions of this API.
-     */
-    ADR_METHOD(MIDIStream*) openStream(const char* filename) = 0;
-  };
-  typedef RefPtr<MIDIDevice> MIDIDevicePtr;
-
-
-  /// PRIVATE API - for internal use only
-  namespace hidden {
-
-    // these are extern "C" so we don't mangle the names
-
-    ADR_FUNCTION(const char*) AdrGetVersion();
-
-    /**
-     * Returns a formatted string that lists the file formats that Audiere
-     * supports.  This function is DLL-safe.
-     *
-     * It is formatted in the following way:
-     *
-     * description1:ext1,ext2,ext3;description2:ext1,ext2,ext3
-     */
-    ADR_FUNCTION(const char*) AdrGetSupportedFileFormats();
-
-    /**
-     * Returns a formatted string that lists the audio devices Audiere
-     * supports.  This function is DLL-safe.
-     *
-     * It is formatted in the following way:
-     *
-     * name1:description1;name2:description2;...
-     */
-    ADR_FUNCTION(const char*) AdrGetSupportedAudioDevices();
-
-    ADR_FUNCTION(int) AdrGetSampleSize(SampleFormat format);
-
-    ADR_FUNCTION(AudioDevice*) AdrOpenDevice(
-      const char* name,
-      const char* parameters);
-
-    ADR_FUNCTION(SampleSource*) AdrOpenSampleSource(
-      const char* filename,
-      FileFormat file_format);
-    ADR_FUNCTION(SampleSource*) AdrOpenSampleSourceFromFile(
-      File* file,
-      FileFormat file_format);
-    ADR_FUNCTION(SampleSource*) AdrCreateTone(double frequency);
-    ADR_FUNCTION(SampleSource*) AdrCreateSquareWave(double frequency);
-    ADR_FUNCTION(SampleSource*) AdrCreateWhiteNoise();
-    ADR_FUNCTION(SampleSource*) AdrCreatePinkNoise();
-
-    ADR_FUNCTION(LoopPointSource*) AdrCreateLoopPointSource(
-      SampleSource* source);
-
-    ADR_FUNCTION(OutputStream*) AdrOpenSound(
-      AudioDevice* device,
-      SampleSource* source,
-      bool streaming);
-
-    ADR_FUNCTION(SampleBuffer*) AdrCreateSampleBuffer(
-      void* samples,
-      int frame_count,
-      int channel_count,
-      int sample_rate,
-      SampleFormat sample_format);
-    ADR_FUNCTION(SampleBuffer*) AdrCreateSampleBufferFromSource(
-      SampleSource* source);
-
-    ADR_FUNCTION(SoundEffect*) AdrOpenSoundEffect(
-      AudioDevice* device,
-      SampleSource* source,
-      SoundEffectType type);
-
-    ADR_FUNCTION(File*) AdrOpenFile(
-      const char* name,
-      bool writeable);
-
-    ADR_FUNCTION(File*) AdrCreateMemoryFile(
-      const void* buffer,
-      int size);
-
-    ADR_FUNCTION(const char*) AdrEnumerateCDDevices();
-
-    ADR_FUNCTION(CDDevice*) AdrOpenCDDevice(
-      const char* name);  // Parameters?
-
-    ADR_FUNCTION(MIDIDevice*) AdrOpenMIDIDevice(
-      const char* name);  // Parameters?
-  }
-
-
-
-
-  /*-------- PUBLIC API FUNCTIONS --------*/
-
-
-  /**
-   * Returns the Audiere version string.
-   *
-   * @return  Audiere version information
-   */
-  inline const char* GetVersion() {
-    return hidden::AdrGetVersion();
-  }
-
-
-  inline void SplitString(
-    std::vector<std::string>& out,
-    const char* in,
-    char delim)
-  {
-    out.clear();
-    while (*in) {
-      const char* next = strchr(in, delim);
-      if (next) {
-        out.push_back(std::string(in, next));
-      } else {
-        out.push_back(in);
-      }
-
-      in = (next ? next + 1 : "");
-    }
-  }
-
-
-  /// Describes a file format that Audiere supports.
-  struct FileFormatDesc {
-    /// Short description of format, such as "MP3 Files" or "Mod Files"
-    std::string description;
-
-    /// List of support extensions, such as {"mod", "it", "xm"}
-    std::vector<std::string> extensions;
-  };
-
-  /// Populates a vector of FileFormatDesc structs.
-  inline void GetSupportedFileFormats(std::vector<FileFormatDesc>& formats) {
-    std::vector<std::string> descriptions;
-    SplitString(descriptions, hidden::AdrGetSupportedFileFormats(), ';');
-
-    formats.resize(descriptions.size());
-    for (unsigned i = 0; i < descriptions.size(); ++i) {
-      const char* d = descriptions[i].c_str();
-      const char* colon = strchr(d, ':');
-      formats[i].description.assign(d, colon);
-
-      SplitString(formats[i].extensions, colon + 1, ',');
-    }
-  }
-
-
-  /// Describes a supported audio device.
-  struct AudioDeviceDesc {
-    /// Name of device, i.e. "directsound", "winmm", or "oss"
-    std::string name;
-
-    // Textual description of device.
-    std::string description;
-  };
-
-  /// Populates a vector of AudioDeviceDesc structs.
-  inline void GetSupportedAudioDevices(std::vector<AudioDeviceDesc>& devices) {
-    std::vector<std::string> descriptions;
-    SplitString(descriptions, hidden::AdrGetSupportedAudioDevices(), ';');
-
-    devices.resize(descriptions.size());
-    for (unsigned i = 0; i < descriptions.size(); ++i) {
-      std::vector<std::string> d;
-      SplitString(d, descriptions[i].c_str(), ':');
-      devices[i].name        = d[0];
-      devices[i].description = d[1];
-    }
-  }
-
-
-  /**
-   * Get the size of a sample in a specific sample format.
-   * This is commonly used to determine how many bytes a chunk of
-   * PCM data will take.
-   *
-   * @return  Number of bytes a single sample in the specified format
-   *          takes.
-   */
-  inline int GetSampleSize(SampleFormat format) {
-    return hidden::AdrGetSampleSize(format);
-  }
-
-  /**
-   * Open a new audio device. If name or parameters are not specified,
-   * defaults are used. Each platform has its own set of audio devices.
-   * Every platform supports the "null" audio device.
-   *
-   * @param  name  name of audio device that should be used
-   * @param  parameters  comma delimited list of audio-device parameters;
-   *                     for example, "buffer=100,rate=44100"
-   *
-   * @return  new audio device object if OpenDevice succeeds, and 0 in case
-   *          of failure
-   */
-  inline AudioDevice* OpenDevice(
-    const char* name = 0,
-    const char* parameters = 0)
-  {
-    return hidden::AdrOpenDevice(name, parameters);
-  }
-
-  /**
-   * Create a streaming sample source from a sound file.  This factory simply
-   * opens a default file from the system filesystem and calls
-   * OpenSampleSource(File*).
-   *
-   * @see OpenSampleSource(File*)
-   */
-  inline SampleSource* OpenSampleSource(
-    const char* filename,
-    FileFormat file_format = FF_AUTODETECT)
-  {
-    return hidden::AdrOpenSampleSource(filename, file_format);
-  }
-
-  /**
-   * Opens a sample source from the specified file object.  If the sound file
-   * cannot be opened, this factory function returns 0.
-   *
-   * @note  Some sound files support seeking, while some don't.
-   *
-   * @param file         File object from which to open the decoder
-   * @param file_format  Format of the file to load.  If FF_AUTODETECT,
-   *                     Audiere will try opening the file in each format.
-   *
-   * @return  new SampleSource if OpenSampleSource succeeds, 0 otherwise
-   */
-  inline SampleSource* OpenSampleSource(
-    const FilePtr& file,
-    FileFormat file_format = FF_AUTODETECT)
-  {
-    return hidden::AdrOpenSampleSourceFromFile(file.get(), file_format);
-  }
-
-  /**
-   * Create a tone sample source with the specified frequency.
-   *
-   * @param  frequency  Frequency of the tone in Hz.
-   *
-   * @return  tone sample source
-   */
-  inline SampleSource* CreateTone(double frequency) {
-    return hidden::AdrCreateTone(frequency);
-  }
-
-  /**
-   * Create a square wave with the specified frequency.
-   *
-   * @param  frequency  Frequency of the wave in Hz.
-   *
-   * @return  wave sample source
-   */
-  inline SampleSource* CreateSquareWave(double frequency) {
-    return hidden::AdrCreateSquareWave(frequency);
-  }
-
-  /**
-   * Create a white noise sample source.  White noise is just random
-   * data.
-   *
-   * @return  white noise sample source
-   */
-  inline SampleSource* CreateWhiteNoise() {
-    return hidden::AdrCreateWhiteNoise();
-  }
-
-  /**
-   * Create a pink noise sample source.  Pink noise is noise with equal
-   * power distribution among octaves (logarithmic), not frequencies.
-   *
-   * @return  pink noise sample source
-   */
-  inline SampleSource* CreatePinkNoise() {
-    return hidden::AdrCreatePinkNoise();
-  }
-
-  /**
-   * Create a LoopPointSource from a SampleSource.  The SampleSource must
-   * be seekable.  If it isn't, or the source isn't valid, this function
-   * returns 0.
-   */
-  inline LoopPointSource* CreateLoopPointSource(
-    const SampleSourcePtr& source)
-  {
-    return hidden::AdrCreateLoopPointSource(source.get());
-  }
-
-  /**
-   * Creates a LoopPointSource from a source loaded from a file.
-   */
-  inline LoopPointSource* CreateLoopPointSource(
-    const char* filename,
-    FileFormat file_format = FF_AUTODETECT)
-  {
-    return CreateLoopPointSource(OpenSampleSource(filename, file_format));
-  }
-
-  /**
-   * Creates a LoopPointSource from a source loaded from a file.
-   */
-  inline LoopPointSource* CreateLoopPointSource(
-    const FilePtr& file,
-    FileFormat file_format = FF_AUTODETECT)
-  {
-    return CreateLoopPointSource(OpenSampleSource(file, file_format));
-  }
-
-  /**
-   * Try to open a sound buffer using the specified AudioDevice and
-   * sample source.  If the specified sample source is seekable, it
-   * loads it into memory and uses AudioDevice::openBuffer to create
-   * the output stream.  If the stream is not seekable, it uses
-   * AudioDevice::openStream to create the output stream.  This means
-   * that certain file types must always be streamed, and therefore,
-   * OpenSound will hold on to the file object.  If you must guarantee
-   * that the file on disk is no longer referenced, you must create
-   * your own memory file implementation and load your data into that
-   * before calling OpenSound.
-   *
-   * @param device  AudioDevice in which to open the output stream.
-   *
-   * @param source  SampleSource used to generate samples for the sound
-   *                object.  OpenSound takes ownership of source, even
-   *                if it returns 0.  (In that case, OpenSound immediately
-   *                deletes the SampleSource.)
-   *
-   * @param streaming  If false or unspecified, OpenSound attempts to
-   *                   open the entire sound into memory.  Otherwise, it
-   *                   streams the sound from the file.
-   *
-   * @return  new output stream if successful, 0 otherwise
-   */
-  inline OutputStream* OpenSound(
-    const AudioDevicePtr& device,
-    const SampleSourcePtr& source,
-    bool streaming = false)
-  {
-    return hidden::AdrOpenSound(device.get(), source.get(), streaming);
-  }
-
-  /**
-   * Calls OpenSound(AudioDevice*, SampleSource*) with a sample source
-   * created via OpenSampleSource(const char*).
-   */
-  inline OutputStream* OpenSound(
-    const AudioDevicePtr& device,
-    const char* filename,
-    bool streaming = false,
-    FileFormat file_format = FF_AUTODETECT)
-  {
-    SampleSource* source = OpenSampleSource(filename, file_format);
-    return OpenSound(device, source, streaming);
-  }
-
-  /**
-   * Calls OpenSound(AudioDevice*, SampleSource*) with a sample source
-   * created via OpenSampleSource(File* file).
-   */
-  inline OutputStream* OpenSound(
-    const AudioDevicePtr& device,
-    const FilePtr& file,
-    bool streaming = false,
-    FileFormat file_format = FF_AUTODETECT)
-  {
-    SampleSource* source = OpenSampleSource(file, file_format);
-    return OpenSound(device, source, streaming);
-  }
-
-  /**
-   * Create a SampleBuffer object using the specified samples and formats.
-   *
-   * @param samples  Pointer to a buffer of samples used to initialize the
-   *                 new object.  If this is 0, the sample buffer contains
-   *                 just silence.
-   *
-   * @param frame_count  Size of the sample buffer in frames.
-   *
-   * @param channel_count  Number of channels in each frame.
-   *
-   * @param sample_rate  Sample rate in Hz.
-   *
-   * @param sample_format  Format of each sample.  @see SampleFormat.
-   *
-   * @return  new SampleBuffer object
-   */
-  inline SampleBuffer* CreateSampleBuffer(
-    void* samples,
-    int frame_count,
-    int channel_count,
-    int sample_rate,
-    SampleFormat sample_format)
-  {
-    return hidden::AdrCreateSampleBuffer(
-      samples, frame_count,
-      channel_count, sample_rate, sample_format);
-  }
-
-  /**
-   * Create a SampleBuffer object from a SampleSource.
-   *
-   * @param source  Seekable sample source used to create the buffer.
-   *                If the source is not seekable, then the function
-   *                fails.
-   *
-   * @return  new sample buffer if success, 0 otherwise
-   */
-  inline SampleBuffer* CreateSampleBuffer(const SampleSourcePtr& source) {
-    return hidden::AdrCreateSampleBufferFromSource(source.get());
-  }
-
-  /**
-   * Open a SoundEffect object from the given sample source and sound
-   * effect type.  @see SoundEffect
-   *
-   * @param device  AudioDevice on which the sound is played.
-   *
-   * @param source  The sample source used to feed the sound effect
-   *                with data.
-   *
-   * @param type  The type of the sound effect.  If type is MULTIPLE,
-   *              the source must be seekable.
-   *
-   * @return  new SoundEffect object if successful, 0 otherwise
-   */
-  inline SoundEffect* OpenSoundEffect(
-    const AudioDevicePtr& device,
-    const SampleSourcePtr& source,
-    SoundEffectType type)
-  {
-    return hidden::AdrOpenSoundEffect(device.get(), source.get(), type);
-  }
-
-  /**
-   * Calls OpenSoundEffect(AudioDevice*, SampleSource*,
-   * SoundEffectType) with a sample source created from the filename.
-   */
-  inline SoundEffect* OpenSoundEffect(
-    const AudioDevicePtr& device,
-    const char* filename,
-    SoundEffectType type,
-    FileFormat file_format = FF_AUTODETECT)
-  {
-    SampleSource* source = OpenSampleSource(filename, file_format);
-    return OpenSoundEffect(device, source, type);
-  }
-
-  /**
-   * Calls OpenSoundEffect(AudioDevice*, SampleSource*,
-   * SoundEffectType) with a sample source created from the file.
-   */
-  inline SoundEffect* OpenSoundEffect(
-    const AudioDevicePtr& device,
-    const FilePtr& file,
-    SoundEffectType type,
-    FileFormat file_format = FF_AUTODETECT)
-  {
-    SampleSource* source = OpenSampleSource(file, file_format);
-    return OpenSoundEffect(device, source, type);
-  }
-
-  /**
-   * Opens a default file implementation from the local filesystem.
-   *
-   * @param filename   The name of the file on the local filesystem.
-   * @param writeable  Whether the writing to the file is allowed.
-   */
-  inline File* OpenFile(const char* filename, bool writeable) {
-    return hidden::AdrOpenFile(filename, writeable);
-  }
-
-  /**
-   * Creates a File implementation that reads from a buffer in memory.
-   * It stores a copy of the buffer that is passed in.
-   *
-   * The File object does <i>not</i> take ownership of the memory buffer.
-   * When the file is destroyed, it will not free the memory.
-   *
-   * @param buffer  Pointer to the beginning of the data.
-   * @param size    Size of the buffer in bytes.
-   *
-   * @return  0 if size is non-zero and buffer is null. Otherwise,
-   *          returns a valid File object.
-   */
-  inline File* CreateMemoryFile(const void* buffer, int size) {
-    return hidden::AdrCreateMemoryFile(buffer, size);
-  }
-
-  /**
-   * Generates a list of available CD device names.
-   *
-   * @param devices A vector of strings to be filled.
-   */
-  inline void EnumerateCDDevices(std::vector<std::string>& devices) {
-    const char* d = hidden::AdrEnumerateCDDevices();
-    while (d && *d) {
-      devices.push_back(d);
-      d += strlen(d) + 1;
-    }
-  }
-
-  /**
-   * Opens the specified CD playback device.
-   * 
-   * @param device  The filesystem device to be played.
-   *                e.g. Linux: "/dev/cdrom", Windows: "D:"
-   *
-   * @return  0 if opening device failed, valid CDDrive object otherwise.
-   */
-  inline CDDevice* OpenCDDevice(const char* device) {
-    return hidden::AdrOpenCDDevice(device);
-  }
-
-  /**
-   * Opens the specified MIDI synthesizer device.
-   *
-   * @param device  The name of the device.  Unused for now.
-   *
-   * @return  0 if opening device failed, valid MIDIDevice object otherwise.
-   */
-  inline MIDIDevice* OpenMIDIDevice(const char* device) {
-    return hidden::AdrOpenMIDIDevice(device);
-  }
-
-}
-
-
-#endif
