Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
O
osdd
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package registry
Model registry
Operate
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Jiří Kalvoda
osdd
Commits
476e4f46
Commit
476e4f46
authored
13 years ago
by
Martin Mareš
Browse files
Options
Downloads
Patches
Plain Diff
osd-alsa: A new client for adjusting ALSA mixer controls
parent
fc0d5469
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
Makefile
+9
-5
9 additions, 5 deletions
Makefile
README
+2
-0
2 additions, 0 deletions
README
osd-alsa.c
+243
-0
243 additions, 0 deletions
osd-alsa.c
with
254 additions
and
5 deletions
Makefile
+
9
−
5
View file @
476e4f46
...
...
@@ -3,20 +3,24 @@ ARCHIVE=osdd-$(VERSION).tar.gz
CFLAGS
=
-O2
-Wall
-W
-Wno-parentheses
-Wstrict-prototypes
-Wmissing-prototypes
-Wundef
-Wredundant-decls
-std
=
gnu99
all
:
osdd osdc osd-batt
all
:
osdd osdc osd-batt
osd-alsa
osdd
:
osdd.o util.o
osdc
:
osdc.o util.o client.o
osd-batt
:
osd-batt.o util.o client.o
osd-alsa
:
osd-alsa.o util.o client.o
osdd.o
:
CFLAGS+=$(shell xosd-config --cflags)
osdd
:
LD
FLAG
S+=$(shell xosd-config --libs)
osdd
:
LD
LIB
S+=$(shell xosd-config --libs)
osdc
:
LDFLAGS+=-lX11
osd-batt
:
LDFLAGS+=-lX11
osdc
:
LDLIBS+=-lX11
osd-batt
:
LDLIBS+=-lX11
osd-alsa.o
:
CFLAGS+=$(shell pkg-config --cflags alsa)
osd-alsa
:
LDLIBS+=$(shell pkg-config --libs alsa) -lX11
clean
:
rm
-f
*
~
*
.o TAGS core osdd osdc osd-batt
rm
-f
*
~
*
.o TAGS core osdd osdc osd-batt
osd-alsa
release
:
git tag v
$(
VERSION
)
...
...
This diff is collapsed.
Click to expand it.
README
+
2
−
0
View file @
476e4f46
...
...
@@ -69,3 +69,5 @@ osd-batt A slightly more complex client written in C, showing
the current status of laptop batteries. It can be asked
to show status immediately or to run in background and
croak whenever the battery is low.
osd-alsa Adjust volume of an ALSA mixer channel. Also written in C.
This diff is collapsed.
Click to expand it.
osd-alsa.c
0 → 100644
+
243
−
0
View file @
476e4f46
/*
* A Simple ALSA Volume Control via OSD
*
* (c) 2012 Martin Mares <mj@ucw.cz>
*/
#undef DEBUG
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
<getopt.h>
#include
<alsa/asoundlib.h>
#include
"osd.h"
static
char
*
alsa_device
=
"default"
;
static
char
*
mixer_control
=
"Master"
;
static
int
adjust_by
;
static
int
want_mute
=
-
1
;
static
snd_mixer_t
*
mixer
;
static
snd_mixer_elem_t
*
elem
;
static
void
init_mixer
(
void
)
{
int
err
;
if
(
err
=
snd_mixer_open
(
&
mixer
,
0
))
die
(
"snd_mixer_open failed: error %d"
,
err
);
if
(
err
=
snd_mixer_attach
(
mixer
,
alsa_device
))
die
(
"snd_mixer_attach failed: error %d"
,
err
);
if
(
err
=
snd_mixer_selem_register
(
mixer
,
NULL
,
NULL
))
die
(
"snd_mixer_selem_register failed: error %d"
,
err
);
if
(
err
=
snd_mixer_load
(
mixer
))
die
(
"snd_mixer_load: error %d"
,
err
);
for
(
elem
=
snd_mixer_first_elem
(
mixer
);
elem
;
elem
=
snd_mixer_elem_next
(
elem
))
{
const
char
*
name
=
snd_mixer_selem_get_name
(
elem
);
int
index
=
snd_mixer_selem_get_index
(
elem
);
if
(
!
strcmp
(
name
,
mixer_control
)
||
index
)
{
if
(
snd_mixer_elem_get_type
(
elem
)
!=
SND_MIXER_ELEM_SIMPLE
)
die
(
"Unable to handle non-simple mixer controls"
);
if
(
!
snd_mixer_selem_is_active
(
elem
))
die
(
"Selected mixer control is not active"
);
DBG
(
"Found mixer control %s[%d]
\n
"
,
name
,
index
);
return
;
}
}
die
(
"Unable to find mixer control %s"
,
mixer_control
);
}
static
int
get_mute
(
void
)
{
int
mute_on
=
0
,
mute_off
=
0
;
if
(
snd_mixer_selem_has_playback_switch
(
elem
))
{
for
(
snd_mixer_selem_channel_id_t
ch
=
0
;
ch
<
SND_MIXER_SCHN_LAST
;
ch
++
)
{
int
val
;
if
(
snd_mixer_selem_get_playback_switch
(
elem
,
ch
,
&
val
))
{
if
(
val
)
mute_off
++
;
else
mute_on
++
;
}
}
}
DBG
(
"Mute: on=%d off=%d
\n
"
,
mute_on
,
mute_off
);
return
!!
mute_on
;
}
static
long
get_volume
(
long
*
pmin
,
long
*
pmax
)
{
long
min
,
max
,
curr
=
0
;
if
(
!
snd_mixer_selem_has_playback_volume
(
elem
)
||
snd_mixer_selem_get_playback_volume_range
(
elem
,
&
min
,
&
max
))
{
*
pmin
=
*
pmax
=
0
;
return
0
;
}
for
(
snd_mixer_selem_channel_id_t
ch
=
0
;
ch
<
SND_MIXER_SCHN_LAST
;
ch
++
)
{
long
val
;
if
(
snd_mixer_selem_get_playback_volume
(
elem
,
ch
,
&
val
))
{
if
(
val
>
curr
)
curr
=
val
;
}
}
DBG
(
"Volume: min=%ld max=%ld curr=%ld
\n
"
,
min
,
max
,
curr
);
*
pmin
=
min
;
*
pmax
=
max
;
return
curr
;
}
static
int
vol_to_perc
(
long
curr
,
long
min
,
long
max
)
{
return
(
100LL
*
(
curr
-
min
)
+
(
max
-
min
)
/
2
)
/
(
max
-
min
);
}
static
long
perc_to_vol
(
int
perc
,
long
min
,
long
max
)
{
return
((
long
long
)
perc
*
(
max
-
min
)
+
50
)
/
100
;
}
static
void
show_mixer
(
void
)
{
long
min
,
max
;
long
curr
=
get_volume
(
&
min
,
&
max
);
int
muted
=
get_mute
();
struct
osd_msg
*
msg
=
osd_new_msg
();
osd_add_line
(
msg
,
"min-duration"
,
"0"
);
char
buf
[
256
];
snprintf
(
buf
,
sizeof
(
buf
),
"%s volume"
,
mixer_control
);
osd_add_line
(
msg
,
NULL
,
buf
);
osd_add_line
(
msg
,
NULL
,
""
);
if
(
muted
)
osd_add_line
(
msg
,
NULL
,
"[mute]"
);
else
if
(
min
<
max
)
{
snprintf
(
buf
,
sizeof
(
buf
),
"%d"
,
vol_to_perc
(
curr
,
min
,
max
));
osd_add_line
(
msg
,
"slider"
,
buf
);
}
osd_send
(
msg
);
}
static
void
set_mute
(
void
)
{
if
(
want_mute
<
0
)
return
;
if
(
want_mute
==
2
)
want_mute
=
!
get_mute
();
if
(
snd_mixer_selem_has_playback_switch
(
elem
))
{
for
(
snd_mixer_selem_channel_id_t
ch
=
0
;
ch
<
SND_MIXER_SCHN_LAST
;
ch
++
)
snd_mixer_selem_set_playback_switch
(
elem
,
ch
,
!
want_mute
);
}
}
static
void
set_volume
(
void
)
{
if
(
!
adjust_by
)
return
;
long
min
,
max
;
long
curr
=
get_volume
(
&
min
,
&
max
);
int
perc
=
vol_to_perc
(
curr
,
min
,
max
);
DBG
(
"Volume: have %d %ld
\n
"
,
perc
,
curr
);
perc
+=
adjust_by
;
if
(
perc
<
0
)
perc
=
0
;
if
(
perc
>
100
)
perc
=
100
;
curr
=
perc_to_vol
(
perc
,
min
,
max
);
curr
=
min
+
(((
long
long
)
perc
*
(
max
-
min
)
+
50
)
/
100
);
DBG
(
"Volume: want %d %ld
\n
"
,
perc
,
curr
);
for
(
snd_mixer_selem_channel_id_t
ch
=
0
;
ch
<
SND_MIXER_SCHN_LAST
;
ch
++
)
snd_mixer_selem_set_playback_volume
(
elem
,
ch
,
curr
);
}
static
void
NONRET
usage
(
void
)
{
fprintf
(
stderr
,
"\
Usage: osd-alsa <options>
\n
\
\n
\
Options:
\n
\
-a, --adjust=<percent> Adjust the control by a given amount
\n
\
-D, --device=<name> ALSA device (default: `default')
\n
\
-m, --mixer=<name> Name of mixer control (default: `Master')
\n
\
-0, --mute Mute the control
\n
\
-t, --toggle Mute/unmute the control
\n
\
-1, --unmute Unmute the control
\n
\
"
);
exit
(
1
);
}
static
const
char
short_opts
[]
=
"01a:c:D:t"
;
static
const
struct
option
long_opts
[]
=
{
{
"adjust"
,
required_argument
,
NULL
,
'a'
},
{
"device"
,
required_argument
,
NULL
,
'D'
},
{
"mixer"
,
required_argument
,
NULL
,
'm'
},
{
"mute"
,
no_argument
,
NULL
,
'0'
},
{
"toggle"
,
no_argument
,
NULL
,
't'
},
{
"unmute"
,
no_argument
,
NULL
,
'1'
},
{
NULL
,
0
,
NULL
,
0
},
};
int
main
(
int
argc
,
char
**
argv
)
{
int
opt
;
while
((
opt
=
getopt_long
(
argc
,
argv
,
short_opts
,
long_opts
,
NULL
))
>=
0
)
switch
(
opt
)
{
case
'0'
:
want_mute
=
1
;
break
;
case
'1'
:
want_mute
=
0
;
break
;
case
'a'
:
adjust_by
=
atoi
(
optarg
);
break
;
case
'D'
:
alsa_device
=
optarg
;
break
;
case
'm'
:
mixer_control
=
optarg
;
break
;
case
't'
:
want_mute
=
2
;
break
;
default:
usage
();
}
if
(
optind
<
argc
)
usage
();
init_mixer
();
osd_init
();
set_mute
();
set_volume
();
show_mixer
();
return
0
;
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment