1 /* the Music Player Daemon (MPD)
2 * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
3 * This project's homepage is: http://www.musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "audioOutput.h"
23 #include "sig_handlers.h"
25 #include "playerData.h"
27 #include "state_file.h"
34 #include <sys/param.h>
38 #define AUDIO_DEVICE_STATE "audio_device_state:"
39 #define AUDIO_DEVICE_STATE_LEN 19 /* strlen(AUDIO_DEVICE_STATE) */
40 #define AUDIO_BUFFER_SIZE 2*MAXPATHLEN
42 static AudioFormat audio_format
;
44 static AudioFormat
*audio_configFormat
;
46 static AudioOutput
*audioOutputArray
;
47 static mpd_uint8 audioOutputArraySize
;
49 #define DEVICE_OFF 0x00
50 #define DEVICE_ENABLE 0x01 /* currently off, but to be turned on */
51 #define DEVICE_ON 0x03
52 #define DEVICE_DISABLE 0x04 /* currently on, but to be turned off */
54 /* the audioEnabledArray should be stuck into shared memory, and then disable
55 and enable in playAudio() routine */
56 static mpd_uint8
*audioDeviceStates
;
58 static mpd_uint8 audioOpened
;
60 static mpd_sint32 audioBufferSize
;
61 static char *audioBuffer
;
62 static mpd_sint32 audioBufferPos
;
64 size_t audio_device_count(void)
67 ConfigParam
*param
= NULL
;
69 while ((param
= getNextConfigParam(CONF_AUDIO_OUTPUT
, param
)))
72 nr
= 1; /* we'll always have at least one device */
76 void copyAudioFormat(AudioFormat
* dest
, AudioFormat
* src
)
81 memcpy(dest
, src
, sizeof(AudioFormat
));
84 int cmpAudioFormat(AudioFormat
* f1
, AudioFormat
* f2
)
86 if (f1
&& f2
&& (f1
->sampleRate
== f2
->sampleRate
) &&
87 (f1
->bits
== f2
->bits
) && (f1
->channels
== f2
->channels
))
92 void loadAudioDrivers(void)
94 initAudioOutputPlugins();
95 loadAudioOutputPlugin(&shoutPlugin
);
96 loadAudioOutputPlugin(&nullPlugin
);
97 loadAudioOutputPlugin(&fifoPlugin
);
98 loadAudioOutputPlugin(&alsaPlugin
);
99 loadAudioOutputPlugin(&aoPlugin
);
100 loadAudioOutputPlugin(&ossPlugin
);
101 loadAudioOutputPlugin(&osxPlugin
);
102 loadAudioOutputPlugin(&pulsePlugin
);
103 loadAudioOutputPlugin(&mvpPlugin
);
104 loadAudioOutputPlugin(&jackPlugin
);
107 /* make sure initPlayerData is called before this function!! */
108 void initAudioDriver(void)
110 ConfigParam
*param
= NULL
;
115 audioOutputArraySize
= audio_device_count();
116 audioDeviceStates
= (getPlayerData())->audioDeviceStates
;
117 audioOutputArray
= xmalloc(sizeof(AudioOutput
) * audioOutputArraySize
);
119 for (i
= 0; i
< audioOutputArraySize
; i
++)
121 AudioOutput
*output
= &audioOutputArray
[i
];
124 param
= getNextConfigParam(CONF_AUDIO_OUTPUT
, param
);
126 /* only allow param to be NULL if there just one audioOutput */
127 assert(param
|| (audioOutputArraySize
== 1));
129 if (!initAudioOutput(output
, param
)) {
132 FATAL("problems configuring output device "
133 "defined at line %i\n", param
->line
);
137 FATAL("No audio_output specified and unable to "
138 "detect a default audio output device\n");
142 /* require output names to be unique: */
143 for (j
= 0; j
< i
; j
++) {
144 if (!strcmp(output
->name
, audioOutputArray
[j
].name
)) {
145 FATAL("output devices with identical "
146 "names: %s\n", output
->name
);
149 audioDeviceStates
[i
] = DEVICE_ENABLE
;
153 void getOutputAudioFormat(AudioFormat
* inAudioFormat
,
154 AudioFormat
* outAudioFormat
)
156 if (audio_configFormat
) {
157 copyAudioFormat(outAudioFormat
, audio_configFormat
);
159 copyAudioFormat(outAudioFormat
, inAudioFormat
);
162 void initAudioConfig(void)
164 ConfigParam
*param
= getConfigParam(CONF_AUDIO_OUTPUT_FORMAT
);
166 if (NULL
== param
|| NULL
== param
->value
)
169 audio_configFormat
= xmalloc(sizeof(AudioFormat
));
171 if (0 != parseAudioConfig(audio_configFormat
, param
->value
)) {
172 FATAL("error parsing \"%s\" at line %i\n",
173 CONF_AUDIO_OUTPUT_FORMAT
, param
->line
);
177 int parseAudioConfig(AudioFormat
* audioFormat
, char *conf
)
181 memset(audioFormat
, 0, sizeof(AudioFormat
));
183 audioFormat
->sampleRate
= strtol(conf
, &test
, 10);
186 ERROR("error parsing audio output format: %s\n", conf
);
190 /*switch(audioFormat->sampleRate) {
197 ERROR("sample rate %i can not be used for audio output\n",
198 (int)audioFormat->sampleRate);
202 if (audioFormat
->sampleRate
<= 0) {
203 ERROR("sample rate %i is not >= 0\n",
204 (int)audioFormat
->sampleRate
);
208 audioFormat
->bits
= strtol(test
+ 1, &test
, 10);
211 ERROR("error parsing audio output format: %s\n", conf
);
215 switch (audioFormat
->bits
) {
219 ERROR("bits %i can not be used for audio output\n",
220 (int)audioFormat
->bits
);
224 audioFormat
->channels
= strtol(test
+ 1, &test
, 10);
227 ERROR("error parsing audio output format: %s\n", conf
);
231 switch (audioFormat
->channels
) {
236 ERROR("channels %i can not be used for audio output\n",
237 (int)audioFormat
->channels
);
244 void finishAudioConfig(void)
246 if (audio_configFormat
)
247 free(audio_configFormat
);
250 void finishAudioDriver(void)
254 for (i
= 0; i
< audioOutputArraySize
; i
++) {
255 finishAudioOutput(&audioOutputArray
[i
]);
258 free(audioOutputArray
);
259 audioOutputArray
= NULL
;
260 audioOutputArraySize
= 0;
263 int isCurrentAudioFormat(AudioFormat
* audioFormat
)
268 if (cmpAudioFormat(audioFormat
, &audio_format
) != 0)
274 static void syncAudioDeviceStates(void)
276 AudioOutput
*audioOutput
;
279 if (!audio_format
.channels
)
282 for (i
= 0; i
< audioOutputArraySize
; ++i
) {
283 audioOutput
= &audioOutputArray
[i
];
284 switch (audioDeviceStates
[i
]) {
286 /* This will reopen only if the audio format changed */
287 if (openAudioOutput(audioOutput
, &audio_format
) < 0)
288 audioDeviceStates
[i
] = DEVICE_ENABLE
;
291 if (openAudioOutput(audioOutput
, &audio_format
) == 0)
292 audioDeviceStates
[i
] = DEVICE_ON
;
295 dropBufferedAudioOutput(audioOutput
);
296 closeAudioOutput(audioOutput
);
297 audioDeviceStates
[i
] = DEVICE_OFF
;
303 static int flushAudioBuffer(void)
308 if (audioBufferPos
== 0)
311 syncAudioDeviceStates();
313 for (i
= 0; i
< audioOutputArraySize
; ++i
) {
314 if (audioDeviceStates
[i
] != DEVICE_ON
)
316 err
= playAudioOutput(&audioOutputArray
[i
], audioBuffer
,
321 /* device should already be closed if the play
322 * func returned an error */
323 audioDeviceStates
[i
] = DEVICE_ENABLE
;
331 int openAudioDevice(AudioFormat
* audioFormat
)
336 if (!audioOutputArray
)
339 if (!audioOpened
|| !isCurrentAudioFormat(audioFormat
)) {
341 copyAudioFormat(&audio_format
, audioFormat
);
342 audioBufferSize
= (audio_format
.bits
>> 3) *
343 audio_format
.channels
;
344 audioBufferSize
*= audio_format
.sampleRate
>> 5;
345 audioBuffer
= xrealloc(audioBuffer
, audioBufferSize
);
348 syncAudioDeviceStates();
350 for (i
= 0; i
< audioOutputArraySize
; ++i
) {
351 if (audioOutputArray
[i
].open
)
358 /* close all devices if there was an error */
359 for (i
= 0; i
< audioOutputArraySize
; ++i
) {
360 closeAudioOutput(&audioOutputArray
[i
]);
369 int playAudio(char *playChunk
, int size
)
374 send
= audioBufferSize
- audioBufferPos
;
375 send
= send
< size
? send
: size
;
377 memcpy(audioBuffer
+ audioBufferPos
, playChunk
, send
);
378 audioBufferPos
+= send
;
382 if (audioBufferPos
== audioBufferSize
) {
383 if (flushAudioBuffer() < 0)
391 int isAudioDeviceOpen(void)
396 void dropBufferedAudio(void)
400 syncAudioDeviceStates();
403 for (i
= 0; i
< audioOutputArraySize
; ++i
) {
404 if (audioDeviceStates
[i
] == DEVICE_ON
)
405 dropBufferedAudioOutput(&audioOutputArray
[i
]);
409 void closeAudioDevice(void)
419 for (i
= 0; i
< audioOutputArraySize
; ++i
) {
420 if (audioDeviceStates
[i
] == DEVICE_ON
)
421 audioDeviceStates
[i
] = DEVICE_ENABLE
;
422 closeAudioOutput(&audioOutputArray
[i
]);
428 void sendMetadataToAudioDevice(MpdTag
* tag
)
432 for (i
= 0; i
< audioOutputArraySize
; ++i
) {
433 sendMetadataToAudioOutput(&audioOutputArray
[i
], tag
);
437 int enableAudioDevice(int fd
, int device
)
439 if (device
< 0 || device
>= audioOutputArraySize
) {
440 commandError(fd
, ACK_ERROR_ARG
, "audio output device id %i "
441 "doesn't exist\n", device
);
445 if (!(audioDeviceStates
[device
] & 0x01))
446 audioDeviceStates
[device
] = DEVICE_ENABLE
;
451 int disableAudioDevice(int fd
, int device
)
453 if (device
< 0 || device
>= audioOutputArraySize
) {
454 commandError(fd
, ACK_ERROR_ARG
, "audio output device id %i "
455 "doesn't exist\n", device
);
458 if (audioDeviceStates
[device
] & 0x01)
459 audioDeviceStates
[device
] = DEVICE_DISABLE
;
464 void printAudioDevices(int fd
)
468 for (i
= 0; i
< audioOutputArraySize
; i
++) {
470 "outputid: %i\noutputname: %s\noutputenabled: %i\n",
472 audioOutputArray
[i
].name
,
473 audioDeviceStates
[i
] & 0x01);
477 void saveAudioDevicesState(FILE *fp
)
481 assert(audioOutputArraySize
!= 0);
482 for (i
= 0; i
< audioOutputArraySize
; i
++) {
483 fprintf(fp
, AUDIO_DEVICE_STATE
"%d:%s\n",
484 audioDeviceStates
[i
] & 0x01,
485 audioOutputArray
[i
].name
);
489 void readAudioDevicesState(FILE *fp
)
491 char buffer
[AUDIO_BUFFER_SIZE
];
494 assert(audioOutputArraySize
!= 0);
496 while (myFgets(buffer
, AUDIO_BUFFER_SIZE
, fp
)) {
499 if (strncmp(buffer
, AUDIO_DEVICE_STATE
, AUDIO_DEVICE_STATE_LEN
))
502 c
= strchr(buffer
, ':');
506 name
= strchr(c
, ':');
507 if (!name
|| !(++name
))
510 for (i
= 0; i
< audioOutputArraySize
; ++i
) {
511 if (!strcmp(name
, audioOutputArray
[i
].name
)) {
512 /* devices default to on */
514 audioDeviceStates
[i
] = DEVICE_DISABLE
;
521 ERROR("invalid line in state_file: %s\n", buffer
);