we ne allow audioOutput plugins to set the final outAudioFormat that will be used. we now use alsa's _near functions to detect what to use.
git-svn-id: https://svn.musicpd.org/mpd/trunk@3038 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
@@ -73,13 +73,14 @@ AudioOutput * newAudioOutput(ConfigParam * param) {
|
|||||||
|
|
||||||
memset(&ret->inAudioFormat, 0, sizeof(AudioFormat));
|
memset(&ret->inAudioFormat, 0, sizeof(AudioFormat));
|
||||||
memset(&ret->outAudioFormat, 0, sizeof(AudioFormat));
|
memset(&ret->outAudioFormat, 0, sizeof(AudioFormat));
|
||||||
|
memset(&ret->reqAudioFormat, 0, sizeof(AudioFormat));
|
||||||
|
|
||||||
getBlockParam(AUDIO_OUTPUT_FORMAT, format, 0);
|
getBlockParam(AUDIO_OUTPUT_FORMAT, format, 0);
|
||||||
|
|
||||||
if(format) {
|
if(format) {
|
||||||
ret->convertAudioFormat = 1;
|
ret->convertAudioFormat = 1;
|
||||||
|
|
||||||
if(0 != parseAudioConfig(&ret->outAudioFormat, format))
|
if(0 != parseAudioConfig(&ret->reqAudioFormat, format))
|
||||||
{
|
{
|
||||||
ERROR("error parsing format at line %i\n",
|
ERROR("error parsing format at line %i\n",
|
||||||
bp->line);
|
bp->line);
|
||||||
@@ -102,6 +103,8 @@ AudioOutput * newAudioOutput(ConfigParam * param) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int openAudioOutput(AudioOutput * audioOutput, AudioFormat * audioFormat) {
|
int openAudioOutput(AudioOutput * audioOutput, AudioFormat * audioFormat) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
if(audioOutput->open) {
|
if(audioOutput->open) {
|
||||||
if(cmpAudioFormat(audioFormat, &audioOutput->inAudioFormat)
|
if(cmpAudioFormat(audioFormat, &audioOutput->inAudioFormat)
|
||||||
== 0)
|
== 0)
|
||||||
@@ -114,20 +117,24 @@ int openAudioOutput(AudioOutput * audioOutput, AudioFormat * audioFormat) {
|
|||||||
copyAudioFormat(&audioOutput->inAudioFormat, audioFormat);
|
copyAudioFormat(&audioOutput->inAudioFormat, audioFormat);
|
||||||
|
|
||||||
if(audioOutput->convertAudioFormat) {
|
if(audioOutput->convertAudioFormat) {
|
||||||
if(cmpAudioFormat(&audioOutput->inAudioFormat,
|
copyAudioFormat(&audioOutput->outAudioFormat,
|
||||||
&audioOutput->outAudioFormat) == 0)
|
&audioOutput->reqAudioFormat);
|
||||||
{
|
|
||||||
audioOutput->sameInAndOutFormats = 1;
|
|
||||||
}
|
|
||||||
else audioOutput->sameInAndOutFormats = 0;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
audioOutput->sameInAndOutFormats = 1;
|
|
||||||
copyAudioFormat(&audioOutput->outAudioFormat,
|
copyAudioFormat(&audioOutput->outAudioFormat,
|
||||||
&audioOutput->inAudioFormat);
|
&audioOutput->inAudioFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
return audioOutput->openDeviceFunc(audioOutput);
|
ret = audioOutput->openDeviceFunc(audioOutput);
|
||||||
|
|
||||||
|
if(cmpAudioFormat(&audioOutput->inAudioFormat,
|
||||||
|
&audioOutput->outAudioFormat) == 0)
|
||||||
|
{
|
||||||
|
audioOutput->sameInAndOutFormats = 1;
|
||||||
|
}
|
||||||
|
else audioOutput->sameInAndOutFormats = 0;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void convertAudioFormat(AudioOutput * audioOutput, char ** chunkArgPtr,
|
static void convertAudioFormat(AudioOutput * audioOutput, char ** chunkArgPtr,
|
||||||
|
@@ -60,6 +60,7 @@ struct _AudioOutput {
|
|||||||
int convertAudioFormat;
|
int convertAudioFormat;
|
||||||
AudioFormat inAudioFormat;
|
AudioFormat inAudioFormat;
|
||||||
AudioFormat outAudioFormat;
|
AudioFormat outAudioFormat;
|
||||||
|
AudioFormat reqAudioFormat;
|
||||||
char * convBuffer;
|
char * convBuffer;
|
||||||
int convBufferLen;
|
int convBufferLen;
|
||||||
int sameInAndOutFormats;
|
int sameInAndOutFormats;
|
||||||
|
@@ -93,6 +93,7 @@ static int alsa_openDevice(AudioOutput * audioOutput)
|
|||||||
snd_pcm_hw_params_t * hwparams;
|
snd_pcm_hw_params_t * hwparams;
|
||||||
snd_pcm_sw_params_t * swparams;
|
snd_pcm_sw_params_t * swparams;
|
||||||
unsigned int sampleRate = audioFormat->sampleRate;
|
unsigned int sampleRate = audioFormat->sampleRate;
|
||||||
|
unsigned int channels = audioFormat->channels;
|
||||||
snd_pcm_uframes_t alsa_buffer_size;
|
snd_pcm_uframes_t alsa_buffer_size;
|
||||||
snd_pcm_uframes_t alsa_period_size;
|
snd_pcm_uframes_t alsa_period_size;
|
||||||
unsigned int alsa_buffer_time = MPD_ALSA_BUFFER_TIME;
|
unsigned int alsa_buffer_time = MPD_ALSA_BUFFER_TIME;
|
||||||
@@ -107,10 +108,10 @@ static int alsa_openDevice(AudioOutput * audioOutput)
|
|||||||
bitformat = SND_PCM_FORMAT_S16;
|
bitformat = SND_PCM_FORMAT_S16;
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
bitformat = SND_PCM_FORMAT_S16;
|
bitformat = SND_PCM_FORMAT_S24;
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
bitformat = SND_PCM_FORMAT_S16;
|
bitformat = SND_PCM_FORMAT_S32;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERROR("Alsa device \"%s\" doesn't support %i bit audio\n",
|
ERROR("Alsa device \"%s\" doesn't support %i bit audio\n",
|
||||||
@@ -162,14 +163,15 @@ static int alsa_openDevice(AudioOutput * audioOutput)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = snd_pcm_hw_params_set_channels(ad->pcmHandle, hwparams,
|
err = snd_pcm_hw_params_set_channels_near(ad->pcmHandle, hwparams,
|
||||||
audioFormat->channels);
|
&channels);
|
||||||
if(err < 0) {
|
if(err < 0) {
|
||||||
ERROR("Alsa device \"%s\" does not support %i channels: "
|
ERROR("Alsa device \"%s\" does not support %i channels: "
|
||||||
"%s\n", ad->device, (int)audioFormat->channels,
|
"%s\n", ad->device, (int)audioFormat->channels,
|
||||||
snd_strerror(-err));
|
snd_strerror(-err));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
audioFormat->channels = channels;
|
||||||
|
|
||||||
err = snd_pcm_hw_params_set_rate_near(ad->pcmHandle, hwparams,
|
err = snd_pcm_hw_params_set_rate_near(ad->pcmHandle, hwparams,
|
||||||
&sampleRate, 0);
|
&sampleRate, 0);
|
||||||
@@ -178,6 +180,7 @@ static int alsa_openDevice(AudioOutput * audioOutput)
|
|||||||
ad->device, (int)audioFormat->sampleRate);
|
ad->device, (int)audioFormat->sampleRate);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
audioFormat->sampleRate = sampleRate;
|
||||||
|
|
||||||
err = snd_pcm_hw_params_set_buffer_time_near(ad->pcmHandle, hwparams,
|
err = snd_pcm_hw_params_set_buffer_time_near(ad->pcmHandle, hwparams,
|
||||||
&alsa_buffer_time, 0);
|
&alsa_buffer_time, 0);
|
||||||
@@ -214,6 +217,9 @@ static int alsa_openDevice(AudioOutput * audioOutput)
|
|||||||
|
|
||||||
audioOutput->open = 1;
|
audioOutput->open = 1;
|
||||||
|
|
||||||
|
DEBUG("alsa device \"%s\" will be playing %i channel audio at %i Hz\n",
|
||||||
|
ad->device, channels, sampleRate);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
Reference in New Issue
Block a user