#ifndef MIXER_H #define MIXER_H #ifdef _MSC_VER #pragma warning(disable : 4786) #endif #include #include "audiere.h" #include "device.h" #include "resampler.h" #include "threads.h" #include "types.h" #include "utility.h" namespace audiere { class MixerStream; /// Always produce 16-bit, stereo audio at the specified rate. class MixerDevice : public AbstractDevice, public Mutex { public: MixerDevice(int rate); // update() must be implementated by the specific device to call read() // and write the samples to the output device. OutputStream* ADR_CALL openStream(SampleSource* source); OutputStream* ADR_CALL openBuffer( void* samples, int frame_count, int channel_count, int sample_rate, SampleFormat sample_format); protected: int read(int sample_count, void* samples); private: std::list m_streams; int m_rate; friend class MixerStream; }; class MixerStream : public RefImplementation, public Mutex { public: MixerStream(MixerDevice* device, SampleSource* source, int rate); ~MixerStream(); void ADR_CALL play(); void ADR_CALL stop(); bool ADR_CALL isPlaying(); void ADR_CALL reset(); void ADR_CALL setRepeat(bool repeat); bool ADR_CALL getRepeat(); void ADR_CALL setVolume(float volume); float ADR_CALL getVolume(); void ADR_CALL setPan(float pan); float ADR_CALL getPan(); void ADR_CALL setPitchShift(float shift); float ADR_CALL getPitchShift(); bool ADR_CALL isSeekable(); int ADR_CALL getLength(); void ADR_CALL setPosition(int position); int ADR_CALL getPosition(); private: void read(int frame_count, s16* buffer); private: RefPtr m_device; RefPtr m_source; s16 m_last_l; s16 m_last_r; bool m_is_playing; int m_volume; int m_pan; friend class MixerDevice; }; class AudioBuffer { public: AudioBuffer() : m_buf(0), m_size(0) { } AudioBuffer(char* buf, int size) : m_buf(buf), m_size(size) { } AudioBuffer(const AudioBuffer& o) : m_buf(o.m_buf), m_size(o.m_size) { } char* m_buf; int m_size; }; class AudioQueue { private: AudioQueue(); AudioQueue(const AudioQueue&); public: AudioQueue(int blockSize, int queueLen); ~AudioQueue(); AudioBuffer* get_buffer(bool wait = true); void put_buffer(AudioBuffer* buffer); bool push(AudioBuffer* buffer); AudioBuffer* pop(bool wait = true); void shutdown(); private: CondVar m_cond; Mutex m_mutex; std::list m_queue; CondVar m_buffer_cond; Mutex m_buffer_mutex; std::list m_buffer_list; std::list m_free_list; int m_block_size; int m_max_queue_len; bool m_shutdown; }; /// Always produce 16-bit, stereo audio at the specified rate. class ThreadedMixerDevice : public MixerDevice { public: ThreadedMixerDevice(int rate, int block_size = 4096, int queue_len = 8); ~ThreadedMixerDevice(); public: virtual void ADR_CALL update(); protected: virtual void outputBuffer(const char* buf, int buf_len) = 0; virtual void start(); virtual void shutdown(); private: static void outputThreadRoutine(void* opaque); void output(); AudioQueue* m_queue; bool m_thread_should_die; bool m_thread_exists; }; } #endif