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
|
#ifdef HAVE_AUDIO
|
||||||
#include <ao/ao.h>
|
#include <ao/ao.h>
|
||||||
|
|
||||||
int audio_write_size;
|
static int audio_write_size;
|
||||||
|
|
||||||
int audio_ao_driver_id;
|
static int audio_ao_driver_id;
|
||||||
ao_option * audio_ao_options;
|
static ao_option * audio_ao_options;
|
||||||
|
|
||||||
AudioFormat audio_format;
|
static AudioFormat audio_format;
|
||||||
ao_device * audio_device = NULL;
|
static ao_device * audio_device = NULL;
|
||||||
#endif
|
#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() {
|
void initAudioDriver() {
|
||||||
#ifdef HAVE_AUDIO
|
#ifdef HAVE_AUDIO
|
||||||
ao_info * ai;
|
ao_info * ai;
|
||||||
@ -115,6 +123,81 @@ void initAudioDriver() {
|
|||||||
#endif
|
#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() {
|
void finishAudioDriver() {
|
||||||
#ifdef HAVE_AUDIO
|
#ifdef HAVE_AUDIO
|
||||||
ao_free_options(audio_ao_options);
|
ao_free_options(audio_ao_options);
|
||||||
@ -137,19 +220,17 @@ int isCurrentAudioFormat(AudioFormat * audioFormat) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int initAudio(AudioFormat * audioFormat) {
|
int openAudioDevice(AudioFormat * audioFormat) {
|
||||||
#ifdef HAVE_AUDIO
|
#ifdef HAVE_AUDIO
|
||||||
ao_sample_format format;
|
ao_sample_format format;
|
||||||
|
|
||||||
if(audio_device && !isCurrentAudioFormat(audioFormat)) {
|
if(audio_device && !isCurrentAudioFormat(audioFormat)) {
|
||||||
finishAudio();
|
closeAudioDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!audio_device) {
|
if(!audio_device) {
|
||||||
if(audioFormat) {
|
if(audioFormat) {
|
||||||
audio_format.bits = audioFormat->bits;
|
copyAudioFormat(&audio_format,audioFormat);
|
||||||
audio_format.sampleRate = audioFormat->sampleRate;
|
|
||||||
audio_format.channels = audioFormat->channels;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
format.bits = audio_format.bits;
|
format.bits = audio_format.bits;
|
||||||
@ -184,7 +265,7 @@ int playAudio(char * playChunk, int size) {
|
|||||||
if(ao_play(audio_device,playChunk,send)==0) {
|
if(ao_play(audio_device,playChunk,send)==0) {
|
||||||
audioError();
|
audioError();
|
||||||
ERROR("closing audio device due to write error\n");
|
ERROR("closing audio device due to write error\n");
|
||||||
finishAudio();
|
closeAudioDevice();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,7 +277,7 @@ int playAudio(char * playChunk, int size) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void finishAudio() {
|
void closeAudioDevice() {
|
||||||
#ifdef HAVE_AUDIO
|
#ifdef HAVE_AUDIO
|
||||||
if(audio_device) {
|
if(audio_device) {
|
||||||
blockSignals();
|
blockSignals();
|
||||||
|
10
src/audio.h
10
src/audio.h
@ -33,15 +33,21 @@ typedef struct _AudioFormat {
|
|||||||
volatile mpd_sint8 bits;
|
volatile mpd_sint8 bits;
|
||||||
} AudioFormat;
|
} AudioFormat;
|
||||||
|
|
||||||
|
void getOutputAudioFormat(AudioFormat * inFormat, AudioFormat * outFormat);
|
||||||
|
|
||||||
|
void initAudioConfig();
|
||||||
|
|
||||||
|
void finishAudioConfig();
|
||||||
|
|
||||||
void initAudioDriver();
|
void initAudioDriver();
|
||||||
|
|
||||||
void finishAudioDriver();
|
void finishAudioDriver();
|
||||||
|
|
||||||
int initAudio(AudioFormat * audioFormat);
|
int openAudioDevice(AudioFormat * audioFormat);
|
||||||
|
|
||||||
int playAudio(char * playChunk,int size);
|
int playAudio(char * playChunk,int size);
|
||||||
|
|
||||||
void finishAudio();
|
void closeAudioDevice();
|
||||||
|
|
||||||
void audioError();
|
void audioError();
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
#define CONF_COMMENT '#'
|
#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_PATHS 6
|
||||||
#define CONF_NUMBER_OF_REQUIRED 5
|
#define CONF_NUMBER_OF_REQUIRED 5
|
||||||
#define CONF_NUMBER_OF_ALLOW_CATS 1
|
#define CONF_NUMBER_OF_ALLOW_CATS 1
|
||||||
@ -124,7 +124,8 @@ char ** readConf(char * file) {
|
|||||||
"password",
|
"password",
|
||||||
"default_permissions",
|
"default_permissions",
|
||||||
"buffer_size",
|
"buffer_size",
|
||||||
"replaygain"
|
"replaygain",
|
||||||
|
"audio_output_format"
|
||||||
};
|
};
|
||||||
|
|
||||||
int conf_absolutePaths[CONF_NUMBER_OF_PATHS] = {
|
int conf_absolutePaths[CONF_NUMBER_OF_PATHS] = {
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#define CONF_DEFAULT_PERMISSIONS 25
|
#define CONF_DEFAULT_PERMISSIONS 25
|
||||||
#define CONF_BUFFER_SIZE 26
|
#define CONF_BUFFER_SIZE 26
|
||||||
#define CONF_REPLAYGAIN 27
|
#define CONF_REPLAYGAIN 27
|
||||||
|
#define CONF_AUDIO_OUTPUT_FORMAT 28
|
||||||
|
|
||||||
#define CONF_CAT_CHAR "\n"
|
#define CONF_CAT_CHAR "\n"
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ int waitOnDecode(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(initAudio(af)<0) {
|
if(openAudioDevice(af)<0) {
|
||||||
strncpy(pc->erroredFile,pc->file,MAXPATHLEN);
|
strncpy(pc->erroredFile,pc->file,MAXPATHLEN);
|
||||||
pc->erroredFile[MAXPATHLEN] = '\0';
|
pc->erroredFile[MAXPATHLEN] = '\0';
|
||||||
pc->error = PLAYER_ERROR_AUDIO;
|
pc->error = PLAYER_ERROR_AUDIO;
|
||||||
@ -190,7 +190,7 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
|
|||||||
pause = !pause; \
|
pause = !pause; \
|
||||||
if(pause) pc->state = PLAYER_STATE_PAUSE; \
|
if(pause) pc->state = PLAYER_STATE_PAUSE; \
|
||||||
else { \
|
else { \
|
||||||
if(initAudio(NULL)<0) { \
|
if(openAudioDevice(NULL)<0) { \
|
||||||
strncpy(pc->erroredFile,pc->file,MAXPATHLEN); \
|
strncpy(pc->erroredFile,pc->file,MAXPATHLEN); \
|
||||||
pc->erroredFile[MAXPATHLEN] = '\0'; \
|
pc->erroredFile[MAXPATHLEN] = '\0'; \
|
||||||
pc->error = PLAYER_ERROR_AUDIO; \
|
pc->error = PLAYER_ERROR_AUDIO; \
|
||||||
@ -201,7 +201,7 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
|
|||||||
} \
|
} \
|
||||||
pc->pause = 0; \
|
pc->pause = 0; \
|
||||||
kill(getppid(),SIGUSR1); \
|
kill(getppid(),SIGUSR1); \
|
||||||
if(pause) finishAudio(); \
|
if(pause) closeAudioDevice(); \
|
||||||
} \
|
} \
|
||||||
if(pc->seek) { \
|
if(pc->seek) { \
|
||||||
pc->totalPlayTime+= pc->elapsedTime-pc->beginTime; \
|
pc->totalPlayTime+= pc->elapsedTime-pc->beginTime; \
|
||||||
|
@ -353,6 +353,7 @@ int main(int argc, char * argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
initCommands();
|
initCommands();
|
||||||
|
initAudioConfig();
|
||||||
initAudioDriver();
|
initAudioDriver();
|
||||||
initPlayerData();
|
initPlayerData();
|
||||||
initVolume();
|
initVolume();
|
||||||
@ -443,6 +444,7 @@ int main(int argc, char * argv[]) {
|
|||||||
finishPlaylist();
|
finishPlaylist();
|
||||||
freePlayerData();
|
freePlayerData();
|
||||||
finishAudioDriver();
|
finishAudioDriver();
|
||||||
|
finishAudioConfig();
|
||||||
finishVolume();
|
finishVolume();
|
||||||
finishPaths();
|
finishPaths();
|
||||||
finishPermissions();
|
finishPermissions();
|
||||||
|
@ -127,7 +127,7 @@ int playerInit() {
|
|||||||
else if(pc->stop) pc->stop = 0;
|
else if(pc->stop) pc->stop = 0;
|
||||||
else if(pc->pause) pc->pause = 0;
|
else if(pc->pause) pc->pause = 0;
|
||||||
else if(pc->closeAudio) {
|
else if(pc->closeAudio) {
|
||||||
finishAudio();
|
closeAudioDevice();
|
||||||
pc->closeAudio = 0;
|
pc->closeAudio = 0;
|
||||||
kill(getppid(),SIGUSR1);
|
kill(getppid(),SIGUSR1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user