aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/audio.c105
-rw-r--r--src/audio.h10
-rw-r--r--src/conf.c5
-rw-r--r--src/conf.h1
-rw-r--r--src/decode.c6
-rw-r--r--src/main.c2
-rw-r--r--src/player.c2
7 files changed, 111 insertions, 20 deletions
diff --git a/src/audio.c b/src/audio.c
index b532c95e4..243f65863 100644
--- a/src/audio.c
+++ b/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();
diff --git a/src/audio.h b/src/audio.h
index 98b44326e..a03c42ca9 100644
--- a/src/audio.h
+++ b/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();
diff --git a/src/conf.c b/src/conf.c
index 2027ae872..c9050b8b0 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -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] = {
diff --git a/src/conf.h b/src/conf.h
index 3999f7f1f..901cdefb7 100644
--- a/src/conf.h
+++ b/src/conf.h
@@ -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"
diff --git a/src/decode.c b/src/decode.c
index 221ca4a9b..d386a201a 100644
--- a/src/decode.c
+++ b/src/decode.c
@@ -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; \
diff --git a/src/main.c b/src/main.c
index b95e052f2..e33ea6e90 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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();
diff --git a/src/player.c b/src/player.c
index 57e489f64..f8d183baa 100644
--- a/src/player.c
+++ b/src/player.c
@@ -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);
}