stuff for configuring the audio output format (sampling rate, channels, bits)
git-svn-id: https://svn.musicpd.org/mpd/trunk@967 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
parent
9edafa886b
commit
cd3180c701
105
src/audio.c
105
src/audio.c
|
@ -28,15 +28,23 @@
|
|||
#ifdef HAVE_AUDIO
|
||||
#include <ao/ao.h>
|
||||
|
||||
int audio_write_size;
|
||||
static int audio_write_size;
|
||||
|
||||
int audio_ao_driver_id;
|
||||
ao_option * audio_ao_options;
|
||||
static int audio_ao_driver_id;
|
||||
static ao_option * audio_ao_options;
|
||||
|
||||
AudioFormat audio_format;
|
||||
ao_device * audio_device = NULL;
|
||||
static AudioFormat audio_format;
|
||||
static ao_device * audio_device = NULL;
|
||||
#endif
|
||||
|
||||
static AudioFormat * audio_configFormat = NULL;
|
||||
|
||||
static void copyAudioFormat(AudioFormat * dest, AudioFormat * src) {
|
||||
dest->sampleRate = src->sampleRate;
|
||||
dest->bits = src->bits;
|
||||
dest->channels = src->channels;
|
||||
}
|
||||
|
||||
void initAudioDriver() {
|
||||
#ifdef HAVE_AUDIO
|
||||
ao_info * ai;
|
||||
|
@ -115,6 +123,81 @@ void initAudioDriver() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void getOutputAudioFormat(AudioFormat * inAudioFormat,
|
||||
AudioFormat * outAudioFormat)
|
||||
{
|
||||
if(audio_configFormat) {
|
||||
copyAudioFormat(outAudioFormat,audio_configFormat);
|
||||
}
|
||||
else copyAudioFormat(outAudioFormat,inAudioFormat);
|
||||
}
|
||||
|
||||
void initAudioConfig() {
|
||||
char * conf = getConf()[CONF_AUDIO_OUTPUT_FORMAT];
|
||||
char * test;
|
||||
|
||||
if(NULL == conf) return;
|
||||
|
||||
audio_configFormat = malloc(sizeof(AudioFormat));
|
||||
|
||||
memset(audio_configFormat,0,sizeof(AudioFormat));
|
||||
|
||||
audio_configFormat->sampleRate = strtol(conf,&test,10);
|
||||
|
||||
if(*test!=':') {
|
||||
ERROR("error parsing audio output format: %s\n",conf);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
switch(audio_configFormat->sampleRate) {
|
||||
case 48000:
|
||||
case 44100:
|
||||
break;
|
||||
default:
|
||||
ERROR("sample rate %i can not be used for audio output\n",
|
||||
(int)audio_configFormat->sampleRate);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
audio_configFormat->bits = strtol(test,&test,10);
|
||||
|
||||
if(*test!=':') {
|
||||
ERROR("error parsing audio output format: %s\n",conf);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
switch(audio_configFormat->bits) {
|
||||
case 8:
|
||||
case 16:
|
||||
break;
|
||||
default:
|
||||
ERROR("bits %i can not be used for audio output\n",
|
||||
(int)audio_configFormat->bits);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
audio_configFormat->channels = strtol(test,&test,10);
|
||||
|
||||
if(*test!='\0') {
|
||||
ERROR("error parsing audio output format: %s\n",conf);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
switch(audio_configFormat->channels) {
|
||||
case 1:
|
||||
case 2:
|
||||
break;
|
||||
default:
|
||||
ERROR("channels %i can not be used for audio output\n",
|
||||
(int)audio_configFormat->channels);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void finishAudioConfig() {
|
||||
if(audio_configFormat) free(audio_configFormat);
|
||||
}
|
||||
|
||||
void finishAudioDriver() {
|
||||
#ifdef HAVE_AUDIO
|
||||
ao_free_options(audio_ao_options);
|
||||
|
@ -137,19 +220,17 @@ int isCurrentAudioFormat(AudioFormat * audioFormat) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int initAudio(AudioFormat * audioFormat) {
|
||||
int openAudioDevice(AudioFormat * audioFormat) {
|
||||
#ifdef HAVE_AUDIO
|
||||
ao_sample_format format;
|
||||
|
||||
if(audio_device && !isCurrentAudioFormat(audioFormat)) {
|
||||
finishAudio();
|
||||
closeAudioDevice();
|
||||
}
|
||||
|
||||
if(!audio_device) {
|
||||
if(audioFormat) {
|
||||
audio_format.bits = audioFormat->bits;
|
||||
audio_format.sampleRate = audioFormat->sampleRate;
|
||||
audio_format.channels = audioFormat->channels;
|
||||
copyAudioFormat(&audio_format,audioFormat);
|
||||
}
|
||||
|
||||
format.bits = audio_format.bits;
|
||||
|
@ -184,7 +265,7 @@ int playAudio(char * playChunk, int size) {
|
|||
if(ao_play(audio_device,playChunk,send)==0) {
|
||||
audioError();
|
||||
ERROR("closing audio device due to write error\n");
|
||||
finishAudio();
|
||||
closeAudioDevice();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -196,7 +277,7 @@ int playAudio(char * playChunk, int size) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void finishAudio() {
|
||||
void closeAudioDevice() {
|
||||
#ifdef HAVE_AUDIO
|
||||
if(audio_device) {
|
||||
blockSignals();
|
||||
|
|
10
src/audio.h
10
src/audio.h
|
@ -33,15 +33,21 @@ typedef struct _AudioFormat {
|
|||
volatile mpd_sint8 bits;
|
||||
} AudioFormat;
|
||||
|
||||
void getOutputAudioFormat(AudioFormat * inFormat, AudioFormat * outFormat);
|
||||
|
||||
void initAudioConfig();
|
||||
|
||||
void finishAudioConfig();
|
||||
|
||||
void initAudioDriver();
|
||||
|
||||
void finishAudioDriver();
|
||||
|
||||
int initAudio(AudioFormat * audioFormat);
|
||||
int openAudioDevice(AudioFormat * audioFormat);
|
||||
|
||||
int playAudio(char * playChunk,int size);
|
||||
|
||||
void finishAudio();
|
||||
void closeAudioDevice();
|
||||
|
||||
void audioError();
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
#define CONF_COMMENT '#'
|
||||
|
||||
#define CONF_NUMBER_OF_PARAMS 28
|
||||
#define CONF_NUMBER_OF_PARAMS 29
|
||||
#define CONF_NUMBER_OF_PATHS 6
|
||||
#define CONF_NUMBER_OF_REQUIRED 5
|
||||
#define CONF_NUMBER_OF_ALLOW_CATS 1
|
||||
|
@ -124,7 +124,8 @@ char ** readConf(char * file) {
|
|||
"password",
|
||||
"default_permissions",
|
||||
"buffer_size",
|
||||
"replaygain"
|
||||
"replaygain",
|
||||
"audio_output_format"
|
||||
};
|
||||
|
||||
int conf_absolutePaths[CONF_NUMBER_OF_PATHS] = {
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#define CONF_DEFAULT_PERMISSIONS 25
|
||||
#define CONF_BUFFER_SIZE 26
|
||||
#define CONF_REPLAYGAIN 27
|
||||
#define CONF_AUDIO_OUTPUT_FORMAT 28
|
||||
|
||||
#define CONF_CAT_CHAR "\n"
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ int waitOnDecode(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if(initAudio(af)<0) {
|
||||
if(openAudioDevice(af)<0) {
|
||||
strncpy(pc->erroredFile,pc->file,MAXPATHLEN);
|
||||
pc->erroredFile[MAXPATHLEN] = '\0';
|
||||
pc->error = PLAYER_ERROR_AUDIO;
|
||||
|
@ -190,7 +190,7 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
|
|||
pause = !pause; \
|
||||
if(pause) pc->state = PLAYER_STATE_PAUSE; \
|
||||
else { \
|
||||
if(initAudio(NULL)<0) { \
|
||||
if(openAudioDevice(NULL)<0) { \
|
||||
strncpy(pc->erroredFile,pc->file,MAXPATHLEN); \
|
||||
pc->erroredFile[MAXPATHLEN] = '\0'; \
|
||||
pc->error = PLAYER_ERROR_AUDIO; \
|
||||
|
@ -201,7 +201,7 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
|
|||
} \
|
||||
pc->pause = 0; \
|
||||
kill(getppid(),SIGUSR1); \
|
||||
if(pause) finishAudio(); \
|
||||
if(pause) closeAudioDevice(); \
|
||||
} \
|
||||
if(pc->seek) { \
|
||||
pc->totalPlayTime+= pc->elapsedTime-pc->beginTime; \
|
||||
|
|
|
@ -353,6 +353,7 @@ int main(int argc, char * argv[]) {
|
|||
}
|
||||
|
||||
initCommands();
|
||||
initAudioConfig();
|
||||
initAudioDriver();
|
||||
initPlayerData();
|
||||
initVolume();
|
||||
|
@ -443,6 +444,7 @@ int main(int argc, char * argv[]) {
|
|||
finishPlaylist();
|
||||
freePlayerData();
|
||||
finishAudioDriver();
|
||||
finishAudioConfig();
|
||||
finishVolume();
|
||||
finishPaths();
|
||||
finishPermissions();
|
||||
|
|
|
@ -127,7 +127,7 @@ int playerInit() {
|
|||
else if(pc->stop) pc->stop = 0;
|
||||
else if(pc->pause) pc->pause = 0;
|
||||
else if(pc->closeAudio) {
|
||||
finishAudio();
|
||||
closeAudioDevice();
|
||||
pc->closeAudio = 0;
|
||||
kill(getppid(),SIGUSR1);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue