mirror of
https://github.com/openharmony/third_party_tinyalsa.git
synced 2026-07-19 15:24:22 -04:00
@@ -41,6 +41,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* TLV header size*/
|
||||
#define TLV_HEADER_SIZE (2 * sizeof(unsigned int))
|
||||
|
||||
struct mixer;
|
||||
|
||||
struct mixer_ctl;
|
||||
@@ -107,6 +110,8 @@ const char *mixer_ctl_get_enum_string(struct mixer_ctl *ctl, unsigned int enum_i
|
||||
*/
|
||||
void mixer_ctl_update(struct mixer_ctl *ctl);
|
||||
|
||||
int mixer_ctl_is_access_tlv_rw(const struct mixer_ctl *ctl);
|
||||
|
||||
/* Set and get mixer controls */
|
||||
int mixer_ctl_get_percent(const struct mixer_ctl *ctl, unsigned int id);
|
||||
|
||||
|
||||
+39
-4
@@ -381,6 +381,17 @@ void mixer_ctl_update(struct mixer_ctl *ctl)
|
||||
ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_INFO, ctl->info);
|
||||
}
|
||||
|
||||
/** Checks the control for TLV Read/Write access.
|
||||
* @param ctl An initialized control handle.
|
||||
* @returns On success, non-zero.
|
||||
* On failure, zero.
|
||||
* @ingroup libtinyalsa-mixer
|
||||
*/
|
||||
int mixer_ctl_is_access_tlv_rw(const struct mixer_ctl *ctl)
|
||||
{
|
||||
return (ctl->info.access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE);
|
||||
}
|
||||
|
||||
/** Gets the control's ID.
|
||||
* @param ctl An initialized control handle.
|
||||
* @returns On success, the control's ID is returned.
|
||||
@@ -579,8 +590,20 @@ int mixer_ctl_get_array(const struct mixer_ctl *ctl, void *array, size_t count)
|
||||
int ret = 0;
|
||||
size_t size;
|
||||
void *source;
|
||||
size_t total_count;
|
||||
|
||||
if (!ctl || (count > ctl->info.count) || !count || !array)
|
||||
if ((!ctl) || !count || !array)
|
||||
return -EINVAL;
|
||||
|
||||
total_count = ctl->info.count;
|
||||
|
||||
if ((ctl->info.type == SNDRV_CTL_ELEM_TYPE_BYTES) &&
|
||||
(mixer_ctl_is_access_tlv_rw(ctl))) {
|
||||
/* Additional two words is for the TLV header */
|
||||
total_count += TLV_HEADER_SIZE;
|
||||
}
|
||||
|
||||
if (count > total_count)
|
||||
return -EINVAL;
|
||||
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
@@ -598,7 +621,7 @@ int mixer_ctl_get_array(const struct mixer_ctl *ctl, void *array, size_t count)
|
||||
|
||||
case SNDRV_CTL_ELEM_TYPE_BYTES:
|
||||
/* check if this is new bytes TLV */
|
||||
if (ctl->info.access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) {
|
||||
if (mixer_ctl_is_access_tlv_rw(ctl)) {
|
||||
struct snd_ctl_tlv *tlv;
|
||||
int ret;
|
||||
|
||||
@@ -703,8 +726,20 @@ int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count)
|
||||
struct snd_ctl_elem_value ev;
|
||||
size_t size;
|
||||
void *dest;
|
||||
size_t total_count;
|
||||
|
||||
if (!ctl || (count > ctl->info.count) || !count || !array)
|
||||
if ((!ctl) || !count || !array)
|
||||
return -EINVAL;
|
||||
|
||||
total_count = ctl->info.count;
|
||||
|
||||
if ((ctl->info.type == SNDRV_CTL_ELEM_TYPE_BYTES) &&
|
||||
(mixer_ctl_is_access_tlv_rw(ctl))) {
|
||||
/* Additional TLV header */
|
||||
total_count += TLV_HEADER_SIZE;
|
||||
}
|
||||
|
||||
if (count > total_count)
|
||||
return -EINVAL;
|
||||
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
@@ -719,7 +754,7 @@ int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count)
|
||||
|
||||
case SNDRV_CTL_ELEM_TYPE_BYTES:
|
||||
/* check if this is new bytes TLV */
|
||||
if (ctl->info.access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) {
|
||||
if (mixer_ctl_is_access_tlv_rw(ctl)) {
|
||||
struct snd_ctl_tlv *tlv;
|
||||
int ret = 0;
|
||||
if (count > SIZE_MAX - sizeof(*tlv))
|
||||
|
||||
+24
-6
@@ -192,6 +192,7 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control)
|
||||
int min, max;
|
||||
int ret;
|
||||
char *buf = NULL;
|
||||
unsigned int tlv_header_size = 0;
|
||||
|
||||
if (isdigit(control[0]))
|
||||
ctl = mixer_get_ctl(mixer, atoi(control));
|
||||
@@ -207,13 +208,16 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control)
|
||||
num_values = mixer_ctl_get_num_values(ctl);
|
||||
|
||||
if ((type == MIXER_CTL_TYPE_BYTE) && (num_values > 0)) {
|
||||
buf = calloc(1, num_values);
|
||||
if (mixer_ctl_is_access_tlv_rw(ctl) != 0) {
|
||||
tlv_header_size = TLV_HEADER_SIZE;
|
||||
}
|
||||
buf = calloc(1, num_values + tlv_header_size);
|
||||
if (buf == NULL) {
|
||||
fprintf(stderr, "Failed to alloc mem for bytes %u\n", num_values);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = mixer_ctl_get_array(ctl, buf, num_values);
|
||||
ret = mixer_ctl_get_array(ctl, buf, num_values + tlv_header_size);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to mixer_ctl_get_array\n");
|
||||
free(buf);
|
||||
@@ -234,7 +238,8 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control)
|
||||
tinymix_print_enum(ctl);
|
||||
break;
|
||||
case MIXER_CTL_TYPE_BYTE:
|
||||
printf("%02x", buf[i]);
|
||||
/* skip printing TLV header if exists */
|
||||
printf(" %02x", buf[i + tlv_header_size]);
|
||||
break;
|
||||
default:
|
||||
printf("unknown");
|
||||
@@ -262,13 +267,25 @@ static void tinymix_set_byte_ctl(struct mixer_ctl *ctl,
|
||||
char *end;
|
||||
unsigned int i;
|
||||
long n;
|
||||
unsigned int *tlv, tlv_size;
|
||||
unsigned int tlv_header_size = 0;
|
||||
|
||||
buf = calloc(1, num_values);
|
||||
if (mixer_ctl_is_access_tlv_rw(ctl) != 0) {
|
||||
tlv_header_size = TLV_HEADER_SIZE;
|
||||
}
|
||||
|
||||
tlv_size = num_values + tlv_header_size;
|
||||
|
||||
buf = calloc(1, tlv_size);
|
||||
if (buf == NULL) {
|
||||
fprintf(stderr, "set_byte_ctl: Failed to alloc mem for bytes %u\n", num_values);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
tlv = (unsigned int *)buf;
|
||||
tlv[0] = 0;
|
||||
tlv[1] = num_values;
|
||||
|
||||
for (i = 0; i < num_values; i++) {
|
||||
errno = 0;
|
||||
n = strtol(values[i], &end, 0);
|
||||
@@ -286,10 +303,11 @@ static void tinymix_set_byte_ctl(struct mixer_ctl *ctl,
|
||||
values[i]);
|
||||
goto fail;
|
||||
}
|
||||
buf[i] = n;
|
||||
/* start filling after tlv header */
|
||||
buf[i + tlv_header_size] = n;
|
||||
}
|
||||
|
||||
ret = mixer_ctl_set_array(ctl, buf, num_values);
|
||||
ret = mixer_ctl_set_array(ctl, buf, tlv_size);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to set binary control\n");
|
||||
goto fail;
|
||||
|
||||
Reference in New Issue
Block a user