SoundIF-solaris.cc
上传用户:weiliju62
上传日期:2007-01-06
资源大小:619k
文件大小:4k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /*  cdrdao - write audio CD-Rs in disc-at-once mode
  2.  *
  3.  *  Copyright (C) 1998, 1999  Andreas Mueller <mueller@daneb.ping.de>
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19. /*
  20.  * $Log: SoundIF-solaris.cc,v $
  21.  * Revision 1.1  1999/05/24 18:07:37  mueller
  22.  * Initial revision
  23.  *
  24.  */
  25. /*
  26.  * Sound interface for Solaris. Thanks to Tobias Oetiker <oetiker@ee.ethz.ch>.
  27.  */
  28. #include <sys/audioio.h>
  29. #include <stdio.h>
  30. #include <assert.h>
  31. #include <string.h>
  32. #include <errno.h>
  33. #include <unistd.h>
  34. #include <fcntl.h>
  35. #include <sys/ioctl.h>
  36. #include <sys/types.h>
  37. #include "SoundIF.h"
  38. #include "Sample.h"
  39. #include "util.h"
  40. class SoundIFImpl {
  41. public:
  42.   SoundIFImpl() { dspFd_ = -1; }
  43.   int setupDevice();
  44.   int openDevice();
  45.   void closeDevice();
  46.   int dspFd_; // sound device
  47. };
  48. SoundIF::SoundIF()
  49. {
  50.   impl_ = new SoundIFImpl;
  51. }
  52. SoundIF::~SoundIF()
  53. {
  54.   delete impl_;
  55.   impl_ = NULL;
  56. }
  57. // Initializes sound interface.
  58. // return: 0: OK
  59. //         1: sounde device not found
  60. //         2: cannot setup sound device
  61. int SoundIF::init()
  62. {
  63.   if (impl_->openDevice() != 0)
  64.     return 1;
  65.   if (impl_->setupDevice() != 0) {
  66.     impl_->closeDevice();
  67.     return 2;
  68.   }
  69.   impl_->closeDevice();
  70.   return 0;
  71. }
  72. // Acquires sound device for playing.
  73. // return 0: OK
  74. //        1: error occured
  75. int SoundIF::start()
  76. {
  77.   if (impl_->dspFd_ >= 0)
  78.     return 0; // already opened
  79.   if (impl_->openDevice() != 0)
  80.     return 1;
  81.   if (impl_->setupDevice() != 0) {
  82.     impl_->closeDevice();
  83.     return 1;
  84.   }
  85.   return 0;
  86. }
  87. // Playes given sample buffer.
  88. // return: 0: OK
  89. //         1: error occured
  90. int SoundIF::play(Sample *sbuf, long nofSamples)
  91. {
  92.   if (impl_->dspFd_ < 0)
  93.     return 1;
  94.   long ret;
  95.   long len = nofSamples * sizeof(Sample);
  96.   long nwritten = 0;
  97.   char *buf = (char *)sbuf;
  98.   while (len > 0) {
  99.     ret = write(impl_->dspFd_, buf + nwritten, len);
  100.     if (ret <= 0)
  101.       return 1;
  102.     nwritten += ret;
  103.     len -= ret;
  104.   }
  105.   return 0;
  106. }
  107. unsigned long SoundIF::getDelay()
  108. {
  109.   return 0;
  110. }
  111. // Finishs playing, sound device is released.
  112. void SoundIF::end()
  113. {
  114.   impl_->closeDevice();
  115. }
  116. int SoundIFImpl::openDevice()
  117. {
  118.   if (dspFd_ >= 0)
  119.     return 0; // already open
  120.   if ((dspFd_ = open("/dev/audio", O_WRONLY | O_NONBLOCK)) < 0) {
  121.     message(-1, "Cannot open "/dev/audio": %s", strerror(errno));
  122.     return 1;
  123.   }
  124.   /* Clear the non-blocking flag */
  125.   (void) fcntl(dspFd_, F_SETFL,
  126.        (fcntl(dspFd_, F_GETFL, 0) & ~(O_NDELAY | O_NONBLOCK)));
  127.   return 0;
  128. }
  129.     
  130. void SoundIFImpl::closeDevice()
  131. {
  132.   if (dspFd_ >= 0) {
  133.     close(dspFd_);
  134.     dspFd_ = -1;
  135.   }
  136. }
  137. int SoundIFImpl::setupDevice()
  138. {
  139.   struct audio_info auinf;
  140.   if (dspFd_ < 0)
  141.     return 1;
  142.   
  143.   if (ioctl(dspFd_, AUDIO_GETINFO, &auinf) < 0) {
  144.     message(-1, "Cannot get state of audio interface: %s", strerror(errno));
  145.     return 1;
  146.   }
  147.   auinf.play.sample_rate=44100;
  148.   auinf.play.channels=2;
  149.   auinf.play.precision=16;
  150.   auinf.play.encoding=AUDIO_ENCODING_LINEAR;
  151.   if (ioctl(dspFd_, AUDIO_SETINFO, &auinf) < 0) {
  152.     message(-1, "Cannot setup audio interface: %s", strerror(errno));
  153.     return 1;
  154.   }
  155.   return 0;
  156. }