Lines 1-10
Link Here
|
1 |
/* $Id: DrvHostOSSAudio.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */ |
1 |
/* $Id: DrvHostOSSAudio.cpp 73370 2018-07-26 13:52:12Z vboxsync $ */ |
2 |
/** @file |
2 |
/** @file |
3 |
* OSS (Open Sound System) host audio backend. |
3 |
* OSS (Open Sound System) host audio backend. |
4 |
*/ |
4 |
*/ |
5 |
|
5 |
|
6 |
/* |
6 |
/* |
7 |
* Copyright (C) 2014-2019 Oracle Corporation |
7 |
* Copyright (C) 2014-2017 Oracle Corporation |
8 |
* |
8 |
* |
9 |
* This file is part of VirtualBox Open Source Edition (OSE), as |
9 |
* This file is part of VirtualBox Open Source Edition (OSE), as |
10 |
* available from http://www.virtualbox.org. This file is free software; |
10 |
* available from http://www.virtualbox.org. This file is free software; |
Lines 157-183
Link Here
|
157 |
switch (fmt) |
157 |
switch (fmt) |
158 |
{ |
158 |
{ |
159 |
case AFMT_S8: |
159 |
case AFMT_S8: |
160 |
pProps->cBytes = 1; |
160 |
pProps->cBits = 8; |
161 |
pProps->fSigned = true; |
161 |
pProps->fSigned = true; |
162 |
break; |
162 |
break; |
163 |
|
163 |
|
164 |
case AFMT_U8: |
164 |
case AFMT_U8: |
165 |
pProps->cBytes = 1; |
165 |
pProps->cBits = 8; |
166 |
pProps->fSigned = false; |
166 |
pProps->fSigned = false; |
167 |
break; |
167 |
break; |
168 |
|
168 |
|
169 |
case AFMT_S16_LE: |
169 |
case AFMT_S16_LE: |
170 |
pProps->cBytes = 2; |
170 |
pProps->cBits = 16; |
171 |
pProps->fSigned = true; |
171 |
pProps->fSigned = true; |
172 |
break; |
172 |
break; |
173 |
|
173 |
|
174 |
case AFMT_U16_LE: |
174 |
case AFMT_U16_LE: |
175 |
pProps->cBytes = 2; |
175 |
pProps->cBits = 16; |
176 |
pProps->fSigned = false; |
176 |
pProps->fSigned = false; |
177 |
break; |
177 |
break; |
178 |
|
178 |
|
179 |
case AFMT_S16_BE: |
179 |
case AFMT_S16_BE: |
180 |
pProps->cBytes = 2; |
180 |
pProps->cBits = 16; |
181 |
pProps->fSigned = true; |
181 |
pProps->fSigned = true; |
182 |
#ifdef RT_LITTLE_ENDIAN |
182 |
#ifdef RT_LITTLE_ENDIAN |
183 |
pProps->fSwapEndian = true; |
183 |
pProps->fSwapEndian = true; |
Lines 185-191
Link Here
|
185 |
break; |
185 |
break; |
186 |
|
186 |
|
187 |
case AFMT_U16_BE: |
187 |
case AFMT_U16_BE: |
188 |
pProps->cBytes = 2; |
188 |
pProps->cBits = 16; |
189 |
pProps->fSigned = false; |
189 |
pProps->fSigned = false; |
190 |
#ifdef RT_LITTLE_ENDIAN |
190 |
#ifdef RT_LITTLE_ENDIAN |
191 |
pProps->fSwapEndian = true; |
191 |
pProps->fSwapEndian = true; |
Lines 224-230
Link Here
|
224 |
|
224 |
|
225 |
static int ossStreamOpen(const char *pszDev, int fOpen, POSSAUDIOSTREAMCFG pOSSReq, POSSAUDIOSTREAMCFG pOSSAcq, int *phFile) |
225 |
static int ossStreamOpen(const char *pszDev, int fOpen, POSSAUDIOSTREAMCFG pOSSReq, POSSAUDIOSTREAMCFG pOSSAcq, int *phFile) |
226 |
{ |
226 |
{ |
227 |
int rc = VERR_AUDIO_STREAM_COULD_NOT_CREATE; |
227 |
int rc = VINF_SUCCESS; |
228 |
|
228 |
|
229 |
int hFile = -1; |
229 |
int hFile = -1; |
230 |
do |
230 |
do |
Lines 233-254
Link Here
|
233 |
if (hFile == -1) |
233 |
if (hFile == -1) |
234 |
{ |
234 |
{ |
235 |
LogRel(("OSS: Failed to open %s: %s (%d)\n", pszDev, strerror(errno), errno)); |
235 |
LogRel(("OSS: Failed to open %s: %s (%d)\n", pszDev, strerror(errno), errno)); |
|
|
236 |
rc = RTErrConvertFromErrno(errno); |
236 |
break; |
237 |
break; |
237 |
} |
238 |
} |
238 |
|
239 |
|
239 |
int iFormat; |
240 |
int iFormat; |
240 |
switch (pOSSReq->Props.cBytes) |
241 |
switch (pOSSReq->Props.cBits) |
241 |
{ |
242 |
{ |
242 |
case 1: |
243 |
case 8: |
243 |
iFormat = pOSSReq->Props.fSigned ? AFMT_S8 : AFMT_U8; |
244 |
iFormat = pOSSReq->Props.fSigned ? AFMT_S8 : AFMT_U8; |
244 |
break; |
245 |
break; |
245 |
|
246 |
|
246 |
case 2: |
247 |
case 16: |
247 |
iFormat = pOSSReq->Props.fSigned ? AFMT_S16_LE : AFMT_U16_LE; |
248 |
iFormat = pOSSReq->Props.fSigned ? AFMT_S16_LE : AFMT_U16_LE; |
248 |
break; |
249 |
break; |
249 |
|
250 |
|
250 |
default: |
251 |
default: |
251 |
rc = VERR_AUDIO_STREAM_COULD_NOT_CREATE; |
252 |
rc = VERR_NOT_SUPPORTED; |
252 |
break; |
253 |
break; |
253 |
} |
254 |
} |
254 |
|
255 |
|
Lines 258-263
Link Here
|
258 |
if (ioctl(hFile, SNDCTL_DSP_SAMPLESIZE, &iFormat)) |
259 |
if (ioctl(hFile, SNDCTL_DSP_SAMPLESIZE, &iFormat)) |
259 |
{ |
260 |
{ |
260 |
LogRel(("OSS: Failed to set audio format to %ld: %s (%d)\n", iFormat, strerror(errno), errno)); |
261 |
LogRel(("OSS: Failed to set audio format to %ld: %s (%d)\n", iFormat, strerror(errno), errno)); |
|
|
262 |
rc = RTErrConvertFromErrno(errno); |
261 |
break; |
263 |
break; |
262 |
} |
264 |
} |
263 |
|
265 |
|
Lines 266-271
Link Here
|
266 |
{ |
268 |
{ |
267 |
LogRel(("OSS: Failed to set number of audio channels (%RU8): %s (%d)\n", |
269 |
LogRel(("OSS: Failed to set number of audio channels (%RU8): %s (%d)\n", |
268 |
pOSSReq->Props.cChannels, strerror(errno), errno)); |
270 |
pOSSReq->Props.cChannels, strerror(errno), errno)); |
|
|
271 |
rc = RTErrConvertFromErrno(errno); |
269 |
break; |
272 |
break; |
270 |
} |
273 |
} |
271 |
|
274 |
|
Lines 273-278
Link Here
|
273 |
if (ioctl(hFile, SNDCTL_DSP_SPEED, &freq)) |
276 |
if (ioctl(hFile, SNDCTL_DSP_SPEED, &freq)) |
274 |
{ |
277 |
{ |
275 |
LogRel(("OSS: Failed to set audio frequency (%dHZ): %s (%d)\n", pOSSReq->Props.uHz, strerror(errno), errno)); |
278 |
LogRel(("OSS: Failed to set audio frequency (%dHZ): %s (%d)\n", pOSSReq->Props.uHz, strerror(errno), errno)); |
|
|
279 |
rc = RTErrConvertFromErrno(errno); |
276 |
break; |
280 |
break; |
277 |
} |
281 |
} |
278 |
|
282 |
|
Lines 281-286
Link Here
|
281 |
if (ioctl(hFile, SNDCTL_DSP_NONBLOCK)) |
285 |
if (ioctl(hFile, SNDCTL_DSP_NONBLOCK)) |
282 |
{ |
286 |
{ |
283 |
LogRel(("OSS: Failed to set non-blocking mode: %s (%d)\n", strerror(errno), errno)); |
287 |
LogRel(("OSS: Failed to set non-blocking mode: %s (%d)\n", strerror(errno), errno)); |
|
|
288 |
rc = RTErrConvertFromErrno(errno); |
284 |
break; |
289 |
break; |
285 |
} |
290 |
} |
286 |
#endif |
291 |
#endif |
Lines 296-301
Link Here
|
296 |
{ |
301 |
{ |
297 |
LogRel(("OSS: Failed to set %RU16 fragments to %RU32 bytes each: %s (%d)\n", |
302 |
LogRel(("OSS: Failed to set %RU16 fragments to %RU32 bytes each: %s (%d)\n", |
298 |
pOSSReq->cFragments, pOSSReq->cbFragmentSize, strerror(errno), errno)); |
303 |
pOSSReq->cFragments, pOSSReq->cbFragmentSize, strerror(errno), errno)); |
|
|
304 |
rc = RTErrConvertFromErrno(errno); |
299 |
break; |
305 |
break; |
300 |
} |
306 |
} |
301 |
|
307 |
|
Lines 303-308
Link Here
|
303 |
if (ioctl(hFile, fIn ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE, &abinfo)) |
309 |
if (ioctl(hFile, fIn ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE, &abinfo)) |
304 |
{ |
310 |
{ |
305 |
LogRel(("OSS: Failed to retrieve %s buffer length: %s (%d)\n", fIn ? "input" : "output", strerror(errno), errno)); |
311 |
LogRel(("OSS: Failed to retrieve %s buffer length: %s (%d)\n", fIn ? "input" : "output", strerror(errno), errno)); |
|
|
312 |
rc = RTErrConvertFromErrno(errno); |
306 |
break; |
313 |
break; |
307 |
} |
314 |
} |
308 |
|
315 |
|
Lines 311-317
Link Here
|
311 |
{ |
318 |
{ |
312 |
pOSSAcq->Props.cChannels = cChannels; |
319 |
pOSSAcq->Props.cChannels = cChannels; |
313 |
pOSSAcq->Props.uHz = freq; |
320 |
pOSSAcq->Props.uHz = freq; |
314 |
pOSSAcq->Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pOSSAcq->Props.cBytes, pOSSAcq->Props.cChannels); |
321 |
pOSSAcq->Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pOSSAcq->Props.cBits, pOSSAcq->Props.cChannels); |
315 |
|
322 |
|
316 |
pOSSAcq->cFragments = abinfo.fragstotal; |
323 |
pOSSAcq->cFragments = abinfo.fragstotal; |
317 |
pOSSAcq->cbFragmentSize = abinfo.fragsize; |
324 |
pOSSAcq->cbFragmentSize = abinfo.fragsize; |
Lines 552-559
Link Here
|
552 |
{ |
559 |
{ |
553 |
RT_NOREF(pInterface); |
560 |
RT_NOREF(pInterface); |
554 |
|
561 |
|
555 |
RTStrPrintf2(pBackendCfg->szName, sizeof(pBackendCfg->szName), "OSS audio driver"); |
|
|
556 |
|
557 |
pBackendCfg->cbStreamIn = sizeof(OSSAUDIOSTREAM); |
562 |
pBackendCfg->cbStreamIn = sizeof(OSSAUDIOSTREAM); |
558 |
pBackendCfg->cbStreamOut = sizeof(OSSAUDIOSTREAM); |
563 |
pBackendCfg->cbStreamOut = sizeof(OSSAUDIOSTREAM); |
559 |
|
564 |
|
Lines 631-637
Link Here
|
631 |
ossReq.cbFragmentSize = s_OSSConf.fragsize; |
636 |
ossReq.cbFragmentSize = s_OSSConf.fragsize; |
632 |
|
637 |
|
633 |
OSSAUDIOSTREAMCFG ossAcq; |
638 |
OSSAUDIOSTREAMCFG ossAcq; |
634 |
RT_ZERO(ossAcq); |
|
|
635 |
|
639 |
|
636 |
rc = ossStreamOpen(s_OSSConf.devpath_in, O_RDONLY | O_NONBLOCK, &ossReq, &ossAcq, &hFile); |
640 |
rc = ossStreamOpen(s_OSSConf.devpath_in, O_RDONLY | O_NONBLOCK, &ossReq, &ossAcq, &hFile); |
637 |
if (RT_SUCCESS(rc)) |
641 |
if (RT_SUCCESS(rc)) |
Lines 681-691
Link Here
|
681 |
|
685 |
|
682 |
do |
686 |
do |
683 |
{ |
687 |
{ |
684 |
OSSAUDIOSTREAMCFG reqStream; |
688 |
OSSAUDIOSTREAMCFG reqStream, obtStream; |
685 |
RT_ZERO(reqStream); |
|
|
686 |
|
687 |
OSSAUDIOSTREAMCFG obtStream; |
688 |
RT_ZERO(obtStream); |
689 |
|
689 |
|
690 |
memcpy(&reqStream.Props, &pCfgReq->Props, sizeof(PDMAUDIOPCMPROPS)); |
690 |
memcpy(&reqStream.Props, &pCfgReq->Props, sizeof(PDMAUDIOPCMPROPS)); |
691 |
|
691 |
|