allow to set quality or bitrate for shout streams
NOTE: setting bitrate uses significantly more CPU for doing the encoding git-svn-id: https://svn.musicpd.org/mpd/trunk@2396 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
parent
40917e6f59
commit
348a1fb373
@ -56,6 +56,7 @@ typedef struct _ShoutData {
|
|||||||
vorbis_comment vc;
|
vorbis_comment vc;
|
||||||
|
|
||||||
float quality;
|
float quality;
|
||||||
|
int bitrate;
|
||||||
AudioFormat outAudioFormat;
|
AudioFormat outAudioFormat;
|
||||||
AudioFormat inAudioFormat;
|
AudioFormat inAudioFormat;
|
||||||
|
|
||||||
@ -77,6 +78,8 @@ static ShoutData * newShoutData() {
|
|||||||
ret->convBufferLen = 0;
|
ret->convBufferLen = 0;
|
||||||
ret->opened = 0;
|
ret->opened = 0;
|
||||||
ret->tag = NULL;
|
ret->tag = NULL;
|
||||||
|
ret->bitrate = -1;
|
||||||
|
ret->quality = -1.0;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -135,17 +138,47 @@ static int shout_initDriver(AudioOutput * audioOutput, ConfigParam * param) {
|
|||||||
checkBlockParam("user");
|
checkBlockParam("user");
|
||||||
user = blockParam->value;
|
user = blockParam->value;
|
||||||
|
|
||||||
checkBlockParam("quality");
|
blockParam = getBlockParam(param, "quality");
|
||||||
|
|
||||||
|
if(blockParam) {
|
||||||
|
int line = blockParam->line;
|
||||||
|
|
||||||
sd->quality = strtod(blockParam->value, &test);
|
sd->quality = strtod(blockParam->value, &test);
|
||||||
|
|
||||||
if(*test != '\0' || sd->quality < 0.0 || sd->quality > 10.0) {
|
if(*test != '\0' || sd->quality < 0.0 || sd->quality > 10.0) {
|
||||||
ERROR("shout quality \"%s\" is not a number in the range "
|
ERROR("shout quality \"%s\" is not a number in the "
|
||||||
"0-10, line %i\n", blockParam->value,
|
"rage 0-10, line %i\n", blockParam->value,
|
||||||
blockParam->line);
|
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");
|
checkBlockParam("format");
|
||||||
|
|
||||||
if(0 != parseAudioConfig(&(sd->outAudioFormat), blockParam->value)) {
|
if(0 != parseAudioConfig(&(sd->outAudioFormat), blockParam->value)) {
|
||||||
@ -162,13 +195,37 @@ static int shout_initDriver(AudioOutput * audioOutput, ConfigParam * param) {
|
|||||||
shout_set_format(sd->shoutConn, SHOUT_FORMAT_VORBIS)
|
shout_set_format(sd->shoutConn, SHOUT_FORMAT_VORBIS)
|
||||||
!= SHOUTERR_SUCCESS ||
|
!= SHOUTERR_SUCCESS ||
|
||||||
shout_set_protocol(sd->shoutConn, SHOUT_PROTOCOL_HTTP)
|
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",
|
ERROR("error configuring shout: %s\n",
|
||||||
shout_get_error(sd->shoutConn));
|
shout_get_error(sd->shoutConn));
|
||||||
exit(EXIT_FAILURE);
|
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;
|
audioOutput->data = sd;
|
||||||
|
|
||||||
if(shoutInitCount == 0) shout_init();
|
if(shoutInitCount == 0) shout_init();
|
||||||
@ -261,13 +318,33 @@ static void copyTagToVorbisComment(ShoutData * sd) {
|
|||||||
static int initEncoder(ShoutData * sd) {
|
static int initEncoder(ShoutData * sd) {
|
||||||
vorbis_info_init(&(sd->vi));
|
vorbis_info_init(&(sd->vi));
|
||||||
|
|
||||||
if( 0 != vorbis_encode_init_vbr(&(sd->vi), sd->outAudioFormat.channels,
|
if(sd->quality >= 0) {
|
||||||
sd->outAudioFormat.sampleRate, sd->quality/10.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");
|
ERROR("problem seting up vorbis encoder for shout\n");
|
||||||
vorbis_info_clear(&(sd->vi));
|
vorbis_info_clear(&(sd->vi));
|
||||||
return -1;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
vorbis_analysis_init(&(sd->vd), &(sd->vi));
|
vorbis_analysis_init(&(sd->vd), &(sd->vi));
|
||||||
vorbis_block_init (&(sd->vd), &(sd->vb));
|
vorbis_block_init (&(sd->vd), &(sd->vb));
|
||||||
|
Loading…
Reference in New Issue
Block a user