xref: /haiku/src/add-ons/media/media-add-ons/multi_audio/MultiAudioUtility.cpp (revision ed24eb5ff12640d052171c6a7feba37fab8a75d1)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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