• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/audio/src/OALFramework/aldlist.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2006, Creative Labs Inc.
00003  * All rights reserved.
00004  * 
00005  * Redistribution and use in source and binary forms, with or without modification, are permitted provided
00006  * that the following conditions are met:
00007  * 
00008  *     * Redistributions of source code must retain the above copyright notice, this list of conditions and
00009  *           the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
00011  *           and the following disclaimer in the documentation and/or other materials provided with the distribution.
00012  *     * Neither the name of Creative Labs Inc. nor the names of its contributors may be used to endorse or
00013  *           promote products derived from this software without specific prior written permission.
00014  * 
00015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00016  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00017  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
00018  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00019  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00020  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00021  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00022  * POSSIBILITY OF SUCH DAMAGE.
00023  */
00024 
00025 #include "../h/OpenAL.h"
00026 /*#include "aldlist.h"
00027 #include <windows.h>
00028 #include "alc.h"*/
00029 
00030 
00031 /* 
00032  * Init call
00033  */
00034 ALDeviceList::ALDeviceList()
00035 {
00036         ALDEVICEINFO    ALDeviceInfo;
00037         char *devices;
00038         int index;
00039         const char *defaultDeviceName;
00040         const char *actualDeviceName;
00041 
00042         // DeviceInfo vector stores, for each enumerated device, it's device name, selection status, spec version #, and extension support
00043         vDeviceInfo.empty();
00044         vDeviceInfo.reserve(10);
00045 
00046         defaultDeviceIndex = 0;
00047 
00048         // grab function pointers for 1.0-API functions, and if successful proceed to enumerate all devices
00049         if (LoadOAL10Library(NULL, &ALFunction) == TRUE) {
00050                 if (ALFunction.alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT")) {
00051                         devices = (char *)ALFunction.alcGetString(NULL, ALC_DEVICE_SPECIFIER);
00052                         defaultDeviceName = (char *)ALFunction.alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
00053                         index = 0;
00054                         // go through device list (each device terminated with a single NULL, list terminated with double NULL)
00055                         while (*devices != NULL) {
00056                                 if (strcmp(defaultDeviceName, devices) == 0) {
00057                                         defaultDeviceIndex = index;
00058                                 }
00059                                 ALCdevice *device = ALFunction.alcOpenDevice(devices);
00060                                 if (device) {
00061                                         ALCcontext *context = ALFunction.alcCreateContext(device, NULL);
00062                                         if (context) {
00063                                                 ALFunction.alcMakeContextCurrent(context);
00064                                                 // if new actual device name isn't already in the list, then add it...
00065                                                 actualDeviceName = ALFunction.alcGetString(device, ALC_DEVICE_SPECIFIER);
00066                                                 bool bNewName = true;
00067                                                 for (int i = 0; i < GetNumDevices(); i++) {
00068                                                         if (strcmp(GetDeviceName(i), actualDeviceName) == 0) {
00069                                                                 bNewName = false;
00070                                                         }
00071                                                 }
00072                                                 if ((bNewName) && (actualDeviceName != NULL) && (strlen(actualDeviceName) > 0)) {
00073                                                         memset(&ALDeviceInfo, 0, sizeof(ALDEVICEINFO));
00074                                                         ALDeviceInfo.bSelected = true;
00075                                                         ALDeviceInfo.strDeviceName = actualDeviceName;
00076                                                         ALFunction.alcGetIntegerv(device, ALC_MAJOR_VERSION, sizeof(int), &ALDeviceInfo.iMajorVersion);
00077                                                         ALFunction.alcGetIntegerv(device, ALC_MINOR_VERSION, sizeof(int), &ALDeviceInfo.iMinorVersion);
00078 
00079                                                         ALDeviceInfo.pvstrExtensions = new vector<string>;
00080 
00081                                                         // Check for ALC Extensions
00082                                                         if (ALFunction.alcIsExtensionPresent(device, "ALC_EXT_CAPTURE") == AL_TRUE)
00083                                                                 ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_CAPTURE");
00084                                                         if (ALFunction.alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_TRUE)
00085                                                                 ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_EFX");
00086 
00087                                                         // Check for AL Extensions
00088                                                         if (ALFunction.alIsExtensionPresent("AL_EXT_OFFSET") == AL_TRUE)
00089                                                                 ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_OFFSET");
00090 
00091                                                         if (ALFunction.alIsExtensionPresent("AL_EXT_LINEAR_DISTANCE") == AL_TRUE)
00092                                                                 ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_LINEAR_DISTANCE");
00093                                                         if (ALFunction.alIsExtensionPresent("AL_EXT_EXPONENT_DISTANCE") == AL_TRUE)
00094                                                                 ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_EXPONENT_DISTANCE");
00095                                                         
00096                                                         if (ALFunction.alIsExtensionPresent("EAX2.0") == AL_TRUE)
00097                                                                 ALDeviceInfo.pvstrExtensions->push_back("EAX2.0");
00098                                                         if (ALFunction.alIsExtensionPresent("EAX3.0") == AL_TRUE)
00099                                                                 ALDeviceInfo.pvstrExtensions->push_back("EAX3.0");
00100                                                         if (ALFunction.alIsExtensionPresent("EAX4.0") == AL_TRUE)
00101                                                                 ALDeviceInfo.pvstrExtensions->push_back("EAX4.0");
00102                                                         if (ALFunction.alIsExtensionPresent("EAX5.0") == AL_TRUE)
00103                                                                 ALDeviceInfo.pvstrExtensions->push_back("EAX5.0");
00104 
00105                                                         if (ALFunction.alIsExtensionPresent("EAX-RAM") == AL_TRUE)
00106                                                                 ALDeviceInfo.pvstrExtensions->push_back("EAX-RAM");
00107 
00108                                                         // Get Source Count
00109                                                         ALDeviceInfo.uiSourceCount = GetMaxNumSources();
00110 
00111                                                         vDeviceInfo.push_back(ALDeviceInfo);
00112                                                 }
00113                                                 ALFunction.alcMakeContextCurrent(NULL);
00114                                                 ALFunction.alcDestroyContext(context);
00115                                         }
00116                                         ALFunction.alcCloseDevice(device);
00117                                 }
00118                                 devices += strlen(devices) + 1;
00119                                 index += 1;
00120                         }
00121                 }
00122         }
00123 
00124         ResetFilters();
00125 }
00126 
00127 /* 
00128  * Exit call
00129  */
00130 ALDeviceList::~ALDeviceList()
00131 {
00132         for (unsigned int i = 0; i < vDeviceInfo.size(); i++) {
00133                 if (vDeviceInfo[i].pvstrExtensions) {
00134                         vDeviceInfo[i].pvstrExtensions->empty();
00135                         delete vDeviceInfo[i].pvstrExtensions;
00136                 }
00137         }
00138 
00139         vDeviceInfo.empty();
00140 
00141         UnloadOAL10Library();
00142 }
00143 
00144 /*
00145  * Returns the number of devices in the complete device list
00146  */
00147 int ALDeviceList::GetNumDevices()
00148 {
00149         return (int)vDeviceInfo.size(); 
00150 }
00151 
00152 /* 
00153  * Returns the device name at an index in the complete device list
00154  */
00155 char * ALDeviceList::GetDeviceName(int index)
00156 {
00157         if (index < GetNumDevices())
00158                 return (char *)vDeviceInfo[index].strDeviceName.c_str();
00159         else
00160                 return NULL;
00161 }
00162 
00163 /*
00164  * Returns the major and minor version numbers for a device at a specified index in the complete list
00165  */
00166 void ALDeviceList::GetDeviceVersion(int index, int *major, int *minor)
00167 {
00168         if (index < GetNumDevices()) {
00169                 if (major)
00170                         *major = vDeviceInfo[index].iMajorVersion;
00171                 if (minor)
00172                         *minor = vDeviceInfo[index].iMinorVersion;
00173         }
00174         return;
00175 }
00176 
00177 /*
00178  * Returns the maximum number of Sources that can be generate on the given device
00179  */
00180 unsigned int ALDeviceList::GetMaxNumSources(int index)
00181 {
00182         if (index < GetNumDevices())
00183                 return vDeviceInfo[index].uiSourceCount;
00184         else
00185                 return 0;
00186 }
00187 
00188 /*
00189  * Checks if the extension is supported on the given device
00190  */
00191 bool ALDeviceList::IsExtensionSupported(int index, char *szExtName)
00192 {
00193         bool bReturn = false;
00194 
00195         if (index < GetNumDevices()) {
00196                 for (unsigned int i = 0; i < vDeviceInfo[index].pvstrExtensions->size(); i++) {
00197                         if (!_stricmp(vDeviceInfo[index].pvstrExtensions->at(i).c_str(), szExtName)) {
00198                                 bReturn = true;
00199                                 break;
00200                         }                               
00201                 }
00202         }
00203 
00204         return bReturn;
00205 }
00206 
00207 /*
00208  * returns the index of the default device in the complete device list
00209  */
00210 int ALDeviceList::GetDefaultDevice()
00211 {
00212         return defaultDeviceIndex;
00213 }
00214 
00215 /* 
00216  * Deselects devices which don't have the specified minimum version
00217  */
00218 void ALDeviceList::FilterDevicesMinVer(int major, int minor)
00219 {
00220         int dMajor, dMinor;
00221         for (unsigned int i = 0; i < vDeviceInfo.size(); i++) {
00222                 GetDeviceVersion(i, &dMajor, &dMinor);
00223                 if ((dMajor < major) || ((dMajor == major) && (dMinor < minor))) {
00224                         vDeviceInfo[i].bSelected = false;
00225                 }
00226         }
00227 }
00228 
00229 /* 
00230  * Deselects devices which don't have the specified maximum version
00231  */
00232 void ALDeviceList::FilterDevicesMaxVer(int major, int minor)
00233 {
00234         int dMajor, dMinor;
00235         for (unsigned int i = 0; i < vDeviceInfo.size(); i++) {
00236                 GetDeviceVersion(i, &dMajor, &dMinor);
00237                 if ((dMajor > major) || ((dMajor == major) && (dMinor > minor))) {
00238                         vDeviceInfo[i].bSelected = false;
00239                 }
00240         }
00241 }
00242 
00243 /*
00244  * Deselects device which don't support the given extension name
00245  */
00246 void ALDeviceList::FilterDevicesExtension(char *szExtName)
00247 {
00248         bool bFound;
00249 
00250         for (unsigned int i = 0; i < vDeviceInfo.size(); i++) {
00251                 bFound = false;
00252                 for (unsigned int j = 0; j < vDeviceInfo[i].pvstrExtensions->size(); j++) {
00253                         if (!_stricmp(vDeviceInfo[i].pvstrExtensions->at(j).c_str(), szExtName)) {
00254                                 bFound = true;
00255                                 break;
00256                         }
00257                 }
00258                 if (!bFound)
00259                         vDeviceInfo[i].bSelected = false;
00260         }
00261 }
00262 
00263 /*
00264  * Resets all filtering, such that all devices are in the list
00265  */
00266 void ALDeviceList::ResetFilters()
00267 {
00268         for (int i = 0; i < GetNumDevices(); i++) {
00269                 vDeviceInfo[i].bSelected = true;
00270         }
00271         filterIndex = 0;
00272 }
00273 
00274 /*
00275  * Gets index of first filtered device
00276  */
00277 int ALDeviceList::GetFirstFilteredDevice()
00278 {
00279         int i;
00280 
00281         for (i = 0; i < GetNumDevices(); i++) {
00282                 if (vDeviceInfo[i].bSelected == true) {
00283                         break;
00284                 }
00285         }
00286         filterIndex = i + 1;
00287         return i;
00288 }
00289 
00290 /*
00291  * Gets index of next filtered device
00292  */
00293 int ALDeviceList::GetNextFilteredDevice()
00294 {
00295         int i;
00296 
00297         for (i = filterIndex; i < GetNumDevices(); i++) {
00298                 if (vDeviceInfo[i].bSelected == true) {
00299                         break;
00300                 }
00301         }
00302         filterIndex = i + 1;
00303         return i;
00304 }
00305 
00306 /*
00307  * Internal function to detemine max number of Sources that can be generated
00308  */
00309 unsigned int ALDeviceList::GetMaxNumSources()
00310 {
00311         ALuint uiSources[256];
00312         unsigned int iSourceCount = 0;
00313 
00314         // Clear AL Error Code
00315         ALFunction.alGetError();
00316 
00317         // Generate up to 256 Sources, checking for any errors
00318         for (iSourceCount = 0; iSourceCount < 256; iSourceCount++)
00319         {
00320                 ALFunction.alGenSources(1, &uiSources[iSourceCount]);
00321                 if (ALFunction.alGetError() != AL_NO_ERROR)
00322                         break;
00323         }
00324 
00325         // Release the Sources
00326         ALFunction.alDeleteSources(iSourceCount, uiSources);
00327         if (ALFunction.alGetError() != AL_NO_ERROR)
00328         {
00329                 for (unsigned int i = 0; i < 256; i++)
00330                 {
00331                         ALFunction.alDeleteSources(1, &uiSources[i]);
00332                 }
00333         }
00334 
00335         return iSourceCount;
00336 }

Generated on Fri Jun 18 2010 17:48:39 for Cannonball by  doxygen 1.7.0