3rdparty/licenseReport: Add seperate LGPL checks
[haiku.git] / src / add-ons / media / media-add-ons / multi_audio / MultiAudioDevice.cpp
bloba3581e9df2baab3fd964ce16b59937f623e6a9f5
1 /*
2 * Copyright (c) 2002-2007, Jerome Duval (jerome.duval@free.fr)
3 * Distributed under the terms of the MIT License.
4 */
7 #include "MultiAudioDevice.h"
9 #include <errno.h>
10 #include <string.h>
12 #include <MediaDefs.h>
14 #include "debug.h"
15 #include "MultiAudioUtility.h"
18 using namespace MultiAudio;
21 MultiAudioDevice::MultiAudioDevice(const char* name, const char* path)
23 CALLED();
25 strlcpy(fPath, path, B_PATH_NAME_LENGTH);
26 PRINT(("name: %s, path: %s\n", name, fPath));
28 fInitStatus = _InitDriver();
32 MultiAudioDevice::~MultiAudioDevice()
34 CALLED();
35 if (fDevice >= 0)
36 close(fDevice);
40 status_t
41 MultiAudioDevice::InitCheck() const
43 CALLED();
44 return fInitStatus;
48 status_t
49 MultiAudioDevice::BufferExchange(multi_buffer_info *info)
51 return buffer_exchange(fDevice, info);
55 status_t
56 MultiAudioDevice::SetMix(multi_mix_value_info *info)
58 return set_mix(fDevice, info);
62 status_t
63 MultiAudioDevice::GetMix(multi_mix_value_info *info)
65 return get_mix(fDevice, info);
69 status_t
70 MultiAudioDevice::SetInputFrameRate(uint32 multiAudioRate)
72 if ((fDescription.input_rates & multiAudioRate) == 0)
73 return B_BAD_VALUE;
75 if (fFormatInfo.input.rate == multiAudioRate)
76 return B_OK;
78 uint32 oldRate = fFormatInfo.input.rate;
79 fFormatInfo.input.rate = multiAudioRate;
81 status_t status = set_global_format(fDevice, &fFormatInfo);
82 if (status != B_OK) {
83 fprintf(stderr, "Failed on B_MULTI_SET_GLOBAL_FORMAT: %s\n",
84 strerror(status));
85 fFormatInfo.input.rate = oldRate;
86 return status;
89 return _GetBuffers();
93 status_t
94 MultiAudioDevice::SetOutputFrameRate(uint32 multiAudioRate)
96 if ((fDescription.output_rates & multiAudioRate) == 0)
97 return B_BAD_VALUE;
99 if (fFormatInfo.output.rate == multiAudioRate)
100 return B_OK;
102 uint32 oldRate = fFormatInfo.output.rate;
103 fFormatInfo.output.rate = multiAudioRate;
105 status_t status = set_global_format(fDevice, &fFormatInfo);
106 if (status != B_OK) {
107 fprintf(stderr, "Failed on B_MULTI_SET_GLOBAL_FORMAT: %s\n",
108 strerror(status));
109 fFormatInfo.output.rate = oldRate;
110 return status;
113 return _GetBuffers();
117 status_t
118 MultiAudioDevice::_InitDriver()
120 int num_outputs, num_inputs, num_channels;
122 CALLED();
124 // open the device driver
126 fDevice = open(fPath, O_WRONLY);
127 if (fDevice == -1) {
128 fprintf(stderr, "Failed to open %s: %s\n", fPath, strerror(errno));
129 return B_ERROR;
132 // Get description
134 fDescription.info_size = sizeof(fDescription);
135 fDescription.request_channel_count = MAX_CHANNELS;
136 fDescription.channels = fChannelInfo;
137 status_t status = get_description(fDevice, &fDescription);
138 if (status != B_OK) {
139 fprintf(stderr, "Failed on B_MULTI_GET_DESCRIPTION: %s\n",
140 strerror(status));
141 return status;
144 PRINT(("Friendly name:\t%s\nVendor:\t\t%s\n",
145 fDescription.friendly_name, fDescription.vendor_info));
146 PRINT(("%" B_PRId32 " outputs\t%" B_PRId32 " inputs\n%" B_PRId32
147 " out busses\t%" B_PRId32 " in busses\n",
148 fDescription.output_channel_count, fDescription.input_channel_count,
149 fDescription.output_bus_channel_count,
150 fDescription.input_bus_channel_count));
151 PRINT(("\nChannels\n"
152 "ID\tKind\tDesig\tConnectors\n"));
154 for (int32 i = 0; i < fDescription.output_channel_count
155 + fDescription.input_channel_count; i++) {
156 PRINT(("%" B_PRId32 "\t%d\t0x%" B_PRIx32 "\t0x%" B_PRIx32 "\n",
157 fDescription.channels[i].channel_id,
158 fDescription.channels[i].kind,
159 fDescription.channels[i].designations,
160 fDescription.channels[i].connectors));
162 PRINT(("\n"));
164 PRINT(("Output rates\t\t0x%" B_PRIx32 "\n", fDescription.output_rates));
165 PRINT(("Input rates\t\t0x%" B_PRIx32 "\n", fDescription.input_rates));
166 PRINT(("Max CVSR\t\t%.0f\n", fDescription.max_cvsr_rate));
167 PRINT(("Min CVSR\t\t%.0f\n", fDescription.min_cvsr_rate));
168 PRINT(("Output formats\t\t0x%" B_PRIx32 "\n", fDescription.output_formats));
169 PRINT(("Input formats\t\t0x%" B_PRIx32 "\n", fDescription.input_formats));
170 PRINT(("Lock sources\t\t0x%" B_PRIx32 "\n", fDescription.lock_sources));
171 PRINT(("Timecode sources\t0x%" B_PRIx32 "\n", fDescription.timecode_sources));
172 PRINT(("Interface flags\t\t0x%" B_PRIx32 "\n", fDescription.interface_flags));
173 PRINT(("Control panel string:\t\t%s\n", fDescription.control_panel));
174 PRINT(("\n"));
176 num_outputs = fDescription.output_channel_count;
177 num_inputs = fDescription.input_channel_count;
178 num_channels = num_outputs + num_inputs;
180 // Get and set enabled channels
182 multi_channel_enable enable;
183 uint32 enableBits;
184 enable.info_size = sizeof(enable);
185 enable.enable_bits = (uchar*)&enableBits;
187 status = get_enabled_channels(fDevice, &enable);
188 if (status != B_OK) {
189 fprintf(stderr, "Failed on B_MULTI_GET_ENABLED_CHANNELS: %s\n",
190 strerror(status));
191 return status;
194 enableBits = (1 << num_channels) - 1;
195 enable.lock_source = B_MULTI_LOCK_INTERNAL;
197 status = set_enabled_channels(fDevice, &enable);
198 if (status != B_OK) {
199 fprintf(stderr, "Failed on B_MULTI_SET_ENABLED_CHANNELS 0x%x: %s\n",
200 *enable.enable_bits, strerror(status));
201 return status;
204 // Set the sample rate
206 fFormatInfo.info_size = sizeof(multi_format_info);
207 fFormatInfo.output.rate = select_sample_rate(fDescription.output_rates);
208 fFormatInfo.output.cvsr = 0;
209 fFormatInfo.output.format = select_format(fDescription.output_formats);
210 fFormatInfo.input.rate = select_sample_rate(fDescription.input_rates);
211 fFormatInfo.input.cvsr = fFormatInfo.output.cvsr;
212 fFormatInfo.input.format = select_format(fDescription.input_formats);
214 status = set_global_format(fDevice, &fFormatInfo);
215 if (status != B_OK) {
216 fprintf(stderr, "Failed on B_MULTI_SET_GLOBAL_FORMAT: %s\n",
217 strerror(status));
220 status = get_global_format(fDevice, &fFormatInfo);
221 if (status != B_OK) {
222 fprintf(stderr, "Failed on B_MULTI_GET_GLOBAL_FORMAT: %s\n",
223 strerror(status));
224 return status;
227 // Get the buffers
228 status = _GetBuffers();
229 if (status != B_OK)
230 return status;
233 fMixControlInfo.info_size = sizeof(fMixControlInfo);
234 fMixControlInfo.control_count = MAX_CONTROLS;
235 fMixControlInfo.controls = fMixControl;
237 status = list_mix_controls(fDevice, &fMixControlInfo);
238 if (status != B_OK) {
239 fprintf(stderr, "Failed on DRIVER_LIST_MIX_CONTROLS: %s\n",
240 strerror(status));
241 return status;
244 return B_OK;
248 status_t
249 MultiAudioDevice::_GetBuffers()
251 for (uint32 i = 0; i < MAX_BUFFERS; i++) {
252 fPlayBuffers[i] = &fPlayBufferList[i * MAX_CHANNELS];
253 fRecordBuffers[i] = &fRecordBufferList[i * MAX_CHANNELS];
255 fBufferList.info_size = sizeof(multi_buffer_list);
256 fBufferList.request_playback_buffer_size = 0;
257 // use the default...
258 fBufferList.request_playback_buffers = MAX_BUFFERS;
259 fBufferList.request_playback_channels = fDescription.output_channel_count;
260 fBufferList.playback_buffers = (buffer_desc **) fPlayBuffers;
261 fBufferList.request_record_buffer_size = 0;
262 // use the default...
263 fBufferList.request_record_buffers = MAX_BUFFERS;
264 fBufferList.request_record_channels = fDescription.input_channel_count;
265 fBufferList.record_buffers = /*(buffer_desc **)*/ fRecordBuffers;
267 status_t status = get_buffers(fDevice, &fBufferList);
268 if (status != B_OK) {
269 fprintf(stderr, "Failed on B_MULTI_GET_BUFFERS: %s\n",
270 strerror(status));
271 return status;
274 for (int32 i = 0; i < fBufferList.return_playback_buffers; i++) {
275 for (int32 j = 0; j < fBufferList.return_playback_channels; j++) {
276 PRINT(("fBufferList.playback_buffers[%" B_PRId32 "][%" B_PRId32
277 "].base: %p\n",
278 i, j, fBufferList.playback_buffers[i][j].base));
279 PRINT(("fBufferList.playback_buffers[%" B_PRId32 "][%" B_PRId32
280 "].stride: %li\n",
281 i, j, fBufferList.playback_buffers[i][j].stride));
285 for (int32 i = 0; i < fBufferList.return_record_buffers; i++) {
286 for (int32 j = 0; j < fBufferList.return_record_channels; j++) {
287 PRINT(("fBufferList.record_buffers[%" B_PRId32 "][%" B_PRId32
288 "].base: %p\n",
289 i, j, fBufferList.record_buffers[i][j].base));
290 PRINT(("fBufferList.record_buffers[%" B_PRId32 "][%" B_PRId32
291 "].stride: %li\n",
292 i, j, fBufferList.record_buffers[i][j].stride));
296 return B_OK;