00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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