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
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.