Uncommented beaudio code
[pwlib.git] / src / ptlib / unix / sunaudio.cxx
blobc19fd5d4d6468e52d0814b50dc48ae93a4921c5a
1 /*
2 * sunaudio.cxx
4 * Sound driver implementation.
6 * Portable Windows Library
8 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
18 * under the License.
20 * The Original Code is Portable Windows Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25 * All Rights Reserved.
27 * Contributor(s): ______________________________________.
29 * $Log$
30 * Revision 1.8 2002/03/27 06:53:47 robertj
31 * iSome more implementation, thanks Raimo Ruokonen
33 * Revision 1.7 2002/02/09 00:52:01 robertj
34 * Slight adjustment to API and documentation for volume functions.
36 * Revision 1.6 2002/02/07 20:57:21 dereks
37 * add SetVolume and GetVolume methods to PSoundChannel
39 * Revision 1.5 2001/10/18 01:15:18 robertj
40 * Fixed compile error.
42 * Revision 1.4 1999/09/03 02:01:34 robertj
43 * Added missing functions so will at least link
45 * Revision 1.3 1999/06/28 09:28:02 robertj
46 * Portability issues, especially n BeOS (thanks Yuri!)
48 * Revision 1.2 1999/03/02 04:34:10 robertj
49 * Fixed header comments
53 #pragma implementation "sound.h"
55 #include <ptlib.h>
57 #include <sys/audioio.h>
60 PSound::PSound(unsigned channels,
61 unsigned samplesPerSecond,
62 unsigned bitsPerSample,
63 PINDEX bufferSize,
64 const BYTE * buffer)
66 encoding = 0;
67 numChannels = channels;
68 sampleRate = samplesPerSecond;
69 sampleSize = bitsPerSample;
70 SetSize(bufferSize);
71 if (buffer != NULL)
72 memcpy(GetPointer(), buffer, bufferSize);
76 PSound::PSound(const PFilePath & filename)
78 encoding = 0;
79 numChannels = 1;
80 sampleRate = 8000;
81 sampleSize = 16;
82 Load(filename);
86 PSound & PSound::operator=(const PBYTEArray & data)
88 PBYTEArray::operator=(data);
89 return *this;
93 void PSound::SetFormat(unsigned channels,
94 unsigned samplesPerSecond,
95 unsigned bitsPerSample)
97 encoding = 0;
98 numChannels = channels;
99 sampleRate = samplesPerSecond;
100 sampleSize = bitsPerSample;
101 formatInfo.SetSize(0);
105 BOOL PSound::Load(const PFilePath & /*filename*/)
107 return FALSE;
111 BOOL PSound::Save(const PFilePath & /*filename*/)
113 return FALSE;
117 ///////////////////////////////////////////////////////////////////////////////
119 PSoundChannel::PSoundChannel()
121 Construct();
125 PSoundChannel::PSoundChannel(const PString & device,
126 Directions dir,
127 unsigned numChannels,
128 unsigned sampleRate,
129 unsigned bitsPerSample)
131 Construct();
132 Open(device, dir, numChannels, sampleRate, bitsPerSample);
136 void PSoundChannel::Construct()
141 PSoundChannel::~PSoundChannel()
143 Close();
147 PStringArray PSoundChannel::GetDeviceNames(Directions /*dir*/)
149 PStringArray array;
151 array[0] = "/dev/audio";
152 array[1] = "/dev/dsp";
154 return array;
158 PString PSoundChannel::GetDefaultDevice(Directions /*dir*/)
160 return "/dev/audio";
164 BOOL PSoundChannel::Open(const PString & device,
165 Directions dir,
166 unsigned numChannels,
167 unsigned sampleRate,
168 unsigned bitsPerSample)
170 Close();
171 if (!ConvertOSError(os_handle = ::open(device, (dir == Player ? O_WRONLY : O_RDONLY) ,0)))
172 return FALSE;
174 direction = dir;
175 if (dir == Player) {
176 int flag = fcntl(os_handle, F_GETFL, 0)| O_NONBLOCK| O_NDELAY;
178 if (fcntl(os_handle, F_SETFL, flag) < 0) {
179 PTRACE(1,"F_SETFL fcntl ERROR");
180 return FALSE;
184 return SetFormat(numChannels, sampleRate, bitsPerSample);
188 BOOL PSoundChannel::Close()
190 return PChannel::Close();
194 BOOL PSoundChannel::SetFormat(unsigned numChannels,
195 unsigned sampleRate,
196 unsigned bitsPerSample){
197 PAssert(numChannels >= 1 && numChannels <= 2, PInvalidParameter);
198 PAssert(bitsPerSample == 8 || bitsPerSample == 16, PInvalidParameter);
200 audio_info_t audio_info;
201 int err;
203 AUDIO_INITINFO(&audio_info); // Change only the values needed below
204 if (direction == Player){
205 mSampleRate = audio_info.play.sample_rate = sampleRate; // Output settings
206 mNumChannels = audio_info.play.channels = numChannels;
207 mBitsPerSample = audio_info.play.precision = bitsPerSample;
208 audio_info.play.encoding = AUDIO_ENCODING_LINEAR;
209 audio_info.play.port &= AUDIO_HEADPHONE;
210 audio_info.play.port &= (~AUDIO_SPEAKER); // No speaker output
211 } else { // Recorder
212 mSampleRate = audio_info.record.sample_rate = sampleRate; // Input settings
213 mNumChannels = audio_info.record.channels = numChannels;
214 mBitsPerSample = audio_info.record.precision = bitsPerSample;
215 audio_info.record.encoding = AUDIO_ENCODING_LINEAR;
216 audio_info.record.port &= AUDIO_MICROPHONE;
217 audio_info.record.port &= (~AUDIO_LINE_IN);
219 err=::ioctl(os_handle,AUDIO_SETINFO,&audio_info); // The actual setting of the parameters
220 if(err==EINVAL || err==EBUSY)
221 return FALSE;
223 err = ::ioctl(os_handle, AUDIO_GETINFO, &audio_info); // Let's recheck the configuration...
224 if (direction == Player){
225 actualSampleRate = audio_info.play.sample_rate;
226 // PAssert(actualSampleRate==sampleRate && audio_info.play.precision==bitsPerSample && audio_info.play.encoding==AUDIO_ENCODING_LINEAR, PInvalidParameter);
227 }else{
228 actualSampleRate = audio_info.record.sample_rate;
229 // PAssert(actualSampleRate==sampleRate && audio_info.record.precision==bitsPerSample && audio_info.record.encoding==AUDIO_ENCODING_LINEAR, PInvalidParameter);
231 return TRUE;
235 BOOL PSoundChannel::SetBuffers(PINDEX size, PINDEX count)
237 PAssert(size > 0 && count > 0 && count < 65536, PInvalidParameter);
239 audio_info_t audio_info;
240 int err;
242 AUDIO_INITINFO(&audio_info); // Change only the values needed below
243 if (direction == Player)
244 audio_info.play.buffer_size = count*size; // man audio says there is no way to set the buffer count... This doesn't affect the actual buffer size on Solaris ?
245 else
246 audio_info.record.buffer_size = count*size; // Recorder
248 err = ioctl(os_handle,AUDIO_SETINFO,&audio_info); // The actual setting of the parameters
249 if (err == EINVAL || err == EBUSY)
250 return FALSE;
252 return TRUE;
256 BOOL PSoundChannel::GetBuffers(PINDEX & size, PINDEX & count)
258 return TRUE;
262 BOOL PSoundChannel::Write(const void * buf, PINDEX len)
264 return PChannel::Write(buf, len);
266 /* Implementation based on OSS PSoundChannel::Write. This works, but no difference on sound when compared to the basic implementation...
267 while (!ConvertOSError(err=::write(os_handle, (void *)buf, len)))
268 if (GetErrorCode() != Interrupted){
269 return FALSE;
271 return TRUE;
276 BOOL PSoundChannel::PlaySound(const PSound & sound, BOOL wait)
278 Abort();
280 if (!Write((const BYTE *)sound, sound.GetSize()))
281 return FALSE;
283 if (wait)
284 return WaitForPlayCompletion();
286 return TRUE;
290 BOOL PSoundChannel::PlayFile(const PFilePath & filename, BOOL wait)
295 BOOL PSoundChannel::HasPlayCompleted()
300 BOOL PSoundChannel::WaitForPlayCompletion()
305 BOOL PSoundChannel::Read(void * buffer, PINDEX length)
307 return PChannel::Read(buffer, length);
311 BOOL PSoundChannel::RecordSound(PSound & sound)
316 BOOL PSoundChannel::RecordFile(const PFilePath & filename)
321 BOOL PSoundChannel::StartRecording()
326 BOOL PSoundChannel::IsRecordBufferFull()
331 BOOL PSoundChannel::AreAllRecordBuffersFull()
336 BOOL PSoundChannel::WaitForRecordBufferFull()
338 if (os_handle < 0)
339 return SetErrorValues(NotOpen, EBADF);
341 return PXSetIOBlock(PXReadBlock, readTimeout);
345 BOOL PSoundChannel::WaitForAllRecordBuffersFull()
347 return FALSE;
351 BOOL PSoundChannel::Abort()
355 BOOL PSoundChannel::SetVolume(unsigned newVolume)
357 cerr << __FILE__ << "PSoundChannel :: SetVolume called in error. Please fix"<<endl;
358 return FALSE;
361 BOOL PSoundChannel::GetVolume(unsigned & volume)
363 cerr << __FILE__ << "PSoundChannel :: GetVolume called in error. Please fix"<<endl;
364 return FALSE;
368 // End of file