Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

audiodrv_linux.cpp

Go to the documentation of this file.
00001 //
00002 // $Date: 2001/06/03 21:08:22 $
00003 //
00004 // --------------------------------------------------------------------------
00005 // ``Open Sound System (OSS)'' / Linux specific audio interface.
00006 // --------------------------------------------------------------------------
00007 
00008 #include "audiodrv.h"
00009 
00010 audioDriver::audioDriver()
00011 {
00012         // Reset everything.
00013         errorString = "None";
00014         frequency = 0;
00015         channels = 0;
00016         encoding = 0;
00017         precision = 0;
00018         audioHd = (-1);
00019 }
00020 
00021 bool audioDriver::IsThere()
00022 {
00023         // Check device availability and write permissions.
00024         return (access(AUDIODEVICE,W_OK)==0);
00025 }
00026 
00027 bool audioDriver::Open(udword inFreq, int inPrecision, int inChannels,
00028                                            int inFragments, int inFragBase)
00029 {
00030         if ((audioHd=open(AUDIODEVICE,O_WRONLY,0)) == (-1))
00031     {
00032                 errorString = "AUDIO: Could not open audio device.";
00033                 return false;
00034     }
00035         
00036         // Transfer input parameters to this object.
00037         // May later be replaced with driver defaults.
00038         frequency = inFreq;
00039         precision = inPrecision;
00040         channels = inChannels;
00041         fragments = inFragments;
00042         fragSizeBase = inFragBase;
00043 
00044         // Set sample precision and type of encoding.
00045         int dsp_sampleSize;
00046         if (precision == SIDEMU_16BIT)
00047                 dsp_sampleSize = 16;
00048         else  // if (precision == SIDEMU_8BIT)
00049                 dsp_sampleSize = 8;
00050         if (ioctl(audioHd,SNDCTL_DSP_SAMPLESIZE,&dsp_sampleSize) == (-1))
00051     {
00052                 errorString = "AUDIO: Could not set sample size.";
00053                 return false;
00054     }
00055         // Verify and accept the sample precision the driver accepted.
00056         if (dsp_sampleSize == 16)
00057     {
00058                 precision = SIDEMU_16BIT;
00059                 encoding = SIDEMU_SIGNED_PCM;
00060     }
00061         else if (dsp_sampleSize == 8)
00062     {
00063                 precision = SIDEMU_8BIT;
00064                 encoding = SIDEMU_UNSIGNED_PCM;
00065     }
00066         else
00067         {
00068                 errorString = "AUDIO: Could not set sample size.";
00069                 return false;
00070         }
00071 
00072         // Set mono/stereo.
00073         int dsp_stereo;
00074         if (channels == SIDEMU_STEREO)
00075                 dsp_stereo = 1;
00076         else  // if (channels == SIDEMU_MONO)
00077                 dsp_stereo = 0;
00078         if (ioctl(audioHd,SNDCTL_DSP_STEREO,&dsp_stereo) == (-1))
00079     {
00080                 errorString = "AUDIO: Could not set mono/stereo.";
00081                 return false;
00082     }
00083         // Verify and accept the number of channels the driver accepted.
00084         if (dsp_stereo == 1)
00085                 channels = SIDEMU_STEREO;
00086         else if (dsp_stereo == 0)
00087                 channels = SIDEMU_MONO;
00088         else
00089     {
00090                 errorString = "AUDIO: Could not set mono/stereo.";
00091                 return false;
00092     }
00093         
00094         // Set frequency.
00095         int dsp_speed = frequency;
00096         if (ioctl(audioHd,SNDCTL_DSP_SPEED,&dsp_speed) == (-1))
00097     {
00098                 errorString = "AUDIO: Could not set frequency.";
00099                 return false;
00100     }
00101         // Accept the frequency the driver accepted.
00102         frequency = dsp_speed;
00103         
00104         // N fragments of size (2 ^ S) bytes
00105         //               NNNNSSSS
00106         // e.g. frag = 0x0004000e;
00107         // fragments should be out of [2,3,..,255]
00108         // fragSizeBase should be out of [7,8,...,17]
00109         // depending on the kernel audio driver buffer size
00110         int frag = (fragments << 16) | fragSizeBase;
00111         ioctl(audioHd,SNDCTL_DSP_SETFRAGMENT,&frag);
00112         ioctl(audioHd,SNDCTL_DSP_GETBLKSIZE,&blockSize);
00113         
00114         audio_buf_info myAudInfo;
00115         if (ioctl(audioHd,SNDCTL_DSP_GETOSPACE,&myAudInfo) == (-1))
00116         {
00117                 errorString = "AUDIO: Could not get audio_buf_info.";
00118                 return false;
00119         }
00120         fragments = myAudInfo.fragstotal;
00121         //cout << "fragsize = " << (int)myAudInfo.fragsize << endl;
00122         //cout << "bytes = " << (int)myAudInfo.bytes << endl;
00123         
00124     return true;
00125 }
00126 
00127 // Close an opened audio device, free any allocated buffers and
00128 // reset any variables that reflect the current state.
00129 void audioDriver::Close()
00130 {
00131         if (audioHd != (-1))
00132     {
00133                 close(audioHd);
00134                 audioHd = (-1);
00135     }
00136 }
00137 
00138 void audioDriver::Play(ubyte* pBuffer, int bufferSize)
00139 {
00140         if (audioHd != (-1))
00141         {
00142                 write(audioHd,pBuffer,bufferSize);
00143         }
00144 }

Generated on Tue Feb 8 04:13:57 2005 for Esidplay by doxygen 1.3.3