00001
00002 #ifdef _MSC_VER
00003 #pragma warning(disable : 4786)
00004 #endif
00005
00006
00007 #include <string>
00008 #include "audiere.h"
00009 #include "debug.h"
00010 #include "device_null.h"
00011 #include "internal.h"
00012 #include "threads.h"
00013
00014 #ifdef WIN32
00015
00016 #include <windows.h>
00017 #include <mmsystem.h>
00018 #include "device_ds.h"
00019 #include "device_mm.h"
00020
00021 #endif
00022
00023 #ifdef HAVE_OSS
00024 #include "device_oss.h"
00025 #endif
00026
00027 #ifdef HAVE_OPENAL
00028 #include "device_oal.h"
00029 #endif
00030
00031 #ifdef HAVE_AL
00032 #include "device_al.h"
00033 #endif
00034
00035
00036 namespace audiere {
00037
00038 #define NEED_SEMICOLON do ; while (false)
00039
00040 #define TRY_GROUP(group_name) { \
00041 AudioDevice* device = DoOpenDevice(group_name, parameters); \
00042 if (device) { \
00043 return device; \
00044 } \
00045 } NEED_SEMICOLON
00046
00047 #define TRY_DEVICE(DeviceType) { \
00048 DeviceType* device = DeviceType::create(parameters); \
00049 if (device) { \
00050 return device; \
00051 } \
00052 } NEED_SEMICOLON
00053
00054
00055 AudioDevice* DoOpenDevice(
00056 const std::string& name,
00057 const ParameterList& parameters)
00058 {
00059 ADR_GUARD("DoOpenDevice");
00060
00061 #ifdef WIN32
00062
00063 if (name == "" || name == "autodetect") {
00064 TRY_GROUP("directsound");
00065 TRY_GROUP("winmm");
00066 TRY_GROUP("openal");
00067 return 0;
00068 }
00069
00070 if (name == "directsound") {
00071 TRY_DEVICE(DSAudioDevice);
00072 return 0;
00073 }
00074
00075 if (name == "winmm") {
00076 TRY_DEVICE(MMAudioDevice);
00077 return 0;
00078 }
00079
00080 #ifdef HAVE_OPENAL
00081 if (name == "openal") {
00082 TRY_DEVICE(ALAudioDevice);
00083 return 0;
00084 }
00085 #endif
00086
00087 if (name == "null") {
00088 TRY_DEVICE(NullAudioDevice);
00089 return 0;
00090 }
00091
00092 #else // not Win32 - assume autoconf UNIX
00093
00094 if (name == "" || name == "autodetect") {
00095
00096 TRY_GROUP("al");
00097 TRY_GROUP("oss");
00098 TRY_GROUP("openal");
00099 return 0;
00100 }
00101
00102 #ifdef HAVE_OSS
00103 if (name == "oss") {
00104 TRY_DEVICE(OSSAudioDevice);
00105 return 0;
00106 }
00107 #endif
00108
00109 #ifdef HAVE_OPENAL
00110 if (name == "openal") {
00111 TRY_DEVICE(OALAudioDevice);
00112 return 0;
00113 }
00114 #endif
00115
00116 #ifdef HAVE_AL
00117 if (name == "al") {
00118 TRY_DEVICE(ALAudioDevice);
00119 return 0;
00120 }
00121 #endif
00122
00123 if (name == "null") {
00124 TRY_DEVICE(NullAudioDevice);
00125 return 0;
00126 }
00127
00128 #endif
00129
00130
00131 return 0;
00132 }
00133
00134
00135 class ThreadedDevice : public RefImplementation<AudioDevice> {
00136 public:
00137 ThreadedDevice(AudioDevice* device) {
00138 ADR_GUARD("ThreadedDevice::ThreadedDevice");
00139 if (device) {
00140 ADR_LOG("Device is valid");
00141 } else {
00142 ADR_LOG("Device is not valid");
00143 }
00144
00145 m_device = device;
00146 m_thread_exists = false;
00147 m_thread_should_die = false;
00148
00150 AI_CreateThread(threadRoutine, this, 2);
00151 }
00152
00153 ~ThreadedDevice() {
00154 m_thread_should_die = true;
00155 while (m_thread_exists) {
00156 AI_Sleep(50);
00157 }
00158 }
00159
00160
00161 void ADR_CALL update() {
00162 }
00163
00164 OutputStream* ADR_CALL openStream(SampleSource* source) {
00165 return m_device->openStream(source);
00166 }
00167
00168 OutputStream* ADR_CALL openBuffer(
00169 void* samples, int frame_count,
00170 int channel_count, int sample_rate, SampleFormat sample_format)
00171 {
00172 return m_device->openBuffer(
00173 samples, frame_count,
00174 channel_count, sample_rate, sample_format);
00175 }
00176
00177 private:
00178 void run() {
00179 m_thread_exists = true;
00180 while (!m_thread_should_die) {
00181 m_device->update();
00182 }
00183 m_thread_exists = false;
00184 }
00185
00186 static void threadRoutine(void* arg) {
00187 ADR_GUARD("ThreadedDevice::threadRoutine");
00188 if (arg) {
00189 ADR_LOG("arg is valid");
00190 } else {
00191 ADR_LOG("arg is not valid");
00192 }
00193
00194 ThreadedDevice* This = (ThreadedDevice*)arg;
00195 This->run();
00196 }
00197
00198 private:
00199 RefPtr<AudioDevice> m_device;
00200 volatile bool m_thread_should_die;
00201 volatile bool m_thread_exists;
00202 };
00203
00204
00205 ADR_EXPORT(AudioDevice*, AdrOpenDevice)(
00206 const char* name,
00207 const char* parameters)
00208 {
00209 ADR_GUARD("AdrOpenDevice");
00210
00211 if (!name) {
00212 name = "";
00213 }
00214 if (!parameters) {
00215 parameters = "";
00216 }
00217
00218
00219 AudioDevice* device = DoOpenDevice(
00220 std::string(name),
00221 ParameterList(parameters));
00222 if (!device) {
00223 ADR_LOG("Could not open device");
00224 return 0;
00225 }
00226
00227 ADR_LOG("creating threaded device");
00228 return new ThreadedDevice(device);
00229 }
00230
00231 }