void printvec_dB(vec4_d64 v) { print_dB(v.m256d_f64[0]); printf(" "); print_dB(v.m256d_f64[1]); printf(" "); print_dB(v.m256d_f64[2]); printf(" "); print_dB(v.m256d_f64[3]); }
static int set_volume_simple(struct mixer_ctl *ctl, char **ptr, long pmin, long pmax, int count) { long val, orig; char *p = *ptr, *s; struct snd_ctl_elem_value ev; unsigned n; if (*p == ':') p++; if (*p == '\0' || (!isdigit(*p) && *p != '-')) goto skip; s = p; val = strtol(s, &p, 10); if (*p == '.') { p++; strtol(p, &p, 10); } if (*p == '%') { val = (long)percent_to_index(strtod(s, NULL), pmin, pmax); p++; } else if (p[0] == 'd' && p[1] == 'B') { val = (long)(strtod(s, NULL) * 100.0); p += 2; } else { if (pmin < 0) { pmax = pmax - pmin; pmin = 0; } } val = check_range(val, pmin, pmax); ALOGV("val = %x", val); if (!ctl) { ALOGV("can't find control\n"); return -EPERM; } if (count < ctl->info->count || count > ctl->info->count) return -EINVAL; ALOGV("Value = "); memset(&ev, 0, sizeof(ev)); ev.id.numid = ctl->info->id.numid; switch (ctl->info->type) { case SNDRV_CTL_ELEM_TYPE_BOOLEAN: for (n = 0; n < ctl->info->count; n++) ev.value.integer.value[n] = !!val; print_dB(val); break; case SNDRV_CTL_ELEM_TYPE_INTEGER: { for (n = 0; n < ctl->info->count; n++) ev.value.integer.value[n] = val; print_dB(val); break; } case SNDRV_CTL_ELEM_TYPE_INTEGER64: { for (n = 0; n < ctl->info->count; n++) { long long value_ll = scale_int64(ctl->info, val); print_dB(value_ll); ev.value.integer64.value[n] = value_ll; } break; } default: errno = EINVAL; return errno; } ALOGV("\n"); return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev); skip: if (*p == ',') p++; *ptr = p; return 0; }
int mixer_ctl_read_tlv(struct mixer_ctl *ctl, unsigned int *tlv, long *min, long *max, unsigned int *tlv_type) { unsigned int tlv_size = DEFAULT_TLV_SIZE; unsigned int type; unsigned int size; if(!!(ctl->info->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ)) { struct snd_ctl_tlv *xtlv; tlv[0] = -1; tlv[1] = 0; xtlv = calloc(1, sizeof(struct snd_ctl_tlv) + tlv_size); if (xtlv == NULL) return -ENOMEM; xtlv->numid = ctl->info->id.numid; xtlv->length = tlv_size; memcpy(xtlv->tlv, tlv, tlv_size); if (ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_TLV_READ, xtlv) < 0) { fprintf( stderr, "SNDRV_CTL_IOCTL_TLV_READ failed\n"); free(xtlv); return -errno; } if (xtlv->tlv[1] + 2 * sizeof(unsigned int) > tlv_size) { free(xtlv); return -EFAULT; } memcpy(tlv, xtlv->tlv, xtlv->tlv[1] + 2 * sizeof(unsigned int)); free(xtlv); type = tlv[0]; *tlv_type = type; size = tlv[1]; switch (type) { case SNDRV_CTL_TLVT_DB_SCALE: { int idx = 2; int step; ALOGV("dBscale-"); if (size != 2 * sizeof(unsigned int)) { while (size > 0) { ALOGV("0x%08x,", tlv[idx++]); size -= sizeof(unsigned int); } } else { ALOGV(" min="); print_dB((int)tlv[2]); *min = (long)tlv[2]; ALOGV(" step="); step = (tlv[3] & 0xffff); print_dB(tlv[3] & 0xffff); ALOGV(" max="); *max = (ctl->info->value.integer.max); print_dB((long)ctl->info->value.integer.max); ALOGV(" mute=%i\n", (tlv[3] >> 16) & 1); } break; } case SNDRV_CTL_TLVT_DB_MINMAX: case SNDRV_CTL_TLVT_DB_LINEAR: { int idx = 2; ALOGV("dBLiner-/dbminmax"); if (size != 2 * sizeof(unsigned int)) { while (size > 0) { ALOGV("0x%08x,", tlv[idx++]); size -= sizeof(unsigned int); } } else { ALOGV(" min="); *min = tlv[2]; print_dB(tlv[2]); ALOGV(" max="); *max = tlv[3]; print_dB(tlv[3]); } break; } default: break; } return 0; } return -EINVAL; }
static void decode_tlv(unsigned int spaces, unsigned int *tlv, unsigned int tlv_size) { unsigned int type = tlv[0]; unsigned int size; unsigned int idx = 0; if (tlv_size < 2 * sizeof(unsigned int)) { printf("TLV size error!\n"); return; } print_spaces(spaces); printf("| "); type = tlv[idx++]; size = tlv[idx++]; tlv_size -= 2 * sizeof(unsigned int); if (size > tlv_size) { printf("TLV size error (%i, %i, %i)!\n", type, size, tlv_size); return; } switch (type) { case SND_CTL_TLVT_CONTAINER: size += sizeof(unsigned int) - 1; size /= sizeof(unsigned int); while (idx < size) { if (tlv[idx + 1] > (size - idx) * sizeof(unsigned int)) { printf("TLV size error in compound!\n"); return; } decode_tlv(spaces + 2, tlv + idx, tlv[idx + 1]); idx += 2 + (tlv[1] + sizeof(unsigned int) - 1) / sizeof(unsigned int); } break; case SND_CTL_TLVT_DB_SCALE: printf("dBscale-"); if (size != 2 * sizeof(unsigned int)) { while (size > 0) { printf("0x%08x,", tlv[idx++]); size -= sizeof(unsigned int); } } else { printf("min="); print_dB((int)tlv[2]); printf(",step="); print_dB(tlv[3] & 0xffff); printf(",mute=%i", (tlv[3] >> 16) & 1); } break; #ifdef SND_CTL_TLVT_DB_LINEAR case SND_CTL_TLVT_DB_LINEAR: printf("dBlinear-"); if (size != 2 * sizeof(unsigned int)) { while (size > 0) { printf("0x%08x,", tlv[idx++]); size -= sizeof(unsigned int); } } else { printf("min="); print_dB(tlv[2]); printf(",max="); print_dB(tlv[3]); } break; #endif #ifdef SND_CTL_TLVT_DB_RANGE case SND_CTL_TLVT_DB_RANGE: printf("dBrange-\n"); if ((size % (6 * sizeof(unsigned int))) != 0) { while (size > 0) { printf("0x%08x,", tlv[idx++]); size -= sizeof(unsigned int); } break; } while (size > 0) { print_spaces(spaces + 2); printf("rangemin=%i,", tlv[idx++]); printf(",rangemax=%i\n", tlv[idx++]); decode_tlv(spaces + 4, tlv + idx, 4 * sizeof(unsigned int)); idx += 4; size -= 6 * sizeof(unsigned int); } break; #endif #ifdef SND_CTL_TLVT_DB_MINMAX case SND_CTL_TLVT_DB_MINMAX: case SND_CTL_TLVT_DB_MINMAX_MUTE: if (type == SND_CTL_TLVT_DB_MINMAX_MUTE) printf("dBminmaxmute-"); else printf("dBminmax-"); if (size != 2 * sizeof(unsigned int)) { while (size > 0) { printf("0x%08x,", tlv[idx++]); size -= sizeof(unsigned int); } } else { printf("min="); print_dB(tlv[2]); printf(",max="); print_dB(tlv[3]); } break; #endif default: printf("unk-%i-", type); while (size > 0) { printf("0x%08x,", tlv[idx++]); size -= sizeof(unsigned int); } break; } putc('\n', stdout); }