From 4594810abea6fa50643c0923a9ee9075e59922ce Mon Sep 17 00:00:00 2001 From: Bruno Morais Date: Thu, 6 Jun 2019 16:48:23 +0200 Subject: Add audio resampling Fixes #683 --- contrib/config-example | 1 + contrib/pianobar.1 | 4 ++++ src/player.c | 15 ++++++++++++--- src/settings.c | 3 +++ src/settings.h | 1 + 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/contrib/config-example b/contrib/config-example index 0229595..275659f 100644 --- a/contrib/config-example +++ b/contrib/config-example @@ -49,6 +49,7 @@ #volume = 0 #ca_bundle = /etc/ssl/certs/ca-certificates.crt #gain_mul = 1.0 +#sample_rate = 44100 # Format strings #format_nowplaying_song = %t by %a on %l%r%@%s diff --git a/contrib/pianobar.1 b/contrib/pianobar.1 index 7462030..196bbb2 100644 --- a/contrib/pianobar.1 +++ b/contrib/pianobar.1 @@ -367,6 +367,10 @@ variable. Only "Basic" http authentication is supported. .TP .B rpc_tls_port = 443 +.TP +.B sample_rate = 0 +Force fixed output sample rate. The default, 0, uses the stream’s sample rate. + .TP .B sort = {name_az, name_za, quickmix_01_name_az, quickmix_01_name_za, quickmix_10_name_az, quickmix_10_name_za} Sort station list by name or type (is quickmix) and name. name_az for example diff --git a/src/player.c b/src/player.c index 17fe7ed..848d58b 100644 --- a/src/player.c +++ b/src/player.c @@ -254,6 +254,15 @@ static bool openStream (player_t * const player) { return true; } +/* Get output sample rate. Default to stream sample rate + */ +static int getSampleRate (const player_t * const player) { + AVCodecParameters const * const cp = player->st->codecpar; + return player->settings->sampleRate == 0 ? + cp->sample_rate : + player->settings->sampleRate; +} + /* setup filter chain */ static bool openFilter (player_t * const player) { @@ -289,8 +298,8 @@ static bool openFilter (player_t * const player) { /* aformat: convert float samples into something more usable */ AVFilterContext *fafmt = NULL; - snprintf (strbuf, sizeof (strbuf), "sample_fmts=%s", - av_get_sample_fmt_name (avformat)); + snprintf (strbuf, sizeof (strbuf), "sample_fmts=%s:sample_rates=%d", + av_get_sample_fmt_name (avformat), getSampleRate (player)); if ((ret = avfilter_graph_create_filter (&fafmt, avfilter_get_by_name ("aformat"), "format", strbuf, NULL, player->fgraph)) < 0) { @@ -328,7 +337,7 @@ static bool openDevice (player_t * const player) { aoFmt.bits = av_get_bytes_per_sample (avformat) * 8; assert (aoFmt.bits > 0); aoFmt.channels = cp->channels; - aoFmt.rate = cp->sample_rate; + aoFmt.rate = getSampleRate (player); aoFmt.byte_format = AO_FMT_NATIVE; int driver = ao_default_driver_id (); diff --git a/src/settings.c b/src/settings.c index 4ee1bd6..bcb5dfc 100644 --- a/src/settings.c +++ b/src/settings.c @@ -183,6 +183,7 @@ void BarSettingsRead (BarSettings_t *settings) { settings->outkey = strdup ("6#26FRL$ZWD"); settings->fifo = BarGetXdgConfigDir (PACKAGE "/ctl"); assert (settings->fifo != NULL); + settings->sampleRate = 0; /* default to stream sample rate */ settings->msgFormat[MSG_NONE].prefix = NULL; settings->msgFormat[MSG_NONE].postfix = NULL; @@ -391,6 +392,8 @@ void BarSettingsRead (BarSettings_t *settings) { settings->fifo = BarSettingsExpandTilde (val, userhome); } else if (streq ("autoselect", key)) { settings->autoselect = atoi (val); + } else if (streq ("sample_rate", key)) { + settings->sampleRate = atoi (val); } else if (strncmp (formatMsgPrefix, key, strlen (formatMsgPrefix)) == 0) { static const char *mapping[] = {"none", "info", "nowplaying", diff --git a/src/settings.h b/src/settings.h index 709a56f..a4264a2 100644 --- a/src/settings.h +++ b/src/settings.h @@ -104,6 +104,7 @@ typedef struct { char *fifo; char *rpcHost, *rpcTlsPort, *partnerUser, *partnerPassword, *device, *inkey, *outkey, *caBundle; char keys[BAR_KS_COUNT]; + int sampleRate; BarMsgFormatStr_t msgFormat[MSG_COUNT]; } BarSettings_t; -- cgit v1.2.3