1566 lines
43 KiB
C++
1566 lines
43 KiB
C++
/**
|
|
* @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
|