2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
23 #include <sys/ioctl.h>
24 #include <sys/types.h>
37 #include <sys/audioio.h>
40 static const ALCchar solaris_device
[] = "Solaris Default";
52 static ALuint
SolarisProc(ALvoid
*ptr
)
54 ALCdevice
*pDevice
= (ALCdevice
*)ptr
;
55 solaris_data
*data
= (solaris_data
*)pDevice
->ExtraData
;
62 frameSize
= aluFrameSizeFromFormat(pDevice
->Format
);
64 while(!data
->killNow
&& pDevice
->Connected
)
66 ALint len
= data
->data_size
;
67 ALubyte
*WritePtr
= data
->mix_data
;
69 aluMixData(pDevice
, WritePtr
, len
/frameSize
);
70 while(len
> 0 && !data
->killNow
)
72 wrote
= write(data
->fd
, WritePtr
, len
);
75 if(errno
!= EAGAIN
&& errno
!= EWOULDBLOCK
&& errno
!= EINTR
)
77 AL_PRINT("write failed: %s\n", strerror(errno
));
78 aluHandleDisconnect(pDevice
);
95 static ALCboolean
solaris_open_playback(ALCdevice
*device
, const ALCchar
*deviceName
)
100 strncpy(driver
, GetConfigValue("solaris", "device", "/dev/audio"), sizeof(driver
)-1);
101 driver
[sizeof(driver
)-1] = 0;
104 deviceName
= solaris_device
;
105 else if(strcmp(deviceName
, solaris_device
) != 0)
108 data
= (solaris_data
*)calloc(1, sizeof(solaris_data
));
111 data
->fd
= open(driver
, O_WRONLY
);
115 AL_PRINT("Could not open %s: %s\n", driver
, strerror(errno
));
119 device
->szDeviceName
= strdup(deviceName
);
120 device
->ExtraData
= data
;
124 static void solaris_close_playback(ALCdevice
*device
)
126 solaris_data
*data
= (solaris_data
*)device
->ExtraData
;
130 device
->ExtraData
= NULL
;
133 static ALCboolean
solaris_reset_playback(ALCdevice
*device
)
135 solaris_data
*data
= (solaris_data
*)device
->ExtraData
;
140 AUDIO_INITINFO(&info
);
142 switch(aluBytesFromFormat(device
->Format
))
145 info
.play
.precision
= 8;
146 info
.play
.encoding
= AUDIO_ENCODING_LINEAR8
;
151 case 1: device
->Format
= AL_FORMAT_MONO16
; break;
152 case 2: device
->Format
= AL_FORMAT_STEREO16
; break;
153 case 4: device
->Format
= AL_FORMAT_QUAD16
; break;
154 case 6: device
->Format
= AL_FORMAT_51CHN16
; break;
155 case 7: device
->Format
= AL_FORMAT_61CHN16
; break;
156 case 8: device
->Format
= AL_FORMAT_71CHN16
; break;
160 info
.play
.precision
= 16;
161 info
.play
.encoding
= AUDIO_ENCODING_LINEAR
;
164 AL_PRINT("Unknown format: 0x%x\n", device
->Format
);
168 numChannels
= aluChannelsFromFormat(device
->Format
);
169 info
.play
.sample_rate
= device
->Frequency
;
170 info
.play
.channels
= numChannels
;
172 frameSize
= numChannels
* aluBytesFromFormat(device
->Format
);
173 info
.play
.buffer_size
= device
->UpdateSize
*device
->NumUpdates
* frameSize
;
175 if(ioctl(data
->fd
, AUDIO_SETINFO
, &info
) < 0)
177 AL_PRINT("ioctl failed: %s\n", strerror(errno
));
181 if(aluChannelsFromFormat(device
->Format
) != info
.play
.channels
)
183 AL_PRINT("Could not set %d channels, got %d instead\n", aluChannelsFromFormat(device
->Format
), info
.play
.channels
);
187 if(!((info
.play
.precision
== 8 && aluBytesFromFormat(device
->Format
) == 1) ||
188 (info
.play
.precision
== 16 && aluBytesFromFormat(device
->Format
) == 2)))
190 AL_PRINT("Could not set %d-bit output, got %d\n", aluBytesFromFormat(device
->Format
)*8, info
.play
.precision
);
194 device
->Frequency
= info
.play
.sample_rate
;
195 device
->UpdateSize
= (info
.play
.buffer_size
/device
->NumUpdates
) + 1;
197 data
->data_size
= device
->UpdateSize
* frameSize
;
198 data
->mix_data
= calloc(1, data
->data_size
);
200 SetDefaultChannelOrder(device
);
202 data
->thread
= StartThread(SolarisProc
, device
);
203 if(data
->thread
== NULL
)
205 free(data
->mix_data
);
206 data
->mix_data
= NULL
;
213 static void solaris_stop_playback(ALCdevice
*device
)
215 solaris_data
*data
= (solaris_data
*)device
->ExtraData
;
221 StopThread(data
->thread
);
226 free(data
->mix_data
);
227 data
->mix_data
= NULL
;
231 static ALCboolean
solaris_open_capture(ALCdevice
*device
, const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei SampleSize
)
241 static void solaris_close_capture(ALCdevice
*device
)
246 static void solaris_start_capture(ALCdevice
*pDevice
)
251 static void solaris_stop_capture(ALCdevice
*pDevice
)
256 static void solaris_capture_samples(ALCdevice
*pDevice
, ALCvoid
*pBuffer
, ALCuint lSamples
)
263 static ALCuint
solaris_available_samples(ALCdevice
*pDevice
)
270 BackendFuncs solaris_funcs
= {
271 solaris_open_playback
,
272 solaris_close_playback
,
273 solaris_reset_playback
,
274 solaris_stop_playback
,
275 solaris_open_capture
,
276 solaris_close_capture
,
277 solaris_start_capture
,
278 solaris_stop_capture
,
279 solaris_capture_samples
,
280 solaris_available_samples
283 void alc_solaris_init(BackendFuncs
*func_list
)
285 *func_list
= solaris_funcs
;
288 void alc_solaris_deinit(void)
292 void alc_solaris_probe(int type
)
296 if(stat(GetConfigValue("solaris", "device", "/dev/audio"), &buf
) != 0)
300 if(type
== DEVICE_PROBE
)
301 AppendDeviceList(solaris_device
);
302 else if(type
== ALL_DEVICE_PROBE
)
303 AppendAllDeviceList(solaris_device
);