|
42 | 42 | #include <ctype.h> |
43 | 43 | #include <alsa/asoundlib.h> |
44 | 44 | #include <sstream> |
| 45 | +#include <numeric> |
45 | 46 |
|
46 | 47 | /* from sound/asound.h, header is not compatible with alsa/asoundlib.h |
47 | 48 | */ |
@@ -217,40 +218,58 @@ bool LegacyAmixerControl::accessHW(bool receive, std::string &error) |
217 | 218 |
|
218 | 219 | return false; |
219 | 220 | } |
220 | | - // Go through all indexes |
221 | | - for (index = 0; index < elementCount; index++) { |
222 | | - |
223 | | - switch (eType) { |
224 | | - case SND_CTL_ELEM_TYPE_BOOLEAN: |
225 | | - value = snd_ctl_elem_value_get_boolean(control, index); |
226 | | - break; |
227 | | - case SND_CTL_ELEM_TYPE_INTEGER: |
228 | | - value = snd_ctl_elem_value_get_integer(control, index); |
229 | | - break; |
230 | | - case SND_CTL_ELEM_TYPE_INTEGER64: |
231 | | - value = snd_ctl_elem_value_get_integer64(control, index); |
232 | | - break; |
233 | | - case SND_CTL_ELEM_TYPE_ENUMERATED: |
234 | | - value = snd_ctl_elem_value_get_enumerated(control, index); |
235 | | - break; |
236 | | - case SND_CTL_ELEM_TYPE_BYTES: |
237 | | - value = snd_ctl_elem_value_get_byte(control, index); |
238 | | - break; |
239 | | - default: |
240 | | - error = "ALSA: Unknown control element type while reading alsa element " + |
241 | | - controlName; |
242 | | - return false; |
243 | | - } |
| 221 | + |
| 222 | + if (eType == SND_CTL_ELEM_TYPE_BYTES) { |
| 223 | + const void *data = snd_ctl_elem_value_get_bytes(control); |
244 | 224 |
|
245 | 225 | if (isDebugEnabled()) { |
| 226 | + const unsigned char *first = reinterpret_cast<const unsigned char *>(data); |
| 227 | + const unsigned char *last = first + elementCount; |
246 | 228 |
|
247 | 229 | // The "info" method has been shadowed by a local variable |
248 | | - this->info() << "Reading alsa element " << controlName |
249 | | - << ", index " << index << " with value " << value; |
| 230 | + this->info() << "Reading alsa element " << controlName << ": " |
| 231 | + << std::accumulate(first, last, std::string{}, |
| 232 | + [](const std::string& a, std::vector<unsigned char>::value_type b) { |
| 233 | + return a.empty() ? std::to_string(b) : a + ',' + std::to_string(b); |
| 234 | + }); |
250 | 235 | } |
251 | 236 |
|
252 | | - // Write data to blackboard (beware this code is OK on Little Endian machines only) |
253 | | - toBlackboard(value); |
| 237 | + blackboardWrite(data, elementCount); |
| 238 | + |
| 239 | + } else { |
| 240 | + |
| 241 | + // Go through all indexes |
| 242 | + for (index = 0; index < elementCount; index++) { |
| 243 | + |
| 244 | + switch (eType) { |
| 245 | + case SND_CTL_ELEM_TYPE_BOOLEAN: |
| 246 | + value = snd_ctl_elem_value_get_boolean(control, index); |
| 247 | + break; |
| 248 | + case SND_CTL_ELEM_TYPE_INTEGER: |
| 249 | + value = snd_ctl_elem_value_get_integer(control, index); |
| 250 | + break; |
| 251 | + case SND_CTL_ELEM_TYPE_INTEGER64: |
| 252 | + value = snd_ctl_elem_value_get_integer64(control, index); |
| 253 | + break; |
| 254 | + case SND_CTL_ELEM_TYPE_ENUMERATED: |
| 255 | + value = snd_ctl_elem_value_get_enumerated(control, index); |
| 256 | + break; |
| 257 | + default: |
| 258 | + error = "ALSA: Unknown control element type while reading alsa element " + |
| 259 | + controlName; |
| 260 | + return false; |
| 261 | + } |
| 262 | + |
| 263 | + if (isDebugEnabled()) { |
| 264 | + |
| 265 | + // The "info" method has been shadowed by a local variable |
| 266 | + this->info() << "Reading alsa element " << controlName |
| 267 | + << ", index " << index << " with value " << value; |
| 268 | + } |
| 269 | + |
| 270 | + // Write data to blackboard (beware this code is OK on Little Endian machines only) |
| 271 | + toBlackboard(value); |
| 272 | + } |
254 | 273 | } |
255 | 274 |
|
256 | 275 | } else { |
@@ -281,39 +300,56 @@ bool LegacyAmixerControl::accessHW(bool receive, std::string &error) |
281 | 300 | return ret == 0; |
282 | 301 | } |
283 | 302 |
|
284 | | - // Go through all indexes |
285 | | - for (index = 0; index < elementCount; index++) { |
| 303 | + if (eType == SND_CTL_ELEM_TYPE_BYTES) { |
| 304 | + std::vector<unsigned char> rawData(elementCount); |
286 | 305 |
|
287 | | - // Read data from blackboard (beware this code is OK on Little Endian machines only) |
288 | | - value = fromBlackboard(); |
| 306 | + blackboardRead(rawData.data(), elementCount); |
289 | 307 |
|
290 | 308 | if (isDebugEnabled()) { |
291 | 309 |
|
292 | 310 | // The "info" method has been shadowed by a local variable |
293 | | - this->info() << "Writing alsa element " << controlName |
294 | | - << ", index " << index << " with value " << value; |
| 311 | + this->info() << "Writing alsa element " << controlName << ": " |
| 312 | + << std::accumulate(begin(rawData), end(rawData), std::string{}, |
| 313 | + [](const std::string& a, std::vector<unsigned char>::value_type b) { |
| 314 | + return a.empty() ? std::to_string(b) : a + ',' + std::to_string(b); |
| 315 | + }); |
| 316 | + |
295 | 317 | } |
296 | 318 |
|
297 | | - switch (eType) { |
298 | | - case SND_CTL_ELEM_TYPE_BOOLEAN: |
299 | | - snd_ctl_elem_value_set_boolean(control, index, value); |
300 | | - break; |
301 | | - case SND_CTL_ELEM_TYPE_INTEGER: |
302 | | - snd_ctl_elem_value_set_integer(control, index, value); |
303 | | - break; |
304 | | - case SND_CTL_ELEM_TYPE_INTEGER64: |
305 | | - snd_ctl_elem_value_set_integer64(control, index, value); |
306 | | - break; |
307 | | - case SND_CTL_ELEM_TYPE_ENUMERATED: |
308 | | - snd_ctl_elem_value_set_enumerated(control, index, value); |
309 | | - break; |
310 | | - case SND_CTL_ELEM_TYPE_BYTES: |
311 | | - snd_ctl_elem_value_set_byte(control, index, value); |
312 | | - break; |
313 | | - default: |
314 | | - error = "ALSA: Unknown control element type while writing alsa element " + |
| 319 | + snd_ctl_elem_set_bytes(control, rawData.data(), elementCount); |
| 320 | + |
| 321 | + } else { |
| 322 | + // Go through all indexes |
| 323 | + for (index = 0; index < elementCount; index++) { |
| 324 | + |
| 325 | + // Read data from blackboard (beware this code is OK on Little Endian machines only) |
| 326 | + value = fromBlackboard(); |
| 327 | + |
| 328 | + if (isDebugEnabled()) { |
| 329 | + |
| 330 | + // The "info" method has been shadowed by a local variable |
| 331 | + this->info() << "Writing alsa element " << controlName |
| 332 | + << ", index " << index << " with value " << value; |
| 333 | + } |
| 334 | + |
| 335 | + switch (eType) { |
| 336 | + case SND_CTL_ELEM_TYPE_BOOLEAN: |
| 337 | + snd_ctl_elem_value_set_boolean(control, index, value); |
| 338 | + break; |
| 339 | + case SND_CTL_ELEM_TYPE_INTEGER: |
| 340 | + snd_ctl_elem_value_set_integer(control, index, value); |
| 341 | + break; |
| 342 | + case SND_CTL_ELEM_TYPE_INTEGER64: |
| 343 | + snd_ctl_elem_value_set_integer64(control, index, value); |
| 344 | + break; |
| 345 | + case SND_CTL_ELEM_TYPE_ENUMERATED: |
| 346 | + snd_ctl_elem_value_set_enumerated(control, index, value); |
| 347 | + break; |
| 348 | + default: |
| 349 | + error = "ALSA: Unknown control element type while writing alsa element " + |
315 | 350 | controlName; |
316 | | - return false; |
| 351 | + return false; |
| 352 | + } |
317 | 353 | } |
318 | 354 | } |
319 | 355 |
|
|
0 commit comments