Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

device.cpp

Go to the documentation of this file.
00001 // *sigh*, looking forward to VS.NET...
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         // in decreasing order of sound API quality
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     // no devices
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     // don't need to update the device...  the thread does it for us
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     // first, we need an unthreaded audio device
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 }

Generated on Sat Oct 12 01:43:01 2002 for audiere by doxygen1.2.17