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

📄 alsamixer.c

📁 ALSA驱动的一些调试测试工具
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (block == '#' && ACS_BOARD == '#')    {      block = stipple;      stipple = ACS_BLOCK;    }  /* lower scroll border   */  l = x2 - x1 - 1;  n = hscroll * l;  r = (hoffs + 1.0 / (2 * (l - n - 1))) * (l - n - 1);  for (i = 0; i < l; i++)    mvaddch (y2, i + x1 + 1, hscroll >= 1 ? ACS_HLINE :	     i >= r && i <= r + n ? block : stipple);  /* right scroll border   */  l = y2 - y1 - 1;  n = vscroll * l;  r = (voffs + 1.0 / (2 * (l - n - 1))) * (l - n - 1);  for (i = 0; i < l; i++)    mvaddch (i + y1 + 1, x2, vscroll >= 1 ? ACS_VLINE :	     i >= r && i <= r + n ? block : stipple);  /* show text   */  x1++; y1++;  for (i = 0; i < *yoffs; i++)    {      l = 0;      mixer_offset_text (&text_offs, 0, &l);    }  for (i = y1; i < y2; i++)    {      l = x2 - x1;      p = mixer_offset_text (&text_offs, *xoffs, &l);      n = x1;      while (l--)	mvaddch (i, n++, *p++);      while (n < x2)	mvaddch (i, n++, ' ');    }}struct vbuffer{  char *buffer;  int size;  int len;};static voidvbuffer_kill (struct vbuffer *vbuf){  if (vbuf->size)    free (vbuf->buffer);  vbuf->buffer = NULL;  vbuf->size = 0;  vbuf->len = 0;}#define vbuffer_append_string(vb,str)	vbuffer_append (vb, str, strlen (str))static voidvbuffer_append (struct vbuffer *vbuf,		char           *text,		int             len){  if (vbuf->size - vbuf->len <= len)    {      vbuf->size += len + 1;      vbuf->buffer = realloc (vbuf->buffer, vbuf->size);    }  memcpy (vbuf->buffer + vbuf->len, text, len);  vbuf->len += len;  vbuf->buffer[vbuf->len] = 0;}static intvbuffer_append_file (struct vbuffer *vbuf,		     char	    *name){  int fd;  fd = open (name, O_RDONLY);  if (fd >= 0)    {      char buffer[1025];      int l;      do	{	  l = read (fd, buffer, 1024);	  	  vbuffer_append (vbuf, buffer, MAX (0, l));	}      while (l > 0 || (l < 0 && (errno == EAGAIN || errno == EINTR)));      close (fd);      return 0;    }  else    return 1;}static voidmixer_show_procinfo (void){  struct vbuffer vbuf = { NULL, 0, 0 };  vbuffer_append_string (&vbuf, "\n");  vbuffer_append_string (&vbuf, "/proc/asound/version:\n");  vbuffer_append_string (&vbuf, "====================\n");  if (vbuffer_append_file (&vbuf, "/proc/asound/version"))    {      vbuffer_kill (&vbuf);      mixer_procinfo_xoffs = mixer_procinfo_yoffs = 0;      mixer_show_text ("/proc",		       " No /proc information available. ",		       &mixer_procinfo_xoffs, &mixer_procinfo_yoffs);      return;    }  else    vbuffer_append_file (&vbuf, "/proc/asound/meminfo");  vbuffer_append_string (&vbuf, "\n");  vbuffer_append_string (&vbuf, "/proc/asound/cards:\n");  vbuffer_append_string (&vbuf, "===================\n");  if (vbuffer_append_file (&vbuf, "/proc/asound/cards"))    vbuffer_append_string (&vbuf, "No information available.\n");  vbuffer_append_string (&vbuf, "\n");  vbuffer_append_string (&vbuf, "/proc/asound/devices:\n");  vbuffer_append_string (&vbuf, "=====================\n");  if (vbuffer_append_file (&vbuf, "/proc/asound/devices"))    vbuffer_append_string (&vbuf, "No information available.\n");  vbuffer_append_string (&vbuf, "\n");  vbuffer_append_string (&vbuf, "/proc/asound/oss/devices:\n");  vbuffer_append_string (&vbuf, "=========================\n");  if (vbuffer_append_file (&vbuf, "/proc/asound/oss/devices"))    vbuffer_append_string (&vbuf, "No information available.\n");  vbuffer_append_string (&vbuf, "\n");  vbuffer_append_string (&vbuf, "/proc/asound/timers:\n");  vbuffer_append_string (&vbuf, "====================\n");  if (vbuffer_append_file (&vbuf, "/proc/asound/timers"))    vbuffer_append_string (&vbuf, "No information available.\n");  vbuffer_append_string (&vbuf, "\n");  vbuffer_append_string (&vbuf, "/proc/asound/pcm:\n");  vbuffer_append_string (&vbuf, "=================\n");  if (vbuffer_append_file (&vbuf, "/proc/asound/pcm"))    vbuffer_append_string (&vbuf, "No information available.\n");  mixer_show_text ("/proc", vbuf.buffer,		   &mixer_procinfo_xoffs, &mixer_procinfo_yoffs);  vbuffer_kill (&vbuf);}static intmixer_event (snd_mixer_t *mixer, unsigned int mask, snd_mixer_elem_t *elem){  mixer_changed_state = 1;  return 0;}static voidmixer_init (void){  snd_ctl_card_info_t *hw_info;  snd_ctl_t *ctl_handle;  int err;  snd_ctl_card_info_alloca(&hw_info);    if ((err = snd_ctl_open (&ctl_handle, card_id, 0)) < 0)    mixer_abort (ERR_OPEN, "snd_ctl_open", err);  if ((err = snd_ctl_card_info (ctl_handle, hw_info)) < 0)    mixer_abort (ERR_FCN, "snd_ctl_card_info", err);  snd_ctl_close (ctl_handle);  /* open mixer device   */  if ((err = snd_mixer_open (&mixer_handle, 0)) < 0)    mixer_abort (ERR_FCN, "snd_mixer_open", err);  if (mixer_level == 0 && (err = snd_mixer_attach (mixer_handle, card_id)) < 0)    mixer_abort (ERR_FCN, "snd_mixer_attach", err);  if ((err = snd_mixer_selem_register (mixer_handle, mixer_level > 0 ? &mixer_options : NULL, NULL)) < 0)    mixer_abort (ERR_FCN, "snd_mixer_selem_register", err);  snd_mixer_set_callback (mixer_handle, mixer_event);  if ((err = snd_mixer_load (mixer_handle)) < 0)    mixer_abort (ERR_FCN, "snd_mixer_load", err);    /* setup global variables   */  strcpy(mixer_card_name, snd_ctl_card_info_get_name(hw_info));  strcpy(mixer_device_name, snd_ctl_card_info_get_mixername(hw_info));}/* init mixer screen */static voidrecalc_screen_size (void){  getmaxyx (mixer_window, mixer_max_y, mixer_max_x);  if (mixer_minimize)    {      mixer_max_x = MIXER_MIN_X;      mixer_max_y = MIXER_MIN_Y;    }  mixer_ofs_x = 2 /* extra begin padding: */ + 1;  /* required allocations */  mixer_n_vis_elems = (mixer_max_x - mixer_ofs_x * 2 + 1) / 9;  mixer_n_vis_elems = CLAMP (mixer_n_vis_elems, 1, mixer_n_view_elems);  mixer_extra_space = mixer_max_x - mixer_ofs_x * 2 + 1 - mixer_n_vis_elems * 9;  mixer_extra_space = MAX (0, mixer_extra_space / (mixer_n_vis_elems + 1));  mixer_text_y = MIXER_TEXT_Y;  if (mixer_view == VIEW_PLAYBACK || mixer_view == VIEW_CHANNELS)    mixer_text_y += 2; /* row for mute switch */  if (mixer_view == VIEW_CAPTURE || mixer_view == VIEW_CHANNELS)    mixer_text_y++; /* row for capture switch */  if (mixer_text_y + MIXER_CBAR_STD_HGT < mixer_max_y)    mixer_cbar_height = MIXER_CBAR_STD_HGT + MAX (1, mixer_max_y - mixer_text_y - MIXER_CBAR_STD_HGT + 1) / 2;  else    mixer_cbar_height = MAX (1, mixer_max_y - mixer_text_y);}static voidmixer_reinit (void){  snd_mixer_elem_t *elem;  int idx, elem_index, i, j, selem_count;  snd_mixer_selem_id_t *sid;  snd_mixer_selem_id_t *focus_gid;  int focus_type = -1;  snd_mixer_selem_id_alloca(&focus_gid);    if (!mixer_changed_state)    return;  if (mixer_sid) {    snd_mixer_selem_id_copy(focus_gid, (snd_mixer_selem_id_t *)(((char *)mixer_sid) + snd_mixer_selem_id_sizeof() * mixer_grpidx[mixer_focus_elem]));    focus_type = mixer_type[mixer_focus_elem] & MIXER_ELEM_TYPE_MASK;  }__again:  mixer_changed_state = 0;  if (mixer_sid != NULL)    free(mixer_sid);  selem_count = snd_mixer_get_count(mixer_handle);  mixer_sid = malloc(snd_mixer_selem_id_sizeof() * selem_count);  if (mixer_sid == NULL)    mixer_abort (ERR_FCN, "malloc", 0);    mixer_n_selems = 0;  for (elem = snd_mixer_first_elem(mixer_handle); elem; elem = snd_mixer_elem_next(elem)) {    sid = (snd_mixer_selem_id_t *)(((char *)mixer_sid) + snd_mixer_selem_id_sizeof() * mixer_n_selems);    if (mixer_changed_state)      goto __again;    if (!snd_mixer_selem_is_active(elem))      continue;    snd_mixer_selem_get_id(elem, sid);    mixer_n_selems++;  }  mixer_n_elems = 0;  for (idx = 0; idx < mixer_n_selems; idx++) {    int nelems_added = 0;    sid = (snd_mixer_selem_id_t *)(((char *)mixer_sid) + snd_mixer_selem_id_sizeof() * idx);    if (mixer_changed_state)      goto __again;    elem = snd_mixer_find_selem(mixer_handle, sid);    if (elem == NULL)      CHECK_ABORT (ERR_FCN, "snd_mixer_find_selem()", -EINVAL);    for (i = 0; i < MIXER_ELEM_CAPTURE; i++) {      int ok;      for (j = ok = 0; j < 2; j++) {	if (mixer_changed_state)	  goto __again;	if (snd_mixer_selem_has_playback_channel(elem, mixer_elem_chn[i][j]))	  ok++;      }      if (ok) {	nelems_added++;	mixer_n_elems++;      }    }    if (snd_mixer_selem_has_capture_volume(elem) ||	(nelems_added == 0 && snd_mixer_selem_has_capture_switch(elem)))      mixer_n_elems++;  }  if (mixer_type)    free(mixer_type);  mixer_type = (int *)calloc(mixer_n_elems, sizeof(int));  if (mixer_type == NULL)    mixer_abort(ERR_FCN, "malloc", 0);  if (mixer_grpidx)    free(mixer_grpidx);  mixer_grpidx = (int *)calloc(mixer_n_elems, sizeof(int));  if (mixer_grpidx == NULL)    mixer_abort(ERR_FCN, "malloc", 0);  elem_index = 0;  for (idx = 0; idx < mixer_n_selems; idx++) {    int nelems_added = 0;    sid = (snd_mixer_selem_id_t *)(((char *)mixer_sid) + snd_mixer_selem_id_sizeof() * idx);    if (mixer_changed_state)      goto __again;    elem = snd_mixer_find_selem(mixer_handle, sid);    if (elem == NULL)      CHECK_ABORT (ERR_FCN, "snd_mixer_find_selem()", -EINVAL);    if ( (mixer_view == VIEW_PLAYBACK) || (mixer_view == VIEW_CHANNELS) ) {      for (i = MIXER_ELEM_FRONT; i <= MIXER_ELEM_SIDE; i++) {        int ok;        for (j = ok = 0; j < 2; j++) {	  if (mixer_changed_state)	    goto __again; 	  if (snd_mixer_selem_has_playback_channel(elem, mixer_elem_chn[i][j]))	    ok++;        }        if (ok) {	  sid = (snd_mixer_selem_id_t *)(((char *)mixer_sid) + snd_mixer_selem_id_sizeof() * idx);	  mixer_grpidx[elem_index] = idx;	  if (snd_mixer_selem_is_enumerated(elem)) {	    if (mixer_view == VIEW_PLAYBACK &&		snd_mixer_selem_is_enum_capture(elem))	      continue;	    mixer_type[elem_index] = MIXER_ELEM_ENUM;	  } else {	    mixer_type[elem_index] = i;	    if (i == 0 && snd_mixer_selem_has_playback_switch(elem))	      mixer_type[elem_index] |= MIXER_ELEM_MUTE_SWITCH;	    if (snd_mixer_selem_has_playback_volume(elem))	      mixer_type[elem_index] |= MIXER_ELEM_HAS_VOLUME;	  }	  if (mixer_view == VIEW_CHANNELS) {	    if (nelems_added == 0 &&		! snd_mixer_selem_has_capture_volume(elem) &&		snd_mixer_selem_has_capture_switch(elem))	      mixer_type[elem_index] |= MIXER_ELEM_CAPTURE_SWITCH;	  }	  elem_index++;	  nelems_added++;	  if (elem_index >= mixer_n_elems)	    break;        }      }    }    if ( (mixer_view == VIEW_CAPTURE) || (mixer_view == VIEW_CHANNELS) ) {      int do_add = 0;      if (snd_mixer_selem_has_capture_volume(elem) &&	  (mixer_view == VIEW_CAPTURE || !snd_mixer_selem_has_common_volume(elem)))	do_add = 1;      if (!do_add &&	  (nelems_added == 0 && snd_mixer_selem_has_capture_switch(elem)) &&	  (mixer_view == VIEW_CAPTURE || !snd_mixer_selem_has_common_switch(elem)))	do_add = 1;      if (!do_add &&	  mixer_view == VIEW_CAPTURE && snd_mixer_selem_is_enum_capture(elem))	do_add = 1;      if (do_add) {        mixer_grpidx[elem_index] = idx;	if (snd_mixer_selem_is_enum_capture(elem))	  mixer_type[elem_index] = MIXER_ELEM_CAPTURE_ENUM;	else {	  mixer_type[elem_index] = MIXER_ELEM_CAPTURE;	  if (nelems_added == 0 && snd_mixer_selem_has_capture_switch(elem))	    mixer_type[elem_index] |= MIXER_ELEM_CAPTURE_SWITCH;	  if (nelems_added)	    mixer_type[elem_index] |= MIXER_ELEM_CAPTURE_SUFFIX;	  if (snd_mixer_selem_has_capture_volume(elem))	    mixer_type[elem_index] |= MIXER_ELEM_HAS_VOLUME;	}        elem_index++;        if (elem_index >= mixer_n_elems)	  break;      }    }  }  mixer_n_view_elems = elem_index;  recalc_screen_size();  mixer_focus_elem = 0;  if (focus_type >= 0) {    for (elem_index = 0; elem_index < mixer_n_view_elems; elem_index++) {      sid = (snd_mixer_selem_id_t *)(((char *)mixer_sid) + snd_mixer_selem_id_sizeof() * mixer_grpidx[elem_index]);      if (!strcmp(snd_mixer_selem_id_get_name(focus_gid),                  snd_mixer_selem_id_get_name(sid)) &&          snd_mixer_selem_id_get_index(focus_gid) ==          snd_mixer_selem_id_get_index(sid) &&	  (mixer_type[elem_index] & MIXER_ELEM_TYPE_MASK) == focus_type) {        mixer_focus_elem = elem_index;        break;      }    }  }  if (mixer_changed_state)    goto __again;}static voidmixer_init_window (void){  /* initialize ncurses   */  setlocale(LC_CTYPE, "");  mixer_window = initscr ();  curs_set (0); /* hide the cursor */  mixer_no_lrcorner = tigetflag ("xenl") != 1 && tigetflag ("am") != 1;  if (mixer_do_color)    mixer_do_color = has_colors ();  mixer_init_draw_contexts ();  /* react on key presses   */  cbreak ();  noecho ();  leaveok (mixer_window, TRUE);  keypad (mixer_window, TRUE);  GETCH_BLOCK (1);  recalc_screen_size();  mixer_clear (TRUE);}static voidmixer_resize (void){  struct winsize winsz = { 0, };  mixer_needs_resize = 0;    if (ioctl (fileno (stdout), TIOCGWINSZ, &winsz) >= 0 &&      winsz.ws_row && winsz.ws_col)    {      keypad (mixer_window, FALSE);      leaveok (mixer_window, FALSE);      endwin ();            mixer_max_x = MAX (2, winsz.ws_col);      mixer_max_y = MAX (2, winsz.ws_row);            /* humpf, i don't get it, if only the number of rows change,       * ncurses will segfault shortly after (could trigger that with mc as well).       */      resizeterm (mixer_max_y + 1, mixer_max_x + 1);      resizeterm (mixer_max_y, mixer_max_x);            mixer_init_window ();            if (mixer_max_x < MIXER_MIN_X ||	  mixer_max_y < MIXER_MIN_Y)	beep (); // mixer_abort (ERR_WINSIZE, "");      mixer_have_old_focus = 0;    }}static voidmixer_set_delta(int delta){  int grp;    for (grp = 0; grp < 2; grp++)    mixer_volume_delta[grp] = delta;}static voidmixer_add_delta(int delta){  int grp;    for (grp = 0; grp < 2; grp++)    mixer_volume_delta[grp] += delta;}static int

⌨️ 快捷键说明

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