|
37 | 37 | #include <assert.h> |
38 | 38 | #include <string.h> |
39 | 39 | #include <string> |
| 40 | +#include <vector> |
40 | 41 | #include <errno.h> |
41 | 42 | #include <ctype.h> |
42 | 43 | #include <alsa/asoundlib.h> |
43 | 44 | #include <sstream> |
44 | 45 |
|
| 46 | +/* from sound/asound.h, header is not compatible with alsa/asoundlib.h |
| 47 | + */ |
| 48 | +struct snd_ctl_tlv { |
| 49 | + unsigned int numid; /* control element numeric identification */ |
| 50 | + unsigned int length; /* in bytes aligned to 4 */ |
| 51 | + unsigned char tlv[]; /* first TLV */ |
| 52 | +}; |
| 53 | + |
45 | 54 |
|
46 | 55 | #define base AmixerControl |
47 | 56 |
|
@@ -172,6 +181,31 @@ bool LegacyAmixerControl::accessHW(bool receive, std::string &error) |
172 | 181 |
|
173 | 182 | if (receive) { |
174 | 183 |
|
| 184 | + // Special hook for TLV Bytes Control |
| 185 | + if ((eType == SND_CTL_ELEM_TYPE_BYTES) && |
| 186 | + snd_ctl_elem_info_is_tlv_readable(info)) { |
| 187 | + |
| 188 | + std::vector<unsigned char> rawTlv(sizeof(struct snd_ctl_tlv) + elementCount); |
| 189 | + |
| 190 | + struct snd_ctl_tlv *tlv = reinterpret_cast<struct snd_ctl_tlv *>(rawTlv.data()); |
| 191 | + |
| 192 | + ret = snd_ctl_elem_tlv_read(sndCtrl, id, reinterpret_cast<unsigned int *>(tlv), |
| 193 | + rawTlv.size()); |
| 194 | + if (ret < 0) { |
| 195 | + |
| 196 | + error = "ALSA: Unable to read element " + controlName + |
| 197 | + ": " + snd_strerror(ret); |
| 198 | + |
| 199 | + } else { |
| 200 | + blackboardWrite(tlv->tlv, elementCount); |
| 201 | + } |
| 202 | + |
| 203 | + // Close sound control |
| 204 | + snd_ctl_close(sndCtrl); |
| 205 | + |
| 206 | + return ret == 0; |
| 207 | + } |
| 208 | + |
175 | 209 | // Read element |
176 | 210 | if ((ret = snd_ctl_elem_read(sndCtrl, control)) < 0) { |
177 | 211 |
|
@@ -221,6 +255,32 @@ bool LegacyAmixerControl::accessHW(bool receive, std::string &error) |
221 | 255 |
|
222 | 256 | } else { |
223 | 257 |
|
| 258 | + // Special hook for TLV Bytes Control |
| 259 | + if ((eType == SND_CTL_ELEM_TYPE_BYTES) && |
| 260 | + snd_ctl_elem_info_is_tlv_writable(info)) { |
| 261 | + |
| 262 | + std::vector<unsigned char> rawTlv(sizeof(struct snd_ctl_tlv) + elementCount); |
| 263 | + |
| 264 | + struct snd_ctl_tlv *tlv = reinterpret_cast<struct snd_ctl_tlv *>(rawTlv.data()); |
| 265 | + |
| 266 | + tlv->numid = 0; |
| 267 | + tlv->length = elementCount; |
| 268 | + |
| 269 | + blackboardRead(tlv->tlv, elementCount); |
| 270 | + |
| 271 | + ret = snd_ctl_elem_tlv_write(sndCtrl, id, reinterpret_cast<unsigned int *>(tlv)); |
| 272 | + if (ret < 0) { |
| 273 | + |
| 274 | + error = "ALSA: Unable to write element " + controlName + |
| 275 | + ": " + snd_strerror(ret); |
| 276 | + } |
| 277 | + |
| 278 | + // Close sound control |
| 279 | + snd_ctl_close(sndCtrl); |
| 280 | + |
| 281 | + return ret == 0; |
| 282 | + } |
| 283 | + |
224 | 284 | // Go through all indexes |
225 | 285 | for (index = 0; index < elementCount; index++) { |
226 | 286 |
|
|
0 commit comments