mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-14 05:15:43 +01:00
* Sun Feb 21 02:23:52 1999 Tim Janik <timj@gtk.org>
* * * don't abort if snd_mixer_* functions failed due to EINTR, * we simply retry on the next cycle. hopefully asoundlib preserves * errno states correctly (Jaroslav can you asure that?). * * * feature WINCH correctly, so we make a complete relayout on * screen resizes. don't abort on too-small screen sizes anymore, * but simply beep. * * * redid the layout algorithm to fix some bugs and to preserve * space for a flag indication line. the channels are * nicer spread horizontally now (i.e. we also pad on the left and * right screen bounds now). * * * various other minor fixes. * * * indicate whether ExactMode is active or not. * * * fixed coding style to follow the GNU coding conventions. * * * reverted record volume changes since they broke ExactMode display. * * * composed ChangeLog entries.
This commit is contained in:
parent
4775b46362
commit
d47938eab3
3 changed files with 953 additions and 823 deletions
|
@ -79,5 +79,6 @@ You can exit with ALT + Q, or by hitting ESC.
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
-----------------------------------------------------------------
|
||||||
|
|
||||||
alsamixer is by Jaroslav Kysela <perex@jcu.cz>
|
Alsamixer has been written by Tim Janik <timj@gtk.org> and
|
||||||
This document is by Paul Winkler <zarmzarm@erols.com>
|
been furtherly improved by Jaroslav Kysela <perex@jcu.cz>.
|
||||||
|
This document was provided by Paul Winkler <zarmzarm@erols.com>.
|
||||||
|
|
|
@ -107,15 +107,14 @@ arecord(1)
|
||||||
\fP
|
\fP
|
||||||
|
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
None known. Some terminal emulators (e.g. \fBnxterm\fP) may not
|
There is no help screen implemented yet. Some terminal emulators
|
||||||
|
(e.g. \fBnxterm\fP) may not
|
||||||
work quite right with ncurses, but that's their own damn
|
work quite right with ncurses, but that's their own damn
|
||||||
fault. Plain old \fBxterm\fP seems to be fine.
|
fault. Plain old \fBxterm\fP seems to be fine.
|
||||||
|
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
\fBalsamixer\fP is by Jaroslav Kysela <perex@jcu.cz>
|
.B alsamixer
|
||||||
This document is by Paul Winkler <zarmzarm@erols.com>.
|
has been written by Tim Janik <timj@gtk.org> and
|
||||||
|
been furtherly improved by Jaroslav Kysela <perex@jcu.cz>.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
This manual page was provided by Paul Winkler <zarmzarm@erols.com>.
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
/* AlsaMixer - Commandline mixer for the ALSA project
|
/* AlsaMixer - Commandline mixer for the ALSA project
|
||||||
* Copyright (C) 1998 Jaroslav Kysela <perex@jcu.cz>,
|
* Copyright (C) 1998, 1999 Tim Janik <timj@gtk.org> and Jaroslav Kysela <perex@jcu.cz>
|
||||||
* Tim Janik <timj@gtk.org>,
|
|
||||||
* Carl van Schaik <carl@dreamcoat.che.uct.ac.za>
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -16,6 +14,49 @@
|
||||||
* You should have received a copy of the GNU Library General Public
|
* You should have received a copy of the GNU Library General Public
|
||||||
* License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* ChangeLog:
|
||||||
|
*
|
||||||
|
* Sun Feb 21 02:23:52 1999 Tim Janik <timj@gtk.org>
|
||||||
|
*
|
||||||
|
* * don't abort if snd_mixer_* functions failed due to EINTR,
|
||||||
|
* we simply retry on the next cycle. hopefully asoundlib preserves
|
||||||
|
* errno states correctly (Jaroslav can you asure that?).
|
||||||
|
*
|
||||||
|
* * feature WINCH correctly, so we make a complete relayout on
|
||||||
|
* screen resizes. don't abort on too-small screen sizes anymore,
|
||||||
|
* but simply beep.
|
||||||
|
*
|
||||||
|
* * redid the layout algorithm to fix some bugs and to preserve
|
||||||
|
* space for a flag indication line. the channels are
|
||||||
|
* nicer spread horizontally now (i.e. we also pad on the left and
|
||||||
|
* right screen bounds now).
|
||||||
|
*
|
||||||
|
* * various other minor fixes.
|
||||||
|
*
|
||||||
|
* * indicate whether ExactMode is active or not.
|
||||||
|
*
|
||||||
|
* * fixed coding style to follow the GNU coding conventions.
|
||||||
|
*
|
||||||
|
* * reverted record volume changes since they broke ExactMode display.
|
||||||
|
*
|
||||||
|
* * composed ChangeLog entries.
|
||||||
|
*
|
||||||
|
* 1998/11/04 19:43:45 perex
|
||||||
|
*
|
||||||
|
* * Stereo record source and route selection...
|
||||||
|
* provided by Carl van Schaik <carl@dreamcoat.che.uct.ac.za>.
|
||||||
|
*
|
||||||
|
* 1998/09/20 08:05:24 perex
|
||||||
|
*
|
||||||
|
* * Fixed -m option...
|
||||||
|
*
|
||||||
|
* 1998/10/29 22:50:10
|
||||||
|
*
|
||||||
|
* * initial checkin of alsamixer.c, written by Tim Janik, modified by
|
||||||
|
* Jaroslav Kysela to feature asoundlib.h instead of plain ioctl()s and
|
||||||
|
* automated updates after select() (i always missed that with OSS!).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -40,13 +81,15 @@
|
||||||
#include <sys/asoundlib.h>
|
#include <sys/asoundlib.h>
|
||||||
|
|
||||||
/* example compilation commandline:
|
/* example compilation commandline:
|
||||||
* clear; gcc -Wall -pipe -O2 alsamixer.c -o alsamixer -lncurses
|
* clear; gcc -Wall -pipe -O2 alsamixer.c -o alsamixer -lasound -lncurses
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* --- defines --- */
|
/* --- defines --- */
|
||||||
#define PRGNAME "alsamixer"
|
#define PRGNAME "alsamixer"
|
||||||
#define PRGNAME_UPPER "AlsaMixer"
|
#define PRGNAME_UPPER "AlsaMixer"
|
||||||
#define VERSION "v0.9"
|
#define VERSION "v0.9"
|
||||||
|
#define REFRESH() ({ if (!mixer_needs_resize) refresh (); })
|
||||||
|
#define CHECK_ABORT(e,s) ({ if (errno != EINTR) mixer_abort ((e), (s)); })
|
||||||
|
|
||||||
#undef MAX
|
#undef MAX
|
||||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
|
@ -57,8 +100,9 @@
|
||||||
#undef CLAMP
|
#undef CLAMP
|
||||||
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
|
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
|
||||||
|
|
||||||
#define MIXER_MIN_X (23) /* minimum: 23 */
|
#define MIXER_MIN_X (18) /* abs minimum: 18 */
|
||||||
#define MIXER_MIN_Y (19) /* minimum: 19 */
|
#define MIXER_TEXT_Y (10)
|
||||||
|
#define MIXER_MIN_Y (MIXER_TEXT_Y + 3) /* abs minimum: 11 */
|
||||||
|
|
||||||
#define MIXER_BLACK (COLOR_BLACK)
|
#define MIXER_BLACK (COLOR_BLACK)
|
||||||
#define MIXER_DARK_RED (COLOR_RED)
|
#define MIXER_DARK_RED (COLOR_RED)
|
||||||
|
@ -78,11 +122,11 @@
|
||||||
|
|
||||||
/* --- variables --- */
|
/* --- variables --- */
|
||||||
static WINDOW *mixer_window = NULL;
|
static WINDOW *mixer_window = NULL;
|
||||||
|
static int mixer_needs_resize = 0;
|
||||||
static int mixer_max_x = 0;
|
static int mixer_max_x = 0;
|
||||||
static int mixer_max_y = 0;
|
static int mixer_max_y = 0;
|
||||||
static int mixer_ofs_x = 0;
|
static int mixer_ofs_x = 0;
|
||||||
static float mixer_extra_space = 0;
|
static float mixer_extra_space = 0;
|
||||||
static int mixer_ofs_y = 0;
|
|
||||||
static int mixer_cbar_height = 0;
|
static int mixer_cbar_height = 0;
|
||||||
|
|
||||||
static int card_id = 0;
|
static int card_id = 0;
|
||||||
|
@ -95,10 +139,9 @@ static int mixer_n_channels = 0;
|
||||||
static int mixer_n_vis_channels = 0;
|
static int mixer_n_vis_channels = 0;
|
||||||
static int mixer_first_vis_channel = 0;
|
static int mixer_first_vis_channel = 0;
|
||||||
static int mixer_focus_channel = 0;
|
static int mixer_focus_channel = 0;
|
||||||
|
static int mixer_have_old_focus = 0;
|
||||||
static int mixer_exact = 0;
|
static int mixer_exact = 0;
|
||||||
|
|
||||||
static int mixer_record_volumes = 0;
|
|
||||||
|
|
||||||
static int mixer_lvolume_delta = 0;
|
static int mixer_lvolume_delta = 0;
|
||||||
static int mixer_rvolume_delta = 0;
|
static int mixer_rvolume_delta = 0;
|
||||||
static int mixer_balance_volumes = 0;
|
static int mixer_balance_volumes = 0;
|
||||||
|
@ -137,15 +180,13 @@ enum {
|
||||||
DC_LAST
|
DC_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
static int dc_fg[DC_LAST] =
|
static int dc_fg[DC_LAST] = { 0 };
|
||||||
{0};
|
static int dc_attrib[DC_LAST] = { 0 };
|
||||||
static int dc_attrib[DC_LAST] =
|
static int dc_char[DC_LAST] = { 0 };
|
||||||
{0};
|
|
||||||
static int dc_char[DC_LAST] =
|
|
||||||
{0};
|
|
||||||
static int mixer_do_color = 1;
|
static int mixer_do_color = 1;
|
||||||
|
|
||||||
static void mixer_init_dc(int c,
|
static void
|
||||||
|
mixer_init_dc (int c,
|
||||||
int n,
|
int n,
|
||||||
int f,
|
int f,
|
||||||
int b,
|
int b,
|
||||||
|
@ -158,7 +199,8 @@ static void mixer_init_dc(int c,
|
||||||
init_pair (n, dc_fg[n] & 0xf, b & 0x0f);
|
init_pair (n, dc_fg[n] & 0xf, b & 0x0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mixer_dc(int n)
|
static int
|
||||||
|
mixer_dc (int n)
|
||||||
{
|
{
|
||||||
if (mixer_do_color)
|
if (mixer_do_color)
|
||||||
attrset (COLOR_PAIR (n) | (dc_fg[n] & 0xfffffff0));
|
attrset (COLOR_PAIR (n) | (dc_fg[n] & 0xfffffff0));
|
||||||
|
@ -168,7 +210,8 @@ static int mixer_dc(int n)
|
||||||
return dc_char[n];
|
return dc_char[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mixer_init_draw_contexts(void)
|
static void
|
||||||
|
mixer_init_draw_contexts (void)
|
||||||
{
|
{
|
||||||
start_color ();
|
start_color ();
|
||||||
|
|
||||||
|
@ -193,7 +236,8 @@ static void mixer_init_draw_contexts(void)
|
||||||
|
|
||||||
|
|
||||||
/* --- error types --- */
|
/* --- error types --- */
|
||||||
typedef enum {
|
typedef enum
|
||||||
|
{
|
||||||
ERR_NONE,
|
ERR_NONE,
|
||||||
ERR_OPEN,
|
ERR_OPEN,
|
||||||
ERR_FCN,
|
ERR_FCN,
|
||||||
|
@ -203,18 +247,21 @@ typedef enum {
|
||||||
|
|
||||||
|
|
||||||
/* --- prototypes --- */
|
/* --- prototypes --- */
|
||||||
static void mixer_abort(ErrType error,
|
static void
|
||||||
|
mixer_abort (ErrType error,
|
||||||
const char *err_string)
|
const char *err_string)
|
||||||
__attribute__
|
__attribute__
|
||||||
((noreturn));
|
((noreturn));
|
||||||
|
|
||||||
|
|
||||||
/* --- functions --- */
|
/* --- functions --- */
|
||||||
static void mixer_clear(void)
|
static void
|
||||||
|
mixer_clear (void)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
mixer_dc (DC_BACK);
|
mixer_dc (DC_BACK);
|
||||||
|
clearok (mixer_window, TRUE);
|
||||||
clear ();
|
clear ();
|
||||||
|
|
||||||
/* buggy ncurses doesn't really write spaces with the specified
|
/* buggy ncurses doesn't really write spaces with the specified
|
||||||
|
@ -223,20 +270,25 @@ static void mixer_clear(void)
|
||||||
for (x = 0; x < mixer_max_x; x++)
|
for (x = 0; x < mixer_max_x; x++)
|
||||||
for (y = 0; y < mixer_max_y; y++)
|
for (y = 0; y < mixer_max_y; y++)
|
||||||
mvaddch (y, x, ' ');
|
mvaddch (y, x, ' ');
|
||||||
refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mixer_abort(ErrType error,
|
static void
|
||||||
|
mixer_abort (ErrType error,
|
||||||
const char *err_string)
|
const char *err_string)
|
||||||
{
|
{
|
||||||
if (mixer_window) {
|
if (mixer_window)
|
||||||
|
{
|
||||||
mixer_clear ();
|
mixer_clear ();
|
||||||
|
refresh ();
|
||||||
|
keypad (mixer_window, FALSE);
|
||||||
|
leaveok (mixer_window, FALSE);
|
||||||
endwin ();
|
endwin ();
|
||||||
mixer_window = NULL;
|
mixer_window = NULL;
|
||||||
}
|
}
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
|
|
||||||
switch (error) {
|
switch (error)
|
||||||
|
{
|
||||||
case ERR_OPEN:
|
case ERR_OPEN:
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
PRGNAME ": failed to open mixer #%i/#%i: %s\n",
|
PRGNAME ": failed to open mixer #%i/#%i: %s\n",
|
||||||
|
@ -268,7 +320,8 @@ static void mixer_abort(ErrType error,
|
||||||
exit (error);
|
exit (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mixer_cbar_get_pos(int channel_index,
|
static int
|
||||||
|
mixer_cbar_get_pos (int channel_index,
|
||||||
int *x_p,
|
int *x_p,
|
||||||
int *y_p)
|
int *y_p)
|
||||||
{
|
{
|
||||||
|
@ -281,11 +334,14 @@ static int mixer_cbar_get_pos(int channel_index,
|
||||||
|
|
||||||
channel_index -= mixer_first_vis_channel;
|
channel_index -= mixer_first_vis_channel;
|
||||||
|
|
||||||
x = mixer_ofs_x + 1;
|
x = mixer_ofs_x;
|
||||||
y = mixer_ofs_y;
|
x += (3 + 2 + 3 + 1) * channel_index + mixer_extra_space * (channel_index + 1);
|
||||||
x += channel_index * (3 + 2 + 3 + 1 + mixer_extra_space);
|
|
||||||
y += mixer_max_y / 2;
|
if (MIXER_TEXT_Y + 10 < mixer_max_y)
|
||||||
y += mixer_cbar_height / 2 + 1;
|
y = mixer_max_y / 2 + 3;
|
||||||
|
else
|
||||||
|
y = (mixer_max_y + 1) / 2 + 3;
|
||||||
|
y += mixer_cbar_height / 2;
|
||||||
|
|
||||||
if (x_p)
|
if (x_p)
|
||||||
*x_p = x;
|
*x_p = x;
|
||||||
|
@ -295,31 +351,26 @@ static int mixer_cbar_get_pos(int channel_index,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mixer_update_cbar(int channel_index)
|
static void
|
||||||
|
mixer_update_cbar (int channel_index)
|
||||||
{
|
{
|
||||||
char string[64];
|
char string[64];
|
||||||
char c;
|
char c;
|
||||||
snd_mixer_channel_info_t cinfo =
|
snd_mixer_channel_info_t cinfo = { 0, };
|
||||||
{0};
|
snd_mixer_channel_t cdata = { 0, };
|
||||||
snd_mixer_channel_t cdata =
|
|
||||||
{0};
|
|
||||||
snd_mixer_channel_t crdata =
|
|
||||||
{0};
|
|
||||||
int vleft, vright;
|
int vleft, vright;
|
||||||
int x, y, i;
|
int x, y, i;
|
||||||
|
|
||||||
int channel_record_volume;
|
|
||||||
|
|
||||||
/* set specified EXACT mode
|
/* set specified EXACT mode
|
||||||
*/
|
*/
|
||||||
if (snd_mixer_exact_mode (mixer_handle, mixer_exact) < 0)
|
if (snd_mixer_exact_mode (mixer_handle, mixer_exact) < 0)
|
||||||
mixer_abort(ERR_FCN, "snd_mixer_exact");
|
CHECK_ABORT (ERR_FCN, "snd_mixer_exact_mode()");
|
||||||
|
|
||||||
/* set new channel indices and read info
|
/* set new channel indices and read info
|
||||||
*/
|
*/
|
||||||
if (snd_mixer_channel_info (mixer_handle, channel_index, &cinfo) < 0)
|
if (snd_mixer_channel_info (mixer_handle, channel_index, &cinfo) < 0)
|
||||||
mixer_abort(ERR_FCN, "snd_mixer_channel_info");
|
CHECK_ABORT (ERR_FCN, "snd_mixer_channel_info()");
|
||||||
channel_record_volume = (cinfo.caps & SND_MIXER_CINFO_CAP_RECORDVOLUME);
|
|
||||||
|
|
||||||
/* set new channel values
|
/* set new channel values
|
||||||
*/
|
*/
|
||||||
|
@ -329,59 +380,38 @@ static void mixer_update_cbar(int channel_index)
|
||||||
mixer_balance_volumes ||
|
mixer_balance_volumes ||
|
||||||
mixer_toggle_record || mixer_toggle_rec_left ||
|
mixer_toggle_record || mixer_toggle_rec_left ||
|
||||||
mixer_toggle_rec_right ||
|
mixer_toggle_rec_right ||
|
||||||
mixer_route_rtol_in || mixer_route_ltor_in)) {
|
mixer_route_rtol_in || mixer_route_ltor_in))
|
||||||
|
{
|
||||||
if (snd_mixer_channel_read (mixer_handle, channel_index, &cdata) < 0)
|
if (snd_mixer_channel_read (mixer_handle, channel_index, &cdata) < 0)
|
||||||
mixer_abort(ERR_FCN, "snd_mixer_channel_read");
|
CHECK_ABORT (ERR_FCN, "snd_mixer_channel_read()");
|
||||||
if (mixer_record_volumes && channel_record_volume &&
|
|
||||||
snd_mixer_channel_record_read(mixer_handle, channel_index, &crdata) < 0)
|
|
||||||
mixer_abort(ERR_FCN, "snd_mixer_channel_record_read");
|
|
||||||
|
|
||||||
cdata.flags &= ~SND_MIXER_FLG_DECIBEL;
|
cdata.flags &= ~SND_MIXER_FLG_DECIBEL;
|
||||||
if (mixer_lvolume_delta) {
|
|
||||||
if (mixer_record_volumes) {
|
|
||||||
if (channel_record_volume)
|
|
||||||
crdata.left = CLAMP(crdata.left + mixer_lvolume_delta, cinfo.min, cinfo.max);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
cdata.left = CLAMP (cdata.left + mixer_lvolume_delta, cinfo.min, cinfo.max);
|
cdata.left = CLAMP (cdata.left + mixer_lvolume_delta, cinfo.min, cinfo.max);
|
||||||
mixer_lvolume_delta = 0;
|
|
||||||
}
|
|
||||||
if (mixer_rvolume_delta) {
|
|
||||||
if (mixer_record_volumes) {
|
|
||||||
if (channel_record_volume)
|
|
||||||
crdata.right = CLAMP(crdata.right + mixer_rvolume_delta, cinfo.min, cinfo.max);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
cdata.right = CLAMP (cdata.right + mixer_rvolume_delta, cinfo.min, cinfo.max);
|
cdata.right = CLAMP (cdata.right + mixer_rvolume_delta, cinfo.min, cinfo.max);
|
||||||
mixer_rvolume_delta = 0;
|
mixer_lvolume_delta = mixer_rvolume_delta = 0;
|
||||||
}
|
if (mixer_balance_volumes)
|
||||||
if (mixer_balance_volumes) {
|
{
|
||||||
if (mixer_record_volumes) {
|
|
||||||
if (channel_record_volume) {
|
|
||||||
crdata.left = (crdata.left + crdata.right) / 2;
|
|
||||||
crdata.right = crdata.left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cdata.left = (cdata.left + cdata.right) / 2;
|
cdata.left = (cdata.left + cdata.right) / 2;
|
||||||
cdata.right = cdata.left;
|
cdata.right = cdata.left;
|
||||||
}
|
|
||||||
mixer_balance_volumes = 0;
|
mixer_balance_volumes = 0;
|
||||||
}
|
}
|
||||||
if (mixer_toggle_mute_left) {
|
if (mixer_toggle_mute_left)
|
||||||
|
{
|
||||||
if (cdata.flags & SND_MIXER_FLG_MUTE_LEFT)
|
if (cdata.flags & SND_MIXER_FLG_MUTE_LEFT)
|
||||||
cdata.flags &= ~SND_MIXER_FLG_MUTE_LEFT;
|
cdata.flags &= ~SND_MIXER_FLG_MUTE_LEFT;
|
||||||
else
|
else
|
||||||
cdata.flags |= SND_MIXER_FLG_MUTE_LEFT;
|
cdata.flags |= SND_MIXER_FLG_MUTE_LEFT;
|
||||||
}
|
}
|
||||||
if (mixer_toggle_mute_right) {
|
if (mixer_toggle_mute_right)
|
||||||
|
{
|
||||||
if (cdata.flags & SND_MIXER_FLG_MUTE_RIGHT)
|
if (cdata.flags & SND_MIXER_FLG_MUTE_RIGHT)
|
||||||
cdata.flags &= ~SND_MIXER_FLG_MUTE_RIGHT;
|
cdata.flags &= ~SND_MIXER_FLG_MUTE_RIGHT;
|
||||||
else
|
else
|
||||||
cdata.flags |= SND_MIXER_FLG_MUTE_RIGHT;
|
cdata.flags |= SND_MIXER_FLG_MUTE_RIGHT;
|
||||||
}
|
}
|
||||||
mixer_toggle_mute_left = mixer_toggle_mute_right = 0;
|
mixer_toggle_mute_left = mixer_toggle_mute_right = 0;
|
||||||
if (mixer_toggle_record) {
|
if (mixer_toggle_record)
|
||||||
|
{
|
||||||
if (cdata.flags & SND_MIXER_FLG_RECORD)
|
if (cdata.flags & SND_MIXER_FLG_RECORD)
|
||||||
cdata.flags &= ~SND_MIXER_FLG_RECORD;
|
cdata.flags &= ~SND_MIXER_FLG_RECORD;
|
||||||
else
|
else
|
||||||
|
@ -389,7 +419,8 @@ static void mixer_update_cbar(int channel_index)
|
||||||
}
|
}
|
||||||
mixer_toggle_record = 0;
|
mixer_toggle_record = 0;
|
||||||
|
|
||||||
if (mixer_toggle_rec_left) {
|
if (mixer_toggle_rec_left)
|
||||||
|
{
|
||||||
if (cdata.flags & SND_MIXER_FLG_RECORD_LEFT)
|
if (cdata.flags & SND_MIXER_FLG_RECORD_LEFT)
|
||||||
cdata.flags &= ~SND_MIXER_FLG_RECORD_LEFT;
|
cdata.flags &= ~SND_MIXER_FLG_RECORD_LEFT;
|
||||||
else
|
else
|
||||||
|
@ -397,7 +428,8 @@ static void mixer_update_cbar(int channel_index)
|
||||||
}
|
}
|
||||||
mixer_toggle_rec_left = 0;
|
mixer_toggle_rec_left = 0;
|
||||||
|
|
||||||
if (mixer_toggle_rec_right) {
|
if (mixer_toggle_rec_right)
|
||||||
|
{
|
||||||
if (cdata.flags & SND_MIXER_FLG_RECORD_RIGHT)
|
if (cdata.flags & SND_MIXER_FLG_RECORD_RIGHT)
|
||||||
cdata.flags &= ~SND_MIXER_FLG_RECORD_RIGHT;
|
cdata.flags &= ~SND_MIXER_FLG_RECORD_RIGHT;
|
||||||
else
|
else
|
||||||
|
@ -405,7 +437,8 @@ static void mixer_update_cbar(int channel_index)
|
||||||
}
|
}
|
||||||
mixer_toggle_rec_right = 0;
|
mixer_toggle_rec_right = 0;
|
||||||
|
|
||||||
if (mixer_route_ltor_in) {
|
if (mixer_route_ltor_in)
|
||||||
|
{
|
||||||
if (cdata.flags & SND_MIXER_FLG_LTOR_IN)
|
if (cdata.flags & SND_MIXER_FLG_LTOR_IN)
|
||||||
cdata.flags &= ~SND_MIXER_FLG_LTOR_IN;
|
cdata.flags &= ~SND_MIXER_FLG_LTOR_IN;
|
||||||
else
|
else
|
||||||
|
@ -415,7 +448,8 @@ static void mixer_update_cbar(int channel_index)
|
||||||
}
|
}
|
||||||
mixer_route_ltor_in = 0;
|
mixer_route_ltor_in = 0;
|
||||||
|
|
||||||
if (mixer_route_rtol_in) {
|
if (mixer_route_rtol_in)
|
||||||
|
{
|
||||||
if (cdata.flags & SND_MIXER_FLG_RTOL_IN)
|
if (cdata.flags & SND_MIXER_FLG_RTOL_IN)
|
||||||
cdata.flags &= ~SND_MIXER_FLG_RTOL_IN;
|
cdata.flags &= ~SND_MIXER_FLG_RTOL_IN;
|
||||||
else
|
else
|
||||||
|
@ -424,45 +458,28 @@ static void mixer_update_cbar(int channel_index)
|
||||||
mixer_route_rtol_in = 0;
|
mixer_route_rtol_in = 0;
|
||||||
|
|
||||||
if (snd_mixer_channel_write (mixer_handle, channel_index, &cdata) < 0)
|
if (snd_mixer_channel_write (mixer_handle, channel_index, &cdata) < 0)
|
||||||
mixer_abort(ERR_FCN, "snd_mixer_channel_write");
|
CHECK_ABORT (ERR_FCN, "snd_mixer_channel_write()");
|
||||||
if (mixer_record_volumes && channel_record_volume &&
|
|
||||||
snd_mixer_channel_record_write(mixer_handle, channel_index, &crdata) < 0)
|
|
||||||
mixer_abort(ERR_FCN, "snd_mixer_channel_record_write");
|
|
||||||
}
|
}
|
||||||
/* first, read values for the numbers to be displayed in
|
/* first, read values for the numbers to be displayed in
|
||||||
* specified EXACT mode
|
* specified EXACT mode
|
||||||
*/
|
*/
|
||||||
if (snd_mixer_channel_read (mixer_handle, channel_index, &cdata) < 0)
|
if (snd_mixer_channel_read (mixer_handle, channel_index, &cdata) < 0)
|
||||||
mixer_abort(ERR_FCN, "snd_mixer_ioctl_channel_read");
|
CHECK_ABORT (ERR_FCN, "snd_mixer_channel_read()");
|
||||||
if (mixer_record_volumes) {
|
|
||||||
if (channel_record_volume) {
|
|
||||||
if (snd_mixer_channel_record_read(mixer_handle, channel_index, &crdata) < 0)
|
|
||||||
mixer_abort(ERR_FCN, "snd_mixer_channel_record_read");
|
|
||||||
vleft = crdata.left;
|
|
||||||
vright = crdata.right;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
vleft = vright = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
vleft = cdata.left;
|
vleft = cdata.left;
|
||||||
vright = cdata.right;
|
vright = cdata.right;
|
||||||
}
|
|
||||||
|
|
||||||
/* then, always use percentage values for the bars. if we don't do
|
/* then, always use percentage values for the bars. if we don't do
|
||||||
* this, we will see aliasing effects on specific circumstances.
|
* this, we will see aliasing effects on specific circumstances.
|
||||||
* (actually they don't really dissapear, but they are transfered
|
* (actually they don't really dissapear, but they are transfered
|
||||||
* to bar<->smaller-scale ambiguities).
|
* to bar<->smaller-scale ambiguities).
|
||||||
*/
|
*/
|
||||||
if (mixer_exact) {
|
if (mixer_exact)
|
||||||
|
{
|
||||||
i = 0;
|
i = 0;
|
||||||
if (snd_mixer_exact_mode (mixer_handle, 0) < 0)
|
if (snd_mixer_exact_mode (mixer_handle, 0) < 0)
|
||||||
mixer_abort(ERR_FCN, "snd_mixer_exact");
|
CHECK_ABORT (ERR_FCN, "snd_mixer_exact_mode()");
|
||||||
if (snd_mixer_channel_read (mixer_handle, channel_index, &cdata) < 0)
|
if (snd_mixer_channel_read (mixer_handle, channel_index, &cdata) < 0)
|
||||||
mixer_abort(ERR_FCN, "snd_mixer_channel_read");
|
CHECK_ABORT (ERR_FCN, "snd_mixer_channel_read()");
|
||||||
if (mixer_record_volumes && channel_record_volume &&
|
|
||||||
snd_mixer_channel_record_read(mixer_handle, channel_index, &crdata) < 0)
|
|
||||||
mixer_abort(ERR_FCN, "snd_mixer_channel_record_read");
|
|
||||||
}
|
}
|
||||||
/* get channel bar position
|
/* get channel bar position
|
||||||
*/
|
*/
|
||||||
|
@ -473,7 +490,8 @@ static void mixer_update_cbar(int channel_index)
|
||||||
*/
|
*/
|
||||||
mixer_dc (channel_index == mixer_focus_channel ? DC_CBAR_FOCUS_LABEL : DC_CBAR_LABEL);
|
mixer_dc (channel_index == mixer_focus_channel ? DC_CBAR_FOCUS_LABEL : DC_CBAR_LABEL);
|
||||||
cinfo.name[8] = 0;
|
cinfo.name[8] = 0;
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
string[i] = ' ';
|
string[i] = ' ';
|
||||||
}
|
}
|
||||||
sprintf (string + (8 - strlen (cinfo.name)) / 2, "%s ", cinfo.name);
|
sprintf (string + (8 - strlen (cinfo.name)) / 2, "%s ", cinfo.name);
|
||||||
|
@ -505,13 +523,15 @@ static void mixer_update_cbar(int channel_index)
|
||||||
mvaddch (y, x + 4, ACS_HLINE);
|
mvaddch (y, x + 4, ACS_HLINE);
|
||||||
mvaddch (y, x + 5, ACS_LRCORNER);
|
mvaddch (y, x + 5, ACS_LRCORNER);
|
||||||
y--;
|
y--;
|
||||||
for (i = 0; i < mixer_cbar_height; i++) {
|
for (i = 0; i < mixer_cbar_height; i++)
|
||||||
|
{
|
||||||
mvaddstr (y - i, x, " ");
|
mvaddstr (y - i, x, " ");
|
||||||
mvaddch (y - i, x + 2, ACS_VLINE);
|
mvaddch (y - i, x + 2, ACS_VLINE);
|
||||||
mvaddch (y - i, x + 5, ACS_VLINE);
|
mvaddch (y - i, x + 5, ACS_VLINE);
|
||||||
}
|
}
|
||||||
string[2] = 0;
|
string[2] = 0;
|
||||||
for (i = 0; i < mixer_cbar_height; i++) {
|
for (i = 0; i < mixer_cbar_height; i++)
|
||||||
|
{
|
||||||
int dc;
|
int dc;
|
||||||
|
|
||||||
if (i + 1 >= 0.8 * mixer_cbar_height)
|
if (i + 1 >= 0.8 * mixer_cbar_height)
|
||||||
|
@ -520,8 +540,8 @@ static void mixer_update_cbar(int channel_index)
|
||||||
dc = DC_CBAR_FULL_2;
|
dc = DC_CBAR_FULL_2;
|
||||||
else
|
else
|
||||||
dc = DC_CBAR_FULL_1;
|
dc = DC_CBAR_FULL_1;
|
||||||
mvaddch(y, x + 3, mixer_dc(vleft > i * 100 / mixer_cbar_height ? dc : DC_CBAR_EMPTY));
|
mvaddch (y, x + 3, mixer_dc (cdata.left > 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));
|
mvaddch (y, x + 4, mixer_dc (cdata.right > i * 100 / mixer_cbar_height ? dc : DC_CBAR_EMPTY));
|
||||||
y--;
|
y--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,38 +562,45 @@ static void mixer_update_cbar(int channel_index)
|
||||||
|
|
||||||
/* record input?
|
/* record input?
|
||||||
*/
|
*/
|
||||||
if (cdata.flags & SND_MIXER_FLG_RECORD) {
|
if (cdata.flags & SND_MIXER_FLG_RECORD)
|
||||||
|
{
|
||||||
mixer_dc (DC_CBAR_RECORD);
|
mixer_dc (DC_CBAR_RECORD);
|
||||||
mvaddstr (y, x + 1, "RECORD");
|
mvaddstr (y, x + 1, "RECORD");
|
||||||
if (cdata.flags & SND_MIXER_FLG_RECORD_LEFT) {
|
if (cdata.flags & SND_MIXER_FLG_RECORD_LEFT)
|
||||||
|
{
|
||||||
if (cdata.flags & SND_MIXER_FLG_LTOR_IN)
|
if (cdata.flags & SND_MIXER_FLG_LTOR_IN)
|
||||||
mvaddstr (y + 2, x + 6, "L");
|
mvaddstr (y + 2, x + 6, "L");
|
||||||
else
|
else
|
||||||
mvaddstr (y + 1, x + 1, "L");
|
mvaddstr (y + 1, x + 1, "L");
|
||||||
}
|
}
|
||||||
if (cdata.flags & SND_MIXER_FLG_RECORD_RIGHT) {
|
if (cdata.flags & SND_MIXER_FLG_RECORD_RIGHT)
|
||||||
|
{
|
||||||
if (cdata.flags & SND_MIXER_FLG_RTOL_IN)
|
if (cdata.flags & SND_MIXER_FLG_RTOL_IN)
|
||||||
mvaddstr (y + 2, x + 1, "R");
|
mvaddstr (y + 2, x + 1, "R");
|
||||||
else
|
else
|
||||||
mvaddstr (y + 1, x + 6, "R");
|
mvaddstr (y + 1, x + 6, "R");
|
||||||
}
|
}
|
||||||
} else if (cinfo.caps & SND_MIXER_CINFO_CAP_RECORD)
|
}
|
||||||
|
else if (cinfo.caps & SND_MIXER_CINFO_CAP_RECORD)
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
mvaddch (y, x + 1 + i, mixer_dc (DC_CBAR_NORECORD));
|
mvaddch (y, x + 1 + i, mixer_dc (DC_CBAR_NORECORD));
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
mixer_dc (DC_BACK);
|
mixer_dc (DC_BACK);
|
||||||
mvaddstr (y, x, " ");
|
mvaddstr (y, x, " ");
|
||||||
}
|
}
|
||||||
y--;
|
y--;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mixer_update_cbars(void)
|
static void
|
||||||
|
mixer_update_cbars (void)
|
||||||
{
|
{
|
||||||
static int o_x = 0;
|
static int o_x = 0;
|
||||||
static int o_y = 0;
|
static int o_y = 0;
|
||||||
int i, x, y;
|
int i, x, y;
|
||||||
|
|
||||||
if (!mixer_cbar_get_pos(mixer_focus_channel, &x, &y)) {
|
if (!mixer_cbar_get_pos (mixer_focus_channel, &x, &y))
|
||||||
|
{
|
||||||
if (mixer_focus_channel < mixer_first_vis_channel)
|
if (mixer_focus_channel < mixer_first_vis_channel)
|
||||||
mixer_first_vis_channel = mixer_focus_channel;
|
mixer_first_vis_channel = mixer_focus_channel;
|
||||||
else if (mixer_focus_channel >= mixer_first_vis_channel + mixer_n_vis_channels)
|
else if (mixer_focus_channel >= mixer_first_vis_channel + mixer_n_vis_channels)
|
||||||
|
@ -585,17 +612,22 @@ static void mixer_update_cbars(void)
|
||||||
|
|
||||||
/* draw focused cbar
|
/* draw focused cbar
|
||||||
*/
|
*/
|
||||||
|
if (mixer_have_old_focus)
|
||||||
|
{
|
||||||
mixer_dc (DC_BACK);
|
mixer_dc (DC_BACK);
|
||||||
mvaddstr (o_y, o_x, " ");
|
mvaddstr (o_y, o_x, " ");
|
||||||
mvaddstr (o_y, o_x + 9, " ");
|
mvaddstr (o_y, o_x + 9, " ");
|
||||||
|
}
|
||||||
o_x = x - 1;
|
o_x = x - 1;
|
||||||
o_y = y;
|
o_y = y;
|
||||||
mixer_dc (DC_FOCUS);
|
mixer_dc (DC_FOCUS);
|
||||||
mvaddstr (o_y, o_x, "<");
|
mvaddstr (o_y, o_x, "<");
|
||||||
mvaddstr (o_y, o_x + 9, ">");
|
mvaddstr (o_y, o_x + 9, ">");
|
||||||
|
mixer_have_old_focus = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mixer_draw_frame(void)
|
static void
|
||||||
|
mixer_draw_frame (void)
|
||||||
{
|
{
|
||||||
char string[128];
|
char string[128];
|
||||||
int i;
|
int i;
|
||||||
|
@ -603,33 +635,6 @@ static void mixer_draw_frame(void)
|
||||||
|
|
||||||
mixer_dc (DC_FRAME);
|
mixer_dc (DC_FRAME);
|
||||||
|
|
||||||
/* corners
|
|
||||||
*/
|
|
||||||
mvaddch(0, 0, ACS_ULCORNER);
|
|
||||||
mvaddch(mixer_max_y - 1, 0, ACS_LLCORNER);
|
|
||||||
mvaddch(mixer_max_y - 1, mixer_max_x - 1, ACS_LRCORNER);
|
|
||||||
mvaddch(0, mixer_max_x - 1, ACS_URCORNER);
|
|
||||||
|
|
||||||
/* lines
|
|
||||||
*/
|
|
||||||
for (i = 1; i < mixer_max_y - 1; i++) {
|
|
||||||
mvaddch(i, 0, ACS_VLINE);
|
|
||||||
mvaddch(i, mixer_max_x - 1, ACS_VLINE);
|
|
||||||
}
|
|
||||||
for (i = 1; i < mixer_max_x - 1; i++) {
|
|
||||||
mvaddch(0, i, ACS_HLINE);
|
|
||||||
mvaddch(mixer_max_y - 1, i, ACS_HLINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* program title
|
|
||||||
*/
|
|
||||||
sprintf(string, "%s %s", PRGNAME_UPPER, VERSION);
|
|
||||||
max_len = strlen(string);
|
|
||||||
mvaddch(0, mixer_max_x / 2 - max_len / 2 - 1, '[');
|
|
||||||
mvaddch(0, mixer_max_x / 2 - max_len / 2 + max_len, ']');
|
|
||||||
mixer_dc(DC_TEXT);
|
|
||||||
mvaddstr(0, mixer_max_x / 2 - max_len / 2, string);
|
|
||||||
|
|
||||||
/* card name
|
/* card name
|
||||||
*/
|
*/
|
||||||
mixer_dc (DC_PROMPT);
|
mixer_dc (DC_PROMPT);
|
||||||
|
@ -639,7 +644,7 @@ static void mixer_draw_frame(void)
|
||||||
max_len = mixer_max_x - 2 - 6 - 2;
|
max_len = mixer_max_x - 2 - 6 - 2;
|
||||||
if (strlen (string) > max_len)
|
if (strlen (string) > max_len)
|
||||||
string[max_len] = 0;
|
string[max_len] = 0;
|
||||||
mvaddstr(1, 2 + 6, string);
|
addstr (string);
|
||||||
|
|
||||||
/* device name
|
/* device name
|
||||||
*/
|
*/
|
||||||
|
@ -650,17 +655,65 @@ static void mixer_draw_frame(void)
|
||||||
max_len = mixer_max_x - 2 - 6 - 2;
|
max_len = mixer_max_x - 2 - 6 - 2;
|
||||||
if (strlen (string) > max_len)
|
if (strlen (string) > max_len)
|
||||||
string[max_len] = 0;
|
string[max_len] = 0;
|
||||||
mvaddstr(2, 2 + 6, string);
|
addstr (string);
|
||||||
if (mixer_record_volumes)
|
|
||||||
mvaddstr(3, 2, "Record mixer");
|
/* indicate exact mode
|
||||||
|
*/
|
||||||
|
if (mixer_exact)
|
||||||
|
{
|
||||||
|
mixer_dc (DC_PROMPT);
|
||||||
|
mvaddstr (3, 2, "[");
|
||||||
|
mixer_dc (DC_TEXT);
|
||||||
|
addstr ("ExactMode");
|
||||||
|
mixer_dc (DC_PROMPT);
|
||||||
|
addstr ("]");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
mvaddstr (3, 2, " ");
|
mvaddstr (3, 2, " ");
|
||||||
|
|
||||||
|
/* lines
|
||||||
|
*/
|
||||||
|
mixer_dc (DC_PROMPT);
|
||||||
|
for (i = 1; i < mixer_max_y - 1; i++)
|
||||||
|
{
|
||||||
|
mvaddch (i, 0, ACS_VLINE);
|
||||||
|
mvaddch (i, mixer_max_x - 1, ACS_VLINE);
|
||||||
|
}
|
||||||
|
for (i = 1; i < mixer_max_x - 1; i++)
|
||||||
|
{
|
||||||
|
mvaddch (0, i, ACS_HLINE);
|
||||||
|
mvaddch (mixer_max_y - 1, i, ACS_HLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mixer_init(void)
|
/* corners
|
||||||
|
*/
|
||||||
|
mixer_dc (DC_PROMPT);
|
||||||
|
mvaddch (mixer_max_y - 1, mixer_max_x - 1, ACS_LRCORNER);
|
||||||
|
mvaddch (mixer_max_y - 1, 0, ACS_LLCORNER);
|
||||||
|
mvaddch (0, 0, ACS_ULCORNER);
|
||||||
|
mvaddch (0, mixer_max_x - 1, ACS_URCORNER);
|
||||||
|
|
||||||
|
/* program title
|
||||||
|
*/
|
||||||
|
sprintf (string, "%s %s", PRGNAME_UPPER, VERSION);
|
||||||
|
max_len = strlen (string);
|
||||||
|
if (mixer_max_x >= max_len + 4)
|
||||||
{
|
{
|
||||||
static snd_mixer_info_t mixer_info =
|
mixer_dc (DC_PROMPT);
|
||||||
{0};
|
mvaddch (0, mixer_max_x / 2 - max_len / 2 - 1, '[');
|
||||||
|
mvaddch (0, mixer_max_x / 2 - max_len / 2 + max_len, ']');
|
||||||
|
}
|
||||||
|
if (mixer_max_x >= max_len + 2)
|
||||||
|
{
|
||||||
|
mixer_dc (DC_TEXT);
|
||||||
|
mvaddstr (0, mixer_max_x / 2 - max_len / 2, string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mixer_init (void)
|
||||||
|
{
|
||||||
|
static snd_mixer_info_t mixer_info = { 0, };
|
||||||
static struct snd_ctl_hw_info hw_info;
|
static struct snd_ctl_hw_info hw_info;
|
||||||
void *ctl_handle;
|
void *ctl_handle;
|
||||||
|
|
||||||
|
@ -683,39 +736,133 @@ static void mixer_init(void)
|
||||||
mixer_device_name = mixer_info.name;
|
mixer_device_name = mixer_info.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mixer_iteration_update(void *dummy, int channel)
|
static void
|
||||||
|
mixer_init_window (void)
|
||||||
{
|
{
|
||||||
|
/* initialize ncurses
|
||||||
|
*/
|
||||||
|
mixer_window = initscr ();
|
||||||
|
|
||||||
|
if (mixer_do_color)
|
||||||
|
mixer_do_color = has_colors ();
|
||||||
|
mixer_init_draw_contexts ();
|
||||||
|
|
||||||
|
/* react on key presses
|
||||||
|
* and draw window
|
||||||
|
*/
|
||||||
|
keypad (mixer_window, TRUE);
|
||||||
|
leaveok (mixer_window, TRUE);
|
||||||
|
cbreak ();
|
||||||
|
noecho ();
|
||||||
|
|
||||||
|
/* init mixer screen
|
||||||
|
*/
|
||||||
|
getmaxyx (mixer_window, mixer_max_y, mixer_max_x);
|
||||||
|
mixer_ofs_x = 2 /* extra begin padding: */ + 1;
|
||||||
|
|
||||||
|
/* required allocations */
|
||||||
|
mixer_n_vis_channels = (mixer_max_x - mixer_ofs_x * 2 + 1) / 9;
|
||||||
|
mixer_n_vis_channels = CLAMP (mixer_n_vis_channels, 1, mixer_n_channels);
|
||||||
|
mixer_extra_space = mixer_max_x - mixer_ofs_x * 2 + 1 - mixer_n_vis_channels * 9;
|
||||||
|
mixer_extra_space = MAX (0, mixer_extra_space / (mixer_n_vis_channels + 1));
|
||||||
|
if (MIXER_TEXT_Y + 10 < mixer_max_y)
|
||||||
|
mixer_cbar_height = 10 + MAX (0, mixer_max_y - MIXER_TEXT_Y - 10 ) / 2;
|
||||||
|
else
|
||||||
|
mixer_cbar_height = MAX (1, mixer_max_y - MIXER_TEXT_Y);
|
||||||
|
|
||||||
|
mixer_clear ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mixer_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,
|
||||||
|
* clear() segfaults (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 void
|
||||||
|
mixer_channel_changed_cb (void *private_data,
|
||||||
|
int channel)
|
||||||
|
{
|
||||||
|
/* we don't actually need to update the individual channels because
|
||||||
|
* we redraw the whole screen upon every main iteration anyways.
|
||||||
|
*/
|
||||||
#if 0
|
#if 0
|
||||||
fprintf (stderr, "*** channel = %i\n", channel);
|
fprintf (stderr, "*** channel = %i\n", channel);
|
||||||
#endif
|
|
||||||
mixer_update_cbar (channel);
|
mixer_update_cbar (channel);
|
||||||
refresh();
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mixer_iteration(void)
|
static int
|
||||||
|
mixer_iteration (void)
|
||||||
{
|
{
|
||||||
snd_mixer_callbacks_t callbacks;
|
struct timeval delay = { 0, };
|
||||||
int key;
|
snd_mixer_callbacks_t callbacks = { 0, };
|
||||||
int finished = 0;
|
|
||||||
int mixer_fd;
|
int mixer_fd;
|
||||||
fd_set in;
|
fd_set rfds;
|
||||||
|
int finished = 0;
|
||||||
|
int key = 0;
|
||||||
|
|
||||||
bzero(&callbacks, sizeof(callbacks));
|
callbacks.channel_was_changed = mixer_channel_changed_cb;
|
||||||
callbacks.channel_was_changed = mixer_iteration_update;
|
|
||||||
|
/* setup for select on stdin and the mixer fd */
|
||||||
mixer_fd = snd_mixer_file_descriptor (mixer_handle);
|
mixer_fd = snd_mixer_file_descriptor (mixer_handle);
|
||||||
while (1) {
|
FD_ZERO (&rfds);
|
||||||
FD_ZERO(&in);
|
FD_SET (fileno (stdin), &rfds);
|
||||||
FD_SET(fileno(stdin), &in);
|
FD_SET (mixer_fd, &rfds);
|
||||||
FD_SET(mixer_fd, &in);
|
|
||||||
if (select(mixer_fd + 1, &in, NULL, NULL, NULL) <= 0)
|
delay.tv_sec = 0;
|
||||||
return 1;
|
delay.tv_usec = 0 * 100 * 1000;
|
||||||
if (FD_ISSET(mixer_fd, &in))
|
|
||||||
snd_mixer_read(mixer_handle, &callbacks);
|
finished = select (mixer_fd + 1, &rfds, NULL, NULL, mixer_needs_resize ? &delay : NULL) < 0;
|
||||||
if (FD_ISSET(fileno(stdin), &in))
|
|
||||||
break;
|
/* don't abort on handled signals */
|
||||||
|
if (finished && errno == EINTR)
|
||||||
|
{
|
||||||
|
FD_ZERO (&rfds);
|
||||||
|
finished = 0;
|
||||||
}
|
}
|
||||||
|
else if (mixer_needs_resize)
|
||||||
|
mixer_resize ();
|
||||||
|
|
||||||
|
if (FD_ISSET (mixer_fd, &rfds))
|
||||||
|
snd_mixer_read (mixer_handle, &callbacks);
|
||||||
|
|
||||||
|
if (FD_ISSET (fileno (stdin), &rfds))
|
||||||
key = getch ();
|
key = getch ();
|
||||||
switch (key) {
|
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
/* ignore */
|
||||||
|
break;
|
||||||
case 27: /* Escape */
|
case 27: /* Escape */
|
||||||
finished = 1;
|
finished = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -731,19 +878,25 @@ static int mixer_iteration(void)
|
||||||
mixer_focus_channel -= 1;
|
mixer_focus_channel -= 1;
|
||||||
break;
|
break;
|
||||||
case KEY_PPAGE:
|
case KEY_PPAGE:
|
||||||
if (mixer_exact) {
|
if (mixer_exact)
|
||||||
|
{
|
||||||
mixer_lvolume_delta = 8;
|
mixer_lvolume_delta = 8;
|
||||||
mixer_rvolume_delta = 8;
|
mixer_rvolume_delta = 8;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
mixer_lvolume_delta = 10;
|
mixer_lvolume_delta = 10;
|
||||||
mixer_rvolume_delta = 10;
|
mixer_rvolume_delta = 10;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KEY_NPAGE:
|
case KEY_NPAGE:
|
||||||
if (mixer_exact) {
|
if (mixer_exact)
|
||||||
|
{
|
||||||
mixer_lvolume_delta = -8;
|
mixer_lvolume_delta = -8;
|
||||||
mixer_rvolume_delta = -8;
|
mixer_rvolume_delta = -8;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
mixer_lvolume_delta = -10;
|
mixer_lvolume_delta = -10;
|
||||||
mixer_rvolume_delta = -10;
|
mixer_rvolume_delta = -10;
|
||||||
}
|
}
|
||||||
|
@ -806,7 +959,6 @@ static int mixer_iteration(void)
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
case 'M':
|
case 'M':
|
||||||
mixer_record_volumes = 0;
|
|
||||||
mixer_toggle_mute_left = 1;
|
mixer_toggle_mute_left = 1;
|
||||||
mixer_toggle_mute_right = 1;
|
mixer_toggle_mute_right = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -817,18 +969,14 @@ static int mixer_iteration(void)
|
||||||
break;
|
break;
|
||||||
case '<':
|
case '<':
|
||||||
case ',':
|
case ',':
|
||||||
mixer_record_volumes = 0;
|
|
||||||
mixer_toggle_mute_left = 1;
|
mixer_toggle_mute_left = 1;
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
case '.':
|
case '.':
|
||||||
mixer_record_volumes = 0;
|
|
||||||
mixer_toggle_mute_right = 1;
|
mixer_toggle_mute_right = 1;
|
||||||
break;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
case 'r':
|
case 'r':
|
||||||
mixer_record_volumes = !mixer_record_volumes;
|
|
||||||
break;
|
|
||||||
case 'L':
|
case 'L':
|
||||||
case 'l':
|
case 'l':
|
||||||
mixer_clear ();
|
mixer_clear ();
|
||||||
|
@ -845,11 +993,9 @@ static int mixer_iteration(void)
|
||||||
mixer_toggle_rec_right = 1;
|
mixer_toggle_rec_right = 1;
|
||||||
break;
|
break;
|
||||||
case '1':
|
case '1':
|
||||||
mixer_record_volumes = 0;
|
|
||||||
mixer_route_rtol_in = 1;
|
mixer_route_rtol_in = 1;
|
||||||
break;
|
break;
|
||||||
case '2':
|
case '2':
|
||||||
mixer_record_volumes = 0;
|
|
||||||
mixer_route_ltor_in = 1;
|
mixer_route_ltor_in = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -858,50 +1004,39 @@ static int mixer_iteration(void)
|
||||||
return finished;
|
return finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mixer_init_screen(void)
|
static void
|
||||||
|
mixer_winch (void)
|
||||||
{
|
{
|
||||||
signal(SIGWINCH, (void *) mixer_init_screen);
|
signal (SIGWINCH, (void*) mixer_winch);
|
||||||
|
|
||||||
getmaxyx(mixer_window, mixer_max_y, mixer_max_x);
|
mixer_needs_resize++;
|
||||||
mixer_clear();
|
|
||||||
mixer_max_x = MAX(MIXER_MIN_X, mixer_max_x);
|
|
||||||
mixer_max_y = MAX(MIXER_MIN_Y, mixer_max_y);
|
|
||||||
mixer_clear();
|
|
||||||
mixer_ofs_x = 2;
|
|
||||||
mixer_ofs_y = 2;
|
|
||||||
mixer_extra_space = 0;
|
|
||||||
mixer_n_vis_channels = MIN((mixer_max_x - 2 * mixer_ofs_x + 1) / (9 + mixer_extra_space),
|
|
||||||
mixer_n_channels);
|
|
||||||
mixer_extra_space = ((mixer_max_x - 2 * mixer_ofs_x - 1 - mixer_n_vis_channels * 9.0) /
|
|
||||||
(mixer_n_vis_channels - 1));
|
|
||||||
if (mixer_n_vis_channels < mixer_n_channels) {
|
|
||||||
/* recalc
|
|
||||||
*/
|
|
||||||
mixer_extra_space = MAX(mixer_extra_space, 1);
|
|
||||||
mixer_n_vis_channels = MIN((mixer_max_x - 2 * mixer_ofs_x + 1) / (9 + mixer_extra_space),
|
|
||||||
mixer_n_channels);
|
|
||||||
mixer_extra_space = ((mixer_max_x - 2 * mixer_ofs_x - 1 - mixer_n_vis_channels * 9.0) /
|
|
||||||
(mixer_n_vis_channels - 1));
|
|
||||||
}
|
|
||||||
mixer_first_vis_channel = 0;
|
|
||||||
mixer_cbar_height = 10 + MAX(0, (mixer_max_y - MIXER_MIN_Y - 1)) / 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mixer_signal_handler(int signal)
|
static void
|
||||||
|
mixer_signal_handler (int signal)
|
||||||
{
|
{
|
||||||
|
if (signal != SIGSEGV)
|
||||||
mixer_abort (ERR_SIGNAL, sys_siglist[signal]);
|
mixer_abort (ERR_SIGNAL, sys_siglist[signal]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf (stderr, "\nSegmentation fault.\n");
|
||||||
|
_exit (11);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc,
|
int
|
||||||
|
main (int argc,
|
||||||
char **argv)
|
char **argv)
|
||||||
{
|
{
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
/* parse args
|
/* parse args
|
||||||
*/
|
*/
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
opt = getopt (argc, argv, "c:m:ehg");
|
opt = getopt (argc, argv, "c:m:ehg");
|
||||||
switch (opt) {
|
switch (opt)
|
||||||
|
{
|
||||||
case '?':
|
case '?':
|
||||||
case 'h':
|
case 'h':
|
||||||
fprintf (stderr, "%s %s\n", PRGNAME_UPPER, VERSION);
|
fprintf (stderr, "%s %s\n", PRGNAME_UPPER, VERSION);
|
||||||
|
@ -940,26 +1075,21 @@ int main(int argc,
|
||||||
|
|
||||||
/* initialize ncurses
|
/* initialize ncurses
|
||||||
*/
|
*/
|
||||||
mixer_window = initscr();
|
mixer_init_window ();
|
||||||
if (mixer_do_color)
|
|
||||||
mixer_do_color = has_colors();
|
|
||||||
mixer_init_draw_contexts();
|
|
||||||
mixer_init_screen();
|
|
||||||
if (mixer_max_x < MIXER_MIN_X ||
|
if (mixer_max_x < MIXER_MIN_X ||
|
||||||
mixer_max_y < MIXER_MIN_Y)
|
mixer_max_y < MIXER_MIN_Y)
|
||||||
mixer_abort(ERR_WINSIZE, "");
|
beep (); // mixer_abort (ERR_WINSIZE, "");
|
||||||
|
|
||||||
|
signal (SIGWINCH, (void*) mixer_winch);
|
||||||
|
|
||||||
/* react on key presses
|
/* react on key presses
|
||||||
* and draw window
|
* and draw window
|
||||||
*/
|
*/
|
||||||
keypad(mixer_window, TRUE);
|
do
|
||||||
leaveok(mixer_window, TRUE);
|
{
|
||||||
cbreak();
|
|
||||||
noecho();
|
|
||||||
do {
|
|
||||||
mixer_update_cbars ();
|
mixer_update_cbars ();
|
||||||
mixer_draw_frame ();
|
mixer_draw_frame ();
|
||||||
refresh();
|
REFRESH ();
|
||||||
}
|
}
|
||||||
while (!mixer_iteration ());
|
while (!mixer_iteration ());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue