2 * Copyright (c) 2002-2007, Jerome Duval (jerome.duval@free.fr)
3 * Distributed under the terms of the MIT License.
7 #include "MultiAudioDevice.h"
12 #include <MediaDefs.h>
15 #include "MultiAudioUtility.h"
18 using namespace MultiAudio
;
21 MultiAudioDevice::MultiAudioDevice(const char* name
, const char* path
)
25 strlcpy(fPath
, path
, B_PATH_NAME_LENGTH
);
26 PRINT(("name: %s, path: %s\n", name
, fPath
));
28 fInitStatus
= _InitDriver();
32 MultiAudioDevice::~MultiAudioDevice()
41 MultiAudioDevice::InitCheck() const
49 MultiAudioDevice::BufferExchange(multi_buffer_info
*info
)
51 return buffer_exchange(fDevice
, info
);
56 MultiAudioDevice::SetMix(multi_mix_value_info
*info
)
58 return set_mix(fDevice
, info
);
63 MultiAudioDevice::GetMix(multi_mix_value_info
*info
)
65 return get_mix(fDevice
, info
);
70 MultiAudioDevice::SetInputFrameRate(uint32 multiAudioRate
)
72 if ((fDescription
.input_rates
& multiAudioRate
) == 0)
75 if (fFormatInfo
.input
.rate
== multiAudioRate
)
78 uint32 oldRate
= fFormatInfo
.input
.rate
;
79 fFormatInfo
.input
.rate
= multiAudioRate
;
81 status_t status
= set_global_format(fDevice
, &fFormatInfo
);
83 fprintf(stderr
, "Failed on B_MULTI_SET_GLOBAL_FORMAT: %s\n",
85 fFormatInfo
.input
.rate
= oldRate
;
94 MultiAudioDevice::SetOutputFrameRate(uint32 multiAudioRate
)
96 if ((fDescription
.output_rates
& multiAudioRate
) == 0)
99 if (fFormatInfo
.output
.rate
== multiAudioRate
)
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",
109 fFormatInfo
.output
.rate
= oldRate
;
113 return _GetBuffers();
118 MultiAudioDevice::_InitDriver()
120 int num_outputs
, num_inputs
, num_channels
;
124 // open the device driver
126 fDevice
= open(fPath
, O_WRONLY
);
128 fprintf(stderr
, "Failed to open %s: %s\n", fPath
, strerror(errno
));
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",
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
));
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
));
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
;
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",
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
));
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",
220 status
= get_global_format(fDevice
, &fFormatInfo
);
221 if (status
!= B_OK
) {
222 fprintf(stderr
, "Failed on B_MULTI_GET_GLOBAL_FORMAT: %s\n",
228 status
= _GetBuffers();
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",
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",
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
278 i
, j
, fBufferList
.playback_buffers
[i
][j
].base
));
279 PRINT(("fBufferList.playback_buffers[%" B_PRId32
"][%" B_PRId32
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
289 i
, j
, fBufferList
.record_buffers
[i
][j
].base
));
290 PRINT(("fBufferList.record_buffers[%" B_PRId32
"][%" B_PRId32
292 i
, j
, fBufferList
.record_buffers
[i
][j
].stride
));