~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Open Mash Cross Reference
mash/audio/audio-bsd.cc

Component: ~ [ mash ] ~ [ apps ] ~ [ gsm ] ~ [ lib ] ~ [ otcl ] ~ [ srm ] ~ [ tcl8.3 ] ~ [ tclcl ] ~ [ tk8.3 ] ~ [ tutorials ] ~

  1 /*
  2  * audio-bsd.cc --
  3  *
  4  *      FIXME: This file needs a description here.
  5  *
  6  * Copyright (c) 1991-2002 The Regents of the University of California.
  7  * All rights reserved.
  8  *
  9  * Redistribution and use in source and binary forms, with or without
 10  * modification, are permitted provided that the following conditions are met:
 11  *
 12  * A. Redistributions of source code must retain the above copyright notice,
 13  *    this list of conditions and the following disclaimer.
 14  * B. Redistributions in binary form must reproduce the above copyright notice,
 15  *    this list of conditions and the following disclaimer in the documentation
 16  *    and/or other materials provided with the distribution.
 17  * C. Neither the names of the copyright holders nor the names of its
 18  *    contributors may be used to endorse or promote products derived from this
 19  *    software without specific prior written permission.
 20  *
 21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
 22  * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 23  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
 25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 31  * POSSIBILITY OF SUCH DAMAGE.
 32  */
 33 
 34 static const char rcsid[] =
 35     "@(#) $Header: /usr/mash/src/repository/mash/mash-1/audio/audio-bsd.cc,v 1.5 2002/02/03 03:10:46 lim Exp $";
 36 
 37 #include "audio-sun.h"
 38 #include <unistd.h>
 39 #include <fcntl.h>
 40 #include <errno.h>
 41 #ifdef sun
 42 #include <sbusdev/bsd_audioio.h>
 43 #else
 44 #include <machine/audioio.h>
 45 #endif
 46 
 47 class BSDAudio : public SUNAudio {
 48     public:
 49         inline BSDAudio(const char* device) : SUNAudio(device) {}
 50         virtual int FrameReady();
 51         virtual u_char* Read();
 52         virtual void Obtain();
 53         virtual int RDrops();
 54         virtual int AdjustTime(u_int);
 55         virtual void Flush();
 56         virtual int CanFilter() const { return 1; }
 57         virtual int outputs() const;
 58     protected:
 59         virtual int setinfo(struct audio_info*);
 60         virtual int getinfo(struct audio_info*);
 61 };
 62 
 63 static class BSDAudioMatcher : public Matcher {
 64 public:
 65         BSDAudioMatcher() : Matcher("audio") {}
 66         TclObject* match(const char* id) {
 67                 if (strcasecmp(id, "bsd") == 0) {
 68                         Tcl& tcl = Tcl::instance();
 69                         const char* device = tcl.attr("audioFileName");
 70                         int i = -1;;
 71                         if (strcmp(device, "/dev/audio") == 0 &&
 72                             (i = open("/dev/audioctl", O_RDONLY, 0)) < 0)
 73                                 return (new BSDAudio(device));
 74                         (void)close(i);
 75                 }
 76                 return (0);
 77         }
 78 } bsdaudio_matcher;
 79 
 80 void BSDAudio::Obtain()
 81 {
 82         if (HaveAudio())
 83                 abort();
 84 
 85         fd_ = open(device_, O_RDWR|O_NDELAY);
 86         if (fd_ >= 0) {
 87                 int on = 1;
 88                 ioctl(fd_, FIONBIO, (char*)&on);
 89                 audio_info_t* i = (audio_info_t*)state;
 90                 AUDIO_INITINFO((audio_info_t*)state);
 91                 i->blocksize = blksize;
 92                 i->record.gain = rgain;
 93                 i->play.gain = pgain;
 94                 i->play.port = oport? AUDIO_HEADPHONE :
 95                 AUDIO_SPEAKER;
 96                 setinfo(i);
 97                 /* flush input to get rid of any data fragments */
 98                 Flush();
 99                 Audio::Obtain();
100         }
101 }
102 
103 u_char* BSDAudio::Read()
104 {
105         u_char* cp = buf;
106         register int len = blksize;
107         int cc = read(fd_, (char *)cp, len);
108         if ((len -= cc) != 0) {
109                 do {
110                         if (cc < 0) {
111                                 switch (errno) {
112                                 case EINVAL:
113                                         /* probably wrapped file pos. */
114                                         lseek(fd_, 0, SEEK_SET);
115                                         break;
116 
117                                 case EPERM:
118                                         /* probably lost audio */
119                                         break;
120 
121                                 default:
122                                         perror("audio read");
123                                         break;
124                                 }
125                                 break;
126                         }
127                         cp += cc;
128                         cc = read(fd_, (char *)cp, len);
129                         len -= cc;
130                 } while (len > 0);
131         }
132         return (buf);
133 }
134 
135 int BSDAudio::FrameReady()
136 {
137         return (1);
138 }
139 
140 int BSDAudio::RDrops()
141 {
142         int n;
143         if (fd_ < 0 || ioctl(fd_, AUDIO_RERROR, (char *)&n) < 0)
144                 n = -1;
145         return (n);
146 }
147 
148 int BSDAudio::getinfo(audio_info_t* info)
149 {
150         int sts;
151         if (fd_ < 0)
152                 sts = 0;
153         else
154                 sts = ioctl(fd_, AUDIO_GETINFO, (char*)info);
155         return (sts);
156 }
157 
158 int BSDAudio::setinfo(audio_info_t* info)
159 {
160         int sts;
161         if (fd_ < 0)
162                 sts = 0;
163         else
164                 sts = ioctl(fd_, AUDIO_SETINFO, (char*)info);
165         return (sts);
166 }
167 
168 /*
169  * The time difference betwee now and when the audio last write
170  * actually happens (i.e., when the last write actually starts
171  * being output by the kernel).
172  */
173 int BSDAudio::AdjustTime(u_int now)
174 {
175         u_long stamp;
176         if (ioctl(fd_, AUDIO_WSEEK, (char *)&stamp) < 0) {
177                 perror("AUDIO_WSEEK");
178                 return (0);
179         }
180         return (stamp - now);
181 }
182 
183 void BSDAudio::Flush()
184 {
185         if (ioctl(fd_, AUDIO_FLUSH, (char *)0) < 0) {
186                 perror("AUDIO_FLUSH");
187                 exit(1);
188         }
189 }
190 
191 int BSDAudio::outputs() const
192 {
193         return (2);
194 }
195 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.