⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alsamixer.c

📁 ALSA驱动的一些调试测试工具
💻 C
📖 第 1 页 / 共 5 页
字号:
static intmixer_conv(int val, int omin, int omax, int nmin, int nmax){	float orange = omax - omin, nrange = nmax - nmin;		if (orange == 0)		return 0;	return ((nrange * (val - omin)) + (orange / 2)) / orange + nmin;}static intmixer_calc_volume(snd_mixer_elem_t *elem,		  int vol, int type,		  snd_mixer_selem_channel_id_t chn){  int vol1;  long v;  long min, max;  if (type != MIXER_ELEM_CAPTURE)    snd_mixer_selem_get_playback_volume_range(elem, &min, &max);  else    snd_mixer_selem_get_capture_volume_range(elem, &min, &max);  vol1 = (vol < 0) ? -vol : vol;  if (vol1 > 0) {    if (vol1 > 100)      vol1 = max;    else      vol1 = mixer_conv(vol1, 0, 100, min, max);    /* Note: we have delta in vol1 and we need to map our */    /*       delta value to hardware range */    vol1 -= min;    if (vol1 <= 0)      vol1 = 1;    if (vol < 0)      vol1 = -vol1;  }  if (type != MIXER_ELEM_CAPTURE)    snd_mixer_selem_get_playback_volume(elem, chn, &v);  else    snd_mixer_selem_get_capture_volume(elem, chn, &v);  vol1 += v;  return CLAMP(vol1, min, max);}static intmixer_convert_volume(snd_mixer_elem_t *elem,		  int vol, int type){  long min, max;  if (type != MIXER_ELEM_CAPTURE)    snd_mixer_selem_get_playback_volume_range(elem, &min, &max);  else    snd_mixer_selem_get_capture_volume_range(elem, &min, &max);  return  mixer_conv(vol, 0, 100, min, max);}/* update enum list */static void update_enum_list(snd_mixer_elem_t *elem, int chn, int delta){  unsigned int eidx;  if (snd_mixer_selem_get_enum_item(elem, chn, &eidx) < 0)    return;  if (delta < 0) {    if (eidx == 0)      return;    eidx--;  } else {    int items = snd_mixer_selem_get_enum_items(elem);    if (items < 0)      return;    eidx++;    if (eidx >= items)      return;  }  snd_mixer_selem_set_enum_item(elem, chn, eidx);}/* set new channel values */static voidmixer_write_cbar (int elem_index){  snd_mixer_elem_t *elem;  int vleft, vright, vbalance;  int type;  snd_mixer_selem_id_t *sid;  snd_mixer_selem_channel_id_t chn_left, chn_right, chn;  int sw;  if (mixer_sid == NULL)    return;  sid = (snd_mixer_selem_id_t *)(((char *)mixer_sid) + snd_mixer_selem_id_sizeof() * mixer_grpidx[elem_index]);  elem = snd_mixer_find_selem(mixer_handle, sid);  if (elem == NULL)    CHECK_ABORT (ERR_FCN, "snd_mixer_find_selem()", -EINVAL);  type = mixer_type[elem_index] & MIXER_ELEM_TYPE_MASK;  chn_left = mixer_elem_chn[type][MIXER_CHN_LEFT];  chn_right = mixer_elem_chn[type][MIXER_CHN_RIGHT];  if (chn_right != SND_MIXER_SCHN_UNKNOWN) {    if (type != MIXER_ELEM_CAPTURE) {      if (!snd_mixer_selem_has_playback_channel(elem, chn_right))	chn_right = SND_MIXER_SCHN_UNKNOWN;    } else {      if (!snd_mixer_selem_has_capture_channel(elem, chn_right))	chn_right = SND_MIXER_SCHN_UNKNOWN;    }  }  /* volume   */  if ((mixer_volume_delta[MIXER_CHN_LEFT] ||       mixer_volume_delta[MIXER_CHN_RIGHT] ||       mixer_volume_absolute != -1 ||       mixer_balance_volumes) &&      (mixer_type[elem_index] & MIXER_ELEM_HAS_VOLUME)) {    int mono;    int joined;    mono = (chn_right == SND_MIXER_SCHN_UNKNOWN);    if (type != MIXER_ELEM_CAPTURE)      joined = snd_mixer_selem_has_playback_volume_joined(elem);    else      joined = snd_mixer_selem_has_capture_volume_joined(elem);    mono |= joined;    if (mixer_volume_absolute != -1) {      vbalance = vright = vleft = mixer_convert_volume(elem, mixer_volume_absolute, type);    } else {      if (mono && !mixer_volume_delta[MIXER_CHN_LEFT])        mixer_volume_delta[MIXER_CHN_LEFT] = mixer_volume_delta[MIXER_CHN_RIGHT];      vleft = mixer_calc_volume(elem, mixer_volume_delta[MIXER_CHN_LEFT], type, chn_left);      vbalance = vleft;      if (! mono) {        vright = mixer_calc_volume(elem, mixer_volume_delta[MIXER_CHN_RIGHT], type, chn_right);        vbalance += vright;        vbalance /= 2;      } else {        vright = vleft;      }    }      if (joined) {	for (chn = 0; chn < SND_MIXER_SCHN_LAST; chn++)	  if (type != MIXER_ELEM_CAPTURE) {	    if (snd_mixer_selem_has_playback_channel(elem, chn))	      snd_mixer_selem_set_playback_volume(elem, chn, vleft);	  } else {	    if (snd_mixer_selem_has_capture_channel(elem, chn))	      snd_mixer_selem_set_capture_volume(elem, chn, vleft);	  }      } else {	if (mixer_balance_volumes)	  vleft = vright = vbalance;	if (type != MIXER_ELEM_CAPTURE) {	  if (snd_mixer_selem_has_playback_volume(elem) &&	      snd_mixer_selem_has_playback_channel(elem, chn_left))	    snd_mixer_selem_set_playback_volume(elem, chn_left, vleft);	} else {	  if (snd_mixer_selem_has_capture_volume(elem) &&	      snd_mixer_selem_has_capture_channel(elem, chn_left))	    snd_mixer_selem_set_capture_volume(elem, chn_left, vleft);	}	if (! mono) {	  if (type != MIXER_ELEM_CAPTURE) {	    if (snd_mixer_selem_has_playback_volume(elem) &&		snd_mixer_selem_has_playback_channel(elem, chn_right))	      snd_mixer_selem_set_playback_volume(elem, chn_right, vright);	  } else {	    if (snd_mixer_selem_has_capture_volume(elem) &&		snd_mixer_selem_has_capture_channel(elem, chn_right))	      snd_mixer_selem_set_capture_volume(elem, chn_right, vright);	  }	}      }  }  /* mute   */  if (mixer_type[elem_index] & MIXER_ELEM_MUTE_SWITCH) {    if (mixer_toggle_mute) {      if (snd_mixer_selem_has_playback_switch_joined(elem)) {	snd_mixer_selem_get_playback_switch(elem, chn_left, &sw);	snd_mixer_selem_set_playback_switch_all(elem, !sw);      } else {	if (mixer_toggle_mute & MIXER_MASK_LEFT) {	  snd_mixer_selem_get_playback_switch(elem, chn_left, &sw);	  snd_mixer_selem_set_playback_switch(elem, chn_left, !sw);	}	if (chn_right != SND_MIXER_SCHN_UNKNOWN && 	    (mixer_toggle_mute & MIXER_MASK_RIGHT)) {	  snd_mixer_selem_get_playback_switch(elem, chn_right, &sw);	  snd_mixer_selem_set_playback_switch(elem, chn_right, !sw);	}      }    }  }  mixer_toggle_mute = 0;  /* capture   */  if (mixer_type[elem_index] & MIXER_ELEM_CAPTURE_SWITCH) {    if (mixer_toggle_capture && snd_mixer_selem_has_capture_switch(elem)) {      if (snd_mixer_selem_has_capture_switch_joined(elem)) {	snd_mixer_selem_get_capture_switch(elem, chn_left, &sw);	snd_mixer_selem_set_capture_switch_all(elem, !sw);      } else {	if ((mixer_toggle_capture & MIXER_MASK_LEFT) &&	    snd_mixer_selem_has_capture_channel(elem, chn_left)) {	  snd_mixer_selem_get_capture_switch(elem, chn_left, &sw);	  snd_mixer_selem_set_capture_switch(elem, chn_left, !sw);	}	if (chn_right != SND_MIXER_SCHN_UNKNOWN && 	    snd_mixer_selem_has_capture_channel(elem, chn_right) &&	    (mixer_toggle_capture & MIXER_MASK_RIGHT)) {	  snd_mixer_selem_get_capture_switch(elem, chn_right, &sw);	  snd_mixer_selem_set_capture_switch(elem, chn_right, !sw);	}      }    }  }  mixer_toggle_capture = 0;  /* enum list   */  if (type == MIXER_ELEM_ENUM || type == MIXER_ELEM_CAPTURE_ENUM) {    if (mixer_volume_delta[MIXER_CHN_LEFT])      update_enum_list(elem, MIXER_CHN_LEFT, mixer_volume_delta[MIXER_CHN_LEFT]);    if (mixer_volume_delta[MIXER_CHN_RIGHT])      update_enum_list(elem, MIXER_CHN_RIGHT, mixer_volume_delta[MIXER_CHN_RIGHT]);  }  mixer_volume_delta[MIXER_CHN_LEFT] = mixer_volume_delta[MIXER_CHN_RIGHT] = 0;  mixer_volume_absolute = -1;  mixer_balance_volumes = 0;}static void draw_blank(int x, int y, int lines){  int i;  mixer_dc (DC_TEXT);  for (i = 0; i < lines; i++)    mvaddstr (y - i, x, "         ");}/* show the current view mode */static void display_view_info(void){  mixer_dc (DC_PROMPT);  mvaddstr (3, 2, "View:  Playback  Capture  All ");  mixer_dc (DC_TEXT);  switch (mixer_view) {  case VIEW_PLAYBACK:    mvaddstr (3, 8, "[Playback]");    break;  case VIEW_CAPTURE:    mvaddstr (3, 18, "[Capture]");    break;  default:    mvaddstr (3, 27, "[All]");    break;  }}/* show the information of the focused item */static void display_item_info(int elem_index, snd_mixer_selem_id_t *sid, char *extra_info){  char string[64], idxstr[10];  int idx;  int i, xlen = mixer_max_x - 8;  if (xlen > sizeof(string) - 1)    xlen = sizeof(string) - 1;  mixer_dc (DC_PROMPT);  mvaddstr (4, 2, "Item: ");  mixer_dc (DC_TEXT);  idx = snd_mixer_selem_id_get_index(sid);  if (idx > 0)    snprintf(idxstr, sizeof(idxstr), " %i", snd_mixer_selem_id_get_index(sid));  snprintf(string, sizeof(string), "%s%s%s%s",	   snd_mixer_selem_id_get_name(sid),	   (mixer_type[elem_index] & MIXER_ELEM_CAPTURE_SUFFIX) ? " Capture" : "",	   idx > 0 ? idxstr : "",	   extra_info);  for (i = strlen(string); i < sizeof(string) - 1; i++)    string[i] = ' ';  string[xlen] = '\0';  addstr(string);}/* show the bar item name */static void display_item_name(int x, int y, int elem_index, snd_mixer_selem_id_t *sid){  const char *suffix;  char string1[9], string[9];  int i;  mixer_dc (elem_index == mixer_focus_elem ? DC_CBAR_FOCUS_LABEL : DC_CBAR_LABEL);  if (mixer_type[elem_index] & MIXER_ELEM_CAPTURE_SUFFIX)    suffix = " Capture";  else    suffix = "";  if (snd_mixer_selem_id_get_index(sid) > 0)    snprintf(string1, sizeof(string1), "%s%s %d", snd_mixer_selem_id_get_name(sid),	     suffix, snd_mixer_selem_id_get_index(sid));  else    snprintf(string1, sizeof(string1), "%s%s", snd_mixer_selem_id_get_name(sid), suffix);  string[8] = 0;  for (i = 0; i < 8; i++)    string[i] = ' ';  memcpy(string + (8 - strlen (string1)) / 2, string1, strlen(string1));  mvaddstr (y, x, string);}static void display_enum_list(snd_mixer_elem_t *elem, int y, int x){  int cury, ch, err;  draw_blank(x, y, mixer_cbar_height + (mixer_view == VIEW_PLAYBACK ? 5 : 6));    cury = y - 4;  for (ch = 0; ch < 2; ch++) {    unsigned int eidx, ofs;    char tmp[9];    err = snd_mixer_selem_get_enum_item(elem, ch, &eidx);    if (err < 0)      break;    if (snd_mixer_selem_get_enum_item_name(elem, eidx, sizeof(tmp) - 1, tmp) < 0)      break;    tmp[8] = 0;    ofs = (8 - strlen(tmp)) / 2;    mvaddstr(cury, x + ofs, tmp);    cury += 2;  }}static void draw_volume_bar(int x, int y, int elem_index, long vleft, long vright){  int i, dc;  mixer_dc (DC_CBAR_FRAME);  if (mixer_type[elem_index] & MIXER_ELEM_MUTE_SWITCH) {    mvaddch (y, x + 2, ACS_LTEE);    mvaddch (y, x + 5, ACS_RTEE);  } else {    mvaddch (y, x + 2, ACS_LLCORNER);    mvaddch (y, x + 3, ACS_HLINE);    mvaddch (y, x + 4, ACS_HLINE);    mvaddch (y, x + 5, ACS_LRCORNER);  }  y--;  for (i = 0; i < mixer_cbar_height; i++)    {      mvaddstr (y - i, x, "         ");      mvaddch (y - i, x + 2, ACS_VLINE);      mvaddch (y - i, x + 5, ACS_VLINE);    }  for (i = 0; i < mixer_cbar_height; i++)    {      if (i + 1 >= 0.8 * mixer_cbar_height)	dc = DC_ANY_3;      else if (i + 1 >= 0.4 * mixer_cbar_height)	dc = DC_ANY_2;      else	dc = DC_ANY_1;      mvaddch (y, x + 3, mixer_dc (vleft > i * 100 / mixer_cbar_height ? dc : DC_CBAR_EMPTY));	mvaddch (y, x + 4, mixer_dc (vright > i * 100 / mixer_cbar_height ? dc : DC_CBAR_EMPTY));	y--;      }    mixer_dc (DC_CBAR_FRAME);  mvaddstr (y, x, "         ");  mvaddch (y, x + 2, ACS_ULCORNER);  mvaddch (y, x + 3, ACS_HLINE);  mvaddch (y, x + 4, ACS_HLINE);  mvaddch (y, x + 5, ACS_URCORNER);}static void draw_playback_switch(int x, int y, int elem_index, int swl, int swr){  int dc;  mixer_dc (DC_CBAR_FRAME);  mvaddch (y, x + 2, ACS_LLCORNER);  mvaddch (y, x + 3, ACS_HLINE);  mvaddch (y, x + 4, ACS_HLINE);  mvaddch (y, x + 5, ACS_LRCORNER);  mvaddstr (y - 1, x, "         ");  mvaddch (y - 1, x + 2, ACS_VLINE);  mvaddch (y - 1, x + 5, ACS_VLINE);  mvaddstr (y - 2, x, "         ");  mvaddch (y - 2, x + 2, ACS_ULCORNER);  mvaddch (y - 2, x + 3, ACS_HLINE);  mvaddch (y - 2, x + 4, ACS_HLINE);  mvaddch (y - 2, x + 5, ACS_URCORNER);  dc = swl ? DC_CBAR_NOMUTE : DC_CBAR_MUTE;  mvaddch (y - 1, x + 3, mixer_dc (dc));  dc = swr ? DC_CBAR_NOMUTE : DC_CBAR_MUTE;  mvaddch (y - 1, x + 4, mixer_dc (dc));}static void draw_capture_switch(int x, int y, int elem_index, int swl, int swr){  int i;  if (swl || swr) {    mixer_dc (DC_CBAR_CAPTURE);    mvaddstr (y, x + 1, "CAPTUR");  } else {    for (i = 0; i < 6; i++)      mvaddch(y, x + i + 1, mixer_dc(DC_CBAR_NOCAPTURE));  }  mixer_dc (DC_CBAR_CAPTURE);  mvaddch (y - 1, x + 1, swl ? 'L' : ' ');  mvaddch (y - 1, x + 6, swr ? 'R' : ' ');}#ifndef SND_CTL_TLV_DB_GAIN_MUTE#define SND_CTL_TLV_DB_GAIN_MUTE	-9999999#endifstatic void dB_value(char *s, long val){	if (val <= SND_CTL_TLV_DB_GAIN_MUTE)		strcpy(s, "mute");	else		snprintf(s, 10, "%3.2f", (float)val / 100);}			static voidmixer_update_cbar (int elem_index){  snd_mixer_elem_t *elem;  long vleft, vright;  int type;  snd_mixer_selem_id_t *sid;  snd_mixer_selem_channel_id_t chn_left, chn_right;  int x, y;  int swl, swr;  char * extra_info;  /* set new scontrol indices and read info   */  if (mixer_sid == NULL)    return;  sid = (snd_mixer_selem_id_t *)(((char *)mixer_sid) + snd_mixer_selem_id_sizeof() * mixer_grpidx[elem_index]);  elem = snd_mixer_find_selem(mixer_handle, sid);  if (elem == NULL)    CHECK_ABORT (ERR_FCN, "snd_mixer_find_selem()", -EINVAL);  type = mixer_type[elem_index] & MIXER_ELEM_TYPE_MASK;  chn_left = mixer_elem_chn[type][MIXER_CHN_LEFT];  chn_right = mixer_elem_chn[type][MIXER_CHN_RIGHT];  if (chn_right != SND_MIXER_SCHN_UNKNOWN) {    if (type != MIXER_ELEM_CAPTURE) {      if (!snd_mixer_selem_has_playback_channel(elem, chn_right))	chn_right = SND_MIXER_SCHN_UNKNOWN;    } else {      if (!snd_mixer_selem_has_capture_channel(elem, chn_right))	chn_right = SND_MIXER_SCHN_UNKNOWN;    }  }  vleft = vright = 0;  if (type != MIXER_ELEM_CAPTURE && snd_mixer_selem_has_playback_volume(elem)) {    long vmin, vmax;    snd_mixer_selem_get_playback_volume_range(elem, &vmin, &vmax);    snd_mixer_selem_get_playback_volume(elem, chn_left, &vleft);    vleft = mixer_conv(vleft, vmin, vmax, 0, 100);    if (chn_right != SND_MIXER_SCHN_UNKNOWN) {      snd_mixer_selem_get_playback_volume(elem, chn_right, &vright);      vright = mixer_conv(vright, vmin, vmax, 0, 100);    } else {      vright = vleft;    }  }  if (type == MIXER_ELEM_CAPTURE && snd_mixer_selem_has_capture_volume(elem)) {    long vmin, vmax;    snd_mixer_selem_get_capture_volume_range(elem, &vmin, &vmax);    snd_mixer_selem_get_capture_volume(elem, chn_left, &vleft);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -