1 /*
2 * Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
3 * Copyright (c) 2002-2007, Jerome Duval (jerome.duval@free.fr)
4 *
5 * Distributed under the terms of the MIT License.
6 */
7
8
9 #include "MultiAudioUtility.h"
10
11 #include <errno.h>
12
13 #include <MediaDefs.h>
14
15
16 const float kSampleRates[] = {
17 8000.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0, 44100.0,
18 48000.0, 64000.0, 88200.0, 96000.0, 176400.0, 192000.0, 384000.0, 1536000.0
19 };
20 const uint32 kSampleRateCount = sizeof(kSampleRates) / sizeof(kSampleRates[0]);
21
22
23 template<typename T> static status_t
call_driver(int device,int32 op,T * data)24 call_driver(int device, int32 op, T* data)
25 {
26 if (ioctl(device, op, data, sizeof(T)) != 0)
27 return errno;
28
29 return B_OK;
30 }
31
32
33 namespace MultiAudio {
34
35
36 float
convert_to_sample_rate(uint32 rate)37 convert_to_sample_rate(uint32 rate)
38 {
39 for (uint32 i = 0; i < kSampleRateCount; i++) {
40 if (rate & 1)
41 return kSampleRates[i];
42
43 rate >>= 1;
44 }
45
46 return 0.0;
47 }
48
49
50 uint32
convert_from_sample_rate(float rate)51 convert_from_sample_rate(float rate)
52 {
53 for (uint32 i = 0; i < kSampleRateCount; i++) {
54 if (rate <= kSampleRates[i])
55 return 1 << i;
56 }
57
58 return 0;
59 }
60
61
62 uint32
convert_to_media_format(uint32 format)63 convert_to_media_format(uint32 format)
64 {
65 switch (format) {
66 case B_FMT_FLOAT:
67 return media_raw_audio_format::B_AUDIO_FLOAT;
68 case B_FMT_18BIT:
69 case B_FMT_20BIT:
70 case B_FMT_24BIT:
71 case B_FMT_32BIT:
72 return media_raw_audio_format::B_AUDIO_INT;
73 case B_FMT_16BIT:
74 return media_raw_audio_format::B_AUDIO_SHORT;
75 case B_FMT_8BIT_S:
76 return media_raw_audio_format::B_AUDIO_CHAR;
77 case B_FMT_8BIT_U:
78 return media_raw_audio_format::B_AUDIO_UCHAR;
79
80 default:
81 return 0;
82 }
83 }
84
85
86 int16
convert_to_valid_bits(uint32 format)87 convert_to_valid_bits(uint32 format)
88 {
89 switch (format) {
90 case B_FMT_18BIT:
91 return 18;
92 case B_FMT_20BIT:
93 return 20;
94 case B_FMT_24BIT:
95 return 24;
96 case B_FMT_32BIT:
97 return 32;
98
99 default:
100 return 0;
101 }
102 }
103
104
105 uint32
convert_from_media_format(uint32 format)106 convert_from_media_format(uint32 format)
107 {
108 switch (format) {
109 case media_raw_audio_format::B_AUDIO_FLOAT:
110 return B_FMT_FLOAT;
111 case media_raw_audio_format::B_AUDIO_INT:
112 return B_FMT_32BIT;
113 case media_raw_audio_format::B_AUDIO_SHORT:
114 return B_FMT_16BIT;
115 case media_raw_audio_format::B_AUDIO_CHAR:
116 return B_FMT_8BIT_S;
117 case media_raw_audio_format::B_AUDIO_UCHAR:
118 return B_FMT_8BIT_U;
119
120 default:
121 return 0;
122 }
123 }
124
125
126 uint32
select_sample_rate(uint32 rate)127 select_sample_rate(uint32 rate)
128 {
129 // highest rate
130 uint32 crate = B_SR_1536000;
131 while (crate != 0) {
132 if (rate & crate)
133 return crate;
134 crate >>= 1;
135 }
136 return 0;
137 }
138
139
140 uint32
select_format(uint32 format)141 select_format(uint32 format)
142 {
143 // best format
144 // TODO ensure we support this format
145 /*if (format & B_FMT_FLOAT)
146 return B_FMT_FLOAT;*/
147 if (format & B_FMT_32BIT)
148 return B_FMT_32BIT;
149 if (format & B_FMT_24BIT)
150 return B_FMT_24BIT;
151 if (format & B_FMT_20BIT)
152 return B_FMT_20BIT;
153 if (format & B_FMT_18BIT)
154 return B_FMT_18BIT;
155 if (format & B_FMT_16BIT)
156 return B_FMT_16BIT;
157 if (format & B_FMT_8BIT_S)
158 return B_FMT_8BIT_S;
159 if (format & B_FMT_8BIT_U)
160 return B_FMT_8BIT_U;
161
162 return 0;
163 }
164
165
166 status_t
get_description(int device,multi_description * description)167 get_description(int device, multi_description* description)
168 {
169 return call_driver(device, B_MULTI_GET_DESCRIPTION, description);
170 }
171
172
173 status_t
get_enabled_channels(int device,multi_channel_enable * enable)174 get_enabled_channels(int device, multi_channel_enable* enable)
175 {
176 return call_driver(device, B_MULTI_GET_ENABLED_CHANNELS, enable);
177 }
178
179
180 status_t
set_enabled_channels(int device,multi_channel_enable * enable)181 set_enabled_channels(int device, multi_channel_enable* enable)
182 {
183 return call_driver(device, B_MULTI_SET_ENABLED_CHANNELS, enable);
184 }
185
186
187 status_t
get_global_format(int device,multi_format_info * info)188 get_global_format(int device, multi_format_info* info)
189 {
190 return call_driver(device, B_MULTI_GET_GLOBAL_FORMAT, info);
191 }
192
193
194 status_t
set_global_format(int device,multi_format_info * info)195 set_global_format(int device, multi_format_info* info)
196 {
197 return call_driver(device, B_MULTI_SET_GLOBAL_FORMAT, info);
198 }
199
200
201 status_t
get_buffers(int device,multi_buffer_list * list)202 get_buffers(int device, multi_buffer_list* list)
203 {
204 return call_driver(device, B_MULTI_GET_BUFFERS, list);
205 }
206
207
208 status_t
buffer_exchange(int device,multi_buffer_info * info)209 buffer_exchange(int device, multi_buffer_info* info)
210 {
211 return call_driver(device, B_MULTI_BUFFER_EXCHANGE, info);
212 }
213
214
215 status_t
list_mix_controls(int device,multi_mix_control_info * info)216 list_mix_controls(int device, multi_mix_control_info* info)
217 {
218 return call_driver(device, B_MULTI_LIST_MIX_CONTROLS, info);
219 }
220
221
222 status_t
get_mix(int device,multi_mix_value_info * info)223 get_mix(int device, multi_mix_value_info* info)
224 {
225 return call_driver(device, B_MULTI_GET_MIX, info);
226 }
227
228
229 status_t
set_mix(int device,multi_mix_value_info * info)230 set_mix(int device, multi_mix_value_info* info)
231 {
232 return call_driver(device, B_MULTI_SET_MIX, info);
233 }
234
235
236 } // namespace MultiAudio
237