aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/audioOutput_shout.c97
1 files changed, 87 insertions, 10 deletions
diff --git a/src/audioOutput_shout.c b/src/audioOutput_shout.c
index 3fb07cc49..8b8ee693c 100644
--- a/src/audioOutput_shout.c
+++ b/src/audioOutput_shout.c
@@ -56,6 +56,7 @@ typedef struct _ShoutData {
vorbis_comment vc;
float quality;
+ int bitrate;
AudioFormat outAudioFormat;
AudioFormat inAudioFormat;
@@ -77,6 +78,8 @@ static ShoutData * newShoutData() {
ret->convBufferLen = 0;
ret->opened = 0;
ret->tag = NULL;
+ ret->bitrate = -1;
+ ret->quality = -1.0;
return ret;
}
@@ -135,15 +138,45 @@ static int shout_initDriver(AudioOutput * audioOutput, ConfigParam * param) {
checkBlockParam("user");
user = blockParam->value;
- checkBlockParam("quality");
+ blockParam = getBlockParam(param, "quality");
- sd->quality = strtod(blockParam->value, &test);
+ if(blockParam) {
+ int line = blockParam->line;
- if(*test != '\0' || sd->quality < 0.0 || sd->quality > 10.0) {
- ERROR("shout quality \"%s\" is not a number in the range "
- "0-10, line %i\n", blockParam->value,
+ sd->quality = strtod(blockParam->value, &test);
+
+ if(*test != '\0' || sd->quality < 0.0 || sd->quality > 10.0) {
+ ERROR("shout quality \"%s\" is not a number in the "
+ "rage 0-10, line %i\n", blockParam->value,
blockParam->line);
- exit(EXIT_FAILURE);
+ exit(EXIT_FAILURE);
+ }
+
+ blockParam = getBlockParam(param, "bitrate");
+
+ if(blockParam) {
+ ERROR("quality (line %i) and bitrate (line %i) are "
+ "both defined for shout output\n", line,
+ blockParam->line);
+ exit(EXIT_FAILURE);
+ }
+ }
+ else {
+ blockParam = getBlockParam(param, "bitrate");
+
+ if(!blockParam) {
+ ERROR("neither bitrate nor quality defined for shout "
+ "output at line %i\n", param->line);
+ exit(EXIT_FAILURE);
+ }
+
+ sd->bitrate = strtol(blockParam->value, &test, 10);
+
+ if(*test != '\0' || sd->bitrate <= 0) {
+ ERROR("bitrate at line %i should be a positve integer "
+ "\n", blockParam->line);
+ exit(EXIT_FAILURE);
+ }
}
checkBlockParam("format");
@@ -162,13 +195,37 @@ static int shout_initDriver(AudioOutput * audioOutput, ConfigParam * param) {
shout_set_format(sd->shoutConn, SHOUT_FORMAT_VORBIS)
!= SHOUTERR_SUCCESS ||
shout_set_protocol(sd->shoutConn, SHOUT_PROTOCOL_HTTP)
- != SHOUTERR_SUCCESS)
+ != SHOUTERR_SUCCESS ||
+ shout_set_agent(sd->shoutConn, "MPD") != SHOUTERR_SUCCESS)
{
ERROR("error configuring shout: %s\n",
shout_get_error(sd->shoutConn));
exit(EXIT_FAILURE);
}
+ {
+ char temp[11];
+ memset(temp, 0, sizeof(temp));
+
+ snprintf(temp, sizeof(temp), "%d", sd->outAudioFormat.channels);
+ shout_set_audio_info(sd->shoutConn, SHOUT_AI_CHANNELS, temp);
+
+ snprintf(temp, sizeof(temp), "%d",
+ sd->outAudioFormat.sampleRate);
+ shout_set_audio_info(sd->shoutConn, SHOUT_AI_SAMPLERATE, temp);
+
+ if(sd->quality >= 0) {
+ snprintf(temp, sizeof(temp), "%2.2f", sd->quality);
+ shout_set_audio_info(sd->shoutConn, SHOUT_AI_QUALITY,
+ temp);
+ }
+ else {
+ snprintf(temp, sizeof(temp), "%d", sd->bitrate);
+ shout_set_audio_info(sd->shoutConn, SHOUT_AI_BITRATE,
+ temp);
+ }
+ }
+
audioOutput->data = sd;
if(shoutInitCount == 0) shout_init();
@@ -261,9 +318,29 @@ static void copyTagToVorbisComment(ShoutData * sd) {
static int initEncoder(ShoutData * sd) {
vorbis_info_init(&(sd->vi));
- if( 0 != vorbis_encode_init_vbr(&(sd->vi), sd->outAudioFormat.channels,
- sd->outAudioFormat.sampleRate, sd->quality/10.0) )
- {
+ if(sd->quality >= 0) {
+ if( 0 != vorbis_encode_init_vbr(&(sd->vi),
+ sd->outAudioFormat.channels,
+ sd->outAudioFormat.sampleRate, sd->quality*0.1) )
+ {
+ ERROR("problem seting up vorbis encoder for shout\n");
+ vorbis_info_clear(&(sd->vi));
+ return -1;
+ }
+ }
+ else {
+ if( 0 != vorbis_encode_setup_managed(&(sd->vi),
+ sd->outAudioFormat.channels,
+ sd->outAudioFormat.sampleRate, -1.0,
+ sd->bitrate*1000, -1.0) )
+ {
+ ERROR("problem seting up vorbis encoder for shout\n");
+ vorbis_info_clear(&(sd->vi));
+ return -1;
+ }
+ }
+
+ if(0 != vorbis_encode_setup_init(&(sd->vi))) {
ERROR("problem seting up vorbis encoder for shout\n");
vorbis_info_clear(&(sd->vi));
return -1;