mirror of
https://github.com/linux-speakup/espeakup.git
synced 2026-08-09 09:19:09 +02:00
Merge pull request #19 from sthibaul/alsa-volume
Support setting ALSA volume in addition to espeak volume
This commit is contained in:
commit
7159441731
3 changed files with 94 additions and 1 deletions
2
Makefile
2
Makefile
|
|
@ -6,7 +6,7 @@ DEPFLAGS = -MMD
|
|||
WARNFLAGS = -Wall
|
||||
CFLAGS += ${DEPFLAGS} ${WARNFLAGS}
|
||||
|
||||
LDLIBS = -lespeak -lpthread
|
||||
LDLIBS = -lespeak -lpthread -lasound -lm
|
||||
|
||||
INSTALL = install
|
||||
BINMODE = 0755
|
||||
|
|
|
|||
6
cli.c
6
cli.c
|
|
@ -30,11 +30,15 @@ extern char *pidPath;
|
|||
/* default voice */
|
||||
extern char *defaultVoice;
|
||||
|
||||
/* Whether to drive ALSA volume */
|
||||
extern int alsaVolume;
|
||||
|
||||
/* command line options */
|
||||
const char *shortOptions = "P:V:adhv";
|
||||
const struct option longOptions[] = {
|
||||
{"pid-path", required_argument, NULL, 'P'},
|
||||
{"default-voice", required_argument, NULL, 'V'},
|
||||
{"alsa-volume", no_argument, &alsaVolume, 1},
|
||||
{"acsint", no_argument, NULL, 'a'},
|
||||
{"debug", no_argument, NULL, 'd'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
|
|
@ -48,6 +52,7 @@ static void show_help()
|
|||
printf("Options are as follows:\n");
|
||||
printf(" --pid-path=path, -P path\t\tSet path for pid file.\n");
|
||||
printf(" --default-voice=voice, -V voice\tSet default voice.\n");
|
||||
printf(" --alsa-volume\t\t\t\tDrive the ALSA volume.\n");
|
||||
printf(" --debug, -d\t\t\t\tDebug mode (stay in the foreground).\n");
|
||||
printf(" --help, -h\t\t\t\tShow this help.\n");
|
||||
printf(" --version, -v\t\t\t\tDisplay the software version.\n");
|
||||
|
|
@ -93,6 +98,7 @@ void process_cli(int argc, char **argv)
|
|||
show_version();
|
||||
break;
|
||||
case -1:
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
show_help();
|
||||
|
|
|
|||
87
espeak.c
87
espeak.c
|
|
@ -22,6 +22,8 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "espeakup.h"
|
||||
|
||||
|
|
@ -32,6 +34,7 @@ const int defaultRange = 5;
|
|||
const int defaultRate = 2;
|
||||
const int defaultVolume = 5;
|
||||
char *defaultVoice = NULL;
|
||||
int alsaVolume = 0;
|
||||
|
||||
/* multipliers and offsets */
|
||||
const int frequencyMultiplier = 11;
|
||||
|
|
@ -152,6 +155,86 @@ static espeak_ERROR set_voice(struct synth_t *s, char *voice)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static void set_alsa_volume(int vol)
|
||||
{
|
||||
snd_mixer_t *m;
|
||||
snd_mixer_elem_t *e;
|
||||
int err;
|
||||
|
||||
err = snd_mixer_open(&m, 0);
|
||||
if (err < 0)
|
||||
{
|
||||
fprintf(stderr, "ALSA mixer open error: %s\n", snd_strerror(err));
|
||||
return;
|
||||
}
|
||||
|
||||
err = snd_mixer_attach(m, "default");
|
||||
if (err < 0)
|
||||
{
|
||||
fprintf(stderr, "ALSA mixer attach error: %s\n", snd_strerror(err));
|
||||
return;
|
||||
}
|
||||
err = snd_mixer_selem_register(m, NULL, NULL);
|
||||
if (err < 0)
|
||||
{
|
||||
fprintf(stderr, "ALSA mixer load error: %s\n", snd_strerror(err));
|
||||
return;
|
||||
}
|
||||
err = snd_mixer_load(m);
|
||||
if (err < 0)
|
||||
{
|
||||
fprintf(stderr, "ALSA mixer load error: %s\n", snd_strerror(err));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Turn vol value to volume %.
|
||||
* We do not want to soften that much with ALSA, espeak is already
|
||||
* doing it. We want the default value (5) to be the usual default
|
||||
* volume (80%), and make higher values increase ALSA volume, up to
|
||||
* 100%. */
|
||||
|
||||
int volume = (vol+1) * 50 / 10 + 50;
|
||||
|
||||
for (e = snd_mixer_first_elem(m); e; e = snd_mixer_elem_next(e))
|
||||
{
|
||||
if (snd_mixer_elem_get_type(e) != SND_MIXER_ELEM_SIMPLE)
|
||||
continue;
|
||||
if (snd_mixer_selem_is_enumerated(e))
|
||||
continue;
|
||||
|
||||
if (snd_mixer_selem_has_playback_switch(e)) {
|
||||
snd_mixer_selem_set_playback_switch_all(e, 1);
|
||||
}
|
||||
|
||||
if (snd_mixer_selem_has_playback_volume(e)) {
|
||||
long min, max, set;
|
||||
|
||||
err = snd_mixer_selem_get_playback_dB_range(e, &min, &max);
|
||||
if (err == 0 && min < max) {
|
||||
if (max - min < 2400) {
|
||||
/* 24dB amplitude is too small for using a logscale */
|
||||
set = min + volume * (max-min) / 100;
|
||||
} else {
|
||||
/* Use a logscale */
|
||||
double volf = volume / 100.;
|
||||
if (min != SND_CTL_TLV_DB_GAIN_MUTE)
|
||||
{
|
||||
double minf = pow(10, (min-max) / 6000.);
|
||||
volf = volf * (1 - minf) + minf;
|
||||
}
|
||||
set = 6000. * log10(volf) + max;
|
||||
}
|
||||
snd_mixer_selem_set_playback_dB_all(e, set, 0);
|
||||
} else {
|
||||
/* No dB setting, try a linear scale */
|
||||
snd_mixer_selem_get_playback_volume_range(e, &min, &max);
|
||||
set = min + volume * (max-min) / 100;
|
||||
snd_mixer_selem_set_playback_volume_all(e, set);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static espeak_ERROR set_volume(struct synth_t *s, int vol,
|
||||
enum adjust_t adj)
|
||||
{
|
||||
|
|
@ -164,7 +247,11 @@ static espeak_ERROR set_volume(struct synth_t *s, int vol,
|
|||
rc = espeak_SetParameter(espeakVOLUME, (vol + 1) * volumeMultiplier,
|
||||
0);
|
||||
if (rc == EE_OK)
|
||||
{
|
||||
s->volume = vol;
|
||||
if (alsaVolume)
|
||||
set_alsa_volume(vol);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue