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

Audio.cc

Go to the documentation of this file.
00001 /*
00002 
00003     Class for OSS audio IO operations
00004     Copyright (C) 1998-2002 Jussi Laako
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 */
00021 
00022 
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <unistd.h>
00026 #include <fcntl.h>
00027 #ifdef linux
00028     #include <sys/ioctl.h>
00029 #elif BSDSYS
00030     #include <sys/ioctl.h>
00031 #else
00032     #include <ioctl.h>
00033 #endif
00034 #include <errno.h>
00035 #include <math.h>
00036 #include <sys/types.h>
00037 #include <sys/stat.h>
00038 
00039 //#include "sys/soundcard.h"
00040 #include "Audio.hh"
00041 
00042 
00043 clAudio::clAudio ()
00044 {
00045     iDevH = -1;
00046     iErrorCode = 0;
00047 }
00048 
00049 
00050 clAudio::clAudio (const char *cpDevName, int *ipFormat, int *ipSampleRate,
00051     int *ipChannels, int iType)
00052 {
00053     iDevH = -1;
00054     iErrorCode = 0;
00055     Open(cpDevName, ipFormat, ipSampleRate, ipChannels, iType);
00056 }
00057 
00058 
00059 clAudio::~clAudio ()
00060 {
00061     Close();
00062 }
00063 
00064 
00065 bool clAudio::Open (const char *cpDevName, int *ipFormat, int *ipSampleRate, 
00066     int *ipChannels, int iType)
00067 {
00068     int iOpenFlags;
00069    
00070     iErrorCode = 0;
00071     switch(iType)
00072     {
00073         case AUDIO_READ:
00074             iOpenFlags = O_RDONLY;
00075             break;
00076         case AUDIO_WRITE:
00077             iOpenFlags = O_WRONLY;
00078             break;
00079         case AUDIO_DUPLEX:
00080             iOpenFlags = O_RDWR;
00081             break;
00082         default:
00083             iOpenFlags = O_RDWR;
00084     }
00085     iDevH = open(cpDevName, iOpenFlags);
00086     if (iDevH < 0)
00087     {
00088         iErrorCode = errno;
00089         return false;
00090     }
00091     if (iType == AUDIO_DUPLEX)
00092     {
00093         if (ioctl(iDevH, SNDCTL_DSP_SETDUPLEX, 0) < 0)
00094         {
00095             iErrorCode = errno;
00096             return false;
00097         }
00098     }
00099     if (ioctl(iDevH, SNDCTL_DSP_SETFMT, ipFormat) < 0)
00100     {
00101         iErrorCode = errno;
00102         return false;
00103     }
00104     if (ioctl(iDevH, SNDCTL_DSP_CHANNELS, ipChannels) < 0)
00105     {
00106         iErrorCode = errno;
00107         return false;
00108     }
00109     if (ioctl(iDevH, SNDCTL_DSP_SPEED, ipSampleRate) < 0)
00110     {
00111         iErrorCode = errno;
00112         return false;
00113     }
00114     return true;
00115 }
00116 
00117 
00118 void clAudio::Close ()
00119 {
00120     if (iDevH >= 0) close(iDevH);
00121     iDevH = -1;
00122 }
00123 
00124 
00125 bool clAudio::SetParams (int *ipFormat, int *ipChannels, int *ipSampleRate)
00126 {
00127     iErrorCode = 0;
00128     if (ioctl(iDevH, SNDCTL_DSP_SETFMT, ipFormat) < 0)
00129     {
00130         iErrorCode = errno;
00131         return false;
00132     }
00133     if (ioctl(iDevH, SNDCTL_DSP_CHANNELS, ipChannels) < 0)
00134     {
00135         iErrorCode = errno;
00136         return false;
00137     }
00138     if (ioctl(iDevH, SNDCTL_DSP_SPEED, ipSampleRate) < 0)
00139     {
00140         iErrorCode = errno;
00141         return false;
00142     }
00143     return true;
00144 }
00145 
00146 
00147 bool clAudio::SetFormat (int *ipFormat)
00148 {
00149     iErrorCode = 0;
00150     if (ioctl(iDevH, SNDCTL_DSP_SETFMT, ipFormat) < 0)
00151     {
00152         iErrorCode = errno;
00153         return false;
00154     }
00155     return true;
00156 }
00157 
00158 
00159 
00160 bool clAudio::SetChannels (int *ipChannels)
00161 {
00162     iErrorCode = 0;
00163     if (ioctl(iDevH, SNDCTL_DSP_CHANNELS, ipChannels) < 0)
00164     {
00165         iErrorCode = 0;
00166         return false;
00167     }
00168     return true;
00169 }
00170 
00171 
00172 bool clAudio::SetSampleRate (int *ipSampleRate)
00173 {
00174     iErrorCode = 0;
00175     if (ioctl(iDevH, SNDCTL_DSP_SPEED, ipSampleRate) < 0)
00176     {
00177         iErrorCode = 0;
00178         return false;
00179     }
00180     return true;
00181 }
00182 
00183 
00184 int clAudio::Read (void *vpData, int iBytes)
00185 {
00186     int iStatus;
00187     int iBytesRead = 0;
00188     unsigned char *ucpData = (unsigned char *) vpData;
00189 
00190     iErrorCode = 0;
00191     do
00192     {
00193         iStatus = read(iDevH, &ucpData[iBytesRead], 
00194             (size_t) (iBytes - iBytesRead));
00195         if (iStatus < 0)
00196         {
00197             iErrorCode = errno;
00198             return iStatus;
00199         }
00200         iBytesRead += iStatus;
00201     } while (iBytesRead < iBytes);
00202     return iBytesRead;
00203 }
00204 
00205 
00206 int clAudio::Write (const void *vpData, int iBytes)
00207 {
00208     int iStatus;
00209     int iBytesWritten = 0;
00210     const unsigned char *ucpData = (const unsigned char *) vpData;
00211    
00212     iErrorCode = 0;
00213     do
00214     {
00215         iStatus = write(iDevH, &ucpData[iBytesWritten], 
00216             (size_t) (iBytes - iBytesWritten));
00217         if (iStatus < 0)
00218         {
00219             iErrorCode = errno;
00220             return iStatus;
00221         }
00222         iBytesWritten += iStatus;
00223     } while (iBytesWritten < iBytes);
00224     return iBytesWritten;
00225 }
00226 
00227 
00228 bool clAudio::Sync ()
00229 {
00230     iErrorCode = 0;
00231     if (ioctl(iDevH, SNDCTL_DSP_SYNC, 0) < 0)
00232     {
00233         iErrorCode = errno;
00234         return false;
00235     }
00236     return true;
00237 }
00238 
00239 
00240 bool clAudio::Reset ()
00241 {
00242     iErrorCode = 0;
00243     if (ioctl(iDevH, SNDCTL_DSP_RESET, 0) < 0)
00244     {
00245         iErrorCode = errno;
00246         return false;
00247     }
00248     return true;
00249 }
00250 
00251 
00252 bool clAudio::Post ()
00253 {
00254     iErrorCode = 0;
00255     if (ioctl(iDevH, SNDCTL_DSP_POST, 0) < 0)
00256     {
00257         iErrorCode = errno;
00258         return false;
00259     }
00260     return true;
00261 }
00262 
00263 
00264 int clAudio::GetFragmentSize ()
00265 {
00266     int iFragSize;
00267 
00268     iErrorCode = 0;
00269     if (ioctl(iDevH, SNDCTL_DSP_GETBLKSIZE, &iFragSize) < 0)
00270     {
00271         iErrorCode = errno;
00272         return -1;
00273     }
00274     return iFragSize;
00275 }
00276 
00277 
00278 bool clAudio::SubDivide (int *ipSubDivide)
00279 {
00280     iErrorCode = 0;
00281     if (ioctl(iDevH, SNDCTL_DSP_SUBDIVIDE, ipSubDivide) < 0)
00282     {
00283         iErrorCode = errno;
00284         return false;
00285     }
00286     return true;
00287 }
00288 
00289 
00290 bool clAudio::SetFragment (int iFragSize, int iFragCount)
00291 {
00292     int iFragSize2P;
00293     int iFragments;
00294 
00295     iErrorCode = 0;
00296     iFragSize2P = (int) (log(iFragSize) / log(2.0) + 0.5);
00297     iFragments = ((iFragCount << 16) | (iFragSize2P & 0xffff));
00298     if (ioctl(iDevH, SNDCTL_DSP_SETFRAGMENT, &iFragments) < 0)
00299     {
00300         iErrorCode = errno;
00301         return false;
00302     }
00303     return true;
00304 }
00305 
00306 
00307 int clAudio::GetFormats ()
00308 {
00309     int iFormats;
00310 
00311     iErrorCode = 0;
00312     if (ioctl(iDevH, SNDCTL_DSP_GETFMTS, &iFormats) < 0)
00313     {
00314         iErrorCode = errno;
00315         return 0;
00316     }
00317     return iFormats;
00318 }
00319 
00320 
00321 bool clAudio::GetInBufInfo (audio_buf_info *spInBufInfo)
00322 {
00323     iErrorCode = 0;
00324     if (ioctl(iDevH, SNDCTL_DSP_GETISPACE, spInBufInfo) < 0)
00325     {
00326         iErrorCode = errno;
00327         return false;
00328     }
00329     return true;
00330 }
00331 
00332 
00333 bool clAudio::GetOutBufInfo (audio_buf_info *spOutBufInfo)
00334 {
00335     iErrorCode = 0;
00336     if (ioctl(iDevH, SNDCTL_DSP_GETOSPACE, spOutBufInfo) < 0)
00337     {
00338         iErrorCode = errno;
00339         return false;
00340     }
00341     return true;
00342 }
00343 
00344 
00345 bool clAudio::GetInBufStat (count_info *spInBufStat)
00346 {
00347     iErrorCode = 0;
00348     if (ioctl(iDevH, SNDCTL_DSP_GETIPTR, spInBufStat) < 0)
00349     {
00350         iErrorCode = errno;
00351         return false;
00352     }
00353     return true;
00354 }
00355 
00356 
00357 bool clAudio::GetOutBufStat (count_info *spOutBufStat)
00358 {
00359     iErrorCode = 0;
00360     if (ioctl(iDevH, SNDCTL_DSP_GETOPTR, spOutBufStat) < 0)
00361     {
00362         iErrorCode = errno;
00363         return false;
00364     }
00365     return true;
00366 }
00367 
00368 
00369 int clAudio::GetCaps ()
00370 {
00371     int iCaps;
00372    
00373     iErrorCode = 0;
00374     if (ioctl(iDevH, SNDCTL_DSP_GETCAPS, &iCaps) < 0)
00375     {
00376         iErrorCode = errno;
00377         return 0;
00378     }
00379     return iCaps;
00380 }
00381 
00382 
00383 bool clAudio::SetDuplex ()
00384 {
00385     iErrorCode = 0;
00386     if (ioctl(iDevH, SNDCTL_DSP_SETDUPLEX, 0) < 0)
00387     {
00388         iErrorCode = errno;
00389         return false;
00390     }
00391     return true;
00392 }
00393 
00394 
00395 bool clAudio::SetNonBlock ()
00396 {
00397     iErrorCode = 0;
00398     if (ioctl(iDevH, SNDCTL_DSP_NONBLOCK, 0) < 0)
00399     {
00400         iErrorCode = errno;
00401         return false;
00402     }
00403     return true;
00404 }
00405 
00406 
00407 bool clAudio::SetSynchronous ()
00408 {
00409     iErrorCode = 0;
00410     if (ioctl(iDevH, SNDCTL_DSP_SETSYNCRO, 0) < 0)
00411     {
00412         iErrorCode = errno;
00413         return false;
00414     }
00415     return true;
00416 }
00417 
00418 
00419 int clAudio::GetTrigger ()
00420 {
00421     int iTrigger;
00422 
00423     iErrorCode = 0;
00424     if (ioctl(iDevH, SNDCTL_DSP_GETTRIGGER, &iTrigger) < 0)
00425     {
00426         iErrorCode = errno;
00427         return 0;
00428     }
00429     return iTrigger;
00430 }
00431 
00432 
00433 bool clAudio::SetTrigger (int iTrigger)
00434 {
00435     iErrorCode = 0;
00436     if (ioctl(iDevH, SNDCTL_DSP_SETTRIGGER, &iTrigger) < 0)
00437     {
00438         iErrorCode = errno;
00439         return false;
00440     }
00441     return true;
00442 }
00443 
00444 
00445 bool clAudio::MapInBuffer (buffmem_desc *spBufferInfo)
00446 {
00447     iErrorCode = 0;
00448     if (ioctl(iDevH, SNDCTL_DSP_MAPINBUF, spBufferInfo) < 0)
00449     {
00450         iErrorCode = errno;
00451         return false;
00452     }
00453     return true;
00454 }
00455 
00456 
00457 bool clAudio::MapOutBuffer (buffmem_desc *spBufferInfo)
00458 {
00459     iErrorCode = 0;
00460     if (ioctl(iDevH, SNDCTL_DSP_MAPOUTBUF, spBufferInfo) < 0)
00461     {
00462         iErrorCode = errno;
00463         return false;
00464     }
00465     return true;
00466 }
00467 
00468 
00469 int clAudio::GetOutDelay ()
00470 {
00471     int iDelay;
00472 
00473     iErrorCode = 0;
00474     if (ioctl(iDevH, SNDCTL_DSP_GETODELAY, &iDelay) < 0)
00475     {
00476         iErrorCode = errno;
00477         return -1;
00478     }
00479     return iDelay;
00480 }
00481 
00482 
00483 #ifndef USE_OSSLITE
00484 bool clAudio::GetErrorInfo (audio_errinfo *spErrorInfo)
00485 {
00486     iErrorCode = 0;
00487     if (ioctl(iDevH, SNDCTL_DSP_GETERROR, spErrorInfo) < 0)
00488     {
00489         iErrorCode = errno;
00490         return false;
00491     }
00492     return true;
00493 }
00494 #endif
00495 
00496 
00497 int clAudio::GetVersion ()
00498 {
00499     int iVersion;
00500 
00501     iErrorCode = 0;
00502     if (ioctl(iDevH, OSS_GETVERSION, &iVersion) < 0)
00503     {
00504         iErrorCode = errno;
00505         return 0;
00506     }
00507     return iVersion;
00508 }
00509 
00510 
00511 void clAudio::DeIntStereo (const signed short *sspSource, 
00512     signed short *sspLeft, signed short *sspRight, unsigned int uiSourceSize)
00513 {
00514     unsigned int uiSrcIdx = 0;
00515     unsigned int uiDstIdx = 0;
00516    
00517     do
00518     {
00519         sspLeft[uiDstIdx] = sspSource[uiSrcIdx++];
00520         sspRight[uiDstIdx++] = sspSource[uiSrcIdx++];
00521     } while (uiSrcIdx < uiSourceSize);
00522 }
00523 
00524 
00525 void clAudio::DeIntStereo (const unsigned char *ucpSource,
00526     unsigned char *ucpLeft, unsigned char *ucpRight, unsigned int uiSourceSize)
00527 {
00528     unsigned int uiSrcIdx = 0;
00529     unsigned int uiDstIdx = 0;
00530    
00531     do {
00532         ucpLeft[uiDstIdx] = ucpSource[uiSrcIdx++];
00533         ucpRight[uiDstIdx++] = ucpSource[uiSrcIdx++];
00534     } while (uiSrcIdx < uiSourceSize);
00535 }
00536 
00537 
00538 void clAudio::IntStereo(signed short *sspDest, 
00539     const signed short *sspLeft, const signed short *sspRight, 
00540     unsigned int uiSourceSize)
00541 {
00542     unsigned int uiSrcIdx = 0;
00543     unsigned int uiDstIdx = 0;
00544    
00545     do {
00546         sspDest[uiDstIdx++] = sspLeft[uiSrcIdx];
00547         sspDest[uiDstIdx++] = sspRight[uiSrcIdx++];
00548     } while (uiSrcIdx < uiSourceSize);
00549 }
00550 
00551 
00552 void clAudio::IntStereo(unsigned char *ucpDest,
00553     const unsigned char *ucpLeft, const unsigned char *ucpRight,
00554     unsigned int uiSourceSize)
00555 {
00556     unsigned int uiSrcIdx = 0;
00557     unsigned int uiDstIdx = 0;
00558    
00559     do {
00560         ucpDest[uiDstIdx++] = ucpLeft[uiSrcIdx];
00561         ucpDest[uiDstIdx++] = ucpRight[uiSrcIdx++];
00562     } while (uiSrcIdx < uiSourceSize);
00563 }
00564 

Generated on Sun Oct 26 19:11:18 2003 for HASAS by doxygen 1.3.3