1 /*
2 * Copyright (c) 2002-2007, Jerome Duval (jerome.duval@free.fr)
3 * Copyright (c) 2007, François Revol (revol@free.fr)
4 * Distributed under the terms of the MIT License.
5 */
6
7 #include "OpenSoundDevice.h"
8 #include "OpenSoundDeviceEngine.h"
9 #include "OpenSoundDeviceMixer.h"
10 #include "debug.h"
11 #include "driver_io.h"
12 #include <MediaDefs.h>
13 #include <Debug.h>
14 #include <errno.h>
15 #include <string.h>
16
17 const int gSupportedFormats[] = {
18 AFMT_SUPPORTED_PCM,
19 #ifdef ENABLE_NON_RAW_SUPPORT
20 AFMT_MU_LAW,
21 AFMT_A_LAW,
22 AFMT_IMA_ADPCM,
23 AFMT_MPEG,
24 AFMT_AC3,
25 AFMT_VORBIS,
26 AFMT_SPDIF_RAW,
27 AFMT_S24_PACKED,
28 #endif /*ENABLE_NON_RAW_SUPPORT*/
29 0
30 };
31
32 const char* gSupportedFormatsNames[] = {
33 "raw", //AFMT_SUPPORTED_PCM,
34 "µ-law", //AFMT_MU_LAW,
35 "a-law", //AFMT_A_LAW,
36 "IMA4 ADPCM", //AFMT_IMA_ADPCM,
37 "MPEG layer 2", //AFMT_MPEG,
38 "AC3", //AFMT_AC3,
39 "Vorbis", //AFMT_VORBIS,
40 "Raw S/PDIF", //AFMT_SPDIF_RAW,
41 "Packed 24bit", //AFMT_S24_PACKED,*/
42 0
43 };
44
45
46
47
convert_oss_rate_to_media_rate(int rate)48 float OpenSoundDevice::convert_oss_rate_to_media_rate(int rate)
49 {
50 return (float)rate;
51 }
52
53
convert_media_rate_to_oss_rate(float rate)54 int OpenSoundDevice::convert_media_rate_to_oss_rate(float rate)
55 {
56 return (int)rate;
57 }
58
59
convert_oss_format_to_media_format(int fmt)60 uint32 OpenSoundDevice::convert_oss_format_to_media_format(int fmt)
61 {
62 if (fmt & AFMT_FLOAT)
63 return media_raw_audio_format::B_AUDIO_FLOAT;
64 if (fmt & AFMT_S32_LE ||
65 fmt & AFMT_S24_LE ||
66 fmt & AFMT_S32_BE ||
67 fmt & AFMT_S24_BE)
68 return media_raw_audio_format::B_AUDIO_INT;
69 if (fmt & AFMT_S16_LE ||
70 fmt & AFMT_S16_BE) /* U16 unsupported */
71 return media_raw_audio_format::B_AUDIO_SHORT;
72 if (fmt & AFMT_S8)
73 return media_raw_audio_format::B_AUDIO_CHAR;
74 if (fmt & AFMT_U8)
75 return media_raw_audio_format::B_AUDIO_UCHAR;
76 return 0;
77 }
78
79
convert_oss_format_to_endian(int fmt)80 int OpenSoundDevice::convert_oss_format_to_endian(int fmt)
81 {
82 if (fmt & AFMT_FLOAT)
83 return B_MEDIA_HOST_ENDIAN;
84 if (fmt & AFMT_S32_LE ||
85 fmt & AFMT_S24_LE ||
86 fmt & AFMT_S16_LE ||
87 fmt & AFMT_U16_LE ||
88 fmt & AFMT_S24_PACKED)
89 return B_MEDIA_LITTLE_ENDIAN;
90 if (fmt & AFMT_S32_BE ||
91 fmt & AFMT_S24_BE ||
92 fmt & AFMT_S16_BE ||
93 fmt & AFMT_U16_BE)
94 return B_MEDIA_BIG_ENDIAN;
95 if (fmt & AFMT_S8 ||
96 fmt & AFMT_U8)
97 return B_MEDIA_HOST_ENDIAN;
98 return B_MEDIA_HOST_ENDIAN;
99 }
100
convert_oss_format_to_valid_bits(int fmt)101 int16 OpenSoundDevice::convert_oss_format_to_valid_bits(int fmt)
102 {
103 if (fmt & AFMT_S32_NE)
104 return 32;
105 if (fmt & AFMT_S24_NE)
106 return 24;
107 if (fmt & AFMT_S32_OE)
108 return 32;
109 if (fmt & AFMT_S24_OE)
110 return 24;
111 if (fmt & AFMT_S24_PACKED)
112 return 24;
113 if (fmt & AFMT_SPDIF_RAW)
114 return 32;
115 return 0;
116 }
117
118
convert_media_format_to_oss_format(uint32 fmt)119 int OpenSoundDevice::convert_media_format_to_oss_format(uint32 fmt)
120 {
121 switch (fmt) {
122 case media_raw_audio_format::B_AUDIO_FLOAT:
123 return AFMT_FLOAT;
124 case media_raw_audio_format::B_AUDIO_INT:
125 return AFMT_S32_NE;
126 case media_raw_audio_format::B_AUDIO_SHORT:
127 return AFMT_S16_NE;
128 case media_raw_audio_format::B_AUDIO_CHAR:
129 return AFMT_S8;
130 case media_raw_audio_format::B_AUDIO_UCHAR:
131 return AFMT_U8;
132 default:
133 return 0;
134 }
135 }
136
137
select_oss_rate(const oss_audioinfo * info,int rate)138 int OpenSoundDevice::select_oss_rate(const oss_audioinfo *info, int rate)
139 {
140 if (info->caps & PCM_CAP_FREERATE) {
141 // if not wildcard and matches, return the hint
142 if (rate && rate >= info->min_rate && rate <= info->max_rate)
143 return rate;
144 // else use max available
145 return info->max_rate;
146 }
147 uint32 max_rate = 0;
148 for (uint32 i = 0; i < info->nrates; i++) {
149 if ((int32)info->rates[i] < info->min_rate
150 || (int32)info->rates[i] > info->max_rate)
151 continue;
152 // if the hint matches
153 if (rate && rate == (int32)info->rates[i])
154 return rate;
155 if (info->rates[i] > max_rate)
156 max_rate = info->rates[i];
157 }
158 // highest rate
159 return max_rate;
160 }
161
162
select_oss_format(int fmt)163 int OpenSoundDevice::select_oss_format(int fmt)
164 {
165 //highest format, Native Endian first
166 if (fmt & AFMT_FLOAT) {
167 return AFMT_FLOAT;
168 } else if (fmt & AFMT_S32_NE) {
169 return AFMT_S32_NE;
170 } else if (fmt & AFMT_S24_NE) {
171 return AFMT_S24_NE;
172 } else if (fmt & AFMT_S16_NE) {
173 return AFMT_S16_NE;
174 } else if (fmt & AFMT_S32_OE) {
175 return AFMT_S32_OE;
176 } else if (fmt & AFMT_S24_OE) {
177 return AFMT_S24_OE;
178 } else if (fmt & AFMT_S16_OE) {
179 return AFMT_S16_OE;
180 } else if (fmt & AFMT_S8) {
181 return AFMT_S8;
182 } else if (fmt & AFMT_U8) {
183 return AFMT_U8;
184 } else
185 return 0;
186 }
187
get_media_format_description_for(int fmt,media_format_description * desc,int count)188 status_t OpenSoundDevice::get_media_format_description_for(int fmt, media_format_description *desc, int count)
189 {
190 int i;
191 for (i = 0; i < count; i++)
192 desc[i] = media_format_description();
193 if (count < 1)
194 return 0;
195 if (fmt & AFMT_SUPPORTED_PCM) {
196 desc[0].family = B_BEOS_FORMAT_FAMILY;
197 desc[0].u.beos.format = 1;
198 return 1;
199 }
200 switch (fmt) {
201 case AFMT_MU_LAW:
202 desc[0].family = B_MISC_FORMAT_FAMILY;
203 desc[0].u.misc.file_format = '.snd';
204 desc[0].u.misc.codec = 'ulaw';
205 if (count < 2)
206 return 1;
207 desc[1].family = B_WAV_FORMAT_FAMILY;
208 desc[1].u.wav.codec = 0x07;
209 return 2;
210 if (count < 3)
211 return 2;
212 desc[1].family = B_QUICKTIME_FORMAT_FAMILY;
213 desc[1].u.quicktime.codec = 'ulaw';
214 desc[1].u.quicktime.vendor = 0;
215 return 3;
216 case AFMT_A_LAW:
217 desc[0].family = B_MISC_FORMAT_FAMILY;
218 desc[0].u.misc.file_format = '.snd';
219 desc[0].u.misc.codec = 'alaw';
220 return 1;
221 // wav/qt ?
222 case AFMT_IMA_ADPCM:
223 desc[0].family = B_BEOS_FORMAT_FAMILY;
224 desc[0].u.beos.format = 'ima4';
225 return 1;
226 case AFMT_MPEG: /* layer 2 */
227 desc[0].family = B_MPEG_FORMAT_FAMILY;
228 desc[0].u.mpeg.id = 0x102;
229 if (count < 2)
230 return 1;
231 desc[1].family = B_WAV_FORMAT_FAMILY;
232 desc[1].u.wav.codec = 0x50;
233 if (count < 3)
234 return 2;
235 desc[1].family = B_AVI_FORMAT_FAMILY;
236 desc[1].u.avi.codec = 0x65610050;
237 return 3;
238 case AFMT_AC3:
239 desc[0].family = B_WAV_FORMAT_FAMILY;
240 desc[0].u.wav.codec = 0x2000;
241 if (count < 2)
242 return 1;
243 desc[1].family = B_AVI_FORMAT_FAMILY;
244 desc[1].u.avi.codec = 0x65612000;
245 return 2;
246 case AFMT_VORBIS:
247 // nothing official
248 desc[0].family = B_MISC_FORMAT_FAMILY;
249 desc[0].u.misc.file_format = 'OSS4';
250 desc[0].u.misc.codec = 'VORB';
251 return 1;
252 case AFMT_SPDIF_RAW:
253 // nothing official
254 desc[0].family = B_MISC_FORMAT_FAMILY;
255 desc[0].u.misc.file_format = 'OSS4';
256 desc[0].u.misc.codec = 'PDIF';
257 return 1;
258 case AFMT_S24_PACKED:
259 // nothing official
260 desc[0].family = B_MISC_FORMAT_FAMILY;
261 desc[0].u.misc.file_format = 'OSS4';
262 desc[0].u.misc.codec = 'S24P';
263 return 1;
264 default:
265 return EINVAL;
266 }
267 return 0;
268 };
269
270
register_media_formats()271 status_t OpenSoundDevice::register_media_formats()
272 {
273 status_t err;
274 int i, count;
275 BMediaFormats formats;
276 if (formats.InitCheck() < B_OK)
277 return formats.InitCheck();
278 media_format format;
279 for (i = 0; gSupportedFormats[i]; i++) {
280 media_format_description desc[10];
281 err = count = get_media_format_description_for(gSupportedFormats[i], desc, 10);
282 if (err < 1)
283 continue;
284 if (gSupportedFormats[i] & AFMT_SUPPORTED_PCM) {
285 format.type = B_MEDIA_RAW_AUDIO;
286 format.u.raw_audio = media_multi_audio_format::wildcard;
287 } else {
288 format.type = B_MEDIA_ENCODED_AUDIO;
289 format.u.encoded_audio = media_encoded_audio_format::wildcard;
290 }
291 err = formats.MakeFormatFor(desc, count, &format);
292 PRINT(("OpenSoundDevice::register_media_formats: MakeFormatFor: %s\n", strerror(err)));
293 }
294 return B_OK;
295 };
296
297
get_media_format_for(int fmt,media_format & format)298 status_t OpenSoundDevice::get_media_format_for(int fmt, media_format &format)
299 {
300 status_t err;
301 BMediaFormats formats;
302 if (formats.InitCheck() < B_OK)
303 return formats.InitCheck();
304 /* shortcut for raw */
305 if (fmt & AFMT_SUPPORTED_PCM) {
306 format = media_format();
307 format.type = B_MEDIA_RAW_AUDIO;
308 format.u.raw_audio = media_raw_audio_format::wildcard;
309 return B_OK;
310 }
311 media_format_description desc;
312 err = get_media_format_description_for(fmt, &desc);
313 if (err < B_OK)
314 return err;
315 err = formats.GetFormatFor(desc, &format);
316 return err;
317 };
318
319
~OpenSoundDevice()320 OpenSoundDevice::~OpenSoundDevice()
321 {
322 CALLED();
323 OpenSoundDeviceEngine *engine;
324 OpenSoundDeviceMixer *mixer;
325 while ((engine = EngineAt(0))) {
326 delete engine;
327 fEngines.RemoveItems(0, 1);
328 }
329 while ((mixer = MixerAt(0))) {
330 delete mixer;
331 fMixers.RemoveItems(0, 1);
332 }
333 }
334
OpenSoundDevice(oss_card_info * cardinfo)335 OpenSoundDevice::OpenSoundDevice(oss_card_info *cardinfo)
336 : fLocker("OpenSoundDevice")
337 {
338 CALLED();
339 fInitCheckStatus = B_NO_INIT;
340 memcpy(&fCardInfo, cardinfo, sizeof(oss_card_info));
341 memset(&fFragments, 0, sizeof(fFragments));
342 #if 0
343 strcpy(fDevice_name, name);
344 strcpy(fDevice_path, path);
345
346 PRINT(("name : %s, path : %s\n", fDevice_name, fDevice_path));
347
348 if (InitDriver() != B_OK)
349 return;
350
351 fInitCheckStatus = B_OK;
352 #endif
353 }
354
355
InitCheck(void) const356 status_t OpenSoundDevice::InitCheck(void) const
357 {
358 CALLED();
359 return fInitCheckStatus;
360 }
361
362
InitDriver()363 status_t OpenSoundDevice::InitDriver()
364 {
365
366 CALLED();
367 PRINT(("OpenSoundDevice::InitDriver: %" B_PRId32 " engines, %" B_PRId32
368 " mixers\n", CountEngines(), CountMixers()));
369
370 if (CountMixers()) {
371 ;//...
372 }
373
374 fInitCheckStatus = B_OK;
375
376 return B_OK;
377 }
378
379
380 status_t
AddEngine(oss_audioinfo * info)381 OpenSoundDevice::AddEngine(oss_audioinfo *info)
382 {
383 status_t err;
384 /* discard shadow/hidden engines (!?) */
385 CALLED();
386 /*
387 if (info->caps & PCM_CAP_SHADOW)
388 return B_OK;
389 if (info->caps & PCM_CAP_HIDDEN)
390 return B_OK;
391 */
392 OpenSoundDeviceEngine *engine =
393 new(std::nothrow) OpenSoundDeviceEngine(info);
394 if (!engine)
395 return ENOMEM;
396 err = engine->InitCheck();
397 if (err < B_OK) {
398 delete engine;
399 return err;
400 }
401 fEngines.AddItem(engine);
402 return B_OK;
403 }
404
405
406 status_t
AddMixer(oss_mixerinfo * info)407 OpenSoundDevice::AddMixer(oss_mixerinfo *info)
408 {
409 status_t err;
410 CALLED();
411 OpenSoundDeviceMixer *mixer =
412 new(std::nothrow) OpenSoundDeviceMixer(info);
413 if (!mixer)
414 return ENOMEM;
415 err = mixer->InitCheck();
416 if (err < B_OK) {
417 delete mixer;
418 return err;
419 }
420 fMixers.AddItem(mixer);
421 return B_OK;
422 }
423
424
425 int32
CountEngines()426 OpenSoundDevice::CountEngines()
427 {
428 return fEngines.CountItems();
429 }
430
431
432 int32
CountMixers()433 OpenSoundDevice::CountMixers()
434 {
435 return fMixers.CountItems();
436 }
437
438
439 OpenSoundDeviceEngine *
EngineAt(int32 i)440 OpenSoundDevice::EngineAt(int32 i)
441 {
442 return (OpenSoundDeviceEngine *)(fEngines.ItemAt(i));
443 }
444
445
446 OpenSoundDeviceMixer *
MixerAt(int32 i)447 OpenSoundDevice::MixerAt(int32 i)
448 {
449 return (OpenSoundDeviceMixer *)(fMixers.ItemAt(i));
450 }
451
452 OpenSoundDeviceEngine *
NextFreeEngineAt(int32 i,bool rec)453 OpenSoundDevice::NextFreeEngineAt(int32 i, bool rec)
454 {
455 // find the first free engine in the rec or play chain
456 OpenSoundDeviceEngine *engine = EngineAt(i);
457 while (engine && engine->InUse()) {
458 engine = rec ? (engine->NextRec()) : (engine->NextPlay());
459 }
460 return engine;
461 }
462
463