aboutsummaryrefslogtreecommitdiffstats
path: root/trunk/src
diff options
context:
space:
mode:
authorJ. Alexander Treuman <jat@spatialrift.net>2007-05-28 15:50:45 +0000
committerJ. Alexander Treuman <jat@spatialrift.net>2007-05-28 15:50:45 +0000
commit4e05a161e54fe05902b99eff521aa0759b102f05 (patch)
tree9014ab8ce74e4fb2f0115c5518c62879bc269324 /trunk/src
parente45bc035931b2c9ef13b85f98a3d4833a8dec8a9 (diff)
downloadmpd-4e05a161e54fe05902b99eff521aa0759b102f05.tar.gz
mpd-4e05a161e54fe05902b99eff521aa0759b102f05.tar.xz
mpd-4e05a161e54fe05902b99eff521aa0759b102f05.zip
Making branch for 0.13.0 fixes.
git-svn-id: https://svn.musicpd.org/mpd/branches/branch-0.13.0-fixes@6330 09075e82-0dd4-0310-85a5-a0d7c8717e4f
Diffstat (limited to '')
-rw-r--r--trunk/src/Makefile.am148
-rw-r--r--trunk/src/ack.h37
-rw-r--r--trunk/src/audio.c518
-rw-r--r--trunk/src/audio.h83
-rw-r--r--trunk/src/audioOutput.c269
-rw-r--r--trunk/src/audioOutput.h117
-rw-r--r--trunk/src/audioOutputs/audioOutput_alsa.c427
-rw-r--r--trunk/src/audioOutputs/audioOutput_ao.c246
-rw-r--r--trunk/src/audioOutputs/audioOutput_jack.c440
-rw-r--r--trunk/src/audioOutputs/audioOutput_mvp.c284
-rw-r--r--trunk/src/audioOutputs/audioOutput_oss.c575
-rw-r--r--trunk/src/audioOutputs/audioOutput_osx.c374
-rw-r--r--trunk/src/audioOutputs/audioOutput_pulse.c221
-rw-r--r--trunk/src/audioOutputs/audioOutput_shout.c636
-rw-r--r--trunk/src/buffer2array.c132
-rw-r--r--trunk/src/buffer2array.h32
-rw-r--r--trunk/src/charConv.c168
-rw-r--r--trunk/src/charConv.h28
-rw-r--r--trunk/src/command.c1299
-rw-r--r--trunk/src/command.h50
-rw-r--r--trunk/src/compress.c411
-rw-r--r--trunk/src/compress.h47
-rw-r--r--trunk/src/conf.c450
-rw-r--r--trunk/src/conf.h98
-rw-r--r--trunk/src/dbUtils.c341
-rw-r--r--trunk/src/dbUtils.h51
-rw-r--r--trunk/src/decode.c706
-rw-r--r--trunk/src/decode.h69
-rw-r--r--trunk/src/directory.c1362
-rw-r--r--trunk/src/directory.h76
-rw-r--r--trunk/src/gcc.h67
-rw-r--r--trunk/src/inputPlugin.c158
-rw-r--r--trunk/src/inputPlugin.h109
-rw-r--r--trunk/src/inputPlugins/_flac_common.c211
-rw-r--r--trunk/src/inputPlugins/_flac_common.h187
-rw-r--r--trunk/src/inputPlugins/_ogg_common.c73
-rw-r--r--trunk/src/inputPlugins/_ogg_common.h35
-rw-r--r--trunk/src/inputPlugins/aac_plugin.c475
-rw-r--r--trunk/src/inputPlugins/audiofile_plugin.c188
-rw-r--r--trunk/src/inputPlugins/flac_plugin.c530
-rw-r--r--trunk/src/inputPlugins/mod_plugin.c299
-rw-r--r--trunk/src/inputPlugins/mp3_plugin.c1092
-rw-r--r--trunk/src/inputPlugins/mp4_plugin.c455
-rw-r--r--trunk/src/inputPlugins/mpc_plugin.c359
-rw-r--r--trunk/src/inputPlugins/oggflac_plugin.c423
-rw-r--r--trunk/src/inputPlugins/oggvorbis_plugin.c434
-rw-r--r--trunk/src/inputStream.c83
-rw-r--r--trunk/src/inputStream.h70
-rw-r--r--trunk/src/inputStream_file.c119
-rw-r--r--trunk/src/inputStream_file.h39
-rw-r--r--trunk/src/inputStream_http.c912
-rw-r--r--trunk/src/inputStream_http.h39
-rw-r--r--trunk/src/interface.c851
-rw-r--r--trunk/src/interface.h37
-rw-r--r--trunk/src/ioops.h51
-rw-r--r--trunk/src/list.c519
-rw-r--r--trunk/src/list.h110
-rw-r--r--trunk/src/listen.c258
-rw-r--r--trunk/src/listen.h41
-rw-r--r--trunk/src/locate.c211
-rw-r--r--trunk/src/locate.h46
-rw-r--r--trunk/src/log.c262
-rw-r--r--trunk/src/log.h50
-rw-r--r--trunk/src/ls.c281
-rw-r--r--trunk/src/ls.h52
-rw-r--r--trunk/src/main.c482
-rw-r--r--trunk/src/metadataChunk.c94
-rw-r--r--trunk/src/metadataChunk.h38
-rw-r--r--trunk/src/mp4ff/Makefile.am9
-rw-r--r--trunk/src/mp4ff/drms.c1043
-rw-r--r--trunk/src/mp4ff/drms.h40
-rw-r--r--trunk/src/mp4ff/drmstables.h449
-rw-r--r--trunk/src/mp4ff/mp4atom.c781
-rw-r--r--trunk/src/mp4ff/mp4ff.c430
-rw-r--r--trunk/src/mp4ff/mp4ff.dsp144
-rw-r--r--trunk/src/mp4ff/mp4ff.h128
-rw-r--r--trunk/src/mp4ff/mp4ff_int_types.h32
-rw-r--r--trunk/src/mp4ff/mp4ffint.h329
-rw-r--r--trunk/src/mp4ff/mp4meta.c414
-rw-r--r--trunk/src/mp4ff/mp4sample.c152
-rw-r--r--trunk/src/mp4ff/mp4tagupdate.c645
-rw-r--r--trunk/src/mp4ff/mp4util.c188
-rw-r--r--trunk/src/mpd_types.h43
-rw-r--r--trunk/src/myfprintf.c72
-rw-r--r--trunk/src/myfprintf.h31
-rw-r--r--trunk/src/normalize.c47
-rw-r--r--trunk/src/normalize.h32
-rw-r--r--trunk/src/outputBuffer.c198
-rw-r--r--trunk/src/outputBuffer.h69
-rw-r--r--trunk/src/path.c310
-rw-r--r--trunk/src/path.h69
-rw-r--r--trunk/src/pcm_utils.c470
-rw-r--r--trunk/src/pcm_utils.h57
-rw-r--r--trunk/src/permission.c140
-rw-r--r--trunk/src/permission.h39
-rw-r--r--trunk/src/player.c530
-rw-r--r--trunk/src/player.h154
-rw-r--r--trunk/src/playerData.c162
-rw-r--r--trunk/src/playerData.h49
-rw-r--r--trunk/src/playlist.c1499
-rw-r--r--trunk/src/playlist.h144
-rw-r--r--trunk/src/replayGain.c165
-rw-r--r--trunk/src/replayGain.h50
-rw-r--r--trunk/src/sig_handlers.c159
-rw-r--r--trunk/src/sig_handlers.h42
-rw-r--r--trunk/src/signal_check.c60
-rw-r--r--trunk/src/signal_check.h30
-rw-r--r--trunk/src/sllist.c72
-rw-r--r--trunk/src/sllist.h52
-rw-r--r--trunk/src/song.c353
-rw-r--r--trunk/src/song.h79
-rw-r--r--trunk/src/state_file.c111
-rw-r--r--trunk/src/state_file.h30
-rw-r--r--trunk/src/stats.c48
-rw-r--r--trunk/src/stats.h40
-rw-r--r--trunk/src/storedPlaylist.c501
-rw-r--r--trunk/src/storedPlaylist.h48
-rw-r--r--trunk/src/tag.c646
-rw-r--r--trunk/src/tag.h89
-rw-r--r--trunk/src/tagTracker.c147
-rw-r--r--trunk/src/tagTracker.h38
-rw-r--r--trunk/src/tree.c706
-rw-r--r--trunk/src/tree.h62
-rw-r--r--trunk/src/utf8.c148
-rw-r--r--trunk/src/utf8.h28
-rw-r--r--trunk/src/utils.c161
-rw-r--r--trunk/src/utils.h85
-rw-r--r--trunk/src/volume.c552
-rw-r--r--trunk/src/volume.h44
-rw-r--r--trunk/src/zeroconf.c498
-rw-r--r--trunk/src/zeroconf.h27
131 files changed, 0 insertions, 33405 deletions
diff --git a/trunk/src/Makefile.am b/trunk/src/Makefile.am
deleted file mode 100644
index b9c6fa0c7..000000000
--- a/trunk/src/Makefile.am
+++ /dev/null
@@ -1,148 +0,0 @@
-bin_PROGRAMS = mpd
-SUBDIRS = $(MP4FF_SUBDIR)
-
-mpd_audioOutputs = \
- audioOutputs/audioOutput_alsa.c \
- audioOutputs/audioOutput_ao.c \
- audioOutputs/audioOutput_oss.c \
- audioOutputs/audioOutput_osx.c \
- audioOutputs/audioOutput_pulse.c \
- audioOutputs/audioOutput_mvp.c \
- audioOutputs/audioOutput_shout.c \
- audioOutputs/audioOutput_jack.c
-
-mpd_inputPlugins = \
- inputPlugins/_flac_common.c \
- inputPlugins/_ogg_common.c \
- inputPlugins/oggflac_plugin.c \
- inputPlugins/oggvorbis_plugin.c \
- inputPlugins/aac_plugin.c \
- inputPlugins/audiofile_plugin.c \
- inputPlugins/flac_plugin.c \
- inputPlugins/mod_plugin.c \
- inputPlugins/mp3_plugin.c \
- inputPlugins/mp4_plugin.c \
- inputPlugins/mpc_plugin.c
-
-
-mpd_headers = \
- ack.h \
- audio.h \
- audioOutput.h \
- buffer2array.h \
- charConv.h \
- command.h \
- conf.h \
- dbUtils.h \
- decode.h \
- directory.h \
- gcc.h \
- inputPlugin.h \
- inputPlugins/_flac_common.h \
- inputPlugins/_ogg_common.h \
- inputStream.h \
- inputStream_file.h \
- inputStream_http.h \
- interface.h \
- list.h \
- listen.h \
- log.h \
- ls.h \
- metadataChunk.h \
- mpd_types.h \
- myfprintf.h \
- normalize.h \
- compress.h \
- outputBuffer.h \
- path.h \
- pcm_utils.h \
- permission.h \
- player.h \
- playerData.h \
- playlist.h \
- replayGain.h \
- signal_check.h \
- sig_handlers.h \
- sllist.h \
- song.h \
- state_file.h \
- stats.h \
- tag.h \
- tagTracker.h \
- tree.h \
- utf8.h \
- utils.h \
- volume.h \
- ioops.h \
- zeroconf.h \
- locate.h \
- storedPlaylist.h
-
-
-mpd_SOURCES = \
- $(mpd_headers) \
- $(mpd_audioOutputs) \
- $(mpd_inputPlugins) \
- audio.c \
- audioOutput.c \
- buffer2array.c \
- charConv.c \
- command.c \
- conf.c \
- dbUtils.c \
- decode.c \
- directory.c \
- inputPlugin.c \
- inputStream.c \
- inputStream_file.c \
- inputStream_http.c \
- interface.c \
- list.c \
- listen.c \
- log.c \
- ls.c \
- main.c \
- metadataChunk.c \
- myfprintf.c \
- normalize.c \
- compress.c \
- outputBuffer.c \
- path.c \
- pcm_utils.c \
- permission.c \
- player.c \
- playerData.c \
- playlist.c \
- replayGain.c \
- sig_handlers.c \
- signal_check.c \
- sllist.c \
- song.c \
- state_file.c \
- stats.c \
- tag.c \
- tagTracker.c \
- tree.c \
- utils.c \
- volume.c \
- utf8.c \
- zeroconf.c \
- locate.c \
- storedPlaylist.c
-
-
-mpd_CFLAGS = $(MPD_CFLAGS)
-mpd_LDADD = $(MPD_LIBS) $(MP4FF_LIB)
-
-DIST_SUBDIRS = mp4ff
-
-# sparse is a semantic parser
-# URL: git://www.kernel.org/pub/scm/devel/sparse/sparse.git
-SPARSE = sparse
-SPARSE_FLAGS =
-sparse-check:
- for i in $(mpd_SOURCES); \
- do \
- $(SPARSE) -I. $(mpd_CFLAGS) $(SPARSE_FLAGS) $(srcdir)/$$i || exit; \
- done
-
diff --git a/trunk/src/ack.h b/trunk/src/ack.h
deleted file mode 100644
index 1b2950e20..000000000
--- a/trunk/src/ack.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef ACK_H
-#define ACK_H
-
-/* Common Errors */
-#define ACK_ERROR_NOT_LIST 1
-#define ACK_ERROR_ARG 2
-#define ACK_ERROR_PASSWORD 3
-#define ACK_ERROR_PERMISSION 4
-#define ACK_ERROR_UNKNOWN 5
-
-#define ACK_ERROR_NO_EXIST 50
-#define ACK_ERROR_PLAYLIST_MAX 51
-#define ACK_ERROR_SYSTEM 52
-#define ACK_ERROR_PLAYLIST_LOAD 53
-#define ACK_ERROR_UPDATE_ALREADY 54
-#define ACK_ERROR_PLAYER_SYNC 55
-#define ACK_ERROR_EXIST 56
-
-#endif
diff --git a/trunk/src/audio.c b/trunk/src/audio.c
deleted file mode 100644
index 912e46ffa..000000000
--- a/trunk/src/audio.c
+++ /dev/null
@@ -1,518 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "audio.h"
-#include "audioOutput.h"
-#include "conf.h"
-#include "log.h"
-#include "sig_handlers.h"
-#include "command.h"
-#include "playerData.h"
-#include "utils.h"
-#include "state_file.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <errno.h>
-#include <unistd.h>
-
-#define AUDIO_DEVICE_STATE "audio_device_state:"
-#define AUDIO_DEVICE_STATE_LEN 19 /* strlen(AUDIO_DEVICE_STATE) */
-#define AUDIO_BUFFER_SIZE 2*MAXPATHLEN
-
-static AudioFormat audio_format;
-
-static AudioFormat *audio_configFormat;
-
-static AudioOutput *audioOutputArray;
-static mpd_uint8 audioOutputArraySize;
-
-#define DEVICE_OFF 0x00
-#define DEVICE_ENABLE 0x01 /* currently off, but to be turned on */
-#define DEVICE_ON 0x03
-#define DEVICE_DISABLE 0x04 /* currently on, but to be turned off */
-
-/* the audioEnabledArray should be stuck into shared memory, and then disable
- and enable in playAudio() routine */
-static mpd_uint8 *audioDeviceStates;
-
-static mpd_uint8 audioOpened;
-
-static mpd_sint32 audioBufferSize;
-static char *audioBuffer;
-static mpd_sint32 audioBufferPos;
-
-size_t audio_device_count(void)
-{
- size_t nr = 0;
- ConfigParam *param = NULL;
-
- while ((param = getNextConfigParam(CONF_AUDIO_OUTPUT, param)))
- nr++;
- if (!nr)
- nr = 1; /* we'll always have at least one device */
- return nr;
-}
-
-void copyAudioFormat(AudioFormat * dest, AudioFormat * src)
-{
- if (!src)
- return;
-
- memcpy(dest, src, sizeof(AudioFormat));
-}
-
-int cmpAudioFormat(AudioFormat * f1, AudioFormat * f2)
-{
- if (f1 && f2 && (f1->sampleRate == f2->sampleRate) &&
- (f1->bits == f2->bits) && (f1->channels == f2->channels))
- return 0;
- return 1;
-}
-
-void loadAudioDrivers(void)
-{
- initAudioOutputPlugins();
- loadAudioOutputPlugin(&alsaPlugin);
- loadAudioOutputPlugin(&aoPlugin);
- loadAudioOutputPlugin(&ossPlugin);
- loadAudioOutputPlugin(&osxPlugin);
- loadAudioOutputPlugin(&pulsePlugin);
- loadAudioOutputPlugin(&mvpPlugin);
- loadAudioOutputPlugin(&shoutPlugin);
- loadAudioOutputPlugin(&jackPlugin);
-}
-
-/* make sure initPlayerData is called before this function!! */
-void initAudioDriver(void)
-{
- ConfigParam *param = NULL;
- int i;
-
- loadAudioDrivers();
-
- audioOutputArraySize = audio_device_count();
- audioDeviceStates = (getPlayerData())->audioDeviceStates;
- audioOutputArray = xmalloc(sizeof(AudioOutput) * audioOutputArraySize);
-
- for (i = 0; i < audioOutputArraySize; i++)
- {
- AudioOutput *output = &audioOutputArray[i];
- int j;
-
- param = getNextConfigParam(CONF_AUDIO_OUTPUT, param);
-
- /* only allow param to be NULL if there just one audioOutput */
- assert(param || (audioOutputArraySize == 1));
-
- if (!initAudioOutput(output, param)) {
- if (param)
- {
- FATAL("problems configuring output device "
- "defined at line %i\n", param->line);
- }
- else
- {
- FATAL("No audio_output specified and unable to "
- "detect a default audio output device\n");
- }
- }
-
- /* require output names to be unique: */
- for (j = 0; j < i; j++) {
- if (!strcmp(output->name, audioOutputArray[j].name)) {
- FATAL("output devices with identical "
- "names: %s\n", output->name);
- }
- }
- audioDeviceStates[i] = DEVICE_ENABLE;
- }
-}
-
-void getOutputAudioFormat(AudioFormat * inAudioFormat,
- AudioFormat * outAudioFormat)
-{
- if (audio_configFormat) {
- copyAudioFormat(outAudioFormat, audio_configFormat);
- } else
- copyAudioFormat(outAudioFormat, inAudioFormat);
-}
-
-void initAudioConfig(void)
-{
- ConfigParam *param = getConfigParam(CONF_AUDIO_OUTPUT_FORMAT);
-
- if (NULL == param || NULL == param->value)
- return;
-
- audio_configFormat = xmalloc(sizeof(AudioFormat));
-
- if (0 != parseAudioConfig(audio_configFormat, param->value)) {
- FATAL("error parsing \"%s\" at line %i\n",
- CONF_AUDIO_OUTPUT_FORMAT, param->line);
- }
-}
-
-int parseAudioConfig(AudioFormat * audioFormat, char *conf)
-{
- char *test;
-
- memset(audioFormat, 0, sizeof(AudioFormat));
-
- audioFormat->sampleRate = strtol(conf, &test, 10);
-
- if (*test != ':') {
- ERROR("error parsing audio output format: %s\n", conf);
- return -1;
- }
-
- /*switch(audioFormat->sampleRate) {
- case 48000:
- case 44100:
- case 32000:
- case 16000:
- break;
- default:
- ERROR("sample rate %i can not be used for audio output\n",
- (int)audioFormat->sampleRate);
- return -1
- } */
-
- if (audioFormat->sampleRate <= 0) {
- ERROR("sample rate %i is not >= 0\n",
- (int)audioFormat->sampleRate);
- return -1;
- }
-
- audioFormat->bits = strtol(test + 1, &test, 10);
-
- if (*test != ':') {
- ERROR("error parsing audio output format: %s\n", conf);
- return -1;
- }
-
- switch (audioFormat->bits) {
- case 16:
- break;
- default:
- ERROR("bits %i can not be used for audio output\n",
- (int)audioFormat->bits);
- return -1;
- }
-
- audioFormat->channels = strtol(test + 1, &test, 10);
-
- if (*test != '\0') {
- ERROR("error parsing audio output format: %s\n", conf);
- return -1;
- }
-
- switch (audioFormat->channels) {
- case 1:
- case 2:
- break;
- default:
- ERROR("channels %i can not be used for audio output\n",
- (int)audioFormat->channels);
- return -1;
- }
-
- return 0;
-}
-
-void finishAudioConfig(void)
-{
- if (audio_configFormat)
- free(audio_configFormat);
-}
-
-void finishAudioDriver(void)
-{
- int i;
-
- for (i = 0; i < audioOutputArraySize; i++) {
- finishAudioOutput(&audioOutputArray[i]);
- }
-
- free(audioOutputArray);
- audioOutputArray = NULL;
- audioOutputArraySize = 0;
-}
-
-int isCurrentAudioFormat(AudioFormat * audioFormat)
-{
- if (!audioFormat)
- return 1;
-
- if (cmpAudioFormat(audioFormat, &audio_format) != 0)
- return 0;
-
- return 1;
-}
-
-static void syncAudioDeviceStates(void)
-{
- int i;
-
- if (!audio_format.channels)
- return;
- for (i = 0; i < audioOutputArraySize; ++i ) {
- switch (audioDeviceStates[i]) {
- case DEVICE_ON:
- /* This will reopen only if the audio format changed */
- openAudioOutput(&audioOutputArray[i], &audio_format);
- break;
- case DEVICE_ENABLE:
- openAudioOutput(&audioOutputArray[i], &audio_format);
- audioDeviceStates[i] = DEVICE_ON;
- break;
- case DEVICE_DISABLE:
- dropBufferedAudioOutput(&audioOutputArray[i]);
- closeAudioOutput(&audioOutputArray[i]);
- audioDeviceStates[i] = DEVICE_OFF;
- break;
- }
- }
-}
-
-static int flushAudioBuffer(void)
-{
- int ret = -1;
- int i, err;
-
- if (audioBufferPos == 0)
- return 0;
-
- syncAudioDeviceStates();
-
- for (i = 0; i < audioOutputArraySize; ++i) {
- if (audioDeviceStates[i] != DEVICE_ON)
- continue;
- err = playAudioOutput(&audioOutputArray[i], audioBuffer,
- audioBufferPos);
- if (!err)
- ret = 0;
- else if (err < 0)
- /* device should already be closed if the play
- * func returned an error */
- audioDeviceStates[i] = DEVICE_ENABLE;
- }
-
- audioBufferPos = 0;
-
- return ret;
-}
-
-int openAudioDevice(AudioFormat * audioFormat)
-{
- int ret = -1;
- int i;
-
- if (!audioOutputArray)
- return -1;
-
- if (!audioOpened || !isCurrentAudioFormat(audioFormat)) {
- flushAudioBuffer();
- copyAudioFormat(&audio_format, audioFormat);
- audioBufferSize = (audio_format.bits >> 3) *
- audio_format.channels;
- audioBufferSize *= audio_format.sampleRate >> 5;
- audioBuffer = xrealloc(audioBuffer, audioBufferSize);
- }
-
- syncAudioDeviceStates();
-
- for (i = 0; i < audioOutputArraySize; ++i) {
- if (audioOutputArray[i].open)
- ret = 0;
- }
-
- if (ret == 0)
- audioOpened = 1;
- else {
- /* close all devices if there was an error */
- for (i = 0; i < audioOutputArraySize; ++i) {
- closeAudioOutput(&audioOutputArray[i]);
- }
-
- audioOpened = 0;
- }
-
- return ret;
-}
-
-int playAudio(char *playChunk, int size)
-{
- int send;
-
- while (size > 0) {
- send = audioBufferSize - audioBufferPos;
- send = send < size ? send : size;
-
- memcpy(audioBuffer + audioBufferPos, playChunk, send);
- audioBufferPos += send;
- size -= send;
- playChunk += send;
-
- if (audioBufferPos == audioBufferSize) {
- if (flushAudioBuffer() < 0)
- return -1;
- }
- }
-
- return 0;
-}
-
-int isAudioDeviceOpen(void)
-{
- return audioOpened;
-}
-
-void dropBufferedAudio(void)
-{
- int i;
-
- syncAudioDeviceStates();
- audioBufferPos = 0;
-
- for (i = 0; i < audioOutputArraySize; ++i) {
- if (audioDeviceStates[i] == DEVICE_ON)
- dropBufferedAudioOutput(&audioOutputArray[i]);
- }
-}
-
-void closeAudioDevice(void)
-{
- int i;
-
- flushAudioBuffer();
-
- free(audioBuffer);
- audioBuffer = NULL;
- audioBufferSize = 0;
-
- for (i = 0; i < audioOutputArraySize; ++i) {
- if (audioDeviceStates[i] == DEVICE_ON)
- audioDeviceStates[i] = DEVICE_ENABLE;
- closeAudioOutput(&audioOutputArray[i]);
- }
-
- audioOpened = 0;
-}
-
-void sendMetadataToAudioDevice(MpdTag * tag)
-{
- int i;
-
- for (i = 0; i < audioOutputArraySize; ++i) {
- sendMetadataToAudioOutput(&audioOutputArray[i], tag);
- }
-}
-
-int enableAudioDevice(int fd, int device)
-{
- if (device < 0 || device >= audioOutputArraySize) {
- commandError(fd, ACK_ERROR_ARG, "audio output device id %i "
- "doesn't exist\n", device);
- return -1;
- }
-
- if (!(audioDeviceStates[device] & 0x01))
- audioDeviceStates[device] = DEVICE_ENABLE;
-
- return 0;
-}
-
-int disableAudioDevice(int fd, int device)
-{
- if (device < 0 || device >= audioOutputArraySize) {
- commandError(fd, ACK_ERROR_ARG, "audio output device id %i "
- "doesn't exist\n", device);
- return -1;
- }
- if (audioDeviceStates[device] & 0x01)
- audioDeviceStates[device] = DEVICE_DISABLE;
-
- return 0;
-}
-
-void printAudioDevices(int fd)
-{
- int i;
-
- for (i = 0; i < audioOutputArraySize; i++) {
- fdprintf(fd,
- "outputid: %i\noutputname: %s\noutputenabled: %i\n",
- i,
- audioOutputArray[i].name,
- audioDeviceStates[i] & 0x01);
- }
-}
-
-void saveAudioDevicesState(FILE *fp)
-{
- int i;
-
- assert(audioOutputArraySize != 0);
- for (i = 0; i < audioOutputArraySize; i++) {
- fprintf(fp, AUDIO_DEVICE_STATE "%d:%s\n",
- audioDeviceStates[i] & 0x01,
- audioOutputArray[i].name);
- }
-}
-
-void readAudioDevicesState(FILE *fp)
-{
- char buffer[AUDIO_BUFFER_SIZE];
- int i;
-
- assert(audioOutputArraySize != 0);
-
- while (myFgets(buffer, AUDIO_BUFFER_SIZE, fp)) {
- char *c, *name;
-
- if (strncmp(buffer, AUDIO_DEVICE_STATE, AUDIO_DEVICE_STATE_LEN))
- continue;
-
- c = strchr(buffer, ':');
- if (!c || !(++c))
- goto errline;
-
- name = strchr(c, ':');
- if (!name || !(++name))
- goto errline;
-
- for (i = 0; i < audioOutputArraySize; ++i) {
- if (!strcmp(name, audioOutputArray[i].name)) {
- /* devices default to on */
- if (!atoi(c))
- audioDeviceStates[i] = DEVICE_DISABLE;
- break;
- }
- }
- continue;
-errline:
- /* nonfatal */
- ERROR("invalid line in state_file: %s\n", buffer);
- }
-}
-
diff --git a/trunk/src/audio.h b/trunk/src/audio.h
deleted file mode 100644
index cc4ac0752..000000000
--- a/trunk/src/audio.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef AUDIO_H
-#define AUDIO_H
-
-#include "../config.h"
-
-#include "mpd_types.h"
-#include "tag.h"
-
-#include <stdio.h>
-
-#define AUDIO_AO_DRIVER_DEFAULT "default"
-
-typedef struct _AudioFormat {
- volatile mpd_sint8 channels;
- volatile mpd_uint32 sampleRate;
- volatile mpd_sint8 bits;
-} AudioFormat;
-
-size_t audio_device_count(void);
-
-void copyAudioFormat(AudioFormat * dest, AudioFormat * src);
-
-int cmpAudioFormat(AudioFormat * dest, AudioFormat * src);
-
-void getOutputAudioFormat(AudioFormat * inFormat, AudioFormat * outFormat);
-
-int parseAudioConfig(AudioFormat * audioFormat, char *conf);
-
-/* make sure initPlayerData is called before this function!! */
-void initAudioConfig(void);
-
-void finishAudioConfig(void);
-
-void initAudioDriver(void);
-
-void finishAudioDriver(void);
-
-int openAudioDevice(AudioFormat * audioFormat);
-
-int playAudio(char *playChunk, int size);
-
-void dropBufferedAudio(void);
-
-void closeAudioDevice(void);
-
-int isAudioDeviceOpen(void);
-
-int isCurrentAudioFormat(AudioFormat * audioFormat);
-
-void sendMetadataToAudioDevice(MpdTag * tag);
-
-/* these functions are called in the main parent process while the child
- process is busy playing to the audio */
-int enableAudioDevice(int fd, int device);
-
-int disableAudioDevice(int fd, int device);
-
-void printAudioDevices(int fd);
-
-void readAudioDevicesState(FILE *fp);
-
-void saveAudioDevicesState(FILE *fp);
-
-void loadAudioDrivers(void);
-#endif
diff --git a/trunk/src/audioOutput.c b/trunk/src/audioOutput.c
deleted file mode 100644
index 49a7ce258..000000000
--- a/trunk/src/audioOutput.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "audioOutput.h"
-
-#include "list.h"
-#include "log.h"
-#include "pcm_utils.h"
-
-#include <string.h>
-
-#define AUDIO_OUTPUT_TYPE "type"
-#define AUDIO_OUTPUT_NAME "name"
-#define AUDIO_OUTPUT_FORMAT "format"
-
-static List *audioOutputPluginList;
-
-void loadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin)
-{
- if (!audioOutputPlugin->name)
- return;
- insertInList(audioOutputPluginList, audioOutputPlugin->name,
- audioOutputPlugin);
-}
-
-void unloadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin)
-{
- if (!audioOutputPlugin->name)
- return;
- deleteFromList(audioOutputPluginList, audioOutputPlugin->name);
-}
-
-void initAudioOutputPlugins(void)
-{
- audioOutputPluginList = makeList(NULL, 0);
-}
-
-void finishAudioOutputPlugins(void)
-{
- freeList(audioOutputPluginList);
-}
-
-#define getBlockParam(name, str, force) { \
- bp = getBlockParam(param, name); \
- if(force && bp == NULL) { \
- FATAL("couldn't find parameter \"%s\" in audio output " \
- "definition beginning at %i\n", \
- name, param->line); \
- } \
- if(bp) str = bp->value; \
-}
-
-int initAudioOutput(AudioOutput *ao, ConfigParam * param)
-{
- void *data = NULL;
- char *name = NULL;
- char *format = NULL;
- char *type = NULL;
- BlockParam *bp = NULL;
- AudioOutputPlugin *plugin = NULL;
-
- if (param) {
- getBlockParam(AUDIO_OUTPUT_NAME, name, 1);
- getBlockParam(AUDIO_OUTPUT_TYPE, type, 1);
- getBlockParam(AUDIO_OUTPUT_FORMAT, format, 0);
-
- if (!findInList(audioOutputPluginList, type, &data)) {
- FATAL("couldn't find audio output plugin for type "
- "\"%s\" at line %i\n", type, param->line);
- }
-
- plugin = (AudioOutputPlugin *) data;
- } else {
- ListNode *node = audioOutputPluginList->firstNode;
-
- WARNING("No \"%s\" defined in config file\n",
- CONF_AUDIO_OUTPUT);
- WARNING("Attempt to detect audio output device\n");
-
- while (node) {
- plugin = (AudioOutputPlugin *) node->data;
- if (plugin->testDefaultDeviceFunc) {
- WARNING("Attempting to detect a %s audio "
- "device\n", plugin->name);
- if (plugin->testDefaultDeviceFunc() == 0) {
- WARNING("Successfully detected a %s "
- "audio device\n", plugin->name);
- break;
- }
- }
- node = node->nextNode;
- }
-
- if (!node) {
- WARNING("Unable to detect an audio device\n");
- return 0;
- }
-
- name = "default detected output";
- type = plugin->name;
- }
-
- ao->name = name;
- ao->type = type;
- ao->finishDriverFunc = plugin->finishDriverFunc;
- ao->openDeviceFunc = plugin->openDeviceFunc;
- ao->playFunc = plugin->playFunc;
- ao->dropBufferedAudioFunc = plugin->dropBufferedAudioFunc;
- ao->closeDeviceFunc = plugin->closeDeviceFunc;
- ao->sendMetdataFunc = plugin->sendMetdataFunc;
- ao->open = 0;
-
- ao->convertAudioFormat = 0;
- ao->sameInAndOutFormats = 0;
- ao->convBuffer = NULL;
- ao->convBufferLen = 0;
-
- memset(&ao->inAudioFormat, 0, sizeof(AudioFormat));
- memset(&ao->outAudioFormat, 0, sizeof(AudioFormat));
- memset(&ao->reqAudioFormat, 0, sizeof(AudioFormat));
- memset(&ao->convState, 0, sizeof(ConvState));
-
- if (format) {
- ao->convertAudioFormat = 1;
-
- if (0 != parseAudioConfig(&ao->reqAudioFormat, format)) {
- FATAL("error parsing format at line %i\n", bp->line);
- }
-
- copyAudioFormat(&ao->outAudioFormat, &ao->reqAudioFormat);
- }
-
- if (plugin->initDriverFunc(ao, param) != 0)
- return 0;
-
- return 1;
-}
-
-int openAudioOutput(AudioOutput * audioOutput, AudioFormat * audioFormat)
-{
- int ret = 0;
-
- if (audioOutput->open)
- {
- if (0==cmpAudioFormat(audioFormat, &audioOutput->inAudioFormat))
- {
- return 0;
- }
- }
-
- copyAudioFormat(&audioOutput->inAudioFormat, audioFormat);
-
- if (audioOutput->convertAudioFormat)
- {
- copyAudioFormat(&audioOutput->outAudioFormat,
- &audioOutput->reqAudioFormat);
- }
- else
- {
- copyAudioFormat(&audioOutput->outAudioFormat,
- &audioOutput->inAudioFormat);
- if (audioOutput->open) closeAudioOutput(audioOutput);
- }
-
- if (!audioOutput->open)
- {
- ret = audioOutput->openDeviceFunc(audioOutput);
- }
-
- audioOutput->sameInAndOutFormats =
- !cmpAudioFormat(&audioOutput->inAudioFormat,
- &audioOutput->outAudioFormat);
-
- return ret;
-}
-
-static void convertAudioFormat(AudioOutput * audioOutput, char **chunkArgPtr,
- int *sizeArgPtr)
-{
- int size = pcm_sizeOfConvBuffer(&(audioOutput->inAudioFormat),
- *sizeArgPtr,
- &(audioOutput->outAudioFormat));
-
- if (size > audioOutput->convBufferLen) {
- audioOutput->convBuffer =
- xrealloc(audioOutput->convBuffer, size);
- audioOutput->convBufferLen = size;
- }
-
- *sizeArgPtr = pcm_convertAudioFormat(&(audioOutput->inAudioFormat),
- *chunkArgPtr, *sizeArgPtr,
- &(audioOutput->outAudioFormat),
- audioOutput->convBuffer,
- &audioOutput->convState);
-
- *chunkArgPtr = audioOutput->convBuffer;
-}
-
-int playAudioOutput(AudioOutput * audioOutput, char *playChunk, int size)
-{
- int ret;
-
- if (!audioOutput->open)
- return -1;
-
- if (!audioOutput->sameInAndOutFormats) {
- convertAudioFormat(audioOutput, &playChunk, &size);
- }
-
- ret = audioOutput->playFunc(audioOutput, playChunk, size);
-
- return ret;
-}
-
-void dropBufferedAudioOutput(AudioOutput * audioOutput)
-{
- if (audioOutput->open)
- audioOutput->dropBufferedAudioFunc(audioOutput);
-}
-
-void closeAudioOutput(AudioOutput * audioOutput)
-{
- if (audioOutput->open)
- audioOutput->closeDeviceFunc(audioOutput);
-}
-
-void finishAudioOutput(AudioOutput * audioOutput)
-{
- closeAudioOutput(audioOutput);
- audioOutput->finishDriverFunc(audioOutput);
- if (audioOutput->convBuffer)
- free(audioOutput->convBuffer);
-}
-
-void sendMetadataToAudioOutput(AudioOutput * audioOutput, MpdTag * tag)
-{
- if (!audioOutput->sendMetdataFunc)
- return;
- audioOutput->sendMetdataFunc(audioOutput, tag);
-}
-
-void printAllOutputPluginTypes(FILE * fp)
-{
- ListNode *node = audioOutputPluginList->firstNode;
- AudioOutputPlugin *plugin;
-
- while (node) {
- plugin = (AudioOutputPlugin *) node->data;
- fprintf(fp, "%s ", plugin->name);
- node = node->nextNode;
- }
- fprintf(fp, "\n");
- fflush(fp);
-}
diff --git a/trunk/src/audioOutput.h b/trunk/src/audioOutput.h
deleted file mode 100644
index bcbe7997d..000000000
--- a/trunk/src/audioOutput.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef AUDIO_OUTPUT_H
-#define AUDIO_OUTPUT_H
-
-#include "../config.h"
-
-#include "pcm_utils.h"
-#include "mpd_types.h"
-#include "audio.h"
-#include "tag.h"
-#include "conf.h"
-#include "utils.h"
-
-#define DISABLED_AUDIO_OUTPUT_PLUGIN(plugin) AudioOutputPlugin plugin;
-
-typedef struct _AudioOutput AudioOutput;
-
-typedef int (*AudioOutputTestDefaultDeviceFunc) ();
-
-typedef int (*AudioOutputInitDriverFunc) (AudioOutput * audioOutput,
- ConfigParam * param);
-
-typedef void (*AudioOutputFinishDriverFunc) (AudioOutput * audioOutput);
-
-typedef int (*AudioOutputOpenDeviceFunc) (AudioOutput * audioOutput);
-
-typedef int (*AudioOutputPlayFunc) (AudioOutput * audioOutput,
- char *playChunk, int size);
-
-typedef void (*AudioOutputDropBufferedAudioFunc) (AudioOutput * audioOutput);
-
-typedef void (*AudioOutputCloseDeviceFunc) (AudioOutput * audioOutput);
-
-typedef void (*AudioOutputSendMetadataFunc) (AudioOutput * audioOutput,
- MpdTag * tag);
-
-struct _AudioOutput {
- int open;
- char *name;
- char *type;
-
- AudioOutputFinishDriverFunc finishDriverFunc;
- AudioOutputOpenDeviceFunc openDeviceFunc;
- AudioOutputPlayFunc playFunc;
- AudioOutputDropBufferedAudioFunc dropBufferedAudioFunc;
- AudioOutputCloseDeviceFunc closeDeviceFunc;
- AudioOutputSendMetadataFunc sendMetdataFunc;
-
- int convertAudioFormat;
- AudioFormat inAudioFormat;
- AudioFormat outAudioFormat;
- AudioFormat reqAudioFormat;
- ConvState convState;
- char *convBuffer;
- int convBufferLen;
- int sameInAndOutFormats;
-
- void *data;
-};
-
-typedef struct _AudioOutputPlugin {
- char *name;
-
- AudioOutputTestDefaultDeviceFunc testDefaultDeviceFunc;
- AudioOutputInitDriverFunc initDriverFunc;
- AudioOutputFinishDriverFunc finishDriverFunc;
- AudioOutputOpenDeviceFunc openDeviceFunc;
- AudioOutputPlayFunc playFunc;
- AudioOutputDropBufferedAudioFunc dropBufferedAudioFunc;
- AudioOutputCloseDeviceFunc closeDeviceFunc;
- AudioOutputSendMetadataFunc sendMetdataFunc;
-} AudioOutputPlugin;
-
-void initAudioOutputPlugins(void);
-void finishAudioOutputPlugins(void);
-
-void loadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin);
-void unloadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin);
-
-int initAudioOutput(AudioOutput *, ConfigParam * param);
-int openAudioOutput(AudioOutput * audioOutput, AudioFormat * audioFormat);
-int playAudioOutput(AudioOutput * audioOutput, char *playChunk, int size);
-void dropBufferedAudioOutput(AudioOutput * audioOutput);
-void closeAudioOutput(AudioOutput * audioOutput);
-void finishAudioOutput(AudioOutput * audioOutput);
-int keepAudioOutputAlive(AudioOutput * audioOutput, int ms);
-void sendMetadataToAudioOutput(AudioOutput * audioOutput, MpdTag * tag);
-
-void printAllOutputPluginTypes(FILE * fp);
-
-extern AudioOutputPlugin alsaPlugin;
-extern AudioOutputPlugin aoPlugin;
-extern AudioOutputPlugin ossPlugin;
-extern AudioOutputPlugin osxPlugin;
-extern AudioOutputPlugin pulsePlugin;
-extern AudioOutputPlugin mvpPlugin;
-extern AudioOutputPlugin shoutPlugin;
-extern AudioOutputPlugin jackPlugin;
-
-#endif
diff --git a/trunk/src/audioOutputs/audioOutput_alsa.c b/trunk/src/audioOutputs/audioOutput_alsa.c
deleted file mode 100644
index 3ade3df46..000000000
--- a/trunk/src/audioOutputs/audioOutput_alsa.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "../audioOutput.h"
-
-#include <stdlib.h>
-
-#ifdef HAVE_ALSA
-
-#define ALSA_PCM_NEW_HW_PARAMS_API
-#define ALSA_PCM_NEW_SW_PARAMS_API
-
-#define MPD_ALSA_BUFFER_TIME_US 500000
-/* the default period time of xmms is 50 ms, so let's use that as well.
- * a user can tweak this parameter via the "period_time" config parameter.
- */
-#define MPD_ALSA_PERIOD_TIME_US 50000
-#define MPD_ALSA_RETRY_NR 5
-
-#include "../conf.h"
-#include "../log.h"
-
-#include <string.h>
-
-#include <alsa/asoundlib.h>
-
-typedef snd_pcm_sframes_t alsa_writei_t(snd_pcm_t * pcm, const void *buffer,
- snd_pcm_uframes_t size);
-
-typedef struct _AlsaData {
- char *device;
- snd_pcm_t *pcmHandle;
- alsa_writei_t *writei;
- unsigned int buffer_time;
- unsigned int period_time;
- int sampleSize;
- int useMmap;
- int canPause;
- int canResume;
-} AlsaData;
-
-static AlsaData *newAlsaData(void)
-{
- AlsaData *ret = xmalloc(sizeof(AlsaData));
-
- ret->device = NULL;
- ret->pcmHandle = NULL;
- ret->writei = snd_pcm_writei;
- ret->useMmap = 0;
- ret->buffer_time = MPD_ALSA_BUFFER_TIME_US;
- ret->period_time = MPD_ALSA_PERIOD_TIME_US;
-
- return ret;
-}
-
-static void freeAlsaData(AlsaData * ad)
-{
- if (ad->device)
- free(ad->device);
-
- free(ad);
-}
-
-static int alsa_initDriver(AudioOutput * audioOutput, ConfigParam * param)
-{
- AlsaData *ad = newAlsaData();
-
- if (param) {
- BlockParam *bp = getBlockParam(param, "device");
- ad->device = bp ? xstrdup(bp->value) : xstrdup("default");
-
- if ((bp = getBlockParam(param, "use_mmap")) &&
- !strcasecmp(bp->value, "yes"))
- ad->useMmap = 1;
- if ((bp = getBlockParam(param, "buffer_time")))
- ad->buffer_time = atoi(bp->value);
- if ((bp = getBlockParam(param, "period_time")))
- ad->period_time = atoi(bp->value);
- } else
- ad->device = xstrdup("default");
- audioOutput->data = ad;
-
- return 0;
-}
-
-static void alsa_finishDriver(AudioOutput * audioOutput)
-{
- AlsaData *ad = audioOutput->data;
-
- freeAlsaData(ad);
-}
-
-static int alsa_testDefault(void)
-{
- snd_pcm_t *handle;
-
- int ret = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK,
- SND_PCM_NONBLOCK);
- snd_config_update_free_global();
-
- if (ret) {
- WARNING("Error opening default alsa device: %s\n",
- snd_strerror(-ret));
- return -1;
- } else
- snd_pcm_close(handle);
-
- return 0;
-}
-
-static int alsa_openDevice(AudioOutput * audioOutput)
-{
- AlsaData *ad = audioOutput->data;
- AudioFormat *audioFormat = &audioOutput->outAudioFormat;
- snd_pcm_format_t bitformat;
- snd_pcm_hw_params_t *hwparams;
- snd_pcm_sw_params_t *swparams;
- unsigned int sampleRate = audioFormat->sampleRate;
- unsigned int channels = audioFormat->channels;
- snd_pcm_uframes_t alsa_buffer_size;
- snd_pcm_uframes_t alsa_period_size;
- int err;
- const char *cmd = NULL;
- int retry = MPD_ALSA_RETRY_NR;
- unsigned int period_time, period_time_ro;
- unsigned int buffer_time;
-
- switch (audioFormat->bits) {
- case 8:
- bitformat = SND_PCM_FORMAT_S8;
- break;
- case 16:
- bitformat = SND_PCM_FORMAT_S16;
- break;
- case 24:
- bitformat = SND_PCM_FORMAT_S24;
- break;
- case 32:
- bitformat = SND_PCM_FORMAT_S32;
- break;
- default:
- ERROR("ALSA device \"%s\" doesn't support %i bit audio\n",
- ad->device, audioFormat->bits);
- return -1;
- }
-
- err = snd_pcm_open(&ad->pcmHandle, ad->device,
- SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
- snd_config_update_free_global();
- if (err < 0) {
- ad->pcmHandle = NULL;
- goto error;
- }
-
- cmd = "snd_pcm_nonblock";
- err = snd_pcm_nonblock(ad->pcmHandle, 0);
- if (err < 0)
- goto error;
-
- period_time_ro = period_time = ad->period_time;
-configure_hw:
- /* configure HW params */
- snd_pcm_hw_params_alloca(&hwparams);
-
- cmd = "snd_pcm_hw_params_any";
- err = snd_pcm_hw_params_any(ad->pcmHandle, hwparams);
- if (err < 0)
- goto error;
-
- if (ad->useMmap) {
- err = snd_pcm_hw_params_set_access(ad->pcmHandle, hwparams,
- SND_PCM_ACCESS_MMAP_INTERLEAVED);
- if (err < 0) {
- ERROR("Cannot set mmap'ed mode on alsa device \"%s\": "
- " %s\n", ad->device, snd_strerror(-err));
- ERROR("Falling back to direct write mode\n");
- ad->useMmap = 0;
- } else
- ad->writei = snd_pcm_mmap_writei;
- }
-
- if (!ad->useMmap) {
- cmd = "snd_pcm_hw_params_set_access";
- err = snd_pcm_hw_params_set_access(ad->pcmHandle, hwparams,
- SND_PCM_ACCESS_RW_INTERLEAVED);
- if (err < 0)
- goto error;
- ad->writei = snd_pcm_writei;
- }
-
- err = snd_pcm_hw_params_set_format(ad->pcmHandle, hwparams, bitformat);
- if (err < 0) {
- ERROR("ALSA device \"%s\" does not support %i bit audio: "
- "%s\n", ad->device, audioFormat->bits, snd_strerror(-err));
- goto fail;
- }
-
- err = snd_pcm_hw_params_set_channels_near(ad->pcmHandle, hwparams,
- &channels);
- if (err < 0) {
- ERROR("ALSA device \"%s\" does not support %i channels: "
- "%s\n", ad->device, (int)audioFormat->channels,
- snd_strerror(-err));
- goto fail;
- }
- audioFormat->channels = channels;
-
- err = snd_pcm_hw_params_set_rate_near(ad->pcmHandle, hwparams,
- &sampleRate, NULL);
- if (err < 0 || sampleRate == 0) {
- ERROR("ALSA device \"%s\" does not support %i Hz audio\n",
- ad->device, (int)audioFormat->sampleRate);
- goto fail;
- }
- audioFormat->sampleRate = sampleRate;
-
- buffer_time = ad->buffer_time;
- cmd = "snd_pcm_hw_params_set_buffer_time_near";
- err = snd_pcm_hw_params_set_buffer_time_near(ad->pcmHandle, hwparams,
- &buffer_time, NULL);
- if (err < 0)
- goto error;
-
- period_time = period_time_ro;
- cmd = "snd_pcm_hw_params_set_period_time_near";
- err = snd_pcm_hw_params_set_period_time_near(ad->pcmHandle, hwparams,
- &period_time, NULL);
- if (err < 0)
- goto error;
-
- cmd = "snd_pcm_hw_params";
- err = snd_pcm_hw_params(ad->pcmHandle, hwparams);
- if (err == -EPIPE && --retry > 0) {
- period_time_ro = period_time_ro >> 1;
- goto configure_hw;
- } else if (err < 0)
- goto error;
- if (retry != MPD_ALSA_RETRY_NR)
- DEBUG("ALSA period_time set to %d\n", period_time);
-
- cmd = "snd_pcm_hw_params_get_buffer_size";
- err = snd_pcm_hw_params_get_buffer_size(hwparams, &alsa_buffer_size);
- if (err < 0)
- goto error;
-
- cmd = "snd_pcm_hw_params_get_period_size";
- err = snd_pcm_hw_params_get_period_size(hwparams, &alsa_period_size,
- NULL);
- if (err < 0)
- goto error;
-
- ad->canPause = snd_pcm_hw_params_can_pause(hwparams);
- ad->canResume = snd_pcm_hw_params_can_resume(hwparams);
-
- /* configure SW params */
- snd_pcm_sw_params_alloca(&swparams);
-
- cmd = "snd_pcm_sw_params_current";
- err = snd_pcm_sw_params_current(ad->pcmHandle, swparams);
- if (err < 0)
- goto error;
-
- cmd = "snd_pcm_sw_params_set_start_threshold";
- err = snd_pcm_sw_params_set_start_threshold(ad->pcmHandle, swparams,
- alsa_buffer_size -
- alsa_period_size);
- if (err < 0)
- goto error;
-
- cmd = "snd_pcm_sw_params_set_avail_min";
- err = snd_pcm_sw_params_set_avail_min(ad->pcmHandle, swparams,
- alsa_period_size);
- if (err < 0)
- goto error;
-
- cmd = "snd_pcm_sw_params_set_xfer_align";
- err = snd_pcm_sw_params_set_xfer_align(ad->pcmHandle, swparams, 1);
- if (err < 0)
- goto error;
-
- cmd = "snd_pcm_sw_params";
- err = snd_pcm_sw_params(ad->pcmHandle, swparams);
- if (err < 0)
- goto error;
-
- ad->sampleSize = (audioFormat->bits / 8) * audioFormat->channels;
-
- audioOutput->open = 1;
-
- DEBUG("alsa device \"%s\" will be playing %i bit, %i channel audio at "
- "%i Hz\n", ad->device, (int)audioFormat->bits,
- channels, sampleRate);
-
- return 0;
-
-error:
- if (cmd) {
- ERROR("Error opening alsa device \"%s\" (%s): %s\n",
- ad->device, cmd, snd_strerror(-err));
- } else {
- ERROR("Error opening alsa device \"%s\": %s\n", ad->device,
- snd_strerror(-err));
- }
-fail:
- if (ad->pcmHandle)
- snd_pcm_close(ad->pcmHandle);
- ad->pcmHandle = NULL;
- audioOutput->open = 0;
- return -1;
-}
-
-static int alsa_errorRecovery(AlsaData * ad, int err)
-{
- if (err == -EPIPE) {
- DEBUG("Underrun on alsa device \"%s\"\n", ad->device);
- } else if (err == -ESTRPIPE) {
- DEBUG("alsa device \"%s\" was suspended\n", ad->device);
- }
-
- switch (snd_pcm_state(ad->pcmHandle)) {
- case SND_PCM_STATE_PAUSED:
- err = snd_pcm_pause(ad->pcmHandle, /* disable */ 0);
- break;
- case SND_PCM_STATE_SUSPENDED:
- err = ad->canResume ?
- snd_pcm_resume(ad->pcmHandle) :
- snd_pcm_prepare(ad->pcmHandle);
- break;
- case SND_PCM_STATE_SETUP:
- case SND_PCM_STATE_XRUN:
- err = snd_pcm_prepare(ad->pcmHandle);
- break;
- case SND_PCM_STATE_DISCONNECTED:
- /* so alsa_closeDevice won't try to drain: */
- snd_pcm_close(ad->pcmHandle);
- ad->pcmHandle = NULL;
- break;
- default:
- /* unknown state, do nothing */
- break;
- }
-
- return err;
-}
-
-static void alsa_dropBufferedAudio(AudioOutput * audioOutput)
-{
- AlsaData *ad = audioOutput->data;
-
- alsa_errorRecovery(ad, snd_pcm_drop(ad->pcmHandle));
-}
-
-static void alsa_closeDevice(AudioOutput * audioOutput)
-{
- AlsaData *ad = audioOutput->data;
-
- if (ad->pcmHandle) {
- snd_pcm_drain(ad->pcmHandle);
- snd_pcm_close(ad->pcmHandle);
- ad->pcmHandle = NULL;
- }
-
- audioOutput->open = 0;
-}
-
-static int alsa_playAudio(AudioOutput * audioOutput, char *playChunk, int size)
-{
- AlsaData *ad = audioOutput->data;
- int ret;
-
- size /= ad->sampleSize;
-
- while (size > 0) {
- ret = ad->writei(ad->pcmHandle, playChunk, size);
-
- if (ret == -EAGAIN || ret == -EINTR)
- continue;
-
- if (ret < 0) {
- if (alsa_errorRecovery(ad, ret) < 0) {
- ERROR("closing alsa device \"%s\" due to write "
- "error: %s\n", ad->device,
- snd_strerror(-errno));
- alsa_closeDevice(audioOutput);
- return -1;
- }
- continue;
- }
-
- playChunk += ret * ad->sampleSize;
- size -= ret;
- }
-
- return 0;
-}
-
-AudioOutputPlugin alsaPlugin = {
- "alsa",
- alsa_testDefault,
- alsa_initDriver,
- alsa_finishDriver,
- alsa_openDevice,
- alsa_playAudio,
- alsa_dropBufferedAudio,
- alsa_closeDevice,
- NULL, /* sendMetadataFunc */
-};
-
-#else /* HAVE ALSA */
-
-DISABLED_AUDIO_OUTPUT_PLUGIN(alsaPlugin)
-#endif /* HAVE_ALSA */
diff --git a/trunk/src/audioOutputs/audioOutput_ao.c b/trunk/src/audioOutputs/audioOutput_ao.c
deleted file mode 100644
index a7f437ef4..000000000
--- a/trunk/src/audioOutputs/audioOutput_ao.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "../audioOutput.h"
-
-#ifdef HAVE_AO
-
-#include "../conf.h"
-#include "../log.h"
-
-#include <string.h>
-
-#include <ao/ao.h>
-
-static int driverInitCount;
-
-typedef struct _AoData {
- int writeSize;
- int driverId;
- ao_option *options;
- ao_device *device;
-} AoData;
-
-static AoData *newAoData(void)
-{
- AoData *ret = xmalloc(sizeof(AoData));
- ret->device = NULL;
- ret->options = NULL;
-
- return ret;
-}
-
-static void audioOutputAo_error(void)
-{
- if (errno == AO_ENOTLIVE) {
- ERROR("not a live ao device\n");
- } else if (errno == AO_EOPENDEVICE) {
- ERROR("not able to open audio device\n");
- } else if (errno == AO_EBADOPTION) {
- ERROR("bad driver option\n");
- }
-}
-
-static int audioOutputAo_initDriver(AudioOutput * audioOutput,
- ConfigParam * param)
-{
- ao_info *ai;
- char *dup;
- char *stk1;
- char *stk2;
- char *n1;
- char *key;
- char *value;
- char *test;
- AoData *ad = newAoData();
- BlockParam *blockParam;
-
- audioOutput->data = ad;
-
- if ((blockParam = getBlockParam(param, "write_size"))) {
- ad->writeSize = strtol(blockParam->value, &test, 10);
- if (*test != '\0') {
- FATAL("\"%s\" is not a valid write size at line %i\n",
- blockParam->value, blockParam->line);
- }
- } else
- ad->writeSize = 1024;
-
- if (driverInitCount == 0) {
- ao_initialize();
- }
- driverInitCount++;
-
- blockParam = getBlockParam(param, "driver");
-
- if (!blockParam || 0 == strcmp(blockParam->value, "default")) {
- ad->driverId = ao_default_driver_id();
- } else if ((ad->driverId = ao_driver_id(blockParam->value)) < 0) {
- FATAL("\"%s\" is not a valid ao driver at line %i\n",
- blockParam->value, blockParam->line);
- }
-
- if ((ai = ao_driver_info(ad->driverId)) == NULL) {
- FATAL("problems getting driver info for device defined at line %i\n"
- "you may not have permission to the audio device\n", param->line);
- }
-
- DEBUG("using ao driver \"%s\" for \"%s\"\n", ai->short_name,
- audioOutput->name);
-
- blockParam = getBlockParam(param, "options");
-
- if (blockParam) {
- dup = xstrdup(blockParam->value);
- } else
- dup = xstrdup("");
-
- if (strlen(dup)) {
- stk1 = NULL;
- n1 = strtok_r(dup, ";", &stk1);
- while (n1) {
- stk2 = NULL;
- key = strtok_r(n1, "=", &stk2);
- if (!key)
- FATAL("problems parsing options \"%s\"\n", n1);
- /*found = 0;
- for(i=0;i<ai->option_count;i++) {
- if(strcmp(ai->options[i],key)==0) {
- found = 1;
- break;
- }
- }
- if(!found) {
- FATAL("\"%s\" is not an option for "
- "\"%s\" ao driver\n",key,
- ai->short_name);
- } */
- value = strtok_r(NULL, "", &stk2);
- if (!value)
- FATAL("problems parsing options \"%s\"\n", n1);
- ao_append_option(&ad->options, key, value);
- n1 = strtok_r(NULL, ";", &stk1);
- }
- }
- free(dup);
-
- return 0;
-}
-
-static void freeAoData(AoData * ad)
-{
- ao_free_options(ad->options);
- free(ad);
-}
-
-static void audioOutputAo_finishDriver(AudioOutput * audioOutput)
-{
- AoData *ad = (AoData *) audioOutput->data;
- freeAoData(ad);
-
- driverInitCount--;
-
- if (driverInitCount == 0)
- ao_shutdown();
-}
-
-static void audioOutputAo_dropBufferedAudio(AudioOutput * audioOutput)
-{
- /* not supported by libao */
-}
-
-static void audioOutputAo_closeDevice(AudioOutput * audioOutput)
-{
- AoData *ad = (AoData *) audioOutput->data;
-
- if (ad->device) {
- ao_close(ad->device);
- ad->device = NULL;
- }
-
- audioOutput->open = 0;
-}
-
-static int audioOutputAo_openDevice(AudioOutput * audioOutput)
-{
- ao_sample_format format;
- AoData *ad = (AoData *) audioOutput->data;
-
- if (ad->device) {
- audioOutputAo_closeDevice(audioOutput);
- }
-
- format.bits = audioOutput->outAudioFormat.bits;
- format.rate = audioOutput->outAudioFormat.sampleRate;
- format.byte_format = AO_FMT_NATIVE;
- format.channels = audioOutput->outAudioFormat.channels;
-
- ad->device = ao_open_live(ad->driverId, &format, ad->options);
-
- if (ad->device == NULL)
- return -1;
-
- audioOutput->open = 1;
-
- return 0;
-}
-
-static int audioOutputAo_play(AudioOutput * audioOutput, char *playChunk,
- int size)
-{
- int send;
- AoData *ad = (AoData *) audioOutput->data;
-
- if (ad->device == NULL)
- return -1;
-
- while (size > 0) {
- send = ad->writeSize > size ? size : ad->writeSize;
-
- if (ao_play(ad->device, playChunk, send) == 0) {
- audioOutputAo_error();
- ERROR("closing audio device due to write error\n");
- audioOutputAo_closeDevice(audioOutput);
- return -1;
- }
-
- playChunk += send;
- size -= send;
- }
-
- return 0;
-}
-
-AudioOutputPlugin aoPlugin = {
- "ao",
- NULL,
- audioOutputAo_initDriver,
- audioOutputAo_finishDriver,
- audioOutputAo_openDevice,
- audioOutputAo_play,
- audioOutputAo_dropBufferedAudio,
- audioOutputAo_closeDevice,
- NULL, /* sendMetadataFunc */
-};
-
-#else
-
-#include <stdio.h>
-
-DISABLED_AUDIO_OUTPUT_PLUGIN(aoPlugin)
-#endif
diff --git a/trunk/src/audioOutputs/audioOutput_jack.c b/trunk/src/audioOutputs/audioOutput_jack.c
deleted file mode 100644
index 1fdfaf4bb..000000000
--- a/trunk/src/audioOutputs/audioOutput_jack.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/* jack plug in for the Music Player Daemon (MPD)
- * (c)2006 by anarch(anarchsss@gmail.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "../audioOutput.h"
-
-#ifdef HAVE_JACK
-
-#include <stdlib.h>
-#include <errno.h>
-
-#include "../conf.h"
-#include "../log.h"
-
-#include <string.h>
-#include <pthread.h>
-
-#include <jack/jack.h>
-#include <jack/types.h>
-#include <jack/ringbuffer.h>
-
-pthread_mutex_t play_audio_lock = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t play_audio = PTHREAD_COND_INITIALIZER;
-
-/*#include "dmalloc.h"*/
-
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-/*#define SAMPLE_SIZE sizeof(jack_default_audio_sample_t);*/
-
-
-static char *name = "mpd";
-static char *output_ports[2];
-static int ringbuf_sz = 32768;
-size_t sample_size = sizeof(jack_default_audio_sample_t);
-
-typedef struct _JackData {
- jack_port_t *ports[2];
- jack_client_t *client;
- jack_ringbuffer_t *ringbuffer[2];
- int bps;
- int shutdown;
-} JackData;
-
-/*JackData *jd = NULL;*/
-
-static JackData *newJackData(void)
-{
- JackData *ret;
- ret = xcalloc(sizeof(JackData), 1);
-
- return ret;
-}
-
-static void freeJackData(AudioOutput *audioOutput)
-{
- JackData *jd = audioOutput->data;
- if (jd) {
- if (jd->ringbuffer[0])
- jack_ringbuffer_free(jd->ringbuffer[0]);
- if (jd->ringbuffer[1])
- jack_ringbuffer_free(jd->ringbuffer[1]);
- free(jd);
- audioOutput->data = NULL;
- }
-}
-
-static void jack_finishDriver(AudioOutput *audioOutput)
-{
- JackData *jd = audioOutput->data;
- int i;
-
- if ( jd && jd->client ) {
- jack_deactivate(jd->client);
- jack_client_close(jd->client);
- }
- DEBUG("disconnect_jack (pid=%d)\n", getpid ());
-
- if ( strcmp(name, "mpd") ) {
- free(name);
- name = "mpd";
- }
-
- for ( i = ARRAY_SIZE(output_ports); --i >= 0; ) {
- if (!output_ports[i])
- continue;
- free(output_ports[i]);
- output_ports[i] = NULL;
- }
-
- freeJackData(audioOutput);
-}
-
-static int srate(jack_nframes_t rate, void *data)
-{
- JackData *jd = (JackData *) ((AudioOutput*) data)->data;
- AudioFormat *audioFormat = &(((AudioOutput*) data)->outAudioFormat);
-
- audioFormat->sampleRate = (int)jack_get_sample_rate(jd->client);
-
- return 0;
-}
-
-static int process(jack_nframes_t nframes, void *arg)
-{
- size_t i;
- JackData *jd = (JackData *) arg;
- jack_default_audio_sample_t *out[2];
- size_t avail_data, avail_frames;
-
- if ( nframes <= 0 )
- return 0;
-
- out[0] = jack_port_get_buffer(jd->ports[0], nframes);
- out[1] = jack_port_get_buffer(jd->ports[1], nframes);
-
- while ( nframes ) {
- avail_data = jack_ringbuffer_read_space(jd->ringbuffer[1]);
-
- if ( avail_data > 0 ) {
- avail_frames = avail_data / sample_size;
-
- if (avail_frames > nframes) {
- avail_frames = nframes;
- avail_data = nframes*sample_size;
- }
-
- jack_ringbuffer_read(jd->ringbuffer[0], (char *)out[0],
- avail_data);
- jack_ringbuffer_read(jd->ringbuffer[1], (char *)out[1],
- avail_data);
-
- nframes -= avail_frames;
- out[0] += avail_data;
- out[1] += avail_data;
- } else {
- for (i = 0; i < nframes; i++)
- out[0][i] = out[1][i] = 0.0;
- nframes = 0;
- }
-
- if (pthread_mutex_trylock (&play_audio_lock) == 0) {
- pthread_cond_signal (&play_audio);
- pthread_mutex_unlock (&play_audio_lock);
- }
- }
-
-
- /*DEBUG("process (pid=%d)\n", getpid());*/
- return 0;
-}
-
-static void shutdown_callback(void *arg)
-{
- JackData *jd = (JackData *) arg;
- jd->shutdown = 1;
-}
-
-static void set_audioformat(AudioOutput *audioOutput)
-{
- JackData *jd = audioOutput->data;
- AudioFormat *audioFormat = &audioOutput->outAudioFormat;
-
- audioFormat->sampleRate = (int) jack_get_sample_rate(jd->client);
- DEBUG("samplerate = %d\n", audioFormat->sampleRate);
- audioFormat->channels = 2;
- audioFormat->bits = 16;
- jd->bps = audioFormat->channels
- * sizeof(jack_default_audio_sample_t)
- * audioFormat->sampleRate;
-}
-
-static void error_callback(const char *msg)
-{
- ERROR("jack: %s\n", msg);
-}
-
-static int jack_initDriver(AudioOutput *audioOutput, ConfigParam *param)
-{
- BlockParam *bp;
- char *endptr;
- int val;
- char *cp = NULL;
-
- DEBUG("jack_initDriver (pid=%d)\n", getpid());
- if ( ! param ) return 0;
-
- if ( (bp = getBlockParam(param, "ports")) ) {
- DEBUG("output_ports=%s\n", bp->value);
-
- if (!(cp = strchr(bp->value, ',')))
- FATAL("expected comma and a second value for '%s' "
- "at line %d: %s\n",
- bp->name, bp->line, bp->value);
-
- *cp = '\0';
- output_ports[0] = xstrdup(bp->value);
- *cp++ = ',';
-
- if (!*cp)
- FATAL("expected a second value for '%s' at line %d: "
- "%s\n", bp->name, bp->line, bp->value);
-
- output_ports[1] = xstrdup(cp);
-
- if (strchr(cp,','))
- FATAL("Only %d values are supported for '%s' "
- "at line %d\n", (int)ARRAY_SIZE(output_ports),
- bp->name, bp->line);
- }
-
- if ( (bp = getBlockParam(param, "ringbuffer_size")) ) {
- errno = 0;
- val = strtol(bp->value, &endptr, 10);
-
- if ( errno == 0 && endptr != bp->value) {
- ringbuf_sz = val < 32768 ? 32768 : val;
- DEBUG("ringbuffer_size=%d\n", ringbuf_sz);
- } else {
- FATAL("%s is not a number; ringbuf_size=%d\n",
- bp->value, ringbuf_sz);
- }
- }
-
- if ( (bp = getBlockParam(param, "name"))
- && (strcmp(bp->value, "mpd") != 0) ) {
- name = xstrdup(bp->value);
- DEBUG("name=%s\n", name);
- }
-
- return 0;
-}
-
-static int jack_testDefault(void)
-{
- return 0;
-}
-
-static int connect_jack(AudioOutput *audioOutput)
-{
- JackData *jd = audioOutput->data;
- char **jports;
- char *port_name;
-
- if ( (jd->client = jack_client_new(name)) == NULL ) {
- ERROR("jack server not running?\n");
- freeJackData(audioOutput);
- return -1;
- }
-
- jack_set_error_function(error_callback);
- jack_set_process_callback(jd->client, process, (void *)jd);
- jack_set_sample_rate_callback(jd->client, (JackProcessCallback)srate,
- (void *)audioOutput);
- jack_on_shutdown(jd->client, shutdown_callback, (void *)jd);
-
- if ( jack_activate(jd->client) ) {
- ERROR("cannot activate client");
- freeJackData(audioOutput);
- return -1;
- }
-
- jd->ports[0] = jack_port_register(jd->client, "left",
- JACK_DEFAULT_AUDIO_TYPE,
- JackPortIsOutput, 0);
- if ( !jd->ports[0] ) {
- ERROR("Cannot register left output port.\n");
- freeJackData(audioOutput);
- return -1;
- }
-
- jd->ports[1] = jack_port_register(jd->client, "right",
- JACK_DEFAULT_AUDIO_TYPE,
- JackPortIsOutput, 0);
- if ( !jd->ports[1] ) {
- ERROR("Cannot register right output port.\n");
- freeJackData(audioOutput);
- return -1;
- }
-
- /* hay que buscar que hay */
- if ( !output_ports[1]
- && (jports = (char **)jack_get_ports(jd->client, NULL, NULL,
- JackPortIsPhysical|
- JackPortIsInput)) ) {
- output_ports[0] = jports[0];
- output_ports[1] = jports[1] ? jports[1] : jports[0];
- DEBUG("output_ports: %s %s\n", output_ports[0], output_ports[1]);
- free(jports);
- }
-
- if ( output_ports[1] ) {
- jd->ringbuffer[0] = jack_ringbuffer_create(ringbuf_sz);
- jd->ringbuffer[1] = jack_ringbuffer_create(ringbuf_sz);
- memset(jd->ringbuffer[0]->buf, 0, jd->ringbuffer[0]->size);
- memset(jd->ringbuffer[1]->buf, 0, jd->ringbuffer[1]->size);
-
- port_name = xmalloc(sizeof(char)*(7+strlen(name)));
-
- sprintf(port_name, "%s:left", name);
- if ( (jack_connect(jd->client, port_name,
- output_ports[0])) != 0 ) {
- ERROR("%s is not a valid Jack Client / Port ",
- output_ports[0]);
- freeJackData(audioOutput);
- free(port_name);
- return -1;
- }
- sprintf(port_name, "%s:right", name);
- if ( (jack_connect(jd->client, port_name,
- output_ports[1])) != 0 ) {
- ERROR("%s is not a valid Jack Client / Port ",
- output_ports[1]);
- freeJackData(audioOutput);
- free(port_name);
- return -1;
- }
- free(port_name);
- }
-
- DEBUG("connect_jack (pid=%d)\n", getpid());
- return 1;
-}
-
-static int jack_openDevice(AudioOutput *audioOutput)
-{
- JackData *jd = audioOutput->data;
-
- if ( !jd ) {
- DEBUG("connect!\n");
- jd = newJackData();
- audioOutput->data = jd;
-
- if (connect_jack(audioOutput) < 0) {
- freeJackData(audioOutput);
- audioOutput->open = 0;
- return -1;
- }
- }
-
- set_audioformat(audioOutput);
- audioOutput->open = 1;
-
- DEBUG("jack_openDevice (pid=%d)!\n", getpid ());
- return 0;
-}
-
-
-static void jack_closeDevice(AudioOutput * audioOutput)
-{
- /*jack_finishDriver(audioOutput);*/
- audioOutput->open = 0;
- DEBUG("jack_closeDevice (pid=%d)\n", getpid());
-}
-
-static void jack_dropBufferedAudio (AudioOutput * audioOutput)
-{
-}
-
-static int jack_playAudio(AudioOutput * audioOutput, char *buff, int size)
-{
- JackData *jd = audioOutput->data;
- size_t space;
- int i;
- short *buffer = (short *) buff;
- jack_default_audio_sample_t sample;
- size_t samples = size/4;
-
- /*DEBUG("jack_playAudio: (pid=%d)!\n", getpid());*/
-
- if ( jd->shutdown ) {
- ERROR("Refusing to play, because there is no client thread.\n");
- freeJackData(audioOutput);
- audioOutput->open = 0;
- return 0;
- }
-
- while ( samples && !jd->shutdown ) {
-
- if ( (space = jack_ringbuffer_write_space(jd->ringbuffer[0]))
- >= samples*sample_size ) {
-
- /*space = MIN(space, samples*sample_size);*/
- /*space = samples*sample_size;*/
-
- /*for(i=0; i<space/sample_size; i++) {*/
- for(i=0; i<samples; i++) {
- sample = (jack_default_audio_sample_t) *(buffer++)/32768.0;
-
- jack_ringbuffer_write(jd->ringbuffer[0], (void*)&sample,
- sample_size);
-
- sample = (jack_default_audio_sample_t) *(buffer++)/32768.0;
-
- jack_ringbuffer_write(jd->ringbuffer[1], (void*)&sample,
- sample_size);
-
- /*samples--;*/
- }
- samples=0;
-
- } else {
- pthread_mutex_lock(&play_audio_lock);
- pthread_cond_wait(&play_audio, &play_audio_lock);
- pthread_mutex_unlock(&play_audio_lock);
- }
-
- }
- return 0;
-}
-
-AudioOutputPlugin jackPlugin = {
- "jack",
- jack_testDefault,
- jack_initDriver,
- jack_finishDriver,
- jack_openDevice,
- jack_playAudio,
- jack_dropBufferedAudio,
- jack_closeDevice,
- NULL, /* sendMetadataFunc */
-};
-
-#else /* HAVE JACK */
-
-DISABLED_AUDIO_OUTPUT_PLUGIN(jackPlugin)
-
-#endif /* HAVE_JACK */
diff --git a/trunk/src/audioOutputs/audioOutput_mvp.c b/trunk/src/audioOutputs/audioOutput_mvp.c
deleted file mode 100644
index ea365c657..000000000
--- a/trunk/src/audioOutputs/audioOutput_mvp.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * Media MVP audio output based on code from MVPMC project:
- * http://mvpmc.sourceforge.net/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "../audioOutput.h"
-
-#include <stdlib.h>
-
-#ifdef HAVE_MVP
-
-#include "../conf.h"
-#include "../log.h"
-
-#include <string.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-
-typedef struct {
- unsigned long dsp_status;
- unsigned long stream_decode_type;
- unsigned long sample_rate;
- unsigned long bit_rate;
- unsigned long raw[64 / sizeof(unsigned long)];
-} aud_status_t;
-
-#define MVP_SET_AUD_STOP _IOW('a',1,int)
-#define MVP_SET_AUD_PLAY _IOW('a',2,int)
-#define MVP_SET_AUD_PAUSE _IOW('a',3,int)
-#define MVP_SET_AUD_UNPAUSE _IOW('a',4,int)
-#define MVP_SET_AUD_SRC _IOW('a',5,int)
-#define MVP_SET_AUD_MUTE _IOW('a',6,int)
-#define MVP_SET_AUD_BYPASS _IOW('a',8,int)
-#define MVP_SET_AUD_CHANNEL _IOW('a',9,int)
-#define MVP_GET_AUD_STATUS _IOR('a',10,aud_status_t)
-#define MVP_SET_AUD_VOLUME _IOW('a',13,int)
-#define MVP_GET_AUD_VOLUME _IOR('a',14,int)
-#define MVP_SET_AUD_STREAMTYPE _IOW('a',15,int)
-#define MVP_SET_AUD_FORMAT _IOW('a',16,int)
-#define MVP_GET_AUD_SYNC _IOR('a',21,pts_sync_data_t*)
-#define MVP_SET_AUD_STC _IOW('a',22,long long int *)
-#define MVP_SET_AUD_SYNC _IOW('a',23,int)
-#define MVP_SET_AUD_END_STREAM _IOW('a',25,int)
-#define MVP_SET_AUD_RESET _IOW('a',26,int)
-#define MVP_SET_AUD_DAC_CLK _IOW('a',27,int)
-#define MVP_GET_AUD_REGS _IOW('a',28,aud_ctl_regs_t*)
-
-typedef struct _MvpData {
- int fd;
-} MvpData;
-
-static int pcmfrequencies[][3] = {
- {9, 8000, 32000},
- {10, 11025, 44100},
- {11, 12000, 48000},
- {1, 16000, 32000},
- {2, 22050, 44100},
- {3, 24000, 48000},
- {5, 32000, 32000},
- {0, 44100, 44100},
- {7, 48000, 48000},
- {13, 64000, 32000},
- {14, 88200, 44100},
- {15, 96000, 48000}
-};
-
-static int numfrequencies = sizeof(pcmfrequencies) / 12;
-
-static int mvp_testDefault(void)
-{
- int fd;
-
- fd = open("/dev/adec_pcm", O_WRONLY);
-
- if (fd) {
- close(fd);
- return 0;
- }
-
- WARNING("Error opening PCM device \"/dev/adec_pcm\": %s\n",
- strerror(errno));
-
- return -1;
-}
-
-static int mvp_initDriver(AudioOutput * audioOutput, ConfigParam * param)
-{
- MvpData *md = xmalloc(sizeof(MvpData));
- md->fd = -1;
- audioOutput->data = md;
-
- return 0;
-}
-
-static void mvp_finishDriver(AudioOutput * audioOutput)
-{
- MvpData *md = audioOutput->data;
- free(md);
-}
-
-static int mvp_setPcmParams(MvpData * md, unsigned long rate, int channels,
- int big_endian, int bits)
-{
- int iloop;
- int mix[5];
-
- if (channels == 1)
- mix[0] = 1;
- else if (channels == 2)
- mix[0] = 0;
- else
- return -1;
-
- /* 0,1=24bit(24) , 2,3=16bit */
- if (bits == 16)
- mix[1] = 2;
- else if (bits == 24)
- mix[1] = 0;
- else
- return -1;
-
- mix[3] = 0; /* stream type? */
-
- if (big_endian == 1)
- mix[4] = 1;
- else if (big_endian == 0)
- mix[4] = 0;
- else
- return -1;
-
- /*
- * if there is an exact match for the frequency, use it.
- */
- for (iloop = 0; iloop < numfrequencies; iloop++) {
- if (rate == pcmfrequencies[iloop][1]) {
- mix[2] = pcmfrequencies[iloop][0];
- break;
- }
- }
-
- if (iloop >= numfrequencies) {
- ERROR("Can not find suitable output frequency for %ld\n", rate);
- return -1;
- }
-
- if (ioctl(md->fd, MVP_SET_AUD_FORMAT, &mix) < 0) {
- ERROR("Can not set audio format\n");
- return -1;
- }
-
- if (ioctl(md->fd, MVP_SET_AUD_SYNC, 2) != 0) {
- ERROR("Can not set audio sync\n");
- return -1;
- }
-
- if (ioctl(md->fd, MVP_SET_AUD_PLAY, 0) < 0) {
- ERROR("Can not set audio play mode\n");
- return -1;
- }
-
- return 0;
-}
-
-static int mvp_openDevice(AudioOutput * audioOutput)
-{
- long long int stc = 0;
- MvpData *md = audioOutput->data;
- AudioFormat *audioFormat = &audioOutput->outAudioFormat;
- int mix[5] = { 0, 2, 7, 1, 0 };
-
- if ((md->fd = open("/dev/adec_pcm", O_RDWR | O_NONBLOCK)) < 0) {
- ERROR("Error opening /dev/adec_pcm: %s\n", strerror(errno));
- return -1;
- }
- if (ioctl(md->fd, MVP_SET_AUD_SRC, 1) < 0) {
- ERROR("Error setting audio source: %s\n", strerror(errno));
- return -1;
- }
- if (ioctl(md->fd, MVP_SET_AUD_STREAMTYPE, 0) < 0) {
- ERROR("Error setting audio streamtype: %s\n", strerror(errno));
- return -1;
- }
- if (ioctl(md->fd, MVP_SET_AUD_FORMAT, &mix) < 0) {
- ERROR("Error setting audio format: %s\n", strerror(errno));
- return -1;
- }
- ioctl(md->fd, MVP_SET_AUD_STC, &stc);
- if (ioctl(md->fd, MVP_SET_AUD_BYPASS, 1) < 0) {
- ERROR("Error setting audio streamtype: %s\n", strerror(errno));
- return -1;
- }
-#ifdef WORDS_BIGENDIAN
- mvp_setPcmParams(md, audioFormat->sampleRate, audioFormat->channels, 0,
- audioFormat->bits);
-#else
- mvp_setPcmParams(md, audioFormat->sampleRate, audioFormat->channels, 1,
- audioFormat->bits);
-#endif
- audioOutput->open = 1;
- return 0;
-}
-
-static void mvp_closeDevice(AudioOutput * audioOutput)
-{
- MvpData *md = audioOutput->data;
- if (md->fd >= 0)
- close(md->fd);
- md->fd = -1;
- audioOutput->open = 0;
-}
-
-static void mvp_dropBufferedAudio(AudioOutput * audioOutput)
-{
- MvpData *md = audioOutput->data;
- if (md->fd >= 0) {
- ioctl(md->fd, MVP_SET_AUD_RESET, 0x11);
- close(md->fd);
- md->fd = -1;
- audioOutput->open = 0;
- }
-}
-
-static int mvp_playAudio(AudioOutput * audioOutput, char *playChunk, int size)
-{
- MvpData *md = audioOutput->data;
- int ret;
-
- /* reopen the device since it was closed by dropBufferedAudio */
- if (md->fd < 0)
- mvp_openDevice(audioOutput);
-
- while (size > 0) {
- ret = write(md->fd, playChunk, size);
- if (ret < 0) {
- if (errno == EINTR)
- continue;
- ERROR("closing mvp PCM device due to write error: "
- "%s\n", strerror(errno));
- mvp_closeDevice(audioOutput);
- return -1;
- }
- playChunk += ret;
- size -= ret;
- }
- return 0;
-}
-
-AudioOutputPlugin mvpPlugin = {
- "mvp",
- mvp_testDefault,
- mvp_initDriver,
- mvp_finishDriver,
- mvp_openDevice,
- mvp_playAudio,
- mvp_dropBufferedAudio,
- mvp_closeDevice,
- NULL, /* sendMetadataFunc */
-};
-
-#else /* HAVE_MVP */
-
-DISABLED_AUDIO_OUTPUT_PLUGIN(mvpPlugin)
-#endif /* HAVE_MVP */
diff --git a/trunk/src/audioOutputs/audioOutput_oss.c b/trunk/src/audioOutputs/audioOutput_oss.c
deleted file mode 100644
index 01293cbd1..000000000
--- a/trunk/src/audioOutputs/audioOutput_oss.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * OSS audio output (c) 2004, 2005, 2006, 2007 by Eric Wong <eric@petta-tech.com>
- * and Warren Dukes <warren.dukes@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "../audioOutput.h"
-
-#include <stdlib.h>
-
-#ifdef HAVE_OSS
-
-#include "../conf.h"
-#include "../log.h"
-
-#include <string.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-
-#if defined(__OpenBSD__) || defined(__NetBSD__)
-# include <soundcard.h>
-#else /* !(defined(__OpenBSD__) || defined(__NetBSD__) */
-# include <sys/soundcard.h>
-#endif /* !(defined(__OpenBSD__) || defined(__NetBSD__) */
-
-#ifdef WORDS_BIGENDIAN
-# define AFMT_S16_MPD AFMT_S16_BE
-#else
-# define AFMT_S16_MPD AFMT_S16_LE
-#endif /* WORDS_BIGENDIAN */
-
-typedef struct _OssData {
- int fd;
- const char *device;
- int channels;
- int sampleRate;
- int bitFormat;
- int bits;
- int *supported[3];
- int numSupported[3];
- int *unsupported[3];
- int numUnsupported[3];
-} OssData;
-
-#define OSS_SUPPORTED 1
-#define OSS_UNSUPPORTED 0
-#define OSS_UNKNOWN -1
-
-#define OSS_RATE 0
-#define OSS_CHANNELS 1
-#define OSS_BITS 2
-
-static int getIndexForParam(int param)
-{
- int index = 0;
-
- switch (param) {
- case SNDCTL_DSP_SPEED:
- index = OSS_RATE;
- break;
- case SNDCTL_DSP_CHANNELS:
- index = OSS_CHANNELS;
- break;
- case SNDCTL_DSP_SAMPLESIZE:
- index = OSS_BITS;
- break;
- }
-
- return index;
-}
-
-static int findSupportedParam(OssData * od, int param, int val)
-{
- int i;
- int index = getIndexForParam(param);
-
- for (i = 0; i < od->numSupported[index]; i++) {
- if (od->supported[index][i] == val)
- return 1;
- }
-
- return 0;
-}
-
-static int canConvert(int index, int val)
-{
- switch (index) {
- case OSS_BITS:
- if (val != 16)
- return 0;
- break;
- case OSS_CHANNELS:
- if (val != 2)
- return 0;
- break;
- }
-
- return 1;
-}
-
-static int getSupportedParam(OssData * od, int param, int val)
-{
- int i;
- int index = getIndexForParam(param);
- int ret = -1;
- int least = val;
- int diff;
-
- for (i = 0; i < od->numSupported[index]; i++) {
- diff = od->supported[index][i] - val;
- if (diff < 0)
- diff = -diff;
- if (diff < least) {
- if (!canConvert(index, od->supported[index][i])) {
- continue;
- }
- least = diff;
- ret = od->supported[index][i];
- }
- }
-
- return ret;
-}
-
-static int findUnsupportedParam(OssData * od, int param, int val)
-{
- int i;
- int index = getIndexForParam(param);
-
- for (i = 0; i < od->numUnsupported[index]; i++) {
- if (od->unsupported[index][i] == val)
- return 1;
- }
-
- return 0;
-}
-
-static void addSupportedParam(OssData * od, int param, int val)
-{
- int index = getIndexForParam(param);
-
- od->numSupported[index]++;
- od->supported[index] = xrealloc(od->supported[index],
- od->numSupported[index] * sizeof(int));
- od->supported[index][od->numSupported[index] - 1] = val;
-}
-
-static void addUnsupportedParam(OssData * od, int param, int val)
-{
- int index = getIndexForParam(param);
-
- od->numUnsupported[index]++;
- od->unsupported[index] = xrealloc(od->unsupported[index],
- od->numUnsupported[index] *
- sizeof(int));
- od->unsupported[index][od->numUnsupported[index] - 1] = val;
-}
-
-static void removeSupportedParam(OssData * od, int param, int val)
-{
- int i = 0;
- int j = 0;
- int index = getIndexForParam(param);
-
- for (i = 0; i < od->numSupported[index] - 1; i++) {
- if (od->supported[index][i] == val)
- j = 1;
- od->supported[index][i] = od->supported[index][i + j];
- }
-
- od->numSupported[index]--;
- od->supported[index] = xrealloc(od->supported[index],
- od->numSupported[index] * sizeof(int));
-}
-
-static void removeUnsupportedParam(OssData * od, int param, int val)
-{
- int i = 0;
- int j = 0;
- int index = getIndexForParam(param);
-
- for (i = 0; i < od->numUnsupported[index] - 1; i++) {
- if (od->unsupported[index][i] == val)
- j = 1;
- od->unsupported[index][i] = od->unsupported[index][i + j];
- }
-
- od->numUnsupported[index]--;
- od->unsupported[index] = xrealloc(od->unsupported[index],
- od->numUnsupported[index] *
- sizeof(int));
-}
-
-static int isSupportedParam(OssData * od, int param, int val)
-{
- if (findSupportedParam(od, param, val))
- return OSS_SUPPORTED;
- if (findUnsupportedParam(od, param, val))
- return OSS_UNSUPPORTED;
- return OSS_UNKNOWN;
-}
-
-static void supportParam(OssData * od, int param, int val)
-{
- int supported = isSupportedParam(od, param, val);
-
- if (supported == OSS_SUPPORTED)
- return;
-
- if (supported == OSS_UNSUPPORTED) {
- removeUnsupportedParam(od, param, val);
- }
-
- addSupportedParam(od, param, val);
-}
-
-static void unsupportParam(OssData * od, int param, int val)
-{
- int supported = isSupportedParam(od, param, val);
-
- if (supported == OSS_UNSUPPORTED)
- return;
-
- if (supported == OSS_SUPPORTED) {
- removeSupportedParam(od, param, val);
- }
-
- addUnsupportedParam(od, param, val);
-}
-
-static OssData *newOssData(void)
-{
- OssData *ret = xmalloc(sizeof(OssData));
-
- ret->device = NULL;
- ret->fd = -1;
-
- ret->supported[OSS_RATE] = NULL;
- ret->supported[OSS_CHANNELS] = NULL;
- ret->supported[OSS_BITS] = NULL;
- ret->unsupported[OSS_RATE] = NULL;
- ret->unsupported[OSS_CHANNELS] = NULL;
- ret->unsupported[OSS_BITS] = NULL;
-
- ret->numSupported[OSS_RATE] = 0;
- ret->numSupported[OSS_CHANNELS] = 0;
- ret->numSupported[OSS_BITS] = 0;
- ret->numUnsupported[OSS_RATE] = 0;
- ret->numUnsupported[OSS_CHANNELS] = 0;
- ret->numUnsupported[OSS_BITS] = 0;
-
- supportParam(ret, SNDCTL_DSP_SPEED, 48000);
- supportParam(ret, SNDCTL_DSP_SPEED, 44100);
- supportParam(ret, SNDCTL_DSP_CHANNELS, 2);
- supportParam(ret, SNDCTL_DSP_SAMPLESIZE, 16);
-
- return ret;
-}
-
-static void freeOssData(OssData * od)
-{
- if (od->supported[OSS_RATE])
- free(od->supported[OSS_RATE]);
- if (od->supported[OSS_CHANNELS])
- free(od->supported[OSS_CHANNELS]);
- if (od->supported[OSS_BITS])
- free(od->supported[OSS_BITS]);
- if (od->unsupported[OSS_RATE])
- free(od->unsupported[OSS_RATE]);
- if (od->unsupported[OSS_CHANNELS])
- free(od->unsupported[OSS_CHANNELS]);
- if (od->unsupported[OSS_BITS])
- free(od->unsupported[OSS_BITS]);
-
- free(od);
-}
-
-#define OSS_STAT_NO_ERROR 0
-#define OSS_STAT_NOT_CHAR_DEV -1
-#define OSS_STAT_NO_PERMS -2
-#define OSS_STAT_DOESN_T_EXIST -3
-#define OSS_STAT_OTHER -4
-
-static int oss_statDevice(const char *device, int *stErrno)
-{
- struct stat st;
-
- if (0 == stat(device, &st)) {
- if (!S_ISCHR(st.st_mode)) {
- return OSS_STAT_NOT_CHAR_DEV;
- }
- } else {
- *stErrno = errno;
-
- switch (errno) {
- case ENOENT:
- case ENOTDIR:
- return OSS_STAT_DOESN_T_EXIST;
- case EACCES:
- return OSS_STAT_NO_PERMS;
- default:
- return OSS_STAT_OTHER;
- }
- }
-
- return 0;
-}
-
-static const char *default_devices[] = { "/dev/sound/dsp", "/dev/dsp" };
-
-static int oss_testDefault(void)
-{
- int fd, i;
-
- for (i = ARRAY_SIZE(default_devices); --i >= 0; ) {
- if ((fd = open(default_devices[i], O_WRONLY)) >= 0) {
- xclose(fd);
- return 0;
- }
- WARNING("Error opening OSS device \"%s\": %s\n",
- default_devices[i], strerror(errno));
- }
-
- return -1;
-}
-
-static int oss_open_default(AudioOutput *ao, ConfigParam *param, OssData *od)
-{
- int i;
- int err[ARRAY_SIZE(default_devices)];
- int ret[ARRAY_SIZE(default_devices)];
-
- for (i = ARRAY_SIZE(default_devices); --i >= 0; ) {
- ret[i] = oss_statDevice(default_devices[i], &err[i]);
- if (ret[i] == 0) {
- od->device = default_devices[i];
- return 0;
- }
- }
-
- if (param)
- ERROR("error trying to open specified OSS device"
- " at line %i\n", param->line);
- else
- ERROR("error trying to open default OSS device\n");
-
- for (i = ARRAY_SIZE(default_devices); --i >= 0; ) {
- const char *dev = default_devices[i];
- switch(ret[i]) {
- case OSS_STAT_DOESN_T_EXIST:
- ERROR("%s not found\n", dev);
- break;
- case OSS_STAT_NOT_CHAR_DEV:
- ERROR("%s is not a character device\n", dev);
- break;
- case OSS_STAT_NO_PERMS:
- ERROR("%s: permission denied\n", dev);
- break;
- default:
- ERROR("Error accessing %s: %s", dev, strerror(err[i]));
- }
- }
- exit(EXIT_FAILURE);
- return 0; /* some compilers can be dumb... */
-}
-
-static int oss_initDriver(AudioOutput * audioOutput, ConfigParam * param)
-{
- OssData *od = newOssData();
- audioOutput->data = od;
- if (param) {
- BlockParam *bp = getBlockParam(param, "device");
- if (bp) {
- od->device = bp->value;
- return 0;
- }
- }
- return oss_open_default(audioOutput, param, od);
-}
-
-static void oss_finishDriver(AudioOutput * audioOutput)
-{
- OssData *od = audioOutput->data;
-
- freeOssData(od);
-}
-
-static int setParam(OssData * od, int param, int *value)
-{
- int val = *value;
- int copy;
- int supported = isSupportedParam(od, param, val);
-
- do {
- if (supported == OSS_UNSUPPORTED) {
- val = getSupportedParam(od, param, val);
- if (copy < 0)
- return -1;
- }
- copy = val;
- if (ioctl(od->fd, param, &copy)) {
- unsupportParam(od, param, val);
- supported = OSS_UNSUPPORTED;
- } else {
- if (supported == OSS_UNKNOWN) {
- supportParam(od, param, val);
- supported = OSS_SUPPORTED;
- }
- val = copy;
- }
- } while (supported == OSS_UNSUPPORTED);
-
- *value = val;
-
- return 0;
-}
-
-static void oss_close(OssData * od)
-{
- if (od->fd >= 0)
- while (close(od->fd) && errno == EINTR) ;
- od->fd = -1;
-}
-
-static int oss_open(AudioOutput * audioOutput)
-{
- int tmp;
- OssData *od = audioOutput->data;
-
- if ((od->fd = open(od->device, O_WRONLY)) < 0) {
- ERROR("Error opening OSS device \"%s\": %s\n", od->device,
- strerror(errno));
- goto fail;
- }
-
- if (setParam(od, SNDCTL_DSP_CHANNELS, &od->channels)) {
- ERROR("OSS device \"%s\" does not support %i channels: %s\n",
- od->device, od->channels, strerror(errno));
- goto fail;
- }
-
- if (setParam(od, SNDCTL_DSP_SPEED, &od->sampleRate)) {
- ERROR("OSS device \"%s\" does not support %i Hz audio: %s\n",
- od->device, od->sampleRate, strerror(errno));
- goto fail;
- }
-
- switch (od->bits) {
- case 8:
- tmp = AFMT_S8;
- break;
- case 16:
- tmp = AFMT_S16_MPD;
- }
-
- if (setParam(od, SNDCTL_DSP_SAMPLESIZE, &tmp)) {
- ERROR("OSS device \"%s\" does not support %i bit audio: %s\n",
- od->device, tmp, strerror(errno));
- goto fail;
- }
-
- audioOutput->open = 1;
-
- return 0;
-
-fail:
- oss_close(od);
- audioOutput->open = 0;
- return -1;
-}
-
-static int oss_openDevice(AudioOutput * audioOutput)
-{
- int ret = -1;
- OssData *od = audioOutput->data;
- AudioFormat *audioFormat = &audioOutput->outAudioFormat;
-
- od->channels = audioFormat->channels;
- od->sampleRate = audioFormat->sampleRate;
- od->bits = audioFormat->bits;
-
- if ((ret = oss_open(audioOutput)) < 0)
- return ret;
-
- audioFormat->channels = od->channels;
- audioFormat->sampleRate = od->sampleRate;
- audioFormat->bits = od->bits;
-
- DEBUG("oss device \"%s\" will be playing %i bit %i channel audio at "
- "%i Hz\n", od->device, od->bits, od->channels, od->sampleRate);
-
- return ret;
-}
-
-static void oss_closeDevice(AudioOutput * audioOutput)
-{
- OssData *od = audioOutput->data;
-
- oss_close(od);
-
- audioOutput->open = 0;
-}
-
-static void oss_dropBufferedAudio(AudioOutput * audioOutput)
-{
- OssData *od = audioOutput->data;
-
- if (od->fd >= 0) {
- ioctl(od->fd, SNDCTL_DSP_RESET, 0);
- oss_close(od);
- }
-}
-
-static int oss_playAudio(AudioOutput * audioOutput, char *playChunk, int size)
-{
- OssData *od = audioOutput->data;
- int ret;
-
- /* reopen the device since it was closed by dropBufferedAudio */
- if (od->fd < 0 && oss_open(audioOutput) < 0)
- return -1;
-
- while (size > 0) {
- ret = write(od->fd, playChunk, size);
- if (ret < 0) {
- if (errno == EINTR)
- continue;
- ERROR("closing oss device \"%s\" due to write error: "
- "%s\n", od->device, strerror(errno));
- oss_closeDevice(audioOutput);
- return -1;
- }
- playChunk += ret;
- size -= ret;
- }
-
- return 0;
-}
-
-AudioOutputPlugin ossPlugin = {
- "oss",
- oss_testDefault,
- oss_initDriver,
- oss_finishDriver,
- oss_openDevice,
- oss_playAudio,
- oss_dropBufferedAudio,
- oss_closeDevice,
- NULL, /* sendMetadataFunc */
-};
-
-#else /* HAVE OSS */
-
-DISABLED_AUDIO_OUTPUT_PLUGIN(ossPlugin)
-#endif /* HAVE_OSS */
diff --git a/trunk/src/audioOutputs/audioOutput_osx.c b/trunk/src/audioOutputs/audioOutput_osx.c
deleted file mode 100644
index 1caebade5..000000000
--- a/trunk/src/audioOutputs/audioOutput_osx.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "../audioOutput.h"
-
-#ifdef HAVE_OSX
-
-#include <AudioUnit/AudioUnit.h>
-#include <stdlib.h>
-#include <pthread.h>
-
-#include "../log.h"
-
-typedef struct _OsxData {
- AudioUnit au;
- pthread_mutex_t mutex;
- pthread_cond_t condition;
- char *buffer;
- int bufferSize;
- int pos;
- int len;
- int started;
-} OsxData;
-
-static OsxData *newOsxData()
-{
- OsxData *ret = xmalloc(sizeof(OsxData));
-
- pthread_mutex_init(&ret->mutex, NULL);
- pthread_cond_init(&ret->condition, NULL);
-
- ret->pos = 0;
- ret->len = 0;
- ret->started = 0;
- ret->buffer = NULL;
- ret->bufferSize = 0;
-
- return ret;
-}
-
-static int osx_testDefault()
-{
- /*AudioUnit au;
- ComponentDescription desc;
- Component comp;
-
- desc.componentType = kAudioUnitType_Output;
- desc.componentSubType = kAudioUnitSubType_Output;
- desc.componentManufacturer = kAudioUnitManufacturer_Apple;
- desc.componentFlags = 0;
- desc.componentFlagsMask = 0;
-
- comp = FindNextComponent(NULL, &desc);
- if(!comp) {
- ERROR("Unable to open default OS X defice\n");
- return -1;
- }
-
- if(OpenAComponent(comp, &au) != noErr) {
- ERROR("Unable to open default OS X defice\n");
- return -1;
- }
-
- CloseComponent(au); */
-
- return 0;
-}
-
-static int osx_initDriver(AudioOutput * audioOutput, ConfigParam * param)
-{
- OsxData *od = newOsxData();
-
- audioOutput->data = od;
-
- return 0;
-}
-
-static void freeOsxData(OsxData * od)
-{
- if (od->buffer)
- free(od->buffer);
- pthread_mutex_destroy(&od->mutex);
- pthread_cond_destroy(&od->condition);
- free(od);
-}
-
-static void osx_finishDriver(AudioOutput * audioOutput)
-{
- OsxData *od = (OsxData *) audioOutput->data;
- freeOsxData(od);
-}
-
-static void osx_dropBufferedAudio(AudioOutput * audioOutput)
-{
- OsxData *od = (OsxData *) audioOutput->data;
-
- pthread_mutex_lock(&od->mutex);
- od->len = 0;
- pthread_mutex_unlock(&od->mutex);
-}
-
-static void osx_closeDevice(AudioOutput * audioOutput)
-{
- OsxData *od = (OsxData *) audioOutput->data;
-
- pthread_mutex_lock(&od->mutex);
- while (od->len) {
- pthread_cond_wait(&od->condition, &od->mutex);
- }
- pthread_mutex_unlock(&od->mutex);
-
- if (od->started) {
- AudioOutputUnitStop(od->au);
- od->started = 0;
- }
-
- CloseComponent(od->au);
- AudioUnitUninitialize(od->au);
-
- audioOutput->open = 0;
-}
-
-static OSStatus osx_render(void *vdata,
- AudioUnitRenderActionFlags * ioActionFlags,
- const AudioTimeStamp * inTimeStamp,
- UInt32 inBusNumber, UInt32 inNumberFrames,
- AudioBufferList * bufferList)
-{
- OsxData *od = (OsxData *) vdata;
- AudioBuffer *buffer = &bufferList->mBuffers[0];
- int bufferSize = buffer->mDataByteSize;
- int bytesToCopy;
- int curpos = 0;
-
- /*DEBUG("osx_render: enter : %i\n", (int)bufferList->mNumberBuffers);
- DEBUG("osx_render: ioActionFlags: %p\n", ioActionFlags);
- if(ioActionFlags) {
- if(*ioActionFlags & kAudioUnitRenderAction_PreRender) {
- DEBUG("prerender\n");
- }
- if(*ioActionFlags & kAudioUnitRenderAction_PostRender) {
- DEBUG("post render\n");
- }
- if(*ioActionFlags & kAudioUnitRenderAction_OutputIsSilence) {
- DEBUG("post render\n");
- }
- if(*ioActionFlags & kAudioOfflineUnitRenderAction_Preflight) {
- DEBUG("prefilight\n");
- }
- if(*ioActionFlags & kAudioOfflineUnitRenderAction_Render) {
- DEBUG("render\n");
- }
- if(*ioActionFlags & kAudioOfflineUnitRenderAction_Complete) {
- DEBUG("complete\n");
- }
- } */
-
- /* while(bufferSize) {
- DEBUG("osx_render: lock\n"); */
- pthread_mutex_lock(&od->mutex);
- /*
- DEBUG("%i:%i\n", bufferSize, od->len);
- while(od->go && od->len < bufferSize &&
- od->len < od->bufferSize)
- {
- DEBUG("osx_render: wait\n");
- pthread_cond_wait(&od->condition, &od->mutex);
- }
- */
-
- bytesToCopy = od->len < bufferSize ? od->len : bufferSize;
- bufferSize = bytesToCopy;
- od->len -= bytesToCopy;
-
- if (od->pos + bytesToCopy > od->bufferSize) {
- int bytes = od->bufferSize - od->pos;
- memcpy(buffer->mData + curpos, od->buffer + od->pos, bytes);
- od->pos = 0;
- curpos += bytes;
- bytesToCopy -= bytes;
- }
-
- memcpy(buffer->mData + curpos, od->buffer + od->pos, bytesToCopy);
- od->pos += bytesToCopy;
- curpos += bytesToCopy;
-
- if (od->pos >= od->bufferSize)
- od->pos = 0;
- /* DEBUG("osx_render: unlock\n"); */
- pthread_mutex_unlock(&od->mutex);
- pthread_cond_signal(&od->condition);
- /* } */
-
- buffer->mDataByteSize = bufferSize;
-
- if (!bufferSize) {
- my_usleep(1000);
- }
-
- /* DEBUG("osx_render: leave\n"); */
- return 0;
-}
-
-static int osx_openDevice(AudioOutput * audioOutput)
-{
- OsxData *od = (OsxData *) audioOutput->data;
- ComponentDescription desc;
- Component comp;
- AURenderCallbackStruct callback;
- AudioFormat *audioFormat = &audioOutput->outAudioFormat;
- AudioStreamBasicDescription streamDesc;
-
- desc.componentType = kAudioUnitType_Output;
- desc.componentSubType = kAudioUnitSubType_DefaultOutput;
- desc.componentManufacturer = kAudioUnitManufacturer_Apple;
- desc.componentFlags = 0;
- desc.componentFlagsMask = 0;
-
- comp = FindNextComponent(NULL, &desc);
- if (comp == 0) {
- ERROR("Error finding OS X component\n");
- return -1;
- }
-
- if (OpenAComponent(comp, &od->au) != noErr) {
- ERROR("Unable to open OS X component\n");
- return -1;
- }
-
- if (AudioUnitInitialize(od->au) != 0) {
- CloseComponent(od->au);
- ERROR("Unable to initialize OS X audio unit\n");
- return -1;
- }
-
- callback.inputProc = osx_render;
- callback.inputProcRefCon = od;
-
- if (AudioUnitSetProperty(od->au, kAudioUnitProperty_SetRenderCallback,
- kAudioUnitScope_Input, 0,
- &callback, sizeof(callback)) != 0) {
- AudioUnitUninitialize(od->au);
- CloseComponent(od->au);
- ERROR("unable to set callback for OS X audio unit\n");
- return -1;
- }
-
- streamDesc.mSampleRate = audioFormat->sampleRate;
- streamDesc.mFormatID = kAudioFormatLinearPCM;
- streamDesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
-#ifdef WORDS_BIGENDIAN
- streamDesc.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
-#endif
-
- streamDesc.mBytesPerPacket =
- audioFormat->channels * audioFormat->bits / 8;
- streamDesc.mFramesPerPacket = 1;
- streamDesc.mBytesPerFrame = streamDesc.mBytesPerPacket;
- streamDesc.mChannelsPerFrame = audioFormat->channels;
- streamDesc.mBitsPerChannel = audioFormat->bits;
-
- if (AudioUnitSetProperty(od->au, kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Input, 0,
- &streamDesc, sizeof(streamDesc)) != 0) {
- AudioUnitUninitialize(od->au);
- CloseComponent(od->au);
- ERROR("Unable to set format on OS X device\n");
- return -1;
- }
-
- /* create a buffer of 1s */
- od->bufferSize = (audioFormat->sampleRate) *
- (audioFormat->bits >> 3) * (audioFormat->channels);
- od->buffer = xrealloc(od->buffer, od->bufferSize);
-
- od->pos = 0;
- od->len = 0;
-
- audioOutput->open = 1;
-
- return 0;
-}
-
-static int osx_play(AudioOutput * audioOutput, char *playChunk, int size)
-{
- OsxData *od = (OsxData *) audioOutput->data;
- int bytesToCopy;
- int curpos;
-
- /* DEBUG("osx_play: enter\n"); */
-
- if (!od->started) {
- int err;
- od->started = 1;
- err = AudioOutputUnitStart(od->au);
- if (err) {
- ERROR("unable to start audio output: %i\n", err);
- return -1;
- }
- }
-
- pthread_mutex_lock(&od->mutex);
-
- while (size) {
- /* DEBUG("osx_play: lock\n"); */
- curpos = od->pos + od->len;
- if (curpos >= od->bufferSize)
- curpos -= od->bufferSize;
-
- bytesToCopy = od->bufferSize < size ? od->bufferSize : size;
-
- while (od->len > od->bufferSize - bytesToCopy) {
- /* DEBUG("osx_play: wait\n"); */
- pthread_cond_wait(&od->condition, &od->mutex);
- }
-
- bytesToCopy = od->bufferSize - od->len;
- bytesToCopy = bytesToCopy < size ? bytesToCopy : size;
- size -= bytesToCopy;
- od->len += bytesToCopy;
-
- if (curpos + bytesToCopy > od->bufferSize) {
- int bytes = od->bufferSize - curpos;
- memcpy(od->buffer + curpos, playChunk, bytes);
- curpos = 0;
- playChunk += bytes;
- bytesToCopy -= bytes;
- }
-
- memcpy(od->buffer + curpos, playChunk, bytesToCopy);
- curpos += bytesToCopy;
- playChunk += bytesToCopy;
-
- }
- /* DEBUG("osx_play: unlock\n"); */
- pthread_mutex_unlock(&od->mutex);
-
- /* DEBUG("osx_play: leave\n"); */
- return 0;
-}
-
-AudioOutputPlugin osxPlugin = {
- "osx",
- osx_testDefault,
- osx_initDriver,
- osx_finishDriver,
- osx_openDevice,
- osx_play,
- osx_dropBufferedAudio,
- osx_closeDevice,
- NULL, /* sendMetadataFunc */
-};
-
-#else
-
-#include <stdio.h>
-
-DISABLED_AUDIO_OUTPUT_PLUGIN(osxPlugin)
-#endif
diff --git a/trunk/src/audioOutputs/audioOutput_pulse.c b/trunk/src/audioOutputs/audioOutput_pulse.c
deleted file mode 100644
index 8948e0263..000000000
--- a/trunk/src/audioOutputs/audioOutput_pulse.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "../audioOutput.h"
-
-#include <stdlib.h>
-
-#ifdef HAVE_PULSE
-
-#include "../conf.h"
-#include "../log.h"
-
-#include <string.h>
-#include <time.h>
-
-#include <pulse/simple.h>
-#include <pulse/error.h>
-
-#define MPD_PULSE_NAME "mpd"
-#define CONN_ATTEMPT_INTERVAL 60
-
-typedef struct _PulseData {
- pa_simple *s;
- char *server;
- char *sink;
- int connAttempts;
- time_t lastAttempt;
-} PulseData;
-
-static PulseData *newPulseData(void)
-{
- PulseData *ret;
-
- ret = xmalloc(sizeof(PulseData));
-
- ret->s = NULL;
- ret->server = NULL;
- ret->sink = NULL;
- ret->connAttempts = 0;
- ret->lastAttempt = 0;
-
- return ret;
-}
-
-static void freePulseData(PulseData * pd)
-{
- if (pd->server)
- free(pd->server);
- if (pd->sink)
- free(pd->sink);
- free(pd);
-}
-
-static int pulse_initDriver(AudioOutput * audioOutput, ConfigParam * param)
-{
- BlockParam *server = NULL;
- BlockParam *sink = NULL;
- PulseData *pd;
-
- if (param) {
- server = getBlockParam(param, "server");
- sink = getBlockParam(param, "sink");
- }
-
- pd = newPulseData();
- pd->server = server ? xstrdup(server->value) : NULL;
- pd->sink = sink ? xstrdup(sink->value) : NULL;
- audioOutput->data = pd;
-
- return 0;
-}
-
-static void pulse_finishDriver(AudioOutput * audioOutput)
-{
- freePulseData((PulseData *) audioOutput->data);
-}
-
-static int pulse_testDefault(void)
-{
- pa_simple *s;
- pa_sample_spec ss;
- int error;
-
- ss.format = PA_SAMPLE_S16NE;
- ss.rate = 44100;
- ss.channels = 2;
-
- s = pa_simple_new(NULL, MPD_PULSE_NAME, PA_STREAM_PLAYBACK, NULL,
- MPD_PULSE_NAME, &ss, NULL, NULL, &error);
- if (!s) {
- WARNING("Cannot connect to default PulseAudio server: %s\n",
- pa_strerror(error));
- return -1;
- }
-
- pa_simple_free(s);
-
- return 0;
-}
-
-static int pulse_openDevice(AudioOutput * audioOutput)
-{
- PulseData *pd;
- AudioFormat *audioFormat;
- pa_sample_spec ss;
- time_t t;
- int error;
-
- t = time(NULL);
- pd = audioOutput->data;
- audioFormat = &audioOutput->outAudioFormat;
-
- if (pd->connAttempts != 0 &&
- (t - pd->lastAttempt) < CONN_ATTEMPT_INTERVAL)
- return -1;
-
- pd->connAttempts++;
- pd->lastAttempt = t;
-
- if (audioFormat->bits != 16) {
- ERROR("PulseAudio doesn't support %i bit audio\n",
- audioFormat->bits);
- return -1;
- }
-
- ss.format = PA_SAMPLE_S16NE;
- ss.rate = audioFormat->sampleRate;
- ss.channels = audioFormat->channels;
-
- pd->s = pa_simple_new(pd->server, MPD_PULSE_NAME, PA_STREAM_PLAYBACK,
- pd->sink, audioOutput->name, &ss, NULL, NULL,
- &error);
- if (!pd->s) {
- ERROR("Cannot connect to server in PulseAudio output "
- "\"%s\" (attempt %i): %s\n", audioOutput->name,
- pd->connAttempts, pa_strerror(error));
- return -1;
- }
-
- pd->connAttempts = 0;
- audioOutput->open = 1;
-
- DEBUG("PulseAudio output \"%s\" connected and playing %i bit, %i "
- "channel audio at %i Hz\n", audioOutput->name, audioFormat->bits,
- audioFormat->channels, audioFormat->sampleRate);
-
- return 0;
-}
-
-static void pulse_dropBufferedAudio(AudioOutput * audioOutput)
-{
- PulseData *pd;
- int error;
-
- pd = audioOutput->data;
- if (pa_simple_flush(pd->s, &error) < 0)
- WARNING("Flush failed in PulseAudio output \"%s\": %s\n",
- audioOutput->name, pa_strerror(error));
-}
-
-static void pulse_closeDevice(AudioOutput * audioOutput)
-{
- PulseData *pd;
-
- pd = audioOutput->data;
- if (pd->s) {
- pa_simple_drain(pd->s, NULL);
- pa_simple_free(pd->s);
- }
-
- audioOutput->open = 0;
-}
-
-static int pulse_playAudio(AudioOutput * audioOutput, char *playChunk, int size)
-{
- PulseData *pd;
- int error;
-
- pd = audioOutput->data;
-
- if (pa_simple_write(pd->s, playChunk, size, &error) < 0) {
- ERROR("PulseAudio output \"%s\" disconnecting due to write "
- "error: %s\n", audioOutput->name, pa_strerror(error));
- pulse_closeDevice(audioOutput);
- return -1;
- }
-
- return 0;
-}
-
-AudioOutputPlugin pulsePlugin = {
- "pulse",
- pulse_testDefault,
- pulse_initDriver,
- pulse_finishDriver,
- pulse_openDevice,
- pulse_playAudio,
- pulse_dropBufferedAudio,
- pulse_closeDevice,
- NULL, /* sendMetadataFunc */
-};
-
-#else /* HAVE_PULSE */
-
-DISABLED_AUDIO_OUTPUT_PLUGIN(pulsePlugin)
-#endif /* HAVE_PULSE */
diff --git a/trunk/src/audioOutputs/audioOutput_shout.c b/trunk/src/audioOutputs/audioOutput_shout.c
deleted file mode 100644
index 7d93f8f85..000000000
--- a/trunk/src/audioOutputs/audioOutput_shout.c
+++ /dev/null
@@ -1,636 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "../audioOutput.h"
-
-#include <stdlib.h>
-
-#ifdef HAVE_SHOUT
-
-#include "../conf.h"
-#include "../log.h"
-#include "../pcm_utils.h"
-
-#include <string.h>
-#include <time.h>
-
-#include <shout/shout.h>
-#include <vorbis/vorbisenc.h>
-
-#define CONN_ATTEMPT_INTERVAL 60
-
-static int shoutInitCount;
-
-/* lots of this code blatantly stolent from bossogg/bossao2 */
-
-typedef struct _ShoutData {
- shout_t *shoutConn;
- int shoutError;
-
- ogg_stream_state os;
- ogg_page og;
- ogg_packet op;
- ogg_packet header_main;
- ogg_packet header_comments;
- ogg_packet header_codebooks;
-
- vorbis_dsp_state vd;
- vorbis_block vb;
- vorbis_info vi;
- vorbis_comment vc;
-
- float quality;
- int bitrate;
-
- int opened;
-
- MpdTag *tag;
- int tagToSend;
-
- int connAttempts;
- time_t lastAttempt;
- int last_err;
-
- /* just a pointer to audioOutput->outAudioFormat */
- AudioFormat *audioFormat;
-} ShoutData;
-
-static ShoutData *newShoutData(void)
-{
- ShoutData *ret = xmalloc(sizeof(ShoutData));
-
- ret->shoutConn = shout_new();
- ret->opened = 0;
- ret->tag = NULL;
- ret->tagToSend = 0;
- ret->bitrate = -1;
- ret->quality = -2.0;
- ret->connAttempts = 0;
- ret->lastAttempt = 0;
- ret->audioFormat = NULL;
- ret->last_err = SHOUTERR_UNCONNECTED;
-
- return ret;
-}
-
-static void freeShoutData(ShoutData * sd)
-{
- if (sd->shoutConn)
- shout_free(sd->shoutConn);
- if (sd->tag)
- freeMpdTag(sd->tag);
-
- free(sd);
-}
-
-#define checkBlockParam(name) { \
- blockParam = getBlockParam(param, name); \
- if (!blockParam) { \
- FATAL("no \"%s\" defined for shout device defined at line " \
- "%i\n", name, param->line); \
- } \
-}
-
-static int myShout_initDriver(AudioOutput * audioOutput, ConfigParam * param)
-{
- ShoutData *sd;
- char *test;
- int port;
- char *host;
- char *mount;
- char *passwd;
- char *user;
- char *name;
- BlockParam *blockParam;
- unsigned int public = 0;
-
- sd = newShoutData();
-
- if (shoutInitCount == 0)
- shout_init();
-
- shoutInitCount++;
-
- checkBlockParam("host");
- host = blockParam->value;
-
- checkBlockParam("mount");
- mount = blockParam->value;
-
- checkBlockParam("port");
-
- port = strtol(blockParam->value, &test, 10);
-
- if (*test != '\0' || port <= 0) {
- FATAL("shout port \"%s\" is not a positive integer, line %i\n",
- blockParam->value, blockParam->line);
- }
-
- checkBlockParam("password");
- passwd = blockParam->value;
-
- checkBlockParam("name");
- name = blockParam->value;
-
- blockParam = getBlockParam(param, "public");
- if (blockParam) {
- if (0 == strcmp(blockParam->value, "yes")) {
- public = 1;
- } else if (0 == strcmp(blockParam->value, "no")) {
- public = 0;
- } else {
- FATAL("public \"%s\" is not \"yes\" or \"no\" at line "
- "%i\n", param->value, param->line);
- }
- }
-
- blockParam = getBlockParam(param, "user");
- if (blockParam)
- user = blockParam->value;
- else
- user = "source";
-
- blockParam = getBlockParam(param, "quality");
-
- if (blockParam) {
- int line = blockParam->line;
-
- sd->quality = strtod(blockParam->value, &test);
-
- if (*test != '\0' || sd->quality < -1.0 || sd->quality > 10.0) {
- FATAL("shout quality \"%s\" is not a number in the "
- "range -1 to 10, line %i\n", blockParam->value,
- blockParam->line);
- }
-
- blockParam = getBlockParam(param, "bitrate");
-
- if (blockParam) {
- FATAL("quality (line %i) and bitrate (line %i) are "
- "both defined for shout output\n", line,
- blockParam->line);
- }
- } else {
- blockParam = getBlockParam(param, "bitrate");
-
- if (!blockParam) {
- FATAL("neither bitrate nor quality defined for shout "
- "output at line %i\n", param->line);
- }
-
- sd->bitrate = strtol(blockParam->value, &test, 10);
-
- if (*test != '\0' || sd->bitrate <= 0) {
- FATAL("bitrate at line %i should be a positive integer "
- "\n", blockParam->line);
- }
- }
-
- checkBlockParam("format");
- sd->audioFormat = &audioOutput->outAudioFormat;
-
- if (shout_set_host(sd->shoutConn, host) != SHOUTERR_SUCCESS ||
- shout_set_port(sd->shoutConn, port) != SHOUTERR_SUCCESS ||
- shout_set_password(sd->shoutConn, passwd) != SHOUTERR_SUCCESS ||
- shout_set_mount(sd->shoutConn, mount) != SHOUTERR_SUCCESS ||
- shout_set_name(sd->shoutConn, name) != SHOUTERR_SUCCESS ||
- shout_set_user(sd->shoutConn, user) != SHOUTERR_SUCCESS ||
- shout_set_public(sd->shoutConn, public) != SHOUTERR_SUCCESS ||
- shout_set_nonblocking(sd->shoutConn, 1) != SHOUTERR_SUCCESS ||
- shout_set_format(sd->shoutConn, SHOUT_FORMAT_VORBIS)
- != SHOUTERR_SUCCESS ||
- shout_set_protocol(sd->shoutConn, SHOUT_PROTOCOL_HTTP)
- != SHOUTERR_SUCCESS ||
- shout_set_agent(sd->shoutConn, "MPD") != SHOUTERR_SUCCESS) {
- FATAL("error configuring shout defined at line %i: %s\n",
- param->line, shout_get_error(sd->shoutConn));
- }
-
- /* optional paramters */
- blockParam = getBlockParam(param, "genre");
- if (blockParam && shout_set_genre(sd->shoutConn, blockParam->value)) {
- FATAL("error configuring shout defined at line %i: %s\n",
- param->line, shout_get_error(sd->shoutConn));
- }
-
- blockParam = getBlockParam(param, "description");
- if (blockParam && shout_set_description(sd->shoutConn,
- blockParam->value)) {
- FATAL("error configuring shout defined at line %i: %s\n",
- param->line, shout_get_error(sd->shoutConn));
- }
-
- {
- char temp[11];
- memset(temp, 0, sizeof(temp));
-
- snprintf(temp, sizeof(temp), "%d", sd->audioFormat->channels);
- shout_set_audio_info(sd->shoutConn, SHOUT_AI_CHANNELS, temp);
-
- snprintf(temp, sizeof(temp), "%d", sd->audioFormat->sampleRate);
-
- shout_set_audio_info(sd->shoutConn, SHOUT_AI_SAMPLERATE, temp);
-
- if (sd->quality >= -1.0) {
- snprintf(temp, sizeof(temp), "%2.2f", sd->quality);
- shout_set_audio_info(sd->shoutConn, SHOUT_AI_QUALITY,
- temp);
- } else {
- snprintf(temp, sizeof(temp), "%d", sd->bitrate);
- shout_set_audio_info(sd->shoutConn, SHOUT_AI_BITRATE,
- temp);
- }
- }
-
- audioOutput->data = sd;
-
- return 0;
-}
-
-static int myShout_handleError(ShoutData * sd, int err)
-{
- switch (err) {
- case SHOUTERR_SUCCESS:
- break;
- case SHOUTERR_UNCONNECTED:
- case SHOUTERR_SOCKET:
- ERROR("Lost shout connection to %s:%i : %s\n",
- shout_get_host(sd->shoutConn),
- shout_get_port(sd->shoutConn),
- shout_get_error(sd->shoutConn));
- sd->shoutError = 1;
- return -1;
- default:
- ERROR("shout: connection to %s:%i error : %s\n",
- shout_get_host(sd->shoutConn),
- shout_get_port(sd->shoutConn),
- shout_get_error(sd->shoutConn));
- sd->shoutError = 1;
- return -1;
- }
-
- return 0;
-}
-
-static int write_page(ShoutData * sd)
-{
- int err = 0;
-
- /*DEBUG("shout_delay: %i\n", shout_delay(sd->shoutConn)); */
- shout_sync(sd->shoutConn);
- err = shout_send(sd->shoutConn, sd->og.header, sd->og.header_len);
- if (myShout_handleError(sd, err) < 0)
- return -1;
- err = shout_send(sd->shoutConn, sd->og.body, sd->og.body_len);
- if (myShout_handleError(sd, err) < 0)
- return -1;
-
- return 0;
-}
-
-static void finishEncoder(ShoutData * sd)
-{
- vorbis_analysis_wrote(&sd->vd, 0);
-
- while (vorbis_analysis_blockout(&sd->vd, &sd->vb) == 1) {
- vorbis_analysis(&sd->vb, NULL);
- vorbis_bitrate_addblock(&sd->vb);
- while (vorbis_bitrate_flushpacket(&sd->vd, &sd->op)) {
- ogg_stream_packetin(&sd->os, &sd->op);
- }
- }
-}
-
-static int flushEncoder(ShoutData * sd)
-{
- return (ogg_stream_pageout(&sd->os, &sd->og) > 0);
-}
-
-static void clearEncoder(ShoutData * sd)
-{
- finishEncoder(sd);
- while (1 == flushEncoder(sd)) {
- if (!sd->shoutError)
- write_page(sd);
- }
-
- vorbis_comment_clear(&sd->vc);
- ogg_stream_clear(&sd->os);
- vorbis_block_clear(&sd->vb);
- vorbis_dsp_clear(&sd->vd);
- vorbis_info_clear(&sd->vi);
-}
-
-static void myShout_closeShoutConn(ShoutData * sd)
-{
- if (sd->opened) {
- clearEncoder(sd);
-
- if (shout_close(sd->shoutConn) != SHOUTERR_SUCCESS) {
- ERROR("problem closing connection to shout server: "
- "%s\n", shout_get_error(sd->shoutConn));
- }
- }
-
- sd->last_err = SHOUTERR_UNCONNECTED;
- sd->opened = 0;
-}
-
-static void myShout_finishDriver(AudioOutput * audioOutput)
-{
- ShoutData *sd = (ShoutData *) audioOutput->data;
-
- myShout_closeShoutConn(sd);
-
- freeShoutData(sd);
-
- shoutInitCount--;
-
- if (shoutInitCount == 0)
- shout_shutdown();
-}
-
-static void myShout_dropBufferedAudio(AudioOutput * audioOutput)
-{
- /* needs to be implemented */
-}
-
-static void myShout_closeDevice(AudioOutput * audioOutput)
-{
- ShoutData *sd = (ShoutData *) audioOutput->data;
-
- myShout_closeShoutConn(sd);
-
- audioOutput->open = 0;
-}
-
-#define addTag(name, value) { \
- if(value) vorbis_comment_add_tag(&(sd->vc), name, value); \
-}
-
-static void copyTagToVorbisComment(ShoutData * sd)
-{
- if (sd->tag) {
- int i;
-
- for (i = 0; i < sd->tag->numOfItems; i++) {
- switch (sd->tag->items[i].type) {
- case TAG_ITEM_ARTIST:
- addTag("ARTIST", sd->tag->items[i].value);
- break;
- case TAG_ITEM_ALBUM:
- addTag("ALBUM", sd->tag->items[i].value);
- break;
- case TAG_ITEM_TITLE:
- addTag("TITLE", sd->tag->items[i].value);
- break;
- }
- }
- }
-}
-
-static int initEncoder(ShoutData * sd)
-{
- vorbis_info_init(&(sd->vi));
-
- if (sd->quality >= -1.0) {
- if (0 != vorbis_encode_init_vbr(&(sd->vi),
- sd->audioFormat->channels,
- sd->audioFormat->sampleRate,
- sd->quality * 0.1)) {
- ERROR("problem setting up vorbis encoder for shout\n");
- vorbis_info_clear(&(sd->vi));
- return -1;
- }
- } else {
- if (0 != vorbis_encode_init(&(sd->vi),
- sd->audioFormat->channels,
- sd->audioFormat->sampleRate, -1.0,
- sd->bitrate * 1000, -1.0)) {
- ERROR("problem setting up vorbis encoder for shout\n");
- vorbis_info_clear(&(sd->vi));
- return -1;
- }
- }
-
- vorbis_analysis_init(&(sd->vd), &(sd->vi));
- vorbis_block_init(&(sd->vd), &(sd->vb));
-
- ogg_stream_init(&(sd->os), rand());
-
- vorbis_comment_init(&(sd->vc));
-
- return 0;
-}
-
-static int myShout_openShoutConn(AudioOutput * audioOutput)
-{
- ShoutData *sd = (ShoutData *) audioOutput->data;
- time_t t = time(NULL);
-
- if (sd->connAttempts != 0 &&
- (t - sd->lastAttempt) < CONN_ATTEMPT_INTERVAL) {
- return -1;
- }
-
- sd->connAttempts++;
-
- if (sd->last_err == SHOUTERR_UNCONNECTED)
- sd->last_err = shout_open(sd->shoutConn);
- switch (sd->last_err) {
- case SHOUTERR_SUCCESS:
- case SHOUTERR_CONNECTED:
- break;
- case SHOUTERR_BUSY:
- sd->last_err = shout_get_connected(sd->shoutConn);
- if (sd->last_err == SHOUTERR_CONNECTED)
- break;
- return -1;
- default:
- sd->lastAttempt = t;
- ERROR("problem opening connection to shout server %s:%i "
- "(attempt %i): %s\n",
- shout_get_host(sd->shoutConn),
- shout_get_port(sd->shoutConn),
- sd->connAttempts, shout_get_error(sd->shoutConn));
- return -1;
- }
-
- if (initEncoder(sd) < 0) {
- shout_close(sd->shoutConn);
- return -1;
- }
-
- sd->shoutError = 0;
-
- copyTagToVorbisComment(sd);
-
- vorbis_analysis_headerout(&(sd->vd), &(sd->vc), &(sd->header_main),
- &(sd->header_comments),
- &(sd->header_codebooks));
-
- ogg_stream_packetin(&(sd->os), &(sd->header_main));
- ogg_stream_packetin(&(sd->os), &(sd->header_comments));
- ogg_stream_packetin(&(sd->os), &(sd->header_codebooks));
-
- sd->opened = 1;
- sd->tagToSend = 0;
-
- while (ogg_stream_flush(&(sd->os), &(sd->og))) {
- if (write_page(sd) < 0) {
- myShout_closeShoutConn(sd);
- return -1;
- }
- }
-
- sd->connAttempts = 0;
-
- return 0;
-}
-
-static int myShout_openDevice(AudioOutput * audioOutput)
-{
- ShoutData *sd = (ShoutData *) audioOutput->data;
-
- audioOutput->open = 1;
-
- if (sd->opened)
- return 0;
-
- if (myShout_openShoutConn(audioOutput) < 0) {
- audioOutput->open = 0;
- return -1;
- }
-
- return 0;
-}
-
-static void myShout_sendMetadata(ShoutData * sd)
-{
- if (!sd->opened || !sd->tag)
- return;
-
- clearEncoder(sd);
- if (initEncoder(sd) < 0)
- return;
-
- copyTagToVorbisComment(sd);
-
- vorbis_analysis_headerout(&(sd->vd), &(sd->vc), &(sd->header_main),
- &(sd->header_comments),
- &(sd->header_codebooks));
-
- ogg_stream_packetin(&(sd->os), &(sd->header_main));
- ogg_stream_packetin(&(sd->os), &(sd->header_comments));
- ogg_stream_packetin(&(sd->os), &(sd->header_codebooks));
-
- while (ogg_stream_flush(&(sd->os), &(sd->og))) {
- if (write_page(sd) < 0) {
- myShout_closeShoutConn(sd);
- return;
- }
- }
-
- /*if(sd->tag) freeMpdTag(sd->tag);
- sd->tag = NULL; */
- sd->tagToSend = 0;
-}
-
-static int myShout_play(AudioOutput * audioOutput, char *playChunk, int size)
-{
- int i, j;
- ShoutData *sd = (ShoutData *) audioOutput->data;
- float **vorbbuf;
- int samples;
- int bytes = sd->audioFormat->bits / 8;
-
- if (sd->opened && sd->tagToSend)
- myShout_sendMetadata(sd);
-
- if (!sd->opened) {
- if (myShout_openShoutConn(audioOutput) < 0) {
- return -1;
- }
- }
-
- samples = size / (bytes * sd->audioFormat->channels);
-
- /* this is for only 16-bit audio */
-
- vorbbuf = vorbis_analysis_buffer(&(sd->vd), samples);
-
- for (i = 0; i < samples; i++) {
- for (j = 0; j < sd->audioFormat->channels; j++) {
- vorbbuf[j][i] = (*((mpd_sint16 *) playChunk)) / 32768.0;
- playChunk += bytes;
- }
- }
-
- vorbis_analysis_wrote(&(sd->vd), samples);
-
- while (1 == vorbis_analysis_blockout(&(sd->vd), &(sd->vb))) {
- vorbis_analysis(&(sd->vb), NULL);
- vorbis_bitrate_addblock(&(sd->vb));
-
- while (vorbis_bitrate_flushpacket(&(sd->vd), &(sd->op))) {
- ogg_stream_packetin(&(sd->os), &(sd->op));
- }
- }
-
- while (ogg_stream_pageout(&(sd->os), &(sd->og)) != 0) {
- if (write_page(sd) < 0) {
- myShout_closeShoutConn(sd);
- return -1;
- }
- }
-
- return 0;
-}
-
-static void myShout_setTag(AudioOutput * audioOutput, MpdTag * tag)
-{
- ShoutData *sd = (ShoutData *) audioOutput->data;
-
- if (sd->tag)
- freeMpdTag(sd->tag);
- sd->tag = NULL;
- sd->tagToSend = 0;
-
- if (!tag)
- return;
-
- sd->tag = mpdTagDup(tag);
- sd->tagToSend = 1;
-}
-
-AudioOutputPlugin shoutPlugin = {
- "shout",
- NULL,
- myShout_initDriver,
- myShout_finishDriver,
- myShout_openDevice,
- myShout_play,
- myShout_dropBufferedAudio,
- myShout_closeDevice,
- myShout_setTag,
-};
-
-#else
-
-DISABLED_AUDIO_OUTPUT_PLUGIN(shoutPlugin)
-#endif
diff --git a/trunk/src/buffer2array.c b/trunk/src/buffer2array.c
deleted file mode 100644
index d7bfc4561..000000000
--- a/trunk/src/buffer2array.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "buffer2array.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-
-static inline
-int
-isWhiteSpace(char c)
-{
- return (c == ' ' || c == '\t');
-}
-
-int buffer2array(char *buffer, char *array[], const int max)
-{
- int i = 0;
- char *c = buffer;
-
- while (*c != '\0' && i < max) {
- if (*c == '\"') {
- array[i++] = ++c;
- while (*c != '\0') {
- if (*c == '\"') {
- *(c++) = '\0';
- break;
- }
- else if (*(c++) == '\\' && *c != '\0') {
- memmove(c - 1, c, strlen(c) + 1);
- }
- }
- } else {
- while (isWhiteSpace(*c))
- ++c;
- array[i++] = c++;
- if (*c == '\0')
- return i;
- while (!isWhiteSpace(*c) && *c != '\0')
- ++c;
- }
- if (*c == '\0')
- return i;
- *(c++) = '\0';
- while (isWhiteSpace(*c))
- ++c;
- }
- return i;
-}
-
-#ifdef UNIT_TEST
-
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-int main()
-{
- char *a[4] = { NULL };
- char *b;
- int max;
-
- b = strdup("lsinfo \"/some/dir/name \\\"test\\\"\"");
- max = buffer2array(b, a, 4);
- assert( !strcmp("lsinfo", a[0]) );
- assert( !strcmp("/some/dir/name \"test\"", a[1]) );
- assert( !a[2] );
-
- b = strdup("lsinfo \"/some/dir/name \\\"test\\\" something else\"");
- max = buffer2array(b, a, 4);
- assert( !strcmp("lsinfo", a[0]) );
- assert( !strcmp("/some/dir/name \"test\" something else", a[1]) );
- assert( !a[2] );
-
- b = strdup("lsinfo \"/some/dir\\\\name\"");
- max = buffer2array(b, a, 4);
- assert( !strcmp("lsinfo", a[0]) );
- assert( !strcmp("/some/dir\\name", a[1]) );
- assert( !a[2] );
-
- b = strdup("lsinfo \"/some/dir name\"");
- max = buffer2array(b, a, 4);
- assert( !strcmp("lsinfo", a[0]) );
- assert( !strcmp("/some/dir name", a[1]) );
- assert( !a[2] );
-
- b = strdup("lsinfo \"\\\"/some/dir\\\"\"");
- max = buffer2array(b, a, 4);
- assert( !strcmp("lsinfo", a[0]) );
- assert( !strcmp("\"/some/dir\"", a[1]) );
- assert( !a[2] );
-
- b = strdup("lsinfo \"\\\"/some/dir\\\" x\"");
- max = buffer2array(b, a, 4);
- assert( !strcmp("lsinfo", a[0]) );
- assert( !strcmp("\"/some/dir\" x", a[1]) );
- assert( !a[2] );
-
- b = strdup("lsinfo \"single quote\\'d from php magicquotes\"");
- max = buffer2array(b, a, 4);
- assert( !strcmp("lsinfo", a[0]) );
- assert( !strcmp("single quote\'d from php magicquotes", a[1]) );
- assert( !a[2] );
-
- b = strdup("lsinfo \"double quote\\\"d from php magicquotes\"");
- max = buffer2array(b, a, 4);
- assert( !strcmp("lsinfo", a[0]) );
- assert( !strcmp("double quote\"d from php magicquotes", a[1]) );
- assert( !a[2] );
-
- return 0;
-}
-
-#endif
diff --git a/trunk/src/buffer2array.h b/trunk/src/buffer2array.h
deleted file mode 100644
index ece663994..000000000
--- a/trunk/src/buffer2array.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef BUFFER_2_ARRAY_H
-#define BUFFER_2_ARRAY_H
-
-#include "../config.h"
-
-/* tokenizes up to max elements in buffer (a null-terminated string) and
- * stores the result in array (which must be capable of holding up to
- * max elements). Tokenization is based on C string quoting rules.
- * The arguments buffer and array are modified.
- * Returns the number of elements tokenized.
- */
-int buffer2array(char *buffer, char *array[], const int max);
-
-#endif
diff --git a/trunk/src/charConv.c b/trunk/src/charConv.c
deleted file mode 100644
index 69777c47a..000000000
--- a/trunk/src/charConv.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "charConv.h"
-#include "mpd_types.h"
-#include "utf8.h"
-#include "utils.h"
-
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-
-#ifdef HAVE_ICONV
-#include <iconv.h>
-static iconv_t char_conv_iconv;
-#endif
-
-static char *char_conv_to;
-static char *char_conv_from;
-static mpd_sint8 char_conv_same;
-static mpd_sint8 char_conv_use_iconv;
-
-/* 1 is to use latin1ToUtf8
- 0 is not to use latin1/utf8 converter
- -1 is to use utf8ToLatin1*/
-static mpd_sint8 char_conv_latin1ToUtf8;
-
-#define BUFFER_SIZE 1024
-
-static void closeCharSetConversion(void);
-
-int setCharSetConversion(char *to, char *from)
-{
- if (char_conv_to && char_conv_from) {
- if (char_conv_latin1ToUtf8 &&
- !strcmp(from, char_conv_to) &&
- !strcmp(to, char_conv_from)) {
- char *swap = char_conv_from;
- char_conv_from = char_conv_to;
- char_conv_to = swap;
- char_conv_latin1ToUtf8 *= -1;
- return 0;
- } else if (!strcmp(to, char_conv_to) &&
- !strcmp(from,char_conv_from)) {
- return 0;
- }
- }
-
- closeCharSetConversion();
-
- if (0 == strcmp(to, from)) {
- char_conv_same = 1;
- char_conv_to = xstrdup(to);
- char_conv_from = xstrdup(from);
- return 0;
- }
-
- if (strcmp(to, "UTF-8") == 0 && strcmp(from, "ISO-8859-1") == 0) {
- char_conv_latin1ToUtf8 = 1;
- } else if (strcmp(to, "ISO-8859-1") == 0 && strcmp(from, "UTF-8") == 0) {
- char_conv_latin1ToUtf8 = -1;
- }
-
- if (char_conv_latin1ToUtf8 != 0) {
- char_conv_to = xstrdup(to);
- char_conv_from = xstrdup(from);
- return 0;
- }
-#ifdef HAVE_ICONV
- if ((char_conv_iconv = iconv_open(to, from)) == (iconv_t) (-1))
- return -1;
-
- char_conv_to = xstrdup(to);
- char_conv_from = xstrdup(from);
- char_conv_use_iconv = 1;
-
- return 0;
-#endif
-
- return -1;
-}
-
-char *convStrDup(char *string)
-{
- if (!char_conv_to)
- return NULL;
-
- if (char_conv_same)
- return xstrdup(string);
-
-#ifdef HAVE_ICONV
- if (char_conv_use_iconv) {
- char buffer[BUFFER_SIZE];
- size_t inleft = strlen(string);
- char *ret;
- size_t outleft;
- size_t retlen = 0;
- size_t err;
- char *bufferPtr;
-
- ret = xmalloc(1);
- ret[0] = '\0';
-
- while (inleft) {
- bufferPtr = buffer;
- outleft = BUFFER_SIZE;
- err =
- iconv(char_conv_iconv, &string, &inleft, &bufferPtr,
- &outleft);
- if (outleft == BUFFER_SIZE
- || (err == -1L && errno != E2BIG)) {
- free(ret);
- return NULL;
- }
-
- ret = xrealloc(ret, retlen + BUFFER_SIZE - outleft + 1);
- memcpy(ret + retlen, buffer, BUFFER_SIZE - outleft);
- retlen += BUFFER_SIZE - outleft;
- ret[retlen] = '\0';
- }
-
- return ret;
- }
-#endif
-
- switch (char_conv_latin1ToUtf8) {
- case 1:
- return latin1StrToUtf8Dup(string);
- break;
- case -1:
- return utf8StrToLatin1Dup(string);
- break;
- }
-
- return NULL;
-}
-
-static void closeCharSetConversion(void)
-{
- if (char_conv_to) {
-#ifdef HAVE_ICONV
- if (char_conv_use_iconv)
- iconv_close(char_conv_iconv);
-#endif
- free(char_conv_to);
- free(char_conv_from);
- char_conv_to = NULL;
- char_conv_from = NULL;
- char_conv_same = 0;
- char_conv_latin1ToUtf8 = 0;
- char_conv_use_iconv = 0;
- }
-}
diff --git a/trunk/src/charConv.h b/trunk/src/charConv.h
deleted file mode 100644
index 4b1ed4237..000000000
--- a/trunk/src/charConv.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef CHAR_CONV_H
-#define CHAR_CONV_H
-
-#include "../config.h"
-
-int setCharSetConversion(char *to, char *from);
-
-char *convStrDup(char *string);
-
-#endif
diff --git a/trunk/src/command.c b/trunk/src/command.c
deleted file mode 100644
index 84a30db2b..000000000
--- a/trunk/src/command.c
+++ /dev/null
@@ -1,1299 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "command.h"
-#include "player.h"
-#include "playlist.h"
-#include "ls.h"
-#include "directory.h"
-#include "volume.h"
-#include "stats.h"
-#include "myfprintf.h"
-#include "list.h"
-#include "permission.h"
-#include "buffer2array.h"
-#include "log.h"
-#include "tag.h"
-#include "utils.h"
-#include "storedPlaylist.h"
-
-#include <assert.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define COMMAND_PLAY "play"
-#define COMMAND_PLAYID "playid"
-#define COMMAND_STOP "stop"
-#define COMMAND_PAUSE "pause"
-#define COMMAND_STATUS "status"
-#define COMMAND_KILL "kill"
-#define COMMAND_CLOSE "close"
-#define COMMAND_ADD "add"
-#define COMMAND_ADDID "addid"
-#define COMMAND_DELETE "delete"
-#define COMMAND_DELETEID "deleteid"
-#define COMMAND_PLAYLIST "playlist"
-#define COMMAND_SHUFFLE "shuffle"
-#define COMMAND_CLEAR "clear"
-#define COMMAND_SAVE "save"
-#define COMMAND_LOAD "load"
-#define COMMAND_LISTPLAYLIST "listplaylist"
-#define COMMAND_LISTPLAYLISTINFO "listplaylistinfo"
-#define COMMAND_LSINFO "lsinfo"
-#define COMMAND_RM "rm"
-#define COMMAND_PLAYLISTINFO "playlistinfo"
-#define COMMAND_PLAYLISTID "playlistid"
-#define COMMAND_FIND "find"
-#define COMMAND_SEARCH "search"
-#define COMMAND_UPDATE "update"
-#define COMMAND_NEXT "next"
-#define COMMAND_PREVIOUS "previous"
-#define COMMAND_LISTALL "listall"
-#define COMMAND_VOLUME "volume"
-#define COMMAND_REPEAT "repeat"
-#define COMMAND_RANDOM "random"
-#define COMMAND_STATS "stats"
-#define COMMAND_CLEAR_ERROR "clearerror"
-#define COMMAND_LIST "list"
-#define COMMAND_MOVE "move"
-#define COMMAND_MOVEID "moveid"
-#define COMMAND_SWAP "swap"
-#define COMMAND_SWAPID "swapid"
-#define COMMAND_SEEK "seek"
-#define COMMAND_SEEKID "seekid"
-#define COMMAND_LISTALLINFO "listallinfo"
-#define COMMAND_PING "ping"
-#define COMMAND_SETVOL "setvol"
-#define COMMAND_PASSWORD "password"
-#define COMMAND_CROSSFADE "crossfade"
-#define COMMAND_URL_HANDLERS "urlhandlers"
-#define COMMAND_PLCHANGES "plchanges"
-#define COMMAND_PLCHANGESPOSID "plchangesposid"
-#define COMMAND_CURRENTSONG "currentsong"
-#define COMMAND_ENABLE_DEV "enableoutput"
-#define COMMAND_DISABLE_DEV "disableoutput"
-#define COMMAND_DEVICES "outputs"
-#define COMMAND_COMMANDS "commands"
-#define COMMAND_NOTCOMMANDS "notcommands"
-#define COMMAND_PLAYLISTCLEAR "playlistclear"
-#define COMMAND_PLAYLISTADD "playlistadd"
-#define COMMAND_PLAYLISTFIND "playlistfind"
-#define COMMAND_PLAYLISTSEARCH "playlistsearch"
-#define COMMAND_PLAYLISTMOVE "playlistmove"
-#define COMMAND_PLAYLISTDELETE "playlistdelete"
-#define COMMAND_TAGTYPES "tagtypes"
-#define COMMAND_COUNT "count"
-#define COMMAND_RENAME "rename"
-
-#define COMMAND_STATUS_VOLUME "volume"
-#define COMMAND_STATUS_STATE "state"
-#define COMMAND_STATUS_REPEAT "repeat"
-#define COMMAND_STATUS_RANDOM "random"
-#define COMMAND_STATUS_PLAYLIST "playlist"
-#define COMMAND_STATUS_PLAYLIST_LENGTH "playlistlength"
-#define COMMAND_STATUS_SONG "song"
-#define COMMAND_STATUS_SONGID "songid"
-#define COMMAND_STATUS_TIME "time"
-#define COMMAND_STATUS_BITRATE "bitrate"
-#define COMMAND_STATUS_ERROR "error"
-#define COMMAND_STATUS_CROSSFADE "xfade"
-#define COMMAND_STATUS_AUDIO "audio"
-#define COMMAND_STATUS_UPDATING_DB "updating_db"
-
-/*
- * The most we ever use is for search/find, and that limits it to the
- * number of tags we can have. Add one for the command, and one extra
- * to catch errors clients may send us
- */
-#define COMMAND_ARGV_MAX (2+(TAG_NUM_OF_ITEM_TYPES*2))
-
-typedef struct _CommandEntry CommandEntry;
-
-typedef int (*CommandHandlerFunction) (int, int *, int, char **);
-typedef int (*CommandListHandlerFunction)
- (int, int *, int, char **, struct strnode *, CommandEntry *);
-
-/* if min: -1 don't check args *
- * if max: -1 no max args */
-struct _CommandEntry {
- char *cmd;
- int min;
- int max;
- int reqPermission;
- CommandHandlerFunction handler;
- CommandListHandlerFunction listHandler;
-};
-
-static char *current_command;
-static int command_listNum;
-
-static CommandEntry *getCommandEntryFromString(char *string, int *permission);
-
-static List *commandList;
-
-static CommandEntry *newCommandEntry(void)
-{
- CommandEntry *cmd = xmalloc(sizeof(CommandEntry));
- cmd->cmd = NULL;
- cmd->min = 0;
- cmd->max = 0;
- cmd->handler = NULL;
- cmd->listHandler = NULL;
- cmd->reqPermission = 0;
- return cmd;
-}
-
-static void addCommand(char *name,
- int reqPermission,
- int minargs,
- int maxargs,
- CommandHandlerFunction handler_func,
- CommandListHandlerFunction listHandler_func)
-{
- CommandEntry *cmd = newCommandEntry();
- cmd->cmd = name;
- cmd->min = minargs;
- cmd->max = maxargs;
- cmd->handler = handler_func;
- cmd->listHandler = listHandler_func;
- cmd->reqPermission = reqPermission;
-
- insertInList(commandList, cmd->cmd, cmd);
-}
-
-static int handleUrlHandlers(int fd, int *permission, int argc, char *argv[])
-{
- return printRemoteUrlHandlers(fd);
-}
-
-static int handleTagTypes(int fd, int *permission, int argc, char *argv[])
-{
- printTagTypes(fd);
- return 0;
-}
-
-static int handlePlay(int fd, int *permission, int argc, char *argv[])
-{
- int song = -1;
- char *test;
-
- if (argc == 2) {
- song = strtol(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG,
- "need a positive integer");
- return -1;
- }
- }
- return playPlaylist(fd, song, 0);
-}
-
-static int handlePlayId(int fd, int *permission, int argc, char *argv[])
-{
- int id = -1;
- char *test;
-
- if (argc == 2) {
- id = strtol(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG,
- "need a positive integer");
- return -1;
- }
- }
- return playPlaylistById(fd, id, 0);
-}
-
-static int handleStop(int fd, int *permission, int argc, char *argv[])
-{
- return stopPlaylist(fd);
-}
-
-static int handleCurrentSong(int fd, int *permission, int argc, char *argv[])
-{
- int song = getPlaylistCurrentSong();
-
- if (song >= 0) {
- return playlistInfo(fd, song);
- } else
- return 0;
-}
-
-static int handlePause(int fd, int *permission, int argc, char *argv[])
-{
- if (argc == 2) {
- char *test;
- int pause = strtol(argv[1], &test, 10);
- if (*test != '\0' || (pause != 0 && pause != 1)) {
- commandError(fd, ACK_ERROR_ARG, "\"%s\" is not 0 or 1",
- argv[1]);
- return -1;
- }
- return playerSetPause(fd, pause);
- }
- return playerPause(fd);
-}
-
-static int commandStatus(int fd, int *permission, int argc, char *argv[])
-{
- char *state = NULL;
- int updateJobId;
- int song;
-
- /*syncPlayerAndPlaylist(); */
- playPlaylistIfPlayerStopped();
- switch (getPlayerState()) {
- case PLAYER_STATE_STOP:
- state = COMMAND_STOP;
- break;
- case PLAYER_STATE_PAUSE:
- state = COMMAND_PAUSE;
- break;
- case PLAYER_STATE_PLAY:
- state = COMMAND_PLAY;
- break;
- }
-
- fdprintf(fd, "%s: %i\n", COMMAND_STATUS_VOLUME, getVolumeLevel());
- fdprintf(fd, "%s: %i\n", COMMAND_STATUS_REPEAT,
- getPlaylistRepeatStatus());
- fdprintf(fd, "%s: %i\n", COMMAND_STATUS_RANDOM,
- getPlaylistRandomStatus());
- fdprintf(fd, "%s: %li\n", COMMAND_STATUS_PLAYLIST,
- getPlaylistVersion());
- fdprintf(fd, "%s: %i\n", COMMAND_STATUS_PLAYLIST_LENGTH,
- getPlaylistLength());
- fdprintf(fd, "%s: %i\n", COMMAND_STATUS_CROSSFADE,
- (int)(getPlayerCrossFade() + 0.5));
-
- fdprintf(fd, "%s: %s\n", COMMAND_STATUS_STATE, state);
-
- song = getPlaylistCurrentSong();
- if (song >= 0) {
- fdprintf(fd, "%s: %i\n", COMMAND_STATUS_SONG, song);
- fdprintf(fd, "%s: %i\n", COMMAND_STATUS_SONGID,
- getPlaylistSongId(song));
- }
- if (getPlayerState() != PLAYER_STATE_STOP) {
- fdprintf(fd, "%s: %i:%i\n", COMMAND_STATUS_TIME,
- getPlayerElapsedTime(), getPlayerTotalTime());
- fdprintf(fd, "%s: %li\n", COMMAND_STATUS_BITRATE,
- getPlayerBitRate());
- fdprintf(fd, "%s: %u:%i:%i\n", COMMAND_STATUS_AUDIO,
- getPlayerSampleRate(), getPlayerBits(),
- getPlayerChannels());
- }
-
- if ((updateJobId = isUpdatingDB())) {
- fdprintf(fd, "%s: %i\n", COMMAND_STATUS_UPDATING_DB,
- updateJobId);
- }
-
- if (getPlayerError() != PLAYER_ERROR_NOERROR) {
- fdprintf(fd, "%s: %s\n", COMMAND_STATUS_ERROR,
- getPlayerErrorStr());
- }
-
- return 0;
-}
-
-static int handleKill(int fd, int *permission, int argc, char *argv[])
-{
- return COMMAND_RETURN_KILL;
-}
-
-static int handleClose(int fd, int *permission, int argc, char *argv[])
-{
- return COMMAND_RETURN_CLOSE;
-}
-
-static int handleAdd(int fd, int *permission, int argc, char *argv[])
-{
- char *path = argv[1];
-
- if (isRemoteUrl(path))
- return addToPlaylist(fd, path, 0);
-
- return addAllIn(fd, path);
-}
-
-static int handleAddId(int fd, int *permission, int argc, char *argv[])
-{
- return addToPlaylist(fd, argv[1], 1);
-}
-
-static int handleDelete(int fd, int *permission, int argc, char *argv[])
-{
- int song;
- char *test;
-
- song = strtol(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG, "need a positive integer");
- return -1;
- }
- return deleteFromPlaylist(fd, song);
-}
-
-static int handleDeleteId(int fd, int *permission, int argc, char *argv[])
-{
- int id;
- char *test;
-
- id = strtol(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG, "need a positive integer");
- return -1;
- }
- return deleteFromPlaylistById(fd, id);
-}
-
-static int handlePlaylist(int fd, int *permission, int argc, char *argv[])
-{
- return showPlaylist(fd);
-}
-
-static int handleShuffle(int fd, int *permission, int argc, char *argv[])
-{
- return shufflePlaylist(fd);
-}
-
-static int handleClear(int fd, int *permission, int argc, char *argv[])
-{
- return clearPlaylist(fd);
-}
-
-static int handleSave(int fd, int *permission, int argc, char *argv[])
-{
- return savePlaylist(fd, argv[1]);
-}
-
-static int handleLoad(int fd, int *permission, int argc, char *argv[])
-{
- return loadPlaylist(fd, argv[1]);
-}
-
-static int handleListPlaylist(int fd, int *permission, int argc, char *argv[])
-{
- return PlaylistInfo(fd, argv[1], 0);
-}
-
-static int handleListPlaylistInfo(int fd, int *permission,
- int argc, char *argv[])
-{
- return PlaylistInfo(fd, argv[1], 1);
-}
-
-static int handleLsInfo(int fd, int *permission, int argc, char *argv[])
-{
- char *path = "";
-
- if (argc == 2)
- path = argv[1];
-
- if (printDirectoryInfo(fd, path) < 0)
- return -1;
-
- if (isRootDirectory(path))
- return lsPlaylists(fd, path);
-
- return 0;
-}
-
-static int handleRm(int fd, int *permission, int argc, char *argv[])
-{
- return deletePlaylist(fd, argv[1]);
-}
-
-static int handleRename(int fd, int *permission, int argc, char *argv[])
-{
- return renameStoredPlaylist(fd, argv[1], argv[2]);
-}
-
-static int handlePlaylistChanges(int fd, int *permission,
- int argc, char *argv[])
-{
- unsigned long version;
- char *test;
-
- version = strtoul(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG, "need a positive integer");
- return -1;
- }
- return playlistChanges(fd, version);
-}
-
-static int handlePlaylistChangesPosId(int fd, int *permission,
- int argc, char *argv[])
-{
- unsigned long version;
- char *test;
-
- version = strtoul(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG, "need a positive integer");
- return -1;
- }
- return playlistChangesPosId(fd, version);
-}
-
-static int handlePlaylistInfo(int fd, int *permission, int argc, char *argv[])
-{
- int song = -1;
- char *test;
-
- if (argc == 2) {
- song = strtol(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG,
- "need a positive integer");
- return -1;
- }
- }
- return playlistInfo(fd, song);
-}
-
-static int handlePlaylistId(int fd, int *permission, int argc, char *argv[])
-{
- int id = -1;
- char *test;
-
- if (argc == 2) {
- id = strtol(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG,
- "need a positive integer");
- return -1;
- }
- }
- return playlistId(fd, id);
-}
-
-static int handleFind(int fd, int *permission, int argc, char *argv[])
-{
- int ret;
-
- LocateTagItem *items;
- int numItems = newLocateTagItemArrayFromArgArray(argv + 1,
- argc - 1,
- &items);
-
- if (numItems <= 0) {
- commandError(fd, ACK_ERROR_ARG, "incorrect arguments");
- return -1;
- }
-
- ret = findSongsIn(fd, NULL, numItems, items);
-
- freeLocateTagItemArray(numItems, items);
-
- return ret;
-}
-
-static int handleSearch(int fd, int *permission, int argc, char *argv[])
-{
- int ret;
-
- LocateTagItem *items;
- int numItems = newLocateTagItemArrayFromArgArray(argv + 1,
- argc - 1,
- &items);
-
- if (numItems <= 0) {
- commandError(fd, ACK_ERROR_ARG, "incorrect arguments");
- return -1;
- }
-
- ret = searchForSongsIn(fd, NULL, numItems, items);
-
- freeLocateTagItemArray(numItems, items);
-
- return ret;
-}
-
-static int handleCount(int fd, int *permission, int argc, char *argv[])
-{
- int ret;
-
- LocateTagItem *items;
- int numItems = newLocateTagItemArrayFromArgArray(argv + 1,
- argc - 1,
- &items);
-
- if (numItems <= 0) {
- commandError(fd, ACK_ERROR_ARG, "incorrect arguments");
- return -1;
- }
-
- ret = searchStatsForSongsIn(fd, NULL, numItems, items);
-
- freeLocateTagItemArray(numItems, items);
-
- return ret;
-}
-
-static int handlePlaylistFind(int fd, int *permission, int argc, char *argv[])
-{
- LocateTagItem *items;
- int numItems = newLocateTagItemArrayFromArgArray(argv + 1,
- argc - 1,
- &items);
-
- if (numItems <= 0) {
- commandError(fd, ACK_ERROR_ARG, "incorrect arguments");
- return -1;
- }
-
- findSongsInPlaylist(fd, numItems, items);
-
- freeLocateTagItemArray(numItems, items);
-
- return 0;
-}
-
-static int handlePlaylistSearch(int fd, int *permission, int argc, char *argv[])
-{
- LocateTagItem *items;
- int numItems = newLocateTagItemArrayFromArgArray(argv + 1,
- argc - 1,
- &items);
-
- if (numItems <= 0) {
- commandError(fd, ACK_ERROR_ARG, "incorrect arguments");
- return -1;
- }
-
- searchForSongsInPlaylist(fd, numItems, items);
-
- freeLocateTagItemArray(numItems, items);
-
- return 0;
-}
-
-static int handlePlaylistDelete(int fd, int *permission, int argc, char *argv[]) {
- char *playlist = argv[1];
- int from;
- char *test;
-
- from = strtol(argv[2], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG,
- "\"%s\" is not a integer", argv[2]);
- return -1;
- }
-
- return removeOneSongFromStoredPlaylistByPath(fd, playlist, from);
-}
-
-static int handlePlaylistMove(int fd, int *permission, int argc, char *argv[])
-{
- char *playlist = argv[1];
- int from, to;
- char *test;
-
- from = strtol(argv[2], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG,
- "\"%s\" is not a integer", argv[2]);
- return -1;
- }
- to = strtol(argv[3], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG,
- "\"%s\" is not a integer", argv[3]);
- return -1;
- }
-
- return moveSongInStoredPlaylistByPath(fd, playlist, from, to);
-}
-
-static int listHandleUpdate(int fd,
- int *permission,
- int argc,
- char *argv[],
- struct strnode *cmdnode, CommandEntry * cmd)
-{
- static List *pathList;
- CommandEntry *nextCmd = NULL;
- struct strnode *next = cmdnode->next;
-
- if (!pathList)
- pathList = makeList(NULL, 1);
-
- if (argc == 2)
- insertInList(pathList, argv[1], NULL);
- else
- insertInList(pathList, "", NULL);
-
- if (next)
- nextCmd = getCommandEntryFromString(next->data, permission);
-
- if (cmd != nextCmd) {
- int ret = updateInit(fd, pathList);
- freeList(pathList);
- pathList = NULL;
- return ret;
- }
-
- return 0;
-}
-
-static int handleUpdate(int fd, int *permission, int argc, char *argv[])
-{
- if (argc == 2) {
- int ret;
- List *pathList = makeList(NULL, 1);
- insertInList(pathList, argv[1], NULL);
- ret = updateInit(fd, pathList);
- freeList(pathList);
- return ret;
- }
- return updateInit(fd, NULL);
-}
-
-static int handleNext(int fd, int *permission, int argc, char *argv[])
-{
- return nextSongInPlaylist(fd);
-}
-
-static int handlePrevious(int fd, int *permission, int argc, char *argv[])
-{
- return previousSongInPlaylist(fd);
-}
-
-static int handleListAll(int fd, int *permission, int argc, char *argv[])
-{
- char *directory = NULL;
-
- if (argc == 2)
- directory = argv[1];
- return printAllIn(fd, directory);
-}
-
-static int handleVolume(int fd, int *permission, int argc, char *argv[])
-{
- int change;
- char *test;
-
- change = strtol(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG, "need an integer");
- return -1;
- }
- return changeVolumeLevel(fd, change, 1);
-}
-
-static int handleSetVol(int fd, int *permission, int argc, char *argv[])
-{
- int level;
- char *test;
-
- level = strtol(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG, "need an integer");
- return -1;
- }
- return changeVolumeLevel(fd, level, 0);
-}
-
-static int handleRepeat(int fd, int *permission, int argc, char *argv[])
-{
- int status;
- char *test;
-
- status = strtol(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG, "need an integer");
- return -1;
- }
- return setPlaylistRepeatStatus(fd, status);
-}
-
-static int handleRandom(int fd, int *permission, int argc, char *argv[])
-{
- int status;
- char *test;
-
- status = strtol(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG, "need an integer");
- return -1;
- }
- return setPlaylistRandomStatus(fd, status);
-}
-
-static int handleStats(int fd, int *permission, int argc, char *argv[])
-{
- return printStats(fd);
-}
-
-static int handleClearError(int fd, int *permission, int argc, char *argv[])
-{
- clearPlayerError();
- return 0;
-}
-
-static int handleList(int fd, int *permission, int argc, char *argv[])
-{
- int numConditionals = 0;
- LocateTagItem *conditionals = NULL;
- int tagType = getLocateTagItemType(argv[1]);
- int ret;
-
- if (tagType < 0) {
- commandError(fd, ACK_ERROR_ARG, "\"%s\" is not known", argv[1]);
- return -1;
- }
-
- if (tagType == LOCATE_TAG_ANY_TYPE) {
- commandError(fd, ACK_ERROR_ARG,
- "\"any\" is not a valid return tag type");
- return -1;
- }
-
- /* for compatibility with < 0.12.0 */
- if (argc == 3) {
- if (tagType != TAG_ITEM_ALBUM) {
- commandError(fd, ACK_ERROR_ARG,
- "should be \"%s\" for 3 arguments",
- mpdTagItemKeys[TAG_ITEM_ALBUM]);
- return -1;
- }
- conditionals = newLocateTagItem(mpdTagItemKeys[TAG_ITEM_ARTIST],
- argv[2]);
- numConditionals = 1;
- } else {
- numConditionals =
- newLocateTagItemArrayFromArgArray(argv + 2,
- argc - 2, &conditionals);
-
- if (numConditionals < 0) {
- commandError(fd, ACK_ERROR_ARG,
- "not able to parse args");
- return -1;
- }
- }
-
- ret = listAllUniqueTags(fd, tagType, numConditionals, conditionals);
-
- if (conditionals)
- freeLocateTagItemArray(numConditionals, conditionals);
-
- return ret;
-}
-
-static int handleMove(int fd, int *permission, int argc, char *argv[])
-{
- int from;
- int to;
- char *test;
-
- from = strtol(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG,
- "\"%s\" is not a integer", argv[1]);
- return -1;
- }
- to = strtol(argv[2], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG,
- "\"%s\" is not a integer", argv[2]);
- return -1;
- }
- return moveSongInPlaylist(fd, from, to);
-}
-
-static int handleMoveId(int fd, int *permission, int argc, char *argv[])
-{
- int id;
- int to;
- char *test;
-
- id = strtol(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG,
- "\"%s\" is not a integer", argv[1]);
- return -1;
- }
- to = strtol(argv[2], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG,
- "\"%s\" is not a integer", argv[2]);
- return -1;
- }
- return moveSongInPlaylistById(fd, id, to);
-}
-
-static int handleSwap(int fd, int *permission, int argc, char *argv[])
-{
- int song1;
- int song2;
- char *test;
-
- song1 = strtol(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG,
- "\"%s\" is not a integer", argv[1]);
- return -1;
- }
- song2 = strtol(argv[2], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG, "\"%s\" is not a integer",
- argv[2]);
- return -1;
- }
- return swapSongsInPlaylist(fd, song1, song2);
-}
-
-static int handleSwapId(int fd, int *permission, int argc, char *argv[])
-{
- int id1;
- int id2;
- char *test;
-
- id1 = strtol(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG,
- "\"%s\" is not a integer", argv[1]);
- return -1;
- }
- id2 = strtol(argv[2], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG, "\"%s\" is not a integer",
- argv[2]);
- return -1;
- }
- return swapSongsInPlaylistById(fd, id1, id2);
-}
-
-static int handleSeek(int fd, int *permission, int argc, char *argv[])
-{
- int song;
- int time;
- char *test;
-
- song = strtol(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG,
- "\"%s\" is not a integer", argv[1]);
- return -1;
- }
- time = strtol(argv[2], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG,
- "\"%s\" is not a integer", argv[2]);
- return -1;
- }
- return seekSongInPlaylist(fd, song, time);
-}
-
-static int handleSeekId(int fd, int *permission, int argc, char *argv[])
-{
- int id;
- int time;
- char *test;
-
- id = strtol(argv[1], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG,
- "\"%s\" is not a integer", argv[1]);
- return -1;
- }
- time = strtol(argv[2], &test, 10);
- if (*test != '\0') {
- commandError(fd, ACK_ERROR_ARG,
- "\"%s\" is not a integer", argv[2]);
- return -1;
- }
- return seekSongInPlaylistById(fd, id, time);
-}
-
-static int handleListAllInfo(int fd, int *permission, int argc, char *argv[])
-{
- char *directory = NULL;
-
- if (argc == 2)
- directory = argv[1];
- return printInfoForAllIn(fd, directory);
-}
-
-static int handlePing(int fd, int *permission, int argc, char *argv[])
-{
- return 0;
-}
-
-static int handlePassword(int fd, int *permission, int argc, char *argv[])
-{
- if (getPermissionFromPassword(argv[1], permission) < 0) {
- commandError(fd, ACK_ERROR_PASSWORD, "incorrect password");
- return -1;
- }
-
- return 0;
-}
-
-static int handleCrossfade(int fd, int *permission, int argc, char *argv[])
-{
- int time;
- char *test;
-
- time = strtol(argv[1], &test, 10);
- if (*test != '\0' || time < 0) {
- commandError(fd, ACK_ERROR_ARG,
- "\"%s\" is not a integer >= 0", argv[1]);
- return -1;
- }
-
- setPlayerCrossFade(time);
-
- return 0;
-}
-
-static int handleEnableDevice(int fd, int *permission, int argc, char *argv[])
-{
- int device;
- char *test;
-
- device = strtol(argv[1], &test, 10);
- if (*test != '\0' || device < 0) {
- commandError(fd, ACK_ERROR_ARG,
- "\"%s\" is not a integer >= 0", argv[1]);
- return -1;
- }
-
- return enableAudioDevice(fd, device);
-}
-
-static int handleDisableDevice(int fd, int *permission, int argc, char *argv[])
-{
- int device;
- char *test;
-
- device = strtol(argv[1], &test, 10);
- if (*test != '\0' || device < 0) {
- commandError(fd, ACK_ERROR_ARG,
- "\"%s\" is not a integer >= 0", argv[1]);
- return -1;
- }
-
- return disableAudioDevice(fd, device);
-}
-
-static int handleDevices(int fd, int *permission, int argc, char *argv[])
-{
- printAudioDevices(fd);
-
- return 0;
-}
-
-/* don't be fooled, this is the command handler for "commands" command */
-static int handleCommands(int fd, int *permission, int argc, char *argv[])
-{
- ListNode *node = commandList->firstNode;
- CommandEntry *cmd;
-
- while (node != NULL) {
- cmd = (CommandEntry *) node->data;
- if (cmd->reqPermission == (*permission & cmd->reqPermission)) {
- fdprintf(fd, "command: %s\n", cmd->cmd);
- }
-
- node = node->nextNode;
- }
-
- return 0;
-}
-
-static int handleNotcommands(int fd, int *permission, int argc, char *argv[])
-{
- ListNode *node = commandList->firstNode;
- CommandEntry *cmd;
-
- while (node != NULL) {
- cmd = (CommandEntry *) node->data;
-
- if (cmd->reqPermission != (*permission & cmd->reqPermission)) {
- fdprintf(fd, "command: %s\n", cmd->cmd);
- }
-
- node = node->nextNode;
- }
-
- return 0;
-}
-
-static int handlePlaylistClear(int fd, int *permission, int argc, char *argv[])
-{
- return clearStoredPlaylist(fd, argv[1]);
-}
-
-static int handlePlaylistAdd(int fd, int *permission, int argc, char *argv[])
-{
- char *playlist = argv[1];
- char *path = argv[2];
-
- if (isRemoteUrl(path))
- return addToStoredPlaylist(fd, path, playlist);
-
- return addAllInToStoredPlaylist(fd, path, playlist);
-}
-
-void initCommands(void)
-{
- commandList = makeList(free, 1);
-
- /* addCommand(name, permission, min, max, handler, list handler); */
- addCommand(COMMAND_PLAY, PERMISSION_CONTROL, 0, 1, handlePlay, NULL);
- addCommand(COMMAND_PLAYID, PERMISSION_CONTROL, 0, 1, handlePlayId, NULL);
- addCommand(COMMAND_STOP, PERMISSION_CONTROL, 0, 0, handleStop, NULL);
- addCommand(COMMAND_CURRENTSONG, PERMISSION_READ, 0, 0, handleCurrentSong, NULL);
- addCommand(COMMAND_PAUSE, PERMISSION_CONTROL, 0, 1, handlePause, NULL);
- addCommand(COMMAND_STATUS, PERMISSION_READ, 0, 0, commandStatus, NULL);
- addCommand(COMMAND_KILL, PERMISSION_ADMIN, -1, -1, handleKill, NULL);
- addCommand(COMMAND_CLOSE, PERMISSION_NONE, -1, -1, handleClose, NULL);
- addCommand(COMMAND_ADD, PERMISSION_ADD, 1, 1, handleAdd, NULL);
- addCommand(COMMAND_ADDID, PERMISSION_ADD, 1, 1, handleAddId, NULL);
- addCommand(COMMAND_DELETE, PERMISSION_CONTROL, 1, 1, handleDelete, NULL);
- addCommand(COMMAND_DELETEID, PERMISSION_CONTROL, 1, 1, handleDeleteId, NULL);
- addCommand(COMMAND_PLAYLIST, PERMISSION_READ, 0, 0, handlePlaylist, NULL);
- addCommand(COMMAND_PLAYLISTID, PERMISSION_READ, 0, 1, handlePlaylistId, NULL);
- addCommand(COMMAND_SHUFFLE, PERMISSION_CONTROL, 0, 0, handleShuffle, NULL);
- addCommand(COMMAND_CLEAR, PERMISSION_CONTROL, 0, 0, handleClear, NULL);
- addCommand(COMMAND_SAVE, PERMISSION_CONTROL, 1, 1, handleSave, NULL);
- addCommand(COMMAND_LOAD, PERMISSION_ADD, 1, 1, handleLoad, NULL);
- addCommand(COMMAND_LISTPLAYLIST, PERMISSION_READ, 1, 1, handleListPlaylist, NULL);
- addCommand(COMMAND_LISTPLAYLISTINFO, PERMISSION_READ, 1, 1, handleListPlaylistInfo, NULL);
- addCommand(COMMAND_LSINFO, PERMISSION_READ, 0, 1, handleLsInfo, NULL);
- addCommand(COMMAND_RM, PERMISSION_CONTROL, 1, 1, handleRm, NULL);
- addCommand(COMMAND_PLAYLISTINFO, PERMISSION_READ, 0, 1, handlePlaylistInfo, NULL);
- addCommand(COMMAND_FIND, PERMISSION_READ, 2, -1, handleFind, NULL);
- addCommand(COMMAND_SEARCH, PERMISSION_READ, 2, -1, handleSearch, NULL);
- addCommand(COMMAND_UPDATE, PERMISSION_ADMIN, 0, 1, handleUpdate, listHandleUpdate);
- addCommand(COMMAND_NEXT, PERMISSION_CONTROL, 0, 0, handleNext, NULL);
- addCommand(COMMAND_PREVIOUS, PERMISSION_CONTROL, 0, 0, handlePrevious, NULL);
- addCommand(COMMAND_LISTALL, PERMISSION_READ, 0, 1, handleListAll, NULL);
- addCommand(COMMAND_VOLUME, PERMISSION_CONTROL, 1, 1, handleVolume, NULL);
- addCommand(COMMAND_REPEAT, PERMISSION_CONTROL, 1, 1, handleRepeat, NULL);
- addCommand(COMMAND_RANDOM, PERMISSION_CONTROL, 1, 1, handleRandom, NULL);
- addCommand(COMMAND_STATS, PERMISSION_READ, 0, 0, handleStats, NULL);
- addCommand(COMMAND_CLEAR_ERROR, PERMISSION_CONTROL, 0, 0, handleClearError, NULL);
- addCommand(COMMAND_LIST, PERMISSION_READ, 1, -1, handleList, NULL);
- addCommand(COMMAND_MOVE, PERMISSION_CONTROL, 2, 2, handleMove, NULL);
- addCommand(COMMAND_MOVEID, PERMISSION_CONTROL, 2, 2, handleMoveId, NULL);
- addCommand(COMMAND_SWAP, PERMISSION_CONTROL, 2, 2, handleSwap, NULL);
- addCommand(COMMAND_SWAPID, PERMISSION_CONTROL, 2, 2, handleSwapId, NULL);
- addCommand(COMMAND_SEEK, PERMISSION_CONTROL, 2, 2, handleSeek, NULL);
- addCommand(COMMAND_SEEKID, PERMISSION_CONTROL, 2, 2, handleSeekId, NULL);
- addCommand(COMMAND_LISTALLINFO, PERMISSION_READ, 0, 1, handleListAllInfo, NULL);
- addCommand(COMMAND_PING, PERMISSION_NONE, 0, 0, handlePing, NULL);
- addCommand(COMMAND_SETVOL, PERMISSION_CONTROL, 1, 1, handleSetVol, NULL);
- addCommand(COMMAND_PASSWORD, PERMISSION_NONE, 1, 1, handlePassword, NULL);
- addCommand(COMMAND_CROSSFADE, PERMISSION_CONTROL, 1, 1, handleCrossfade, NULL);
- addCommand(COMMAND_URL_HANDLERS, PERMISSION_READ, 0, 0, handleUrlHandlers, NULL);
- addCommand(COMMAND_PLCHANGES, PERMISSION_READ, 1, 1, handlePlaylistChanges, NULL);
- addCommand(COMMAND_PLCHANGESPOSID, PERMISSION_READ, 1, 1, handlePlaylistChangesPosId, NULL);
- addCommand(COMMAND_ENABLE_DEV, PERMISSION_ADMIN, 1, 1, handleEnableDevice, NULL);
- addCommand(COMMAND_DISABLE_DEV, PERMISSION_ADMIN, 1, 1, handleDisableDevice, NULL);
- addCommand(COMMAND_DEVICES, PERMISSION_READ, 0, 0, handleDevices, NULL);
- addCommand(COMMAND_COMMANDS, PERMISSION_NONE, 0, 0, handleCommands, NULL);
- addCommand(COMMAND_NOTCOMMANDS, PERMISSION_NONE, 0, 0, handleNotcommands, NULL);
- addCommand(COMMAND_PLAYLISTCLEAR, PERMISSION_CONTROL, 1, 1, handlePlaylistClear, NULL);
- addCommand(COMMAND_PLAYLISTADD, PERMISSION_CONTROL, 2, 2, handlePlaylistAdd, NULL);
- addCommand(COMMAND_PLAYLISTFIND, PERMISSION_READ, 2, -1, handlePlaylistFind, NULL);
- addCommand(COMMAND_PLAYLISTSEARCH, PERMISSION_READ, 2, -1, handlePlaylistSearch, NULL);
- addCommand(COMMAND_PLAYLISTMOVE, PERMISSION_CONTROL, 3, 3, handlePlaylistMove, NULL);
- addCommand(COMMAND_PLAYLISTDELETE, PERMISSION_CONTROL, 2, 2, handlePlaylistDelete, NULL);
- addCommand(COMMAND_TAGTYPES, PERMISSION_READ, 0, 0, handleTagTypes, NULL);
- addCommand(COMMAND_COUNT, PERMISSION_READ, 2, -1, handleCount, NULL);
- addCommand(COMMAND_RENAME, PERMISSION_CONTROL, 2, 2, handleRename, NULL);
-
- sortList(commandList);
-}
-
-void finishCommands(void)
-{
- freeList(commandList);
-}
-
-static int checkArgcAndPermission(CommandEntry * cmd, int fd,
- int permission, int argc, char *argv[])
-{
- int min = cmd->min + 1;
- int max = cmd->max + 1;
-
- if (cmd->reqPermission != (permission & cmd->reqPermission)) {
- if (fd) {
- commandError(fd, ACK_ERROR_PERMISSION,
- "you don't have permission for \"%s\"",
- cmd->cmd);
- }
- return -1;
- }
-
- if (min == 0)
- return 0;
-
- if (min == max && max != argc) {
- if (fd) {
- commandError(fd, ACK_ERROR_ARG,
- "wrong number of arguments for \"%s\"",
- argv[0]);
- }
- return -1;
- } else if (argc < min) {
- if (fd) {
- commandError(fd, ACK_ERROR_ARG,
- "too few arguments for \"%s\"", argv[0]);
- }
- return -1;
- } else if (argc > max && max /* != 0 */ ) {
- if (fd) {
- commandError(fd, ACK_ERROR_ARG,
- "too many arguments for \"%s\"", argv[0]);
- }
- return -1;
- } else
- return 0;
-}
-
-static CommandEntry *getCommandEntryAndCheckArgcAndPermission(int fd,
- int *permission,
- int argc,
- char *argv[])
-{
- static char unknown[] = "";
- CommandEntry *cmd;
-
- current_command = unknown;
-
- if (argc == 0)
- return NULL;
-
- if (!findInList(commandList, argv[0], (void *)&cmd)) {
- if (fd) {
- commandError(fd, ACK_ERROR_UNKNOWN,
- "unknown command \"%s\"", argv[0]);
- }
- return NULL;
- }
-
- current_command = cmd->cmd;
-
- if (checkArgcAndPermission(cmd, fd, *permission, argc, argv) < 0) {
- return NULL;
- }
-
- return cmd;
-}
-
-static CommandEntry *getCommandEntryFromString(char *string, int *permission)
-{
- CommandEntry *cmd = NULL;
- char *argv[COMMAND_ARGV_MAX] = { NULL };
- int argc = buffer2array(string, argv, COMMAND_ARGV_MAX);
-
- if (0 == argc)
- return NULL;
-
- cmd = getCommandEntryAndCheckArgcAndPermission(0, permission,
- argc, argv);
-
- return cmd;
-}
-
-static int processCommandInternal(int fd, int *permission,
- char *commandString, struct strnode *cmdnode)
-{
- int argc;
- char *argv[COMMAND_ARGV_MAX] = { NULL };
- CommandEntry *cmd;
- int ret = -1;
-
- argc = buffer2array(commandString, argv, COMMAND_ARGV_MAX);
-
- if (argc == 0)
- return 0;
-
- if ((cmd = getCommandEntryAndCheckArgcAndPermission(fd, permission,
- argc, argv))) {
- if (!cmdnode || !cmd->listHandler) {
- ret = cmd->handler(fd, permission, argc, argv);
- } else {
- ret = cmd->listHandler(fd, permission, argc, argv,
- cmdnode, cmd);
- }
- }
-
- current_command = NULL;
-
- return ret;
-}
-
-int processListOfCommands(int fd, int *permission, int *expired,
- int listOK, struct strnode *list)
-{
- struct strnode *cur = list;
- int ret = 0;
-
- command_listNum = 0;
-
- while (cur) {
- DEBUG("processListOfCommands: process command \"%s\"\n",
- cur->data);
- ret = processCommandInternal(fd, permission, cur->data, cur);
- DEBUG("processListOfCommands: command returned %i\n", ret);
- if (ret != 0 || (*expired) != 0)
- goto out;
- else if (listOK)
- fdprintf(fd, "list_OK\n");
- command_listNum++;
- cur = cur->next;
- }
-out:
- command_listNum = 0;
- return ret;
-}
-
-int processCommand(int fd, int *permission, char *commandString)
-{
- return processCommandInternal(fd, permission, commandString, NULL);
-}
-
-mpd_fprintf_ void commandError(int fd, int error, const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
-
- if (current_command && fd != STDERR_FILENO) {
- fdprintf(fd, "ACK [%i@%i] {%s} ",
- (int)error, command_listNum, current_command);
- vfdprintf(fd, fmt, args);
- fdprintf(fd, "\n");
- current_command = NULL;
- } else {
- fdprintf(STDERR_FILENO, "ACK [%i@%i] ",
- (int)error, command_listNum);
- vfdprintf(STDERR_FILENO, fmt, args);
- fdprintf(STDERR_FILENO, "\n");
- }
-
- va_end(args);
-}
diff --git a/trunk/src/command.h b/trunk/src/command.h
deleted file mode 100644
index a560b9484..000000000
--- a/trunk/src/command.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef COMMAND_H
-#define COMMAND_H
-
-#include "../config.h"
-
-#include "list.h"
-#include "myfprintf.h"
-#include "log.h"
-#include "ack.h"
-#include "sllist.h"
-
-#include <unistd.h>
-#include <stdio.h>
-
-#define COMMAND_RETURN_KILL 10
-#define COMMAND_RETURN_CLOSE 20
-#define COMMAND_MASTER_READY 30
-
-int processListOfCommands(int fd, int *permission, int *expired,
- int listOK, struct strnode *list);
-
-int processCommand(int fd, int *permission, char *commandString);
-
-void initCommands(void);
-
-void finishCommands(void);
-
-#define commandSuccess(fd) fdprintf(fd, "OK\n")
-
-mpd_fprintf_ void commandError(int fd, int error, const char *fmt, ...);
-
-#endif
diff --git a/trunk/src/compress.c b/trunk/src/compress.c
deleted file mode 100644
index d8db7ab64..000000000
--- a/trunk/src/compress.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * Compressor logic by
- * (c)2003-6 fluffy@beesbuzz.biz
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "compress.h"
-#include "utils.h"
-
-#ifdef USE_X
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-static Display *display;
-static Window window;
-static Visual *visual;
-static int screen;
-static GC blackGC, whiteGC, blueGC, yellowGC, dkyellowGC, redGC;
-#endif
-
-static int *peaks;
-static int gainCurrent, gainTarget;
-
-static struct {
- int show_mon;
- int anticlip;
- int target;
- int gainmax;
- int gainsmooth;
- int buckets;
-} prefs;
-
-#ifdef USE_X
-static int mon_init;
-#endif
-
-void CompressCfg(int show_mon, int anticlip, int target, int gainmax,
- int gainsmooth, int buckets)
-{
- static int lastsize;
-
- prefs.show_mon = show_mon;
- prefs.anticlip = anticlip;
- prefs.target = target;
- prefs.gainmax = gainmax;
- prefs.gainsmooth = gainsmooth;
- prefs.buckets = buckets;
-
- /* Allocate the peak structure */
- peaks = xrealloc(peaks, sizeof(int)*prefs.buckets);
-
- if (prefs.buckets > lastsize)
- memset(peaks + lastsize, 0, sizeof(int)*(prefs.buckets
- - lastsize));
- lastsize = prefs.buckets;
-
-#ifdef USE_X
- /* Configure the monitor window if needed */
- if (show_mon && !mon_init)
- {
- display = XOpenDisplay(getenv("DISPLAY"));
-
- /* We really shouldn't try to init X if there's no X */
- if (!display)
- {
- fprintf(stderr,
- "X not detected; disabling monitor window\n");
- show_mon = prefs.show_mon = 0;
- }
- }
-
- if (show_mon && !mon_init)
- {
- XGCValues gcv;
- XColor col;
-
- gainCurrent = gainTarget = (1 << GAINSHIFT);
-
-
-
- screen = DefaultScreen(display);
- visual = DefaultVisual(display, screen);
- window = XCreateSimpleWindow(display,
- RootWindow(display, screen),
- 0, 0, prefs.buckets, 128 + 8, 0,
- BlackPixel(display, screen),
- WhitePixel(display, screen));
- XStoreName(display, window, "AudioCompress monitor");
-
- gcv.foreground = BlackPixel(display, screen);
- blackGC = XCreateGC(display, window, GCForeground, &gcv);
- gcv.foreground = WhitePixel(display, screen);
- whiteGC = XCreateGC(display, window, GCForeground, &gcv);
- col.red = 0;
- col.green = 0;
- col.blue = 65535;
- XAllocColor(display, DefaultColormap(display, screen), &col);
- gcv.foreground = col.pixel;
- blueGC = XCreateGC(display, window, GCForeground, &gcv);
- col.red = 65535;
- col.green = 65535;
- col.blue = 0;
- XAllocColor(display, DefaultColormap(display, screen), &col);
- gcv.foreground = col.pixel;
- yellowGC = XCreateGC(display, window, GCForeground, &gcv);
- col.red = 32767;
- col.green = 32767;
- col.blue = 0;
- XAllocColor(display, DefaultColormap(display, screen), &col);
- gcv.foreground = col.pixel;
- dkyellowGC = XCreateGC(display, window, GCForeground, &gcv);
- col.red = 65535;
- col.green = 0;
- col.blue = 0;
- XAllocColor(display, DefaultColormap(display, screen), &col);
- gcv.foreground = col.pixel;
- redGC = XCreateGC(display, window, GCForeground, &gcv);
- mon_init = 1;
- }
-
- if (mon_init)
- {
- if (show_mon)
- XMapWindow(display, window);
- else
- XUnmapWindow(display, window);
- XResizeWindow(display, window, prefs.buckets, 128 + 8);
- XFlush(display);
- }
-#endif
-}
-
-void CompressFree(void)
-{
-#ifdef USE_X
- if (mon_init)
- {
- XFreeGC(display, blackGC);
- XFreeGC(display, whiteGC);
- XFreeGC(display, blueGC);
- XFreeGC(display, yellowGC);
- XFreeGC(display, dkyellowGC);
- XFreeGC(display, redGC);
- XDestroyWindow(display, window);
- XCloseDisplay(display);
- }
-#endif
-
- if (peaks)
- free(peaks);
-}
-
-void CompressDo(void *data, unsigned int length)
-{
- int16_t *audio = (int16_t *)data, *ap;
- int peak, pos;
- int i;
- int gr, gf, gn;
- static int pn = -1;
-#ifdef STATS
- static int clip;
-#endif
- static int clipped;
-
- if (!peaks)
- return;
-
- if (pn == -1)
- {
- for (i = 0; i < prefs.buckets; i++)
- peaks[i] = 0;
- }
- pn = (pn + 1)%prefs.buckets;
-
-#ifdef DEBUG
- fprintf(stderr, "modifyNative16(0x%08x, %d)\n",(unsigned int)data,
- length);
-#endif
-
- /* Determine peak's value and position */
- peak = 1;
- pos = 0;
-
-#ifdef DEBUG
- fprintf(stderr, "finding peak(b=%d)\n", pn);
-#endif
-
- ap = audio;
- for (i = 0; i < length/2; i++)
- {
- int val = *ap;
- if (val > peak)
- {
- peak = val;
- pos = i;
- } else if (-val > peak)
- {
- peak = -val;
- pos = i;
- }
- ap++;
- }
- peaks[pn] = peak;
-
- /* Only draw if needed, of course */
-#ifdef USE_X
- if (prefs.show_mon)
- {
- /* current amplitude */
- XDrawLine(display, window, whiteGC,
- pn, 0,
- pn,
- 127 -
- (peaks[pn]*gainCurrent >> (GAINSHIFT + 8)));
-
- /* amplification */
- XDrawLine(display, window, yellowGC,
- pn,
- 127 - (peaks[pn]*gainCurrent
- >> (GAINSHIFT + 8)),
- pn, 127);
-
- /* peak */
- XDrawLine(display, window, blackGC,
- pn, 127 - (peaks[pn] >> 8), pn, 127);
-
- /* clip indicator */
- if (clipped)
- XDrawLine(display, window, redGC,
- (pn + prefs.buckets - 1)%prefs.buckets,
- 126 - clipped/(length*512),
- (pn + prefs.buckets - 1)%prefs.buckets,
- 127);
- clipped = 0;
-
- /* target line */
- /* XDrawPoint(display, window, redGC, */
- /* pn, 127 - TARGET/256); */
- /* amplification edge */
- XDrawLine(display, window, dkyellowGC,
- pn,
- 127 - (peaks[pn]*gainCurrent
- >> (GAINSHIFT + 8)),
- pn - 1,
- 127 -
- (peaks[(pn + prefs.buckets
- - 1)%prefs.buckets]*gainCurrent
- >> (GAINSHIFT + 8)));
- }
-#endif
-
- for (i = 0; i < prefs.buckets; i++)
- {
- if (peaks[i] > peak)
- {
- peak = peaks[i];
- pos = 0;
- }
- }
-
- /* Determine target gain */
- gn = (1 << GAINSHIFT)*prefs.target/peak;
-
- if (gn <(1 << GAINSHIFT))
- gn = 1 << GAINSHIFT;
-
- gainTarget = (gainTarget *((1 << prefs.gainsmooth) - 1) + gn)
- >> prefs.gainsmooth;
-
- /* Give it an extra insignifigant nudge to counteract possible
- ** rounding error
- */
-
- if (gn < gainTarget)
- gainTarget--;
- else if (gn > gainTarget)
- gainTarget++;
-
- if (gainTarget > prefs.gainmax << GAINSHIFT)
- gainTarget = prefs.gainmax << GAINSHIFT;
-
-
-#ifdef USE_X
- if (prefs.show_mon)
- {
- int x;
-
- /* peak*gain */
- XDrawPoint(display, window, redGC,
- pn,
- 127 - (peak*gainCurrent
- >> (GAINSHIFT + 8)));
-
- /* gain indicator */
- XFillRectangle(display, window, whiteGC, 0, 128,
- prefs.buckets, 8);
- x = (gainTarget - (1 << GAINSHIFT))*prefs.buckets
- / ((prefs.gainmax - 1) << GAINSHIFT);
- XDrawLine(display, window, redGC, x,
- 128, x, 128 + 8);
-
- x = (gn - (1 << GAINSHIFT))*prefs.buckets
- / ((prefs.gainmax - 1) << GAINSHIFT);
-
- XDrawLine(display, window, blackGC,
- x, 132 - 1,
- x, 132 + 1);
-
- /* blue peak line */
- XDrawLine(display, window, blueGC,
- 0, 127 - (peak >> 8), prefs.buckets,
- 127 - (peak >> 8));
- XFlush(display);
- XDrawLine(display, window, whiteGC,
- 0, 127 - (peak >> 8), prefs.buckets,
- 127 - (peak >> 8));
- }
-#endif
-
- /* See if a peak is going to clip */
- gn = (1 << GAINSHIFT)*32768/peak;
-
- if (gn < gainTarget)
- {
- gainTarget = gn;
-
- if (prefs.anticlip)
- pos = 0;
-
- } else
- {
- /* We're ramping up, so draw it out over the whole frame */
- pos = length;
- }
-
- /* Determine gain rate necessary to make target */
- if (!pos)
- pos = 1;
-
- gr = ((gainTarget - gainCurrent) << 16)/pos;
-
- /* Do the shiznit */
- gf = gainCurrent << 16;
-
-#ifdef STATS
- fprintf(stderr, "\rgain = %2.2f%+.2e ",
- gainCurrent*1.0/(1 << GAINSHIFT),
- (gainTarget - gainCurrent)*1.0/(1 << GAINSHIFT));
-#endif
-
- ap = audio;
- for (i = 0; i < length/2; i++)
- {
- int sample;
-
- /* Interpolate the gain */
- gainCurrent = gf >> 16;
- if (i < pos)
- gf += gr;
- else if (i == pos)
- gf = gainTarget << 16;
-
- /* Amplify */
- sample = (*ap)*gainCurrent >> GAINSHIFT;
- if (sample < -32768)
- {
-#ifdef STATS
- clip++;
-#endif
- clipped += -32768 - sample;
- sample = -32768;
- } else if (sample > 32767)
- {
-#ifdef STATS
- clip++;
-#endif
- clipped += sample - 32767;
- sample = 32767;
- }
- *ap++ = sample;
- }
-#ifdef STATS
- fprintf(stderr, "clip %d b%-3d ", clip, pn);
-#endif
-
-#ifdef DEBUG
- fprintf(stderr, "\ndone\n");
-#endif
-}
-
diff --git a/trunk/src/compress.h b/trunk/src/compress.h
deleted file mode 100644
index 42638f788..000000000
--- a/trunk/src/compress.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * interface to audio compression
- * (c)2003-6 fluffy@beesbuzz.biz
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef COMPRESS_H
-#define COMPRESS_H
-
-/* These are copied from the AudioCompress config.h, mainly because CompressDo
- * needs GAINSHIFT defined. The rest are here so they can be used as defaults
- * to pass to CompressCfg(). -- jat */
-#define ANTICLIP 0 /* Strict clipping protection */
-#define TARGET 25000 /* Target level */
-#define GAINMAX 32 /* The maximum amount to amplify by */
-#define GAINSHIFT 10 /* How fine-grained the gain is */
-#define GAINSMOOTH 8 /* How much inertia ramping has*/
-#define BUCKETS 400 /* How long of a history to store */
-
-void CompressCfg(int monitor,
- int anticlip,
- int target,
- int maxgain,
- int smooth,
- int buckets);
-
-void CompressDo(void *data, unsigned int numSamples);
-
-void CompressFree(void);
-
-#endif
diff --git a/trunk/src/conf.c b/trunk/src/conf.c
deleted file mode 100644
index 8ab59a505..000000000
--- a/trunk/src/conf.c
+++ /dev/null
@@ -1,450 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "conf.h"
-
-#include "log.h"
-
-#include "utils.h"
-#include "buffer2array.h"
-#include "list.h"
-
-#include <sys/param.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include <errno.h>
-
-#define MAX_STRING_SIZE MAXPATHLEN+80
-
-#define CONF_COMMENT '#'
-#define CONF_BLOCK_BEGIN "{"
-#define CONF_BLOCK_END "}"
-
-#define CONF_REPEATABLE_MASK 0x01
-#define CONF_BLOCK_MASK 0x02
-#define CONF_LINE_TOKEN_MAX 3
-
-typedef struct _configEntry {
- unsigned char mask;
- List *configParamList;
-} ConfigEntry;
-
-static List *configEntriesList;
-
-static ConfigParam *newConfigParam(char *value, int line)
-{
- ConfigParam *ret = xmalloc(sizeof(ConfigParam));
-
- if (!value)
- ret->value = NULL;
- else
- ret->value = xstrdup(value);
-
- ret->line = line;
-
- ret->numberOfBlockParams = 0;
- ret->blockParams = NULL;
-
- return ret;
-}
-
-static void freeConfigParam(ConfigParam * param)
-{
- int i;
-
- if (param->value)
- free(param->value);
-
- for (i = 0; i < param->numberOfBlockParams; i++) {
- if (param->blockParams[i].name) {
- free(param->blockParams[i].name);
- }
- if (param->blockParams[i].value) {
- free(param->blockParams[i].value);
- }
- }
-
- if (param->numberOfBlockParams)
- free(param->blockParams);
-
- free(param);
-}
-
-static ConfigEntry *newConfigEntry(int repeatable, int block)
-{
- ConfigEntry *ret = xmalloc(sizeof(ConfigEntry));
-
- ret->mask = 0;
- ret->configParamList =
- makeList((ListFreeDataFunc *) freeConfigParam, 1);
-
- if (repeatable)
- ret->mask |= CONF_REPEATABLE_MASK;
- if (block)
- ret->mask |= CONF_BLOCK_MASK;
-
- return ret;
-}
-
-static void freeConfigEntry(ConfigEntry * entry)
-{
- freeList(entry->configParamList);
- free(entry);
-}
-
-static void registerConfigParam(char *name, int repeatable, int block)
-{
- ConfigEntry *entry;
-
- if (findInList(configEntriesList, name, NULL))
- FATAL("config parameter \"%s\" already registered\n", name);
-
- entry = newConfigEntry(repeatable, block);
-
- insertInList(configEntriesList, name, entry);
-}
-
-void finishConf(void)
-{
- freeList(configEntriesList);
-}
-
-void initConf(void)
-{
- configEntriesList = makeList((ListFreeDataFunc *) freeConfigEntry, 1);
-
- /* registerConfigParam(name, repeatable, block); */
- registerConfigParam(CONF_MUSIC_DIR, 0, 0);
- registerConfigParam(CONF_PLAYLIST_DIR, 0, 0);
- registerConfigParam(CONF_DB_FILE, 0, 0);
- registerConfigParam(CONF_LOG_FILE, 0, 0);
- registerConfigParam(CONF_ERROR_FILE, 0, 0);
- registerConfigParam(CONF_PID_FILE, 0, 0);
- registerConfigParam(CONF_STATE_FILE, 0, 0);
- registerConfigParam(CONF_USER, 0, 0);
- registerConfigParam(CONF_BIND_TO_ADDRESS, 1, 0);
- registerConfigParam(CONF_PORT, 0, 0);
- registerConfigParam(CONF_LOG_LEVEL, 0, 0);
- registerConfigParam(CONF_ZEROCONF_NAME, 0, 0);
- registerConfigParam(CONF_PASSWORD, 1, 0);
- registerConfigParam(CONF_DEFAULT_PERMS, 0, 0);
- registerConfigParam(CONF_AUDIO_OUTPUT, 1, 1);
- registerConfigParam(CONF_AUDIO_OUTPUT_FORMAT, 0, 0);
- registerConfigParam(CONF_MIXER_TYPE, 0, 0);
- registerConfigParam(CONF_MIXER_DEVICE, 0, 0);
- registerConfigParam(CONF_MIXER_CONTROL, 0, 0);
- registerConfigParam(CONF_REPLAYGAIN, 0, 0);
- registerConfigParam(CONF_REPLAYGAIN_PREAMP, 0, 0);
- registerConfigParam(CONF_VOLUME_NORMALIZATION, 0, 0);
- registerConfigParam(CONF_SAMPLERATE_CONVERTER, 0, 0);
- registerConfigParam(CONF_AUDIO_BUFFER_SIZE, 0, 0);
- registerConfigParam(CONF_BUFFER_BEFORE_PLAY, 0, 0);
- registerConfigParam(CONF_HTTP_BUFFER_SIZE, 0, 0);
- registerConfigParam(CONF_HTTP_PREBUFFER_SIZE, 0, 0);
- registerConfigParam(CONF_HTTP_PROXY_HOST, 0, 0);
- registerConfigParam(CONF_HTTP_PROXY_PORT, 0, 0);
- registerConfigParam(CONF_HTTP_PROXY_USER, 0, 0);
- registerConfigParam(CONF_HTTP_PROXY_PASSWORD, 0, 0);
- registerConfigParam(CONF_CONN_TIMEOUT, 0, 0);
- registerConfigParam(CONF_MAX_CONN, 0, 0);
- registerConfigParam(CONF_MAX_PLAYLIST_LENGTH, 0, 0);
- registerConfigParam(CONF_MAX_COMMAND_LIST_SIZE, 0, 0);
- registerConfigParam(CONF_MAX_OUTPUT_BUFFER_SIZE, 0, 0);
- registerConfigParam(CONF_FS_CHARSET, 0, 0);
- registerConfigParam(CONF_ID3V1_ENCODING, 0, 0);
- registerConfigParam(CONF_METADATA_TO_USE, 0, 0);
- registerConfigParam(CONF_SAVE_ABSOLUTE_PATHS, 0, 0);
- registerConfigParam(CONF_GAPLESS_MP3_PLAYBACK, 0, 0);
-}
-
-static void addBlockParam(ConfigParam * param, char *name, char *value,
- int line)
-{
- param->numberOfBlockParams++;
-
- param->blockParams = xrealloc(param->blockParams,
- param->numberOfBlockParams *
- sizeof(BlockParam));
-
- param->blockParams[param->numberOfBlockParams - 1].name = xstrdup(name);
- param->blockParams[param->numberOfBlockParams - 1].value =
- xstrdup(value);
- param->blockParams[param->numberOfBlockParams - 1].line = line;
-}
-
-static ConfigParam *readConfigBlock(FILE * fp, int *count, char *string)
-{
- ConfigParam *ret = newConfigParam(NULL, *count);
-
- int i;
- int numberOfArgs;
- int argsMinusComment;
-
- while (myFgets(string, MAX_STRING_SIZE, fp)) {
- char *array[CONF_LINE_TOKEN_MAX] = { NULL };
-
- (*count)++;
-
- numberOfArgs = buffer2array(string, array, CONF_LINE_TOKEN_MAX);
-
- for (i = 0; i < numberOfArgs; i++) {
- if (array[i][0] == CONF_COMMENT)
- break;
- }
-
- argsMinusComment = i;
-
- if (0 == argsMinusComment) {
- continue;
- }
-
- if (1 == argsMinusComment &&
- 0 == strcmp(array[0], CONF_BLOCK_END)) {
- break;
- }
-
- if (2 != argsMinusComment) {
- FATAL("improperly formatted config file at line %i:"
- " %s\n", *count, string);
- }
-
- if (0 == strcmp(array[0], CONF_BLOCK_BEGIN) ||
- 0 == strcmp(array[1], CONF_BLOCK_BEGIN) ||
- 0 == strcmp(array[0], CONF_BLOCK_END) ||
- 0 == strcmp(array[1], CONF_BLOCK_END)) {
- FATAL("improperly formatted config file at line %i: %s\n"
- "in block beginning at line %i\n",
- *count, string, ret->line);;
- }
-
- addBlockParam(ret, array[0], array[1], *count);
- }
-
- return ret;
-}
-
-void readConf(char *file)
-{
- FILE *fp;
- char string[MAX_STRING_SIZE + 1];
- int i;
- int numberOfArgs;
- int argsMinusComment;
- int count = 0;
- ConfigEntry *entry;
- void *voidPtr;
- ConfigParam *param;
-
- if (!(fp = fopen(file, "r"))) {
- FATAL("problems opening file %s for reading: %s\n", file,
- strerror(errno));
- }
-
- while (myFgets(string, MAX_STRING_SIZE, fp)) {
- char *array[CONF_LINE_TOKEN_MAX] = { NULL };
- count++;
-
- numberOfArgs = buffer2array(string, array, CONF_LINE_TOKEN_MAX);
-
- for (i = 0; i < numberOfArgs; i++) {
- if (array[i][0] == CONF_COMMENT)
- break;
- }
-
- argsMinusComment = i;
-
- if (0 == argsMinusComment) {
- continue;
- }
-
- if (2 != argsMinusComment) {
- FATAL("improperly formatted config file at line %i:"
- " %s\n", count, string);
- }
-
- if (!findInList(configEntriesList, array[0], &voidPtr)) {
- FATAL("unrecognized parameter in config file at line "
- "%i: %s\n", count, string);
- }
-
- entry = (ConfigEntry *) voidPtr;
-
- if (!(entry->mask & CONF_REPEATABLE_MASK) &&
- entry->configParamList->numberOfNodes) {
- param = entry->configParamList->firstNode->data;
- FATAL("config parameter \"%s\" is first defined on line "
- "%i and redefined on line %i\n", array[0],
- param->line, count);
- }
-
- if (entry->mask & CONF_BLOCK_MASK) {
- if (0 != strcmp(array[1], CONF_BLOCK_BEGIN)) {
- FATAL("improperly formatted config file at "
- "line %i: %s\n", count, string);
- }
- param = readConfigBlock(fp, &count, string);
- } else
- param = newConfigParam(array[1], count);
-
- insertInListWithoutKey(entry->configParamList, param);
- }
- fclose(fp);
-}
-
-ConfigParam *getNextConfigParam(char *name, ConfigParam * last)
-{
- void *voidPtr;
- ConfigEntry *entry;
- ListNode *node;
- ConfigParam *param;
-
- if (!findInList(configEntriesList, name, &voidPtr))
- return NULL;
-
- entry = voidPtr;
-
- node = entry->configParamList->firstNode;
-
- if (last) {
- while (node != NULL) {
- param = node->data;
- node = node->nextNode;
- if (param == last)
- break;
- }
- }
-
- if (node == NULL)
- return NULL;
-
- param = node->data;
-
- return param;
-}
-
-char *getConfigParamValue(char *name)
-{
- ConfigParam *param = getConfigParam(name);
-
- if (!param)
- return NULL;
-
- return param->value;
-}
-
-int getBoolConfigParam(char *name)
-{
- ConfigParam *param;
-
- param = getConfigParam(name);
- if (!param) return -1;
-
- if (strcmp("yes", param->value) == 0) return 1;
- else if (strcmp("no", param->value) == 0) return 0;
-
- ERROR("%s is not \"yes\" or \"no\" on line %i\n", name, param->line);
-
- return -2;
-}
-
-BlockParam *getBlockParam(ConfigParam * param, char *name)
-{
- BlockParam *ret = NULL;
- int i;
-
- for (i = 0; i < param->numberOfBlockParams; i++) {
- if (0 == strcmp(name, param->blockParams[i].name)) {
- if (ret) {
- ERROR("\"%s\" first defined on line %i, and "
- "redefined on line %i\n", name,
- ret->line, param->blockParams[i].line);
- }
- ret = param->blockParams + i;
- }
- }
-
- return ret;
-}
-
-ConfigParam *parseConfigFilePath(char *name, int force)
-{
- ConfigParam *param = getConfigParam(name);
- char *path;
-
- if (!param && force)
- FATAL("config parameter \"%s\" not found\n", name);
-
- if (!param)
- return NULL;
-
- path = param->value;
-
- if (path[0] != '/' && path[0] != '~') {
- FATAL("\"%s\" is not an absolute path at line %i\n",
- param->value, param->line);
- }
- /* Parse ~ in path */
- else if (path[0] == '~') {
- struct passwd *pwd = NULL;
- char *newPath;
- int pos = 1;
- if (path[1] == '/' || path[1] == '\0') {
- ConfigParam *userParam = getConfigParam(CONF_USER);
-
- if (userParam) {
- pwd = getpwnam(userParam->value);
- if (!pwd) {
- FATAL("no such user %s at line %i\n",
- userParam->value,
- userParam->line);
- }
- } else {
- uid_t uid = geteuid();
- if ((pwd = getpwuid(uid)) == NULL) {
- FATAL("problems getting passwd entry "
- "for current user\n");
- }
- }
- } else {
- int foundSlash = 0;
- char *ch = path + 1;
- for (; *ch != '\0' && *ch != '/'; ch++) ;
- if (*ch == '/')
- foundSlash = 1;
- *ch = '\0';
- pos += ch - path - 1;
- if ((pwd = getpwnam(path + 1)) == NULL) {
- FATAL("user \"%s\" not found at line %i\n",
- path + 1, param->line);
- }
- if (foundSlash)
- *ch = '/';
- }
- newPath = xmalloc(strlen(pwd->pw_dir) + strlen(path + pos) + 1);
- strcpy(newPath, pwd->pw_dir);
- strcat(newPath, path + pos);
- free(param->value);
- param->value = newPath;
- }
-
- return param;
-}
diff --git a/trunk/src/conf.h b/trunk/src/conf.h
deleted file mode 100644
index 7059eaa90..000000000
--- a/trunk/src/conf.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef CONF_H
-#define CONF_H
-
-#include "../config.h"
-
-#define CONF_MUSIC_DIR "music_directory"
-#define CONF_PLAYLIST_DIR "playlist_directory"
-#define CONF_DB_FILE "db_file"
-#define CONF_LOG_FILE "log_file"
-#define CONF_ERROR_FILE "error_file"
-#define CONF_PID_FILE "pid_file"
-#define CONF_STATE_FILE "state_file"
-#define CONF_USER "user"
-#define CONF_BIND_TO_ADDRESS "bind_to_address"
-#define CONF_PORT "port"
-#define CONF_LOG_LEVEL "log_level"
-#define CONF_ZEROCONF_NAME "zeroconf_name"
-#define CONF_PASSWORD "password"
-#define CONF_DEFAULT_PERMS "default_permissions"
-#define CONF_AUDIO_OUTPUT "audio_output"
-#define CONF_AUDIO_OUTPUT_FORMAT "audio_output_format"
-#define CONF_MIXER_TYPE "mixer_type"
-#define CONF_MIXER_DEVICE "mixer_device"
-#define CONF_MIXER_CONTROL "mixer_control"
-#define CONF_REPLAYGAIN "replaygain"
-#define CONF_REPLAYGAIN_PREAMP "replaygain_preamp"
-#define CONF_VOLUME_NORMALIZATION "volume_normalization"
-#define CONF_SAMPLERATE_CONVERTER "samplerate_converter"
-#define CONF_AUDIO_BUFFER_SIZE "audio_buffer_size"
-#define CONF_BUFFER_BEFORE_PLAY "buffer_before_play"
-#define CONF_HTTP_BUFFER_SIZE "http_buffer_size"
-#define CONF_HTTP_PREBUFFER_SIZE "http_prebuffer_size"
-#define CONF_HTTP_PROXY_HOST "http_proxy_host"
-#define CONF_HTTP_PROXY_PORT "http_proxy_port"
-#define CONF_HTTP_PROXY_USER "http_proxy_user"
-#define CONF_HTTP_PROXY_PASSWORD "http_proxy_password"
-#define CONF_CONN_TIMEOUT "connection_timeout"
-#define CONF_MAX_CONN "max_connections"
-#define CONF_MAX_PLAYLIST_LENGTH "max_playlist_length"
-#define CONF_MAX_COMMAND_LIST_SIZE "max_command_list_size"
-#define CONF_MAX_OUTPUT_BUFFER_SIZE "max_output_buffer_size"
-#define CONF_FS_CHARSET "filesystem_charset"
-#define CONF_ID3V1_ENCODING "id3v1_encoding"
-#define CONF_METADATA_TO_USE "metadata_to_use"
-#define CONF_SAVE_ABSOLUTE_PATHS "save_absolute_paths_in_playlists"
-#define CONF_GAPLESS_MP3_PLAYBACK "gapless_mp3_playback"
-
-typedef struct _BlockParam {
- char *name;
- char *value;
- int line;
-} BlockParam;
-
-typedef struct _ConfigParam {
- char *value;
- unsigned int line;
- BlockParam *blockParams;
- int numberOfBlockParams;
-} ConfigParam;
-
-void initConf(void);
-void finishConf(void);
-
-void readConf(char *file);
-
-/* don't free the returned value
- set _last_ to NULL to get first entry */
-ConfigParam *getNextConfigParam(char *name, ConfigParam * last);
-
-#define getConfigParam(name) getNextConfigParam(name, NULL)
-
-char *getConfigParamValue(char *name);
-
-int getBoolConfigParam(char *name);
-
-BlockParam *getBlockParam(ConfigParam * param, char *name);
-
-ConfigParam *parseConfigFilePath(char *name, int force);
-
-#endif
diff --git a/trunk/src/dbUtils.c b/trunk/src/dbUtils.c
deleted file mode 100644
index f83ae4c21..000000000
--- a/trunk/src/dbUtils.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "dbUtils.h"
-
-#include "directory.h"
-#include "myfprintf.h"
-#include "utils.h"
-#include "playlist.h"
-#include "song.h"
-#include "tag.h"
-#include "tagTracker.h"
-#include "log.h"
-#include "storedPlaylist.h"
-
-typedef struct _ListCommandItem {
- mpd_sint8 tagType;
- int numConditionals;
- LocateTagItem *conditionals;
-} ListCommandItem;
-
-typedef struct _LocateTagItemArray {
- int numItems;
- LocateTagItem *items;
-} LocateTagItemArray;
-
-typedef struct _SearchStats {
- LocateTagItemArray locateArray;
- int numberOfSongs;
- unsigned long playTime;
-} SearchStats;
-
-static int countSongsInDirectory(int fd, Directory * directory, void *data)
-{
- int *count = (int *)data;
-
- *count += directory->songs->numberOfNodes;
-
- return 0;
-}
-
-static int printDirectoryInDirectory(int fd, Directory * directory,
- void *data)
-{
- if (directory->path) {
- fdprintf(fd, "directory: %s\n", getDirectoryPath(directory));
- }
- return 0;
-}
-
-static int printSongInDirectory(int fd, Song * song, void *data)
-{
- printSongUrl(fd, song);
- return 0;
-}
-
-static int searchInDirectory(int fd, Song * song, void *data)
-{
- LocateTagItemArray *array = data;
-
- if (strstrSearchTags(song, array->numItems, array->items))
- printSongInfo(fd, song);
-
- return 0;
-}
-
-int searchForSongsIn(int fd, char *name, int numItems, LocateTagItem * items)
-{
- int ret = -1;
- int i;
-
- char **originalNeedles = xmalloc(numItems * sizeof(char *));
- LocateTagItemArray array;
-
- for (i = 0; i < numItems; i++) {
- originalNeedles[i] = items[i].needle;
- items[i].needle = strDupToUpper(originalNeedles[i]);
- }
-
- array.numItems = numItems;
- array.items = items;
-
- ret = traverseAllIn(fd, name, searchInDirectory, NULL, &array);
-
- for (i = 0; i < numItems; i++) {
- free(items[i].needle);
- items[i].needle = originalNeedles[i];
- }
-
- free(originalNeedles);
-
- return ret;
-}
-
-static int findInDirectory(int fd, Song * song, void *data)
-{
- LocateTagItemArray *array = data;
-
- if (tagItemsFoundAndMatches(song, array->numItems, array->items))
- printSongInfo(fd, song);
-
- return 0;
-}
-
-int findSongsIn(int fd, char *name, int numItems, LocateTagItem * items)
-{
- LocateTagItemArray array;
-
- array.numItems = numItems;
- array.items = items;
-
- return traverseAllIn(fd, name, findInDirectory, NULL, (void *)&array);
-}
-
-static void printSearchStats(int fd, SearchStats *stats)
-{
- fdprintf(fd, "songs: %i\n", stats->numberOfSongs);
- fdprintf(fd, "playtime: %li\n", stats->playTime);
-}
-
-static int searchStatsInDirectory(int fd, Song * song, void *data)
-{
- SearchStats *stats = data;
-
- if (tagItemsFoundAndMatches(song, stats->locateArray.numItems,
- stats->locateArray.items)) {
- stats->numberOfSongs++;
- if (song->tag->time > 0)
- stats->playTime += song->tag->time;
- }
-
- return 0;
-}
-
-int searchStatsForSongsIn(int fd, char *name, int numItems,
- LocateTagItem * items)
-{
- SearchStats stats;
- int ret;
-
- stats.locateArray.numItems = numItems;
- stats.locateArray.items = items;
- stats.numberOfSongs = 0;
- stats.playTime = 0;
-
- ret = traverseAllIn(fd, name, searchStatsInDirectory, NULL, &stats);
- if (ret == 0)
- printSearchStats(fd, &stats);
-
- return ret;
-}
-
-int printAllIn(int fd, char *name)
-{
- return traverseAllIn(fd, name, printSongInDirectory,
- printDirectoryInDirectory, NULL);
-}
-
-static int directoryAddSongToPlaylist(int fd, Song * song, void *data)
-{
- return addSongToPlaylist(fd, song, 0);
-}
-
-static int directoryAddSongToStoredPlaylist(int fd, Song *song, void *data)
-{
- if (appendSongToStoredPlaylistByPath(fd, (char *)data, song) != 0)
- return -1;
- return 0;
-}
-
-int addAllIn(int fd, char *name)
-{
- return traverseAllIn(fd, name, directoryAddSongToPlaylist, NULL, NULL);
-}
-
-int addAllInToStoredPlaylist(int fd, char *name, char *utf8file)
-{
- return traverseAllIn(fd, name, directoryAddSongToStoredPlaylist, NULL,
- (void *)utf8file);
-}
-
-static int directoryPrintSongInfo(int fd, Song * song, void *data)
-{
- return printSongInfo(fd, song);
-}
-
-static int sumSongTime(int fd, Song * song, void *data)
-{
- unsigned long *time = (unsigned long *)data;
-
- if (song->tag && song->tag->time >= 0)
- *time += song->tag->time;
-
- return 0;
-}
-
-int printInfoForAllIn(int fd, char *name)
-{
- return traverseAllIn(fd, name, directoryPrintSongInfo,
- printDirectoryInDirectory, NULL);
-}
-
-int countSongsIn(int fd, char *name)
-{
- int count = 0;
- void *ptr = (void *)&count;
-
- traverseAllIn(fd, name, NULL, countSongsInDirectory, ptr);
-
- return count;
-}
-
-unsigned long sumSongTimesIn(int fd, char *name)
-{
- unsigned long dbPlayTime = 0;
- void *ptr = (void *)&dbPlayTime;
-
- traverseAllIn(fd, name, sumSongTime, NULL, ptr);
-
- return dbPlayTime;
-}
-
-static ListCommandItem *newListCommandItem(int tagType, int numConditionals,
- LocateTagItem * conditionals)
-{
- ListCommandItem *item = xmalloc(sizeof(ListCommandItem));
-
- item->tagType = tagType;
- item->numConditionals = numConditionals;
- item->conditionals = conditionals;
-
- return item;
-}
-
-static void freeListCommandItem(ListCommandItem * item)
-{
- free(item);
-}
-
-static void visitTag(int fd, Song * song, int tagType)
-{
- int i;
- MpdTag *tag = song->tag;
-
- if (tagType == LOCATE_TAG_FILE_TYPE) {
- printSongUrl(fd, song);
- return;
- }
-
- if (!tag)
- return;
-
- for (i = 0; i < tag->numOfItems; i++) {
- if (tag->items[i].type == tagType) {
- visitInTagTracker(tagType, tag->items[i].value);
- }
- }
-}
-
-static int listUniqueTagsInDirectory(int fd, Song * song, void *data)
-{
- ListCommandItem *item = data;
-
- if (tagItemsFoundAndMatches(song, item->numConditionals,
- item->conditionals)) {
- visitTag(fd, song, item->tagType);
- }
-
- return 0;
-}
-
-int listAllUniqueTags(int fd, int type, int numConditionals,
- LocateTagItem * conditionals)
-{
- int ret;
- ListCommandItem *item = newListCommandItem(type, numConditionals,
- conditionals);
-
- if (type >= 0 && type <= TAG_NUM_OF_ITEM_TYPES) {
- resetVisitedFlagsInTagTracker(type);
- }
-
- ret = traverseAllIn(fd, NULL, listUniqueTagsInDirectory, NULL,
- (void *)item);
-
- if (type >= 0 && type <= TAG_NUM_OF_ITEM_TYPES) {
- printVisitedInTagTracker(fd, type);
- }
-
- freeListCommandItem(item);
-
- return ret;
-}
-
-static int sumSavedFilenameMemoryInDirectory(int fd, Directory * dir,
- void *data)
-{
- int *sum = data;
-
- if (!dir->path)
- return 0;
-
- *sum += (strlen(getDirectoryPath(dir)) + 1 - sizeof(Directory *)) *
- dir->songs->numberOfNodes;
-
- return 0;
-}
-
-static int sumSavedFilenameMemoryInSong(int fd, Song * song, void *data)
-{
- int *sum = data;
-
- *sum += strlen(song->url) + 1;
-
- return 0;
-}
-
-void printSavedMemoryFromFilenames(void)
-{
- int sum = 0;
-
- traverseAllIn(STDERR_FILENO, NULL, sumSavedFilenameMemoryInSong,
- sumSavedFilenameMemoryInDirectory, (void *)&sum);
-
- DEBUG("saved memory from filenames: %i\n", sum);
-}
diff --git a/trunk/src/dbUtils.h b/trunk/src/dbUtils.h
deleted file mode 100644
index 0607bc3b5..000000000
--- a/trunk/src/dbUtils.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef DB_UTILS_H
-#define DB_UTILS_H
-
-#include <stdio.h>
-
-#include "locate.h"
-
-int printAllIn(int fd, char *name);
-
-int addAllIn(int fd, char *name);
-
-int addAllInToStoredPlaylist(int fd, char *name, char *utf8file);
-
-int printInfoForAllIn(int fd, char *name);
-
-int searchForSongsIn(int fd, char *name, int numItems,
- LocateTagItem * items);
-
-int findSongsIn(int fd, char *name, int numItems, LocateTagItem * items);
-
-int searchStatsForSongsIn(int fd, char *name, int numItems,
- LocateTagItem * items);
-
-int countSongsIn(int fd, char *name);
-
-unsigned long sumSongTimesIn(int fd, char *name);
-
-int listAllUniqueTags(int fd, int type, int numConditiionals,
- LocateTagItem * conditionals);
-
-void printSavedMemoryFromFilenames(void);
-
-#endif
diff --git a/trunk/src/decode.c b/trunk/src/decode.c
deleted file mode 100644
index 82eba19b9..000000000
--- a/trunk/src/decode.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "decode.h"
-
-#include "player.h"
-#include "playerData.h"
-#include "utils.h"
-#include "pcm_utils.h"
-#include "audio.h"
-#include "path.h"
-#include "log.h"
-#include "sig_handlers.h"
-#include "ls.h"
-#include "utf8.h"
-
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <string.h>
-
-static int decode_pid;
-
-void decodeSigHandler(int sig, siginfo_t * si, void *v)
-{
- if (sig == SIGCHLD) {
- int status;
- if (decode_pid == wait3(&status, WNOHANG, NULL)) {
- if (WIFSIGNALED(status)) {
- if (WTERMSIG(status) != SIGTERM) {
- ERROR("decode process died from "
- "signal: %i\n", WTERMSIG(status));
- }
- }
- decode_pid = 0;
- getPlayerData()->playerControl.decode_pid = 0;
- }
- } else if (sig == SIGTERM) {
- int pid = decode_pid;
- if (pid > 0) {
- DEBUG("player (or child) got SIGTERM\n");
- kill(pid, SIGTERM);
- } else
- DEBUG("decoder (or child) got SIGTERM\n");
- exit(EXIT_SUCCESS);
- }
-}
-
-static void stopDecode(DecoderControl * dc)
-{
- if (decode_pid > 0 && (dc->start || dc->state != DECODE_STATE_STOP)) {
- dc->stop = 1;
- while (decode_pid > 0 && dc->stop)
- my_usleep(10000);
- }
-}
-
-static void quitDecode(PlayerControl * pc, DecoderControl * dc)
-{
- stopDecode(dc);
- pc->state = PLAYER_STATE_STOP;
- dc->seek = 0;
- pc->play = 0;
- pc->stop = 0;
- pc->pause = 0;
- kill(getppid(), SIGUSR1);
-}
-
-static int calculateCrossFadeChunks(PlayerControl * pc, AudioFormat * af)
-{
- long chunks;
-
- if (pc->crossFade <= 0)
- return 0;
-
- chunks = (af->sampleRate * af->bits * af->channels / 8.0 / CHUNK_SIZE);
- chunks = (chunks * pc->crossFade + 0.5);
-
- if (chunks > (buffered_chunks - buffered_before_play)) {
- chunks = buffered_chunks - buffered_before_play;
- }
-
- if (chunks < 0)
- chunks = 0;
-
- return (int)chunks;
-}
-
-#define handleDecodeStart() \
- if(decodeWaitedOn) { \
- if(dc->state!=DECODE_STATE_START && decode_pid > 0 && \
- dc->error==DECODE_ERROR_NOERROR) \
- { \
- decodeWaitedOn = 0; \
- if(openAudioDevice(&(cb->audioFormat))<0) { \
- pathcpy_trunc(pc->erroredUrl, pc->utf8url); \
- pc->error = PLAYER_ERROR_AUDIO; \
- ERROR("problems opening audio device while playing \"%s\"\n", pc->utf8url); \
- quitDecode(pc,dc); \
- return; \
- } \
- pc->totalTime = dc->totalTime; \
- pc->sampleRate = dc->audioFormat.sampleRate; \
- pc->bits = dc->audioFormat.bits; \
- pc->channels = dc->audioFormat.channels; \
- sizeToTime = 8.0/cb->audioFormat.bits/ \
- cb->audioFormat.channels/ \
- cb->audioFormat.sampleRate; \
- } \
- else if(dc->state!=DECODE_STATE_START || decode_pid <= 0) { \
- pathcpy_trunc(pc->erroredUrl, pc->utf8url); \
- pc->error = PLAYER_ERROR_FILE; \
- quitDecode(pc,dc); \
- return; \
- } \
- else { \
- my_usleep(10000); \
- continue; \
- } \
- }
-
-static int waitOnDecode(PlayerControl * pc, DecoderControl * dc,
- OutputBuffer * cb, int *decodeWaitedOn)
-{
- MpdTag *tag = NULL;
- pathcpy_trunc(pc->currentUrl, pc->utf8url);
-
- while (decode_pid > 0 && dc->start)
- my_usleep(10000);
-
- if (dc->start || dc->error != DECODE_ERROR_NOERROR) {
- pathcpy_trunc(pc->erroredUrl, pc->utf8url);
- pc->error = PLAYER_ERROR_FILE;
- quitDecode(pc, dc);
- return -1;
- }
-
- if ((tag = metadataChunkToMpdTagDup(&(pc->fileMetadataChunk)))) {
- sendMetadataToAudioDevice(tag);
- freeMpdTag(tag);
- }
-
- pc->totalTime = pc->fileTime;
- pc->bitRate = 0;
- pc->sampleRate = 0;
- pc->bits = 0;
- pc->channels = 0;
- *decodeWaitedOn = 1;
-
- return 0;
-}
-
-static int decodeSeek(PlayerControl * pc, DecoderControl * dc,
- OutputBuffer * cb, int *decodeWaitedOn, int *next)
-{
- int ret = -1;
-
- if (decode_pid > 0) {
- if (dc->state == DECODE_STATE_STOP || dc->error ||
- strcmp(dc->utf8url, pc->utf8url) != 0) {
- stopDecode(dc);
- *next = -1;
- cb->begin = 0;
- cb->end = 0;
- dc->error = 0;
- dc->start = 1;
- waitOnDecode(pc, dc, cb, decodeWaitedOn);
- }
- if (decode_pid > 0 && dc->state != DECODE_STATE_STOP &&
- dc->seekable) {
- *next = -1;
- dc->seekWhere = pc->seekWhere > pc->totalTime - 0.1 ?
- pc->totalTime - 0.1 : pc->seekWhere;
- dc->seekWhere = 0 > dc->seekWhere ? 0 : dc->seekWhere;
- dc->seekError = 0;
- dc->seek = 1;
- while (decode_pid > 0 && dc->seek)
- my_usleep(10000);
- if (!dc->seekError) {
- pc->elapsedTime = dc->seekWhere;
- ret = 0;
- }
- }
- }
- pc->seek = 0;
-
- return ret;
-}
-
-#define processDecodeInput() \
- if(pc->cycleLogFiles) { \
- cycle_log_files(); \
- pc->cycleLogFiles = 0; \
- } \
- if(pc->lockQueue) { \
- pc->queueLockState = PLAYER_QUEUE_LOCKED; \
- pc->lockQueue = 0; \
- } \
- if(pc->unlockQueue) { \
- pc->queueLockState = PLAYER_QUEUE_UNLOCKED; \
- pc->unlockQueue = 0; \
- } \
- if(pc->pause) { \
- pause = !pause; \
- if (pause) pc->state = PLAYER_STATE_PAUSE; \
- else { \
- if (openAudioDevice(NULL) >= 0) pc->state = PLAYER_STATE_PLAY; \
- else { \
- pathcpy_trunc(pc->erroredUrl, pc->utf8url); \
- pc->error = PLAYER_ERROR_AUDIO; \
- ERROR("problems opening audio device while playing \"%s\"\n", pc->utf8url); \
- pause = -1; \
- } \
- } \
- pc->pause = 0; \
- kill(getppid(), SIGUSR1); \
- if (pause == -1) pause = 1; \
- else if (pause) { \
- dropBufferedAudio(); \
- closeAudioDevice(); \
- } \
- } \
- if(pc->seek) { \
- dropBufferedAudio(); \
- if(decodeSeek(pc,dc,cb,&decodeWaitedOn,&next) == 0) { \
- doCrossFade = 0; \
- nextChunk = -1; \
- bbp = 0; \
- } \
- } \
- if(pc->stop) { \
- dropBufferedAudio(); \
- quitDecode(pc,dc); \
- return; \
- }
-
-static void decodeStart(PlayerControl * pc, OutputBuffer * cb,
- DecoderControl * dc)
-{
- int ret;
- InputStream inStream;
- InputPlugin *plugin = NULL;
- char *path;
-
- if (isRemoteUrl(pc->utf8url))
- path = utf8StrToLatin1Dup(pc->utf8url);
- else
- path = xstrdup(rmp2amp(utf8ToFsCharset(pc->utf8url)));
-
- if (!path) {
- dc->error = DECODE_ERROR_FILE;
- dc->state = DECODE_STATE_STOP;
- dc->start = 0;
- return;
- }
-
- copyMpdTagToOutputBuffer(cb, NULL);
-
- pathcpy_trunc(dc->utf8url, pc->utf8url);
-
- if (openInputStream(&inStream, path) < 0) {
- dc->error = DECODE_ERROR_FILE;
- dc->state = DECODE_STATE_STOP;
- dc->start = 0;
- free(path);
- return;
- }
-
- dc->state = DECODE_STATE_START;
- dc->start = 0;
-
- while (!inputStreamAtEOF(&inStream) && bufferInputStream(&inStream) < 0
- && !dc->stop) {
- /* sleep so we don't consume 100% of the cpu */
- my_usleep(1000);
- }
-
- /* for http streams, seekable is determined in bufferInputStream */
- dc->seekable = inStream.seekable;
-
- if (dc->stop) {
- dc->state = DECODE_STATE_STOP;
- dc->stop = 0;
- free(path);
- return;
- }
-
- /*if(inStream.metaName) {
- MpdTag * tag = newMpdTag();
- tag->name = xstrdup(inStream.metaName);
- copyMpdTagToOutputBuffer(cb, tag);
- freeMpdTag(tag);
- } */
-
- /* reset Metadata in OutputBuffer */
-
- ret = DECODE_ERROR_UNKTYPE;
- if (isRemoteUrl(dc->utf8url)) {
- unsigned int next = 0;
- cb->acceptMetadata = 1;
-
- /* first we try mime types: */
- while (ret
- && (plugin =
- getInputPluginFromMimeType(inStream.mime, next++))) {
- if (!plugin->streamDecodeFunc)
- continue;
- if (!(plugin->streamTypes & INPUT_PLUGIN_STREAM_URL))
- continue;
- if (plugin->tryDecodeFunc
- && !plugin->tryDecodeFunc(&inStream))
- continue;
- ret = plugin->streamDecodeFunc(cb, dc, &inStream);
- break;
- }
-
- /* if that fails, try suffix matching the URL: */
- if (plugin == NULL) {
- char *s = getSuffix(dc->utf8url);
- next = 0;
- while (ret
- && (plugin =
- getInputPluginFromSuffix(s, next++))) {
- if (!plugin->streamDecodeFunc)
- continue;
- if (!(plugin->streamTypes &
- INPUT_PLUGIN_STREAM_URL))
- continue;
- if (plugin->tryDecodeFunc &&
- !plugin->tryDecodeFunc(&inStream))
- continue;
- ret =
- plugin->streamDecodeFunc(cb, dc, &inStream);
- break;
- }
- }
- /* fallback to mp3: */
- /* this is needed for bastard streams that don't have a suffix
- or set the mimeType */
- if (plugin == NULL) {
- /* we already know our mp3Plugin supports streams, no
- * need to check for stream{Types,DecodeFunc} */
- if ((plugin = getInputPluginFromName("mp3")))
- ret = plugin->streamDecodeFunc(cb, dc,
- &inStream);
- }
- } else {
- unsigned int next = 0;
- char *s = getSuffix(dc->utf8url);
- cb->acceptMetadata = 0;
- while (ret && (plugin = getInputPluginFromSuffix(s, next++))) {
- if (!plugin->streamTypes & INPUT_PLUGIN_STREAM_FILE)
- continue;
- if (plugin->tryDecodeFunc
- && !plugin->tryDecodeFunc(&inStream))
- continue;
-
- if (plugin->streamDecodeFunc) {
- ret =
- plugin->streamDecodeFunc(cb, dc, &inStream);
- break;
- } else if (plugin->fileDecodeFunc) {
- closeInputStream(&inStream);
- ret = plugin->fileDecodeFunc(cb, dc, path);
- }
- }
- }
-
- if (ret < 0 || ret == DECODE_ERROR_UNKTYPE) {
- pathcpy_trunc(pc->erroredUrl, dc->utf8url);
- if (ret != DECODE_ERROR_UNKTYPE)
- dc->error = DECODE_ERROR_FILE;
- else {
- dc->error = DECODE_ERROR_UNKTYPE;
- closeInputStream(&inStream);
- }
- dc->stop = 0;
- dc->state = DECODE_STATE_STOP;
- }
-
- free(path);
-}
-
-static int decoderInit(PlayerControl * pc, OutputBuffer * cb,
- DecoderControl * dc)
-{
- blockSignals();
- getPlayerData()->playerControl.decode_pid = 0;
- decode_pid = fork();
-
- if (decode_pid == 0) {
- /* CHILD */
- unblockSignals();
-
- while (1) {
- if (dc->cycleLogFiles) {
- cycle_log_files();
- dc->cycleLogFiles = 0;
- } else if (dc->start || dc->seek)
- decodeStart(pc, cb, dc);
- else if (dc->stop) {
- dc->state = DECODE_STATE_STOP;
- dc->stop = 0;
- } else
- my_usleep(10000);
- }
-
- exit(EXIT_SUCCESS);
- /* END OF CHILD */
- } else if (decode_pid < 0) {
- unblockSignals();
- pathcpy_trunc(pc->erroredUrl, pc->utf8url);
- pc->error = PLAYER_ERROR_SYSTEM;
- return -1;
- }
- DEBUG("decoder PID: %d\n", decode_pid);
- getPlayerData()->playerControl.decode_pid = decode_pid;
- unblockSignals();
-
- return 0;
-}
-
-static void handleMetadata(OutputBuffer * cb, PlayerControl * pc, int *previous,
- int *currentChunkSent, MetadataChunk * currentChunk)
-{
- if (cb->begin != cb->end) {
- int meta = cb->metaChunk[cb->begin];
- if (meta != *previous) {
- DEBUG("player: metadata change\n");
- if (meta >= 0 && cb->metaChunkSet[meta]) {
- DEBUG("player: new metadata from decoder!\n");
- memcpy(currentChunk,
- cb->metadataChunks + meta,
- sizeof(MetadataChunk));
- *currentChunkSent = 0;
- cb->metaChunkSet[meta] = 0;
- }
- }
- *previous = meta;
- }
- if (!(*currentChunkSent) && pc->metadataState ==
- PLAYER_METADATA_STATE_WRITE) {
- MpdTag *tag = NULL;
-
- *currentChunkSent = 1;
-
- if ((tag = metadataChunkToMpdTagDup(currentChunk))) {
- sendMetadataToAudioDevice(tag);
- freeMpdTag(tag);
- }
-
- memcpy(&(pc->metadataChunk), currentChunk,
- sizeof(MetadataChunk));
- pc->metadataState = PLAYER_METADATA_STATE_READ;
- kill(getppid(), SIGUSR1);
- }
-}
-
-static void advanceOutputBufferTo(OutputBuffer * cb, PlayerControl * pc,
- int *previous, int *currentChunkSent,
- MetadataChunk * currentChunk, int to)
-{
- while (cb->begin != to) {
- handleMetadata(cb, pc, previous, currentChunkSent,
- currentChunk);
- if (cb->begin + 1 >= buffered_chunks) {
- cb->begin = 0;
- }
- else cb->begin++;
- }
-}
-
-static void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb)
-{
- int pause = 0;
- int quit = 0;
- int bbp = buffered_before_play;
- int doCrossFade = 0;
- int crossFadeChunks = 0;
- int fadePosition;
- int nextChunk = -1;
- int test;
- int decodeWaitedOn = 0;
- char silence[CHUNK_SIZE];
- double sizeToTime = 0.0;
- int previousMetadataChunk = -1;
- MetadataChunk currentMetadataChunk;
- int currentChunkSent = 1;
- int end;
- int next = -1;
-
- memset(silence, 0, CHUNK_SIZE);
-
- if (waitOnDecode(pc, dc, cb, &decodeWaitedOn) < 0)
- return;
-
- pc->elapsedTime = 0;
- pc->state = PLAYER_STATE_PLAY;
- pc->play = 0;
- kill(getppid(), SIGUSR1);
-
- while (decode_pid > 0 &&
- cb->end - cb->begin < bbp &&
- cb->end != buffered_chunks - 1 &&
- dc->state != DECODE_STATE_STOP) {
- processDecodeInput();
- my_usleep(1000);
- }
-
- while (!quit) {
- processDecodeInput();
- handleDecodeStart();
- handleMetadata(cb, pc, &previousMetadataChunk,
- &currentChunkSent, &currentMetadataChunk);
- if (dc->state == DECODE_STATE_STOP &&
- pc->queueState == PLAYER_QUEUE_FULL &&
- pc->queueLockState == PLAYER_QUEUE_UNLOCKED) {
- next = cb->end;
- dc->start = 1;
- pc->queueState = PLAYER_QUEUE_DECODE;
- kill(getppid(), SIGUSR1);
- }
- if (next >= 0 && doCrossFade == 0 && !dc->start &&
- dc->state != DECODE_STATE_START) {
- nextChunk = -1;
- if (isCurrentAudioFormat(&(cb->audioFormat))) {
- doCrossFade = 1;
- crossFadeChunks =
- calculateCrossFadeChunks(pc,
- &(cb->
- audioFormat));
- if (!crossFadeChunks
- || pc->crossFade >= dc->totalTime) {
- doCrossFade = -1;
- }
- } else
- doCrossFade = -1;
- }
-
- /* copy these to local variables to prevent any potential
- race conditions and weirdness */
- end = cb->end;
-
- if (pause)
- my_usleep(10000);
- else if (cb->begin != end && cb->begin != next) {
- if (doCrossFade == 1 && next >= 0 &&
- ((next > cb->begin &&
- (fadePosition = next - cb->begin)
- <= crossFadeChunks) ||
- (cb->begin > next &&
- (fadePosition = next - cb->begin +
- buffered_chunks) <= crossFadeChunks))) {
- if (nextChunk < 0) {
- crossFadeChunks = fadePosition;
- }
- test = end;
- if (end < cb->begin)
- test += buffered_chunks;
- nextChunk = cb->begin + crossFadeChunks;
- if (nextChunk < test) {
- if (nextChunk >= buffered_chunks) {
- nextChunk -= buffered_chunks;
- }
- pcm_mix(cb->chunks +
- cb->begin * CHUNK_SIZE,
- cb->chunks +
- nextChunk * CHUNK_SIZE,
- cb->chunkSize[cb->begin],
- cb->chunkSize[nextChunk],
- &(cb->audioFormat),
- ((float)fadePosition) /
- crossFadeChunks);
- if (cb->chunkSize[nextChunk] >
- cb->chunkSize[cb->begin]
- ) {
- cb->chunkSize[cb->begin]
- = cb->chunkSize[nextChunk];
- }
- } else {
- if (dc->state == DECODE_STATE_STOP) {
- doCrossFade = -1;
- } else
- continue;
- }
- }
- pc->elapsedTime = cb->times[cb->begin];
- pc->bitRate = cb->bitRate[cb->begin];
- pcm_volumeChange(cb->chunks + cb->begin *
- CHUNK_SIZE,
- cb->chunkSize[cb->begin],
- &(cb->audioFormat),
- pc->softwareVolume);
- if (playAudio(cb->chunks + cb->begin * CHUNK_SIZE,
- cb->chunkSize[cb->begin]) < 0) {
- quit = 1;
- }
- pc->totalPlayTime +=
- sizeToTime * cb->chunkSize[cb->begin];
- if (cb->begin + 1 >= buffered_chunks) {
- cb->begin = 0;
- } else
- cb->begin++;
- } else if (cb->begin != end && cb->begin == next) {
- if (doCrossFade == 1 && nextChunk >= 0) {
- nextChunk = cb->begin + crossFadeChunks;
- test = end;
- if (end < cb->begin)
- test += buffered_chunks;
- if (nextChunk < test) {
- if (nextChunk >= buffered_chunks) {
- nextChunk -= buffered_chunks;
- }
- advanceOutputBufferTo(cb, pc,
- &previousMetadataChunk,
- &currentChunkSent,
- &currentMetadataChunk,
- nextChunk);
- }
- }
- while (pc->queueState == PLAYER_QUEUE_DECODE ||
- pc->queueLockState == PLAYER_QUEUE_LOCKED) {
- processDecodeInput();
- if (quit) {
- quitDecode(pc, dc);
- return;
- }
- my_usleep(10000);
- }
- if (pc->queueState != PLAYER_QUEUE_PLAY) {
- quit = 1;
- break;
- } else {
- next = -1;
- if (waitOnDecode(pc, dc, cb, &decodeWaitedOn) <
- 0) {
- return;
- }
- nextChunk = -1;
- doCrossFade = 0;
- crossFadeChunks = 0;
- pc->queueState = PLAYER_QUEUE_EMPTY;
- kill(getppid(), SIGUSR1);
- }
- } else if (decode_pid <= 0 ||
- (dc->state == DECODE_STATE_STOP && !dc->start)) {
- quit = 1;
- break;
- } else {
- /*DEBUG("waiting for decoded audio, play silence\n");*/
- if (playAudio(silence, CHUNK_SIZE) < 0)
- quit = 1;
- }
- }
-
- quitDecode(pc, dc);
-}
-
-/* decode w/ buffering
- * this will fork another process
- * child process does decoding
- * parent process does playing audio
- */
-void decode(void)
-{
- OutputBuffer *cb;
- PlayerControl *pc;
- DecoderControl *dc;
-
- cb = &(getPlayerData()->buffer);
-
- clearAllMetaChunkSets(cb);
- cb->begin = 0;
- cb->end = 0;
- pc = &(getPlayerData()->playerControl);
- dc = &(getPlayerData()->decoderControl);
- dc->error = 0;
- dc->seek = 0;
- dc->stop = 0;
- dc->start = 1;
-
- if (decode_pid <= 0) {
- if (decoderInit(pc, cb, dc) < 0)
- return;
- }
-
- decodeParent(pc, dc, cb);
-}
diff --git a/trunk/src/decode.h b/trunk/src/decode.h
deleted file mode 100644
index f073c0d55..000000000
--- a/trunk/src/decode.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef DECODE_H
-#define DECODE_H
-
-#include "../config.h"
-#include "tag.h"
-
-#include "mpd_types.h"
-#include "audio.h"
-
-#include <stdio.h>
-#include <sys/param.h>
-#include <signal.h>
-
-#define DECODE_TYPE_FILE 0
-#define DECODE_TYPE_URL 1
-
-#define DECODE_STATE_STOP 0
-#define DECODE_STATE_START 1
-#define DECODE_STATE_DECODE 2
-
-#define DECODE_ERROR_NOERROR 0
-#define DECODE_ERROR_UNKTYPE 10
-#define DECODE_ERROR_FILE 20
-
-#define DECODE_SUFFIX_MP3 1
-#define DECODE_SUFFIX_OGG 2
-#define DECODE_SUFFIX_FLAC 3
-#define DECODE_SUFFIX_AAC 4
-#define DECODE_SUFFIX_MP4 5
-#define DECODE_SUFFIX_WAVE 6
-
-typedef struct _DecoderControl {
- volatile mpd_sint8 state;
- volatile mpd_sint8 stop;
- volatile mpd_sint8 start;
- volatile mpd_uint16 error;
- volatile mpd_sint8 seek;
- volatile mpd_sint8 seekError;
- volatile mpd_sint8 seekable;
- volatile mpd_sint8 cycleLogFiles;
- volatile double seekWhere;
- AudioFormat audioFormat;
- char utf8url[MAXPATHLEN + 1];
- volatile float totalTime;
-} DecoderControl;
-
-void decodeSigHandler(int sig, siginfo_t * siginfo, void *v);
-
-void decode(void);
-
-#endif
diff --git a/trunk/src/directory.c b/trunk/src/directory.c
deleted file mode 100644
index 560c04b7b..000000000
--- a/trunk/src/directory.c
+++ /dev/null
@@ -1,1362 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "directory.h"
-
-#include "command.h"
-#include "conf.h"
-#include "dbUtils.h"
-#include "interface.h"
-#include "list.h"
-#include "listen.h"
-#include "log.h"
-#include "ls.h"
-#include "mpd_types.h"
-#include "path.h"
-#include "player.h"
-#include "playlist.h"
-#include "sig_handlers.h"
-#include "stats.h"
-#include "tagTracker.h"
-#include "utils.h"
-#include "volume.h"
-
-#include <sys/wait.h>
-#include <dirent.h>
-#include <errno.h>
-#include <assert.h>
-#include <libgen.h>
-
-#define DIRECTORY_DIR "directory: "
-#define DIRECTORY_MTIME "mtime: "
-#define DIRECTORY_BEGIN "begin: "
-#define DIRECTORY_END "end: "
-#define DIRECTORY_INFO_BEGIN "info_begin"
-#define DIRECTORY_INFO_END "info_end"
-#define DIRECTORY_MPD_VERSION "mpd_version: "
-#define DIRECTORY_FS_CHARSET "fs_charset: "
-
-#define DIRECTORY_UPDATE_EXIT_NOUPDATE 0
-#define DIRECTORY_UPDATE_EXIT_UPDATE 1
-#define DIRECTORY_UPDATE_EXIT_ERROR 2
-
-#define DIRECTORY_RETURN_NOUPDATE 0
-#define DIRECTORY_RETURN_UPDATE 1
-#define DIRECTORY_RETURN_ERROR -1
-
-static Directory *mp3rootDirectory;
-
-static time_t directory_dbModTime;
-
-static volatile int directory_updatePid;
-
-static volatile int directory_reReadDB;
-
-static volatile mpd_uint16 directory_updateJobId;
-
-static DirectoryList *newDirectoryList();
-
-static int addToDirectory(Directory * directory, char *shortname, char *name);
-
-static void freeDirectoryList(DirectoryList * list);
-
-static void freeDirectory(Directory * directory);
-
-static int exploreDirectory(Directory * directory);
-
-static int updateDirectory(Directory * directory);
-
-static void deleteEmptyDirectoriesInDirectory(Directory * directory);
-
-static void removeSongFromDirectory(Directory * directory, char *shortname);
-
-static int addSubDirectoryToDirectory(Directory * directory, char *shortname,
- char *name, struct stat *st);
-
-static Directory *getDirectoryDetails(char *name, char **shortname);
-
-static Directory *getDirectory(char *name);
-
-static Song *getSongDetails(char *file, char **shortnameRet,
- Directory ** directoryRet);
-
-static int updatePath(char *utf8path);
-
-static void sortDirectory(Directory * directory);
-
-static int inodeFoundInParent(Directory * parent, ino_t inode, dev_t device);
-
-static int statDirectory(Directory * dir);
-
-static char *getDbFile(void)
-{
- ConfigParam *param = parseConfigFilePath(CONF_DB_FILE, 1);
-
- assert(param);
- assert(param->value);
-
- return param->value;
-}
-
-static void clearUpdatePid(void)
-{
- directory_updatePid = 0;
-}
-
-int isUpdatingDB(void)
-{
- if (directory_updatePid > 0 || directory_reReadDB) {
- return directory_updateJobId;
- }
- return 0;
-}
-
-void directory_sigChldHandler(int pid, int status)
-{
- if (directory_updatePid == pid) {
- if (WIFSIGNALED(status) && WTERMSIG(status) != SIGTERM) {
- ERROR("update process died from a "
- "non-TERM signal: %i\n", WTERMSIG(status));
- } else if (!WIFSIGNALED(status)) {
- switch (WEXITSTATUS(status)) {
- case DIRECTORY_UPDATE_EXIT_UPDATE:
- directory_reReadDB = 1;
- DEBUG("directory_sigChldHandler: "
- "updated db\n");
- case DIRECTORY_UPDATE_EXIT_NOUPDATE:
- DEBUG("directory_sigChldHandler: "
- "update exited succesffully\n");
- break;
- default:
- ERROR("error updating db\n");
- }
- }
- clearUpdatePid();
- }
-}
-
-void readDirectoryDBIfUpdateIsFinished(void)
-{
- if (directory_reReadDB && 0 == directory_updatePid) {
- DEBUG("readDirectoryDB since update finished successfully\n");
- readDirectoryDB();
- playlistVersionChange();
- directory_reReadDB = 0;
- }
-}
-
-int updateInit(int fd, List * pathList)
-{
- if (directory_updatePid > 0) {
- commandError(fd, ACK_ERROR_UPDATE_ALREADY, "already updating");
- return -1;
- }
-
- /* need to block CHLD signal, cause it can exit before we
- even get a chance to assign directory_updatePID */
- blockSignals();
- directory_updatePid = fork();
- if (directory_updatePid == 0) {
- /* child */
- int dbUpdated = 0;
- clearPlayerPid();
-
- unblockSignals();
-
- finishSigHandlers();
- closeAllListenSockets();
- freeAllInterfaces();
- finishPlaylist();
- finishVolume();
-
- if (pathList) {
- ListNode *node = pathList->firstNode;
-
- while (node) {
- switch (updatePath(node->key)) {
- case 1:
- dbUpdated = 1;
- break;
- case 0:
- break;
- default:
- exit(DIRECTORY_UPDATE_EXIT_ERROR);
- }
- node = node->nextNode;
- }
- } else {
- if ((dbUpdated = updateDirectory(mp3rootDirectory)) < 0) {
- exit(DIRECTORY_UPDATE_EXIT_ERROR);
- }
- }
-
- if (!dbUpdated)
- exit(DIRECTORY_UPDATE_EXIT_NOUPDATE);
-
- /* ignore signals since we don't want them to corrupt the db */
- ignoreSignals();
- if (writeDirectoryDB() < 0) {
- exit(DIRECTORY_UPDATE_EXIT_ERROR);
- }
- exit(DIRECTORY_UPDATE_EXIT_UPDATE);
- } else if (directory_updatePid < 0) {
- unblockSignals();
- ERROR("updateInit: Problems forking()'ing\n");
- commandError(fd, ACK_ERROR_SYSTEM,
- "problems trying to update");
- directory_updatePid = 0;
- return -1;
- }
- unblockSignals();
-
- directory_updateJobId++;
- if (directory_updateJobId > 1 << 15)
- directory_updateJobId = 1;
- DEBUG("updateInit: fork()'d update child for update job id %i\n",
- (int)directory_updateJobId);
- fdprintf(fd, "updating_db: %i\n", (int)directory_updateJobId);
-
- return 0;
-}
-
-static DirectoryStat *newDirectoryStat(struct stat *st)
-{
- DirectoryStat *ret = xmalloc(sizeof(DirectoryStat));
- ret->inode = st->st_ino;
- ret->device = st->st_dev;
- return ret;
-}
-
-static void freeDirectoryStatFromDirectory(Directory * dir)
-{
- if (dir->stat)
- free(dir->stat);
- dir->stat = NULL;
-}
-
-static DirectoryList *newDirectoryList(void)
-{
- return makeList((ListFreeDataFunc *) freeDirectory, 1);
-}
-
-static Directory *newDirectory(char *dirname, Directory * parent)
-{
- Directory *directory;
-
- directory = xmalloc(sizeof(Directory));
-
- if (dirname && strlen(dirname))
- directory->path = xstrdup(dirname);
- else
- directory->path = NULL;
- directory->subDirectories = newDirectoryList();
- directory->songs = newSongList();
- directory->stat = NULL;
- directory->parent = parent;
-
- return directory;
-}
-
-static void freeDirectory(Directory * directory)
-{
- freeDirectoryList(directory->subDirectories);
- freeSongList(directory->songs);
- if (directory->path)
- free(directory->path);
- freeDirectoryStatFromDirectory(directory);
- free(directory);
- /* this resets last dir returned */
- /*getDirectoryPath(NULL); */
-}
-
-static void freeDirectoryList(DirectoryList * directoryList)
-{
- freeList(directoryList);
-}
-
-static void removeSongFromDirectory(Directory * directory, char *shortname)
-{
- void *song;
-
- if (findInList(directory->songs, shortname, &song)) {
- LOG("removing: %s\n", getSongUrl((Song *) song));
- deleteFromList(directory->songs, shortname);
- }
-}
-
-static void deleteEmptyDirectoriesInDirectory(Directory * directory)
-{
- ListNode *node = directory->subDirectories->firstNode;
- ListNode *nextNode;
- Directory *subDir;
-
- while (node) {
- subDir = (Directory *) node->data;
- deleteEmptyDirectoriesInDirectory(subDir);
- nextNode = node->nextNode;
- if (subDir->subDirectories->numberOfNodes == 0 &&
- subDir->songs->numberOfNodes == 0) {
- deleteNodeFromList(directory->subDirectories, node);
- }
- node = nextNode;
- }
-}
-
-/* return values:
- -1 -> error
- 0 -> no error, but nothing updated
- 1 -> no error, and stuff updated
- */
-static int updateInDirectory(Directory * directory, char *shortname, char *name)
-{
- void *song;
- void *subDir;
- struct stat st;
-
- if (myStat(name, &st))
- return -1;
-
- if (S_ISREG(st.st_mode) && hasMusicSuffix(name, 0)) {
- if (0 == findInList(directory->songs, shortname, &song)) {
- addToDirectory(directory, shortname, name);
- return DIRECTORY_RETURN_UPDATE;
- } else if (st.st_mtime != ((Song *) song)->mtime) {
- LOG("updating %s\n", name);
- if (updateSongInfo((Song *) song) < 0) {
- removeSongFromDirectory(directory, shortname);
- }
- return 1;
- }
- } else if (S_ISDIR(st.st_mode)) {
- if (findInList
- (directory->subDirectories, shortname, (void **)&subDir)) {
- freeDirectoryStatFromDirectory(subDir);
- ((Directory *) subDir)->stat = newDirectoryStat(&st);
- return updateDirectory((Directory *) subDir);
- } else {
- return addSubDirectoryToDirectory(directory, shortname,
- name, &st);
- }
- }
-
- return 0;
-}
-
-/* return values:
- -1 -> error
- 0 -> no error, but nothing removed
- 1 -> no error, and stuff removed
- */
-static int removeDeletedFromDirectory(Directory * directory, DIR * dir)
-{
- char cwd[2];
- struct dirent *ent;
- char *dirname = getDirectoryPath(directory);
- List *entList = makeList(free, 1);
- void *name;
- char *s;
- char *utf8;
- ListNode *node;
- ListNode *tmpNode;
- int ret = 0;
-
- cwd[0] = '.';
- cwd[1] = '\0';
- if (dirname == NULL)
- dirname = cwd;
-
- while ((ent = readdir(dir))) {
- if (ent->d_name[0] == '.')
- continue; /* hide hidden stuff */
- if (strchr(ent->d_name, '\n'))
- continue;
-
- utf8 = fsCharsetToUtf8(ent->d_name);
-
- if (!utf8)
- continue;
-
- if (directory->path) {
- s = xmalloc(strlen(getDirectoryPath(directory))
- + strlen(utf8) + 2);
- sprintf(s, "%s/%s", getDirectoryPath(directory), utf8);
- } else
- s = xstrdup(utf8);
- insertInList(entList, utf8, s);
- }
-
- node = directory->subDirectories->firstNode;
- while (node) {
- tmpNode = node->nextNode;
- if (findInList(entList, node->key, &name)) {
- if (!isDir((char *)name)) {
- LOG("removing directory: %s\n", (char *)name);
- deleteFromList(directory->subDirectories,
- node->key);
- ret = 1;
- }
- } else {
- LOG("removing directory: %s/%s\n",
- getDirectoryPath(directory), node->key);
- deleteFromList(directory->subDirectories, node->key);
- ret = 1;
- }
- node = tmpNode;
- }
-
- node = directory->songs->firstNode;
- while (node) {
- tmpNode = node->nextNode;
- if (findInList(entList, node->key, (void **)&name)) {
- if (!isMusic(name, NULL, 0)) {
- removeSongFromDirectory(directory, node->key);
- ret = 1;
- }
- } else {
- removeSongFromDirectory(directory, node->key);
- ret = 1;
- }
- node = tmpNode;
- }
-
- freeList(entList);
-
- return ret;
-}
-
-static Directory *addDirectoryPathToDB(char *utf8path, char **shortname)
-{
- char *parent;
- Directory *parentDirectory;
- void *directory;
-
- parent = xstrdup(parentPath(utf8path));
-
- if (strlen(parent) == 0)
- parentDirectory = (void *)mp3rootDirectory;
- else
- parentDirectory = addDirectoryPathToDB(parent, shortname);
-
- if (!parentDirectory) {
- free(parent);
- return NULL;
- }
-
- *shortname = utf8path + strlen(parent);
- while (*(*shortname) && *(*shortname) == '/')
- (*shortname)++;
-
- if (!findInList
- (parentDirectory->subDirectories, *shortname, &directory)) {
- struct stat st;
- if (myStat(utf8path, &st) < 0 ||
- inodeFoundInParent(parentDirectory, st.st_ino, st.st_dev)) {
- free(parent);
- return NULL;
- } else {
- directory = newDirectory(utf8path, parentDirectory);
- insertInList(parentDirectory->subDirectories,
- *shortname, directory);
- }
- }
-
- /* if we're adding directory paths, make sure to delete filenames
- with potentially the same name */
- removeSongFromDirectory(parentDirectory, *shortname);
-
- free(parent);
-
- return (Directory *) directory;
-}
-
-static Directory *addParentPathToDB(char *utf8path, char **shortname)
-{
- char *parent;
- Directory *parentDirectory;
-
- parent = xstrdup(parentPath(utf8path));
-
- if (strlen(parent) == 0)
- parentDirectory = (void *)mp3rootDirectory;
- else
- parentDirectory = addDirectoryPathToDB(parent, shortname);
-
- if (!parentDirectory) {
- free(parent);
- return NULL;
- }
-
- *shortname = utf8path + strlen(parent);
- while (*(*shortname) && *(*shortname) == '/')
- (*shortname)++;
-
- free(parent);
-
- return (Directory *) parentDirectory;
-}
-
-/* return values:
- -1 -> error
- 0 -> no error, but nothing updated
- 1 -> no error, and stuff updated
- */
-static int updatePath(char *utf8path)
-{
- Directory *directory;
- Directory *parentDirectory;
- Song *song;
- char *shortname;
- char *path = sanitizePathDup(utf8path);
- time_t mtime;
- int ret = 0;
-
- if (NULL == path)
- return -1;
-
- /* if path is in the DB try to update it, or else delete it */
- if ((directory = getDirectoryDetails(path, &shortname))) {
- parentDirectory = directory->parent;
-
- /* if this update directory is successfull, we are done */
- if ((ret = updateDirectory(directory)) >= 0) {
- free(path);
- sortDirectory(directory);
- return ret;
- }
- /* we don't want to delete the root directory */
- else if (directory == mp3rootDirectory) {
- free(path);
- return 0;
- }
- /* if updateDirectory fails, means we should delete it */
- else {
- LOG("removing directory: %s\n", path);
- deleteFromList(parentDirectory->subDirectories,
- shortname);
- ret = 1;
- /* don't return, path maybe a song now */
- }
- } else if ((song = getSongDetails(path, &shortname, &parentDirectory))) {
- if (!parentDirectory->stat
- && statDirectory(parentDirectory) < 0) {
- free(path);
- return 0;
- }
- /* if this song update is successfull, we are done */
- else if (0 == inodeFoundInParent(parentDirectory->parent,
- parentDirectory->stat->inode,
- parentDirectory->stat->device)
- && song && isMusic(getSongUrl(song), &mtime, 0)) {
- free(path);
- if (song->mtime == mtime)
- return 0;
- else if (updateSongInfo(song) == 0)
- return 1;
- else {
- removeSongFromDirectory(parentDirectory,
- shortname);
- return 1;
- }
- }
- /* if updateDirectory fails, means we should delete it */
- else {
- removeSongFromDirectory(parentDirectory, shortname);
- ret = 1;
- /* don't return, path maybe a directory now */
- }
- }
-
- /* path not found in the db, see if it actually exists on the fs.
- * Also, if by chance a directory was replaced by a file of the same
- * name or vice versa, we need to add it to the db
- */
- if (isDir(path) || isMusic(path, NULL, 0)) {
- parentDirectory = addParentPathToDB(path, &shortname);
- if (!parentDirectory || (!parentDirectory->stat &&
- statDirectory(parentDirectory) < 0)) {
- } else if (0 == inodeFoundInParent(parentDirectory->parent,
- parentDirectory->stat->inode,
- parentDirectory->stat->
- device)
- && addToDirectory(parentDirectory, shortname, path)
- > 0) {
- ret = 1;
- }
- }
-
- free(path);
-
- return ret;
-}
-
-/* return values:
- -1 -> error
- 0 -> no error, but nothing updated
- 1 -> no error, and stuff updated
- */
-static int updateDirectory(Directory * directory)
-{
- DIR *dir;
- char cwd[2];
- struct dirent *ent;
- char *s;
- char *utf8;
- char *dirname = getDirectoryPath(directory);
- int ret = 0;
-
- {
- if (!directory->stat && statDirectory(directory) < 0) {
- return -1;
- } else if (inodeFoundInParent(directory->parent,
- directory->stat->inode,
- directory->stat->device)) {
- return -1;
- }
- }
-
- cwd[0] = '.';
- cwd[1] = '\0';
- if (dirname == NULL)
- dirname = cwd;
-
- if ((dir = opendir(rmp2amp(utf8ToFsCharset(dirname)))) == NULL)
- return -1;
-
- if (removeDeletedFromDirectory(directory, dir) > 0)
- ret = 1;
-
- rewinddir(dir);
-
- while ((ent = readdir(dir))) {
- if (ent->d_name[0] == '.')
- continue; /* hide hidden stuff */
- if (strchr(ent->d_name, '\n'))
- continue;
-
- utf8 = fsCharsetToUtf8(ent->d_name);
-
- if (!utf8)
- continue;
-
- utf8 = xstrdup(utf8);
-
- if (directory->path) {
- s = xmalloc(strlen(getDirectoryPath(directory)) +
- strlen(utf8) + 2);
- sprintf(s, "%s/%s", getDirectoryPath(directory), utf8);
- } else
- s = xstrdup(utf8);
- if (updateInDirectory(directory, utf8, s) > 0)
- ret = 1;
- free(utf8);
- free(s);
- }
-
- closedir(dir);
-
- return ret;
-}
-
-/* return values:
- -1 -> error
- 0 -> no error, but nothing found
- 1 -> no error, and stuff found
- */
-static int exploreDirectory(Directory * directory)
-{
- DIR *dir;
- char cwd[2];
- struct dirent *ent;
- char *s;
- char *utf8;
- char *dirname = getDirectoryPath(directory);
- int ret = 0;
-
- cwd[0] = '.';
- cwd[1] = '\0';
- if (dirname == NULL)
- dirname = cwd;
-
- DEBUG("explore: attempting to opendir: %s\n", dirname);
- if ((dir = opendir(rmp2amp(utf8ToFsCharset(dirname)))) == NULL)
- return -1;
-
- DEBUG("explore: %s\n", dirname);
- while ((ent = readdir(dir))) {
- if (ent->d_name[0] == '.')
- continue; /* hide hidden stuff */
- if (strchr(ent->d_name, '\n'))
- continue;
-
- utf8 = fsCharsetToUtf8(ent->d_name);
-
- if (!utf8)
- continue;
-
- utf8 = xstrdup(utf8);
-
- DEBUG("explore: found: %s (%s)\n", ent->d_name, utf8);
-
- if (directory->path) {
- s = xmalloc(strlen(getDirectoryPath(directory)) +
- strlen(utf8) + 2);
- sprintf(s, "%s/%s", getDirectoryPath(directory), utf8);
- } else
- s = xstrdup(utf8);
- if (addToDirectory(directory, utf8, s) > 0)
- ret = 1;
- free(utf8);
- free(s);
- }
-
- closedir(dir);
-
- return ret;
-}
-
-static int statDirectory(Directory * dir)
-{
- struct stat st;
-
- if (myStat(getDirectoryPath(dir) ? getDirectoryPath(dir) : "", &st) < 0)
- {
- return -1;
- }
-
- dir->stat = newDirectoryStat(&st);
-
- return 0;
-}
-
-static int inodeFoundInParent(Directory * parent, ino_t inode, dev_t device)
-{
- while (parent) {
- if (!parent->stat) {
- if (statDirectory(parent) < 0)
- return -1;
- }
- if (parent->stat->inode == inode &&
- parent->stat->device == device) {
- DEBUG("recursive directory found\n");
- return 1;
- }
- parent = parent->parent;
- }
-
- return 0;
-}
-
-static int addSubDirectoryToDirectory(Directory * directory, char *shortname,
- char *name, struct stat *st)
-{
- Directory *subDirectory;
-
- if (inodeFoundInParent(directory, st->st_ino, st->st_dev))
- return 0;
-
- subDirectory = newDirectory(name, directory);
- subDirectory->stat = newDirectoryStat(st);
-
- if (exploreDirectory(subDirectory) < 1) {
- freeDirectory(subDirectory);
- return 0;
- }
-
- insertInList(directory->subDirectories, shortname, subDirectory);
-
- return 1;
-}
-
-static int addToDirectory(Directory * directory, char *shortname, char *name)
-{
- struct stat st;
-
- if (myStat(name, &st)) {
- DEBUG("failed to stat %s: %s\n", name, strerror(errno));
- return -1;
- }
-
- if (S_ISREG(st.st_mode) && hasMusicSuffix(name, 0)) {
- Song *song;
- song = addSongToList(directory->songs, shortname, name,
- SONG_TYPE_FILE, directory);
- if (!song)
- return -1;
- LOG("added %s\n", name);
- return 1;
- } else if (S_ISDIR(st.st_mode)) {
- return addSubDirectoryToDirectory(directory, shortname, name,
- &st);
- }
-
- DEBUG("addToDirectory: %s is not a directory or music\n", name);
-
- return -1;
-}
-
-void closeMp3Directory(void)
-{
- freeDirectory(mp3rootDirectory);
-}
-
-static Directory *findSubDirectory(Directory * directory, char *name)
-{
- void *subDirectory;
- char *dup = xstrdup(name);
- char *key;
-
- key = strtok(dup, "/");
- if (!key) {
- free(dup);
- return NULL;
- }
-
- if (findInList(directory->subDirectories, key, &subDirectory)) {
- free(dup);
- return (Directory *) subDirectory;
- }
-
- free(dup);
- return NULL;
-}
-
-int isRootDirectory(char *name)
-{
- if (name == NULL || name[0] == '\0' || strcmp(name, "/") == 0) {
- return 1;
- }
- return 0;
-}
-
-static Directory *getSubDirectory(Directory * directory, char *name,
- char **shortname)
-{
- Directory *subDirectory;
- int len;
-
- if (isRootDirectory(name)) {
- return directory;
- }
-
- if ((subDirectory = findSubDirectory(directory, name)) == NULL)
- return NULL;
-
- *shortname = name;
-
- len = 0;
- while (name[len] != '/' && name[len] != '\0')
- len++;
- while (name[len] == '/')
- len++;
-
- return getSubDirectory(subDirectory, &(name[len]), shortname);
-}
-
-static Directory *getDirectoryDetails(char *name, char **shortname)
-{
- *shortname = NULL;
-
- return getSubDirectory(mp3rootDirectory, name, shortname);
-}
-
-static Directory *getDirectory(char *name)
-{
- char *shortname;
-
- return getSubDirectory(mp3rootDirectory, name, &shortname);
-}
-
-static int printDirectoryList(int fd, DirectoryList * directoryList)
-{
- ListNode *node = directoryList->firstNode;
- Directory *directory;
-
- while (node != NULL) {
- directory = (Directory *) node->data;
- fdprintf(fd, "%s%s\n", DIRECTORY_DIR,
- getDirectoryPath(directory));
- node = node->nextNode;
- }
-
- return 0;
-}
-
-int printDirectoryInfo(int fd, char *name)
-{
- Directory *directory;
-
- if ((directory = getDirectory(name)) == NULL) {
- commandError(fd, ACK_ERROR_NO_EXIST, "directory not found");
- return -1;
- }
-
- printDirectoryList(fd, directory->subDirectories);
- printSongInfoFromList(fd, directory->songs);
-
- return 0;
-}
-
-static void writeDirectoryInfo(FILE * fp, Directory * directory)
-{
- ListNode *node = (directory->subDirectories)->firstNode;
- Directory *subDirectory;
-
- if (directory->path) {
- fprintf(fp, "%s%s\n", DIRECTORY_BEGIN,
- getDirectoryPath(directory));
- }
-
- while (node != NULL) {
- subDirectory = (Directory *) node->data;
- fprintf(fp, "%s%s\n", DIRECTORY_DIR, node->key);
- writeDirectoryInfo(fp, subDirectory);
- node = node->nextNode;
- }
-
- writeSongInfoFromList(fp, directory->songs);
-
- if (directory->path) {
- fprintf(fp, "%s%s\n", DIRECTORY_END,
- getDirectoryPath(directory));
- }
-}
-
-static void readDirectoryInfo(FILE * fp, Directory * directory)
-{
- char buffer[MAXPATHLEN * 2];
- int bufferSize = MAXPATHLEN * 2;
- char *key;
- Directory *subDirectory;
- int strcmpRet;
- char *name;
- ListNode *nextDirNode = directory->subDirectories->firstNode;
- ListNode *nodeTemp;
-
- while (myFgets(buffer, bufferSize, fp)
- && 0 != strncmp(DIRECTORY_END, buffer, strlen(DIRECTORY_END))) {
- if (0 == strncmp(DIRECTORY_DIR, buffer, strlen(DIRECTORY_DIR))) {
- key = xstrdup(&(buffer[strlen(DIRECTORY_DIR)]));
- if (!myFgets(buffer, bufferSize, fp))
- FATAL("Error reading db, fgets\n");
- /* for compatibility with db's prior to 0.11 */
- if (0 == strncmp(DIRECTORY_MTIME, buffer,
- strlen(DIRECTORY_MTIME))) {
- if (!myFgets(buffer, bufferSize, fp))
- FATAL("Error reading db, fgets\n");
- }
- if (strncmp
- (DIRECTORY_BEGIN, buffer,
- strlen(DIRECTORY_BEGIN))) {
- FATAL("Error reading db at line: %s\n", buffer);
- }
- name = xstrdup(&(buffer[strlen(DIRECTORY_BEGIN)]));
-
- while (nextDirNode && (strcmpRet =
- strcmp(key,
- nextDirNode->key)) > 0) {
- nodeTemp = nextDirNode->nextNode;
- deleteNodeFromList(directory->subDirectories,
- nextDirNode);
- nextDirNode = nodeTemp;
- }
-
- if (NULL == nextDirNode) {
- subDirectory = newDirectory(name, directory);
- insertInList(directory->subDirectories,
- key, (void *)subDirectory);
- } else if (strcmpRet == 0) {
- subDirectory = (Directory *) nextDirNode->data;
- nextDirNode = nextDirNode->nextNode;
- } else {
- subDirectory = newDirectory(name, directory);
- insertInListBeforeNode(directory->
- subDirectories,
- nextDirNode, -1, key,
- (void *)subDirectory);
- }
-
- free(name);
- free(key);
- readDirectoryInfo(fp, subDirectory);
- } else if (0 == strncmp(SONG_BEGIN, buffer, strlen(SONG_BEGIN))) {
- readSongInfoIntoList(fp, directory->songs, directory);
- } else {
- FATAL("Unknown line in db: %s\n", buffer);
- }
- }
-
- while (nextDirNode) {
- nodeTemp = nextDirNode->nextNode;
- deleteNodeFromList(directory->subDirectories, nextDirNode);
- nextDirNode = nodeTemp;
- }
-}
-
-static void sortDirectory(Directory * directory)
-{
- ListNode *node = directory->subDirectories->firstNode;
- Directory *subDir;
-
- sortList(directory->subDirectories);
- sortList(directory->songs);
-
- while (node != NULL) {
- subDir = (Directory *) node->data;
- sortDirectory(subDir);
- node = node->nextNode;
- }
-}
-
-int checkDirectoryDB(void)
-{
- struct stat st;
- char *dbFile;
- char *dirPath;
- char *dbPath;
-
- dbFile = getDbFile();
-
- /* Check if the file exists */
- if (access(dbFile, F_OK)) {
- /* If the file doesn't exist, we can't check if we can write
- * it, so we are going to try to get the directory path, and
- * see if we can write a file in that */
- dbPath = xstrdup(dbFile);
- dirPath = dirname(dbPath);
-
- /* Check that the parent part of the path is a directory */
- if (stat(dirPath, &st) < 0) {
- ERROR("Couldn't stat parent directory of db file "
- "\"%s\": %s\n", dbFile, strerror(errno));
- free(dbPath);
- return -1;
- }
-
- if (!S_ISDIR(st.st_mode)) {
- ERROR("Couldn't create db file \"%s\" because the "
- "parent path is not a directory\n", dbFile);
- free(dbPath);
- return -1;
- }
-
- /* Check if we can write to the directory */
- if (access(dirPath, R_OK | W_OK)) {
- ERROR("Can't create db file in \"%s\": %s\n", dirPath,
- strerror(errno));
- free(dbPath);
- return -1;
-
- }
-
- free(dbPath);
- return 0;
- }
-
- /* Path exists, now check if it's a regular file */
- if (stat(dbFile, &st) < 0) {
- ERROR("Couldn't stat db file \"%s\": %s\n", dbFile,
- strerror(errno));
- return -1;
- }
-
- if (!S_ISREG(st.st_mode)) {
- ERROR("db file \"%s\" is not a regular file\n", dbFile);
- return -1;
- }
-
- /* And check that we can write to it */
- if (access(dbFile, R_OK | W_OK)) {
- ERROR("Can't open db file \"%s\" for reading/writing: %s\n",
- dbFile, strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-int writeDirectoryDB(void)
-{
- FILE *fp;
- char *dbFile = getDbFile();
- struct stat st;
-
- DEBUG("removing empty directories from DB\n");
- deleteEmptyDirectoriesInDirectory(mp3rootDirectory);
-
- DEBUG("sorting DB\n");
-
- sortDirectory(mp3rootDirectory);
-
- DEBUG("writing DB\n");
-
- while (!(fp = fopen(dbFile, "w")) && errno == EINTR);
- if (!fp) {
- ERROR("unable to write to db file \"%s\": %s\n",
- dbFile, strerror(errno));
- return -1;
- }
-
- /* block signals when writing the db so we don't get a corrupted db */
- fprintf(fp, "%s\n", DIRECTORY_INFO_BEGIN);
- fprintf(fp, "%s%s\n", DIRECTORY_MPD_VERSION, VERSION);
- fprintf(fp, "%s%s\n", DIRECTORY_FS_CHARSET, getFsCharset());
- fprintf(fp, "%s\n", DIRECTORY_INFO_END);
-
- writeDirectoryInfo(fp, mp3rootDirectory);
-
- while (fclose(fp) && errno == EINTR);
-
- if (stat(dbFile, &st) == 0)
- directory_dbModTime = st.st_mtime;
-
- return 0;
-}
-
-int readDirectoryDB(void)
-{
- FILE *fp = NULL;
- char *dbFile = getDbFile();
- struct stat st;
-
- if (!mp3rootDirectory)
- mp3rootDirectory = newDirectory(NULL, NULL);
- while (!(fp = fopen(dbFile, "r")) && errno == EINTR) ;
- if (fp == NULL) {
- ERROR("unable to open db file \"%s\": %s\n",
- dbFile, strerror(errno));
- return -1;
- }
-
- /* get initial info */
- {
- char buffer[100];
- int bufferSize = 100;
- int foundFsCharset = 0;
- int foundVersion = 0;
-
- if (!myFgets(buffer, bufferSize, fp))
- FATAL("Error reading db, fgets\n");
- if (0 == strcmp(DIRECTORY_INFO_BEGIN, buffer)) {
- while (myFgets(buffer, bufferSize, fp) &&
- 0 != strcmp(DIRECTORY_INFO_END, buffer)) {
- if (0 == strncmp(DIRECTORY_MPD_VERSION, buffer,
- strlen(DIRECTORY_MPD_VERSION)))
- {
- if (foundVersion)
- FATAL("already found version in db\n");
- foundVersion = 1;
- } else if (0 ==
- strncmp(DIRECTORY_FS_CHARSET, buffer,
- strlen
- (DIRECTORY_FS_CHARSET))) {
- char *fsCharset;
- char *tempCharset;
-
- if (foundFsCharset)
- FATAL("already found fs charset in db\n");
-
- foundFsCharset = 1;
-
- fsCharset = &(buffer[strlen(DIRECTORY_FS_CHARSET)]);
- if ((tempCharset = getConfigParamValue(CONF_FS_CHARSET))
- && strcmp(fsCharset, tempCharset)) {
- WARNING("Using \"%s\" for the "
- "filesystem charset "
- "instead of \"%s\"\n",
- fsCharset, tempCharset);
- WARNING("maybe you need to "
- "recreate the db?\n");
- setFsCharset(fsCharset);
- }
- } else {
- FATAL("directory: unknown line in db info: %s\n",
- buffer);
- }
- }
- } else {
- ERROR("db info not found in db file\n");
- ERROR("you should recreate the db using --create-db\n");
- fseek(fp, 0, SEEK_SET);
- return -1;
- }
- }
-
- DEBUG("reading DB\n");
-
- readDirectoryInfo(fp, mp3rootDirectory);
- while (fclose(fp) && errno == EINTR) ;
-
- stats.numberOfSongs = countSongsIn(STDERR_FILENO, NULL);
- stats.dbPlayTime = sumSongTimesIn(STDERR_FILENO, NULL);
-
- if (stat(dbFile, &st) == 0)
- directory_dbModTime = st.st_mtime;
-
- return 0;
-}
-
-void updateMp3Directory(void)
-{
- switch (updateDirectory(mp3rootDirectory)) {
- case 0:
- /* nothing updated */
- return;
- case 1:
- if (writeDirectoryDB() < 0)
- exit(EXIT_FAILURE);
- break;
- default:
- /* something was updated and db should be written */
- FATAL("problems updating music db\n");
- }
-
- return;
-}
-
-static int traverseAllInSubDirectory(int fd, Directory * directory,
- int (*forEachSong) (int, Song *,
- void *),
- int (*forEachDir) (int, Directory *,
- void *), void *data)
-{
- ListNode *node = directory->songs->firstNode;
- Song *song;
- Directory *dir;
- int errFlag = 0;
-
- if (forEachDir) {
- errFlag = forEachDir(fd, directory, data);
- if (errFlag)
- return errFlag;
- }
-
- if (forEachSong) {
- while (node != NULL && !errFlag) {
- song = (Song *) node->data;
- errFlag = forEachSong(fd, song, data);
- node = node->nextNode;
- }
- if (errFlag)
- return errFlag;
- }
-
- node = directory->subDirectories->firstNode;
-
- while (node != NULL && !errFlag) {
- dir = (Directory *) node->data;
- errFlag = traverseAllInSubDirectory(fd, dir, forEachSong,
- forEachDir, data);
- node = node->nextNode;
- }
-
- return errFlag;
-}
-
-int traverseAllIn(int fd, char *name,
- int (*forEachSong) (int, Song *, void *),
- int (*forEachDir) (int, Directory *, void *), void *data)
-{
- Directory *directory;
-
- if ((directory = getDirectory(name)) == NULL) {
- Song *song;
- if ((song = getSongFromDB(name)) && forEachSong) {
- return forEachSong(fd, song, data);
- }
- commandError(fd, ACK_ERROR_NO_EXIST,
- "directory or file not found");
- return -1;
- }
-
- return traverseAllInSubDirectory(fd, directory, forEachSong, forEachDir,
- data);
-}
-
-static void freeAllDirectoryStats(Directory * directory)
-{
- ListNode *node = directory->subDirectories->firstNode;
-
- while (node != NULL) {
- freeAllDirectoryStats((Directory *) node->data);
- node = node->nextNode;
- }
-
- freeDirectoryStatFromDirectory(directory);
-}
-
-void initMp3Directory(void)
-{
- mp3rootDirectory = newDirectory(NULL, NULL);
- exploreDirectory(mp3rootDirectory);
- freeAllDirectoryStats(mp3rootDirectory);
- stats.numberOfSongs = countSongsIn(STDERR_FILENO, NULL);
- stats.dbPlayTime = sumSongTimesIn(STDERR_FILENO, NULL);
-}
-
-static Song *getSongDetails(char *file, char **shortnameRet,
- Directory ** directoryRet)
-{
- void *song = NULL;
- Directory *directory;
- char *dir = NULL;
- char *dup = xstrdup(file);
- char *shortname = dup;
- char *c = strtok(dup, "/");
-
- DEBUG("get song: %s\n", file);
-
- while (c) {
- shortname = c;
- c = strtok(NULL, "/");
- }
-
- if (shortname != dup) {
- for (c = dup; c < shortname - 1; c++) {
- if (*c == '\0')
- *c = '/';
- }
- dir = dup;
- }
-
- if (!(directory = getDirectory(dir))) {
- free(dup);
- return NULL;
- }
-
- if (!findInList(directory->songs, shortname, &song)) {
- free(dup);
- return NULL;
- }
-
- free(dup);
- if (shortnameRet)
- *shortnameRet = shortname;
- if (directoryRet)
- *directoryRet = directory;
- return (Song *) song;
-}
-
-Song *getSongFromDB(char *file)
-{
- return getSongDetails(file, NULL, NULL);
-}
-
-time_t getDbModTime(void)
-{
- return directory_dbModTime;
-}
diff --git a/trunk/src/directory.h b/trunk/src/directory.h
deleted file mode 100644
index b1482988f..000000000
--- a/trunk/src/directory.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef DIRECTORY_H
-#define DIRECTORY_H
-
-#include "../config.h"
-
-#include "song.h"
-#include "list.h"
-
-typedef List DirectoryList;
-
-typedef struct _DirectoryStat {
- ino_t inode;
- dev_t device;
-} DirectoryStat;
-
-typedef struct _Directory {
- char *path;
- DirectoryList *subDirectories;
- SongList *songs;
- struct _Directory *parent;
- DirectoryStat *stat;
-} Directory;
-
-void readDirectoryDBIfUpdateIsFinished(void);
-
-int isUpdatingDB(void);
-
-void directory_sigChldHandler(int pid, int status);
-
-int updateInit(int fd, List * pathList);
-
-void initMp3Directory(void);
-
-void closeMp3Directory(void);
-
-int isRootDirectory(char *name);
-
-int printDirectoryInfo(int fd, char *dirname);
-
-int checkDirectoryDB(void);
-
-int writeDirectoryDB(void);
-
-int readDirectoryDB(void);
-
-void updateMp3Directory(void);
-
-Song *getSongFromDB(char *file);
-
-time_t getDbModTime(void);
-
-int traverseAllIn(int fd, char *name,
- int (*forEachSong) (int, Song *, void *),
- int (*forEachDir) (int, Directory *, void *), void *data);
-
-#define getDirectoryPath(dir) ((dir && dir->path) ? dir->path : "")
-
-#endif
diff --git a/trunk/src/gcc.h b/trunk/src/gcc.h
deleted file mode 100644
index 4ae18c46b..000000000
--- a/trunk/src/gcc.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef MPD_GCC_H
-#define MPD_GCC_H
-
-/* this allows us to take advantage of special gcc features while still
- * allowing other compilers to compile:
- *
- * example taken from: http://rlove.org/log/2005102601
- */
-
-#if defined(__GNUC__) && (__GNUC__ >= 3)
-# define mpd_const __attribute__ ((const))
-# define mpd_deprecated __attribute__ ((deprecated))
-# define mpd_malloc __attribute__ ((malloc))
-# define mpd_must_check __attribute__ ((warn_unused_result))
-# define mpd_noreturn __attribute__ ((noreturn))
-# define mpd_packed __attribute__ ((packed))
-/* these are very useful for type checking */
-# define mpd_printf __attribute__ ((format(printf,1,2)))
-# define mpd_fprintf __attribute__ ((format(printf,2,3)))
-# define mpd_fprintf_ __attribute__ ((format(printf,3,4)))
-# define mpd_pure __attribute__ ((pure))
-# define mpd_scanf __attribute__ ((format(scanf,1,2)))
-# define mpd_unused __attribute__ ((unused))
-# define mpd_used __attribute__ ((used))
-/* # define inline inline __attribute__ ((always_inline)) */
-# define mpd_noinline __attribute__ ((noinline))
-# define mpd_likely(x) __builtin_expect (!!(x), 1)
-# define mpd_unlikely(x) __builtin_expect (!!(x), 0)
-#else
-# define mpd_const
-# define mpd_deprecated
-# define mpd_malloc
-# define mpd_must_check
-# define mpd_noreturn
-# define mpd_packed
-# define mpd_printf
-# define mpd_fprintf
-# define mpd_fprintf_
-# define mpd_pure
-# define mpd_scanf
-# define mpd_unused
-# define mpd_used
-/* # define inline */
-# define mpd_noinline
-# define mpd_likely(x) (x)
-# define mpd_unlikely(x) (x)
-#endif
-
-#endif /* MPD_GCC_H */
diff --git a/trunk/src/inputPlugin.c b/trunk/src/inputPlugin.c
deleted file mode 100644
index 60e60947b..000000000
--- a/trunk/src/inputPlugin.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "inputPlugin.h"
-
-#include "list.h"
-#include "myfprintf.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-static List *inputPlugin_list;
-
-void loadInputPlugin(InputPlugin * inputPlugin)
-{
- if (!inputPlugin)
- return;
- if (!inputPlugin->name)
- return;
-
- if (inputPlugin->initFunc && inputPlugin->initFunc() < 0)
- return;
-
- insertInList(inputPlugin_list, inputPlugin->name, (void *)inputPlugin);
-}
-
-void unloadInputPlugin(InputPlugin * inputPlugin)
-{
- if (inputPlugin->finishFunc)
- inputPlugin->finishFunc();
- deleteFromList(inputPlugin_list, inputPlugin->name);
-}
-
-static int stringFoundInStringArray(char **array, char *suffix)
-{
- while (array && *array) {
- if (strcasecmp(*array, suffix) == 0)
- return 1;
- array++;
- }
-
- return 0;
-}
-
-InputPlugin *getInputPluginFromSuffix(char *suffix, unsigned int next)
-{
- static ListNode *pos;
- ListNode *node;
- InputPlugin *plugin;
-
- if (suffix == NULL)
- return NULL;
-
- if (next) {
- if (pos)
- node = pos;
- else
- return NULL;
- } else
- node = inputPlugin_list->firstNode;
-
- while (node != NULL) {
- plugin = node->data;
- if (stringFoundInStringArray(plugin->suffixes, suffix)) {
- pos = node->nextNode;
- return plugin;
- }
- node = node->nextNode;
- }
-
- return NULL;
-}
-
-InputPlugin *getInputPluginFromMimeType(char *mimeType, unsigned int next)
-{
- static ListNode *pos;
- ListNode *node;
- InputPlugin *plugin;
-
- if (mimeType == NULL)
- return NULL;
-
- node = (next && pos) ? pos : inputPlugin_list->firstNode;
-
- while (node != NULL) {
- plugin = node->data;
- if (stringFoundInStringArray(plugin->mimeTypes, mimeType)) {
- pos = node->nextNode;
- return plugin;
- }
- node = node->nextNode;
- }
-
- return NULL;
-}
-
-InputPlugin *getInputPluginFromName(char *name)
-{
- void *plugin = NULL;
-
- findInList(inputPlugin_list, name, &plugin);
-
- return (InputPlugin *) plugin;
-}
-
-void printAllInputPluginSuffixes(FILE * fp)
-{
- ListNode *node = inputPlugin_list->firstNode;
- InputPlugin *plugin;
- char **suffixes;
-
- while (node) {
- plugin = (InputPlugin *) node->data;
- suffixes = plugin->suffixes;
- while (suffixes && *suffixes) {
- fprintf(fp, "%s ", *suffixes);
- suffixes++;
- }
- node = node->nextNode;
- }
- fprintf(fp, "\n");
- fflush(fp);
-}
-
-void initInputPlugins(void)
-{
- inputPlugin_list = makeList(NULL, 1);
-
- /* load plugins here */
- loadInputPlugin(&mp3Plugin);
- loadInputPlugin(&oggvorbisPlugin);
- loadInputPlugin(&oggflacPlugin);
- loadInputPlugin(&flacPlugin);
- loadInputPlugin(&audiofilePlugin);
- loadInputPlugin(&mp4Plugin);
- loadInputPlugin(&mpcPlugin);
- loadInputPlugin(&modPlugin);
-}
-
-void finishInputPlugins(void)
-{
- freeList(inputPlugin_list);
-}
diff --git a/trunk/src/inputPlugin.h b/trunk/src/inputPlugin.h
deleted file mode 100644
index 398ddc1cb..000000000
--- a/trunk/src/inputPlugin.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef INPUT_PLUGIN_H
-#define INPUT_PLUGIN_H
-
-#include "../config.h"
-#include "inputStream.h"
-#include "decode.h"
-#include "outputBuffer.h"
-#include "tag.h"
-
-/* valid values for streamTypes in the InputPlugin struct: */
-#define INPUT_PLUGIN_STREAM_FILE 0x01
-#define INPUT_PLUGIN_STREAM_URL 0x02
-
-/* optional, set this to NULL if the InputPlugin doesn't have/need one
- * this must return < 0 if there is an error and >= 0 otherwise */
-typedef int (*InputPlugin_initFunc) ();
-
-/* optional, set this to NULL if the InputPlugin doesn't have/need one */
-typedef void (*InputPlugin_finishFunc) ();
-
-/* boolean return value, returns 1 if the InputStream is decodable by
- * the InputPlugin, 0 if not */
-typedef unsigned int (*InputPlugin_tryDecodeFunc) (InputStream *);
-
-/* this will be used to decode InputStreams, and is recommended for files
- * and networked (HTTP) connections.
- *
- * returns -1 on error, 0 on success */
-typedef int (*InputPlugin_streamDecodeFunc) (OutputBuffer *, DecoderControl *,
- InputStream *);
-
-/* use this if and only if your InputPlugin can only be passed a filename or
- * handle as input, and will not allow callbacks to be set (like Ogg-Vorbis
- * and FLAC libraries allow)
- *
- * returns -1 on error, 0 on success */
-typedef int (*InputPlugin_fileDecodeFunc) (OutputBuffer *, DecoderControl *,
- char *path);
-
-/* file should be the full path! Returns NULL if a tag cannot be found
- * or read */
-typedef MpdTag *(*InputPlugin_tagDupFunc) (char *file);
-
-typedef struct _InputPlugin {
- char *name;
- InputPlugin_initFunc initFunc;
- InputPlugin_finishFunc finishFunc;
- InputPlugin_tryDecodeFunc tryDecodeFunc;
- InputPlugin_streamDecodeFunc streamDecodeFunc;
- InputPlugin_fileDecodeFunc fileDecodeFunc;
- InputPlugin_tagDupFunc tagDupFunc;
-
- /* one or more of the INPUT_PLUGIN_STREAM_* values OR'd together */
- unsigned char streamTypes;
-
- /* last element in these arrays must always be a NULL: */
- char **suffixes;
- char **mimeTypes;
-} InputPlugin;
-
-/* individual functions to load/unload plugins */
-void loadInputPlugin(InputPlugin * inputPlugin);
-void unloadInputPlugin(InputPlugin * inputPlugin);
-
-/* interface for using plugins */
-
-InputPlugin *getInputPluginFromSuffix(char *suffix, unsigned int next);
-
-InputPlugin *getInputPluginFromMimeType(char *mimeType, unsigned int next);
-
-InputPlugin *getInputPluginFromName(char *name);
-
-void printAllInputPluginSuffixes(FILE * fp);
-
-/* this is where we "load" all the "plugins" ;-) */
-void initInputPlugins(void);
-
-/* this is where we "unload" all the "plugins" */
-void finishInputPlugins(void);
-
-extern InputPlugin mp3Plugin;
-extern InputPlugin oggvorbisPlugin;
-extern InputPlugin flacPlugin;
-extern InputPlugin oggflacPlugin;
-extern InputPlugin audiofilePlugin;
-extern InputPlugin mp4Plugin;
-extern InputPlugin mpcPlugin;
-extern InputPlugin aacPlugin;
-extern InputPlugin modPlugin;
-
-#endif
diff --git a/trunk/src/inputPlugins/_flac_common.c b/trunk/src/inputPlugins/_flac_common.c
deleted file mode 100644
index 11126cd1b..000000000
--- a/trunk/src/inputPlugins/_flac_common.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * Common data structures and functions used by FLAC and OggFLAC
- * (c) 2005 by Eric Wong <normalperson@yhbt.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "../inputPlugin.h"
-
-#if defined(HAVE_FLAC) || defined(HAVE_OGGFLAC)
-
-#include "_flac_common.h"
-
-#include "../log.h"
-#include "../tag.h"
-#include "../inputStream.h"
-#include "../outputBuffer.h"
-#include "../decode.h"
-#include "../replayGain.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <FLAC/format.h>
-#include <FLAC/metadata.h>
-
-void init_FlacData(FlacData * data, OutputBuffer * cb,
- DecoderControl * dc, InputStream * inStream)
-{
- data->chunk_length = 0;
- data->time = 0;
- data->position = 0;
- data->bitRate = 0;
- data->cb = cb;
- data->dc = dc;
- data->inStream = inStream;
- data->replayGainInfo = NULL;
- data->tag = NULL;
-}
-
-static int flacFindVorbisCommentFloat(const FLAC__StreamMetadata * block,
- const char *cmnt, float *fl)
-{
- int offset =
- FLAC__metadata_object_vorbiscomment_find_entry_from(block, 0, cmnt);
-
- if (offset >= 0) {
- size_t pos = strlen(cmnt) + 1; /* 1 is for '=' */
- int len = block->data.vorbis_comment.comments[offset].length
- - pos;
- if (len > 0) {
- unsigned char tmp;
- unsigned char *dup = &(block->data.vorbis_comment.
- comments[offset].entry[pos]);
- tmp = dup[len];
- dup[len] = '\0';
- *fl = atof((char *)dup);
- dup[len] = tmp;
-
- return 1;
- }
- }
-
- return 0;
-}
-
-/* replaygain stuff by AliasMrJones */
-static void flacParseReplayGain(const FLAC__StreamMetadata * block,
- FlacData * data)
-{
- int found = 0;
-
- if (data->replayGainInfo)
- freeReplayGainInfo(data->replayGainInfo);
-
- data->replayGainInfo = newReplayGainInfo();
-
- found |= flacFindVorbisCommentFloat(block, "replaygain_album_gain",
- &data->replayGainInfo->albumGain);
- found |= flacFindVorbisCommentFloat(block, "replaygain_album_peak",
- &data->replayGainInfo->albumPeak);
- found |= flacFindVorbisCommentFloat(block, "replaygain_track_gain",
- &data->replayGainInfo->trackGain);
- found |= flacFindVorbisCommentFloat(block, "replaygain_track_peak",
- &data->replayGainInfo->trackPeak);
-
- if (!found) {
- freeReplayGainInfo(data->replayGainInfo);
- data->replayGainInfo = NULL;
- }
-}
-
-/* tracknumber is used in VCs, MPD uses "track" ..., all the other
- * tag names match */
-static const char *VORBIS_COMMENT_TRACK_KEY = "tracknumber";
-static const char *VORBIS_COMMENT_DISC_KEY = "discnumber";
-
-static unsigned int commentMatchesAddToTag(const
- FLAC__StreamMetadata_VorbisComment_Entry
- * entry, unsigned int itemType,
- MpdTag ** tag)
-{
- const char *str;
- size_t slen;
- int vlen;
-
- switch (itemType) {
- case TAG_ITEM_TRACK:
- str = VORBIS_COMMENT_TRACK_KEY;
- break;
- case TAG_ITEM_DISC:
- str = VORBIS_COMMENT_DISC_KEY;
- break;
- default:
- str = mpdTagItemKeys[itemType];
- }
- slen = strlen(str);
- vlen = entry->length - slen - 1;
-
- if ((vlen > 0) && (0 == strncasecmp(str, (char *)entry->entry, slen))
- && (*(entry->entry + slen) == '=')) {
- if (!*tag)
- *tag = newMpdTag();
-
- addItemToMpdTagWithLen(*tag, itemType,
- (char *)(entry->entry + slen + 1), vlen);
-
- return 1;
- }
-
- return 0;
-}
-
-MpdTag *copyVorbisCommentBlockToMpdTag(const FLAC__StreamMetadata * block,
- MpdTag * tag)
-{
- unsigned int i, j;
- FLAC__StreamMetadata_VorbisComment_Entry *comments;
-
- comments = block->data.vorbis_comment.comments;
-
- for (i = block->data.vorbis_comment.num_comments; i != 0; --i) {
- for (j = TAG_NUM_OF_ITEM_TYPES; j--;) {
- if (commentMatchesAddToTag(comments, j, &tag))
- break;
- }
- comments++;
- }
-
- return tag;
-}
-
-void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
- FlacData * data)
-{
- DecoderControl *dc = data->dc;
- const FLAC__StreamMetadata_StreamInfo *si = &(block->data.stream_info);
-
- switch (block->type) {
- case FLAC__METADATA_TYPE_STREAMINFO:
- dc->audioFormat.bits = si->bits_per_sample;
- dc->audioFormat.sampleRate = si->sample_rate;
- dc->audioFormat.channels = si->channels;
- dc->totalTime = ((float)si->total_samples) / (si->sample_rate);
- getOutputAudioFormat(&(dc->audioFormat),
- &(data->cb->audioFormat));
- break;
- case FLAC__METADATA_TYPE_VORBIS_COMMENT:
- flacParseReplayGain(block, data);
- default:
- break;
- }
-}
-
-void flac_error_common_cb(const char *plugin,
- const FLAC__StreamDecoderErrorStatus status,
- FlacData * data)
-{
- if (data->dc->stop)
- return;
-
- switch (status) {
- case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
- ERROR("%s lost sync\n", plugin);
- break;
- case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
- ERROR("bad %s header\n", plugin);
- break;
- case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
- ERROR("%s crc mismatch\n", plugin);
- break;
- default:
- ERROR("unknown %s error\n", plugin);
- }
-}
-
-#endif /* HAVE_FLAC || HAVE_OGGFLAC */
diff --git a/trunk/src/inputPlugins/_flac_common.h b/trunk/src/inputPlugins/_flac_common.h
deleted file mode 100644
index e04e70693..000000000
--- a/trunk/src/inputPlugins/_flac_common.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * Common data structures and functions used by FLAC and OggFLAC
- * (c) 2005 by Eric Wong <normalperson@yhbt.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _FLAC_COMMON_H
-#define _FLAC_COMMON_H
-
-#include "../inputPlugin.h"
-
-#if defined(HAVE_FLAC) || defined(HAVE_OGGFLAC)
-
-#include "../tag.h"
-#include "../inputStream.h"
-#include "../outputBuffer.h"
-#include "../decode.h"
-#include <FLAC/export.h>
-#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
-# include <FLAC/seekable_stream_decoder.h>
-# define flac_decoder FLAC__SeekableStreamDecoder
-# define flac_new() FLAC__seekable_stream_decoder_new()
-
-# define flac_ogg_init(a,b,c,d,e,f,g,h,i,j) (0)
-
-# define flac_get_decode_position(x,y) \
- FLAC__seekable_stream_decoder_get_decode_position(x,y)
-# define flac_get_state(x) FLAC__seekable_stream_decoder_get_state(x)
-# define flac_process_single(x) FLAC__seekable_stream_decoder_process_single(x)
-# define flac_process_metadata(x) \
- FLAC__seekable_stream_decoder_process_until_end_of_metadata(x)
-# define flac_seek_absolute(x,y) \
- FLAC__seekable_stream_decoder_seek_absolute(x,y)
-# define flac_finish(x) FLAC__seekable_stream_decoder_finish(x)
-# define flac_delete(x) FLAC__seekable_stream_decoder_delete(x)
-
-# define flac_decoder_eof FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM
-
-typedef unsigned flac_read_status_size_t;
-# define flac_read_status FLAC__SeekableStreamDecoderReadStatus
-# define flac_read_status_continue \
- FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK
-# define flac_read_status_eof FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK
-# define flac_read_status_abort \
- FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR
-
-# define flac_seek_status FLAC__SeekableStreamDecoderSeekStatus
-# define flac_seek_status_ok FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK
-# define flac_seek_status_error FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR
-
-# define flac_tell_status FLAC__SeekableStreamDecoderTellStatus
-# define flac_tell_status_ok FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK
-# define flac_tell_status_error \
- FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR
-# define flac_tell_status_unsupported \
- FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR
-
-# define flac_length_status FLAC__SeekableStreamDecoderLengthStatus
-# define flac_length_status_ok FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK
-# define flac_length_status_error \
- FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR
-# define flac_length_status_unsupported \
- FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR
-
-# ifdef HAVE_OGGFLAC
-# include <OggFLAC/seekable_stream_decoder.h>
-# endif
-#else /* FLAC_API_VERSION_CURRENT >= 7 */
-
- /* OggFLAC support is handled by our flac_plugin already, and
- * thus we *can* always have it if libFLAC was compiled with it */
-# ifndef HAVE_OGGFLAC
-# define HAVE_OGGFLAC 1
-# endif
-# include "_ogg_common.h"
-# undef HAVE_OGGFLAC /* we don't need this defined anymore */
-
-# include <FLAC/stream_decoder.h>
-# define flac_decoder FLAC__StreamDecoder
-# define flac_new() FLAC__stream_decoder_new()
-
-# define flac_init(a,b,c,d,e,f,g,h,i,j) \
- (FLAC__stream_decoder_init_stream(a,b,c,d,e,f,g,h,i,j) \
- == FLAC__STREAM_DECODER_INIT_STATUS_OK)
-# define flac_ogg_init(a,b,c,d,e,f,g,h,i,j) \
- (FLAC__stream_decoder_init_ogg_stream(a,b,c,d,e,f,g,h,i,j) \
- == FLAC__STREAM_DECODER_INIT_STATUS_OK)
-
-# define flac_get_decode_position(x,y) \
- FLAC__stream_decoder_get_decode_position(x,y)
-# define flac_get_state(x) FLAC__stream_decoder_get_state(x)
-# define flac_process_single(x) FLAC__stream_decoder_process_single(x)
-# define flac_process_metadata(x) \
- FLAC__stream_decoder_process_until_end_of_metadata(x)
-# define flac_seek_absolute(x,y) FLAC__stream_decoder_seek_absolute(x,y)
-# define flac_finish(x) FLAC__stream_decoder_finish(x)
-# define flac_delete(x) FLAC__stream_decoder_delete(x)
-
-# define flac_decoder_eof FLAC__STREAM_DECODER_END_OF_STREAM
-
-typedef size_t flac_read_status_size_t;
-# define flac_read_status FLAC__StreamDecoderReadStatus
-# define flac_read_status_continue \
- FLAC__STREAM_DECODER_READ_STATUS_CONTINUE
-# define flac_read_status_eof FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM
-# define flac_read_status_abort FLAC__STREAM_DECODER_READ_STATUS_ABORT
-
-# define flac_seek_status FLAC__StreamDecoderSeekStatus
-# define flac_seek_status_ok FLAC__STREAM_DECODER_SEEK_STATUS_OK
-# define flac_seek_status_error FLAC__STREAM_DECODER_SEEK_STATUS_ERROR
-# define flac_seek_status_unsupported \
- FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED
-
-# define flac_tell_status FLAC__StreamDecoderTellStatus
-# define flac_tell_status_ok FLAC__STREAM_DECODER_TELL_STATUS_OK
-# define flac_tell_status_error FLAC__STREAM_DECODER_TELL_STATUS_ERROR
-# define flac_tell_status_unsupported \
- FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED
-
-# define flac_length_status FLAC__StreamDecoderLengthStatus
-# define flac_length_status_ok FLAC__STREAM_DECODER_LENGTH_STATUS_OK
-# define flac_length_status_error FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR
-# define flac_length_status_unsupported \
- FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED
-
-#endif /* FLAC_API_VERSION_CURRENT >= 7 */
-
-#include <FLAC/metadata.h>
-
-#define FLAC_CHUNK_SIZE 4080
-
-typedef struct {
- unsigned char chunk[FLAC_CHUNK_SIZE];
- int chunk_length;
- float time;
- int bitRate;
- FLAC__uint64 position;
- OutputBuffer *cb;
- DecoderControl *dc;
- InputStream *inStream;
- ReplayGainInfo *replayGainInfo;
- MpdTag *tag;
-} FlacData;
-
-/* initializes a given FlacData struct */
-void init_FlacData(FlacData * data, OutputBuffer * cb,
- DecoderControl * dc, InputStream * inStream);
-void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
- FlacData * data);
-void flac_error_common_cb(const char *plugin,
- FLAC__StreamDecoderErrorStatus status,
- FlacData * data);
-
-MpdTag *copyVorbisCommentBlockToMpdTag(const FLAC__StreamMetadata * block,
- MpdTag * tag);
-
-/* keep this inlined, this is just macro but prettier :) */
-static inline int flacSendChunk(FlacData * data)
-{
- if (sendDataToOutputBuffer(data->cb, NULL, data->dc, 1, data->chunk,
- data->chunk_length, data->time,
- data->bitRate,
- data->replayGainInfo) ==
- OUTPUT_BUFFER_DC_STOP)
- return -1;
-
- return 0;
-}
-
-#endif /* HAVE_FLAC || HAVE_OGGFLAC */
-
-#endif /* _FLAC_COMMON_H */
diff --git a/trunk/src/inputPlugins/_ogg_common.c b/trunk/src/inputPlugins/_ogg_common.c
deleted file mode 100644
index c83e46103..000000000
--- a/trunk/src/inputPlugins/_ogg_common.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * Common functions used for Ogg data streams (Ogg-Vorbis and OggFLAC)
- * (c) 2005 by Eric Wong <normalperson@yhbt.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "../inputPlugin.h"
-
-#if defined(HAVE_OGGFLAC) || defined(HAVE_OGGVORBIS)
-
-#include "../utils.h"
-#include "_ogg_common.h"
-
-#include <string.h>
-
-ogg_stream_type ogg_stream_type_detect(InputStream * inStream)
-{
- /* oggflac detection based on code in ogg123 and this post
- * http://lists.xiph.org/pipermail/flac/2004-December/000393.html
- * ogg123 trunk still doesn't have this patch as of June 2005 */
- unsigned char buf[41];
- size_t r, to_read = 41;
-
- seekInputStream(inStream, 0, SEEK_SET);
-
- while (to_read) {
- r = readFromInputStream(inStream, buf, 1, to_read);
- if (inStream->error)
- break;
- to_read -= r;
- if (!r && !inputStreamAtEOF(inStream))
- my_usleep(10000);
- else
- break;
- }
-
- seekInputStream(inStream, 0, SEEK_SET);
-
- if (r >= 32 && memcmp(buf, "OggS", 4) == 0 && ((memcmp
- (buf + 29, "FLAC",
- 4) == 0
- && memcmp(buf + 37,
- "fLaC",
- 4) == 0)
- ||
- (memcmp
- (buf + 28, "FLAC",
- 4) == 0)
- ||
- (memcmp
- (buf + 28, "fLaC",
- 4) == 0))) {
- return FLAC;
- }
- return VORBIS;
-}
-
-#endif /* defined(HAVE_OGGFLAC || defined(HAVE_OGGVORBIS) */
diff --git a/trunk/src/inputPlugins/_ogg_common.h b/trunk/src/inputPlugins/_ogg_common.h
deleted file mode 100644
index 5821e6641..000000000
--- a/trunk/src/inputPlugins/_ogg_common.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * Common functions used for Ogg data streams (Ogg-Vorbis and OggFLAC)
- * (c) 2005 by Eric Wong <normalperson@yhbt.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _OGG_COMMON_H
-#define _OGG_COMMON_H
-
-#include "../inputPlugin.h"
-
-#if defined(HAVE_OGGFLAC) || defined(HAVE_OGGVORBIS)
-
-typedef enum _ogg_stream_type { VORBIS, FLAC } ogg_stream_type;
-
-ogg_stream_type ogg_stream_type_detect(InputStream * inStream);
-
-#endif /* defined(HAVE_OGGFLAC || defined(HAVE_OGGVORBIS) */
-
-#endif /* _OGG_COMMON_H */
diff --git a/trunk/src/inputPlugins/aac_plugin.c b/trunk/src/inputPlugins/aac_plugin.c
deleted file mode 100644
index 529689706..000000000
--- a/trunk/src/inputPlugins/aac_plugin.c
+++ /dev/null
@@ -1,475 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "../inputPlugin.h"
-
-#ifdef HAVE_FAAD
-
-#define AAC_MAX_CHANNELS 6
-
-#include "../utils.h"
-#include "../audio.h"
-#include "../log.h"
-#include "../inputStream.h"
-#include "../outputBuffer.h"
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <faad.h>
-
-/* all code here is either based on or copied from FAAD2's frontend code */
-typedef struct {
- InputStream *inStream;
- long bytesIntoBuffer;
- long bytesConsumed;
- long fileOffset;
- unsigned char *buffer;
- int atEof;
-} AacBuffer;
-
-static void fillAacBuffer(AacBuffer * b)
-{
- if (b->bytesConsumed > 0) {
- int bread;
-
- if (b->bytesIntoBuffer) {
- memmove((void *)b->buffer, (void *)(b->buffer +
- b->bytesConsumed),
- b->bytesIntoBuffer);
- }
-
- if (!b->atEof) {
- bread = readFromInputStream(b->inStream,
- (void *)(b->buffer +
- b->
- bytesIntoBuffer),
- 1, b->bytesConsumed);
- if (bread != b->bytesConsumed)
- b->atEof = 1;
- b->bytesIntoBuffer += bread;
- }
-
- b->bytesConsumed = 0;
-
- if (b->bytesIntoBuffer > 3) {
- if (memcmp(b->buffer, "TAG", 3) == 0)
- b->bytesIntoBuffer = 0;
- }
- if (b->bytesIntoBuffer > 11) {
- if (memcmp(b->buffer, "LYRICSBEGIN", 11) == 0) {
- b->bytesIntoBuffer = 0;
- }
- }
- if (b->bytesIntoBuffer > 8) {
- if (memcmp(b->buffer, "APETAGEX", 8) == 0) {
- b->bytesIntoBuffer = 0;
- }
- }
- }
-}
-
-static void advanceAacBuffer(AacBuffer * b, int bytes)
-{
- b->fileOffset += bytes;
- b->bytesConsumed = bytes;
- b->bytesIntoBuffer -= bytes;
-}
-
-static int adtsSampleRates[] =
- { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
- 16000, 12000, 11025, 8000, 7350, 0, 0, 0
-};
-
-static int adtsParse(AacBuffer * b, float *length)
-{
- int frames, frameLength;
- int tFrameLength = 0;
- int sampleRate = 0;
- float framesPerSec, bytesPerFrame;
-
- /* Read all frames to ensure correct time and bitrate */
- for (frames = 0;; frames++) {
- fillAacBuffer(b);
-
- if (b->bytesIntoBuffer > 7) {
- /* check syncword */
- if (!((b->buffer[0] == 0xFF) &&
- ((b->buffer[1] & 0xF6) == 0xF0))) {
- break;
- }
-
- if (frames == 0) {
- sampleRate = adtsSampleRates[(b->
- buffer[2] & 0x3c)
- >> 2];
- }
-
- frameLength = ((((unsigned int)b->buffer[3] & 0x3))
- << 11) | (((unsigned int)b->buffer[4])
- << 3) | (b->buffer[5] >> 5);
-
- tFrameLength += frameLength;
-
- if (frameLength > b->bytesIntoBuffer)
- break;
-
- advanceAacBuffer(b, frameLength);
- } else
- break;
- }
-
- framesPerSec = (float)sampleRate / 1024.0;
- if (frames != 0) {
- bytesPerFrame = (float)tFrameLength / (float)(frames * 1000);
- } else
- bytesPerFrame = 0;
- if (framesPerSec != 0)
- *length = (float)frames / framesPerSec;
-
- return 1;
-}
-
-static void initAacBuffer(InputStream * inStream, AacBuffer * b, float *length,
- size_t * retFileread, size_t * retTagsize)
-{
- size_t fileread;
- size_t bread;
- size_t tagsize;
-
- if (length)
- *length = -1;
-
- memset(b, 0, sizeof(AacBuffer));
-
- b->inStream = inStream;
-
- fileread = inStream->size;
-
- b->buffer = xmalloc(FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS);
- memset(b->buffer, 0, FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS);
-
- bread = readFromInputStream(inStream, b->buffer, 1,
- FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS);
- b->bytesIntoBuffer = bread;
- b->bytesConsumed = 0;
- b->fileOffset = 0;
-
- if (bread != FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS)
- b->atEof = 1;
-
- tagsize = 0;
- if (!memcmp(b->buffer, "ID3", 3)) {
- tagsize = (b->buffer[6] << 21) | (b->buffer[7] << 14) |
- (b->buffer[8] << 7) | (b->buffer[9] << 0);
-
- tagsize += 10;
- advanceAacBuffer(b, tagsize);
- fillAacBuffer(b);
- }
-
- if (retFileread)
- *retFileread = fileread;
- if (retTagsize)
- *retTagsize = tagsize;
-
- if (length == NULL)
- return;
-
- if ((b->buffer[0] == 0xFF) && ((b->buffer[1] & 0xF6) == 0xF0)) {
- adtsParse(b, length);
- seekInputStream(b->inStream, tagsize, SEEK_SET);
-
- bread = readFromInputStream(b->inStream, b->buffer, 1,
- FAAD_MIN_STREAMSIZE *
- AAC_MAX_CHANNELS);
- if (bread != FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS)
- b->atEof = 1;
- else
- b->atEof = 0;
- b->bytesIntoBuffer = bread;
- b->bytesConsumed = 0;
- b->fileOffset = tagsize;
- } else if (memcmp(b->buffer, "ADIF", 4) == 0) {
- int bitRate;
- int skipSize = (b->buffer[4] & 0x80) ? 9 : 0;
- bitRate =
- ((unsigned int)(b->
- buffer[4 +
- skipSize] & 0x0F) << 19) | ((unsigned
- int)b->
- buffer[5
- +
- skipSize]
- << 11) |
- ((unsigned int)b->
- buffer[6 + skipSize] << 3) | ((unsigned int)b->buffer[7 +
- skipSize]
- & 0xE0);
-
- if (fileread != 0 && bitRate != 0)
- *length = fileread * 8.0 / bitRate;
- else
- *length = fileread;
- }
-}
-
-static float getAacFloatTotalTime(char *file)
-{
- AacBuffer b;
- float length;
- size_t fileread, tagsize;
- faacDecHandle decoder;
- faacDecConfigurationPtr config;
- unsigned long sampleRate;
- unsigned char channels;
- InputStream inStream;
- long bread;
-
- if (openInputStream(&inStream, file) < 0)
- return -1;
-
- initAacBuffer(&inStream, &b, &length, &fileread, &tagsize);
-
- if (length < 0) {
- decoder = faacDecOpen();
-
- config = faacDecGetCurrentConfiguration(decoder);
- config->outputFormat = FAAD_FMT_16BIT;
- faacDecSetConfiguration(decoder, config);
-
- fillAacBuffer(&b);
-#ifdef HAVE_FAAD_BUFLEN_FUNCS
- bread = faacDecInit(decoder, b.buffer, b.bytesIntoBuffer,
- &sampleRate, &channels);
-#else
- bread = faacDecInit(decoder, b.buffer, &sampleRate, &channels);
-#endif
- if (bread >= 0 && sampleRate > 0 && channels > 0)
- length = 0;
-
- faacDecClose(decoder);
- }
-
- if (b.buffer)
- free(b.buffer);
- closeInputStream(&inStream);
-
- return length;
-}
-
-static int getAacTotalTime(char *file)
-{
- int time = -1;
- float length;
-
- if ((length = getAacFloatTotalTime(file)) >= 0)
- time = length + 0.5;
-
- return time;
-}
-
-static int aac_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
-{
- float time;
- float totalTime;
- faacDecHandle decoder;
- faacDecFrameInfo frameInfo;
- faacDecConfigurationPtr config;
- long bread;
- unsigned long sampleRate;
- unsigned char channels;
- int eof = 0;
- unsigned int sampleCount;
- char *sampleBuffer;
- size_t sampleBufferLen;
- /*float * seekTable;
- long seekTableEnd = -1;
- int seekPositionFound = 0; */
- mpd_uint16 bitRate = 0;
- AacBuffer b;
- InputStream inStream;
-
- if ((totalTime = getAacFloatTotalTime(path)) < 0)
- return -1;
-
- if (openInputStream(&inStream, path) < 0)
- return -1;
-
- initAacBuffer(&inStream, &b, NULL, NULL, NULL);
-
- decoder = faacDecOpen();
-
- config = faacDecGetCurrentConfiguration(decoder);
- config->outputFormat = FAAD_FMT_16BIT;
-#ifdef HAVE_FAACDECCONFIGURATION_DOWNMATRIX
- config->downMatrix = 1;
-#endif
-#ifdef HAVE_FAACDECCONFIGURATION_DONTUPSAMPLEIMPLICITSBR
- config->dontUpSampleImplicitSBR = 0;
-#endif
- faacDecSetConfiguration(decoder, config);
-
- fillAacBuffer(&b);
-
-#ifdef HAVE_FAAD_BUFLEN_FUNCS
- bread = faacDecInit(decoder, b.buffer, b.bytesIntoBuffer,
- &sampleRate, &channels);
-#else
- bread = faacDecInit(decoder, b.buffer, &sampleRate, &channels);
-#endif
- if (bread < 0) {
- ERROR("Error not a AAC stream.\n");
- faacDecClose(decoder);
- closeInputStream(b.inStream);
- if (b.buffer)
- free(b.buffer);
- return -1;
- }
-
- dc->audioFormat.bits = 16;
-
- dc->totalTime = totalTime;
-
- time = 0.0;
-
- advanceAacBuffer(&b, bread);
-
- while (!eof) {
- fillAacBuffer(&b);
-
- if (b.bytesIntoBuffer == 0) {
- eof = 1;
- break;
- }
-#ifdef HAVE_FAAD_BUFLEN_FUNCS
- sampleBuffer = faacDecDecode(decoder, &frameInfo, b.buffer,
- b.bytesIntoBuffer);
-#else
- sampleBuffer = faacDecDecode(decoder, &frameInfo, b.buffer);
-#endif
-
- if (frameInfo.error > 0) {
- ERROR("error decoding AAC file: %s\n", path);
- ERROR("faad2 error: %s\n",
- faacDecGetErrorMessage(frameInfo.error));
- eof = 1;
- break;
- }
-#ifdef HAVE_FAACDECFRAMEINFO_SAMPLERATE
- sampleRate = frameInfo.samplerate;
-#endif
-
- if (dc->state != DECODE_STATE_DECODE) {
- dc->audioFormat.channels = frameInfo.channels;
- dc->audioFormat.sampleRate = sampleRate;
- getOutputAudioFormat(&(dc->audioFormat),
- &(cb->audioFormat));
- dc->state = DECODE_STATE_DECODE;
- }
-
- advanceAacBuffer(&b, frameInfo.bytesconsumed);
-
- sampleCount = (unsigned long)(frameInfo.samples);
-
- if (sampleCount > 0) {
- bitRate = frameInfo.bytesconsumed * 8.0 *
- frameInfo.channels * sampleRate /
- frameInfo.samples / 1000 + 0.5;
- time +=
- (float)(frameInfo.samples) / frameInfo.channels /
- sampleRate;
- }
-
- sampleBufferLen = sampleCount * 2;
-
- sendDataToOutputBuffer(cb, NULL, dc, 0, sampleBuffer,
- sampleBufferLen, time, bitRate, NULL);
- if (dc->seek) {
- dc->seekError = 1;
- dc->seek = 0;
- } else if (dc->stop) {
- eof = 1;
- break;
- }
- }
-
- flushOutputBuffer(cb);
-
- faacDecClose(decoder);
- closeInputStream(b.inStream);
- if (b.buffer)
- free(b.buffer);
-
- if (dc->state != DECODE_STATE_DECODE)
- return -1;
-
- if (dc->seek) {
- dc->seekError = 1;
- dc->seek = 0;
- }
-
- if (dc->stop) {
- dc->state = DECODE_STATE_STOP;
- dc->stop = 0;
- } else
- dc->state = DECODE_STATE_STOP;
-
- return 0;
-}
-
-static MpdTag *aacTagDup(char *file)
-{
- MpdTag *ret = NULL;
- int time;
-
- time = getAacTotalTime(file);
-
- if (time >= 0) {
- if ((ret = id3Dup(file)) == NULL)
- ret = newMpdTag();
- ret->time = time;
- } else {
- DEBUG("aacTagDup: Failed to get total song time from: %s\n",
- file);
- }
-
- return ret;
-}
-
-static char *aacSuffixes[] = { "aac", NULL };
-
-InputPlugin aacPlugin = {
- "aac",
- NULL,
- NULL,
- NULL,
- NULL,
- aac_decode,
- aacTagDup,
- INPUT_PLUGIN_STREAM_FILE,
- aacSuffixes,
- NULL
-};
-
-#else
-
-InputPlugin aacPlugin;
-
-#endif /* HAVE_FAAD */
diff --git a/trunk/src/inputPlugins/audiofile_plugin.c b/trunk/src/inputPlugins/audiofile_plugin.c
deleted file mode 100644
index 35fb48b8a..000000000
--- a/trunk/src/inputPlugins/audiofile_plugin.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * libaudiofile (wave) support added by Eric Wong <normalperson@yhbt.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "../inputPlugin.h"
-
-#ifdef HAVE_AUDIOFILE
-
-#include "../utils.h"
-#include "../audio.h"
-#include "../log.h"
-#include "../pcm_utils.h"
-#include "../playerData.h"
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <audiofile.h>
-
-static int getAudiofileTotalTime(char *file)
-{
- int time;
- AFfilehandle af_fp = afOpenFile(file, "r", NULL);
- if (af_fp == AF_NULL_FILEHANDLE) {
- return -1;
- }
- time = (int)
- ((double)afGetFrameCount(af_fp, AF_DEFAULT_TRACK)
- / afGetRate(af_fp, AF_DEFAULT_TRACK));
- afCloseFile(af_fp);
- return time;
-}
-
-static int audiofile_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
-{
- int fs, frame_count;
- AFfilehandle af_fp;
- int bits;
- mpd_uint16 bitRate;
- struct stat st;
-
- if (stat(path, &st) < 0) {
- ERROR("failed to stat: %s\n", path);
- return -1;
- }
-
- af_fp = afOpenFile(path, "r", NULL);
- if (af_fp == AF_NULL_FILEHANDLE) {
- ERROR("failed to open: %s\n", path);
- return -1;
- }
-
- afSetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK,
- AF_SAMPFMT_TWOSCOMP, 16);
- afGetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits);
- dc->audioFormat.bits = bits;
- dc->audioFormat.sampleRate = afGetRate(af_fp, AF_DEFAULT_TRACK);
- dc->audioFormat.channels = afGetVirtualChannels(af_fp, AF_DEFAULT_TRACK);
- getOutputAudioFormat(&(dc->audioFormat), &(cb->audioFormat));
-
- frame_count = afGetFrameCount(af_fp, AF_DEFAULT_TRACK);
-
- dc->totalTime =
- ((float)frame_count / (float)dc->audioFormat.sampleRate);
-
- bitRate = st.st_size * 8.0 / dc->totalTime / 1000.0 + 0.5;
-
- if (dc->audioFormat.bits != 8 && dc->audioFormat.bits != 16) {
- ERROR("Only 8 and 16-bit files are supported. %s is %i-bit\n",
- path, dc->audioFormat.bits);
- afCloseFile(af_fp);
- return -1;
- }
-
- fs = (int)afGetVirtualFrameSize(af_fp, AF_DEFAULT_TRACK, 1);
-
- dc->state = DECODE_STATE_DECODE;
- {
- int ret, eof = 0, current = 0;
- char chunk[CHUNK_SIZE];
-
- while (!eof) {
- if (dc->seek) {
- clearOutputBuffer(cb);
- current = dc->seekWhere *
- dc->audioFormat.sampleRate;
- afSeekFrame(af_fp, AF_DEFAULT_TRACK, current);
- dc->seek = 0;
- }
-
- ret =
- afReadFrames(af_fp, AF_DEFAULT_TRACK, chunk,
- CHUNK_SIZE / fs);
- if (ret <= 0)
- eof = 1;
- else {
- current += ret;
- sendDataToOutputBuffer(cb,
- NULL,
- dc,
- 1,
- chunk,
- ret * fs,
- (float)current /
- (float)dc->audioFormat.
- sampleRate, bitRate,
- NULL);
- if (dc->stop)
- break;
- }
- }
-
- flushOutputBuffer(cb);
-
- /*if(dc->seek) {
- dc->seekError = 1;
- dc->seek = 0;
- } */
-
- if (dc->stop) {
- dc->state = DECODE_STATE_STOP;
- dc->stop = 0;
- } else
- dc->state = DECODE_STATE_STOP;
- }
- afCloseFile(af_fp);
-
- return 0;
-}
-
-static MpdTag *audiofileTagDup(char *file)
-{
- MpdTag *ret = NULL;
- int time = getAudiofileTotalTime(file);
-
- if (time >= 0) {
- if (!ret)
- ret = newMpdTag();
- ret->time = time;
- } else {
- DEBUG
- ("audiofileTagDup: Failed to get total song time from: %s\n",
- file);
- }
-
- return ret;
-}
-
-static char *audiofileSuffixes[] = { "wav", "au", "aiff", "aif", NULL };
-
-InputPlugin audiofilePlugin = {
- "audiofile",
- NULL,
- NULL,
- NULL,
- NULL,
- audiofile_decode,
- audiofileTagDup,
- INPUT_PLUGIN_STREAM_FILE,
- audiofileSuffixes,
- NULL
-};
-
-#else
-
-InputPlugin audiofilePlugin;
-
-#endif /* HAVE_AUDIOFILE */
diff --git a/trunk/src/inputPlugins/flac_plugin.c b/trunk/src/inputPlugins/flac_plugin.c
deleted file mode 100644
index 3f3a4b4f1..000000000
--- a/trunk/src/inputPlugins/flac_plugin.c
+++ /dev/null
@@ -1,530 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "_flac_common.h"
-
-#ifdef HAVE_FLAC
-
-#include "../utils.h"
-#include "../log.h"
-#include "../pcm_utils.h"
-#include "../inputStream.h"
-#include "../outputBuffer.h"
-#include "../replayGain.h"
-#include "../audio.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <assert.h>
-
-/* this code was based on flac123, from flac-tools */
-
-static flac_read_status flacRead(const flac_decoder * flacDec,
- FLAC__byte buf[],
- flac_read_status_size_t *bytes,
- void *fdata)
-{
- FlacData *data = (FlacData *) fdata;
- size_t r;
-
- while (1) {
- r = readFromInputStream(data->inStream, (void *)buf, 1, *bytes);
- if (r == 0 && !inputStreamAtEOF(data->inStream) &&
- !data->dc->stop)
- my_usleep(10000);
- else
- break;
- }
- *bytes = r;
-
- if (r == 0 && !data->dc->stop) {
- if (inputStreamAtEOF(data->inStream))
- return flac_read_status_eof;
- else
- return flac_read_status_abort;
- }
- return flac_read_status_continue;
-}
-
-static flac_seek_status flacSeek(const flac_decoder * flacDec,
- FLAC__uint64 offset,
- void *fdata)
-{
- FlacData *data = (FlacData *) fdata;
-
- if (seekInputStream(data->inStream, offset, SEEK_SET) < 0) {
- return flac_seek_status_error;
- }
-
- return flac_seek_status_ok;
-}
-
-static flac_tell_status flacTell(const flac_decoder * flacDec,
- FLAC__uint64 * offset,
- void *fdata)
-{
- FlacData *data = (FlacData *) fdata;
-
- *offset = (long)(data->inStream->offset);
-
- return flac_tell_status_ok;
-}
-
-static flac_length_status flacLength(const flac_decoder * flacDec,
- FLAC__uint64 * length,
- void *fdata)
-{
- FlacData *data = (FlacData *) fdata;
-
- *length = (size_t) (data->inStream->size);
-
- return flac_length_status_ok;
-}
-
-static FLAC__bool flacEOF(const flac_decoder * flacDec, void *fdata)
-{
- FlacData *data = (FlacData *) fdata;
-
- if (inputStreamAtEOF(data->inStream) == 1)
- return true;
- return false;
-}
-
-static void flacError(const flac_decoder *dec,
- FLAC__StreamDecoderErrorStatus status, void *fdata)
-{
- flac_error_common_cb("flac", status, (FlacData *) fdata);
-}
-
-#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
-static void flacPrintErroredState(FLAC__SeekableStreamDecoderState state)
-{
- const char *str = ""; /* "" to silence compiler warning */
- switch (state) {
- case FLAC__SEEKABLE_STREAM_DECODER_OK:
- case FLAC__SEEKABLE_STREAM_DECODER_SEEKING:
- case FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM:
- return;
- case FLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
- str = "allocation error";
- break;
- case FLAC__SEEKABLE_STREAM_DECODER_READ_ERROR:
- str = "read error";
- break;
- case FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR:
- str = "seek error";
- break;
- case FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR:
- str = "seekable stream error";
- break;
- case FLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED:
- str = "decoder already initialized";
- break;
- case FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK:
- str = "invalid callback";
- break;
- case FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED:
- str = "decoder uninitialized";
- }
- ERROR("flac %s\n", str);
-}
-
-static int flac_init(FLAC__SeekableStreamDecoder *dec,
- FLAC__SeekableStreamDecoderReadCallback read_cb,
- FLAC__SeekableStreamDecoderSeekCallback seek_cb,
- FLAC__SeekableStreamDecoderTellCallback tell_cb,
- FLAC__SeekableStreamDecoderLengthCallback length_cb,
- FLAC__SeekableStreamDecoderEofCallback eof_cb,
- FLAC__SeekableStreamDecoderWriteCallback write_cb,
- FLAC__SeekableStreamDecoderMetadataCallback metadata_cb,
- FLAC__SeekableStreamDecoderErrorCallback error_cb,
- void *data)
-{
- int s = 1;
- s &= FLAC__seekable_stream_decoder_set_read_callback(dec, read_cb);
- s &= FLAC__seekable_stream_decoder_set_seek_callback(dec, seek_cb);
- s &= FLAC__seekable_stream_decoder_set_tell_callback(dec, tell_cb);
- s &= FLAC__seekable_stream_decoder_set_length_callback(dec, length_cb);
- s &= FLAC__seekable_stream_decoder_set_eof_callback(dec, eof_cb);
- s &= FLAC__seekable_stream_decoder_set_write_callback(dec, write_cb);
- s &= FLAC__seekable_stream_decoder_set_metadata_callback(dec,
- metadata_cb);
- s &= FLAC__seekable_stream_decoder_set_metadata_respond(dec,
- FLAC__METADATA_TYPE_VORBIS_COMMENT);
- s &= FLAC__seekable_stream_decoder_set_error_callback(dec, error_cb);
- s &= FLAC__seekable_stream_decoder_set_client_data(dec, data);
- if (!s || (FLAC__seekable_stream_decoder_init(dec) !=
- FLAC__SEEKABLE_STREAM_DECODER_OK))
- return 0;
- return 1;
-}
-#else /* FLAC_API_VERSION_CURRENT >= 7 */
-static void flacPrintErroredState(FLAC__StreamDecoderState state)
-{
- const char *str = ""; /* "" to silence compiler warning */
- switch (state) {
- case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
- case FLAC__STREAM_DECODER_READ_METADATA:
- case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
- case FLAC__STREAM_DECODER_READ_FRAME:
- case FLAC__STREAM_DECODER_END_OF_STREAM:
- return;
- case FLAC__STREAM_DECODER_OGG_ERROR:
- str = "error in the Ogg layer";
- break;
- case FLAC__STREAM_DECODER_SEEK_ERROR:
- str = "seek error";
- break;
- case FLAC__STREAM_DECODER_ABORTED:
- str = "decoder aborted by read";
- break;
- case FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
- str = "allocation error";
- break;
- case FLAC__STREAM_DECODER_UNINITIALIZED:
- str = "decoder uninitialized";
- }
- ERROR("flac %s\n", str);
-}
-#endif /* FLAC_API_VERSION_CURRENT >= 7 */
-
-static void flacMetadata(const flac_decoder * dec,
- const FLAC__StreamMetadata * block, void *vdata)
-{
- flac_metadata_common_cb(block, (FlacData *) vdata);
-}
-
-static FLAC__StreamDecoderWriteStatus flacWrite(const flac_decoder *dec,
- const FLAC__Frame * frame,
- const FLAC__int32 * const buf[],
- void *vdata)
-{
- FlacData *data = (FlacData *) vdata;
- FLAC__uint32 samples = frame->header.blocksize;
- FLAC__uint16 u16;
- unsigned char *uc;
- int c_samp, c_chan, d_samp;
- int i;
- float timeChange;
- FLAC__uint64 newPosition = 0;
-
- timeChange = ((float)samples) / frame->header.sample_rate;
- data->time += timeChange;
-
- flac_get_decode_position(dec, &newPosition);
- if (data->position) {
- data->bitRate =
- ((newPosition - data->position) * 8.0 / timeChange)
- / 1000 + 0.5;
- }
- data->position = newPosition;
-
- for (c_samp = d_samp = 0; c_samp < frame->header.blocksize; c_samp++) {
- for (c_chan = 0; c_chan < frame->header.channels;
- c_chan++, d_samp++) {
- u16 = buf[c_chan][c_samp];
- uc = (unsigned char *)&u16;
- for (i = 0; i < (data->dc->audioFormat.bits / 8); i++) {
- if (data->chunk_length >= FLAC_CHUNK_SIZE) {
- if (flacSendChunk(data) < 0) {
- return
- FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
- }
- data->chunk_length = 0;
- if (data->dc->seek) {
- return
- FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
- }
- }
- data->chunk[data->chunk_length++] = *(uc++);
- }
- }
- }
-
- return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
-}
-
-static MpdTag *flacMetadataDup(char *file, int *vorbisCommentFound)
-{
- MpdTag *ret = NULL;
- FLAC__Metadata_SimpleIterator *it;
- FLAC__StreamMetadata *block = NULL;
-
- *vorbisCommentFound = 0;
-
- it = FLAC__metadata_simple_iterator_new();
- if (!FLAC__metadata_simple_iterator_init(it, file, 1, 0)) {
- switch (FLAC__metadata_simple_iterator_status(it)) {
- case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT:
- DEBUG
- ("flacMetadataDup: Reading '%s' metadata gave the following error: Illegal Input\n",
- file);
- break;
- case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE:
- DEBUG
- ("flacMetadataDup: Reading '%s' metadata gave the following error: Error Opening File\n",
- file);
- break;
- case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE:
- DEBUG
- ("flacMetadataDup: Reading '%s' metadata gave the following error: Not A Flac File\n",
- file);
- break;
- default:
- DEBUG("flacMetadataDup: Reading '%s' metadata failed\n",
- file);
- }
- FLAC__metadata_simple_iterator_delete(it);
- return ret;
- }
-
- do {
- block = FLAC__metadata_simple_iterator_get_block(it);
- if (!block)
- break;
- if (block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
- ret = copyVorbisCommentBlockToMpdTag(block, ret);
-
- if (ret)
- *vorbisCommentFound = 1;
- } else if (block->type == FLAC__METADATA_TYPE_STREAMINFO) {
- if (!ret)
- ret = newMpdTag();
- ret->time = ((float)block->data.stream_info.
- total_samples) /
- block->data.stream_info.sample_rate + 0.5;
- }
- FLAC__metadata_object_delete(block);
- } while (FLAC__metadata_simple_iterator_next(it));
-
- FLAC__metadata_simple_iterator_delete(it);
- return ret;
-}
-
-static MpdTag *flacTagDup(char *file)
-{
- MpdTag *ret = NULL;
- int foundVorbisComment = 0;
-
- ret = flacMetadataDup(file, &foundVorbisComment);
- if (!ret) {
- DEBUG("flacTagDup: Failed to grab information from: %s\n",
- file);
- return NULL;
- }
- if (!foundVorbisComment) {
- MpdTag *temp = id3Dup(file);
- if (temp) {
- temp->time = ret->time;
- freeMpdTag(ret);
- ret = temp;
- }
- }
-
- return ret;
-}
-
-static int flac_decode_internal(OutputBuffer * cb, DecoderControl * dc,
- InputStream * inStream, int is_ogg)
-{
- flac_decoder *flacDec;
- FlacData data;
- const char *err = NULL;
-
- if (!(flacDec = flac_new()))
- return -1;
- init_FlacData(&data, cb, dc, inStream);
- if (is_ogg) {
- if (!flac_ogg_init(flacDec, flacRead, flacSeek, flacTell,
- flacLength, flacEOF, flacWrite, flacMetadata,
- flacError, (void *)&data)) {
- err = "doing Ogg init()";
- goto fail;
- }
- } else {
- if (!flac_init(flacDec, flacRead, flacSeek, flacTell,
- flacLength, flacEOF, flacWrite, flacMetadata,
- flacError, (void *)&data)) {
- err = "doing init()";
- goto fail;
- }
- if (!flac_process_metadata(flacDec)) {
- err = "problem reading metadata";
- goto fail;
- }
- }
-
- dc->state = DECODE_STATE_DECODE;
-
- while (1) {
- if (!flac_process_single(flacDec))
- break;
- if (flac_get_state(flacDec) == flac_decoder_eof)
- break;
- if (dc->seek) {
- FLAC__uint64 sampleToSeek = dc->seekWhere *
- dc->audioFormat.sampleRate + 0.5;
- if (flac_seek_absolute(flacDec, sampleToSeek)) {
- clearOutputBuffer(cb);
- data.time = ((float)sampleToSeek) /
- dc->audioFormat.sampleRate;
- data.position = 0;
- } else
- dc->seekError = 1;
- dc->seek = 0;
- }
- }
- if (!dc->stop) {
- flacPrintErroredState(flac_get_state(flacDec));
- flac_finish(flacDec);
- }
- /* send last little bit */
- if (data.chunk_length > 0 && !dc->stop) {
- flacSendChunk(&data);
- flushOutputBuffer(data.cb);
- }
-
- /*if(dc->seek) {
- dc->seekError = 1;
- dc->seek = 0;
- } */
-
- dc->state = DECODE_STATE_STOP;
- dc->stop = 0;
-
-fail:
- if (data.replayGainInfo)
- freeReplayGainInfo(data.replayGainInfo);
-
- if (flacDec)
- flac_delete(flacDec);
-
- closeInputStream(inStream);
-
- if (err) {
- ERROR("flac %s\n", err);
- return -1;
- }
- return 0;
-}
-
-static int flac_decode(OutputBuffer * cb, DecoderControl * dc,
- InputStream * inStream)
-{
- return flac_decode_internal(cb, dc, inStream, 0);
-}
-
-#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
-# define flac_plugin_init NULL
-#else /* FLAC_API_VERSION_CURRENT >= 7 */
-/* some of this stuff is duplicated from oggflac_plugin.c */
-extern InputPlugin oggflacPlugin;
-
-static MpdTag *oggflac_tag_dup(char *file)
-{
- MpdTag *ret = NULL;
- FLAC__Metadata_Iterator *it;
- FLAC__StreamMetadata *block;
- FLAC__Metadata_Chain *chain = FLAC__metadata_chain_new();
-
- if (!(FLAC__metadata_chain_read_ogg(chain, file)))
- goto out;
- it = FLAC__metadata_iterator_new();
- FLAC__metadata_iterator_init(it, chain);
- do {
- if (!(block = FLAC__metadata_iterator_get_block(it)))
- break;
- if (block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
- ret = copyVorbisCommentBlockToMpdTag(block, ret);
- } else if (block->type == FLAC__METADATA_TYPE_STREAMINFO) {
- if (!ret)
- ret = newMpdTag();
- ret->time = ((float)block->data.stream_info.
- total_samples) /
- block->data.stream_info.sample_rate + 0.5;
- }
- } while (FLAC__metadata_iterator_next(it));
- FLAC__metadata_iterator_delete(it);
-out:
- FLAC__metadata_chain_delete(chain);
- return ret;
-}
-
-static int oggflac_decode(OutputBuffer * cb, DecoderControl * dc,
- InputStream * inStream)
-{
- return flac_decode_internal(cb, dc, inStream, 1);
-}
-
-static unsigned int oggflac_try_decode(InputStream * inStream)
-{
- return (ogg_stream_type_detect(inStream) == FLAC) ? 1 : 0;
-}
-
-static char *oggflac_suffixes[] = { "ogg", NULL };
-static char *oggflac_mime_types[] = { "audio/x-flac+ogg",
- "application/ogg",
- "application/x-ogg",
- NULL };
-
-static int flac_plugin_init(void)
-{
- if (!FLAC_API_SUPPORTS_OGG_FLAC) {
- DEBUG("libFLAC does not support OggFLAC\n");
- return 1;
- }
- DEBUG("libFLAC supports OggFLAC, initializing OggFLAC support\n");
- assert(oggflacPlugin.name == NULL);
- oggflacPlugin.name = "oggflac";
- oggflacPlugin.tryDecodeFunc = oggflac_try_decode;
- oggflacPlugin.streamDecodeFunc = oggflac_decode;
- oggflacPlugin.tagDupFunc = oggflac_tag_dup;
- oggflacPlugin.streamTypes = INPUT_PLUGIN_STREAM_URL |
- INPUT_PLUGIN_STREAM_FILE;
- oggflacPlugin.suffixes = oggflac_suffixes;
- oggflacPlugin.mimeTypes = oggflac_mime_types;
- loadInputPlugin(&oggflacPlugin);
- return 1;
-}
-
-#endif /* FLAC_API_VERSION_CURRENT >= 7 */
-
-static char *flacSuffixes[] = { "flac", NULL };
-static char *flac_mime_types[] = { "audio/x-flac",
- "application/x-flac",
- NULL };
-
-InputPlugin flacPlugin = {
- "flac",
- flac_plugin_init,
- NULL,
- NULL,
- flac_decode,
- NULL,
- flacTagDup,
- INPUT_PLUGIN_STREAM_URL | INPUT_PLUGIN_STREAM_FILE,
- flacSuffixes,
- flac_mime_types
-};
-
-#else /* !HAVE_FLAC */
-
-InputPlugin flacPlugin;
-
-#endif /* HAVE_FLAC */
diff --git a/trunk/src/inputPlugins/mod_plugin.c b/trunk/src/inputPlugins/mod_plugin.c
deleted file mode 100644
index 800abc95f..000000000
--- a/trunk/src/inputPlugins/mod_plugin.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "../inputPlugin.h"
-
-#ifdef HAVE_MIKMOD
-
-#include "../utils.h"
-#include "../audio.h"
-#include "../log.h"
-#include "../pcm_utils.h"
-#include "../playerData.h"
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <mikmod.h>
-
-/* this is largely copied from alsaplayer */
-
-#define MIKMOD_FRAME_SIZE 4096
-
-static BOOL mod_mpd_Init(void)
-{
- return VC_Init();
-}
-
-static void mod_mpd_Exit(void)
-{
- VC_Exit();
-}
-
-static void mod_mpd_Update(void)
-{
-}
-
-static BOOL mod_mpd_IsThere(void)
-{
- return 1;
-}
-
-static MDRIVER drv_mpd = {
- NULL,
- "MPD",
- "MPD Output Driver v0.1",
- 0,
- 255,
-#if (LIBMIKMOD_VERSION > 0x030106)
- "mpd", /* Alias */
-#if (LIBMIKMOD_VERSION > 0x030200)
- NULL, /* CmdLineHelp */
-#endif
- NULL, /* CommandLine */
-#endif
- mod_mpd_IsThere,
- VC_SampleLoad,
- VC_SampleUnload,
- VC_SampleSpace,
- VC_SampleLength,
- mod_mpd_Init,
- mod_mpd_Exit,
- NULL,
- VC_SetNumVoices,
- VC_PlayStart,
- VC_PlayStop,
- mod_mpd_Update,
- NULL,
- VC_VoiceSetVolume,
- VC_VoiceGetVolume,
- VC_VoiceSetFrequency,
- VC_VoiceGetFrequency,
- VC_VoiceSetPanning,
- VC_VoiceGetPanning,
- VC_VoicePlay,
- VC_VoiceStop,
- VC_VoiceStopped,
- VC_VoiceGetPosition,
- VC_VoiceRealVolume
-};
-
-static int mod_mikModInitiated;
-static int mod_mikModInitError;
-
-static int mod_initMikMod(void)
-{
- if (mod_mikModInitError)
- return -1;
-
- if (!mod_mikModInitiated) {
- mod_mikModInitiated = 1;
-
- md_device = 0;
- md_reverb = 0;
-
- MikMod_RegisterDriver(&drv_mpd);
- MikMod_RegisterAllLoaders();
- }
-
- md_pansep = 64;
- md_mixfreq = 44100;
- md_mode = (DMODE_SOFT_MUSIC | DMODE_INTERP | DMODE_STEREO |
- DMODE_16BITS);
-
- if (MikMod_Init("")) {
- ERROR("Could not init MikMod: %s\n",
- MikMod_strerror(MikMod_errno));
- mod_mikModInitError = 1;
- return -1;
- }
-
- return 0;
-}
-
-static void mod_finishMikMod(void)
-{
- MikMod_Exit();
-}
-
-typedef struct _mod_Data {
- MODULE *moduleHandle;
- SBYTE *audio_buffer;
-} mod_Data;
-
-static mod_Data *mod_open(char *path)
-{
- MODULE *moduleHandle;
- mod_Data *data;
-
- if (!(moduleHandle = Player_Load(path, 128, 0)))
- return NULL;
-
- /* Prevent module from looping forever */
- moduleHandle->loop = 0;
-
- data = xmalloc(sizeof(mod_Data));
-
- data->audio_buffer = xmalloc(MIKMOD_FRAME_SIZE);
- data->moduleHandle = moduleHandle;
-
- Player_Start(data->moduleHandle);
-
- return data;
-}
-
-static void mod_close(mod_Data * data)
-{
- Player_Stop();
- Player_Free(data->moduleHandle);
- free(data->audio_buffer);
- free(data);
-}
-
-static int mod_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
-{
- mod_Data *data;
- float time = 0.0;
- int ret;
- float secPerByte;
-
- if (mod_initMikMod() < 0)
- return -1;
-
- if (!(data = mod_open(path))) {
- ERROR("failed to open mod: %s\n", path);
- MikMod_Exit();
- return -1;
- }
-
- dc->totalTime = 0;
- dc->audioFormat.bits = 16;
- dc->audioFormat.sampleRate = 44100;
- dc->audioFormat.channels = 2;
- getOutputAudioFormat(&(dc->audioFormat), &(cb->audioFormat));
-
- secPerByte =
- 1.0 / ((dc->audioFormat.bits * dc->audioFormat.channels / 8.0) *
- (float)dc->audioFormat.sampleRate);
-
- dc->state = DECODE_STATE_DECODE;
- while (1) {
- if (dc->seek) {
- dc->seekError = 1;
- dc->seek = 0;
- }
-
- if (dc->stop)
- break;
-
- if (!Player_Active())
- break;
-
- ret = VC_WriteBytes(data->audio_buffer, MIKMOD_FRAME_SIZE);
- time += ret * secPerByte;
- sendDataToOutputBuffer(cb, NULL, dc, 0,
- (char *)data->audio_buffer, ret, time,
- 0, NULL);
- }
-
- flushOutputBuffer(cb);
-
- mod_close(data);
-
- MikMod_Exit();
-
- if (dc->stop) {
- dc->state = DECODE_STATE_STOP;
- dc->stop = 0;
- } else
- dc->state = DECODE_STATE_STOP;
-
- return 0;
-}
-
-static MpdTag *modTagDup(char *file)
-{
- MpdTag *ret = NULL;
- MODULE *moduleHandle;
- char *title;
-
- if (mod_initMikMod() < 0) {
- DEBUG("modTagDup: Failed to initialize MikMod\n");
- return NULL;
- }
-
- if (!(moduleHandle = Player_Load(file, 128, 0))) {
- DEBUG("modTagDup: Failed to open file: %s\n", file);
- MikMod_Exit();
- return NULL;
-
- }
- Player_Free(moduleHandle);
-
- ret = newMpdTag();
-
- ret->time = 0;
- title = xstrdup(Player_LoadTitle(file));
- if (title)
- addItemToMpdTag(ret, TAG_ITEM_TITLE, title);
-
- MikMod_Exit();
-
- return ret;
-}
-
-static char *modSuffixes[] = { "amf",
- "dsm",
- "far",
- "gdm",
- "imf",
- "it",
- "med",
- "mod",
- "mtm",
- "s3m",
- "stm",
- "stx",
- "ult",
- "uni",
- "xm",
- NULL
-};
-
-InputPlugin modPlugin = {
- "mod",
- NULL,
- mod_finishMikMod,
- NULL,
- NULL,
- mod_decode,
- modTagDup,
- INPUT_PLUGIN_STREAM_FILE,
- modSuffixes,
- NULL
-};
-
-#else
-
-InputPlugin modPlugin;
-
-#endif /* HAVE_MIKMOD */
diff --git a/trunk/src/inputPlugins/mp3_plugin.c b/trunk/src/inputPlugins/mp3_plugin.c
deleted file mode 100644
index a920b98a1..000000000
--- a/trunk/src/inputPlugins/mp3_plugin.c
+++ /dev/null
@@ -1,1092 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "../inputPlugin.h"
-
-#ifdef HAVE_MAD
-
-#include "../pcm_utils.h"
-#include <mad.h>
-
-#ifdef HAVE_ID3TAG
-#include <id3tag.h>
-#endif
-
-#include "../log.h"
-#include "../utils.h"
-#include "../replayGain.h"
-#include "../tag.h"
-#include "../conf.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-
-#define FRAMES_CUSHION 2000
-
-#define READ_BUFFER_SIZE 40960
-
-#define DECODE_SKIP -3
-#define DECODE_BREAK -2
-#define DECODE_CONT -1
-#define DECODE_OK 0
-
-#define MUTEFRAME_SKIP 1
-#define MUTEFRAME_SEEK 2
-
-/* the number of samples of silence the decoder inserts at start */
-#define DECODERDELAY 529
-
-#define DEFAULT_GAPLESS_MP3_PLAYBACK 1
-
-static int gaplessPlayback;
-
-/* this is stolen from mpg321! */
-struct audio_dither {
- mad_fixed_t error[3];
- mad_fixed_t random;
-};
-
-static unsigned long prng(unsigned long state)
-{
- return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL;
-}
-
-static signed long audio_linear_dither(unsigned int bits, mad_fixed_t sample,
- struct audio_dither *dither)
-{
- unsigned int scalebits;
- mad_fixed_t output, mask, random;
-
- enum {
- MIN = -MAD_F_ONE,
- MAX = MAD_F_ONE - 1
- };
-
- sample += dither->error[0] - dither->error[1] + dither->error[2];
-
- dither->error[2] = dither->error[1];
- dither->error[1] = dither->error[0] / 2;
-
- output = sample + (1L << (MAD_F_FRACBITS + 1 - bits - 1));
-
- scalebits = MAD_F_FRACBITS + 1 - bits;
- mask = (1L << scalebits) - 1;
-
- random = prng(dither->random);
- output += (random & mask) - (dither->random & mask);
-
- dither->random = random;
-
- if (output > MAX) {
- output = MAX;
-
- if (sample > MAX)
- sample = MAX;
- } else if (output < MIN) {
- output = MIN;
-
- if (sample < MIN)
- sample = MIN;
- }
-
- output &= ~mask;
-
- dither->error[0] = sample - output;
-
- return output >> scalebits;
-}
-
-/* end of stolen stuff from mpg321 */
-
-static int mp3_plugin_init(void)
-{
- gaplessPlayback = getBoolConfigParam(CONF_GAPLESS_MP3_PLAYBACK);
- if (gaplessPlayback == -1) gaplessPlayback = DEFAULT_GAPLESS_MP3_PLAYBACK;
- else if (gaplessPlayback < 0) exit(EXIT_FAILURE);
- return 1;
-}
-
-/* decoder stuff is based on madlld */
-
-#define MP3_DATA_OUTPUT_BUFFER_SIZE 4096
-
-typedef struct _mp3DecodeData {
- struct mad_stream stream;
- struct mad_frame frame;
- struct mad_synth synth;
- mad_timer_t timer;
- unsigned char readBuffer[READ_BUFFER_SIZE];
- char outputBuffer[MP3_DATA_OUTPUT_BUFFER_SIZE];
- char *outputPtr;
- char *outputBufferEnd;
- float totalTime;
- float elapsedTime;
- int muteFrame;
- long *frameOffset;
- mad_timer_t *times;
- long highestFrame;
- long maxFrames;
- long currentFrame;
- int dropFramesAtStart;
- int dropFramesAtEnd;
- int dropSamplesAtStart;
- int dropSamplesAtEnd;
- int foundXing;
- int foundFirstFrame;
- int decodedFirstFrame;
- int flush;
- unsigned long bitRate;
- InputStream *inStream;
- struct audio_dither dither;
- enum mad_layer layer;
-} mp3DecodeData;
-
-static void initMp3DecodeData(mp3DecodeData * data, InputStream * inStream)
-{
- data->outputPtr = data->outputBuffer;
- data->outputBufferEnd =
- data->outputBuffer + MP3_DATA_OUTPUT_BUFFER_SIZE;
- data->muteFrame = 0;
- data->highestFrame = 0;
- data->maxFrames = 0;
- data->frameOffset = NULL;
- data->times = NULL;
- data->currentFrame = 0;
- data->dropFramesAtStart = 0;
- data->dropFramesAtEnd = 0;
- data->dropSamplesAtStart = 0;
- data->dropSamplesAtEnd = 0;
- data->foundXing = 0;
- data->foundFirstFrame = 0;
- data->decodedFirstFrame = 0;
- data->flush = 1;
- data->inStream = inStream;
- data->layer = 0;
- memset(&(data->dither), 0, sizeof(struct audio_dither));
-
- mad_stream_init(&data->stream);
- mad_stream_options(&data->stream, MAD_OPTION_IGNORECRC);
- mad_frame_init(&data->frame);
- mad_synth_init(&data->synth);
- mad_timer_reset(&data->timer);
-}
-
-static int seekMp3InputBuffer(mp3DecodeData * data, long offset)
-{
- if (seekInputStream(data->inStream, offset, SEEK_SET) < 0) {
- return -1;
- }
-
- mad_stream_buffer(&data->stream, data->readBuffer, 0);
- (data->stream).error = 0;
-
- return 0;
-}
-
-static int fillMp3InputBuffer(mp3DecodeData * data)
-{
- size_t readSize;
- size_t remaining;
- size_t readed;
- unsigned char *readStart;
-
- if ((data->stream).next_frame != NULL) {
- remaining = (data->stream).bufend - (data->stream).next_frame;
- memmove(data->readBuffer, (data->stream).next_frame, remaining);
- readStart = (data->readBuffer) + remaining;
- readSize = READ_BUFFER_SIZE - remaining;
- } else {
- readSize = READ_BUFFER_SIZE;
- readStart = data->readBuffer, remaining = 0;
- }
-
- /* we've exhausted the read buffer, so give up!, these potential
- * mp3 frames are way too big, and thus unlikely to be mp3 frames */
- if (readSize == 0)
- return -1;
-
- readed = readFromInputStream(data->inStream, readStart, (size_t) 1,
- readSize);
- if (readed <= 0 && inputStreamAtEOF(data->inStream))
- return -1;
- /* sleep for a fraction of a second! */
- else if (readed <= 0) {
- readed = 0;
- my_usleep(10000);
- }
-
- mad_stream_buffer(&data->stream, data->readBuffer, readed + remaining);
- (data->stream).error = 0;
-
- return 0;
-}
-
-#ifdef HAVE_ID3TAG
-static ReplayGainInfo *parseId3ReplayGainInfo(struct id3_tag *tag)
-{
- int i;
- char *key;
- char *value;
- struct id3_frame *frame;
- int found = 0;
- ReplayGainInfo *replayGainInfo;
-
- replayGainInfo = newReplayGainInfo();
-
- for (i = 0; (frame = id3_tag_findframe(tag, "TXXX", i)); i++) {
- if (frame->nfields < 3)
- continue;
-
- key = (char *)
- id3_ucs4_latin1duplicate(id3_field_getstring
- (&frame->fields[1]));
- value = (char *)
- id3_ucs4_latin1duplicate(id3_field_getstring
- (&frame->fields[2]));
-
- if (strcasecmp(key, "replaygain_track_gain") == 0) {
- replayGainInfo->trackGain = atof(value);
- found = 1;
- } else if (strcasecmp(key, "replaygain_album_gain") == 0) {
- replayGainInfo->albumGain = atof(value);
- found = 1;
- } else if (strcasecmp(key, "replaygain_track_peak") == 0) {
- replayGainInfo->trackPeak = atof(value);
- found = 1;
- } else if (strcasecmp(key, "replaygain_album_peak") == 0) {
- replayGainInfo->albumPeak = atof(value);
- found = 1;
- }
-
- free(key);
- free(value);
- }
-
- if (found)
- return replayGainInfo;
- freeReplayGainInfo(replayGainInfo);
- return NULL;
-}
-#endif
-
-#ifdef HAVE_ID3TAG
-static void mp3_parseId3Tag(mp3DecodeData * data, signed long tagsize,
- MpdTag ** mpdTag, ReplayGainInfo ** replayGainInfo)
-{
- struct id3_tag *id3Tag = NULL;
- id3_length_t count;
- id3_byte_t const *id3_data;
- id3_byte_t *allocated = NULL;
- MpdTag *tmpMpdTag;
- ReplayGainInfo *tmpReplayGainInfo;
-
- count = data->stream.bufend - data->stream.this_frame;
-
- if (tagsize <= count) {
- id3_data = data->stream.this_frame;
- mad_stream_skip(&(data->stream), tagsize);
- } else {
- allocated = xmalloc(tagsize);
- if (!allocated)
- goto fail;
-
- memcpy(allocated, data->stream.this_frame, count);
- mad_stream_skip(&(data->stream), count);
-
- while (count < tagsize) {
- int len;
-
- len = readFromInputStream(data->inStream,
- allocated + count, (size_t) 1,
- tagsize - count);
- if (len <= 0 && inputStreamAtEOF(data->inStream)) {
- break;
- } else if (len <= 0)
- my_usleep(10000);
- else
- count += len;
- }
-
- if (count != tagsize) {
- DEBUG("mp3_decode: error parsing ID3 tag\n");
- goto fail;
- }
-
- id3_data = allocated;
- }
-
- id3Tag = id3_tag_parse(id3_data, tagsize);
- if (!id3Tag)
- goto fail;
-
- if (mpdTag) {
- tmpMpdTag = parseId3Tag(id3Tag);
- if (tmpMpdTag) {
- if (*mpdTag)
- freeMpdTag(*mpdTag);
- *mpdTag = tmpMpdTag;
- }
- }
-
- if (replayGainInfo) {
- tmpReplayGainInfo = parseId3ReplayGainInfo(id3Tag);
- if (tmpReplayGainInfo) {
- if (*replayGainInfo)
- freeReplayGainInfo(*replayGainInfo);
- *replayGainInfo = tmpReplayGainInfo;
- }
- }
-
- id3_tag_delete(id3Tag);
-fail:
- if (allocated)
- free(allocated);
-}
-#endif
-
-static int decodeNextFrameHeader(mp3DecodeData * data, MpdTag ** tag,
- ReplayGainInfo ** replayGainInfo)
-{
- enum mad_layer layer;
-
- if ((data->stream).buffer == NULL
- || (data->stream).error == MAD_ERROR_BUFLEN) {
- if (fillMp3InputBuffer(data) < 0) {
- return DECODE_BREAK;
- }
- }
- if (mad_header_decode(&data->frame.header, &data->stream)) {
-#ifdef HAVE_ID3TAG
- if ((data->stream).error == MAD_ERROR_LOSTSYNC &&
- (data->stream).this_frame) {
- signed long tagsize = id3_tag_query((data->stream).
- this_frame,
- (data->stream).
- bufend -
- (data->stream).
- this_frame);
-
- if (tagsize > 0) {
- if (tag && !(*tag)) {
- mp3_parseId3Tag(data, tagsize, tag,
- replayGainInfo);
- } else {
- mad_stream_skip(&(data->stream),
- tagsize);
- }
- return DECODE_CONT;
- }
- }
-#endif
- if (MAD_RECOVERABLE((data->stream).error)) {
- return DECODE_SKIP;
- } else {
- if ((data->stream).error == MAD_ERROR_BUFLEN)
- return DECODE_CONT;
- else {
- ERROR("unrecoverable frame level error "
- "(%s).\n",
- mad_stream_errorstr(&data->stream));
- data->flush = 0;
- return DECODE_BREAK;
- }
- }
- }
-
- layer = data->frame.header.layer;
- if (!data->layer) {
- if (layer != MAD_LAYER_II && layer != MAD_LAYER_III) {
- /* Only layer 2 and 3 have been tested to work */
- return DECODE_SKIP;
- }
- data->layer = layer;
- } else if (layer != data->layer) {
- /* Don't decode frames with a different layer than the first */
- return DECODE_SKIP;
- }
-
- return DECODE_OK;
-}
-
-static int decodeNextFrame(mp3DecodeData * data)
-{
- if ((data->stream).buffer == NULL
- || (data->stream).error == MAD_ERROR_BUFLEN) {
- if (fillMp3InputBuffer(data) < 0) {
- return DECODE_BREAK;
- }
- }
- if (mad_frame_decode(&data->frame, &data->stream)) {
-#ifdef HAVE_ID3TAG
- if ((data->stream).error == MAD_ERROR_LOSTSYNC) {
- signed long tagsize = id3_tag_query((data->stream).
- this_frame,
- (data->stream).
- bufend -
- (data->stream).
- this_frame);
- if (tagsize > 0) {
- mad_stream_skip(&(data->stream), tagsize);
- return DECODE_CONT;
- }
- }
-#endif
- if (MAD_RECOVERABLE((data->stream).error)) {
- return DECODE_SKIP;
- } else {
- if ((data->stream).error == MAD_ERROR_BUFLEN)
- return DECODE_CONT;
- else {
- ERROR("unrecoverable frame level error "
- "(%s).\n",
- mad_stream_errorstr(&data->stream));
- data->flush = 0;
- return DECODE_BREAK;
- }
- }
- }
-
- return DECODE_OK;
-}
-
-/* xing stuff stolen from alsaplayer, and heavily modified by jat */
-#define XI_MAGIC (('X' << 8) | 'i')
-#define NG_MAGIC (('n' << 8) | 'g')
-#define IN_MAGIC (('I' << 8) | 'n')
-#define FO_MAGIC (('f' << 8) | 'o')
-
-enum xing_magic {
- XING_MAGIC_XING, /* VBR */
- XING_MAGIC_INFO /* CBR */
-};
-
-struct xing {
- long flags; /* valid fields (see below) */
- unsigned long frames; /* total number of frames */
- unsigned long bytes; /* total number of bytes */
- unsigned char toc[100]; /* 100-point seek table */
- long scale; /* VBR quality */
- enum xing_magic magic; /* header magic */
-};
-
-enum {
- XING_FRAMES = 0x00000001L,
- XING_BYTES = 0x00000002L,
- XING_TOC = 0x00000004L,
- XING_SCALE = 0x00000008L
-};
-
-struct lame {
- char encoder[10]; /* 9 byte encoder name/version ("LAME3.97b") */
-#if 0
- /* See related comment in parse_lame() */
- float peak; /* replaygain peak */
- float trackGain; /* replaygain track gain */
- float albumGain; /* replaygain album gain */
-#endif
- int encoderDelay; /* # of added samples at start of mp3 */
- int encoderPadding; /* # of added samples at end of mp3 */
-};
-
-static int parse_xing(struct xing *xing, struct mad_bitptr *ptr, int *oldbitlen)
-{
- unsigned long bits;
- int bitlen;
- int bitsleft;
- int i;
-
- bitlen = *oldbitlen;
-
- if (bitlen < 16) goto fail;
- bits = mad_bit_read(ptr, 16);
- bitlen -= 16;
-
- if (bits == XI_MAGIC) {
- if (bitlen < 16) goto fail;
- if (mad_bit_read(ptr, 16) != NG_MAGIC) goto fail;
- bitlen -= 16;
- xing->magic = XING_MAGIC_XING;
- } else if (bits == IN_MAGIC) {
- if (bitlen < 16) goto fail;
- if (mad_bit_read(ptr, 16) != FO_MAGIC) goto fail;
- bitlen -= 16;
- xing->magic = XING_MAGIC_INFO;
- }
- else if (bits == NG_MAGIC) xing->magic = XING_MAGIC_XING;
- else if (bits == FO_MAGIC) xing->magic = XING_MAGIC_INFO;
- else goto fail;
-
- if (bitlen < 32) goto fail;
- xing->flags = mad_bit_read(ptr, 32);
- bitlen -= 32;
-
- if (xing->flags & XING_FRAMES) {
- if (bitlen < 32) goto fail;
- xing->frames = mad_bit_read(ptr, 32);
- bitlen -= 32;
- }
-
- if (xing->flags & XING_BYTES) {
- if (bitlen < 32) goto fail;
- xing->bytes = mad_bit_read(ptr, 32);
- bitlen -= 32;
- }
-
- if (xing->flags & XING_TOC) {
- if (bitlen < 800) goto fail;
- for (i = 0; i < 100; ++i) xing->toc[i] = mad_bit_read(ptr, 8);
- bitlen -= 800;
- }
-
- if (xing->flags & XING_SCALE) {
- if (bitlen < 32) goto fail;
- xing->scale = mad_bit_read(ptr, 32);
- bitlen -= 32;
- }
-
- /* Make sure we consume no less than 120 bytes (960 bits) in hopes that
- * the LAME tag is found there, and not right after the Xing header */
- bitsleft = 960 - ((*oldbitlen) - bitlen);
- if (bitsleft < 0) goto fail;
- else if (bitsleft > 0) {
- mad_bit_read(ptr, bitsleft);
- bitlen -= bitsleft;
- }
-
- *oldbitlen = bitlen;
-
- return 1;
-fail:
- xing->flags = 0;
- return 0;
-}
-
-static int parse_lame(struct lame *lame, struct mad_bitptr *ptr, int *bitlen)
-{
- int i;
-
- /* Unlike the xing header, the lame tag has a fixed length. Fail if
- * not all 36 bytes (288 bits) are there. */
- if (*bitlen < 288) return 0;
-
- for (i = 0; i < 9; i++) lame->encoder[i] = (char)mad_bit_read(ptr, 8);
- lame->encoder[9] = '\0';
-
- /* This is technically incorrect, since the encoder might not be lame.
- * But there's no other way to determine if this is a lame tag, and we
- * wouldn't want to go reading a tag that's not there. */
- if (strncmp(lame->encoder, "LAME", 4) != 0) return 0;
-
-#if 0
- /* Apparently lame versions <3.97b1 do not calculate replaygain. I'm
- * using lame 3.97b2, and while it does calculate replaygain, it's
- * setting the values to 0. Using --replaygain-(fast|accurate) doesn't
- * make any difference. Leaving this code unused until we have a way
- * of testing it. -- jat */
-
- mad_bit_read(ptr, 16);
-
- mad_bit_read(ptr, 32); /* peak */
-
- mad_bit_read(ptr, 6); /* header */
- bits = mad_bit_read(ptr, 1); /* sign bit */
- lame->trackGain = mad_bit_read(ptr, 9); /* gain*10 */
- lame->trackGain = (bits ? -lame->trackGain : lame->trackGain) / 10;
-
- mad_bit_read(ptr, 6); /* header */
- bits = mad_bit_read(ptr, 1); /* sign bit */
- lame->albumGain = mad_bit_read(ptr, 9); /* gain*10 */
- lame->albumGain = (bits ? -lame->albumGain : lame->albumGain) / 10;
-
- mad_bit_read(ptr, 16);
-#else
- mad_bit_read(ptr, 96);
-#endif
-
- lame->encoderDelay = mad_bit_read(ptr, 12);
- lame->encoderPadding = mad_bit_read(ptr, 12);
-
- mad_bit_read(ptr, 96);
-
- *bitlen -= 288;
-
- return 1;
-}
-
-static int decodeFirstFrame(mp3DecodeData * data, DecoderControl * dc,
- MpdTag ** tag, ReplayGainInfo ** replayGainInfo)
-{
- struct xing xing;
- struct lame lame;
- struct mad_bitptr ptr;
- int bitlen;
- int ret;
-
- /* stfu gcc */
- memset(&xing, 0, sizeof(struct xing));
- xing.flags = 0;
-
- while (1) {
- while ((ret = decodeNextFrameHeader(data, tag, replayGainInfo)) == DECODE_CONT &&
- (!dc || !dc->stop));
- if (ret == DECODE_BREAK || (dc && dc->stop)) return -1;
- if (ret == DECODE_SKIP) continue;
-
- while ((ret = decodeNextFrame(data)) == DECODE_CONT &&
- (!dc || !dc->stop));
- if (ret == DECODE_BREAK || (dc && dc->stop)) return -1;
- if (ret == DECODE_OK) break;
- }
-
- ptr = data->stream.anc_ptr;
- bitlen = data->stream.anc_bitlen;
-
- /*
- * Attempt to calulcate the length of the song from filesize
- */
- {
- size_t offset = data->inStream->offset;
- mad_timer_t duration = data->frame.header.duration;
- float frameTime = ((float)mad_timer_count(duration,
- MAD_UNITS_MILLISECONDS)) / 1000;
-
- if (data->stream.this_frame != NULL)
- offset -= data->stream.bufend - data->stream.this_frame;
- else
- offset -= data->stream.bufend - data->stream.buffer;
-
- if (data->inStream->size >= offset) {
- data->totalTime = ((data->inStream->size - offset) *
- 8.0) / (data->frame).header.bitrate;
- data->maxFrames = data->totalTime / frameTime +
- FRAMES_CUSHION;
- } else {
- data->maxFrames = FRAMES_CUSHION;
- data->totalTime = 0;
- }
- }
- /*
- * if an xing tag exists, use that!
- */
- if (parse_xing(&xing, &ptr, &bitlen)) {
- data->foundXing = 1;
- data->muteFrame = MUTEFRAME_SKIP;
-
- if (gaplessPlayback && data->inStream->seekable &&
- parse_lame(&lame, &ptr, &bitlen)) {
- data->dropSamplesAtStart = lame.encoderDelay + DECODERDELAY;
- data->dropSamplesAtEnd = lame.encoderPadding;
- }
-
- if ((xing.flags & XING_FRAMES) && xing.frames) {
- mad_timer_t duration = data->frame.header.duration;
- mad_timer_multiply(&duration, xing.frames);
- data->totalTime = ((float)mad_timer_count(duration, MAD_UNITS_MILLISECONDS)) / 1000;
- data->maxFrames = xing.frames;
- }
- }
-
- if (!data->maxFrames) return -1;
-
- data->frameOffset = xmalloc(sizeof(long) * data->maxFrames);
- data->times = xmalloc(sizeof(mad_timer_t) * data->maxFrames);
-
- return 0;
-}
-
-static void mp3DecodeDataFinalize(mp3DecodeData * data)
-{
- mad_synth_finish(&data->synth);
- mad_frame_finish(&data->frame);
- mad_stream_finish(&data->stream);
-
- if (data->frameOffset) free(data->frameOffset);
- if (data->times) free(data->times);
-}
-
-/* this is primarily used for getting total time for tags */
-static int getMp3TotalTime(char *file)
-{
- InputStream inStream;
- mp3DecodeData data;
- int ret;
-
- if (openInputStream(&inStream, file) < 0)
- return -1;
- initMp3DecodeData(&data, &inStream);
- if (decodeFirstFrame(&data, NULL, NULL, NULL) < 0)
- ret = -1;
- else
- ret = data.totalTime + 0.5;
- mp3DecodeDataFinalize(&data);
- closeInputStream(&inStream);
-
- return ret;
-}
-
-static int openMp3FromInputStream(InputStream * inStream, mp3DecodeData * data,
- DecoderControl * dc, MpdTag ** tag,
- ReplayGainInfo ** replayGainInfo)
-{
- initMp3DecodeData(data, inStream);
- *tag = NULL;
- if (decodeFirstFrame(data, dc, tag, replayGainInfo) < 0) {
- mp3DecodeDataFinalize(data);
- if (tag && *tag)
- freeMpdTag(*tag);
- return -1;
- }
-
- return 0;
-}
-
-static int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc,
- ReplayGainInfo ** replayGainInfo)
-{
- int samplesPerFrame;
- int samplesLeft;
- int i;
- int ret;
- int skip;
-
- if (data->currentFrame >= data->highestFrame) {
- mad_timer_add(&data->timer, (data->frame).header.duration);
- data->bitRate = (data->frame).header.bitrate;
- if (data->currentFrame >= data->maxFrames) {
- data->currentFrame = data->maxFrames - 1;
- } else {
- data->highestFrame++;
- }
- data->frameOffset[data->currentFrame] = data->inStream->offset;
- if (data->stream.this_frame != NULL) {
- data->frameOffset[data->currentFrame] -=
- data->stream.bufend - data->stream.this_frame;
- } else {
- data->frameOffset[data->currentFrame] -=
- data->stream.bufend - data->stream.buffer;
- }
- data->times[data->currentFrame] = data->timer;
- } else {
- data->timer = data->times[data->currentFrame];
- }
- data->currentFrame++;
- data->elapsedTime =
- ((float)mad_timer_count(data->timer, MAD_UNITS_MILLISECONDS)) /
- 1000;
-
- switch (data->muteFrame) {
- case MUTEFRAME_SKIP:
- data->muteFrame = 0;
- break;
- case MUTEFRAME_SEEK:
- if (dc->seekWhere <= data->elapsedTime) {
- data->outputPtr = data->outputBuffer;
- clearOutputBuffer(cb);
- data->muteFrame = 0;
- dc->seek = 0;
- }
- break;
- default:
- mad_synth_frame(&data->synth, &data->frame);
-
- if (!data->foundFirstFrame) {
- samplesPerFrame = (data->synth).pcm.length;
- data->dropFramesAtStart = data->dropSamplesAtStart / samplesPerFrame;
- data->dropFramesAtEnd = data->dropSamplesAtEnd / samplesPerFrame;
- data->dropSamplesAtStart = data->dropSamplesAtStart % samplesPerFrame;
- data->dropSamplesAtEnd = data->dropSamplesAtEnd % samplesPerFrame;
- data->foundFirstFrame = 1;
- }
-
- if (data->dropFramesAtStart > 0) {
- data->dropFramesAtStart--;
- break;
- } else if ((data->dropFramesAtEnd > 0) &&
- (data->currentFrame == (data->maxFrames + 1 - data->dropFramesAtEnd))) {
- /* stop decoding, effectively dropping all remaining
- * frames */
- return DECODE_BREAK;
- }
-
- if (data->inStream->metaTitle) {
- MpdTag *tag = newMpdTag();
- if (data->inStream->metaName) {
- addItemToMpdTag(tag,
- TAG_ITEM_NAME,
- data->inStream->metaName);
- }
- addItemToMpdTag(tag, TAG_ITEM_TITLE,
- data->inStream->metaTitle);
- free(data->inStream->metaTitle);
- data->inStream->metaTitle = NULL;
- copyMpdTagToOutputBuffer(cb, tag);
- freeMpdTag(tag);
- }
-
- samplesLeft = (data->synth).pcm.length;
-
- for (i = 0; i < (data->synth).pcm.length; i++) {
- mpd_sint16 *sample;
-
- samplesLeft--;
-
- if (!data->decodedFirstFrame &&
- (i < data->dropSamplesAtStart)) {
- continue;
- } else if (data->dropSamplesAtEnd &&
- (data->currentFrame == (data->maxFrames - data->dropFramesAtEnd)) &&
- (samplesLeft < data->dropSamplesAtEnd)) {
- /* stop decoding, effectively dropping
- * all remaining samples */
- return DECODE_BREAK;
- }
-
- sample = (mpd_sint16 *) data->outputPtr;
- *sample = (mpd_sint16) audio_linear_dither(16,
- (data->synth).pcm.samples[0][i],
- &(data->dither));
- data->outputPtr += 2;
-
- if (MAD_NCHANNELS(&(data->frame).header) == 2) {
- sample = (mpd_sint16 *) data->outputPtr;
- *sample = (mpd_sint16) audio_linear_dither(16,
- (data->synth).pcm.samples[1][i],
- &(data->dither));
- data->outputPtr += 2;
- }
-
- if (data->outputPtr >= data->outputBufferEnd) {
- ret = sendDataToOutputBuffer(cb,
- data->inStream,
- dc,
- data->inStream->seekable,
- data->outputBuffer,
- data->outputPtr - data->outputBuffer,
- data->elapsedTime,
- data->bitRate / 1000,
- (replayGainInfo != NULL) ? *replayGainInfo : NULL);
- if (ret == OUTPUT_BUFFER_DC_STOP) {
- data->flush = 0;
- return DECODE_BREAK;
- }
-
- data->outputPtr = data->outputBuffer;
-
- if (ret == OUTPUT_BUFFER_DC_SEEK)
- break;
- }
- }
-
- data->decodedFirstFrame = 1;
-
- if (dc->seek && data->inStream->seekable) {
- long j = 0;
- data->muteFrame = MUTEFRAME_SEEK;
- while (j < data->highestFrame && dc->seekWhere >
- ((float)mad_timer_count(data->times[j],
- MAD_UNITS_MILLISECONDS))
- / 1000) {
- j++;
- }
- if (j < data->highestFrame) {
- if (seekMp3InputBuffer(data,
- data->frameOffset[j]) ==
- 0) {
- data->outputPtr = data->outputBuffer;
- clearOutputBuffer(cb);
- data->currentFrame = j;
- } else
- dc->seekError = 1;
- data->muteFrame = 0;
- dc->seek = 0;
- }
- } else if (dc->seek && !data->inStream->seekable) {
- dc->seek = 0;
- dc->seekError = 1;
- }
- }
-
- while (1) {
- skip = 0;
- while ((ret =
- decodeNextFrameHeader(data, NULL,
- replayGainInfo)) == DECODE_CONT
- && !dc->stop) ;
- if (ret == DECODE_BREAK || dc->stop || dc->seek)
- break;
- else if (ret == DECODE_SKIP)
- skip = 1;
- if (!data->muteFrame) {
- while ((ret = decodeNextFrame(data)) == DECODE_CONT &&
- !dc->stop && !dc->seek) ;
- if (ret == DECODE_BREAK || dc->stop || dc->seek)
- break;
- }
- if (!skip && ret == DECODE_OK)
- break;
- }
-
- if (dc->stop)
- return DECODE_BREAK;
-
- return ret;
-}
-
-static void initAudioFormatFromMp3DecodeData(mp3DecodeData * data,
- AudioFormat * af)
-{
- af->bits = 16;
- af->sampleRate = (data->frame).header.samplerate;
- af->channels = MAD_NCHANNELS(&(data->frame).header);
-}
-
-static int mp3_decode(OutputBuffer * cb, DecoderControl * dc,
- InputStream * inStream)
-{
- mp3DecodeData data;
- MpdTag *tag = NULL;
- ReplayGainInfo *replayGainInfo = NULL;
-
- if (openMp3FromInputStream(inStream, &data, dc, &tag, &replayGainInfo) <
- 0) {
- closeInputStream(inStream);
- if (!dc->stop) {
- ERROR
- ("Input does not appear to be a mp3 bit stream.\n");
- return -1;
- } else {
- dc->state = DECODE_STATE_STOP;
- dc->stop = 0;
- }
- return 0;
- }
-
- initAudioFormatFromMp3DecodeData(&data, &(dc->audioFormat));
- getOutputAudioFormat(&(dc->audioFormat), &(cb->audioFormat));
-
- dc->totalTime = data.totalTime;
-
- if (inStream->metaTitle) {
- if (tag)
- freeMpdTag(tag);
- tag = newMpdTag();
- addItemToMpdTag(tag, TAG_ITEM_TITLE, inStream->metaTitle);
- free(inStream->metaTitle);
- inStream->metaTitle = NULL;
- if (inStream->metaName) {
- addItemToMpdTag(tag, TAG_ITEM_NAME, inStream->metaName);
- }
- copyMpdTagToOutputBuffer(cb, tag);
- freeMpdTag(tag);
- } else if (tag) {
- if (inStream->metaName) {
- clearItemsFromMpdTag(tag, TAG_ITEM_NAME);
- addItemToMpdTag(tag, TAG_ITEM_NAME, inStream->metaName);
- }
- copyMpdTagToOutputBuffer(cb, tag);
- freeMpdTag(tag);
- } else if (inStream->metaName) {
- tag = newMpdTag();
- if (inStream->metaName) {
- addItemToMpdTag(tag, TAG_ITEM_NAME, inStream->metaName);
- }
- copyMpdTagToOutputBuffer(cb, tag);
- freeMpdTag(tag);
- }
-
- dc->state = DECODE_STATE_DECODE;
-
- while (mp3Read(&data, cb, dc, &replayGainInfo) != DECODE_BREAK) ;
- /* send last little bit if not dc->stop */
- if (!dc->stop && data.outputPtr != data.outputBuffer && data.flush) {
- sendDataToOutputBuffer(cb, NULL, dc,
- data.inStream->seekable,
- data.outputBuffer,
- data.outputPtr - data.outputBuffer,
- data.elapsedTime, data.bitRate / 1000,
- replayGainInfo);
- }
-
- if (replayGainInfo)
- freeReplayGainInfo(replayGainInfo);
-
- closeInputStream(inStream);
-
- if (dc->seek && data.muteFrame == MUTEFRAME_SEEK) {
- clearOutputBuffer(cb);
- dc->seek = 0;
- }
-
- flushOutputBuffer(cb);
- mp3DecodeDataFinalize(&data);
-
- if (dc->stop) {
- dc->state = DECODE_STATE_STOP;
- dc->stop = 0;
- } else
- dc->state = DECODE_STATE_STOP;
-
- return 0;
-}
-
-static MpdTag *mp3_tagDup(char *file)
-{
- MpdTag *ret = NULL;
- int time;
-
- ret = id3Dup(file);
-
- time = getMp3TotalTime(file);
-
- if (time >= 0) {
- if (!ret)
- ret = newMpdTag();
- ret->time = time;
- } else {
- DEBUG("mp3_tagDup: Failed to get total song time from: %s\n",
- file);
- }
-
- return ret;
-}
-
-static char *mp3_suffixes[] = { "mp3", "mp2", NULL };
-static char *mp3_mimeTypes[] = { "audio/mpeg", NULL };
-
-InputPlugin mp3Plugin = {
- "mp3",
- mp3_plugin_init,
- NULL,
- NULL,
- mp3_decode,
- NULL,
- mp3_tagDup,
- INPUT_PLUGIN_STREAM_FILE | INPUT_PLUGIN_STREAM_URL,
- mp3_suffixes,
- mp3_mimeTypes
-};
-#else
-
-InputPlugin mp3Plugin;
-
-#endif /* HAVE_MAD */
diff --git a/trunk/src/inputPlugins/mp4_plugin.c b/trunk/src/inputPlugins/mp4_plugin.c
deleted file mode 100644
index 1ebf556c6..000000000
--- a/trunk/src/inputPlugins/mp4_plugin.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "../inputPlugin.h"
-
-#ifdef HAVE_FAAD
-
-#include "../utils.h"
-#include "../audio.h"
-#include "../log.h"
-#include "../pcm_utils.h"
-#include "../inputStream.h"
-#include "../outputBuffer.h"
-#include "../decode.h"
-
-#include "../mp4ff/mp4ff.h"
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <faad.h>
-
-/* all code here is either based on or copied from FAAD2's frontend code */
-
-static int mp4_getAACTrack(mp4ff_t * infile)
-{
- /* find AAC track */
- int i, rc;
- int numTracks = mp4ff_total_tracks(infile);
-
- for (i = 0; i < numTracks; i++) {
- unsigned char *buff = NULL;
- unsigned int buff_size = 0;
-#ifdef HAVE_MP4AUDIOSPECIFICCONFIG
- mp4AudioSpecificConfig mp4ASC;
-#else
- unsigned long dummy1_32;
- unsigned char dummy2_8, dummy3_8, dummy4_8, dummy5_8, dummy6_8,
- dummy7_8, dummy8_8;
-#endif
-
- mp4ff_get_decoder_config(infile, i, &buff, &buff_size);
-
- if (buff) {
-#ifdef HAVE_MP4AUDIOSPECIFICCONFIG
- rc = AudioSpecificConfig(buff, buff_size, &mp4ASC);
-#else
- rc = AudioSpecificConfig(buff, &dummy1_32, &dummy2_8,
- &dummy3_8, &dummy4_8,
- &dummy5_8, &dummy6_8,
- &dummy7_8, &dummy8_8);
-#endif
- free(buff);
- if (rc < 0)
- continue;
- return i;
- }
- }
-
- /* can't decode this */
- return -1;
-}
-
-static uint32_t mp4_inputStreamReadCallback(void *inStream, void *buffer,
- uint32_t length)
-{
- return readFromInputStream((InputStream *) inStream, buffer, 1, length);
-}
-
-static uint32_t mp4_inputStreamSeekCallback(void *inStream, uint64_t position)
-{
- return seekInputStream((InputStream *) inStream, position, SEEK_SET);
-}
-
-static int mp4_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
-{
- mp4ff_t *mp4fh;
- mp4ff_callback_t *mp4cb;
- int32_t track;
- float time;
- int32_t scale;
- faacDecHandle decoder;
- faacDecFrameInfo frameInfo;
- faacDecConfigurationPtr config;
- unsigned char *mp4Buffer;
- unsigned int mp4BufferSize;
- unsigned long sampleRate;
- unsigned char channels;
- long sampleId;
- long numSamples;
- int eof = 0;
- long dur;
- unsigned int sampleCount;
- char *sampleBuffer;
- size_t sampleBufferLen;
- unsigned int initial = 1;
- float *seekTable;
- long seekTableEnd = -1;
- int seekPositionFound = 0;
- long offset;
- mpd_uint16 bitRate = 0;
- InputStream inStream;
- int seeking = 0;
-
- if (openInputStream(&inStream, path) < 0) {
- ERROR("failed to open %s\n", path);
- return -1;
- }
-
- mp4cb = xmalloc(sizeof(mp4ff_callback_t));
- mp4cb->read = mp4_inputStreamReadCallback;
- mp4cb->seek = mp4_inputStreamSeekCallback;
- mp4cb->user_data = &inStream;
-
- mp4fh = mp4ff_open_read(mp4cb);
- if (!mp4fh) {
- ERROR("Input does not appear to be a mp4 stream.\n");
- free(mp4cb);
- closeInputStream(&inStream);
- return -1;
- }
-
- track = mp4_getAACTrack(mp4fh);
- if (track < 0) {
- ERROR("No AAC track found in mp4 stream.\n");
- mp4ff_close(mp4fh);
- closeInputStream(&inStream);
- free(mp4cb);
- return -1;
- }
-
- decoder = faacDecOpen();
-
- config = faacDecGetCurrentConfiguration(decoder);
- config->outputFormat = FAAD_FMT_16BIT;
-#ifdef HAVE_FAACDECCONFIGURATION_DOWNMATRIX
- config->downMatrix = 1;
-#endif
-#ifdef HAVE_FAACDECCONFIGURATION_DONTUPSAMPLEIMPLICITSBR
- config->dontUpSampleImplicitSBR = 0;
-#endif
- faacDecSetConfiguration(decoder, config);
-
- dc->audioFormat.bits = 16;
-
- mp4Buffer = NULL;
- mp4BufferSize = 0;
- mp4ff_get_decoder_config(mp4fh, track, &mp4Buffer, &mp4BufferSize);
-
- if (faacDecInit2
- (decoder, mp4Buffer, mp4BufferSize, &sampleRate, &channels) < 0) {
- ERROR("Error not a AAC stream.\n");
- faacDecClose(decoder);
- mp4ff_close(mp4fh);
- free(mp4cb);
- closeInputStream(&inStream);
- return -1;
- }
-
- dc->audioFormat.sampleRate = sampleRate;
- dc->audioFormat.channels = channels;
- time = mp4ff_get_track_duration_use_offsets(mp4fh, track);
- scale = mp4ff_time_scale(mp4fh, track);
-
- if (mp4Buffer)
- free(mp4Buffer);
-
- if (scale < 0) {
- ERROR("Error getting audio format of mp4 AAC track.\n");
- faacDecClose(decoder);
- mp4ff_close(mp4fh);
- closeInputStream(&inStream);
- free(mp4cb);
- return -1;
- }
- dc->totalTime = ((float)time) / scale;
-
- numSamples = mp4ff_num_samples(mp4fh, track);
-
- time = 0.0;
-
- seekTable = xmalloc(sizeof(float) * numSamples);
-
- for (sampleId = 0; sampleId < numSamples && !eof; sampleId++) {
- if (dc->seek)
- seeking = 1;
-
- if (seeking && seekTableEnd > 1 &&
- seekTable[seekTableEnd] >= dc->seekWhere) {
- int i = 2;
- while (seekTable[i] < dc->seekWhere)
- i++;
- sampleId = i - 1;
- time = seekTable[sampleId];
- }
-
- dur = mp4ff_get_sample_duration(mp4fh, track, sampleId);
- offset = mp4ff_get_sample_offset(mp4fh, track, sampleId);
-
- if (sampleId > seekTableEnd) {
- seekTable[sampleId] = time;
- seekTableEnd = sampleId;
- }
-
- if (sampleId == 0)
- dur = 0;
- if (offset > dur)
- dur = 0;
- else
- dur -= offset;
- time += ((float)dur) / scale;
-
- if (seeking && time > dc->seekWhere)
- seekPositionFound = 1;
-
- if (seeking && seekPositionFound) {
- seekPositionFound = 0;
- clearOutputBuffer(cb);
- seeking = 0;
- dc->seek = 0;
- }
-
- if (seeking)
- continue;
-
- if (mp4ff_read_sample(mp4fh, track, sampleId, &mp4Buffer,
- &mp4BufferSize) == 0) {
- eof = 1;
- continue;
- }
-#ifdef HAVE_FAAD_BUFLEN_FUNCS
- sampleBuffer = faacDecDecode(decoder, &frameInfo, mp4Buffer,
- mp4BufferSize);
-#else
- sampleBuffer = faacDecDecode(decoder, &frameInfo, mp4Buffer);
-#endif
-
- if (mp4Buffer)
- free(mp4Buffer);
- if (frameInfo.error > 0) {
- ERROR("error decoding MP4 file: %s\n", path);
- ERROR("faad2 error: %s\n",
- faacDecGetErrorMessage(frameInfo.error));
- eof = 1;
- break;
- }
-
- if (dc->state != DECODE_STATE_DECODE) {
- channels = frameInfo.channels;
-#ifdef HAVE_FAACDECFRAMEINFO_SAMPLERATE
- scale = frameInfo.samplerate;
-#endif
- dc->audioFormat.sampleRate = scale;
- dc->audioFormat.channels = frameInfo.channels;
- getOutputAudioFormat(&(dc->audioFormat),
- &(cb->audioFormat));
- dc->state = DECODE_STATE_DECODE;
- }
-
- if (channels * (dur + offset) > frameInfo.samples) {
- dur = frameInfo.samples / channels;
- offset = 0;
- }
-
- sampleCount = (unsigned long)(dur * channels);
-
- if (sampleCount > 0) {
- initial = 0;
- bitRate = frameInfo.bytesconsumed * 8.0 *
- frameInfo.channels * scale /
- frameInfo.samples / 1000 + 0.5;
- }
-
- sampleBufferLen = sampleCount * 2;
-
- sampleBuffer += offset * channels * 2;
-
- sendDataToOutputBuffer(cb, NULL, dc, 1, sampleBuffer,
- sampleBufferLen, time, bitRate, NULL);
- if (dc->stop) {
- eof = 1;
- break;
- }
- }
-
- free(seekTable);
- faacDecClose(decoder);
- mp4ff_close(mp4fh);
- closeInputStream(&inStream);
- free(mp4cb);
-
- if (dc->state != DECODE_STATE_DECODE)
- return -1;
-
- if (dc->seek && seeking) {
- clearOutputBuffer(cb);
- dc->seek = 0;
- }
- flushOutputBuffer(cb);
-
- if (dc->stop) {
- dc->state = DECODE_STATE_STOP;
- dc->stop = 0;
- } else
- dc->state = DECODE_STATE_STOP;
-
- return 0;
-}
-
-static MpdTag *mp4DataDup(char *file, int *mp4MetadataFound)
-{
- MpdTag *ret = NULL;
- InputStream inStream;
- mp4ff_t *mp4fh;
- mp4ff_callback_t *cb;
- int32_t track;
- int32_t time;
- int32_t scale;
- int i;
-
- *mp4MetadataFound = 0;
-
- if (openInputStream(&inStream, file) < 0) {
- DEBUG("mp4DataDup: Failed to open file: %s\n", file);
- return NULL;
- }
-
- cb = xmalloc(sizeof(mp4ff_callback_t));
- cb->read = mp4_inputStreamReadCallback;
- cb->seek = mp4_inputStreamSeekCallback;
- cb->user_data = &inStream;
-
- mp4fh = mp4ff_open_read(cb);
- if (!mp4fh) {
- free(cb);
- closeInputStream(&inStream);
- return NULL;
- }
-
- track = mp4_getAACTrack(mp4fh);
- if (track < 0) {
- mp4ff_close(mp4fh);
- closeInputStream(&inStream);
- free(cb);
- return NULL;
- }
-
- ret = newMpdTag();
- time = mp4ff_get_track_duration_use_offsets(mp4fh, track);
- scale = mp4ff_time_scale(mp4fh, track);
- if (scale < 0) {
- mp4ff_close(mp4fh);
- closeInputStream(&inStream);
- free(cb);
- freeMpdTag(ret);
- return NULL;
- }
- ret->time = ((float)time) / scale + 0.5;
-
- for (i = 0; i < mp4ff_meta_get_num_items(mp4fh); i++) {
- char *item;
- char *value;
-
- mp4ff_meta_get_by_index(mp4fh, i, &item, &value);
-
- if (0 == strcasecmp("artist", item)) {
- addItemToMpdTag(ret, TAG_ITEM_ARTIST, value);
- *mp4MetadataFound = 1;
- } else if (0 == strcasecmp("title", item)) {
- addItemToMpdTag(ret, TAG_ITEM_TITLE, value);
- *mp4MetadataFound = 1;
- } else if (0 == strcasecmp("album", item)) {
- addItemToMpdTag(ret, TAG_ITEM_ALBUM, value);
- *mp4MetadataFound = 1;
- } else if (0 == strcasecmp("track", item)) {
- addItemToMpdTag(ret, TAG_ITEM_TRACK, value);
- *mp4MetadataFound = 1;
- } else if (0 == strcasecmp("disc", item)) { /* Is that the correct id? */
- addItemToMpdTag(ret, TAG_ITEM_DISC, value);
- *mp4MetadataFound = 1;
- } else if (0 == strcasecmp("genre", item)) {
- addItemToMpdTag(ret, TAG_ITEM_GENRE, value);
- *mp4MetadataFound = 1;
- } else if (0 == strcasecmp("date", item)) {
- addItemToMpdTag(ret, TAG_ITEM_DATE, value);
- *mp4MetadataFound = 1;
- }
-
- free(item);
- free(value);
- }
-
- mp4ff_close(mp4fh);
- closeInputStream(&inStream);
- free(cb);
-
- return ret;
-}
-
-static MpdTag *mp4TagDup(char *file)
-{
- MpdTag *ret = NULL;
- int mp4MetadataFound = 0;
-
- ret = mp4DataDup(file, &mp4MetadataFound);
- if (!ret)
- return NULL;
- if (!mp4MetadataFound) {
- MpdTag *temp = id3Dup(file);
- if (temp) {
- temp->time = ret->time;
- freeMpdTag(ret);
- ret = temp;
- }
- }
-
- return ret;
-}
-
-static char *mp4Suffixes[] = { "m4a", "mp4", NULL };
-
-InputPlugin mp4Plugin = {
- "mp4",
- NULL,
- NULL,
- NULL,
- NULL,
- mp4_decode,
- mp4TagDup,
- INPUT_PLUGIN_STREAM_FILE,
- mp4Suffixes,
- NULL
-};
-
-#else
-
-InputPlugin mp4Plugin;
-
-#endif /* HAVE_FAAD */
diff --git a/trunk/src/inputPlugins/mpc_plugin.c b/trunk/src/inputPlugins/mpc_plugin.c
deleted file mode 100644
index 885f6cfc9..000000000
--- a/trunk/src/inputPlugins/mpc_plugin.c
+++ /dev/null
@@ -1,359 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "../inputPlugin.h"
-
-#ifdef HAVE_MPCDEC
-
-#include "../utils.h"
-#include "../audio.h"
-#include "../log.h"
-#include "../pcm_utils.h"
-#include "../inputStream.h"
-#include "../outputBuffer.h"
-#include "../replayGain.h"
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <mpcdec/mpcdec.h>
-#include <errno.h>
-#include <math.h>
-
-typedef struct _MpcCallbackData {
- InputStream *inStream;
- DecoderControl *dc;
-} MpcCallbackData;
-
-static mpc_int32_t mpc_read_cb(void *vdata, void *ptr, mpc_int32_t size)
-{
- mpc_int32_t ret = 0;
- MpcCallbackData *data = (MpcCallbackData *) vdata;
-
- while (1) {
- ret = readFromInputStream(data->inStream, ptr, 1, size);
- if (ret == 0 && !inputStreamAtEOF(data->inStream) &&
- (data->dc && !data->dc->stop)) {
- my_usleep(10000);
- } else
- break;
- }
-
- return ret;
-}
-
-static mpc_bool_t mpc_seek_cb(void *vdata, mpc_int32_t offset)
-{
- MpcCallbackData *data = (MpcCallbackData *) vdata;
-
- return seekInputStream(data->inStream, offset, SEEK_SET) < 0 ? 0 : 1;
-}
-
-static mpc_int32_t mpc_tell_cb(void *vdata)
-{
- MpcCallbackData *data = (MpcCallbackData *) vdata;
-
- return (long)(data->inStream->offset);
-}
-
-static mpc_bool_t mpc_canseek_cb(void *vdata)
-{
- MpcCallbackData *data = (MpcCallbackData *) vdata;
-
- return data->inStream->seekable;
-}
-
-static mpc_int32_t mpc_getsize_cb(void *vdata)
-{
- MpcCallbackData *data = (MpcCallbackData *) vdata;
-
- return data->inStream->size;
-}
-
-/* this _looks_ performance-critical, don't de-inline -- eric */
-static inline mpd_sint16 convertSample(MPC_SAMPLE_FORMAT sample)
-{
- /* only doing 16-bit audio for now */
- mpd_sint32 val;
-
- const int clip_min = -1 << (16 - 1);
- const int clip_max = (1 << (16 - 1)) - 1;
-
-#ifdef MPC_FIXED_POINT
- const int shift = 16 - MPC_FIXED_POINT_SCALE_SHIFT;
-
- if (sample > 0) {
- sample <<= shift;
- } else if (shift < 0) {
- sample >>= -shift;
- }
- val = sample;
-#else
- const int float_scale = 1 << (16 - 1);
-
- val = sample * float_scale;
-#endif
-
- if (val < clip_min)
- val = clip_min;
- else if (val > clip_max)
- val = clip_max;
-
- return val;
-}
-
-static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
- InputStream * inStream)
-{
- mpc_decoder decoder;
- mpc_reader reader;
- mpc_streaminfo info;
-
- MpcCallbackData data;
-
- MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH];
-
- int eof = 0;
- long ret;
-#define MPC_CHUNK_SIZE 4096
- char chunk[MPC_CHUNK_SIZE];
- int chunkpos = 0;
- long bitRate = 0;
- mpd_sint16 *s16 = (mpd_sint16 *) chunk;
- unsigned long samplePos = 0;
- mpc_uint32_t vbrUpdateAcc;
- mpc_uint32_t vbrUpdateBits;
- float time;
- int i;
- ReplayGainInfo *replayGainInfo = NULL;
-
- data.inStream = inStream;
- data.dc = dc;
-
- reader.read = mpc_read_cb;
- reader.seek = mpc_seek_cb;
- reader.tell = mpc_tell_cb;
- reader.get_size = mpc_getsize_cb;
- reader.canseek = mpc_canseek_cb;
- reader.data = &data;
-
- mpc_streaminfo_init(&info);
-
- if ((ret = mpc_streaminfo_read(&info, &reader)) != ERROR_CODE_OK) {
- closeInputStream(inStream);
- if (!dc->stop) {
- ERROR("Not a valid musepack stream");
- return -1;
- } else {
- dc->state = DECODE_STATE_STOP;
- dc->stop = 0;
- }
- return 0;
- }
-
- mpc_decoder_setup(&decoder, &reader);
-
- if (!mpc_decoder_initialize(&decoder, &info)) {
- closeInputStream(inStream);
- if (!dc->stop) {
- ERROR("Not a valid musepack stream");
- } else {
- dc->state = DECODE_STATE_STOP;
- dc->stop = 0;
- }
- }
-
- dc->totalTime = mpc_streaminfo_get_length(&info);
-
- dc->audioFormat.bits = 16;
- dc->audioFormat.channels = info.channels;
- dc->audioFormat.sampleRate = info.sample_freq;
-
- getOutputAudioFormat(&(dc->audioFormat), &(cb->audioFormat));
-
- replayGainInfo = newReplayGainInfo();
- replayGainInfo->albumGain = info.gain_album * 0.01;
- replayGainInfo->albumPeak = info.peak_album / 32767.0;
- replayGainInfo->trackGain = info.gain_title * 0.01;
- replayGainInfo->trackPeak = info.peak_title / 32767.0;
-
- dc->state = DECODE_STATE_DECODE;
-
- while (!eof) {
- if (dc->seek) {
- samplePos = dc->seekWhere * dc->audioFormat.sampleRate;
- if (mpc_decoder_seek_sample(&decoder, samplePos)) {
- clearOutputBuffer(cb);
- s16 = (mpd_sint16 *) chunk;
- chunkpos = 0;
- } else
- dc->seekError = 1;
- dc->seek = 0;
- }
-
- vbrUpdateAcc = 0;
- vbrUpdateBits = 0;
- ret = mpc_decoder_decode(&decoder, sample_buffer,
- &vbrUpdateAcc, &vbrUpdateBits);
-
- if (ret <= 0 || dc->stop) {
- eof = 1;
- break;
- }
-
- samplePos += ret;
-
- /* ret is in samples, and we have stereo */
- ret *= 2;
-
- for (i = 0; i < ret; i++) {
- /* 16 bit audio again */
- *s16 = convertSample(sample_buffer[i]);
- chunkpos += 2;
- s16++;
-
- if (chunkpos >= MPC_CHUNK_SIZE) {
- time = ((float)samplePos) /
- dc->audioFormat.sampleRate;
-
- bitRate = vbrUpdateBits *
- dc->audioFormat.sampleRate / 1152 / 1000;
-
- sendDataToOutputBuffer(cb, inStream, dc,
- inStream->seekable,
- chunk, chunkpos,
- time,
- bitRate, replayGainInfo);
-
- chunkpos = 0;
- s16 = (mpd_sint16 *) chunk;
- if (dc->stop) {
- eof = 1;
- break;
- }
- }
- }
- }
-
- if (!dc->stop && chunkpos > 0) {
- time = ((float)samplePos) / dc->audioFormat.sampleRate;
-
- bitRate =
- vbrUpdateBits * dc->audioFormat.sampleRate / 1152 / 1000;
-
- sendDataToOutputBuffer(cb, NULL, dc, inStream->seekable,
- chunk, chunkpos, time, bitRate,
- replayGainInfo);
- }
-
- closeInputStream(inStream);
-
- flushOutputBuffer(cb);
-
- freeReplayGainInfo(replayGainInfo);
-
- if (dc->stop) {
- dc->state = DECODE_STATE_STOP;
- dc->stop = 0;
- } else {
- dc->state = DECODE_STATE_STOP;
- }
-
- return 0;
-}
-
-static float mpcGetTime(char *file)
-{
- InputStream inStream;
- float time = -1;
-
- mpc_reader reader;
- mpc_streaminfo info;
- MpcCallbackData data;
-
- data.inStream = &inStream;
- data.dc = NULL;
-
- reader.read = mpc_read_cb;
- reader.seek = mpc_seek_cb;
- reader.tell = mpc_tell_cb;
- reader.get_size = mpc_getsize_cb;
- reader.canseek = mpc_canseek_cb;
- reader.data = &data;
-
- mpc_streaminfo_init(&info);
-
- if (openInputStream(&inStream, file) < 0) {
- DEBUG("mpcGetTime: Failed to open file: %s\n", file);
- return -1;
- }
-
- if (mpc_streaminfo_read(&info, &reader) != ERROR_CODE_OK) {
- closeInputStream(&inStream);
- return -1;
- }
-
- time = mpc_streaminfo_get_length(&info);
-
- closeInputStream(&inStream);
-
- return time;
-}
-
-static MpdTag *mpcTagDup(char *file)
-{
- MpdTag *ret = NULL;
- float time = mpcGetTime(file);
-
- if (time < 0) {
- DEBUG("mpcTagDup: Failed to get Songlength of file: %s\n",
- file);
- return NULL;
- }
-
- ret = apeDup(file);
- if (!ret)
- ret = id3Dup(file);
- if (!ret)
- ret = newMpdTag();
- ret->time = time;
-
- return ret;
-}
-
-static char *mpcSuffixes[] = { "mpc", NULL };
-
-InputPlugin mpcPlugin = {
- "mpc",
- NULL,
- NULL,
- NULL,
- mpc_decode,
- NULL,
- mpcTagDup,
- INPUT_PLUGIN_STREAM_URL | INPUT_PLUGIN_STREAM_FILE,
- mpcSuffixes,
- NULL
-};
-
-#else
-
-InputPlugin mpcPlugin;
-
-#endif /* HAVE_MPCDEC */
diff --git a/trunk/src/inputPlugins/oggflac_plugin.c b/trunk/src/inputPlugins/oggflac_plugin.c
deleted file mode 100644
index 58eb0a5f7..000000000
--- a/trunk/src/inputPlugins/oggflac_plugin.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * OggFLAC support (half-stolen from flac_plugin.c :))
- * (c) 2005 by Eric Wong <normalperson@yhbt.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "_flac_common.h"
-
-#ifdef HAVE_OGGFLAC
-
-#include "_ogg_common.h"
-
-#include "../utils.h"
-#include "../log.h"
-#include "../pcm_utils.h"
-#include "../inputStream.h"
-#include "../outputBuffer.h"
-#include "../replayGain.h"
-#include "../audio.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-static void oggflac_cleanup(InputStream * inStream,
- FlacData * data,
- OggFLAC__SeekableStreamDecoder * decoder)
-{
- if (data->replayGainInfo)
- freeReplayGainInfo(data->replayGainInfo);
- if (decoder)
- OggFLAC__seekable_stream_decoder_delete(decoder);
- closeInputStream(inStream);
-}
-
-static OggFLAC__SeekableStreamDecoderReadStatus of_read_cb(const
- OggFLAC__SeekableStreamDecoder
- * decoder,
- FLAC__byte buf[],
- unsigned *bytes,
- void *fdata)
-{
- FlacData *data = (FlacData *) fdata;
- size_t r;
-
- while (1) {
- r = readFromInputStream(data->inStream, (void *)buf, 1, *bytes);
- if (r == 0 && !inputStreamAtEOF(data->inStream) &&
- !data->dc->stop)
- my_usleep(10000);
- else
- break;
- }
- *bytes = r;
-
- if (r == 0 && !inputStreamAtEOF(data->inStream) && !data->dc->stop)
- return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
-
- return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
-}
-
-static OggFLAC__SeekableStreamDecoderSeekStatus of_seek_cb(const
- OggFLAC__SeekableStreamDecoder
- * decoder,
- FLAC__uint64 offset,
- void *fdata)
-{
- FlacData *data = (FlacData *) fdata;
-
- if (seekInputStream(data->inStream, offset, SEEK_SET) < 0) {
- return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
- }
-
- return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
-}
-
-static OggFLAC__SeekableStreamDecoderTellStatus of_tell_cb(const
- OggFLAC__SeekableStreamDecoder
- * decoder,
- FLAC__uint64 *
- offset, void *fdata)
-{
- FlacData *data = (FlacData *) fdata;
-
- *offset = (long)(data->inStream->offset);
-
- return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
-}
-
-static OggFLAC__SeekableStreamDecoderLengthStatus of_length_cb(const
- OggFLAC__SeekableStreamDecoder
- * decoder,
- FLAC__uint64 *
- length,
- void *fdata)
-{
- FlacData *data = (FlacData *) fdata;
-
- *length = (size_t) (data->inStream->size);
-
- return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
-}
-
-static FLAC__bool of_EOF_cb(const OggFLAC__SeekableStreamDecoder * decoder,
- void *fdata)
-{
- FlacData *data = (FlacData *) fdata;
-
- if (inputStreamAtEOF(data->inStream) == 1)
- return true;
- return false;
-}
-
-static void of_error_cb(const OggFLAC__SeekableStreamDecoder * decoder,
- FLAC__StreamDecoderErrorStatus status, void *fdata)
-{
- flac_error_common_cb("oggflac", status, (FlacData *) fdata);
-}
-
-static void oggflacPrintErroredState(OggFLAC__SeekableStreamDecoderState state)
-{
- switch (state) {
- case OggFLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
- ERROR("oggflac allocation error\n");
- break;
- case OggFLAC__SEEKABLE_STREAM_DECODER_READ_ERROR:
- ERROR("oggflac read error\n");
- break;
- case OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR:
- ERROR("oggflac seek error\n");
- break;
- case OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR:
- ERROR("oggflac seekable stream error\n");
- break;
- case OggFLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED:
- ERROR("oggflac decoder already initialized\n");
- break;
- case OggFLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK:
- ERROR("invalid oggflac callback\n");
- break;
- case OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED:
- ERROR("oggflac decoder uninitialized\n");
- break;
- case OggFLAC__SEEKABLE_STREAM_DECODER_OK:
- case OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING:
- case OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM:
- break;
- }
-}
-
-static FLAC__StreamDecoderWriteStatus oggflacWrite(const
- OggFLAC__SeekableStreamDecoder
- * decoder,
- const FLAC__Frame * frame,
- const FLAC__int32 *
- const buf[], void *vdata)
-{
- FlacData *data = (FlacData *) vdata;
- FLAC__uint32 samples = frame->header.blocksize;
- FLAC__uint16 u16;
- unsigned char *uc;
- int c_samp, c_chan, d_samp;
- int i;
- float timeChange;
-
- timeChange = ((float)samples) / frame->header.sample_rate;
- data->time += timeChange;
-
- /* ogg123 uses a complicated method of calculating bitrate
- * with averaging which I'm not too fond of.
- * (waste of memory/CPU cycles, especially given this is _lossless_)
- * a get_decode_position() is not available in OggFLAC, either
- *
- * this does not give an accurate bitrate:
- * (bytes_last_read was set in the read callback)
- data->bitRate = ((8.0 * data->bytes_last_read *
- frame->header.sample_rate)
- /((float)samples * 1000)) + 0.5;
- */
-
- for (c_samp = d_samp = 0; c_samp < frame->header.blocksize; c_samp++) {
- for (c_chan = 0; c_chan < frame->header.channels;
- c_chan++, d_samp++) {
- u16 = buf[c_chan][c_samp];
- uc = (unsigned char *)&u16;
- for (i = 0; i < (data->dc->audioFormat.bits / 8); i++) {
- if (data->chunk_length >= FLAC_CHUNK_SIZE) {
- if (flacSendChunk(data) < 0) {
- return
- FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
- }
- data->chunk_length = 0;
- if (data->dc->seek) {
- return
- FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
- }
- }
- data->chunk[data->chunk_length++] = *(uc++);
- }
- }
- }
-
- return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
-}
-
-/* used by TagDup */
-static void of_metadata_dup_cb(const OggFLAC__SeekableStreamDecoder * decoder,
- const FLAC__StreamMetadata * block, void *vdata)
-{
- FlacData *data = (FlacData *) vdata;
-
- switch (block->type) {
- case FLAC__METADATA_TYPE_STREAMINFO:
- if (!data->tag)
- data->tag = newMpdTag();
- data->tag->time = ((float)block->data.stream_info.
- total_samples) /
- block->data.stream_info.sample_rate + 0.5;
- return;
- case FLAC__METADATA_TYPE_VORBIS_COMMENT:
- copyVorbisCommentBlockToMpdTag(block, data->tag);
- default:
- break;
- }
-}
-
-/* used by decode */
-static void of_metadata_decode_cb(const OggFLAC__SeekableStreamDecoder * dec,
- const FLAC__StreamMetadata * block,
- void *vdata)
-{
- flac_metadata_common_cb(block, (FlacData *) vdata);
-}
-
-static OggFLAC__SeekableStreamDecoder
- * full_decoder_init_and_read_metadata(FlacData * data,
- unsigned int metadata_only)
-{
- OggFLAC__SeekableStreamDecoder *decoder = NULL;
- unsigned int s = 1;
-
- if (!(decoder = OggFLAC__seekable_stream_decoder_new()))
- return NULL;
-
- if (metadata_only) {
- s &= OggFLAC__seekable_stream_decoder_set_metadata_callback
- (decoder, of_metadata_dup_cb);
- s &= OggFLAC__seekable_stream_decoder_set_metadata_respond
- (decoder, FLAC__METADATA_TYPE_STREAMINFO);
- } else {
- s &= OggFLAC__seekable_stream_decoder_set_metadata_callback
- (decoder, of_metadata_decode_cb);
- }
-
- s &= OggFLAC__seekable_stream_decoder_set_read_callback(decoder,
- of_read_cb);
- s &= OggFLAC__seekable_stream_decoder_set_seek_callback(decoder,
- of_seek_cb);
- s &= OggFLAC__seekable_stream_decoder_set_tell_callback(decoder,
- of_tell_cb);
- s &= OggFLAC__seekable_stream_decoder_set_length_callback(decoder,
- of_length_cb);
- s &= OggFLAC__seekable_stream_decoder_set_eof_callback(decoder,
- of_EOF_cb);
- s &= OggFLAC__seekable_stream_decoder_set_write_callback(decoder,
- oggflacWrite);
- s &= OggFLAC__seekable_stream_decoder_set_metadata_respond(decoder,
- FLAC__METADATA_TYPE_VORBIS_COMMENT);
- s &= OggFLAC__seekable_stream_decoder_set_error_callback(decoder,
- of_error_cb);
- s &= OggFLAC__seekable_stream_decoder_set_client_data(decoder,
- (void *)data);
-
- if (!s) {
- ERROR("oggflac problem before init()\n");
- goto fail;
- }
- if (OggFLAC__seekable_stream_decoder_init(decoder) !=
- OggFLAC__SEEKABLE_STREAM_DECODER_OK) {
- ERROR("oggflac problem doing init()\n");
- goto fail;
- }
- if (!OggFLAC__seekable_stream_decoder_process_until_end_of_metadata
- (decoder)) {
- ERROR("oggflac problem reading metadata\n");
- goto fail;
- }
-
- return decoder;
-
-fail:
- oggflacPrintErroredState(OggFLAC__seekable_stream_decoder_get_state
- (decoder));
- OggFLAC__seekable_stream_decoder_delete(decoder);
- return NULL;
-}
-
-/* public functions: */
-static MpdTag *oggflac_TagDup(char *file)
-{
- InputStream inStream;
- OggFLAC__SeekableStreamDecoder *decoder;
- FlacData data;
-
- if (openInputStream(&inStream, file) < 0)
- return NULL;
- if (ogg_stream_type_detect(&inStream) != FLAC) {
- closeInputStream(&inStream);
- return NULL;
- }
-
- init_FlacData(&data, NULL, NULL, &inStream);
-
- /* errors here won't matter,
- * data.tag will be set or unset, that's all we care about */
- decoder = full_decoder_init_and_read_metadata(&data, 1);
-
- oggflac_cleanup(&inStream, &data, decoder);
-
- return data.tag;
-}
-
-static unsigned int oggflac_try_decode(InputStream * inStream)
-{
- return (ogg_stream_type_detect(inStream) == FLAC) ? 1 : 0;
-}
-
-static int oggflac_decode(OutputBuffer * cb, DecoderControl * dc,
- InputStream * inStream)
-{
- OggFLAC__SeekableStreamDecoder *decoder = NULL;
- FlacData data;
- int ret = 0;
-
- init_FlacData(&data, cb, dc, inStream);
-
- if (!(decoder = full_decoder_init_and_read_metadata(&data, 0))) {
- ret = -1;
- goto fail;
- }
-
- dc->state = DECODE_STATE_DECODE;
-
- while (1) {
- OggFLAC__seekable_stream_decoder_process_single(decoder);
- if (OggFLAC__seekable_stream_decoder_get_state(decoder) !=
- OggFLAC__SEEKABLE_STREAM_DECODER_OK) {
- break;
- }
- if (dc->seek) {
- FLAC__uint64 sampleToSeek = dc->seekWhere *
- dc->audioFormat.sampleRate + 0.5;
- if (OggFLAC__seekable_stream_decoder_seek_absolute
- (decoder, sampleToSeek)) {
- clearOutputBuffer(cb);
- data.time = ((float)sampleToSeek) /
- dc->audioFormat.sampleRate;
- data.position = 0;
- } else
- dc->seekError = 1;
- dc->seek = 0;
- }
- }
-
- if (!dc->stop) {
- oggflacPrintErroredState
- (OggFLAC__seekable_stream_decoder_get_state(decoder));
- OggFLAC__seekable_stream_decoder_finish(decoder);
- }
- /* send last little bit */
- if (data.chunk_length > 0 && !dc->stop) {
- flacSendChunk(&data);
- flushOutputBuffer(data.cb);
- }
-
- dc->state = DECODE_STATE_STOP;
- dc->stop = 0;
-
-fail:
- oggflac_cleanup(inStream, &data, decoder);
-
- return ret;
-}
-
-static char *oggflac_Suffixes[] = { "ogg", NULL };
-static char *oggflac_mime_types[] = { "audio/x-flac+ogg",
- "application/ogg",
- "application/x-ogg",
- NULL };
-
-InputPlugin oggflacPlugin = {
- "oggflac",
- NULL,
- NULL,
- oggflac_try_decode,
- oggflac_decode,
- NULL,
- oggflac_TagDup,
- INPUT_PLUGIN_STREAM_URL | INPUT_PLUGIN_STREAM_FILE,
- oggflac_Suffixes,
- oggflac_mime_types
-};
-
-#else /* !HAVE_FLAC */
-
-InputPlugin oggflacPlugin;
-
-#endif /* HAVE_OGGFLAC */
diff --git a/trunk/src/inputPlugins/oggvorbis_plugin.c b/trunk/src/inputPlugins/oggvorbis_plugin.c
deleted file mode 100644
index 4b4b87c8a..000000000
--- a/trunk/src/inputPlugins/oggvorbis_plugin.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* TODO 'ogg' should probably be replaced with 'oggvorbis' in all instances */
-
-#include "../inputPlugin.h"
-
-#ifdef HAVE_OGGVORBIS
-
-#include "_ogg_common.h"
-
-#include "../utils.h"
-#include "../audio.h"
-#include "../log.h"
-#include "../pcm_utils.h"
-#include "../inputStream.h"
-#include "../outputBuffer.h"
-#include "../replayGain.h"
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef HAVE_TREMOR
-#include <vorbis/vorbisfile.h>
-#else
-#include <tremor/ivorbisfile.h>
-/* Macros to make Tremor's API look like libogg. Tremor always
- returns host-byte-order 16-bit signed data, and uses integer
- milliseconds where libogg uses double seconds.
-*/
-#define ov_read(VF, BUFFER, LENGTH, BIGENDIANP, WORD, SGNED, BITSTREAM) \
- ov_read(VF, BUFFER, LENGTH, BITSTREAM)
-#define ov_time_total(VF, I) ((double)ov_time_total(VF, I)/1000)
-#define ov_time_tell(VF) ((double)ov_time_tell(VF)/1000)
-#define ov_time_seek_page(VF, S) (ov_time_seek_page(VF, (S)*1000))
-#endif /* HAVE_TREMOR */
-
-#include <errno.h>
-
-#ifdef WORDS_BIGENDIAN
-#define OGG_DECODE_USE_BIGENDIAN 1
-#else
-#define OGG_DECODE_USE_BIGENDIAN 0
-#endif
-
-typedef struct _OggCallbackData {
- InputStream *inStream;
- DecoderControl *dc;
-} OggCallbackData;
-
-static size_t ogg_read_cb(void *ptr, size_t size, size_t nmemb, void *vdata)
-{
- size_t ret = 0;
- OggCallbackData *data = (OggCallbackData *) vdata;
-
- while (1) {
- ret = readFromInputStream(data->inStream, ptr, size, nmemb);
- if (ret == 0 && !inputStreamAtEOF(data->inStream) &&
- !data->dc->stop) {
- my_usleep(10000);
- } else
- break;
- }
- errno = 0;
- /*if(ret<0) errno = ((InputStream *)inStream)->error; */
-
- return ret;
-}
-
-static int ogg_seek_cb(void *vdata, ogg_int64_t offset, int whence)
-{
- OggCallbackData *data = (OggCallbackData *) vdata;
-
- return seekInputStream(data->inStream, offset, whence);
-}
-
-static int ogg_close_cb(void *vdata)
-{
- OggCallbackData *data = (OggCallbackData *) vdata;
-
- return closeInputStream(data->inStream);
-}
-
-static long ogg_tell_cb(void *vdata)
-{
- OggCallbackData *data = (OggCallbackData *) vdata;
-
- return (long)(data->inStream->offset);
-}
-
-static char *ogg_parseComment(char *comment, char *needle)
-{
- int len = strlen(needle);
-
- if (strncasecmp(comment, needle, len) == 0 && *(comment + len) == '=') {
- return comment + len + 1;
- }
-
- return NULL;
-}
-
-static void ogg_getReplayGainInfo(char **comments, ReplayGainInfo ** infoPtr)
-{
- char *temp;
- int found = 0;
-
- if (*infoPtr)
- freeReplayGainInfo(*infoPtr);
- *infoPtr = newReplayGainInfo();
-
- while (*comments) {
- if ((temp =
- ogg_parseComment(*comments, "replaygain_track_gain"))) {
- (*infoPtr)->trackGain = atof(temp);
- found = 1;
- } else if ((temp = ogg_parseComment(*comments,
- "replaygain_album_gain"))) {
- (*infoPtr)->albumGain = atof(temp);
- found = 1;
- } else if ((temp = ogg_parseComment(*comments,
- "replaygain_track_peak"))) {
- (*infoPtr)->trackPeak = atof(temp);
- found = 1;
- } else if ((temp = ogg_parseComment(*comments,
- "replaygain_album_peak"))) {
- (*infoPtr)->albumPeak = atof(temp);
- found = 1;
- }
-
- comments++;
- }
-
- if (!found) {
- freeReplayGainInfo(*infoPtr);
- *infoPtr = NULL;
- }
-}
-
-static const char *VORBIS_COMMENT_TRACK_KEY = "tracknumber";
-static const char *VORBIS_COMMENT_DISC_KEY = "discnumber";
-
-static unsigned int ogg_parseCommentAddToTag(char *comment,
- unsigned int itemType,
- MpdTag ** tag)
-{
- const char *needle;
- unsigned int len;
- switch (itemType) {
- case TAG_ITEM_TRACK:
- needle = VORBIS_COMMENT_TRACK_KEY;
- break;
- case TAG_ITEM_DISC:
- needle = VORBIS_COMMENT_DISC_KEY;
- break;
- default:
- needle = mpdTagItemKeys[itemType];
- }
- len = strlen(needle);
-
- if (strncasecmp(comment, needle, len) == 0 && *(comment + len) == '=') {
- if (!*tag)
- *tag = newMpdTag();
-
- addItemToMpdTag(*tag, itemType, comment + len + 1);
-
- return 1;
- }
-
- return 0;
-}
-
-static MpdTag *oggCommentsParse(char **comments)
-{
- MpdTag *tag = NULL;
-
- while (*comments) {
- int j;
- for (j = TAG_NUM_OF_ITEM_TYPES; --j >= 0;) {
- if (ogg_parseCommentAddToTag(*comments, j, &tag))
- break;
- }
- comments++;
- }
-
- return tag;
-}
-
-static void putOggCommentsIntoOutputBuffer(OutputBuffer * cb, char *streamName,
- char **comments)
-{
- MpdTag *tag;
-
- tag = oggCommentsParse(comments);
- if (!tag && streamName) {
- tag = newMpdTag();
- }
- if (!tag)
- return;
-
- /*if(tag->artist) printf("Artist: %s\n", tag->artist);
- if(tag->album) printf("Album: %s\n", tag->album);
- if(tag->track) printf("Track: %s\n", tag->track);
- if(tag->title) printf("Title: %s\n", tag->title); */
-
- if (streamName) {
- clearItemsFromMpdTag(tag, TAG_ITEM_NAME);
- addItemToMpdTag(tag, TAG_ITEM_NAME, streamName);
- }
-
- copyMpdTagToOutputBuffer(cb, tag);
-
- freeMpdTag(tag);
-}
-
-/* public */
-static int oggvorbis_decode(OutputBuffer * cb, DecoderControl * dc,
- InputStream * inStream)
-{
- OggVorbis_File vf;
- ov_callbacks callbacks;
- OggCallbackData data;
- int current_section;
- int prev_section = -1;
- int eof = 0;
- long ret;
-#define OGG_CHUNK_SIZE 4096
- char chunk[OGG_CHUNK_SIZE];
- int chunkpos = 0;
- long bitRate = 0;
- long test;
- ReplayGainInfo *replayGainInfo = NULL;
- char **comments;
- char *errorStr;
-
- data.inStream = inStream;
- data.dc = dc;
-
- callbacks.read_func = ogg_read_cb;
- callbacks.seek_func = ogg_seek_cb;
- callbacks.close_func = ogg_close_cb;
- callbacks.tell_func = ogg_tell_cb;
-
- if ((ret = ov_open_callbacks(&data, &vf, NULL, 0, callbacks)) < 0) {
- closeInputStream(inStream);
- if (!dc->stop) {
- switch (ret) {
- case OV_EREAD:
- errorStr = "read error";
- break;
- case OV_ENOTVORBIS:
- errorStr = "not vorbis stream";
- break;
- case OV_EVERSION:
- errorStr = "vorbis version mismatch";
- break;
- case OV_EBADHEADER:
- errorStr = "invalid vorbis header";
- break;
- case OV_EFAULT:
- errorStr = "internal logic error";
- break;
- default:
- errorStr = "unknown error";
- break;
- }
- ERROR("Error decoding Ogg Vorbis stream: %s\n",
- errorStr);
- return -1;
- } else {
- dc->state = DECODE_STATE_STOP;
- dc->stop = 0;
- }
- return 0;
- }
-
- dc->totalTime = ov_time_total(&vf, -1);
- if (dc->totalTime < 0)
- dc->totalTime = 0;
-
- dc->audioFormat.bits = 16;
-
- while (!eof) {
- if (dc->seek) {
- if (0 == ov_time_seek_page(&vf, dc->seekWhere)) {
- clearOutputBuffer(cb);
- chunkpos = 0;
- } else
- dc->seekError = 1;
- dc->seek = 0;
- }
- ret = ov_read(&vf, chunk + chunkpos,
- OGG_CHUNK_SIZE - chunkpos,
- OGG_DECODE_USE_BIGENDIAN, 2, 1, &current_section);
-
- if (current_section != prev_section) {
- /*printf("new song!\n"); */
- vorbis_info *vi = ov_info(&vf, -1);
- dc->audioFormat.channels = vi->channels;
- dc->audioFormat.sampleRate = vi->rate;
- if (dc->state == DECODE_STATE_START) {
- getOutputAudioFormat(&(dc->audioFormat),
- &(cb->audioFormat));
- dc->state = DECODE_STATE_DECODE;
- }
- comments = ov_comment(&vf, -1)->user_comments;
- putOggCommentsIntoOutputBuffer(cb, inStream->metaName,
- comments);
- ogg_getReplayGainInfo(comments, &replayGainInfo);
- }
-
- prev_section = current_section;
-
- if (ret <= 0 && ret != OV_HOLE) {
- eof = 1;
- break;
- }
- if (ret == OV_HOLE)
- ret = 0;
-
- chunkpos += ret;
-
- if (chunkpos >= OGG_CHUNK_SIZE) {
- if ((test = ov_bitrate_instant(&vf)) > 0) {
- bitRate = test / 1000;
- }
- sendDataToOutputBuffer(cb, inStream, dc,
- inStream->seekable,
- chunk, chunkpos,
- ov_pcm_tell(&vf) /
- dc->audioFormat.sampleRate,
- bitRate, replayGainInfo);
- chunkpos = 0;
- if (dc->stop)
- break;
- }
- }
-
- if (!dc->stop && chunkpos > 0) {
- sendDataToOutputBuffer(cb, NULL, dc, inStream->seekable,
- chunk, chunkpos,
- ov_time_tell(&vf), bitRate,
- replayGainInfo);
- }
-
- if (replayGainInfo)
- freeReplayGainInfo(replayGainInfo);
-
- ov_clear(&vf);
-
- flushOutputBuffer(cb);
-
- if (dc->stop) {
- dc->state = DECODE_STATE_STOP;
- dc->stop = 0;
- } else
- dc->state = DECODE_STATE_STOP;
-
- return 0;
-}
-
-static MpdTag *oggvorbis_TagDup(char *file)
-{
- MpdTag *ret = NULL;
- FILE *fp;
- OggVorbis_File vf;
-
- fp = fopen(file, "r");
- if (!fp) {
- DEBUG("oggvorbis_TagDup: Failed to open file: '%s', %s\n",
- file, strerror(errno));
- return NULL;
- }
- if (ov_open(fp, &vf, NULL, 0) < 0) {
- fclose(fp);
- return NULL;
- }
-
- ret = oggCommentsParse(ov_comment(&vf, -1)->user_comments);
-
- if (!ret)
- ret = newMpdTag();
- ret->time = (int)(ov_time_total(&vf, -1) + 0.5);
-
- ov_clear(&vf);
-
- return ret;
-}
-
-static unsigned int oggvorbis_try_decode(InputStream * inStream)
-{
- return (ogg_stream_type_detect(inStream) == VORBIS) ? 1 : 0;
-}
-
-static char *oggvorbis_Suffixes[] = { "ogg", NULL };
-static char *oggvorbis_MimeTypes[] = { "application/ogg",
- "audio/x-vorbis+ogg",
- "application/x-ogg",
- NULL };
-
-InputPlugin oggvorbisPlugin = {
- "oggvorbis",
- NULL,
- NULL,
- oggvorbis_try_decode,
- oggvorbis_decode,
- NULL,
- oggvorbis_TagDup,
- INPUT_PLUGIN_STREAM_URL | INPUT_PLUGIN_STREAM_FILE,
- oggvorbis_Suffixes,
- oggvorbis_MimeTypes
-};
-
-#else /* !HAVE_OGGVORBIS */
-
-InputPlugin oggvorbisPlugin;
-
-#endif /* HAVE_OGGVORBIS */
diff --git a/trunk/src/inputStream.c b/trunk/src/inputStream.c
deleted file mode 100644
index 013d75f17..000000000
--- a/trunk/src/inputStream.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "inputStream.h"
-
-#include "inputStream_file.h"
-#include "inputStream_http.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-void initInputStream(void)
-{
- inputStream_initFile();
- inputStream_initHttp();
-}
-
-int openInputStream(InputStream * inStream, char *url)
-{
- inStream->offset = 0;
- inStream->size = 0;
- inStream->error = 0;
- inStream->mime = NULL;
- inStream->seekable = 0;
- inStream->metaName = NULL;
- inStream->metaTitle = NULL;
-
- if (inputStream_fileOpen(inStream, url) == 0)
- return 0;
- if (inputStream_httpOpen(inStream, url) == 0)
- return 0;
-
- return -1;
-}
-
-int seekInputStream(InputStream * inStream, long offset, int whence)
-{
- return inStream->seekFunc(inStream, offset, whence);
-}
-
-size_t readFromInputStream(InputStream * inStream, void *ptr, size_t size,
- size_t nmemb)
-{
- return inStream->readFunc(inStream, ptr, size, nmemb);
-}
-
-int closeInputStream(InputStream * inStream)
-{
- if (inStream->mime)
- free(inStream->mime);
- if (inStream->metaName)
- free(inStream->metaName);
- if (inStream->metaTitle)
- free(inStream->metaTitle);
-
- return inStream->closeFunc(inStream);
-}
-
-int inputStreamAtEOF(InputStream * inStream)
-{
- return inStream->atEOFFunc(inStream);
-}
-
-int bufferInputStream(InputStream * inStream)
-{
- return inStream->bufferFunc(inStream);
-}
diff --git a/trunk/src/inputStream.h b/trunk/src/inputStream.h
deleted file mode 100644
index 74397f07f..000000000
--- a/trunk/src/inputStream.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef INPUT_STREAM_H
-#define INPUT_STREAM_H
-
-#include <stdlib.h>
-
-typedef struct _InputStream InputStream;
-
-typedef int (*InputStreamSeekFunc) (InputStream * inStream, long offset,
- int whence);
-typedef size_t(*InputStreamReadFunc) (InputStream * inStream, void *ptr,
- size_t size, size_t nmemb);
-typedef int (*InputStreamCloseFunc) (InputStream * inStream);
-typedef int (*InputStreamAtEOFFunc) (InputStream * inStream);
-typedef int (*InputStreamBufferFunc) (InputStream * inStream);
-
-struct _InputStream {
- int error;
- long offset;
- size_t size;
- char *mime;
- int seekable;
-
- /* don't touc this stuff */
- InputStreamSeekFunc seekFunc;
- InputStreamReadFunc readFunc;
- InputStreamCloseFunc closeFunc;
- InputStreamAtEOFFunc atEOFFunc;
- InputStreamBufferFunc bufferFunc;
- void *data;
- char *metaName;
- char *metaTitle;
-};
-
-void initInputStream(void);
-
-int isUrlSaneForInputStream(char *url);
-
-/* if an error occurs for these 3 functions, then -1 is returned and errno
- for the input stream is set */
-int openInputStream(InputStream * inStream, char *url);
-int seekInputStream(InputStream * inStream, long offset, int whence);
-int closeInputStream(InputStream * inStream);
-int inputStreamAtEOF(InputStream * inStream);
-
-/* return value: -1 is error, 1 inidicates stuff was buffered, 0 means nothing
- was buffered */
-int bufferInputStream(InputStream * inStream);
-
-size_t readFromInputStream(InputStream * inStream, void *ptr, size_t size,
- size_t nmemb);
-
-#endif
diff --git a/trunk/src/inputStream_file.c b/trunk/src/inputStream_file.c
deleted file mode 100644
index 389aaad01..000000000
--- a/trunk/src/inputStream_file.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "inputStream_file.h"
-
-#include "log.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <errno.h>
-#define _XOPEN_SOURCE 600
-#include <fcntl.h>
-
-void inputStream_initFile(void)
-{
-}
-
-int inputStream_fileOpen(InputStream * inStream, char *filename)
-{
- FILE *fp;
-
- fp = fopen(filename, "r");
- if (!fp) {
- inStream->error = errno;
- return -1;
- }
-
- inStream->seekable = 1;
-
- fseek(fp, 0, SEEK_END);
- inStream->size = ftell(fp);
- fseek(fp, 0, SEEK_SET);
-
-#ifdef POSIX_FADV_SEQUENTIAL
- posix_fadvise(fileno(fp), (off_t)0, inStream->size, POSIX_FADV_SEQUENTIAL);
-#endif
-
- inStream->data = fp;
- inStream->seekFunc = inputStream_fileSeek;
- inStream->closeFunc = inputStream_fileClose;
- inStream->readFunc = inputStream_fileRead;
- inStream->atEOFFunc = inputStream_fileAtEOF;
- inStream->bufferFunc = inputStream_fileBuffer;
-
- return 0;
-}
-
-int inputStream_fileSeek(InputStream * inStream, long offset, int whence)
-{
- if (fseek((FILE *) inStream->data, offset, whence) == 0) {
- inStream->offset = ftell((FILE *) inStream->data);
- } else {
- inStream->error = errno;
- return -1;
- }
-
- return 0;
-}
-
-size_t inputStream_fileRead(InputStream * inStream, void *ptr, size_t size,
- size_t nmemb)
-{
- size_t readSize;
-
- readSize = fread(ptr, size, nmemb, (FILE *) inStream->data);
- if (readSize <= 0 && ferror((FILE *) inStream->data)) {
- inStream->error = errno;
- DEBUG("inputStream_fileRead: error reading: %s\n",
- strerror(inStream->error));
- }
-
- inStream->offset = ftell((FILE *) inStream->data);
-
- return readSize;
-}
-
-int inputStream_fileClose(InputStream * inStream)
-{
- if (fclose((FILE *) inStream->data) < 0) {
- inStream->error = errno;
- return -1;
- }
-
- return 0;
-}
-
-int inputStream_fileAtEOF(InputStream * inStream)
-{
- if (feof((FILE *) inStream->data))
- return 1;
-
- if (ferror((FILE *) inStream->data) && inStream->error != EINTR) {
- return 1;
- }
-
- return 0;
-}
-
-int inputStream_fileBuffer(InputStream * inStream)
-{
- return 0;
-}
diff --git a/trunk/src/inputStream_file.h b/trunk/src/inputStream_file.h
deleted file mode 100644
index fad7ac26e..000000000
--- a/trunk/src/inputStream_file.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef INPUT_STREAM_FILE_H
-#define INPUT_STREAM_FILE_H
-
-#include "inputStream.h"
-
-void inputStream_initFile(void);
-
-int inputStream_fileOpen(InputStream * inStream, char *filename);
-
-int inputStream_fileSeek(InputStream * inStream, long offset, int whence);
-
-size_t inputStream_fileRead(InputStream * inStream, void *ptr, size_t size,
- size_t nmemb);
-
-int inputStream_fileClose(InputStream * inStream);
-
-int inputStream_fileAtEOF(InputStream * inStream);
-
-int inputStream_fileBuffer(InputStream * inStream);
-
-#endif
diff --git a/trunk/src/inputStream_http.c b/trunk/src/inputStream_http.c
deleted file mode 100644
index 3f18575dd..000000000
--- a/trunk/src/inputStream_http.c
+++ /dev/null
@@ -1,912 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "inputStream_http.h"
-
-#include "utils.h"
-#include "log.h"
-#include "conf.h"
-
-#include <stdio.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-
-#define HTTP_CONN_STATE_CLOSED 0
-#define HTTP_CONN_STATE_INIT 1
-#define HTTP_CONN_STATE_HELLO 2
-#define HTTP_CONN_STATE_OPEN 3
-#define HTTP_CONN_STATE_REOPEN 4
-
-#define HTTP_BUFFER_SIZE_DEFAULT 131072
-#define HTTP_PREBUFFER_SIZE_DEFAULT (HTTP_BUFFER_SIZE_DEFAULT >> 2)
-
-#define HTTP_REDIRECT_MAX 10
-
-static char *proxyHost;
-static char *proxyPort;
-static char *proxyUser;
-static char *proxyPassword;
-static int bufferSize = HTTP_BUFFER_SIZE_DEFAULT;
-static int prebufferSize = HTTP_PREBUFFER_SIZE_DEFAULT;
-
-typedef struct _InputStreemHTTPData {
- char *host;
- char *path;
- char *port;
- int sock;
- int connState;
- char *buffer;
- size_t buflen;
- int timesRedirected;
- int icyMetaint;
- int prebuffer;
- int icyOffset;
- char *proxyAuth;
- char *httpAuth;
-} InputStreamHTTPData;
-
-void inputStream_initHttp(void)
-{
- ConfigParam *param = getConfigParam(CONF_HTTP_PROXY_HOST);
- char *test;
-
- if (param) {
- proxyHost = param->value;
-
- param = getConfigParam(CONF_HTTP_PROXY_PORT);
-
- if (!param) {
- FATAL("%s specified but not %s", CONF_HTTP_PROXY_HOST,
- CONF_HTTP_PROXY_PORT);
- }
- proxyPort = param->value;
-
- param = getConfigParam(CONF_HTTP_PROXY_USER);
-
- if (param) {
- proxyUser = param->value;
-
- param = getConfigParam(CONF_HTTP_PROXY_PASSWORD);
-
- if (!param) {
- FATAL("%s specified but not %s\n",
- CONF_HTTP_PROXY_USER,
- CONF_HTTP_PROXY_PASSWORD);
- }
-
- proxyPassword = param->value;
- } else {
- param = getConfigParam(CONF_HTTP_PROXY_PASSWORD);
-
- if (param) {
- FATAL("%s specified but not %s\n",
- CONF_HTTP_PROXY_PASSWORD, CONF_HTTP_PROXY_USER);
- }
- }
- } else if ((param = getConfigParam(CONF_HTTP_PROXY_PORT))) {
- FATAL("%s specified but not %s, line %i\n",
- CONF_HTTP_PROXY_PORT, CONF_HTTP_PROXY_HOST, param->line);
- } else if ((param = getConfigParam(CONF_HTTP_PROXY_USER))) {
- FATAL("%s specified but not %s, line %i\n",
- CONF_HTTP_PROXY_USER, CONF_HTTP_PROXY_HOST, param->line);
- } else if ((param = getConfigParam(CONF_HTTP_PROXY_PASSWORD))) {
- FATAL("%s specified but not %s, line %i\n",
- CONF_HTTP_PROXY_PASSWORD, CONF_HTTP_PROXY_HOST,
- param->line);
- }
-
- param = getConfigParam(CONF_HTTP_BUFFER_SIZE);
-
- if (param) {
- bufferSize = strtol(param->value, &test, 10);
-
- if (bufferSize <= 0 || *test != '\0') {
- FATAL("\"%s\" specified for %s at line %i is not a "
- "positive integer\n",
- param->value, CONF_HTTP_BUFFER_SIZE, param->line);
- }
-
- bufferSize *= 1024;
-
- if (prebufferSize > bufferSize)
- prebufferSize = bufferSize;
- }
-
- param = getConfigParam(CONF_HTTP_PREBUFFER_SIZE);
-
- if (param) {
- prebufferSize = strtol(param->value, &test, 10);
-
- if (prebufferSize <= 0 || *test != '\0') {
- FATAL("\"%s\" specified for %s at line %i is not a "
- "positive integer\n",
- param->value, CONF_HTTP_PREBUFFER_SIZE,
- param->line);
- }
-
- prebufferSize *= 1024;
- }
-
- if (prebufferSize > bufferSize)
- prebufferSize = bufferSize;
-}
-
-/* base64 code taken from xmms */
-
-#define BASE64_LENGTH(len) (4 * (((len) + 2) / 3))
-
-static char *base64Dup(char *s)
-{
- int i;
- int len = strlen(s);
- char *ret = xcalloc(BASE64_LENGTH(len) + 1, 1);
- unsigned char *p = (unsigned char *)ret;
-
- char tbl[64] = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
- 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
- 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
- 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
- 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
- 'w', 'x', 'y', 'z', '0', '1', '2', '3',
- '4', '5', '6', '7', '8', '9', '+', '/'
- };
-
- /* Transform the 3x8 bits to 4x6 bits, as required by base64. */
- for (i = 0; i < len; i += 3) {
- *p++ = tbl[s[0] >> 2];
- *p++ = tbl[((s[0] & 3) << 4) + (s[1] >> 4)];
- *p++ = tbl[((s[1] & 0xf) << 2) + (s[2] >> 6)];
- *p++ = tbl[s[2] & 0x3f];
- s += 3;
- }
- /* Pad the result if necessary... */
- if (i == len + 1)
- *(p - 1) = '=';
- else if (i == len + 2)
- *(p - 1) = *(p - 2) = '=';
- /* ...and zero-terminate it. */
- *p = '\0';
-
- return ret;
-}
-
-static char *authString(char *header, char *user, char *password)
-{
- char *ret = NULL;
- int templen;
- char *temp;
- char *temp64;
-
- if (!user || !password)
- return NULL;
-
- templen = strlen(user) + strlen(password) + 2;
- temp = xmalloc(templen);
- strcpy(temp, user);
- strcat(temp, ":");
- strcat(temp, password);
- temp64 = base64Dup(temp);
- free(temp);
-
- ret = xmalloc(strlen(temp64) + strlen(header) + 3);
- strcpy(ret, header);
- strcat(ret, temp64);
- strcat(ret, "\r\n");
- free(temp64);
-
- return ret;
-}
-
-#define PROXY_AUTH_HEADER "Proxy-Authorization: Basic "
-#define HTTP_AUTH_HEADER "Authorization: Basic "
-
-#define proxyAuthString(x, y) authString(PROXY_AUTH_HEADER, x, y)
-#define httpAuthString(x, y) authString(HTTP_AUTH_HEADER, x, y)
-
-static InputStreamHTTPData *newInputStreamHTTPData(void)
-{
- InputStreamHTTPData *ret = xmalloc(sizeof(InputStreamHTTPData));
-
- if (proxyHost) {
- ret->proxyAuth = proxyAuthString(proxyUser, proxyPassword);
- } else
- ret->proxyAuth = NULL;
-
- ret->httpAuth = NULL;
- ret->host = NULL;
- ret->path = NULL;
- ret->port = NULL;
- ret->connState = HTTP_CONN_STATE_CLOSED;
- ret->timesRedirected = 0;
- ret->icyMetaint = 0;
- ret->prebuffer = 0;
- ret->icyOffset = 0;
- ret->buffer = xmalloc(bufferSize);
-
- return ret;
-}
-
-static void freeInputStreamHTTPData(InputStreamHTTPData * data)
-{
- if (data->host)
- free(data->host);
- if (data->path)
- free(data->path);
- if (data->port)
- free(data->port);
- if (data->proxyAuth)
- free(data->proxyAuth);
- if (data->httpAuth)
- free(data->httpAuth);
-
- free(data->buffer);
-
- free(data);
-}
-
-static int parseUrl(InputStreamHTTPData * data, char *url)
-{
- char *temp;
- char *colon;
- char *slash;
- char *at;
- int len;
-
- if (strncmp("http://", url, strlen("http://")) != 0)
- return -1;
-
- temp = url + strlen("http://");
-
- colon = strchr(temp, ':');
- at = strchr(temp, '@');
-
- if (data->httpAuth) {
- free(data->httpAuth);
- data->httpAuth = NULL;
- }
-
- if (at) {
- char *user;
- char *passwd;
-
- if (colon && colon < at) {
- user = xmalloc(colon - temp + 1);
- memcpy(user, temp, colon - temp);
- user[colon - temp] = '\0';
-
- passwd = xmalloc(at - colon);
- memcpy(passwd, colon + 1, at - colon - 1);
- passwd[at - colon - 1] = '\0';
- } else {
- user = xmalloc(at - temp + 1);
- memcpy(user, temp, at - temp);
- user[at - temp] = '\0';
-
- passwd = xstrdup("");
- }
-
- data->httpAuth = httpAuthString(user, passwd);
-
- free(user);
- free(passwd);
-
- temp = at + 1;
- colon = strchr(temp, ':');
- }
-
- slash = strchr(temp, '/');
-
- if (slash && colon && slash <= colon)
- return -1;
-
- /* fetch the host portion */
- if (colon)
- len = colon - temp + 1;
- else if (slash)
- len = slash - temp + 1;
- else
- len = strlen(temp) + 1;
-
- if (len <= 1)
- return -1;
-
- data->host = xmalloc(len);
- memcpy(data->host, temp, len - 1);
- data->host[len - 1] = '\0';
- /* fetch the port */
- if (colon && (!slash || slash != colon + 1)) {
- len = strlen(colon) - 1;
- if (slash)
- len -= strlen(slash);
- data->port = xmalloc(len + 1);
- memcpy(data->port, colon + 1, len);
- data->port[len] = '\0';
- DEBUG(__FILE__ ": Port: %s\n", data->port);
- } else {
- data->port = xstrdup("80");
- }
-
- /* fetch the path */
- if (proxyHost)
- data->path = xstrdup(url);
- else
- data->path = xstrdup(slash ? slash : "/");
-
- return 0;
-}
-
-static int initHTTPConnection(InputStream * inStream)
-{
- char *connHost;
- char *connPort;
- struct addrinfo *ans = NULL;
- struct addrinfo *ap = NULL;
- struct addrinfo hints;
- int error, flags;
- InputStreamHTTPData *data = (InputStreamHTTPData *) inStream->data;
- /**
- * Setup hints
- */
- hints.ai_flags = 0;
- hints.ai_family = PF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
- hints.ai_addrlen = 0;
- hints.ai_addr = NULL;
- hints.ai_canonname = NULL;
- hints.ai_next = NULL;
-
- if (proxyHost) {
- connHost = proxyHost;
- connPort = proxyPort;
- } else {
- connHost = data->host;
- connPort = data->port;
- }
-
- error = getaddrinfo(connHost, connPort, &hints, &ans);
- if (error) {
- DEBUG(__FILE__ ": Error getting address info: %s\n",
- gai_strerror(error));
- return -1;
- }
-
- /* loop through possible addresses */
- for (ap = ans; ap != NULL; ap = ap->ai_next) {
- if ((data->sock = socket(ap->ai_family, ap->ai_socktype,
- ap->ai_protocol)) < 0) {
- DEBUG(__FILE__ ": unable to connect: %s\n",
- strerror(errno));
- freeaddrinfo(ans);
- return -1;
- }
-
- flags = fcntl(data->sock, F_GETFL, 0);
- fcntl(data->sock, F_SETFL, flags | O_NONBLOCK);
-
- if (connect(data->sock, ap->ai_addr, ap->ai_addrlen) >= 0
- || errno == EINPROGRESS) {
- data->connState = HTTP_CONN_STATE_INIT;
- data->buflen = 0;
- freeaddrinfo(ans);
- return 0; /* success */
- }
-
- /* failed, get the next one */
-
- DEBUG(__FILE__ ": unable to connect: %s\n", strerror(errno));
- close(data->sock);
- }
-
- freeaddrinfo(ans);
- return -1; /* failed */
-}
-
-static int finishHTTPInit(InputStream * inStream)
-{
- InputStreamHTTPData *data = (InputStreamHTTPData *) inStream->data;
- struct timeval tv;
- fd_set writeSet;
- fd_set errorSet;
- int error;
- socklen_t error_len = sizeof(int);
- int ret;
- int length;
- char request[2048];
-
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- FD_ZERO(&writeSet);
- FD_ZERO(&errorSet);
- FD_SET(data->sock, &writeSet);
- FD_SET(data->sock, &errorSet);
-
- ret = select(data->sock + 1, NULL, &writeSet, &errorSet, &tv);
-
- if (ret == 0 || (ret < 0 && errno == EINTR))
- return 0;
-
- if (ret < 0) {
- DEBUG(__FILE__ ": problem select'ing: %s\n", strerror(errno));
- goto close_err;
- }
-
- getsockopt(data->sock, SOL_SOCKET, SO_ERROR, &error, &error_len);
- if (error)
- goto close_err;
-
- /* deal with ICY metadata later, for now its fucking up stuff! */
- length = snprintf(request, sizeof(request),
- "GET %s HTTP/1.1\r\n" "Host: %s\r\n"
- /*"Connection: close\r\n" */
- "User-Agent: %s/%s\r\n"
- "Range: bytes=%ld-\r\n"
- "%s" /* authorization */
- "Icy-Metadata:1\r\n"
- "\r\n",
- data->path, data->host,
- PACKAGE_NAME, PACKAGE_VERSION,
- inStream->offset,
- data->proxyAuth ? data->proxyAuth :
- (data->httpAuth ? data->httpAuth : ""));
-
- if (length >= sizeof(request))
- goto close_err;
- ret = write(data->sock, request, length);
- if (ret != length)
- goto close_err;
-
- data->connState = HTTP_CONN_STATE_HELLO;
- return 0;
-
-close_err:
- close(data->sock);
- data->connState = HTTP_CONN_STATE_CLOSED;
- return -1;
-}
-
-static int getHTTPHello(InputStream * inStream)
-{
- InputStreamHTTPData *data = (InputStreamHTTPData *) inStream->data;
- fd_set readSet;
- struct timeval tv;
- int ret;
- char *needle;
- char *cur = data->buffer;
- int rc;
- long readed;
-
- FD_ZERO(&readSet);
- FD_SET(data->sock, &readSet);
-
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- ret = select(data->sock + 1, &readSet, NULL, NULL, &tv);
-
- if (ret == 0 || (ret < 0 && errno == EINTR))
- return 0;
-
- if (ret < 0) {
- data->connState = HTTP_CONN_STATE_CLOSED;
- close(data->sock);
- data->buflen = 0;
- return -1;
- }
-
- if (data->buflen >= bufferSize - 1) {
- data->connState = HTTP_CONN_STATE_CLOSED;
- close(data->sock);
- return -1;
- }
-
- readed = recv(data->sock, data->buffer + data->buflen,
- bufferSize - 1 - data->buflen, 0);
-
- if (readed < 0 && (errno == EAGAIN || errno == EINTR))
- return 0;
-
- if (readed <= 0) {
- data->connState = HTTP_CONN_STATE_CLOSED;
- close(data->sock);
- data->buflen = 0;
- return -1;
- }
-
- data->buffer[data->buflen + readed] = '\0';
- data->buflen += readed;
-
- needle = strstr(data->buffer, "\r\n\r\n");
-
- if (!needle)
- return 0;
-
- if (0 == strncmp(cur, "HTTP/1.0 ", 9)) {
- inStream->seekable = 0;
- rc = atoi(cur + 9);
- } else if (0 == strncmp(cur, "HTTP/1.1 ", 9)) {
- inStream->seekable = 1;
- rc = atoi(cur + 9);
- } else if (0 == strncmp(cur, "ICY 200 OK", 10)) {
- inStream->seekable = 0;
- rc = 200;
- } else if (0 == strncmp(cur, "ICY 400 Server Full", 19))
- rc = 400;
- else if (0 == strncmp(cur, "ICY 404", 7))
- rc = 404;
- else {
- close(data->sock);
- data->connState = HTTP_CONN_STATE_CLOSED;
- return -1;
- }
-
- switch (rc) {
- case 200:
- case 206:
- break;
- case 301:
- case 302:
- cur = strstr(cur, "Location: ");
- if (cur) {
- char *url;
- int curlen = 0;
- cur += strlen("Location: ");
- while (*(cur + curlen) != '\0'
- && *(cur + curlen) != '\r') {
- curlen++;
- }
- url = xmalloc(curlen + 1);
- memcpy(url, cur, curlen);
- url[curlen] = '\0';
- ret = parseUrl(data, url);
- free(url);
- if (ret == 0 && data->timesRedirected <
- HTTP_REDIRECT_MAX) {
- data->timesRedirected++;
- close(data->sock);
- data->connState = HTTP_CONN_STATE_REOPEN;
- data->buflen = 0;
- return 0;
- }
- }
- case 400:
- case 401:
- case 403:
- case 404:
- default:
- close(data->sock);
- data->connState = HTTP_CONN_STATE_CLOSED;
- data->buflen = 0;
- return -1;
- }
-
- cur = strstr(data->buffer, "\r\n");
- while (cur && cur != needle) {
- if (0 == strncmp(cur, "\r\nContent-Length: ", 18)) {
- if (!inStream->size)
- inStream->size = atol(cur + 18);
- } else if (0 == strncmp(cur, "\r\nicy-metaint:", 14)) {
- data->icyMetaint = atoi(cur + 14);
- } else if (0 == strncmp(cur, "\r\nicy-name:", 11) ||
- 0 == strncmp(cur, "\r\nice-name:", 11)) {
- int incr = 11;
- char *temp = strstr(cur + incr, "\r\n");
- if (!temp)
- break;
- *temp = '\0';
- if (inStream->metaName)
- free(inStream->metaName);
- while (*(incr + cur) == ' ')
- incr++;
- inStream->metaName = xstrdup(cur + incr);
- *temp = '\r';
- DEBUG("inputStream_http: metaName: %s\n",
- inStream->metaName);
- } else if (0 == strncmp(cur, "\r\nx-audiocast-name:", 19)) {
- int incr = 19;
- char *temp = strstr(cur + incr, "\r\n");
- if (!temp)
- break;
- *temp = '\0';
- if (inStream->metaName)
- free(inStream->metaName);
- while (*(incr + cur) == ' ')
- incr++;
- inStream->metaName = xstrdup(cur + incr);
- *temp = '\r';
- DEBUG("inputStream_http: metaName: %s\n",
- inStream->metaName);
- } else if (0 == strncmp(cur, "\r\nContent-Type:", 15)) {
- int incr = 15;
- char *temp = strstr(cur + incr, "\r\n");
- if (!temp)
- break;
- *temp = '\0';
- if (inStream->mime)
- free(inStream->mime);
- while (*(incr + cur) == ' ')
- incr++;
- inStream->mime = xstrdup(cur + incr);
- *temp = '\r';
- }
-
- cur = strstr(cur + 2, "\r\n");
- }
-
- if (inStream->size <= 0)
- inStream->seekable = 0;
-
- needle += 4; /* 4 == strlen("\r\n\r\n") */
- data->buflen -= (needle - data->buffer);
- /*fwrite(data->buffer, 1, data->buflen, stdout); */
- memmove(data->buffer, needle, data->buflen);
-
- data->connState = HTTP_CONN_STATE_OPEN;
-
- data->prebuffer = 1;
-
- return 0;
-}
-
-int inputStream_httpOpen(InputStream * inStream, char *url)
-{
- InputStreamHTTPData *data = newInputStreamHTTPData();
-
- inStream->data = data;
-
- if (parseUrl(data, url) < 0) {
- freeInputStreamHTTPData(data);
- return -1;
- }
-
- if (initHTTPConnection(inStream) < 0) {
- freeInputStreamHTTPData(data);
- return -1;
- }
-
- inStream->seekFunc = inputStream_httpSeek;
- inStream->closeFunc = inputStream_httpClose;
- inStream->readFunc = inputStream_httpRead;
- inStream->atEOFFunc = inputStream_httpAtEOF;
- inStream->bufferFunc = inputStream_httpBuffer;
-
- return 0;
-}
-
-int inputStream_httpSeek(InputStream * inStream, long offset, int whence)
-{
- InputStreamHTTPData *data;
-
- if (!inStream->seekable)
- return -1;
-
- switch (whence) {
- case SEEK_SET:
- inStream->offset = offset;
- break;
- case SEEK_CUR:
- inStream->offset += offset;
- break;
- case SEEK_END:
- inStream->offset = inStream->size + offset;
- break;
- default:
- return -1;
- }
-
- data = (InputStreamHTTPData *)inStream->data;
- close(data->sock);
- data->connState = HTTP_CONN_STATE_REOPEN;
- data->buflen = 0;
-
- inputStream_httpBuffer(inStream);
-
- return 0;
-}
-
-static void parseIcyMetadata(InputStream * inStream, char *metadata, int size)
-{
- char *r;
- char *s;
- char *temp = xmalloc(size + 1);
- memcpy(temp, metadata, size);
- temp[size] = '\0';
- s = strtok_r(temp, ";", &r);
- while (s) {
- if (0 == strncmp(s, "StreamTitle=", 12)) {
- int cur = 12;
- if (inStream->metaTitle)
- free(inStream->metaTitle);
- if (*(s + cur) == '\'')
- cur++;
- if (s[strlen(s) - 1] == '\'') {
- s[strlen(s) - 1] = '\0';
- }
- inStream->metaTitle = xstrdup(s + cur);
- DEBUG("inputStream_http: metaTitle: %s\n",
- inStream->metaTitle);
- }
- s = strtok_r(NULL, ";", &r);
- }
- free(temp);
-}
-
-size_t inputStream_httpRead(InputStream * inStream, void *ptr, size_t size,
- size_t nmemb)
-{
- InputStreamHTTPData *data = (InputStreamHTTPData *) inStream->data;
- long tosend = 0;
- long inlen = size * nmemb;
- long maxToSend = data->buflen;
-
- inputStream_httpBuffer(inStream);
-
- switch (data->connState) {
- case HTTP_CONN_STATE_OPEN:
- if (data->prebuffer || data->buflen < data->icyMetaint)
- return 0;
-
- break;
- case HTTP_CONN_STATE_CLOSED:
- if (data->buflen)
- break;
- default:
- return 0;
- }
-
- if (data->icyMetaint > 0) {
- if (data->icyOffset >= data->icyMetaint) {
- int metalen = *(data->buffer);
- metalen <<= 4;
- if (metalen < 0)
- metalen = 0;
- if (metalen + 1 > data->buflen) {
- /* damn that's some fucking big metadata! */
- if (bufferSize < metalen + 1) {
- data->connState =
- HTTP_CONN_STATE_CLOSED;
- close(data->sock);
- data->buflen = 0;
- }
- return 0;
- }
- if (metalen > 0) {
- parseIcyMetadata(inStream, data->buffer + 1,
- metalen);
- }
- data->buflen -= metalen + 1;
- memmove(data->buffer, data->buffer + metalen + 1,
- data->buflen);
- data->icyOffset = 0;
- }
- maxToSend = data->icyMetaint - data->icyOffset;
- maxToSend = maxToSend > data->buflen ? data->buflen : maxToSend;
- }
-
- if (data->buflen > 0) {
- tosend = inlen > maxToSend ? maxToSend : inlen;
- tosend = (tosend / size) * size;
-
- memcpy(ptr, data->buffer, tosend);
- /*fwrite(ptr,1,readed,stdout); */
- data->buflen -= tosend;
- data->icyOffset += tosend;
- /*fwrite(data->buffer,1,readed,stdout); */
- memmove(data->buffer, data->buffer + tosend, data->buflen);
-
- inStream->offset += tosend;
- }
-
- return tosend / size;
-}
-
-int inputStream_httpClose(InputStream * inStream)
-{
- InputStreamHTTPData *data = (InputStreamHTTPData *) inStream->data;
-
- switch (data->connState) {
- case HTTP_CONN_STATE_CLOSED:
- break;
- default:
- close(data->sock);
- }
-
- freeInputStreamHTTPData(data);
-
- return 0;
-}
-
-int inputStream_httpAtEOF(InputStream * inStream)
-{
- InputStreamHTTPData *data = (InputStreamHTTPData *) inStream->data;
- switch (data->connState) {
- case HTTP_CONN_STATE_CLOSED:
- if (data->buflen == 0)
- return 1;
- default:
- return 0;
- }
-}
-
-int inputStream_httpBuffer(InputStream * inStream)
-{
- InputStreamHTTPData *data = (InputStreamHTTPData *) inStream->data;
- ssize_t readed = 0;
-
- if (data->connState == HTTP_CONN_STATE_REOPEN) {
- if (initHTTPConnection(inStream) < 0)
- return -1;
- }
-
- if (data->connState == HTTP_CONN_STATE_INIT) {
- if (finishHTTPInit(inStream) < 0)
- return -1;
- }
-
- if (data->connState == HTTP_CONN_STATE_HELLO) {
- if (getHTTPHello(inStream) < 0)
- return -1;
- }
-
- switch (data->connState) {
- case HTTP_CONN_STATE_OPEN:
- case HTTP_CONN_STATE_CLOSED:
- break;
- default:
- return -1;
- }
-
- if (data->buflen == 0 || data->buflen < data->icyMetaint) {
- data->prebuffer = 1;
- } else if (data->buflen > prebufferSize)
- data->prebuffer = 0;
-
- if (data->connState == HTTP_CONN_STATE_OPEN &&
- data->buflen < bufferSize - 1) {
- readed = read(data->sock, data->buffer + data->buflen,
- (size_t) (bufferSize - 1 - data->buflen));
-
- if (readed < 0 && (errno == EAGAIN || errno == EINTR)) {
- readed = 0;
- } else if (readed <= 0) {
- close(data->sock);
- data->connState = HTTP_CONN_STATE_CLOSED;
- readed = 0;
- }
- /*fwrite(data->buffer+data->buflen,1,readed,stdout); */
- data->buflen += readed;
- }
-
- if (data->buflen > prebufferSize)
- data->prebuffer = 0;
-
- return (readed ? 1 : 0);
-}
diff --git a/trunk/src/inputStream_http.h b/trunk/src/inputStream_http.h
deleted file mode 100644
index 7ab23a5de..000000000
--- a/trunk/src/inputStream_http.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef INPUT_STREAM_HTTP_H
-#define INPUT_STREAM_HTTP_H
-
-#include "inputStream.h"
-
-void inputStream_initHttp(void);
-
-int inputStream_httpOpen(InputStream * inStream, char *filename);
-
-int inputStream_httpSeek(InputStream * inStream, long offset, int whence);
-
-size_t inputStream_httpRead(InputStream * inStream, void *ptr, size_t size,
- size_t nmemb);
-
-int inputStream_httpClose(InputStream * inStream);
-
-int inputStream_httpAtEOF(InputStream * inStream);
-
-int inputStream_httpBuffer(InputStream * inStream);
-
-#endif
diff --git a/trunk/src/interface.c b/trunk/src/interface.c
deleted file mode 100644
index 22660432f..000000000
--- a/trunk/src/interface.c
+++ /dev/null
@@ -1,851 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "interface.h"
-#include "command.h"
-#include "conf.h"
-#include "list.h"
-#include "log.h"
-#include "listen.h"
-#include "playlist.h"
-#include "permission.h"
-#include "sllist.h"
-#include "utils.h"
-#include "ioops.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <sys/select.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <signal.h>
-
-#define GREETING "OK MPD " PROTOCOL_VERSION "\n"
-
-#define INTERFACE_MAX_BUFFER_LENGTH (40960)
-#define INTERFACE_LIST_MODE_BEGIN "command_list_begin"
-#define INTERFACE_LIST_OK_MODE_BEGIN "command_list_ok_begin"
-#define INTERFACE_LIST_MODE_END "command_list_end"
-#define INTERFACE_DEFAULT_OUT_BUFFER_SIZE (4096)
-#define INTERFACE_TIMEOUT_DEFAULT (60)
-#define INTERFACE_MAX_CONNECTIONS_DEFAULT (10)
-#define INTERFACE_MAX_COMMAND_LIST_DEFAULT (2048*1024)
-#define INTERFACE_MAX_OUTPUT_BUFFER_SIZE_DEFAULT (8192*1024)
-
-/* set this to zero to indicate we have no possible interfaces */
-static int interface_max_connections; /*INTERFACE_MAX_CONNECTIONS_DEFAULT; */
-static int interface_timeout = INTERFACE_TIMEOUT_DEFAULT;
-static size_t interface_max_command_list_size =
- INTERFACE_MAX_COMMAND_LIST_DEFAULT;
-static size_t interface_max_output_buffer_size =
- INTERFACE_MAX_OUTPUT_BUFFER_SIZE_DEFAULT;
-
-/* List of registered external IO handlers */
-static struct ioOps *ioList;
-
-/* maybe make conf option for this, or... 32 might be good enough */
-static long int interface_list_cache_size = 32;
-
-/* shared globally between all interfaces: */
-static struct strnode *list_cache;
-static struct strnode *list_cache_head;
-static struct strnode *list_cache_tail;
-
-typedef struct _Interface {
- char buffer[INTERFACE_MAX_BUFFER_LENGTH];
- int bufferLength;
- int bufferPos;
- int fd; /* file descriptor */
- int permission;
- time_t lastTime;
- struct strnode *cmd_list; /* for when in list mode */
- struct strnode *cmd_list_tail; /* for when in list mode */
- int cmd_list_OK; /* print OK after each command execution */
- int cmd_list_size; /* mem cmd_list consumes */
- int cmd_list_dup; /* has the cmd_list been copied to private space? */
- struct sllnode *deferred_send; /* for output if client is slow */
- int deferred_bytes; /* mem deferred_send consumes */
- int expired; /* set whether this interface should be closed on next
- check of old interfaces */
- int num; /* interface number */
-
- char *send_buf;
- int send_buf_used; /* bytes used this instance */
- int send_buf_size; /* bytes usable this instance */
- int send_buf_alloc; /* bytes actually allocated */
-} Interface;
-
-static Interface *interfaces;
-
-static void flushInterfaceBuffer(Interface * interface);
-
-static void printInterfaceOutBuffer(Interface * interface);
-
-#ifdef SO_SNDBUF
-static int get_default_snd_buf_size(Interface * interface)
-{
- int new_size;
- socklen_t sockOptLen = sizeof(int);
-
- if (getsockopt(interface->fd, SOL_SOCKET, SO_SNDBUF,
- (char *)&new_size, &sockOptLen) < 0) {
- DEBUG("problem getting sockets send buffer size\n");
- return INTERFACE_DEFAULT_OUT_BUFFER_SIZE;
- }
- if (new_size > 0)
- return new_size;
- DEBUG("sockets send buffer size is not positive\n");
- return INTERFACE_DEFAULT_OUT_BUFFER_SIZE;
-}
-#else /* !SO_SNDBUF */
-static int get_default_snd_buf_size(Interface * interface)
-{
- return INTERFACE_DEFAULT_OUT_BUFFER_SIZE;
-}
-#endif /* !SO_SNDBUF */
-
-static void set_send_buf_size(Interface * interface)
-{
- int new_size = get_default_snd_buf_size(interface);
- if (interface->send_buf_size != new_size) {
- interface->send_buf_size = new_size;
- /* don't resize to get smaller, only bigger */
- if (interface->send_buf_alloc < new_size) {
- if (interface->send_buf)
- free(interface->send_buf);
- interface->send_buf = xmalloc(new_size);
- interface->send_buf_alloc = new_size;
- }
- }
-}
-
-static void openInterface(Interface * interface, int fd)
-{
- int flags;
-
- assert(interface->fd < 0);
-
- interface->cmd_list_size = 0;
- interface->cmd_list_dup = 0;
- interface->cmd_list_OK = -1;
- interface->bufferLength = 0;
- interface->bufferPos = 0;
- interface->fd = fd;
- while ((flags = fcntl(fd, F_GETFL)) < 0 && errno == EINTR) ;
- while (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0 && errno == EINTR) ;
- interface->lastTime = time(NULL);
- interface->cmd_list = NULL;
- interface->cmd_list_tail = NULL;
- interface->deferred_send = NULL;
- interface->expired = 0;
- interface->deferred_bytes = 0;
- interface->send_buf_used = 0;
-
- interface->permission = getDefaultPermissions();
- set_send_buf_size(interface);
-
- xwrite(fd, GREETING, strlen(GREETING));
-}
-
-static void free_cmd_list(struct strnode *list)
-{
- struct strnode *tmp = list;
-
- while (tmp) {
- struct strnode *next = tmp->next;
- if (tmp >= list_cache_head && tmp <= list_cache_tail) {
- /* inside list_cache[] array */
- tmp->data = NULL;
- tmp->next = NULL;
- } else
- free(tmp);
- tmp = next;
- }
-}
-
-static void cmd_list_clone(Interface * interface)
-{
- struct strnode *new = dup_strlist(interface->cmd_list);
- free_cmd_list(interface->cmd_list);
- interface->cmd_list = new;
- interface->cmd_list_dup = 1;
-
- /* new tail */
- while (new && new->next)
- new = new->next;
- interface->cmd_list_tail = new;
-}
-
-static void new_cmd_list_ptr(Interface * interface, char *s, const int size)
-{
- int i;
- struct strnode *new;
-
- if (!interface->cmd_list_dup) {
- for (i = interface_list_cache_size - 1; i >= 0; --i) {
- if (list_cache[i].data)
- continue;
- new = &(list_cache[i]);
- new->data = s;
- /* implied in free_cmd_list() and init: */
- /* last->next->next = NULL; */
- goto out;
- }
- }
-
- /* allocate from the heap */
- new = interface->cmd_list_dup ? new_strnode_dup(s, size)
- : new_strnode(s);
-out:
- if (interface->cmd_list) {
- interface->cmd_list_tail->next = new;
- interface->cmd_list_tail = new;
- } else
- interface->cmd_list = interface->cmd_list_tail = new;
-}
-
-static void closeInterface(Interface * interface)
-{
- struct sllnode *buf;
- if (interface->fd < 0)
- return;
- xclose(interface->fd);
- interface->fd = -1;
-
- if (interface->cmd_list) {
- free_cmd_list(interface->cmd_list);
- interface->cmd_list = NULL;
- }
-
- if ((buf = interface->deferred_send)) {
- do {
- struct sllnode *prev = buf;
- buf = buf->next;
- free(prev);
- } while (buf);
- interface->deferred_send = NULL;
- }
-
- SECURE("interface %i: closed\n", interface->num);
-}
-
-void openAInterface(int fd, struct sockaddr *addr)
-{
- int i;
-
- for (i = 0; i < interface_max_connections
- && interfaces[i].fd >= 0; i++) /* nothing */ ;
-
- if (i == interface_max_connections) {
- ERROR("Max Connections Reached!\n");
- xclose(fd);
- } else {
- SECURE("interface %i: opened from ", i);
- switch (addr->sa_family) {
- case AF_INET:
- {
- char *host = inet_ntoa(((struct sockaddr_in *)
- addr)->sin_addr);
- if (host) {
- SECURE("%s\n", host);
- } else {
- SECURE("error getting ipv4 address\n");
- }
- }
- break;
-#ifdef HAVE_IPV6
- case AF_INET6:
- {
- char host[INET6_ADDRSTRLEN + 1];
- memset(host, 0, INET6_ADDRSTRLEN + 1);
- if (inet_ntop(AF_INET6, (void *)
- &(((struct sockaddr_in6 *)addr)->
- sin6_addr), host,
- INET6_ADDRSTRLEN)) {
- SECURE("%s\n", host);
- } else {
- SECURE("error getting ipv6 address\n");
- }
- }
- break;
-#endif
- case AF_UNIX:
- SECURE("local connection\n");
- break;
- default:
- SECURE("unknown\n");
- }
- openInterface(&(interfaces[i]), fd);
- }
-}
-
-static int processLineOfInput(Interface * interface)
-{
- int ret = 1;
- char *line = interface->buffer + interface->bufferPos;
-
- if (interface->cmd_list_OK >= 0) {
- if (strcmp(line, INTERFACE_LIST_MODE_END) == 0) {
- DEBUG("interface %i: process command "
- "list\n", interface->num);
- ret = processListOfCommands(interface->fd,
- &(interface->permission),
- &(interface->expired),
- interface->cmd_list_OK,
- interface->cmd_list);
- DEBUG("interface %i: process command "
- "list returned %i\n", interface->num, ret);
- if (ret == 0)
- commandSuccess(interface->fd);
- else if (ret == COMMAND_RETURN_CLOSE
- || interface->expired)
- closeInterface(interface);
-
- printInterfaceOutBuffer(interface);
- free_cmd_list(interface->cmd_list);
- interface->cmd_list = NULL;
- interface->cmd_list_OK = -1;
- } else {
- size_t len = strlen(line) + 1;
- interface->cmd_list_size += len;
- if (interface->cmd_list_size >
- interface_max_command_list_size) {
- ERROR("interface %i: command "
- "list size (%i) is "
- "larger than the max "
- "(%li)\n",
- interface->num,
- interface->cmd_list_size,
- (long)interface_max_command_list_size);
- closeInterface(interface);
- ret = COMMAND_RETURN_CLOSE;
- } else
- new_cmd_list_ptr(interface, line, len);
- }
- } else {
- if (strcmp(line, INTERFACE_LIST_MODE_BEGIN) == 0) {
- interface->cmd_list_OK = 0;
- ret = 1;
- } else if (strcmp(line, INTERFACE_LIST_OK_MODE_BEGIN) == 0) {
- interface->cmd_list_OK = 1;
- ret = 1;
- } else {
- DEBUG("interface %i: process command \"%s\"\n",
- interface->num, line);
- ret = processCommand(interface->fd,
- &(interface->permission), line);
- DEBUG("interface %i: command returned %i\n",
- interface->num, ret);
- if (ret == 0)
- commandSuccess(interface->fd);
- else if (ret == COMMAND_RETURN_CLOSE
- || interface->expired) {
- closeInterface(interface);
- }
- printInterfaceOutBuffer(interface);
- }
- }
-
- return ret;
-}
-
-static int processBytesRead(Interface * interface, int bytesRead)
-{
- int ret = 0;
- char *buf_tail = &(interface->buffer[interface->bufferLength - 1]);
-
- while (bytesRead > 0) {
- interface->bufferLength++;
- bytesRead--;
- buf_tail++;
- if (*buf_tail == '\n') {
- *buf_tail = '\0';
- if (interface->bufferLength - interface->bufferPos > 1) {
- if (*(buf_tail - 1) == '\r')
- *(buf_tail - 1) = '\0';
- }
- ret = processLineOfInput(interface);
- interface->bufferPos = interface->bufferLength;
- }
- if (interface->bufferLength == INTERFACE_MAX_BUFFER_LENGTH) {
- if (interface->bufferPos == 0) {
- ERROR("interface %i: buffer overflow\n",
- interface->num);
- closeInterface(interface);
- return 1;
- }
- if (interface->cmd_list_OK >= 0 &&
- interface->cmd_list &&
- !interface->cmd_list_dup)
- cmd_list_clone(interface);
- interface->bufferLength -= interface->bufferPos;
- memmove(interface->buffer,
- interface->buffer + interface->bufferPos,
- interface->bufferLength);
- interface->bufferPos = 0;
- }
- if (ret == COMMAND_RETURN_KILL || ret == COMMAND_RETURN_CLOSE) {
- return ret;
- }
-
- }
-
- return ret;
-}
-
-static int interfaceReadInput(Interface * interface)
-{
- int bytesRead;
-
- bytesRead = read(interface->fd,
- interface->buffer + interface->bufferLength,
- INTERFACE_MAX_BUFFER_LENGTH - interface->bufferLength);
-
- if (bytesRead > 0)
- return processBytesRead(interface, bytesRead);
- else if (bytesRead == 0 || (bytesRead < 0 && errno != EINTR)) {
- closeInterface(interface);
- } else
- return 0;
-
- return 1;
-}
-
-static void addInterfacesReadyToReadAndListenSocketToFdSet(fd_set * fds,
- int *fdmax)
-{
- int i;
-
- FD_ZERO(fds);
- addListenSocketsToFdSet(fds, fdmax);
-
- for (i = 0; i < interface_max_connections; i++) {
- if (interfaces[i].fd >= 0 && !interfaces[i].expired
- && !interfaces[i].deferred_send) {
- FD_SET(interfaces[i].fd, fds);
- if (*fdmax < interfaces[i].fd)
- *fdmax = interfaces[i].fd;
- }
- }
-}
-
-static void addInterfacesForBufferFlushToFdSet(fd_set * fds, int *fdmax)
-{
- int i;
-
- FD_ZERO(fds);
-
- for (i = 0; i < interface_max_connections; i++) {
- if (interfaces[i].fd >= 0 && !interfaces[i].expired
- && interfaces[i].deferred_send) {
- FD_SET(interfaces[i].fd, fds);
- if (*fdmax < interfaces[i].fd)
- *fdmax = interfaces[i].fd;
- }
- }
-}
-
-static void closeNextErroredInterface(void)
-{
- fd_set fds;
- struct timeval tv;
- int i;
-
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- for (i = 0; i < interface_max_connections; i++) {
- if (interfaces[i].fd >= 0) {
- FD_ZERO(&fds);
- FD_SET(interfaces[i].fd, &fds);
- if (select(FD_SETSIZE, &fds, NULL, NULL, &tv) < 0) {
- closeInterface(&interfaces[i]);
- return;
- }
- }
- }
-}
-
-int doIOForInterfaces(void)
-{
- fd_set rfds;
- fd_set wfds;
- fd_set efds;
- struct timeval tv;
- int i;
- int selret;
- int fdmax;
-
- tv.tv_sec = 1;
- tv.tv_usec = 0;
-
- while (1) {
- fdmax = 0;
-
- FD_ZERO( &rfds );
- FD_ZERO( &wfds );
- FD_ZERO( &efds );
- addInterfacesReadyToReadAndListenSocketToFdSet(&rfds, &fdmax);
- addInterfacesForBufferFlushToFdSet(&wfds, &fdmax);
-
- /* Add fds for all registered IO handlers */
- if( ioList ) {
- struct ioOps *o = ioList;
- while( o ) {
- struct ioOps *current = o;
- int fdnum;
- assert( current->fdset );
- fdnum = current->fdset( &rfds, &wfds, &efds );
- if( fdmax < fdnum )
- fdmax = fdnum;
- o = o->next;
- }
- }
-
- selret = select(fdmax + 1, &rfds, &wfds, &efds, &tv);
-
- if (selret < 0 && errno == EINTR)
- break;
-
- /* Consume fds for all registered IO handlers */
- if( ioList ) {
- struct ioOps *o = ioList;
- while( o ) {
- struct ioOps *current = o;
- assert( current->consume );
- selret = current->consume( selret, &rfds, &wfds, &efds );
- o = o->next;
- }
- }
-
- if (selret == 0)
- break;
-
- if (selret < 0) {
- closeNextErroredInterface();
- continue;
- }
-
- getConnections(&rfds);
-
- for (i = 0; i < interface_max_connections; i++) {
- if (interfaces[i].fd >= 0
- && FD_ISSET(interfaces[i].fd, &rfds)) {
- if (COMMAND_RETURN_KILL ==
- interfaceReadInput(&(interfaces[i]))) {
- return COMMAND_RETURN_KILL;
- }
- interfaces[i].lastTime = time(NULL);
- }
- if (interfaces[i].fd >= 0
- && FD_ISSET(interfaces[i].fd, &wfds)) {
- flushInterfaceBuffer(&interfaces[i]);
- interfaces[i].lastTime = time(NULL);
- }
- }
-
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- }
-
- return 1;
-}
-
-void initInterfaces(void)
-{
- int i;
- char *test;
- ConfigParam *param;
-
- param = getConfigParam(CONF_CONN_TIMEOUT);
-
- if (param) {
- interface_timeout = strtol(param->value, &test, 10);
- if (*test != '\0' || interface_timeout <= 0) {
- FATAL("connection timeout \"%s\" is not a positive "
- "integer, line %i\n", CONF_CONN_TIMEOUT,
- param->line);
- }
- }
-
- param = getConfigParam(CONF_MAX_CONN);
-
- if (param) {
- interface_max_connections = strtol(param->value, &test, 10);
- if (*test != '\0' || interface_max_connections <= 0) {
- FATAL("max connections \"%s\" is not a positive integer"
- ", line %i\n", param->value, param->line);
- }
- } else
- interface_max_connections = INTERFACE_MAX_CONNECTIONS_DEFAULT;
-
- param = getConfigParam(CONF_MAX_COMMAND_LIST_SIZE);
-
- if (param) {
- interface_max_command_list_size = strtol(param->value,
- &test, 10);
- if (*test != '\0' || interface_max_command_list_size <= 0) {
- FATAL("max command list size \"%s\" is not a positive "
- "integer, line %i\n", param->value, param->line);
- }
- interface_max_command_list_size *= 1024;
- }
-
- param = getConfigParam(CONF_MAX_OUTPUT_BUFFER_SIZE);
-
- if (param) {
- interface_max_output_buffer_size = strtol(param->value,
- &test, 10);
- if (*test != '\0' || interface_max_output_buffer_size <= 0) {
- FATAL("max output buffer size \"%s\" is not a positive "
- "integer, line %i\n", param->value, param->line);
- }
- interface_max_output_buffer_size *= 1024;
- }
-
- interfaces = xmalloc(sizeof(Interface) * interface_max_connections);
-
- list_cache = xcalloc(interface_list_cache_size, sizeof(struct strnode));
- list_cache_head = &(list_cache[0]);
- list_cache_tail = &(list_cache[interface_list_cache_size - 1]);
-
- for (i = 0; i < interface_max_connections; i++) {
- interfaces[i].fd = -1;
- interfaces[i].send_buf = NULL;
- interfaces[i].send_buf_size = 0;
- interfaces[i].send_buf_alloc = 0;
- interfaces[i].num = i;
- }
-}
-
-static void closeAllInterfaces(void)
-{
- int i;
-
- for (i = 0; i < interface_max_connections; i++) {
- if (interfaces[i].fd > 0)
- closeInterface(&(interfaces[i]));
- if (interfaces[i].send_buf)
- free(interfaces[i].send_buf);
- }
- free(list_cache);
-}
-
-void freeAllInterfaces(void)
-{
- closeAllInterfaces();
-
- free(interfaces);
-
- interface_max_connections = 0;
-}
-
-void closeOldInterfaces(void)
-{
- int i;
-
- for (i = 0; i < interface_max_connections; i++) {
- if (interfaces[i].fd > 0) {
- if (interfaces[i].expired) {
- DEBUG("interface %i: expired\n", i);
- closeInterface(&(interfaces[i]));
- } else if (time(NULL) - interfaces[i].lastTime >
- interface_timeout) {
- DEBUG("interface %i: timeout\n", i);
- closeInterface(&(interfaces[i]));
- }
- }
- }
-}
-
-static void flushInterfaceBuffer(Interface * interface)
-{
- struct sllnode *buf;
- int ret = 0;
-
- buf = interface->deferred_send;
- while (buf) {
- ret = write(interface->fd, buf->data, buf->size);
- if (ret < 0)
- break;
- else if (ret < buf->size) {
- interface->deferred_bytes -= ret;
- buf->data = (char *)buf->data + ret;
- buf->size -= ret;
- } else {
- struct sllnode *tmp = buf;
- interface->deferred_bytes -= (buf->size +
- sizeof(struct sllnode));
- buf = buf->next;
- free(tmp);
- interface->deferred_send = buf;
- }
- interface->lastTime = time(NULL);
- }
-
- if (!interface->deferred_send) {
- DEBUG("interface %i: buffer empty %i\n", interface->num,
- interface->deferred_bytes);
- assert(interface->deferred_bytes == 0);
- } else if (ret < 0 && errno != EAGAIN && errno != EINTR) {
- /* cause interface to close */
- DEBUG("interface %i: problems flushing buffer\n",
- interface->num);
- buf = interface->deferred_send;
- do {
- struct sllnode *prev = buf;
- buf = buf->next;
- free(prev);
- } while (buf);
- interface->deferred_send = NULL;
- interface->deferred_bytes = 0;
- interface->expired = 1;
- }
-}
-
-int interfacePrintWithFD(int fd, char *buffer, int buflen)
-{
- static int i;
- int copylen;
- Interface *interface;
-
- assert(fd > 0);
-
- if (i >= interface_max_connections ||
- interfaces[i].fd < 0 || interfaces[i].fd != fd) {
- for (i = 0; i < interface_max_connections; i++) {
- if (interfaces[i].fd == fd)
- break;
- }
- if (i == interface_max_connections)
- return -1;
- }
-
- /* if fd isn't found or interfaces is going to be closed, do nothing */
- if (interfaces[i].expired)
- return 0;
-
- interface = interfaces + i;
-
- while (buflen > 0 && !interface->expired) {
- int left = interface->send_buf_size - interface->send_buf_used;
- copylen = buflen > left ? left : buflen;
- memcpy(interface->send_buf + interface->send_buf_used, buffer,
- copylen);
- buflen -= copylen;
- interface->send_buf_used += copylen;
- buffer += copylen;
- if (interface->send_buf_used >= interface->send_buf_size)
- printInterfaceOutBuffer(interface);
- }
-
- return 0;
-}
-
-static void printInterfaceOutBuffer(Interface * interface)
-{
- int ret;
- struct sllnode *buf;
-
- if (interface->fd < 0 || interface->expired ||
- !interface->send_buf_used)
- return;
-
- if ((buf = interface->deferred_send)) {
- interface->deferred_bytes += sizeof(struct sllnode)
- + interface->send_buf_used;
- if (interface->deferred_bytes >
- interface_max_output_buffer_size) {
- ERROR("interface %i: output buffer size (%li) is "
- "larger than the max (%li)\n",
- interface->num,
- (long)interface->deferred_bytes,
- (long)interface_max_output_buffer_size);
- /* cause interface to close */
- interface->expired = 1;
- do {
- struct sllnode *prev = buf;
- buf = buf->next;
- free(prev);
- } while (buf);
- interface->deferred_send = NULL;
- interface->deferred_bytes = 0;
- } else {
- while (buf->next)
- buf = buf->next;
- buf->next = new_sllnode(interface->send_buf,
- interface->send_buf_used);
- }
- } else {
- if ((ret = write(interface->fd, interface->send_buf,
- interface->send_buf_used)) < 0) {
- if (errno == EAGAIN || errno == EINTR) {
- interface->deferred_send =
- new_sllnode(interface->send_buf,
- interface->send_buf_used);
- } else {
- DEBUG("interface %i: problems writing\n",
- interface->num);
- interface->expired = 1;
- return;
- }
- } else if (ret < interface->send_buf_used) {
- interface->deferred_send =
- new_sllnode(interface->send_buf + ret,
- interface->send_buf_used - ret);
- }
- if (interface->deferred_send) {
- DEBUG("interface %i: buffer created\n", interface->num);
- interface->deferred_bytes =
- interface->deferred_send->size
- + sizeof(struct sllnode);
- }
- }
-
- interface->send_buf_used = 0;
-}
-
-/* From ioops.h: */
-void registerIO( struct ioOps *ops )
-{
- assert( ops != NULL );
-
- ops->next = ioList;
- ioList = ops;
- ops->prev = NULL;
- if( ops->next )
- ops->next->prev = ops;
-}
-
-void deregisterIO( struct ioOps *ops )
-{
- assert( ops != NULL );
-
- if( ioList == ops )
- ioList = ops->next;
- else if( ops->prev != NULL )
- ops->prev->next = ops->next;
-}
diff --git a/trunk/src/interface.h b/trunk/src/interface.h
deleted file mode 100644
index 6f3c2c070..000000000
--- a/trunk/src/interface.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef INTERFACE_H
-#define INTERFACE_H
-
-#include "../config.h"
-
-#include <stdio.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-void initInterfaces(void);
-void openAInterface(int fd, struct sockaddr *addr);
-void freeAllInterfaces(void);
-void closeOldInterfaces(void);
-int interfacePrintWithFD(int fd, char *buffer, int len);
-
-int doIOForInterfaces(void);
-
-#endif
diff --git a/trunk/src/ioops.h b/trunk/src/ioops.h
deleted file mode 100644
index e797a7153..000000000
--- a/trunk/src/ioops.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IOOPS_H
-#define IOOPS_H
-
-#include <sys/select.h>
-
-struct ioOps {
- struct ioOps *prev, *next;
-
- /*
- * Called before each 'select' statement.
- * To register for IO, call FD_SET for each required queue
- * Return the highest fd number you registered
- */
- int (*fdset) ( fd_set *rfds, fd_set *wfds, fd_set *efds );
-
- /*
- * Called after each 'select' statement.
- * fdCount is the number of fds total in all sets. It may be 0.
- * For each fd you registered for in (fdset), you should FD_CLR it from the
- * appropriate queue(s).
- * Return the total number of fds left in all sets (Ie, return fdCount
- * minus the number of times you called FD_CLR).
- */
- int (*consume) ( int fdCount, fd_set *rfds, fd_set *wfds, fd_set *efds );
-};
-
-/* Call this to register your io operation handler struct */
-void registerIO( struct ioOps *ops );
-
-/* Call this to deregister your io operation handler struct */
-void deregisterIO( struct ioOps *ops );
-
-#endif
diff --git a/trunk/src/list.c b/trunk/src/list.c
deleted file mode 100644
index 71c30f7b6..000000000
--- a/trunk/src/list.c
+++ /dev/null
@@ -1,519 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "list.h"
-#include "utils.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <time.h>
-#include <stdio.h>
-
-static void makeListNodesArray(List * list)
-{
- ListNode *node = list->firstNode;
- long i;
-
- if (!list->numberOfNodes)
- return;
-
- list->nodesArray = xrealloc(list->nodesArray,
- sizeof(ListNode *) * list->numberOfNodes);
-
- for (i = 0; i < list->numberOfNodes; i++) {
- list->nodesArray[i] = node;
- node = node->nextNode;
- }
-}
-
-static void freeListNodesArray(List * list)
-{
- if (!list->nodesArray)
- return;
- free(list->nodesArray);
- list->nodesArray = NULL;
-}
-
-List *makeList(ListFreeDataFunc * freeDataFunc, int strdupKeys)
-{
- List *list = xmalloc(sizeof(List));
-
- assert(list != NULL);
-
- list->sorted = 0;
- list->firstNode = NULL;
- list->lastNode = NULL;
- list->freeDataFunc = freeDataFunc;
- list->numberOfNodes = 0;
- list->nodesArray = NULL;
- list->strdupKeys = strdupKeys;
-
- return list;
-}
-
-ListNode *insertInListBeforeNode(List * list, ListNode * beforeNode, int pos,
- char *key, void *data)
-{
- ListNode *node;
-
- assert(list != NULL);
- assert(key != NULL);
- /*assert(data!=NULL); */
-
- node = xmalloc(sizeof(ListNode));
- assert(node != NULL);
-
- node->nextNode = beforeNode;
- if (beforeNode == list->firstNode) {
- if (list->firstNode == NULL) {
- assert(list->lastNode == NULL);
- list->lastNode = node;
- } else {
- assert(list->lastNode != NULL);
- assert(list->lastNode->nextNode == NULL);
- list->firstNode->prevNode = node;
- }
- node->prevNode = NULL;
- list->firstNode = node;
- } else {
- if (beforeNode) {
- node->prevNode = beforeNode->prevNode;
- beforeNode->prevNode = node;
- } else {
- node->prevNode = list->lastNode;
- list->lastNode = node;
- }
- node->prevNode->nextNode = node;
- }
-
- if (list->strdupKeys)
- node->key = xstrdup(key);
- else
- node->key = key;
-
- node->data = data;
-
- list->numberOfNodes++;
-
- if (list->sorted) {
- list->nodesArray = xrealloc(list->nodesArray,
- list->numberOfNodes *
- sizeof(ListNode *));
- if (node == list->lastNode) {
- list->nodesArray[list->numberOfNodes - 1] = node;
- } else if (pos < 0)
- makeListNodesArray(list);
- else {
- memmove(list->nodesArray + pos + 1,
- list->nodesArray + pos,
- sizeof(ListNode *) * (list->numberOfNodes -
- pos - 1));
- list->nodesArray[pos] = node;
- }
- }
-
- return node;
-}
-
-ListNode *insertInList(List * list, char *key, void *data)
-{
- ListNode *node;
-
- assert(list != NULL);
- assert(key != NULL);
- /*assert(data!=NULL); */
-
- node = xmalloc(sizeof(ListNode));
- assert(node != NULL);
-
- if (list->nodesArray)
- freeListNodesArray(list);
-
- if (list->firstNode == NULL) {
- assert(list->lastNode == NULL);
- list->firstNode = node;
- } else {
- assert(list->lastNode != NULL);
- assert(list->lastNode->nextNode == NULL);
- list->lastNode->nextNode = node;
- }
-
- if (list->strdupKeys)
- node->key = xstrdup(key);
- else
- node->key = key;
-
- node->data = data;
- node->nextNode = NULL;
- node->prevNode = list->lastNode;
-
- list->lastNode = node;
-
- list->numberOfNodes++;
-
- return node;
-}
-
-int insertInListWithoutKey(List * list, void *data)
-{
- ListNode *node;
-
- assert(list != NULL);
- assert(data != NULL);
-
- node = xmalloc(sizeof(ListNode));
- assert(node != NULL);
-
- if (list->nodesArray)
- freeListNodesArray(list);
-
- if (list->firstNode == NULL) {
- assert(list->lastNode == NULL);
- list->firstNode = node;
- } else {
- assert(list->lastNode != NULL);
- assert(list->lastNode->nextNode == NULL);
- list->lastNode->nextNode = node;
- }
-
- node->key = NULL;
- node->data = data;
- node->nextNode = NULL;
- node->prevNode = list->lastNode;
-
- list->lastNode = node;
-
- list->numberOfNodes++;
-
- return 1;
-}
-
-/* if _key_ is not found, *_node_ is assigned to the node before which
- the info would be found */
-int findNodeInList(List * list, char *key, ListNode ** node, int *pos)
-{
- long high;
- long low;
- long cur;
- ListNode *tmpNode;
- int cmp;
-
- assert(list != NULL);
-
- if (list->sorted && list->nodesArray) {
- high = list->numberOfNodes - 1;
- low = 0;
- cur = high;
-
- while (high > low) {
- cur = (high + low) / 2;
- tmpNode = list->nodesArray[cur];
- cmp = strcmp(tmpNode->key, key);
- if (cmp == 0) {
- *node = tmpNode;
- *pos = cur;
- return 1;
- } else if (cmp > 0)
- high = cur;
- else {
- if (low == cur)
- break;
- low = cur;
- }
- }
-
- cur = high;
- if (cur >= 0) {
- tmpNode = list->nodesArray[cur];
- *node = tmpNode;
- *pos = high;
- cmp = tmpNode ? strcmp(tmpNode->key, key) : -1;
- if (0 == cmp)
- return 1;
- else if (cmp > 0)
- return 0;
- else {
- *pos = -1;
- *node = NULL;
- return 0;
- }
- } else {
- *pos = 0;
- *node = list->firstNode;
- return 0;
- }
- } else {
- tmpNode = list->firstNode;
-
- while (tmpNode != NULL && strcmp(tmpNode->key, key) != 0) {
- tmpNode = tmpNode->nextNode;
- }
-
- *node = tmpNode;
- if (tmpNode)
- return 1;
- }
-
- return 0;
-}
-
-int findInList(List * list, char *key, void **data)
-{
- ListNode *node;
- int pos;
-
- if (findNodeInList(list, key, &node, &pos)) {
- if (data)
- *data = node->data;
- return 1;
- }
-
- return 0;
-}
-
-int deleteFromList(List * list, char *key)
-{
- ListNode *tmpNode;
-
- assert(list != NULL);
-
- tmpNode = list->firstNode;
-
- while (tmpNode != NULL && strcmp(tmpNode->key, key) != 0) {
- tmpNode = tmpNode->nextNode;
- }
-
- if (tmpNode != NULL)
- deleteNodeFromList(list, tmpNode);
- else
- return 0;
-
- return 1;
-}
-
-void deleteNodeFromList(List * list, ListNode * node)
-{
- assert(list != NULL);
- assert(node != NULL);
-
- if (node->prevNode == NULL) {
- list->firstNode = node->nextNode;
- } else {
- node->prevNode->nextNode = node->nextNode;
- }
- if (node->nextNode == NULL) {
- list->lastNode = node->prevNode;
- } else {
- node->nextNode->prevNode = node->prevNode;
- }
- if (list->freeDataFunc) {
- list->freeDataFunc(node->data);
- }
-
- if (list->strdupKeys)
- free(node->key);
- free(node);
- list->numberOfNodes--;
-
- if (list->nodesArray) {
- freeListNodesArray(list);
- if (list->sorted)
- makeListNodesArray(list);
- }
-
-}
-
-void freeList(void *list)
-{
- ListNode *tmpNode;
- ListNode *tmpNode2;
-
- assert(list != NULL);
-
- tmpNode = ((List *) list)->firstNode;
-
- if (((List *) list)->nodesArray)
- free(((List *) list)->nodesArray);
-
- while (tmpNode != NULL) {
- tmpNode2 = tmpNode->nextNode;
- if (((List *) list)->strdupKeys)
- free(tmpNode->key);
- if (((List *) list)->freeDataFunc) {
- ((List *) list)->freeDataFunc(tmpNode->data);
- }
- free(tmpNode);
- tmpNode = tmpNode2;
- }
-
- free(list);
-}
-
-static void swapNodes(ListNode * nodeA, ListNode * nodeB)
-{
- char *key;
- void *data;
-
- assert(nodeA != NULL);
- assert(nodeB != NULL);
-
- key = nodeB->key;
- data = nodeB->data;
-
- nodeB->key = nodeA->key;
- nodeB->data = nodeA->data;
-
- nodeA->key = key;
- nodeA->data = data;
-}
-
-static void bubbleSort(ListNode ** nodesArray, long start, long end)
-{
- long i;
- long j;
- ListNode *node;
-
- if (start >= end)
- return;
-
- for (j = start; j < end; j++) {
- for (i = end - 1; i >= start; i--) {
- node = nodesArray[i];
- if (strcmp(node->key, node->nextNode->key) > 0) {
- swapNodes(node, node->nextNode);
- }
- }
- }
-}
-
-static void quickSort(ListNode ** nodesArray, long start, long end)
-{
- if (start >= end)
- return;
- else if (end - start < 5)
- bubbleSort(nodesArray, start, end);
- else {
- long i;
- ListNode *node;
- long pivot;
- ListNode *pivotNode;
- char *pivotKey;
-
- List *startList = makeList(free, 0);
- List *endList = makeList(free, 0);
- long *startPtr = xmalloc(sizeof(long));
- long *endPtr = xmalloc(sizeof(long));
- *startPtr = start;
- *endPtr = end;
- insertInListWithoutKey(startList, (void *)startPtr);
- insertInListWithoutKey(endList, (void *)endPtr);
-
- while (startList->numberOfNodes) {
- start = *((long *)startList->lastNode->data);
- end = *((long *)endList->lastNode->data);
-
- if (end - start < 5) {
- bubbleSort(nodesArray, start, end);
- deleteNodeFromList(startList,
- startList->lastNode);
- deleteNodeFromList(endList, endList->lastNode);
- } else {
- pivot = (start + end) / 2;
- pivotNode = nodesArray[pivot];
- pivotKey = pivotNode->key;
-
- for (i = pivot - 1; i >= start; i--) {
- node = nodesArray[i];
- if (strcmp(node->key, pivotKey) > 0) {
- pivot--;
- if (pivot > i) {
- swapNodes(node,
- nodesArray
- [pivot]);
- }
- swapNodes(pivotNode,
- nodesArray[pivot]);
- pivotNode = nodesArray[pivot];
- }
- }
- for (i = pivot + 1; i <= end; i++) {
- node = nodesArray[i];
- if (strcmp(pivotKey, node->key) > 0) {
- pivot++;
- if (pivot < i) {
- swapNodes(node,
- nodesArray
- [pivot]);
- }
- swapNodes(pivotNode,
- nodesArray[pivot]);
- pivotNode = nodesArray[pivot];
- }
- }
-
- deleteNodeFromList(startList,
- startList->lastNode);
- deleteNodeFromList(endList, endList->lastNode);
-
- if (pivot - 1 - start > 0) {
- startPtr = xmalloc(sizeof(long));
- endPtr = xmalloc(sizeof(long));
- *startPtr = start;
- *endPtr = pivot - 1;
- insertInListWithoutKey(startList,
- (void *)
- startPtr);
- insertInListWithoutKey(endList,
- (void *)endPtr);
- }
-
- if (end - pivot - 1 > 0) {
- startPtr = xmalloc(sizeof(long));
- endPtr = xmalloc(sizeof(long));
- *startPtr = pivot + 1;
- *endPtr = end;
- insertInListWithoutKey(startList,
- (void *)
- startPtr);
- insertInListWithoutKey(endList,
- (void *)endPtr);
- }
- }
- }
-
- freeList(startList);
- freeList(endList);
- }
-}
-
-void sortList(List * list)
-{
- assert(list != NULL);
-
- list->sorted = 1;
-
- if (list->numberOfNodes < 2)
- return;
-
- if (list->nodesArray)
- freeListNodesArray(list);
- makeListNodesArray(list);
-
- quickSort(list->nodesArray, 0, list->numberOfNodes - 1);
-}
diff --git a/trunk/src/list.h b/trunk/src/list.h
deleted file mode 100644
index 5938934ff..000000000
--- a/trunk/src/list.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef LIST_H
-#define LIST_H
-
-#include "../config.h"
-
-#include <stdlib.h>
-
-/* used to make a list where free() will be used to free data in list */
-#define DEFAULT_FREE_DATA_FUNC free
-
-/* typedef for function to free data stored in the list nodes */
-typedef void ListFreeDataFunc(void *);
-
-typedef struct _ListNode {
- /* used to identify node (ie. when using findInList) */
- char *key;
- /* data store in node */
- void *data;
- /* next node in list */
- struct _ListNode *nextNode;
- /* previous node in list */
- struct _ListNode *prevNode;
-} ListNode;
-
-typedef struct _List {
- /* first node in list */
- ListNode *firstNode;
- /* last node in list */
- ListNode *lastNode;
- /* function used to free data stored in nodes of the list */
- ListFreeDataFunc *freeDataFunc;
- /* number of nodes */
- long numberOfNodes;
- /* array for searching when list is sorted */
- ListNode **nodesArray;
- /* sorted */
- int sorted;
- /* whether to strdup() key's on insertion */
- int strdupKeys;
-} List;
-
-/* allocates memory for a new list and initializes it
- * _freeDataFunc_ -> pointer to function used to free data, use
- * DEFAULT_FREE_DATAFUNC to use free()
- * returns pointer to new list if successful, NULL otherwise
- */
-List *makeList(ListFreeDataFunc * freeDataFunc, int strdupKeys);
-
-/* inserts a node into _list_ with _key_ and _data_
- * _list_ -> list the data will be inserted in
- * _key_ -> identifier for node/data to be inserted into list
- * _data_ -> data to be inserted in list
- * returns 1 if successful, 0 otherwise
- */
-ListNode *insertInList(List * list, char *key, void *data);
-
-ListNode *insertInListBeforeNode(List * list, ListNode * beforeNode,
- int pos, char *key, void *data);
-
-int insertInListWithoutKey(List * list, void *data);
-
-/* deletes the first node in the list with the key _key_
- * _list_ -> list the node will be deleted from
- * _key_ -> key used to identify node to delete
- * returns 1 if node is found and deleted, 0 otherwise
- */
-int deleteFromList(List * list, char *key);
-
-void deleteNodeFromList(List * list, ListNode * node);
-
-/* finds data in a list based on key
- * _list_ -> list to search for _key_ in
- * _key_ -> which node is being searched for
- * _data_ -> a pointer to where data will be placed,
- * _data_ memory should not by allocated or freed
- * _data_ can be NULL
- * returns 1 if successful, 0 otherwise
- */
-int findInList(List * list, char *key, void **data);
-
-/* if _key_ is not found, *_node_ is assigned to the node before which
- the info would be found */
-int findNodeInList(List * list, char *key, ListNode ** node, int *pos);
-
-/* frees memory malloc'd for list and its nodes
- * _list_ -> List to be free'd
- */
-void freeList(void *list);
-
-void sortList(List * list);
-
-#endif
diff --git a/trunk/src/listen.c b/trunk/src/listen.c
deleted file mode 100644
index 323bf430f..000000000
--- a/trunk/src/listen.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "listen.h"
-#include "interface.h"
-#include "conf.h"
-#include "log.h"
-#include "utils.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <string.h>
-#include <errno.h>
-#include <resolv.h>
-#include <fcntl.h>
-
-#define MAXHOSTNAME 1024
-
-#define ALLOW_REUSE 1
-
-#define DEFAULT_PORT 6600
-
-#define BINDERROR() do { \
- FATAL("unable to bind port %u: %s\n" \
- "maybe MPD is still running?\n", \
- port, strerror(errno)); \
-} while (0);
-
-static int *listenSockets;
-static int numberOfListenSockets;
-static int boundPort;
-
-static int establishListen(unsigned int port,
- struct sockaddr *addrp, socklen_t addrlen)
-{
- int pf = 0;
- int sock;
- int allowReuse = ALLOW_REUSE;
-
- switch (addrp->sa_family) {
- case AF_INET:
- pf = PF_INET;
- break;
-#ifdef HAVE_IPV6
- case AF_INET6:
- pf = PF_INET6;
- break;
-#endif
- case AF_UNIX:
- pf = PF_UNIX;
- break;
- default:
- FATAL("unknown address family: %i\n", addrp->sa_family);
- }
-
- if ((sock = socket(pf, SOCK_STREAM, 0)) < 0)
- FATAL("socket < 0\n");
-
- if (fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK) < 0) {
- FATAL("problems setting nonblocking on listen socket: %s\n",
- strerror(errno));
- }
-
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&allowReuse,
- sizeof(allowReuse)) < 0) {
- FATAL("problems setsockopt'ing: %s\n", strerror(errno));
- }
-
- if (bind(sock, addrp, addrlen) < 0) {
- close(sock);
- return -1;
- }
-
- if (listen(sock, 5) < 0)
- FATAL("problems listen'ing: %s\n", strerror(errno));
-
- numberOfListenSockets++;
- listenSockets =
- xrealloc(listenSockets, sizeof(int) * numberOfListenSockets);
-
- listenSockets[numberOfListenSockets - 1] = sock;
-
- return 0;
-}
-
-static void parseListenConfigParam(unsigned int port, ConfigParam * param)
-{
- struct sockaddr *addrp = NULL;
- socklen_t addrlen = 0;
- struct sockaddr_in sin;
-#ifdef HAVE_IPV6
- struct sockaddr_in6 sin6;
- int useIpv6 = ipv6Supported();
-
- memset(&sin6, 0, sizeof(struct sockaddr_in6));
- sin6.sin6_port = htons(port);
- sin6.sin6_family = AF_INET6;
-#endif
- memset(&sin, 0, sizeof(struct sockaddr_in));
- sin.sin_port = htons(port);
- sin.sin_family = AF_INET;
-
- if (!param || 0 == strcmp(param->value, "any")) {
- DEBUG("binding to any address\n");
-#ifdef HAVE_IPV6
- if (useIpv6) {
- sin6.sin6_addr = in6addr_any;
- addrp = (struct sockaddr *)&sin6;
- addrlen = sizeof(struct sockaddr_in6);
- if (establishListen(port, addrp, addrlen) < 0)
- BINDERROR();
- }
-#endif
- sin.sin_addr.s_addr = INADDR_ANY;
- addrp = (struct sockaddr *)&sin;
- addrlen = sizeof(struct sockaddr_in);
-#ifdef HAVE_IPV6
- if ((establishListen(port, addrp, addrlen) < 0) && !useIpv6) {
-#else
- if (establishListen(port, addrp, addrlen) < 0) {
-#endif
- BINDERROR();
- }
- } else {
- struct hostent *he;
- DEBUG("binding to address for %s\n", param->value);
- if (!(he = gethostbyname(param->value))) {
- FATAL("can't lookup host \"%s\" at line %i\n",
- param->value, param->line);
- }
- switch (he->h_addrtype) {
-#ifdef HAVE_IPV6
- case AF_INET6:
- if (!useIpv6) {
- FATAL("no IPv6 support, but a IPv6 address "
- "found for \"%s\" at line %i\n",
- param->value, param->line);
- }
- memcpy((char *)&sin6.sin6_addr.s6_addr,
- (char *)he->h_addr, he->h_length);
- addrp = (struct sockaddr *)&sin6;
- addrlen = sizeof(struct sockaddr_in6);
- break;
-#endif
- case AF_INET:
- memcpy((char *)&sin.sin_addr.s_addr,
- (char *)he->h_addr, he->h_length);
- addrp = (struct sockaddr *)&sin;
- addrlen = sizeof(struct sockaddr_in);
- break;
- default:
- FATAL("address type for \"%s\" is not IPv4 or IPv6 "
- "at line %i\n", param->value, param->line);
- }
-
- if (establishListen(port, addrp, addrlen) < 0)
- BINDERROR();
- }
-}
-
-void listenOnPort(void)
-{
- int port = DEFAULT_PORT;
- ConfigParam *param = getNextConfigParam(CONF_BIND_TO_ADDRESS, NULL);
- ConfigParam *portParam = getConfigParam(CONF_PORT);
-
- if (portParam) {
- char *test;
- port = strtol(portParam->value, &test, 10);
- if (port <= 0 || *test != '\0') {
- FATAL("%s \"%s\" specified at line %i is not a "
- "positive integer", CONF_PORT,
- portParam->value, portParam->line);
- }
- }
-
- boundPort = port;
-
- do {
- parseListenConfigParam(port, param);
- } while ((param = getNextConfigParam(CONF_BIND_TO_ADDRESS, param)));
-}
-
-void addListenSocketsToFdSet(fd_set * fds, int *fdmax)
-{
- int i;
-
- for (i = 0; i < numberOfListenSockets; i++) {
- FD_SET(listenSockets[i], fds);
- if (listenSockets[i] > *fdmax)
- *fdmax = listenSockets[i];
- }
-}
-
-void closeAllListenSockets(void)
-{
- int i;
-
- DEBUG("closeAllListenSockets called\n");
-
- for (i = 0; i < numberOfListenSockets; i++) {
- DEBUG("closing listen socket %i\n", i);
- while (close(listenSockets[i]) < 0 && errno == EINTR) ;
- }
- freeAllListenSockets();
-}
-
-void freeAllListenSockets(void)
-{
- numberOfListenSockets = 0;
- free(listenSockets);
- listenSockets = NULL;
-}
-
-void getConnections(fd_set * fds)
-{
- int i;
- int fd = 0;
- struct sockaddr sockAddr;
- socklen_t socklen = sizeof(sockAddr);
-
- for (i = 0; i < numberOfListenSockets; i++) {
- if (FD_ISSET(listenSockets[i], fds)) {
- if ((fd = accept(listenSockets[i], &sockAddr, &socklen))
- >= 0) {
- openAInterface(fd, &sockAddr);
- } else if (fd < 0
- && (errno != EAGAIN && errno != EINTR)) {
- ERROR("Problems accept()'ing\n");
- }
- }
- }
-}
-
-int getBoundPort(void)
-{
- return boundPort;
-}
diff --git a/trunk/src/listen.h b/trunk/src/listen.h
deleted file mode 100644
index 638214003..000000000
--- a/trunk/src/listen.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef LISTEN_H
-#define LISTEN_H
-
-#include "../config.h"
-
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/select.h>
-
-void listenOnPort(void);
-
-void getConnections(fd_set * fds);
-
-void closeAllListenSockets(void);
-void freeAllListenSockets(void);
-
-/* fdmax should be initialized to something */
-void addListenSocketsToFdSet(fd_set * fds, int *fdmax);
-
-int getBoundPort(void);
-
-#endif
diff --git a/trunk/src/locate.c b/trunk/src/locate.c
deleted file mode 100644
index 7c3bab899..000000000
--- a/trunk/src/locate.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/* the Music Player Daemon (MPD)
- * (c)2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "locate.h"
-
-#include "utils.h"
-
-#define LOCATE_TAG_FILE_KEY "file"
-#define LOCATE_TAG_FILE_KEY_OLD "filename"
-#define LOCATE_TAG_ANY_KEY "any"
-
-int getLocateTagItemType(char *str)
-{
- int i;
-
- if (0 == strcasecmp(str, LOCATE_TAG_FILE_KEY) ||
- 0 == strcasecmp(str, LOCATE_TAG_FILE_KEY_OLD))
- {
- return LOCATE_TAG_FILE_TYPE;
- }
-
- if (0 == strcasecmp(str, LOCATE_TAG_ANY_KEY))
- {
- return LOCATE_TAG_ANY_TYPE;
- }
-
- for (i = 0; i < TAG_NUM_OF_ITEM_TYPES; i++)
- {
- if (0 == strcasecmp(str, mpdTagItemKeys[i]))
- return i;
- }
-
- return -1;
-}
-
-static int initLocateTagItem(LocateTagItem * item, char *typeStr, char *needle)
-{
- item->tagType = getLocateTagItemType(typeStr);
-
- if (item->tagType < 0)
- return -1;
-
- item->needle = xstrdup(needle);
-
- return 0;
-}
-
-LocateTagItem *newLocateTagItem(char *typeStr, char *needle)
-{
- LocateTagItem *ret = xmalloc(sizeof(LocateTagItem));
-
- if (initLocateTagItem(ret, typeStr, needle) < 0) {
- free(ret);
- ret = NULL;
- }
-
- return ret;
-}
-
-void freeLocateTagItemArray(int count, LocateTagItem * array)
-{
- int i;
-
- for (i = 0; i < count; i++)
- free(array[i].needle);
-
- free(array);
-}
-
-int newLocateTagItemArrayFromArgArray(char *argArray[],
- int numArgs, LocateTagItem ** arrayRet)
-{
- int i, j;
- LocateTagItem *item;
-
- if (numArgs == 0)
- return 0;
-
- if (numArgs % 2 != 0)
- return -1;
-
- *arrayRet = xmalloc(sizeof(LocateTagItem) * numArgs / 2);
-
- for (i = 0, item = *arrayRet; i < numArgs / 2; i++, item++) {
- if (initLocateTagItem
- (item, argArray[i * 2], argArray[i * 2 + 1]) < 0)
- goto fail;
- }
-
- return numArgs / 2;
-
-fail:
- for (j = 0; j < i; j++) {
- free((*arrayRet)[j].needle);
- }
-
- free(*arrayRet);
- *arrayRet = NULL;
- return -1;
-}
-
-void freeLocateTagItem(LocateTagItem * item)
-{
- free(item->needle);
- free(item);
-}
-
-static int strstrSearchTag(Song * song, int type, char *str)
-{
- int i;
- char *dup;
- int ret = 0;
-
- if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) {
- dup = strDupToUpper(getSongUrl(song));
- if (strstr(dup, str))
- ret = 1;
- free(dup);
- if (ret == 1 || type == LOCATE_TAG_FILE_TYPE) {
- return ret;
- }
- }
-
- if (!song->tag)
- return 0;
-
- for (i = 0; i < song->tag->numOfItems && !ret; i++) {
- if (type != LOCATE_TAG_ANY_TYPE &&
- song->tag->items[i].type != type) {
- continue;
- }
-
- dup = strDupToUpper(song->tag->items[i].value);
- if (strstr(dup, str))
- ret = 1;
- free(dup);
- }
-
- return ret;
-}
-
-int strstrSearchTags(Song * song, int numItems, LocateTagItem * items)
-{
- int i;
-
- for (i = 0; i < numItems; i++) {
- if (!strstrSearchTag(song, items[i].tagType,
- items[i].needle)) {
- return 0;
- }
- }
-
- return 1;
-}
-
-static int tagItemFoundAndMatches(Song * song, int type, char *str)
-{
- int i;
-
- if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) {
- if (0 == strcmp(str, getSongUrl(song)))
- return 1;
- if (type == LOCATE_TAG_FILE_TYPE)
- return 0;
- }
-
- if (!song->tag)
- return 0;
-
- for (i = 0; i < song->tag->numOfItems; i++) {
- if (type != LOCATE_TAG_ANY_TYPE &&
- song->tag->items[i].type != type) {
- continue;
- }
-
- if (0 == strcmp(str, song->tag->items[i].value))
- return 1;
- }
-
- return 0;
-}
-
-
-int tagItemsFoundAndMatches(Song * song, int numItems, LocateTagItem * items)
-{
- int i;
-
- for (i = 0; i < numItems; i++) {
- if (!tagItemFoundAndMatches(song, items[i].tagType,
- items[i].needle)) {
- return 0;
- }
- }
-
- return 1;
-}
diff --git a/trunk/src/locate.h b/trunk/src/locate.h
deleted file mode 100644
index c165a310a..000000000
--- a/trunk/src/locate.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* the Music Player Daemon (MPD)
- * (c)2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "song.h"
-
-#define LOCATE_TAG_FILE_TYPE TAG_NUM_OF_ITEM_TYPES+10
-#define LOCATE_TAG_ANY_TYPE TAG_NUM_OF_ITEM_TYPES+20
-
-/* struct used for search, find, list queries */
-typedef struct _LocateTagItem {
- mpd_sint8 tagType;
- /* what we are looking for */
- char *needle;
-} LocateTagItem;
-
-int getLocateTagItemType(char *str);
-
-/* returns NULL if not a known type */
-LocateTagItem *newLocateTagItem(char *typeString, char *needle);
-
-/* return number of items or -1 on error */
-int newLocateTagItemArrayFromArgArray(char *argArray[], int numArgs,
- LocateTagItem ** arrayRet);
-
-void freeLocateTagItemArray(int count, LocateTagItem * array);
-
-void freeLocateTagItem(LocateTagItem * item);
-
-int strstrSearchTags(Song * song, int numItems, LocateTagItem * items);
-
-int tagItemsFoundAndMatches(Song * song, int numItems, LocateTagItem * items);
diff --git a/trunk/src/log.c b/trunk/src/log.c
deleted file mode 100644
index fa4ae64f0..000000000
--- a/trunk/src/log.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "log.h"
-
-#include "conf.h"
-#include "myfprintf.h"
-#include "utils.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <time.h>
-
-static unsigned int logLevel = LOG_LEVEL_LOW;
-static int warningFlushed;
-static int stdout_mode = 1;
-static char *warningBuffer;
-static int out_fd = -1;
-static int err_fd = -1;
-static const char *out_filename;
-static const char *err_filename;
-
-/* redirect stdin to /dev/null to work around a libao bug */
-static void redirect_stdin(void)
-{
- int fd;
- if ((fd = open("/dev/null", O_RDONLY)) < 0)
- FATAL("failed to open /dev/null %s\n", strerror(errno));
- if (dup2(fd, STDIN_FILENO) < 0)
- FATAL("dup2 stdin: %s\n", strerror(errno));
-}
-
-static void redirect_logs(void)
-{
- assert(out_fd > 0);
- assert(err_fd > 0);
- if (dup2(out_fd, STDOUT_FILENO) < 0)
- FATAL("problems dup2 stdout : %s\n", strerror(errno));
- if (dup2(err_fd, STDERR_FILENO) < 0)
- FATAL("problems dup2 stderr : %s\n", strerror(errno));
-}
-
-static const char *log_date(void)
-{
- static char buf[16];
- time_t t = time(NULL);
- strftime(buf, 16, "%b %d %H:%M : ", localtime(&t));
- return buf;
-}
-
-#define BUFFER_LENGTH 4096
-static void buffer_warning(const char *fmt, va_list args)
-{
- char buffer[BUFFER_LENGTH];
- char *tmp = buffer;
- size_t len = BUFFER_LENGTH;
-
- if (!stdout_mode) {
- memcpy(buffer, log_date(), 15);
- tmp += 15;
- len -= 15;
- }
-
- vsnprintf(tmp, len, fmt, args);
- warningBuffer = appendToString(warningBuffer, buffer);
-
- va_end(args);
-}
-
-static void do_log(FILE *fp, const char *fmt, va_list args)
-{
- if (!stdout_mode)
- fwrite(log_date(), 15, 1, fp);
- vfprintf(fp, fmt, args);
-}
-
-void flushWarningLog(void)
-{
- char *s = warningBuffer;
-
- DEBUG("flushing warning messages\n");
-
- if (warningBuffer != NULL)
- {
- while (s != NULL) {
- char *next = strchr(s, '\n');
- if (next == NULL) break;
- *next = '\0';
- next++;
- fprintf(stderr, "%s\n", s);
- s = next;
- }
-
- warningBuffer = NULL;
- }
-
- warningFlushed = 1;
-
- DEBUG("done flushing warning messages\n");
-}
-
-void initLog(const int verbose)
-{
- ConfigParam *param;
-
- /* unbuffer stdout, stderr is unbuffered by default, leave it */
- setvbuf(stdout, (char *)NULL, _IONBF, 0);
-
- if (verbose) {
- logLevel = LOG_LEVEL_DEBUG;
- return;
- }
- if (!(param = getConfigParam(CONF_LOG_LEVEL)))
- return;
- if (0 == strcmp(param->value, "default")) {
- logLevel = LOG_LEVEL_LOW;
- } else if (0 == strcmp(param->value, "secure")) {
- logLevel = LOG_LEVEL_SECURE;
- } else if (0 == strcmp(param->value, "verbose")) {
- logLevel = LOG_LEVEL_DEBUG;
- } else {
- FATAL("unknown log level \"%s\" at line %i\n",
- param->value, param->line);
- }
-}
-
-void open_log_files(const int use_stdout)
-{
- mode_t prev;
- ConfigParam *param;
-
- if (use_stdout) {
- flushWarningLog();
- return;
- }
-
- prev = umask(0066);
- param = parseConfigFilePath(CONF_LOG_FILE, 1);
- out_filename = param->value;
- out_fd = open(out_filename, O_CREAT | O_WRONLY | O_APPEND, 0666);
- if (out_fd < 0)
- FATAL("problem opening log file \"%s\" (config line %i) for "
- "writing\n", param->value, param->line);
-
- param = parseConfigFilePath(CONF_ERROR_FILE, 1);
- err_filename = param->value;
- err_fd = open(err_filename, O_CREAT | O_WRONLY | O_APPEND, 0666);
- if (err_fd < 0)
- FATAL("problem opening error file \"%s\" (config line %i) for "
- "writing\n", param->value, param->line);
-
- umask(prev);
-}
-
-void setup_log_output(const int use_stdout)
-{
- fflush(NULL);
- if (!use_stdout) {
- redirect_logs();
- stdout_mode = 0;
- }
- redirect_stdin();
-}
-
-#define log_func(func,level,fp) \
-mpd_printf void func(const char *fmt, ...) \
-{ \
- if (logLevel >= level) { \
- va_list args; \
- va_start(args, fmt); \
- do_log(fp, fmt, args); \
- va_end(args); \
- } \
-}
-
-log_func(ERROR, 0, stderr)
-log_func(LOG, 0, stdout)
-log_func(SECURE, LOG_LEVEL_SECURE, stdout)
-log_func(DEBUG, LOG_LEVEL_DEBUG, stdout)
-
-#undef log_func
-
-void WARNING(const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- if (warningFlushed) {
- do_log(stderr, fmt, args);
- } else
- buffer_warning(fmt, args);
- va_end(args);
-}
-
-mpd_printf mpd_noreturn void FATAL(const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- do_log(stderr, fmt, args);
- va_end(args);
- exit(EXIT_FAILURE);
-}
-
-int cycle_log_files(void)
-{
- mode_t prev;
-
- if (stdout_mode)
- return 0;
- assert(out_filename);
- assert(err_filename);
-
- DEBUG("Cycling log files...\n");
- close_log_files();
-
- prev = umask(0066);
-
- out_fd = open(out_filename, O_CREAT | O_WRONLY | O_APPEND, 0666);
- if (out_fd < 0) {
- ERROR("error re-opening log file: %s\n", out_filename);
- return -1;
- }
-
- err_fd = open(err_filename, O_CREAT | O_WRONLY | O_APPEND, 0666);
- if (err_fd < 0) {
- ERROR("error re-opening error file: %s\n", err_filename);
- return -1;
- }
-
- umask(prev);
-
- redirect_logs();
- DEBUG("Done cycling log files\n");
- return 0;
-}
-
-void close_log_files(void)
-{
- if (stdout_mode)
- return;
- assert(out_fd > 0);
- assert(err_fd > 0);
- xclose(out_fd);
- xclose(err_fd);
-}
-
diff --git a/trunk/src/log.h b/trunk/src/log.h
deleted file mode 100644
index 34f6ac00e..000000000
--- a/trunk/src/log.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef LOG_H
-#define LOG_H
-
-#include "../config.h"
-#include "gcc.h"
-
-#include <unistd.h>
-
-#define LOG_LEVEL_LOW 0
-#define LOG_LEVEL_SECURE 1
-#define LOG_LEVEL_DEBUG 2
-
-mpd_printf void ERROR(const char *fmt, ...);
-mpd_printf void LOG(const char *fmt, ...);
-mpd_printf void SECURE(const char *fmt, ...);
-mpd_printf void DEBUG(const char *fmt, ...);
-mpd_printf void WARNING(const char *fmt, ...);
-mpd_printf void FATAL(const char *fmt, ...);
-
-void initLog(const int verbose);
-
-void setup_log_output(const int use_stdout);
-
-void open_log_files(const int use_stdout);
-
-int cycle_log_files(void);
-
-void close_log_files(void);
-
-void flushWarningLog(void);
-
-#endif /* LOG_H */
diff --git a/trunk/src/ls.c b/trunk/src/ls.c
deleted file mode 100644
index 0b3f7f354..000000000
--- a/trunk/src/ls.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ls.h"
-#include "playlist.h"
-#include "path.h"
-#include "myfprintf.h"
-#include "log.h"
-#include "utf8.h"
-#include "utils.h"
-
-#include <dirent.h>
-#include <stdio.h>
-#include <errno.h>
-
-static char *remoteUrlPrefixes[] = {
- "http://",
- NULL
-};
-
-int printRemoteUrlHandlers(int fd)
-{
- char **prefixes = remoteUrlPrefixes;
-
- while (*prefixes) {
- fdprintf(fd, "handler: %s\n", *prefixes);
- prefixes++;
- }
-
- return 0;
-}
-
-int isValidRemoteUtf8Url(char *utf8url)
-{
- int ret = 0;
- char *temp;
-
- switch (isRemoteUrl(utf8url)) {
- case 1:
- ret = 1;
- temp = utf8url;
- while (*temp) {
- if ((*temp >= 'a' && *temp <= 'z') ||
- (*temp >= 'A' && *temp <= 'Z') ||
- (*temp >= '0' && *temp <= '9') ||
- *temp == '$' ||
- *temp == '-' ||
- *temp == '.' ||
- *temp == '+' ||
- *temp == '!' ||
- *temp == '*' ||
- *temp == '\'' ||
- *temp == '(' ||
- *temp == ')' ||
- *temp == ',' ||
- *temp == '%' ||
- *temp == '/' ||
- *temp == ':' ||
- *temp == '?' ||
- *temp == ';' || *temp == '&' || *temp == '=') {
- } else {
- ret = 1;
- break;
- }
- temp++;
- }
- break;
- }
-
- return ret;
-}
-
-int isRemoteUrl(char *url)
-{
- int count = 0;
- char **urlPrefixes = remoteUrlPrefixes;
-
- while (*urlPrefixes) {
- count++;
- if (strncmp(*urlPrefixes, url, strlen(*urlPrefixes)) == 0) {
- return count;
- }
- urlPrefixes++;
- }
-
- return 0;
-}
-
-int lsPlaylists(int fd, char *utf8path)
-{
- DIR *dir;
- struct stat st;
- struct dirent *ent;
- char *dup;
- char *utf8;
- char s[MAXPATHLEN + 1];
- List *list = NULL;
- ListNode *node = NULL;
- char *path = utf8ToFsCharset(utf8path);
- char *actualPath = rpp2app(path);
- int actlen = strlen(actualPath) + 1;
- int maxlen = MAXPATHLEN - actlen;
- int suflen = strlen(PLAYLIST_FILE_SUFFIX) + 1;
- int suff;
-
- if (actlen > MAXPATHLEN - 1 || (dir = opendir(actualPath)) == NULL) {
- return 0;
- }
-
- s[MAXPATHLEN] = '\0';
- /* this is safe, notice actlen > MAXPATHLEN-1 above */
- strcpy(s, actualPath);
- strcat(s, "/");
-
- while ((ent = readdir(dir))) {
- size_t len = strlen(ent->d_name) + 1;
- dup = ent->d_name;
- if (mpd_likely(len <= maxlen) &&
- dup[0] != '.' &&
- (suff = strlen(dup) - suflen) > 0 &&
- dup[suff] == '.' &&
- strcmp(dup + suff + 1, PLAYLIST_FILE_SUFFIX) == 0) {
- memcpy(s + actlen, ent->d_name, len);
- if (stat(s, &st) == 0) {
- if (S_ISREG(st.st_mode)) {
- if (list == NULL)
- list = makeList(NULL, 1);
- dup[suff] = '\0';
- if ((utf8 = fsCharsetToUtf8(dup))) {
- insertInList(list, utf8, NULL);
- }
- }
- }
- }
- }
-
- closedir(dir);
-
- if (list) {
- int i;
- sortList(list);
-
- dup = xmalloc(strlen(utf8path) + 2);
- strcpy(dup, utf8path);
- for (i = strlen(dup) - 1; i >= 0 && dup[i] == '/'; i--) {
- dup[i] = '\0';
- }
- if (strlen(dup))
- strcat(dup, "/");
-
- node = list->firstNode;
- while (node != NULL) {
- if (!strchr(node->key, '\n')) {
- fdprintf(fd, "playlist: %s%s\n", dup,
- node->key);
- }
- node = node->nextNode;
- }
-
- freeList(list);
- free(dup);
- }
-
- return 0;
-}
-
-int myStat(char *utf8file, struct stat *st)
-{
- char *file = utf8ToFsCharset(utf8file);
- char *actualFile = file;
-
- if (actualFile[0] != '/')
- actualFile = rmp2amp(file);
-
- return stat(actualFile, st);
-}
-
-static int isFile(char *utf8file, time_t * mtime)
-{
- struct stat st;
-
- if (myStat(utf8file, &st) == 0) {
- if (S_ISREG(st.st_mode)) {
- if (mtime)
- *mtime = st.st_mtime;
- return 1;
- } else {
- DEBUG("isFile: %s is not a regular file\n", utf8file);
- return 0;
- }
- } else {
- DEBUG("isFile: failed to stat: %s: %s\n", utf8file,
- strerror(errno));
- }
-
- return 0;
-}
-
-/* suffixes should be ascii only characters */
-char *getSuffix(char *utf8file)
-{
- char *ret = NULL;
-
- while (*utf8file) {
- if (*utf8file == '.')
- ret = utf8file + 1;
- utf8file++;
- }
-
- return ret;
-}
-
-static int hasSuffix(char *utf8file, char *suffix)
-{
- char *s = getSuffix(utf8file);
- if (s && 0 == strcmp(s, suffix))
- return 1;
- return 0;
-}
-
-int isPlaylist(char *utf8file)
-{
- if (isFile(utf8file, NULL)) {
- return hasSuffix(utf8file, PLAYLIST_FILE_SUFFIX);
- }
- return 0;
-}
-
-int isDir(char *utf8name)
-{
- struct stat st;
-
- if (myStat(utf8name, &st) == 0) {
- if (S_ISDIR(st.st_mode)) {
- return 1;
- }
- }
-
- return 0;
-}
-
-InputPlugin *hasMusicSuffix(char *utf8file, unsigned int next)
-{
- InputPlugin *ret = NULL;
-
- char *s = getSuffix(utf8file);
- if (s) {
- ret = getInputPluginFromSuffix(s, next);
- } else {
- DEBUG("hasMusicSuffix: The file: %s has no valid suffix\n",
- utf8file);
- }
-
- return ret;
-}
-
-InputPlugin *isMusic(char *utf8file, time_t * mtime, unsigned int next)
-{
- if (isFile(utf8file, mtime)) {
- InputPlugin *plugin = hasMusicSuffix(utf8file, next);
- if (plugin != NULL)
- return plugin;
- }
- DEBUG("isMusic: %s is not a valid file\n", utf8file);
- return NULL;
-}
diff --git a/trunk/src/ls.h b/trunk/src/ls.h
deleted file mode 100644
index 20f668bd9..000000000
--- a/trunk/src/ls.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef LS_H
-#define LS_H
-
-#include "../config.h"
-
-#include "inputPlugin.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <time.h>
-
-int lsPlaylists(int fd, char *utf8path);
-
-char *getSuffix(char *utf8file);
-
-int isValidRemoteUtf8Url(char *utf8url);
-
-int isRemoteUrl(char *url);
-
-int myStat(char *utf8file, struct stat *st);
-
-int isDir(char *utf8name);
-
-int isPlaylist(char *utf8file);
-
-InputPlugin *hasMusicSuffix(char *utf8file, unsigned int next);
-
-InputPlugin *isMusic(char *utf8file, time_t * mtime, unsigned int next);
-
-int printRemoteUrlHandlers(int fd);
-
-#endif
diff --git a/trunk/src/main.c b/trunk/src/main.c
deleted file mode 100644
index 4c537eb1d..000000000
--- a/trunk/src/main.c
+++ /dev/null
@@ -1,482 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "interface.h"
-#include "command.h"
-#include "playlist.h"
-#include "directory.h"
-#include "player.h"
-#include "listen.h"
-#include "conf.h"
-#include "path.h"
-#include "playerData.h"
-#include "stats.h"
-#include "sig_handlers.h"
-#include "audio.h"
-#include "volume.h"
-#include "log.h"
-#include "permission.h"
-#include "replayGain.h"
-#include "inputPlugin.h"
-#include "audioOutput.h"
-#include "inputStream.h"
-#include "state_file.h"
-#include "tag.h"
-#include "tagTracker.h"
-#include "dbUtils.h"
-#include "../config.h"
-#include "utils.h"
-#include "normalize.h"
-#include "zeroconf.h"
-
-#include <stdio.h>
-#include <sys/select.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <grp.h>
-#include <time.h>
-#include <unistd.h>
-
-#define SYSTEM_CONFIG_FILE_LOCATION "/etc/mpd.conf"
-#define USER_CONFIG_FILE_LOCATION "/.mpdconf"
-
-typedef struct _Options {
- int kill;
- int daemon;
- int stdOutput;
- int createDB;
- int verbose;
-} Options;
-
-/*
- * from git-1.3.0, needed for solaris
- */
-#ifndef HAVE_SETENV
-static int setenv(const char *name, const char *value, int replace)
-{
- int out;
- size_t namelen, valuelen;
- char *envstr;
-
- if (!name || !value)
- return -1;
- if (!replace) {
- char *oldval = NULL;
- oldval = getenv(name);
- if (oldval)
- return 0;
- }
-
- namelen = strlen(name);
- valuelen = strlen(value);
- envstr = xmalloc((namelen + valuelen + 2));
- if (!envstr)
- return -1;
-
- memcpy(envstr, name, namelen);
- envstr[namelen] = '=';
- memcpy(envstr + namelen + 1, value, valuelen);
- envstr[namelen + valuelen + 1] = 0;
-
- out = putenv(envstr);
- /* putenv(3) makes the argument string part of the environment,
- * and changing that string modifies the environment --- which
- * means we do not own that storage anymore. Do not free
- * envstr.
- */
-
- return out;
-}
-#endif /* HAVE_SETENV */
-
-static void usage(char *argv[])
-{
- ERROR("usage:\n");
- ERROR(" %s [options] <conf file>\n", argv[0]);
- ERROR(" %s [options] (searches for ~%s then %s)\n",
- argv[0], USER_CONFIG_FILE_LOCATION, SYSTEM_CONFIG_FILE_LOCATION);
- ERROR("\n");
- ERROR("options:\n");
- ERROR(" --help this usage statement\n");
- ERROR(" --kill kill the currently running mpd session\n");
- ERROR
- (" --create-db force (re)creation of database and exit\n");
- ERROR
- (" --no-create-db don't create database, even if it doesn't exist\n");
- ERROR(" --no-daemon don't detach from console\n");
- ERROR(" --stdout print messages to stdout and stderr\n");
- ERROR(" --verbose verbose logging\n");
- ERROR(" --version prints version information\n");
-}
-
-static void version(void)
-{
- LOG("mpd (MPD: Music Player Daemon) %s\n", VERSION);
- LOG("\n");
- LOG("Copyright (C) 2003-2007 Warren Dukes <warren.dukes@gmail.com>\n");
- LOG("This is free software; see the source for copying conditions. There is NO\n");
- LOG("warranty; not even MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
- LOG("\n");
- LOG("Supported formats:\n");
-
- initInputPlugins();
- printAllInputPluginSuffixes(stdout);
-
- LOG("\n");
- LOG("Supported outputs:\n");
- loadAudioDrivers();
- printAllOutputPluginTypes(stdout);
-}
-
-static void parseOptions(int argc, char **argv, Options * options)
-{
- int argcLeft = argc;
-
- options->verbose = 0;
- options->daemon = 1;
- options->stdOutput = 0;
- options->createDB = 0;
- options->kill = 0;
-
- if (argc > 1) {
- int i = 1;
- while (i < argc) {
- if (strncmp(argv[i], "--", 2) == 0) {
- if (strcmp(argv[i], "--help") == 0) {
- usage(argv);
- exit(EXIT_SUCCESS);
- } else if (strcmp(argv[i], "--kill") == 0) {
- options->kill++;
- argcLeft--;
- } else if (strcmp(argv[i], "--no-daemon") == 0) {
- options->daemon = 0;
- argcLeft--;
- } else if (strcmp(argv[i], "--stdout") == 0) {
- options->stdOutput = 1;
- argcLeft--;
- } else if (strcmp(argv[i], "--create-db") == 0) {
- options->stdOutput = 1;
- options->createDB = 1;
- argcLeft--;
- } else if (strcmp(argv[i], "--no-create-db") ==
- 0) {
- options->createDB = -1;
- argcLeft--;
- } else if (strcmp(argv[i], "--verbose") == 0) {
- options->verbose = 1;
- argcLeft--;
- } else if (strcmp(argv[i], "--version") == 0) {
- version();
- exit(EXIT_SUCCESS);
- } else {
- fprintf(stderr,
- "unknown command line option: %s\n",
- argv[i]);
- exit(EXIT_FAILURE);
- }
- } else
- break;
- i++;
- }
- }
-
- if (argcLeft <= 2) {
- if (argcLeft == 2) {
- readConf(argv[argc - 1]);
- return;
- } else if (argcLeft == 1) {
- struct stat st;
- char *homedir = getenv("HOME");
- char userfile[MAXPATHLEN + 1] = "";
- if (homedir && (strlen(homedir) +
- strlen(USER_CONFIG_FILE_LOCATION)) <
- MAXPATHLEN) {
- strcpy(userfile, homedir);
- strcat(userfile, USER_CONFIG_FILE_LOCATION);
- }
- if (strlen(userfile) && (0 == stat(userfile, &st))) {
- readConf(userfile);
- return;
- } else if (0 == stat(SYSTEM_CONFIG_FILE_LOCATION, &st)) {
- readConf(SYSTEM_CONFIG_FILE_LOCATION);
- return;
- }
- }
- }
-
- usage(argv);
- exit(EXIT_FAILURE);
-}
-
-static void closeAllFDs(void)
-{
- int i;
- int fds = getdtablesize();
-
- for (i = 3; i < fds; i++)
- close(i);
-}
-
-static void changeToUser(void)
-{
- ConfigParam *param = getConfigParam(CONF_USER);
-
- if (param && strlen(param->value)) {
- /* get uid */
- struct passwd *userpwd;
- if ((userpwd = getpwnam(param->value)) == NULL) {
- FATAL("no such user \"%s\" at line %i\n", param->value,
- param->line);
- }
-
- if (setgid(userpwd->pw_gid) == -1) {
- FATAL("cannot setgid for user \"%s\" at line %i: %s\n",
- param->value, param->line, strerror(errno));
- }
-#ifdef _BSD_SOURCE
- /* init suplementary groups
- * (must be done before we change our uid)
- */
- if (initgroups(param->value, userpwd->pw_gid) == -1) {
- WARNING("cannot init supplementary groups "
- "of user \"%s\" at line %i: %s\n",
- param->value, param->line, strerror(errno));
- }
-#endif
-
- /* set uid */
- if (setuid(userpwd->pw_uid) == -1) {
- FATAL("cannot change to uid of user "
- "\"%s\" at line %i: %s\n",
- param->value, param->line, strerror(errno));
- }
-
- /* this is needed by libs such as arts */
- if (userpwd->pw_dir) {
- setenv("HOME", userpwd->pw_dir, 1);
- }
- }
-}
-
-static void openDB(Options * options, char *argv0)
-{
- if (options->createDB > 0 || readDirectoryDB() < 0) {
- if (options->createDB < 0) {
- FATAL("can't open db file and using "
- "\"--no-create-db\" command line option\n"
- "try running \"%s --create-db\"\n", argv0);
- }
- flushWarningLog();
- if (checkDirectoryDB() < 0)
- exit(EXIT_FAILURE);
- initMp3Directory();
- if (writeDirectoryDB() < 0)
- exit(EXIT_FAILURE);
- if (options->createDB)
- exit(EXIT_SUCCESS);
- }
-}
-
-static void daemonize(Options * options)
-{
- FILE *fp = NULL;
- ConfigParam *pidFileParam = parseConfigFilePath(CONF_PID_FILE, 0);
-
- if (pidFileParam) {
- /* do this before daemon'izing so we can fail gracefully if we can't
- * write to the pid file */
- DEBUG("opening pid file\n");
- fp = fopen(pidFileParam->value, "w+");
- if (!fp) {
- FATAL("could not open %s \"%s\" (at line %i) for writing: %s\n",
- CONF_PID_FILE, pidFileParam->value,
- pidFileParam->line, strerror(errno));
- }
- }
-
- if (options->daemon) {
- int pid;
-
- fflush(NULL);
- pid = fork();
- if (pid > 0)
- _exit(EXIT_SUCCESS);
- else if (pid < 0) {
- FATAL("problems fork'ing for daemon!\n");
- }
-
- if (chdir("/") < 0) {
- FATAL("problems changing to root directory\n");
- }
-
- if (setsid() < 0) {
- FATAL("problems setsid'ing\n");
- }
-
- fflush(NULL);
- pid = fork();
- if (pid > 0)
- _exit(EXIT_SUCCESS);
- else if (pid < 0) {
- FATAL("problems fork'ing for daemon!\n");
- }
-
- DEBUG("daemonized!\n");
- }
-
- if (pidFileParam) {
- DEBUG("writing pid file\n");
- fprintf(fp, "%lu\n", (unsigned long)getpid());
- fclose(fp);
- }
-}
-
-static void cleanUpPidFile(void)
-{
- ConfigParam *pidFileParam = parseConfigFilePath(CONF_PID_FILE, 0);
-
- if (!pidFileParam)
- return;
-
- DEBUG("cleaning up pid file\n");
-
- unlink(pidFileParam->value);
-}
-
-static void killFromPidFile(char *cmd, int killOption)
-{
- FILE *fp;
- ConfigParam *pidFileParam = parseConfigFilePath(CONF_PID_FILE, 0);
- int pid;
-
- if (!pidFileParam) {
- FATAL("no pid_file specified in the config file\n");
- }
-
- fp = fopen(pidFileParam->value, "r");
- if (!fp) {
- FATAL("unable to open %s \"%s\": %s\n",
- CONF_PID_FILE, pidFileParam->value, strerror(errno));
- }
- if (fscanf(fp, "%i", &pid) != 1) {
- FATAL("unable to read the pid from file \"%s\"\n",
- pidFileParam->value);
- }
- fclose(fp);
-
- if (kill(pid, SIGTERM)) {
- FATAL("unable to kill proccess %i: %s\n", pid, strerror(errno));
- }
- exit(EXIT_SUCCESS);
-}
-
-int main(int argc, char *argv[])
-{
- Options options;
- clock_t start;
-
- closeAllFDs();
-
- initConf();
-
- parseOptions(argc, argv, &options);
-
- if (options.kill)
- killFromPidFile(argv[0], options.kill);
-
- initStats();
- initTagConfig();
- initLog(options.verbose);
-
- if (options.createDB <= 0)
- listenOnPort();
-
- changeToUser();
-
- open_log_files(options.stdOutput);
-
- initPaths();
- initPermissions();
- initPlaylist();
- initInputPlugins();
-
- openDB(&options, argv[0]);
-
- initCommands();
- initPlayerData();
- initAudioConfig();
- initAudioDriver();
- initVolume();
- initInterfaces();
- initZeroconf();
- initReplayGainState();
- initNormalization();
- initInputStream();
-
- daemonize(&options);
-
- setup_log_output(options.stdOutput);
-
-
-
- initSigHandlers();
-
- openVolumeDevice();
- read_state_file();
-
- while (COMMAND_RETURN_KILL != doIOForInterfaces()) {
- if (COMMAND_RETURN_KILL == handlePendingSignals())
- break;
- syncPlayerAndPlaylist();
- closeOldInterfaces();
- readDirectoryDBIfUpdateIsFinished();
- }
-
- write_state_file();
- playerKill();
- finishZeroconf();
- freeAllInterfaces();
- closeAllListenSockets();
- finishPlaylist();
-
- start = clock();
- closeMp3Directory();
- DEBUG("closeMp3Directory took %f seconds\n",
- ((float)(clock()-start))/CLOCKS_PER_SEC);
-
- finishNormalization();
- finishAudioDriver();
- finishAudioConfig();
- finishVolume();
- finishPaths();
- finishPermissions();
- finishCommands();
- finishInputPlugins();
- cleanUpPidFile();
- finishConf();
- freePlayerData();
-
- close_log_files();
- return EXIT_SUCCESS;
-}
diff --git a/trunk/src/metadataChunk.c b/trunk/src/metadataChunk.c
deleted file mode 100644
index bc5118fd0..000000000
--- a/trunk/src/metadataChunk.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "metadataChunk.h"
-#include "gcc.h"
-
-#include <string.h>
-
-static void initMetadataChunk(MetadataChunk * chunk)
-{
- chunk->name = -1;
- chunk->artist = -1;
- chunk->album = -1;
- chunk->title = -1;
-}
-
-#define dupElementToTag(item, element) { \
- if(element >= 0 && element < METADATA_BUFFER_LENGTH) { \
- addItemToMpdTag(ret, item, chunk->buffer+element); \
- } \
-}
-
-MpdTag *metadataChunkToMpdTagDup(MetadataChunk * chunk)
-{
- MpdTag *ret = newMpdTag();
-
- chunk->buffer[METADATA_BUFFER_LENGTH - 1] = '\0';
-
- dupElementToTag(TAG_ITEM_NAME, chunk->name);
- dupElementToTag(TAG_ITEM_TITLE, chunk->title);
- dupElementToTag(TAG_ITEM_ARTIST, chunk->artist);
- dupElementToTag(TAG_ITEM_ALBUM, chunk->album);
-
- return ret;
-}
-
-#define copyStringToChunk(string, element) { \
- if(element < 0 && string && (slen = strlen(string)) && \
- pos < METADATA_BUFFER_LENGTH-1) \
- { \
- size_t len = slen; \
- size_t max = METADATA_BUFFER_LENGTH - 1 - pos; \
- if (mpd_unlikely(len > max)) \
- len = max; \
- memcpy(chunk->buffer+pos, string, len); \
- *(chunk->buffer+pos+len) = '\0'; \
- element = pos; \
- pos += slen+1; \
- } \
-}
-
-void copyMpdTagToMetadataChunk(MpdTag * tag, MetadataChunk * chunk)
-{
- int pos = 0;
- int slen;
- int i;
-
- initMetadataChunk(chunk);
-
- if (!tag)
- return;
-
- for (i = 0; i < tag->numOfItems; i++) {
- switch (tag->items[i].type) {
- case TAG_ITEM_NAME:
- copyStringToChunk(tag->items[i].value, chunk->name);
- break;
- case TAG_ITEM_TITLE:
- copyStringToChunk(tag->items[i].value, chunk->title);
- break;
- case TAG_ITEM_ARTIST:
- copyStringToChunk(tag->items[i].value, chunk->artist);
- break;
- case TAG_ITEM_ALBUM:
- copyStringToChunk(tag->items[i].value, chunk->album);
- break;
- }
- }
-}
diff --git a/trunk/src/metadataChunk.h b/trunk/src/metadataChunk.h
deleted file mode 100644
index c1da8b320..000000000
--- a/trunk/src/metadataChunk.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef METADATA_CHUNK_H
-#define METADATA_CHUNK_H
-
-#define METADATA_BUFFER_LENGTH 1024
-
-#include "tag.h"
-
-typedef struct _MetadataChunk {
- int name;
- int title;
- int artist;
- int album;
- char buffer[METADATA_BUFFER_LENGTH];
-} MetadataChunk;
-
-MpdTag *metadataChunkToMpdTagDup(MetadataChunk * chunk);
-
-void copyMpdTagToMetadataChunk(MpdTag * tag, MetadataChunk * chunk);
-
-#endif
diff --git a/trunk/src/mp4ff/Makefile.am b/trunk/src/mp4ff/Makefile.am
deleted file mode 100644
index d1258e7b8..000000000
--- a/trunk/src/mp4ff/Makefile.am
+++ /dev/null
@@ -1,9 +0,0 @@
-noinst_LTLIBRARIES = libmp4ff.la
-
-noinst_HEADERS = mp4ff.h
-
-libmp4ff_la_SOURCES = mp4ff.c mp4atom.c mp4meta.c mp4sample.c mp4util.c \
- mp4tagupdate.c mp4ff.h mp4ffint.h mp4ff_int_types.h \
- drms.h drms.c drmstables.h
-
-AM_CFLAGS = -DUSE_TAGGING=1
diff --git a/trunk/src/mp4ff/drms.c b/trunk/src/mp4ff/drms.c
deleted file mode 100644
index 368b88110..000000000
--- a/trunk/src/mp4ff/drms.c
+++ /dev/null
@@ -1,1043 +0,0 @@
-/*****************************************************************************
- * drms.c : DRMS
- *****************************************************************************
- * Copyright (C) 2004 VideoLAN
- * $Id: drms.c,v 1.3 2004/01/11 15:52:18 menno Exp $
- *
- * Author: Jon Lech Johansen <jon-vl@nanocrew.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
-
-#include <stdlib.h> /* malloc(), free() */
-
-#include "mp4ffint.h"
-
-#ifdef ITUNES_DRM
-
-#ifdef _WIN32
-#include <tchar.h>
-#include <shlobj.h>
-#include <windows.h>
-#endif
-
-#include "drms.h"
-#include "drmstables.h"
-
-static __inline uint32_t U32_AT( void * _p )
-{
- uint8_t * p = (uint8_t *)_p;
- return ( ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16)
- | ((uint32_t)p[2] << 8) | p[3] );
-}
-
-#define TAOS_INIT( tmp, i ) \
- memset( tmp, 0, sizeof(tmp) ); \
- tmp[ i + 0 ] = 0x67452301; \
- tmp[ i + 1 ] = 0xEFCDAB89; \
- tmp[ i + 2 ] = 0x98BADCFE; \
- tmp[ i + 3 ] = 0x10325476;
-
-#define ROR( x, n ) (((x) << (32-(n))) | ((x) >> (n)))
-
-static void init_ctx( uint32_t *p_ctx, uint32_t *p_input )
-{
- uint32_t i;
- uint32_t p_tmp[ 6 ];
-
- p_ctx[ 0 ] = sizeof(*p_input);
-
- memset( &p_ctx[ 1 + 4 ], 0, sizeof(*p_input) * 4 );
- memcpy( &p_ctx[ 1 + 0 ], p_input, sizeof(*p_input) * 4 );
-
- p_tmp[ 0 ] = p_ctx[ 1 + 3 ];
-
- for( i = 0; i < sizeof(p_drms_tab1)/sizeof(p_drms_tab1[ 0 ]); i++ )
- {
- p_tmp[ 0 ] = ROR( p_tmp[ 0 ], 8 );
-
- p_tmp[ 5 ] = p_drms_tab2[ (p_tmp[ 0 ] >> 24) & 0xFF ]
- ^ ROR( p_drms_tab2[ (p_tmp[ 0 ] >> 16) & 0xFF ], 8 )
- ^ ROR( p_drms_tab2[ (p_tmp[ 0 ] >> 8) & 0xFF ], 16 )
- ^ ROR( p_drms_tab2[ p_tmp[ 0 ] & 0xFF ], 24 )
- ^ p_drms_tab1[ i ]
- ^ p_ctx[ 1 + ((i + 1) * 4) - 4 ];
-
- p_ctx[ 1 + ((i + 1) * 4) + 0 ] = p_tmp[ 5 ];
- p_tmp[ 5 ] ^= p_ctx[ 1 + ((i + 1) * 4) - 3 ];
- p_ctx[ 1 + ((i + 1) * 4) + 1 ] = p_tmp[ 5 ];
- p_tmp[ 5 ] ^= p_ctx[ 1 + ((i + 1) * 4) - 2 ];
- p_ctx[ 1 + ((i + 1) * 4) + 2 ] = p_tmp[ 5 ];
- p_tmp[ 5 ] ^= p_ctx[ 1 + ((i + 1) * 4) - 1 ];
- p_ctx[ 1 + ((i + 1) * 4) + 3 ] = p_tmp[ 5 ];
-
- p_tmp[ 0 ] = p_tmp[ 5 ];
- }
-
- memcpy( &p_ctx[ 1 + 64 ], &p_ctx[ 1 ], sizeof(*p_ctx) * 4 );
-
- for( i = 4; i < sizeof(p_drms_tab1); i++ )
- {
- p_tmp[ 2 ] = p_ctx[ 1 + 4 + (i - 4) ];
-
- p_tmp[ 0 ] = (((p_tmp[ 2 ] >> 7) & 0x01010101) * 27)
- ^ ((p_tmp[ 2 ] & 0xFF7F7F7F) << 1);
- p_tmp[ 1 ] = (((p_tmp[ 0 ] >> 7) & 0x01010101) * 27)
- ^ ((p_tmp[ 0 ] & 0xFF7F7F7F) << 1);
- p_tmp[ 4 ] = (((p_tmp[ 1 ] >> 7) & 0x01010101) * 27)
- ^ ((p_tmp[ 1 ] & 0xFF7F7F7F) << 1);
-
- p_tmp[ 2 ] ^= p_tmp[ 4 ];
-
- p_tmp[ 3 ] = ROR( p_tmp[ 1 ] ^ p_tmp[ 2 ], 16 )
- ^ ROR( p_tmp[ 0 ] ^ p_tmp[ 2 ], 8 )
- ^ ROR( p_tmp[ 2 ], 24 );
-
- p_ctx[ 1 + 4 + 64 + (i - 4) ] = p_tmp[ 3 ] ^ p_tmp[ 4 ]
- ^ p_tmp[ 1 ] ^ p_tmp[ 0 ];
- }
-}
-
-static void ctx_xor( uint32_t *p_ctx, uint32_t *p_in, uint32_t *p_out,
- uint32_t p_table1[ 256 ], uint32_t p_table2[ 256 ] )
-{
- uint32_t i, x, y;
- uint32_t p_tmp1[ 4 ];
- uint32_t p_tmp2[ 4 ];
-
- i = p_ctx[ 0 ] * 4;
-
- p_tmp1[ 0 ] = p_ctx[ 1 + i + 24 ] ^ p_in[ 0 ];
- p_tmp1[ 1 ] = p_ctx[ 1 + i + 25 ] ^ p_in[ 1 ];
- p_tmp1[ 2 ] = p_ctx[ 1 + i + 26 ] ^ p_in[ 2 ];
- p_tmp1[ 3 ] = p_ctx[ 1 + i + 27 ] ^ p_in[ 3 ];
-
- i += 84;
-
-#define XOR_ROR( p_table, p_tmp, i_ctx ) \
- p_table[ (p_tmp[ y > 2 ? y - 3 : y + 1 ] >> 24) & 0xFF ] \
- ^ ROR( p_table[ (p_tmp[ y > 1 ? y - 2 : y + 2 ] >> 16) & 0xFF ], 8 ) \
- ^ ROR( p_table[ (p_tmp[ y > 0 ? y - 1 : y + 3 ] >> 8) & 0xFF ], 16 ) \
- ^ ROR( p_table[ p_tmp[ y ] & 0xFF ], 24 ) \
- ^ p_ctx[ i_ctx ]
-
- for( x = 0; x < 1; x++ )
- {
- memcpy( p_tmp2, p_tmp1, sizeof(p_tmp1) );
-
- for( y = 0; y < 4; y++ )
- {
- p_tmp1[ y ] = XOR_ROR( p_table1, p_tmp2, 1 + i - x + y );
- }
- }
-
- for( ; x < 9; x++ )
- {
- memcpy( p_tmp2, p_tmp1, sizeof(p_tmp1) );
-
- for( y = 0; y < 4; y++ )
- {
- p_tmp1[ y ] = XOR_ROR( p_table1, p_tmp2,
- 1 + i - x - ((x * 3) - y) );
- }
- }
-
- for( y = 0; y < 4; y++ )
- {
- p_out[ y ] = XOR_ROR( p_table2, p_tmp1,
- 1 + i - x - ((x * 3) - y) );
- }
-
-#undef XOR_ROR
-}
-
-static void taos( uint32_t *p_buffer, uint32_t *p_input )
-{
- uint32_t i;
- uint32_t x = 0;
- uint32_t p_tmp1[ 4 ];
- uint32_t p_tmp2[ 4 ];
-
- memcpy( p_tmp1, p_buffer, sizeof(p_tmp1) );
-
- p_tmp2[ 0 ] = ((~p_tmp1[ 1 ] & p_tmp1[ 3 ])
- | (p_tmp1[ 2 ] & p_tmp1[ 1 ])) + p_input[ x ];
- p_tmp1[ 0 ] = p_tmp2[ 0 ] + p_tmp1[ 0 ] + p_drms_tab_taos[ x++ ];
-
- for( i = 0; i < 4; i++ )
- {
- p_tmp2[ 0 ] = ((p_tmp1[ 0 ] >> 0x19)
- | (p_tmp1[ 0 ] << 0x7)) + p_tmp1[ 1 ];
- p_tmp2[ 1 ] = ((~p_tmp2[ 0 ] & p_tmp1[ 2 ])
- | (p_tmp1[ 1 ] & p_tmp2[ 0 ])) + p_input[ x ];
- p_tmp2[ 1 ] += p_tmp1[ 3 ] + p_drms_tab_taos[ x++ ];
-
- p_tmp1[ 3 ] = ((p_tmp2[ 1 ] >> 0x14)
- | (p_tmp2[ 1 ] << 0xC)) + p_tmp2[ 0 ];
- p_tmp2[ 1 ] = ((~p_tmp1[ 3 ] & p_tmp1[ 1 ])
- | (p_tmp1[ 3 ] & p_tmp2[ 0 ])) + p_input[ x ];
- p_tmp2[ 1 ] += p_tmp1[ 2 ] + p_drms_tab_taos[ x++ ];
-
- p_tmp1[ 2 ] = ((p_tmp2[ 1 ] >> 0xF)
- | (p_tmp2[ 1 ] << 0x11)) + p_tmp1[ 3 ];
- p_tmp2[ 1 ] = ((~p_tmp1[ 2 ] & p_tmp2[ 0 ])
- | (p_tmp1[ 3 ] & p_tmp1[ 2 ])) + p_input[ x ];
- p_tmp2[ 2 ] = p_tmp2[ 1 ] + p_tmp1[ 1 ] + p_drms_tab_taos[ x++ ];
-
- p_tmp1[ 1 ] = ((p_tmp2[ 2 ] << 0x16)
- | (p_tmp2[ 2 ] >> 0xA)) + p_tmp1[ 2 ];
- if( i == 3 )
- {
- p_tmp2[ 1 ] = ((~p_tmp1[ 3 ] & p_tmp1[ 2 ])
- | (p_tmp1[ 3 ] & p_tmp1[ 1 ])) + p_input[ 1 ];
- }
- else
- {
- p_tmp2[ 1 ] = ((~p_tmp1[ 1 ] & p_tmp1[ 3 ])
- | (p_tmp1[ 2 ] & p_tmp1[ 1 ])) + p_input[ x ];
- }
- p_tmp1[ 0 ] = p_tmp2[ 0 ] + p_tmp2[ 1 ] + p_drms_tab_taos[ x++ ];
- }
-
- for( i = 0; i < 4; i++ )
- {
- uint8_t p_table[ 4 ][ 4 ] =
- {
- { 6, 11, 0, 5 },
- { 10, 15, 4, 9 },
- { 14, 3, 8, 13 },
- { 2, 7, 12, 5 }
- };
-
- p_tmp2[ 0 ] = ((p_tmp1[ 0 ] >> 0x1B)
- | (p_tmp1[ 0 ] << 0x5)) + p_tmp1[ 1 ];
- p_tmp2[ 1 ] = ((~p_tmp1[ 2 ] & p_tmp1[ 1 ])
- | (p_tmp1[ 2 ] & p_tmp2[ 0 ]))
- + p_input[ p_table[ i ][ 0 ] ];
- p_tmp2[ 1 ] += p_tmp1[ 3 ] + p_drms_tab_taos[ x++ ];
-
- p_tmp1[ 3 ] = ((p_tmp2[ 1 ] >> 0x17)
- | (p_tmp2[ 1 ] << 0x9)) + p_tmp2[ 0 ];
- p_tmp2[ 1 ] = ((~p_tmp1[ 1 ] & p_tmp2[ 0 ])
- | (p_tmp1[ 3 ] & p_tmp1[ 1 ]))
- + p_input[ p_table[ i ][ 1 ] ];
- p_tmp2[ 1 ] += p_tmp1[ 2 ] + p_drms_tab_taos[ x++ ];
-
- p_tmp1[ 2 ] = ((p_tmp2[ 1 ] >> 0x12)
- | (p_tmp2[ 1 ] << 0xE)) + p_tmp1[ 3 ];
- p_tmp2[ 1 ] = ((~p_tmp2[ 0 ] & p_tmp1[ 3 ])
- | (p_tmp1[ 2 ] & p_tmp2[ 0 ]))
- + p_input[ p_table[ i ][ 2 ] ];
- p_tmp2[ 1 ] += p_tmp1[ 1 ] + p_drms_tab_taos[ x++ ];
-
- p_tmp1[ 1 ] = ((p_tmp2[ 1 ] << 0x14)
- | (p_tmp2[ 1 ] >> 0xC)) + p_tmp1[ 2 ];
- if( i == 3 )
- {
- p_tmp2[ 1 ] = (p_tmp1[ 3 ] ^ p_tmp1[ 2 ] ^ p_tmp1[ 1 ])
- + p_input[ p_table[ i ][ 3 ] ];
- }
- else
- {
- p_tmp2[ 1 ] = ((~p_tmp1[ 3 ] & p_tmp1[ 2 ])
- | (p_tmp1[ 3 ] & p_tmp1[ 1 ]))
- + p_input[ p_table[ i ][ 3 ] ];
- }
- p_tmp1[ 0 ] = p_tmp2[ 0 ] + p_tmp2[ 1 ] + p_drms_tab_taos[ x++ ];
- }
-
- for( i = 0; i < 4; i++ )
- {
- uint8_t p_table[ 4 ][ 4 ] =
- {
- { 8, 11, 14, 1 },
- { 4, 7, 10, 13 },
- { 0, 3, 6, 9 },
- { 12, 15, 2, 0 }
- };
-
- p_tmp2[ 0 ] = ((p_tmp1[ 0 ] >> 0x1C)
- | (p_tmp1[ 0 ] << 0x4)) + p_tmp1[ 1 ];
- p_tmp2[ 1 ] = (p_tmp1[ 2 ] ^ p_tmp1[ 1 ] ^ p_tmp2[ 0 ])
- + p_input[ p_table[ i ][ 0 ] ];
- p_tmp2[ 1 ] += p_tmp1[ 3 ] + p_drms_tab_taos[ x++ ];
-
- p_tmp1[ 3 ] = ((p_tmp2[ 1 ] >> 0x15)
- | (p_tmp2[ 1 ] << 0xB)) + p_tmp2[ 0 ];
- p_tmp2[ 1 ] = (p_tmp1[ 3 ] ^ p_tmp1[ 1 ] ^ p_tmp2[ 0 ])
- + p_input[ p_table[ i ][ 1 ] ];
- p_tmp2[ 1 ] += p_tmp1[ 2 ] + p_drms_tab_taos[ x++ ];
-
- p_tmp1[ 2 ] = ((p_tmp2[ 1 ] >> 0x10)
- | (p_tmp2[ 1 ] << 0x10)) + p_tmp1[ 3 ];
- p_tmp2[ 1 ] = (p_tmp1[ 3 ] ^ p_tmp1[ 2 ] ^ p_tmp2[ 0 ])
- + p_input[ p_table[ i ][ 2 ] ];
- p_tmp2[ 1 ] += p_tmp1[ 1 ] + p_drms_tab_taos[ x++ ];
-
- p_tmp1[ 1 ] = ((p_tmp2[ 1 ] << 0x17)
- | (p_tmp2[ 1 ] >> 0x9)) + p_tmp1[ 2 ];
- if( i == 3 )
- {
- p_tmp2[ 1 ] = ((~p_tmp1[ 3 ] | p_tmp1[ 1 ]) ^ p_tmp1[ 2 ])
- + p_input[ p_table[ i ][ 3 ] ];
- }
- else
- {
- p_tmp2[ 1 ] = (p_tmp1[ 3 ] ^ p_tmp1[ 2 ] ^ p_tmp1[ 1 ])
- + p_input[ p_table[ i ][ 3 ] ];
- }
- p_tmp1[ 0 ] = p_tmp2[ 0 ] + p_tmp2[ 1 ] + p_drms_tab_taos[ x++ ];
- }
-
- for( i = 0; i < 4; i++ )
- {
- uint8_t p_table[ 4 ][ 4 ] =
- {
- { 7, 14, 5, 12 },
- { 3, 10, 1, 8 },
- { 15, 6, 13, 4 },
- { 11, 2, 9, 0 }
- };
-
- p_tmp2[ 0 ] = ((p_tmp1[ 0 ] >> 0x1A)
- | (p_tmp1[ 0 ] << 0x6)) + p_tmp1[ 1 ];
- p_tmp2[ 1 ] = ((~p_tmp1[ 2 ] | p_tmp2[ 0 ]) ^ p_tmp1[ 1 ])
- + p_input[ p_table[ i ][ 0 ] ];
- p_tmp2[ 1 ] += p_tmp1[ 3 ] + p_drms_tab_taos[ x++ ];
-
- p_tmp1[ 3 ] = ((p_tmp2[ 1 ] >> 0x16)
- | (p_tmp2[ 1 ] << 0xA)) + p_tmp2[ 0 ];
- p_tmp2[ 1 ] = ((~p_tmp1[ 1 ] | p_tmp1[ 3 ]) ^ p_tmp2[ 0 ])
- + p_input[ p_table[ i ][ 1 ] ];
- p_tmp2[ 1 ] += p_tmp1[ 2 ] + p_drms_tab_taos[ x++ ];
-
- p_tmp1[ 2 ] = ((p_tmp2[ 1 ] >> 0x11)
- | (p_tmp2[ 1 ] << 0xF)) + p_tmp1[ 3 ];
- p_tmp2[ 1 ] = ((~p_tmp2[ 0 ] | p_tmp1[ 2 ]) ^ p_tmp1[ 3 ])
- + p_input[ p_table[ i ][ 2 ] ];
- p_tmp2[ 1 ] += p_tmp1[ 1 ] + p_drms_tab_taos[ x++ ];
-
- p_tmp1[ 1 ] = ((p_tmp2[ 1 ] << 0x15)
- | (p_tmp2[ 1 ] >> 0xB)) + p_tmp1[ 2 ];
-
- if( i < 3 )
- {
- p_tmp2[ 1 ] = ((~p_tmp1[ 3 ] | p_tmp1[ 1 ]) ^ p_tmp1[ 2 ])
- + p_input[ p_table[ i ][ 3 ] ];
- p_tmp1[ 0 ] = p_tmp2[ 0 ] + p_tmp2[ 1 ] + p_drms_tab_taos[ x++ ];
- }
- }
-
- p_buffer[ 0 ] += p_tmp2[ 0 ];
- p_buffer[ 1 ] += p_tmp1[ 1 ];
- p_buffer[ 2 ] += p_tmp1[ 2 ];
- p_buffer[ 3 ] += p_tmp1[ 3 ];
-}
-
-static void taos_add1( uint32_t *p_buffer,
- uint8_t *p_in, uint32_t i_len )
-{
- uint32_t i;
- uint32_t x, y;
- uint32_t p_tmp[ 16 ];
- uint32_t i_offset = 0;
-
- x = p_buffer[ 6 ] & 63;
- y = 64 - x;
-
- p_buffer[ 6 ] += i_len;
-
- if( i_len < y )
- {
- memcpy( &((uint8_t *)p_buffer)[ 48 + x ], p_in, i_len );
- }
- else
- {
- if( x )
- {
- memcpy( &((uint8_t *)p_buffer)[ 48 + x ], p_in, y );
- taos( &p_buffer[ 8 ], &p_buffer[ 12 ] );
- i_offset = y;
- i_len -= y;
- }
-
- if( i_len >= 64 )
- {
- for( i = 0; i < i_len / 64; i++ )
- {
- memcpy( p_tmp, &p_in[ i_offset ], sizeof(p_tmp) );
- taos( &p_buffer[ 8 ], p_tmp );
- i_offset += 64;
- i_len -= 64;
- }
- }
-
- if( i_len )
- {
- memcpy( &p_buffer[ 12 ], &p_in[ i_offset ], i_len );
- }
- }
-}
-
-static void taos_end1( uint32_t *p_buffer, uint32_t *p_out )
-{
- uint32_t x, y;
-
- x = p_buffer[ 6 ] & 63;
- y = 63 - x;
-
- ((uint8_t *)p_buffer)[ 48 + x++ ] = 128;
-
- if( y < 8 )
- {
- memset( &((uint8_t *)p_buffer)[ 48 + x ], 0, y );
- taos( &p_buffer[ 8 ], &p_buffer[ 12 ] );
- y = 64;
- x = 0;
- }
-
- memset( &((uint8_t *)p_buffer)[ 48 + x ], 0, y );
-
- p_buffer[ 26 ] = p_buffer[ 6 ] * 8;
- p_buffer[ 27 ] = p_buffer[ 6 ] >> 29;
- taos( &p_buffer[ 8 ], &p_buffer[ 12 ] );
-
- memcpy( p_out, &p_buffer[ 8 ], sizeof(*p_out) * 4 );
-}
-
-static void taos_add2( uint32_t *p_buffer, uint8_t *p_in, uint32_t i_len )
-{
- uint32_t i, x;
- uint32_t p_tmp[ 16 ];
-
- x = (p_buffer[ 0 ] / 8) & 63;
- i = p_buffer[ 0 ] + i_len * 8;
-
- if( i < p_buffer[ 0 ] )
- {
- p_buffer[ 1 ] += 1;
- }
-
- p_buffer[ 0 ] = i;
- p_buffer[ 1 ] += i_len >> 29;
-
- for( i = 0; i < i_len; i++ )
- {
- ((uint8_t *)p_buffer)[ 24 + x++ ] = p_in[ i ];
-
- if( x != 64 )
- continue;
-
- memcpy( p_tmp, &p_buffer[ 6 ], sizeof(p_tmp) );
- taos( &p_buffer[ 2 ], p_tmp );
- }
-}
-
-static void taos_add2e( uint32_t *p_buffer, uint32_t *p_in, uint32_t i_len )
-{
- uint32_t i, x, y;
- uint32_t p_tmp[ 32 ];
-
- if( i_len )
- {
- for( x = i_len; x; x -= y )
- {
- y = x > 32 ? 32 : x;
-
- for( i = 0; i < y; i++ )
- {
- p_tmp[ i ] = U32_AT(&p_in[ i ]);
- }
- }
- }
-
- taos_add2( p_buffer, (uint8_t *)p_tmp, i_len * sizeof(p_tmp[ 0 ]) );
-}
-
-static void taos_end2( uint32_t *p_buffer )
-{
- uint32_t x;
- uint32_t p_tmp[ 16 ];
-
- p_tmp[ 14 ] = p_buffer[ 0 ];
- p_tmp[ 15 ] = p_buffer[ 1 ];
-
- x = (p_buffer[ 0 ] / 8) & 63;
-
- taos_add2( p_buffer, p_drms_tab_tend, 56 - x );
- memcpy( p_tmp, &p_buffer[ 6 ], 56 );
- taos( &p_buffer[ 2 ], p_tmp );
- memcpy( &p_buffer[ 22 ], &p_buffer[ 2 ], sizeof(*p_buffer) * 4 );
-}
-
-static void taos_add3( uint32_t *p_buffer, uint8_t *p_key, uint32_t i_len )
-{
- uint32_t x, y;
- uint32_t i = 0;
-
- x = (p_buffer[ 4 ] / 8) & 63;
- p_buffer[ 4 ] += i_len * 8;
-
- if( p_buffer[ 4 ] < i_len * 8 )
- p_buffer[ 5 ] += 1;
-
- p_buffer[ 5 ] += i_len >> 29;
-
- y = 64 - x;
-
- if( i_len >= y )
- {
- memcpy( &((uint8_t *)p_buffer)[ 24 + x ], p_key, y );
- taos( p_buffer, &p_buffer[ 6 ] );
-
- i = y;
- y += 63;
-
- if( y < i_len )
- {
- for( ; y < i_len; y += 64, i += 64 )
- {
- taos( p_buffer, (uint32_t *)&p_key[y - 63] );
- }
- }
- else
- {
- x = 0;
- }
- }
-
- memcpy( &((uint8_t *)p_buffer)[ 24 + x ], &p_key[ i ], i_len - i );
-}
-
-static int taos_osi( uint32_t *p_buffer )
-{
- int i_ret = 0;
-
-#ifdef _WIN32
- HKEY i_key;
- uint32_t i;
- DWORD i_size;
- DWORD i_serial;
- LPBYTE p_reg_buf;
-
- static LPCTSTR p_reg_keys[ 3 ][ 2 ] =
- {
- {
- _T("HARDWARE\\DESCRIPTION\\System"),
- _T("SystemBiosVersion")
- },
-
- {
- _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
- _T("ProcessorNameString")
- },
-
- {
- _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"),
- _T("ProductId")
- }
- };
-
- taos_add1( p_buffer, "cache-control", 13 );
- taos_add1( p_buffer, "Ethernet", 8 );
-
- GetVolumeInformation( _T("C:\\"), NULL, 0, &i_serial,
- NULL, NULL, NULL, 0 );
- taos_add1( p_buffer, (uint8_t *)&i_serial, 4 );
-
- for( i = 0; i < sizeof(p_reg_keys)/sizeof(p_reg_keys[ 0 ]); i++ )
- {
- if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, p_reg_keys[ i ][ 0 ],
- 0, KEY_READ, &i_key ) == ERROR_SUCCESS )
- {
- if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
- NULL, NULL, NULL,
- &i_size ) == ERROR_SUCCESS )
- {
- p_reg_buf = malloc( i_size );
-
- if( p_reg_buf != NULL )
- {
- if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
- NULL, NULL, p_reg_buf,
- &i_size ) == ERROR_SUCCESS )
- {
- taos_add1( p_buffer, (uint8_t *)p_reg_buf,
- i_size );
- }
-
- free( p_reg_buf );
- }
- }
-
- RegCloseKey( i_key );
- }
- }
-
-#else
- i_ret = -1;
-#endif
-
- return( i_ret );
-}
-
-static int get_sci_data( uint32_t p_sci[ 11 ][ 4 ] )
-{
- int i_ret = -1;
-
-#ifdef _WIN32
- HANDLE i_file;
- DWORD i_size, i_read;
- TCHAR p_path[ MAX_PATH ];
- TCHAR *p_filename = _T("\\Apple Computer\\iTunes\\SC Info\\SC Info.sidb");
-
- typedef HRESULT (WINAPI *SHGETFOLDERPATH)( HWND, int, HANDLE, DWORD,
- LPTSTR );
-
- HINSTANCE shfolder_dll = NULL;
- SHGETFOLDERPATH dSHGetFolderPath = NULL;
-
- if( ( shfolder_dll = LoadLibrary( _T("SHFolder.dll") ) ) != NULL )
- {
- dSHGetFolderPath =
- (SHGETFOLDERPATH)GetProcAddress( shfolder_dll,
-#ifdef _UNICODE
- _T("SHGetFolderPathW") );
-#else
- _T("SHGetFolderPathA") );
-#endif
- }
-
- if( dSHGetFolderPath != NULL &&
- SUCCEEDED( dSHGetFolderPath( NULL, /*CSIDL_COMMON_APPDATA*/ 0x0023,
- NULL, 0, p_path ) ) )
- {
- _tcsncat( p_path, p_filename, min( _tcslen( p_filename ),
- (MAX_PATH-1) - _tcslen( p_path ) ) );
-
- i_file = CreateFile( p_path, GENERIC_READ, 0, NULL,
- OPEN_EXISTING, 0, NULL );
- if( i_file != INVALID_HANDLE_VALUE )
- {
- i_read = sizeof(p_sci[ 0 ]) * 11;
- i_size = GetFileSize( i_file, NULL );
- if( i_size != INVALID_FILE_SIZE && i_size >= i_read )
- {
- i_size = SetFilePointer( i_file, 4, NULL, FILE_BEGIN );
- if( i_size != /*INVALID_SET_FILE_POINTER*/ ((DWORD)-1))
- {
- if( ReadFile( i_file, p_sci, i_read, &i_size, NULL ) &&
- i_size == i_read )
- {
- i_ret = 0;
- }
- }
- }
-
- CloseHandle( i_file );
- }
- }
-#endif
-
- return( i_ret );
-}
-
-static void acei_taxs( uint32_t *p_acei, uint32_t i_val )
-{
- uint32_t i, x;
-
- i = (i_val / 16) & 15;
- x = (~(i_val & 15)) & 15;
-
- if( (i_val & 768) == 768 )
- {
- x = (~i) & 15;
- i = i_val & 15;
-
- p_acei[ 25 + i ] = p_acei[ 25 + ((16 - x) & 15) ]
- + p_acei[ 25 + (15 - x) ];
- }
- else if( (i_val & 512) == 512 )
- {
- p_acei[ 25 + i ] ^= p_drms_tab_xor[ 15 - i ][ x ];
- }
- else if( (i_val & 256) == 256 )
- {
- p_acei[ 25 + i ] -= p_drms_tab_sub[ 15 - i ][ x ];
- }
- else
- {
- p_acei[ 25 + i ] += p_drms_tab_add[ 15 - i ][ x ];
- }
-}
-
-static void acei( uint32_t *p_acei, uint8_t *p_buffer, uint32_t i_len )
-{
- uint32_t i, x;
- uint32_t p_tmp[ 26 ];
-
- for( i = 5; i < 25; i++ )
- {
- if( p_acei[ i ] )
- {
- acei_taxs( p_acei, p_acei[ i ] );
- }
- }
-
- TAOS_INIT( p_tmp, 2 );
- taos_add2e( p_tmp, &p_acei[ 25 ], sizeof(*p_acei) * 4 );
- taos_end2( p_tmp );
-
- x = i_len < 16 ? i_len : 16;
-
- if( x > 0 )
- {
- for( i = 0; i < x; i++ )
- {
- p_buffer[ i ] ^= ((uint8_t *)&p_tmp)[ 88 + i ];
- }
- }
-}
-
-static uint32_t ttov_calc( uint32_t *p_acei )
-{
- int32_t i_val;
- uint32_t p_tmp[ 26 ];
-
- TAOS_INIT( p_tmp, 2 );
- taos_add2e( p_tmp, &p_acei[ 0 ], 4 );
- taos_add2e( p_tmp, &p_acei[ 4 ], 1 );
- taos_end2( p_tmp );
-
- p_acei[ 4 ]++;
-
- i_val = ((int32_t)U32_AT(&p_tmp[ 22 ])) % 1024;
-
- return( i_val < 0 ? i_val * -1 : i_val );
-}
-
-static void acei_init( uint32_t *p_acei, uint32_t *p_sys_key )
-{
- uint32_t i;
-
- for( i = 0; i < 4; i++ )
- {
- p_acei[ i ] = U32_AT(&p_sys_key[ i ]);
- }
-
- p_acei[ 4 ] = 0x5476212A;
-
- for( i = 5; i < 25; i++ )
- {
- p_acei[ i ] = ttov_calc( p_acei );
- }
-
- p_acei[ 25 + 0 ] = p_acei[ 0 ];
- p_acei[ 25 + 1 ] = 0x68723876;
- p_acei[ 25 + 2 ] = 0x41617376;
- p_acei[ 25 + 3 ] = 0x4D4B4F76;
-
- p_acei[ 25 + 4 ] = p_acei[ 1 ];
- p_acei[ 25 + 5 ] = 0x48556646;
- p_acei[ 25 + 6 ] = 0x38393725;
- p_acei[ 25 + 7 ] = 0x2E3B5B3D;
-
- p_acei[ 25 + 8 ] = p_acei[ 2 ];
- p_acei[ 25 + 9 ] = 0x37363866;
- p_acei[ 25 + 10 ] = 0x30383637;
- p_acei[ 25 + 11 ] = 0x34333661;
-
- p_acei[ 25 + 12 ] = p_acei[ 3 ];
- p_acei[ 25 + 13 ] = 0x37386162;
- p_acei[ 25 + 14 ] = 0x494F6E66;
- p_acei[ 25 + 15 ] = 0x2A282966;
-}
-
-static __inline void block_xor( uint32_t *p_in, uint32_t *p_key,
- uint32_t *p_out )
-{
- uint32_t i;
-
- for( i = 0; i < 4; i++ )
- {
- p_out[ i ] = p_key[ i ] ^ p_in[ i ];
- }
-}
-
-int drms_get_sys_key( uint32_t *p_sys_key )
-{
- uint32_t p_tmp[ 128 ];
- uint32_t p_tmp_key[ 4 ];
-
- TAOS_INIT( p_tmp, 8 );
- if( taos_osi( p_tmp ) )
- {
- return( -1 );
- }
- taos_end1( p_tmp, p_tmp_key );
-
- TAOS_INIT( p_tmp, 2 );
- taos_add2( p_tmp, "YuaFlafu", 8 );
- taos_add2( p_tmp, (uint8_t *)p_tmp_key, 6 );
- taos_add2( p_tmp, (uint8_t *)p_tmp_key, 6 );
- taos_add2( p_tmp, (uint8_t *)p_tmp_key, 6 );
- taos_add2( p_tmp, "zPif98ga", 8 );
- taos_end2( p_tmp );
-
- memcpy( p_sys_key, &p_tmp[ 2 ], sizeof(*p_sys_key) * 4 );
-
- return( 0 );
-}
-
-int drms_get_user_key( uint32_t *p_sys_key, uint32_t *p_user_key )
-{
- uint32_t i;
- uint32_t p_tmp[ 4 ];
- uint32_t *p_cur_key;
- uint32_t p_acei[ 41 ];
- uint32_t p_ctx[ 128 ];
- uint32_t p_sci[ 2 ][ 11 ][ 4 ];
-
- uint32_t p_sci_key[ 4 ] =
- {
- 0x6E66556D, 0x6E676F70, 0x67666461, 0x33373866
- };
-
- if( p_sys_key == NULL )
- {
- if( drms_get_sys_key( p_tmp ) )
- {
- return( -1 );
- }
-
- p_sys_key = p_tmp;
- }
-
- if( get_sci_data( p_sci[ 0 ] ) )
- {
- return( -1 );
- }
-
- init_ctx( p_ctx, p_sys_key );
-
- for( i = 0, p_cur_key = p_sci_key;
- i < sizeof(p_sci[ 0 ])/sizeof(p_sci[ 0 ][ 0 ]); i++ )
- {
- ctx_xor( p_ctx, &p_sci[ 0 ][ i ][ 0 ], &p_sci[ 1 ][ i ][ 0 ],
- p_drms_tab3, p_drms_tab4 );
- block_xor( &p_sci[ 1 ][ i ][ 0 ], p_cur_key, &p_sci[ 1 ][ i ][ 0 ] );
-
- p_cur_key = &p_sci[ 0 ][ i ][ 0 ];
- }
-
- acei_init( p_acei, p_sys_key );
-
- for( i = 0; i < sizeof(p_sci[ 1 ])/sizeof(p_sci[ 1 ][ 0 ]); i++ )
- {
- acei( p_acei, (uint8_t *)&p_sci[ 1 ][ i ][ 0 ],
- sizeof(p_sci[ 1 ][ i ]) );
- }
-
- memcpy( p_user_key, &p_sci[ 1 ][ 10 ][ 0 ], sizeof(p_sci[ 1 ][ i ]) );
-
- return( 0 );
-}
-
-struct drms_s
-{
- uint8_t *p_iviv;
- uint32_t i_iviv_len;
- uint8_t *p_name;
- uint32_t i_name_len;
-
- uint32_t *p_tmp;
- uint32_t i_tmp_len;
-
- uint32_t p_key[ 4 ];
- uint32_t p_ctx[ 128 ];
-};
-
-#define P_DRMS ((struct drms_s *)p_drms)
-
-void *drms_alloc()
-{
- struct drms_s *p_drms;
-
- p_drms = malloc( sizeof(struct drms_s) );
-
- if( p_drms != NULL )
- {
- memset( p_drms, 0, sizeof(struct drms_s) );
-
- p_drms->i_tmp_len = 1024;
- p_drms->p_tmp = malloc( p_drms->i_tmp_len );
- if( p_drms->p_tmp == NULL )
- {
- free( (void *)p_drms );
- p_drms = NULL;
- }
- }
-
- return( (void *)p_drms );
-}
-
-void drms_free( void *p_drms )
-{
- if( P_DRMS->p_name != NULL )
- {
- free( (void *)P_DRMS->p_name );
- }
-
- if( P_DRMS->p_iviv != NULL )
- {
- free( (void *)P_DRMS->p_iviv );
- }
-
- if( P_DRMS->p_tmp != NULL )
- {
- free( (void *)P_DRMS->p_tmp );
- }
-
- free( p_drms );
-}
-
-void drms_decrypt( void *p_drms, uint32_t *p_buffer, uint32_t i_len )
-{
- uint32_t i, x, y;
- uint32_t *p_cur_key = P_DRMS->p_key;
-
- x = (i_len / sizeof(P_DRMS->p_key)) * sizeof(P_DRMS->p_key);
-
- if( P_DRMS->i_tmp_len < x )
- {
- free( (void *)P_DRMS->p_tmp );
-
- P_DRMS->i_tmp_len = x;
- P_DRMS->p_tmp = malloc( P_DRMS->i_tmp_len );
- }
-
- if( P_DRMS->p_tmp != NULL )
- {
- memcpy( P_DRMS->p_tmp, p_buffer, x );
-
- for( i = 0, x /= sizeof(P_DRMS->p_key); i < x; i++ )
- {
- y = i * sizeof(*p_buffer);
-
- ctx_xor( P_DRMS->p_ctx, P_DRMS->p_tmp + y, p_buffer + y,
- p_drms_tab3, p_drms_tab4 );
- block_xor( p_buffer + y, p_cur_key, p_buffer + y );
-
- p_cur_key = P_DRMS->p_tmp + y;
- }
- }
-}
-
-int drms_init( void *p_drms, uint32_t i_type,
- uint8_t *p_info, uint32_t i_len )
-{
- int i_ret = 0;
-
- switch( i_type )
- {
- case DRMS_INIT_UKEY:
- {
- if( i_len != sizeof(P_DRMS->p_key) )
- {
- i_ret = -1;
- break;
- }
-
- init_ctx( P_DRMS->p_ctx, (uint32_t *)p_info );
- }
- break;
-
- case DRMS_INIT_IVIV:
- {
- if( i_len != sizeof(P_DRMS->p_key) )
- {
- i_ret = -1;
- break;
- }
-
- P_DRMS->p_iviv = malloc( i_len );
- if( P_DRMS->p_iviv == NULL )
- {
- i_ret = -1;
- break;
- }
-
- memcpy( P_DRMS->p_iviv, p_info, i_len );
- P_DRMS->i_iviv_len = i_len;
- }
- break;
-
- case DRMS_INIT_NAME:
- {
- P_DRMS->p_name = malloc( i_len );
- if( P_DRMS->p_name == NULL )
- {
- i_ret = -1;
- break;
- }
-
- memcpy( P_DRMS->p_name, p_info, i_len );
- P_DRMS->i_name_len = i_len;
- }
- break;
-
- case DRMS_INIT_PRIV:
- {
- uint32_t i;
- uint32_t p_priv[ 64 ];
- uint32_t p_tmp[ 128 ];
-
- if( i_len < 64 )
- {
- i_ret = -1;
- break;
- }
-
- TAOS_INIT( p_tmp, 0 );
- taos_add3( p_tmp, P_DRMS->p_name, P_DRMS->i_name_len );
- taos_add3( p_tmp, P_DRMS->p_iviv, P_DRMS->i_iviv_len );
- memcpy( p_priv, &p_tmp[ 4 ], sizeof(p_priv[ 0 ]) * 2 );
- i = (p_tmp[ 4 ] / 8) & 63;
- i = i >= 56 ? 120 - i : 56 - i;
- taos_add3( p_tmp, p_drms_tab_tend, i );
- taos_add3( p_tmp, (uint8_t *)p_priv, sizeof(p_priv[ 0 ]) * 2 );
-
- memcpy( p_priv, p_info, 64 );
- memcpy( P_DRMS->p_key, p_tmp, sizeof(P_DRMS->p_key) );
- drms_decrypt( p_drms, p_priv, sizeof(p_priv) );
-
- init_ctx( P_DRMS->p_ctx, &p_priv[ 6 ] );
- memcpy( P_DRMS->p_key, &p_priv[ 12 ], sizeof(P_DRMS->p_key) );
-
- free( (void *)P_DRMS->p_name );
- P_DRMS->p_name = NULL;
- free( (void *)P_DRMS->p_iviv );
- P_DRMS->p_iviv = NULL;
- }
- break;
- }
-
- return( i_ret );
-}
-
-#undef P_DRMS
-
-#endif
-
diff --git a/trunk/src/mp4ff/drms.h b/trunk/src/mp4ff/drms.h
deleted file mode 100644
index 42d957400..000000000
--- a/trunk/src/mp4ff/drms.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*****************************************************************************
- * drms.h : DRMS
- *****************************************************************************
- * Copyright (C) 2004 VideoLAN
- * $Id: drms.h,v 1.3 2004/01/11 15:52:18 menno Exp $
- *
- * Author: Jon Lech Johansen <jon-vl@nanocrew.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
-
-
-#define DRMS_INIT_UKEY 0
-#define DRMS_INIT_IVIV 1
-#define DRMS_INIT_NAME 2
-#define DRMS_INIT_PRIV 3
-
-extern int drms_get_sys_key( uint32_t *p_sys_key );
-extern int drms_get_user_key( uint32_t *p_sys_key,
- uint32_t *p_user_key );
-
-extern void *drms_alloc();
-extern void drms_free( void *p_drms );
-extern int drms_init( void *p_drms, uint32_t i_type,
- uint8_t *p_info, uint32_t i_len );
-extern void drms_decrypt( void *p_drms, uint32_t *p_buffer,
- uint32_t i_len );
-
diff --git a/trunk/src/mp4ff/drmstables.h b/trunk/src/mp4ff/drmstables.h
deleted file mode 100644
index e38c1f762..000000000
--- a/trunk/src/mp4ff/drmstables.h
+++ /dev/null
@@ -1,449 +0,0 @@
-/*****************************************************************************
- * drmstables.h : DRMS tables
- *****************************************************************************
- * Copyright (C) 2004 VideoLAN
- * $Id: drmstables.h,v 1.2 2004/01/11 15:52:18 menno Exp $
- *
- * Author: Jon Lech Johansen <jon-vl@nanocrew.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
-
-
-static uint32_t p_drms_tab1[ 10 ] =
-{
- 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020,
- 0x00000040, 0x00000080, 0x0000001B, 0x00000036
-};
-
-static uint32_t p_drms_tab2[ 256 ] =
-{
- 0x63000000, 0x7C000000, 0x77000000, 0x7B000000, 0xF2000000, 0x6B000000,
- 0x6F000000, 0xC5000000, 0x30000000, 0x01000000, 0x67000000, 0x2B000000,
- 0xFE000000, 0xD7000000, 0xAB000000, 0x76000000, 0xCA000000, 0x82000000,
- 0xC9000000, 0x7D000000, 0xFA000000, 0x59000000, 0x47000000, 0xF0000000,
- 0xAD000000, 0xD4000000, 0xA2000000, 0xAF000000, 0x9C000000, 0xA4000000,
- 0x72000000, 0xC0000000, 0xB7000000, 0xFD000000, 0x93000000, 0x26000000,
- 0x36000000, 0x3F000000, 0xF7000000, 0xCC000000, 0x34000000, 0xA5000000,
- 0xE5000000, 0xF1000000, 0x71000000, 0xD8000000, 0x31000000, 0x15000000,
- 0x04000000, 0xC7000000, 0x23000000, 0xC3000000, 0x18000000, 0x96000000,
- 0x05000000, 0x9A000000, 0x07000000, 0x12000000, 0x80000000, 0xE2000000,
- 0xEB000000, 0x27000000, 0xB2000000, 0x75000000, 0x09000000, 0x83000000,
- 0x2C000000, 0x1A000000, 0x1B000000, 0x6E000000, 0x5A000000, 0xA0000000,
- 0x52000000, 0x3B000000, 0xD6000000, 0xB3000000, 0x29000000, 0xE3000000,
- 0x2F000000, 0x84000000, 0x53000000, 0xD1000000, 0x00000000, 0xED000000,
- 0x20000000, 0xFC000000, 0xB1000000, 0x5B000000, 0x6A000000, 0xCB000000,
- 0xBE000000, 0x39000000, 0x4A000000, 0x4C000000, 0x58000000, 0xCF000000,
- 0xD0000000, 0xEF000000, 0xAA000000, 0xFB000000, 0x43000000, 0x4D000000,
- 0x33000000, 0x85000000, 0x45000000, 0xF9000000, 0x02000000, 0x7F000000,
- 0x50000000, 0x3C000000, 0x9F000000, 0xA8000000, 0x51000000, 0xA3000000,
- 0x40000000, 0x8F000000, 0x92000000, 0x9D000000, 0x38000000, 0xF5000000,
- 0xBC000000, 0xB6000000, 0xDA000000, 0x21000000, 0x10000000, 0xFF000000,
- 0xF3000000, 0xD2000000, 0xCD000000, 0x0C000000, 0x13000000, 0xEC000000,
- 0x5F000000, 0x97000000, 0x44000000, 0x17000000, 0xC4000000, 0xA7000000,
- 0x7E000000, 0x3D000000, 0x64000000, 0x5D000000, 0x19000000, 0x73000000,
- 0x60000000, 0x81000000, 0x4F000000, 0xDC000000, 0x22000000, 0x2A000000,
- 0x90000000, 0x88000000, 0x46000000, 0xEE000000, 0xB8000000, 0x14000000,
- 0xDE000000, 0x5E000000, 0x0B000000, 0xDB000000, 0xE0000000, 0x32000000,
- 0x3A000000, 0x0A000000, 0x49000000, 0x06000000, 0x24000000, 0x5C000000,
- 0xC2000000, 0xD3000000, 0xAC000000, 0x62000000, 0x91000000, 0x95000000,
- 0xE4000000, 0x79000000, 0xE7000000, 0xC8000000, 0x37000000, 0x6D000000,
- 0x8D000000, 0xD5000000, 0x4E000000, 0xA9000000, 0x6C000000, 0x56000000,
- 0xF4000000, 0xEA000000, 0x65000000, 0x7A000000, 0xAE000000, 0x08000000,
- 0xBA000000, 0x78000000, 0x25000000, 0x2E000000, 0x1C000000, 0xA6000000,
- 0xB4000000, 0xC6000000, 0xE8000000, 0xDD000000, 0x74000000, 0x1F000000,
- 0x4B000000, 0xBD000000, 0x8B000000, 0x8A000000, 0x70000000, 0x3E000000,
- 0xB5000000, 0x66000000, 0x48000000, 0x03000000, 0xF6000000, 0x0E000000,
- 0x61000000, 0x35000000, 0x57000000, 0xB9000000, 0x86000000, 0xC1000000,
- 0x1D000000, 0x9E000000, 0xE1000000, 0xF8000000, 0x98000000, 0x11000000,
- 0x69000000, 0xD9000000, 0x8E000000, 0x94000000, 0x9B000000, 0x1E000000,
- 0x87000000, 0xE9000000, 0xCE000000, 0x55000000, 0x28000000, 0xDF000000,
- 0x8C000000, 0xA1000000, 0x89000000, 0x0D000000, 0xBF000000, 0xE6000000,
- 0x42000000, 0x68000000, 0x41000000, 0x99000000, 0x2D000000, 0x0F000000,
- 0xB0000000, 0x54000000, 0xBB000000, 0x16000000
-};
-
-static uint32_t p_drms_tab3[ 256 ] =
-{
- 0x5150A7F4, 0x7E536541, 0x1AC3A417, 0x3A965E27, 0x3BCB6BAB, 0x1FF1459D,
- 0xACAB58FA, 0x4B9303E3, 0x2055FA30, 0xADF66D76, 0x889176CC, 0xF5254C02,
- 0x4FFCD7E5, 0xC5D7CB2A, 0x26804435, 0xB58FA362, 0xDE495AB1, 0x25671BBA,
- 0x45980EEA, 0x5DE1C0FE, 0xC302752F, 0x8112F04C, 0x8DA39746, 0x6BC6F9D3,
- 0x03E75F8F, 0x15959C92, 0xBFEB7A6D, 0x95DA5952, 0xD42D83BE, 0x58D32174,
- 0x492969E0, 0x8E44C8C9, 0x756A89C2, 0xF478798E, 0x996B3E58, 0x27DD71B9,
- 0xBEB64FE1, 0xF017AD88, 0xC966AC20, 0x7DB43ACE, 0x63184ADF, 0xE582311A,
- 0x97603351, 0x62457F53, 0xB1E07764, 0xBB84AE6B, 0xFE1CA081, 0xF9942B08,
- 0x70586848, 0x8F19FD45, 0x94876CDE, 0x52B7F87B, 0xAB23D373, 0x72E2024B,
- 0xE3578F1F, 0x662AAB55, 0xB20728EB, 0x2F03C2B5, 0x869A7BC5, 0xD3A50837,
- 0x30F28728, 0x23B2A5BF, 0x02BA6A03, 0xED5C8216, 0x8A2B1CCF, 0xA792B479,
- 0xF3F0F207, 0x4EA1E269, 0x65CDF4DA, 0x06D5BE05, 0xD11F6234, 0xC48AFEA6,
- 0x349D532E, 0xA2A055F3, 0x0532E18A, 0xA475EBF6, 0x0B39EC83, 0x40AAEF60,
- 0x5E069F71, 0xBD51106E, 0x3EF98A21, 0x963D06DD, 0xDDAE053E, 0x4D46BDE6,
- 0x91B58D54, 0x71055DC4, 0x046FD406, 0x60FF1550, 0x1924FB98, 0xD697E9BD,
- 0x89CC4340, 0x67779ED9, 0xB0BD42E8, 0x07888B89, 0xE7385B19, 0x79DBEEC8,
- 0xA1470A7C, 0x7CE90F42, 0xF8C91E84, 0x00000000, 0x09838680, 0x3248ED2B,
- 0x1EAC7011, 0x6C4E725A, 0xFDFBFF0E, 0x0F563885, 0x3D1ED5AE, 0x3627392D,
- 0x0A64D90F, 0x6821A65C, 0x9BD1545B, 0x243A2E36, 0x0CB1670A, 0x930FE757,
- 0xB4D296EE, 0x1B9E919B, 0x804FC5C0, 0x61A220DC, 0x5A694B77, 0x1C161A12,
- 0xE20ABA93, 0xC0E52AA0, 0x3C43E022, 0x121D171B, 0x0E0B0D09, 0xF2ADC78B,
- 0x2DB9A8B6, 0x14C8A91E, 0x578519F1, 0xAF4C0775, 0xEEBBDD99, 0xA3FD607F,
- 0xF79F2601, 0x5CBCF572, 0x44C53B66, 0x5B347EFB, 0x8B762943, 0xCBDCC623,
- 0xB668FCED, 0xB863F1E4, 0xD7CADC31, 0x42108563, 0x13402297, 0x842011C6,
- 0x857D244A, 0xD2F83DBB, 0xAE1132F9, 0xC76DA129, 0x1D4B2F9E, 0xDCF330B2,
- 0x0DEC5286, 0x77D0E3C1, 0x2B6C16B3, 0xA999B970, 0x11FA4894, 0x472264E9,
- 0xA8C48CFC, 0xA01A3FF0, 0x56D82C7D, 0x22EF9033, 0x87C74E49, 0xD9C1D138,
- 0x8CFEA2CA, 0x98360BD4, 0xA6CF81F5, 0xA528DE7A, 0xDA268EB7, 0x3FA4BFAD,
- 0x2CE49D3A, 0x500D9278, 0x6A9BCC5F, 0x5462467E, 0xF6C2138D, 0x90E8B8D8,
- 0x2E5EF739, 0x82F5AFC3, 0x9FBE805D, 0x697C93D0, 0x6FA92DD5, 0xCFB31225,
- 0xC83B99AC, 0x10A77D18, 0xE86E639C, 0xDB7BBB3B, 0xCD097826, 0x6EF41859,
- 0xEC01B79A, 0x83A89A4F, 0xE6656E95, 0xAA7EE6FF, 0x2108CFBC, 0xEFE6E815,
- 0xBAD99BE7, 0x4ACE366F, 0xEAD4099F, 0x29D67CB0, 0x31AFB2A4, 0x2A31233F,
- 0xC63094A5, 0x35C066A2, 0x7437BC4E, 0xFCA6CA82, 0xE0B0D090, 0x3315D8A7,
- 0xF14A9804, 0x41F7DAEC, 0x7F0E50CD, 0x172FF691, 0x768DD64D, 0x434DB0EF,
- 0xCC544DAA, 0xE4DF0496, 0x9EE3B5D1, 0x4C1B886A, 0xC1B81F2C, 0x467F5165,
- 0x9D04EA5E, 0x015D358C, 0xFA737487, 0xFB2E410B, 0xB35A1D67, 0x9252D2DB,
- 0xE9335610, 0x6D1347D6, 0x9A8C61D7, 0x377A0CA1, 0x598E14F8, 0xEB893C13,
- 0xCEEE27A9, 0xB735C961, 0xE1EDE51C, 0x7A3CB147, 0x9C59DFD2, 0x553F73F2,
- 0x1879CE14, 0x73BF37C7, 0x53EACDF7, 0x5F5BAAFD, 0xDF146F3D, 0x7886DB44,
- 0xCA81F3AF, 0xB93EC468, 0x382C3424, 0xC25F40A3, 0x1672C31D, 0xBC0C25E2,
- 0x288B493C, 0xFF41950D, 0x397101A8, 0x08DEB30C, 0xD89CE4B4, 0x6490C156,
- 0x7B6184CB, 0xD570B632, 0x48745C6C, 0xD04257B8
-};
-
-static uint32_t p_drms_tab4[ 256 ] =
-{
- 0x52000000, 0x09000000, 0x6A000000, 0xD5000000, 0x30000000, 0x36000000,
- 0xA5000000, 0x38000000, 0xBF000000, 0x40000000, 0xA3000000, 0x9E000000,
- 0x81000000, 0xF3000000, 0xD7000000, 0xFB000000, 0x7C000000, 0xE3000000,
- 0x39000000, 0x82000000, 0x9B000000, 0x2F000000, 0xFF000000, 0x87000000,
- 0x34000000, 0x8E000000, 0x43000000, 0x44000000, 0xC4000000, 0xDE000000,
- 0xE9000000, 0xCB000000, 0x54000000, 0x7B000000, 0x94000000, 0x32000000,
- 0xA6000000, 0xC2000000, 0x23000000, 0x3D000000, 0xEE000000, 0x4C000000,
- 0x95000000, 0x0B000000, 0x42000000, 0xFA000000, 0xC3000000, 0x4E000000,
- 0x08000000, 0x2E000000, 0xA1000000, 0x66000000, 0x28000000, 0xD9000000,
- 0x24000000, 0xB2000000, 0x76000000, 0x5B000000, 0xA2000000, 0x49000000,
- 0x6D000000, 0x8B000000, 0xD1000000, 0x25000000, 0x72000000, 0xF8000000,
- 0xF6000000, 0x64000000, 0x86000000, 0x68000000, 0x98000000, 0x16000000,
- 0xD4000000, 0xA4000000, 0x5C000000, 0xCC000000, 0x5D000000, 0x65000000,
- 0xB6000000, 0x92000000, 0x6C000000, 0x70000000, 0x48000000, 0x50000000,
- 0xFD000000, 0xED000000, 0xB9000000, 0xDA000000, 0x5E000000, 0x15000000,
- 0x46000000, 0x57000000, 0xA7000000, 0x8D000000, 0x9D000000, 0x84000000,
- 0x90000000, 0xD8000000, 0xAB000000, 0x00000000, 0x8C000000, 0xBC000000,
- 0xD3000000, 0x0A000000, 0xF7000000, 0xE4000000, 0x58000000, 0x05000000,
- 0xB8000000, 0xB3000000, 0x45000000, 0x06000000, 0xD0000000, 0x2C000000,
- 0x1E000000, 0x8F000000, 0xCA000000, 0x3F000000, 0x0F000000, 0x02000000,
- 0xC1000000, 0xAF000000, 0xBD000000, 0x03000000, 0x01000000, 0x13000000,
- 0x8A000000, 0x6B000000, 0x3A000000, 0x91000000, 0x11000000, 0x41000000,
- 0x4F000000, 0x67000000, 0xDC000000, 0xEA000000, 0x97000000, 0xF2000000,
- 0xCF000000, 0xCE000000, 0xF0000000, 0xB4000000, 0xE6000000, 0x73000000,
- 0x96000000, 0xAC000000, 0x74000000, 0x22000000, 0xE7000000, 0xAD000000,
- 0x35000000, 0x85000000, 0xE2000000, 0xF9000000, 0x37000000, 0xE8000000,
- 0x1C000000, 0x75000000, 0xDF000000, 0x6E000000, 0x47000000, 0xF1000000,
- 0x1A000000, 0x71000000, 0x1D000000, 0x29000000, 0xC5000000, 0x89000000,
- 0x6F000000, 0xB7000000, 0x62000000, 0x0E000000, 0xAA000000, 0x18000000,
- 0xBE000000, 0x1B000000, 0xFC000000, 0x56000000, 0x3E000000, 0x4B000000,
- 0xC6000000, 0xD2000000, 0x79000000, 0x20000000, 0x9A000000, 0xDB000000,
- 0xC0000000, 0xFE000000, 0x78000000, 0xCD000000, 0x5A000000, 0xF4000000,
- 0x1F000000, 0xDD000000, 0xA8000000, 0x33000000, 0x88000000, 0x07000000,
- 0xC7000000, 0x31000000, 0xB1000000, 0x12000000, 0x10000000, 0x59000000,
- 0x27000000, 0x80000000, 0xEC000000, 0x5F000000, 0x60000000, 0x51000000,
- 0x7F000000, 0xA9000000, 0x19000000, 0xB5000000, 0x4A000000, 0x0D000000,
- 0x2D000000, 0xE5000000, 0x7A000000, 0x9F000000, 0x93000000, 0xC9000000,
- 0x9C000000, 0xEF000000, 0xA0000000, 0xE0000000, 0x3B000000, 0x4D000000,
- 0xAE000000, 0x2A000000, 0xF5000000, 0xB0000000, 0xC8000000, 0xEB000000,
- 0xBB000000, 0x3C000000, 0x83000000, 0x53000000, 0x99000000, 0x61000000,
- 0x17000000, 0x2B000000, 0x04000000, 0x7E000000, 0xBA000000, 0x77000000,
- 0xD6000000, 0x26000000, 0xE1000000, 0x69000000, 0x14000000, 0x63000000,
- 0x55000000, 0x21000000, 0x0C000000, 0x7D000000
-};
-
-static int32_t p_drms_tab_taos[ 64 ] =
-{
- -0x28955B88, -0x173848AA, +0x242070DB, -0x3E423112, -0x0A83F051,
- +0x4787C62A, -0x57CFB9ED, -0x02B96AFF, +0x698098D8, -0x74BB0851,
- -0x0000A44F, -0x76A32842, +0x6B901122, -0x02678E6D, -0x5986BC72,
- +0x49B40821, -0x09E1DA9E, -0x3FBF4CC0, +0x265E5A51, -0x16493856,
- -0x29D0EFA3, +0x02441453, -0x275E197F, -0x182C0438, +0x21E1CDE6,
- -0x3CC8F82A, -0x0B2AF279, +0x455A14ED, -0x561C16FB, -0x03105C08,
- +0x676F02D9, -0x72D5B376, -0x0005C6BE, -0x788E097F, +0x6D9D6122,
- -0x021AC7F4, -0x5B4115BC, +0x4BDECFA9, -0x0944B4A0, -0x41404390,
- +0x289B7EC6, -0x155ED806, -0x2B10CF7B, +0x04881D05, -0x262B2FC7,
- -0x1924661B, +0x1FA27CF8, -0x3B53A99B, -0x0BD6DDBC, +0x432AFF97,
- -0x546BDC59, -0x036C5FC7, +0x655B59C3, -0x70F3336E, -0x00100B83,
- -0x7A7BA22F, +0x6FA87E4F, -0x01D31920, -0x5CFEBCEC, +0x4E0811A1,
- -0x08AC817E, -0x42C50DCB, +0x2AD7D2BB, -0x14792C6F
-};
-
-static uint8_t p_drms_tab_tend[ 64 ] =
-{
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static uint16_t p_drms_tab_xor[ 16 ][ 16 ] =
-{
- {
- 0x00D1, 0x0315, 0x1A32, 0x19EC, 0x1BBB, 0x1D6F, 0x14FE, 0x0E9E,
- 0x029E, 0x1B8F, 0x0B70, 0x033A, 0x188E, 0x1D18, 0x0BD8, 0x0EDB
- },
-
- {
- 0x0C64, 0x1C2B, 0x149C, 0x047B, 0x1064, 0x1C7C, 0x118D, 0x1355,
- 0x0AE5, 0x0F18, 0x016F, 0x17D6, 0x1595, 0x0084, 0x0616, 0x1CCD
- },
-
- {
- 0x1D94, 0x0618, 0x182C, 0x195B, 0x196D, 0x0394, 0x07DB, 0x0287,
- 0x1636, 0x0B81, 0x1519, 0x0DF9, 0x1BA3, 0x1CC3, 0x0EE2, 0x1434
- },
-
- {
- 0x1457, 0x0CED, 0x0F7D, 0x0D7B, 0x0B9E, 0x0D13, 0x13D7, 0x18D0,
- 0x1259, 0x1977, 0x0606, 0x1E80, 0x05F2, 0x06B8, 0x1F07, 0x1365
- },
-
- {
- 0x0334, 0x0E30, 0x195F, 0x15F1, 0x058E, 0x0AA8, 0x045A, 0x0465,
- 0x0B3E, 0x071E, 0x0A36, 0x105C, 0x01AC, 0x1A1E, 0x04E4, 0x056B
- },
-
- {
- 0x12BF, 0x0DA2, 0x0B41, 0x0EAF, 0x034F, 0x0181, 0x04E2, 0x002B,
- 0x12E6, 0x01BE, 0x10E8, 0x128F, 0x0EB2, 0x1369, 0x05BE, 0x1A59
- },
-
- {
- 0x117E, 0x047C, 0x1E86, 0x056A, 0x0DA7, 0x0D61, 0x03FC, 0x1E6E,
- 0x1D0C, 0x1E6D, 0x14BF, 0x0C50, 0x063A, 0x1B47, 0x17AE, 0x1321
- },
-
- {
- 0x041B, 0x0A24, 0x0D4D, 0x1F2B, 0x1CB6, 0x1BED, 0x1549, 0x03A7,
- 0x0254, 0x006C, 0x0C9E, 0x0F73, 0x006C, 0x0008, 0x11F9, 0x0DD5
- },
-
- {
- 0x0BCF, 0x0AF9, 0x1DFE, 0x0341, 0x0E49, 0x0D38, 0x17CB, 0x1513,
- 0x0E96, 0x00ED, 0x0556, 0x1B28, 0x100C, 0x19D8, 0x14FA, 0x028C
- },
-
- {
- 0x1C60, 0x1232, 0x13D3, 0x0D00, 0x1534, 0x192C, 0x14B5, 0x1CF2,
- 0x0504, 0x0B5B, 0x1ECF, 0x0423, 0x183B, 0x06B0, 0x169E, 0x1066
- },
-
- {
- 0x04CB, 0x08A2, 0x1B4A, 0x1254, 0x198D, 0x1044, 0x0236, 0x1BD8,
- 0x18A1, 0x03FF, 0x1A0D, 0x0277, 0x0C2D, 0x17C9, 0x007C, 0x116E
- },
-
- {
- 0x048A, 0x1EAF, 0x0922, 0x0C45, 0x0766, 0x1E5F, 0x1A28, 0x0120,
- 0x1C15, 0x034C, 0x0508, 0x0E73, 0x0879, 0x0441, 0x09AE, 0x132F
- },
-
- {
- 0x14FE, 0x0413, 0x0A9D, 0x1727, 0x01D7, 0x1A2B, 0x0474, 0x18F0,
- 0x1F3B, 0x14F5, 0x1071, 0x0895, 0x1071, 0x18FF, 0x18E3, 0x0EB9
- },
-
- {
- 0x0BA9, 0x0961, 0x1599, 0x019E, 0x1D12, 0x1BAA, 0x1E94, 0x1921,
- 0x14DC, 0x124E, 0x0A25, 0x03AB, 0x1CC0, 0x1EBB, 0x0B4B, 0x16E5
- },
-
- {
- 0x11EA, 0x0D78, 0x1BB3, 0x1BA7, 0x1510, 0x1B7B, 0x0C64, 0x1995,
- 0x1A58, 0x1651, 0x1964, 0x147A, 0x15F2, 0x11BB, 0x1654, 0x166E
- },
-
- {
- 0x0EA9, 0x1DE1, 0x1443, 0x13C5, 0x00E1, 0x0B2F, 0x0B6F, 0x0A37,
- 0x18AC, 0x08E6, 0x06F0, 0x136E, 0x0853, 0x0B2E, 0x0813, 0x10D6
- }
-};
-
-static uint16_t p_drms_tab_sub[ 16 ][ 16 ] =
-{
- {
- 0x067A, 0x0C7D, 0x0B4F, 0x127D, 0x0BD6, 0x04AC, 0x16E0, 0x1730,
- 0x0587, 0x0AFB, 0x1AC3, 0x0120, 0x14B5, 0x0F67, 0x11DE, 0x0961
- },
-
- {
- 0x1127, 0x1A68, 0x07F0, 0x17D0, 0x1A6F, 0x1F3B, 0x01EF, 0x0919,
- 0x131E, 0x0F90, 0x19E9, 0x18A8, 0x0CB2, 0x1AD0, 0x0C66, 0x0378
- },
-
- {
- 0x03B0, 0x01BE, 0x1866, 0x1159, 0x197C, 0x1105, 0x010B, 0x0353,
- 0x1ABB, 0x09A6, 0x028A, 0x1BAD, 0x1B20, 0x0455, 0x0F57, 0x0588
- },
-
- {
- 0x1491, 0x0A1D, 0x0F04, 0x0650, 0x191E, 0x1E0E, 0x174B, 0x016B,
- 0x051F, 0x0532, 0x00DF, 0x1AEA, 0x0005, 0x0E1B, 0x0FF6, 0x08D8
- },
-
- {
- 0x14B4, 0x086A, 0x0C20, 0x0149, 0x1971, 0x0F26, 0x1852, 0x017D,
- 0x1228, 0x0352, 0x0A44, 0x1330, 0x18DF, 0x1E38, 0x01BC, 0x0BAC
- },
-
- {
- 0x1A48, 0x021F, 0x02F7, 0x0C31, 0x0BC4, 0x1E75, 0x105C, 0x13E3,
- 0x0B20, 0x03A1, 0x1AF3, 0x1A36, 0x0E34, 0x181F, 0x09BD, 0x122B
- },
-
- {
- 0x0EE0, 0x163B, 0x0BE7, 0x103D, 0x1075, 0x1E9D, 0x02AF, 0x0BA2,
- 0x1DAA, 0x0CF1, 0x04B6, 0x0598, 0x06A1, 0x0D33, 0x1CFE, 0x04EE
- },
-
- {
- 0x1BAD, 0x07C8, 0x1A48, 0x05E6, 0x031F, 0x0E0A, 0x0326, 0x1650,
- 0x0526, 0x0B4E, 0x08FC, 0x0E4D, 0x0832, 0x06EA, 0x09BF, 0x0993
- },
-
- {
- 0x09EB, 0x0F31, 0x071B, 0x14D5, 0x11CA, 0x0722, 0x120D, 0x014C,
- 0x1993, 0x0AE4, 0x1CCB, 0x04E9, 0x0AEE, 0x1708, 0x0C3D, 0x12F2
- },
-
- {
- 0x1A19, 0x07C1, 0x05A7, 0x0744, 0x1606, 0x1A9B, 0x042D, 0x1BFC,
- 0x1841, 0x0C3C, 0x0FFE, 0x1AB1, 0x1416, 0x18A9, 0x0320, 0x1EC2
- },
-
- {
- 0x0AE7, 0x11C6, 0x124A, 0x11DF, 0x0F81, 0x06CF, 0x0ED9, 0x0253,
- 0x1D2B, 0x0349, 0x0805, 0x08B3, 0x1052, 0x12CF, 0x0A44, 0x0EA6
- },
-
- {
- 0x03BF, 0x1D90, 0x0EF8, 0x0657, 0x156D, 0x0405, 0x10BE, 0x091F,
- 0x1C82, 0x1725, 0x19EF, 0x0B8C, 0x04D9, 0x02C7, 0x025A, 0x1B89
- },
-
- {
- 0x0F5C, 0x013D, 0x02F7, 0x12E3, 0x0BC5, 0x1B56, 0x0848, 0x0239,
- 0x0FCF, 0x03A4, 0x092D, 0x1354, 0x1D83, 0x01BD, 0x071A, 0x0AF1
- },
-
- {
- 0x0875, 0x0793, 0x1B41, 0x1782, 0x0DEF, 0x1D20, 0x13BE, 0x0095,
- 0x1650, 0x19D4, 0x0DE3, 0x0980, 0x18F2, 0x0CA3, 0x0098, 0x149A
- },
-
- {
- 0x0B81, 0x0AD2, 0x1BBA, 0x1A02, 0x027B, 0x1906, 0x07F5, 0x1CAE,
- 0x0C3F, 0x02F6, 0x1298, 0x175E, 0x15B2, 0x13D8, 0x14CC, 0x161A
- },
-
- {
- 0x0A42, 0x15F3, 0x0870, 0x1C1D, 0x1203, 0x18B1, 0x1738, 0x1954,
- 0x1143, 0x1AE8, 0x1D9D, 0x155B, 0x11E8, 0x0ED9, 0x06F7, 0x04CA
- }
-};
-
-static uint16_t p_drms_tab_add[ 16 ][ 16 ] =
-{
- {
- 0x0706, 0x175A, 0x0DEF, 0x1E72, 0x0297, 0x1B0E, 0x1D5A, 0x15B8,
- 0x13E2, 0x1347, 0x10C6, 0x0B4F, 0x0629, 0x0A75, 0x0A9B, 0x0F55
- },
-
- {
- 0x1A69, 0x09BF, 0x0BA6, 0x1582, 0x1086, 0x1921, 0x01CB, 0x1C6A,
- 0x0FF5, 0x00F7, 0x0A67, 0x0A1E, 0x1838, 0x0196, 0x10D6, 0x0C7A
- },
-
- {
- 0x180E, 0x038D, 0x1ADD, 0x0684, 0x154A, 0x0AB0, 0x18A4, 0x0D73,
- 0x1641, 0x0EC6, 0x09F1, 0x1A62, 0x0414, 0x162A, 0x194E, 0x1EC9
- },
-
- {
- 0x022F, 0x0296, 0x1104, 0x14FC, 0x096C, 0x1D02, 0x09BD, 0x027C,
- 0x080E, 0x1324, 0x128C, 0x0DC1, 0x00B9, 0x17F2, 0x0CBC, 0x0F97
- },
-
- {
- 0x1B93, 0x1C3C, 0x0415, 0x0395, 0x0C7A, 0x06CC, 0x0D4B, 0x16E2,
- 0x04A2, 0x0DAB, 0x1228, 0x012B, 0x0896, 0x0012, 0x1CD6, 0x1DAC
- },
-
- {
- 0x080D, 0x0446, 0x047A, 0x00AD, 0x029E, 0x0686, 0x17C3, 0x1466,
- 0x0D16, 0x1896, 0x076E, 0x00CD, 0x17DC, 0x1E9F, 0x1A7C, 0x02BB
- },
-
- {
- 0x0D06, 0x112B, 0x14CB, 0x0A03, 0x1541, 0x1290, 0x0F6D, 0x1503,
- 0x084B, 0x0382, 0x1A3F, 0x0371, 0x1977, 0x0B67, 0x0CAD, 0x1DF8
- },
-
- {
- 0x1CE3, 0x1306, 0x13F8, 0x1163, 0x1B0B, 0x00BD, 0x0BF0, 0x1A4F,
- 0x16F7, 0x0B4F, 0x0CF8, 0x1254, 0x0541, 0x100D, 0x0296, 0x0410
- },
-
- {
- 0x1A2B, 0x1169, 0x17D9, 0x0819, 0x03D6, 0x0D03, 0x194D, 0x184A,
- 0x07CA, 0x1989, 0x0FAD, 0x011C, 0x1C71, 0x0EF6, 0x0DC8, 0x0F2F
- },
-
- {
- 0x0FA5, 0x11BE, 0x0F3B, 0x1D52, 0x0DE2, 0x016E, 0x1AD1, 0x0C4A,
- 0x1BC2, 0x0AC9, 0x1485, 0x1BEE, 0x0949, 0x1A79, 0x1894, 0x12BB
- },
-
- {
- 0x17B6, 0x14F5, 0x16B1, 0x142C, 0x1301, 0x03EF, 0x16FF, 0x0D37,
- 0x0D78, 0x01FF, 0x00D6, 0x1053, 0x1A2A, 0x0F61, 0x1352, 0x0C7F
- },
-
- {
- 0x137F, 0x09C4, 0x1D96, 0x021D, 0x1037, 0x1B19, 0x10EF, 0x14E4,
- 0x02A0, 0x0236, 0x0A5D, 0x1519, 0x141C, 0x1399, 0x007E, 0x1E74
- },
-
- {
- 0x0941, 0x1B3C, 0x0062, 0x0371, 0x09AD, 0x08E8, 0x0A24, 0x0B97,
- 0x1ED2, 0x0889, 0x136B, 0x0006, 0x1C4C, 0x0444, 0x06F8, 0x0DFB
- },
-
- {
- 0x1D0F, 0x198D, 0x0700, 0x0AFC, 0x1781, 0x12F3, 0x10DA, 0x1F19,
- 0x1055, 0x0DC9, 0x1860, 0x012B, 0x05BF, 0x082D, 0x0C17, 0x1941
- },
-
- {
- 0x0359, 0x1232, 0x104C, 0x0762, 0x0897, 0x1D6C, 0x030F, 0x1A36,
- 0x16B0, 0x094D, 0x1782, 0x036F, 0x0EEA, 0x06E6, 0x0D00, 0x0187
- },
-
- {
- 0x17E2, 0x05E5, 0x19FA, 0x1950, 0x146A, 0x0B2A, 0x0512, 0x0EE0,
- 0x1E27, 0x112D, 0x1DF0, 0x0B13, 0x0378, 0x1DD0, 0x00C1, 0x01E6
- }
-};
-
diff --git a/trunk/src/mp4ff/mp4atom.c b/trunk/src/mp4ff/mp4atom.c
deleted file mode 100644
index b75a3da7f..000000000
--- a/trunk/src/mp4ff/mp4atom.c
+++ /dev/null
@@ -1,781 +0,0 @@
-/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-**
-** Any non-GPL usage of this software or parts of this software is strictly
-** forbidden.
-**
-** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
-**
-** $Id: mp4atom.c,v 1.17 2004/01/11 15:52:18 menno Exp $
-**/
-
-#include <stdlib.h>
-#include "mp4ffint.h"
-
-#include "drms.h"
-
-/* parse atom header size */
-static int32_t mp4ff_atom_get_size(const int8_t *data)
-{
- uint32_t result;
- uint32_t a, b, c, d;
-
- a = (uint8_t)data[0];
- b = (uint8_t)data[1];
- c = (uint8_t)data[2];
- d = (uint8_t)data[3];
-
- result = (a<<24) | (b<<16) | (c<<8) | d;
- //if (result > 0 && result < 8) result = 8;
-
- return (int32_t)result;
-}
-
-/* comnapre 2 atom names, returns 1 for equal, 0 for unequal */
-static int32_t mp4ff_atom_compare(const int8_t a1, const int8_t b1, const int8_t c1, const int8_t d1,
- const int8_t a2, const int8_t b2, const int8_t c2, const int8_t d2)
-{
- if (a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2)
- return 1;
- else
- return 0;
-}
-
-static uint8_t mp4ff_atom_name_to_type(const int8_t a, const int8_t b,
- const int8_t c, const int8_t d)
-{
- if (a == 'm')
- {
- if (mp4ff_atom_compare(a,b,c,d, 'm','o','o','v'))
- return ATOM_MOOV;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','i','n','f'))
- return ATOM_MINF;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','d','i','a'))
- return ATOM_MDIA;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','d','a','t'))
- return ATOM_MDAT;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','d','h','d'))
- return ATOM_MDHD;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','v','h','d'))
- return ATOM_MVHD;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','a'))
- return ATOM_MP4A;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','v'))
- return ATOM_MP4V;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','s'))
- return ATOM_MP4S;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','e','t','a'))
- return ATOM_META;
- } else if (a == 't') {
- if (mp4ff_atom_compare(a,b,c,d, 't','r','a','k'))
- return ATOM_TRAK;
- else if (mp4ff_atom_compare(a,b,c,d, 't','k','h','d'))
- return ATOM_TKHD;
- else if (mp4ff_atom_compare(a,b,c,d, 't','r','e','f'))
- return ATOM_TREF;
- else if (mp4ff_atom_compare(a,b,c,d, 't','r','k','n'))
- return ATOM_TRACK;
- else if (mp4ff_atom_compare(a,b,c,d, 't','m','p','o'))
- return ATOM_TEMPO;
- } else if (a == 's') {
- if (mp4ff_atom_compare(a,b,c,d, 's','t','b','l'))
- return ATOM_STBL;
- else if (mp4ff_atom_compare(a,b,c,d, 's','m','h','d'))
- return ATOM_SMHD;
- else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','d'))
- return ATOM_STSD;
- else if (mp4ff_atom_compare(a,b,c,d, 's','t','t','s'))
- return ATOM_STTS;
- else if (mp4ff_atom_compare(a,b,c,d, 's','t','c','o'))
- return ATOM_STCO;
- else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','c'))
- return ATOM_STSC;
- else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','z'))
- return ATOM_STSZ;
- else if (mp4ff_atom_compare(a,b,c,d, 's','t','z','2'))
- return ATOM_STZ2;
- else if (mp4ff_atom_compare(a,b,c,d, 's','k','i','p'))
- return ATOM_SKIP;
- else if (mp4ff_atom_compare(a,b,c,d, 's','i','n','f'))
- return ATOM_SINF;
- else if (mp4ff_atom_compare(a,b,c,d, 's','c','h','i'))
- return ATOM_SCHI;
- } else if (a == '©') {
- if (mp4ff_atom_compare(a,b,c,d, '©','n','a','m'))
- return ATOM_TITLE;
- else if (mp4ff_atom_compare(a,b,c,d, '©','A','R','T'))
- return ATOM_ARTIST;
- else if (mp4ff_atom_compare(a,b,c,d, '©','w','r','t'))
- return ATOM_WRITER;
- else if (mp4ff_atom_compare(a,b,c,d, '©','a','l','b'))
- return ATOM_ALBUM;
- else if (mp4ff_atom_compare(a,b,c,d, '©','d','a','y'))
- return ATOM_DATE;
- else if (mp4ff_atom_compare(a,b,c,d, '©','t','o','o'))
- return ATOM_TOOL;
- else if (mp4ff_atom_compare(a,b,c,d, '©','c','m','t'))
- return ATOM_COMMENT;
- else if (mp4ff_atom_compare(a,b,c,d, '©','g','e','n'))
- return ATOM_GENRE1;
- }
-
- if (mp4ff_atom_compare(a,b,c,d, 'e','d','t','s'))
- return ATOM_EDTS;
- else if (mp4ff_atom_compare(a,b,c,d, 'e','s','d','s'))
- return ATOM_ESDS;
- else if (mp4ff_atom_compare(a,b,c,d, 'f','t','y','p'))
- return ATOM_FTYP;
- else if (mp4ff_atom_compare(a,b,c,d, 'f','r','e','e'))
- return ATOM_FREE;
- else if (mp4ff_atom_compare(a,b,c,d, 'h','m','h','d'))
- return ATOM_HMHD;
- else if (mp4ff_atom_compare(a,b,c,d, 'v','m','h','d'))
- return ATOM_VMHD;
- else if (mp4ff_atom_compare(a,b,c,d, 'u','d','t','a'))
- return ATOM_UDTA;
- else if (mp4ff_atom_compare(a,b,c,d, 'i','l','s','t'))
- return ATOM_ILST;
- else if (mp4ff_atom_compare(a,b,c,d, 'n','a','m','e'))
- return ATOM_NAME;
- else if (mp4ff_atom_compare(a,b,c,d, 'd','a','t','a'))
- return ATOM_DATA;
- else if (mp4ff_atom_compare(a,b,c,d, 'd','i','s','k'))
- return ATOM_DISC;
- else if (mp4ff_atom_compare(a,b,c,d, 'g','n','r','e'))
- return ATOM_GENRE2;
- else if (mp4ff_atom_compare(a,b,c,d, 'c','o','v','r'))
- return ATOM_COVER;
- else if (mp4ff_atom_compare(a,b,c,d, 'c','p','i','l'))
- return ATOM_COMPILATION;
- else if (mp4ff_atom_compare(a,b,c,d, 'c','t','t','s'))
- return ATOM_CTTS;
- else if (mp4ff_atom_compare(a,b,c,d, 'd','r','m','s'))
- return ATOM_DRMS;
- else if (mp4ff_atom_compare(a,b,c,d, 'f','r','m','a'))
- return ATOM_FRMA;
- else if (mp4ff_atom_compare(a,b,c,d, 'p','r','i','v'))
- return ATOM_PRIV;
- else if (mp4ff_atom_compare(a,b,c,d, 'i','v','i','v'))
- return ATOM_IVIV;
- else
- return ATOM_UNKNOWN;
-}
-
-/* read atom header, return atom size, atom size is with header included */
-uint64_t mp4ff_atom_read_header(mp4ff_t *f, uint8_t *atom_type, uint8_t *header_size)
-{
- uint64_t size;
- int32_t ret;
- int8_t atom_header[8];
-
- ret = mp4ff_read_data(f, atom_header, 8);
- if (ret != 8)
- return 0;
-
- size = mp4ff_atom_get_size(atom_header);
- *header_size = 8;
-
- /* check for 64 bit atom size */
- if (size == 1)
- {
- *header_size = 16;
- size = mp4ff_read_int64(f);
- }
-
- //printf("%c%c%c%c\n", atom_header[4], atom_header[5], atom_header[6], atom_header[7]);
-
- *atom_type = mp4ff_atom_name_to_type(atom_header[4], atom_header[5], atom_header[6], atom_header[7]);
-
- return size;
-}
-
-static int32_t mp4ff_read_stsz(mp4ff_t *f)
-{
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
- f->track[f->total_tracks - 1]->stsz_sample_size = mp4ff_read_int32(f);
- f->track[f->total_tracks - 1]->stsz_sample_count = mp4ff_read_int32(f);
-
- if (f->track[f->total_tracks - 1]->stsz_sample_size == 0)
- {
- int32_t i;
- f->track[f->total_tracks - 1]->stsz_table =
- (int32_t*)malloc(f->track[f->total_tracks - 1]->stsz_sample_count*sizeof(int32_t));
-
- for (i = 0; i < f->track[f->total_tracks - 1]->stsz_sample_count; i++)
- {
- f->track[f->total_tracks - 1]->stsz_table[i] = mp4ff_read_int32(f);
- }
- }
-
- return 0;
-}
-
-static int32_t mp4ff_read_esds(mp4ff_t *f)
-{
- uint8_t tag;
- uint32_t temp;
-
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
-
- /* get and verify ES_DescrTag */
- tag = mp4ff_read_char(f);
- if (tag == 0x03)
- {
- /* read length */
- if (mp4ff_read_mp4_descr_length(f) < 5 + 15)
- {
- return 1;
- }
- /* skip 3 bytes */
- mp4ff_read_int24(f);
- } else {
- /* skip 2 bytes */
- mp4ff_read_int16(f);
- }
-
- /* get and verify DecoderConfigDescrTab */
- if (mp4ff_read_char(f) != 0x04)
- {
- return 1;
- }
-
- /* read length */
- temp = mp4ff_read_mp4_descr_length(f);
- if (temp < 13) return 1;
-
- f->track[f->total_tracks - 1]->audioType = mp4ff_read_char(f);
- mp4ff_read_int32(f);//0x15000414 ????
- f->track[f->total_tracks - 1]->maxBitrate = mp4ff_read_int32(f);
- f->track[f->total_tracks - 1]->avgBitrate = mp4ff_read_int32(f);
-
- /* get and verify DecSpecificInfoTag */
- if (mp4ff_read_char(f) != 0x05)
- {
- return 1;
- }
-
- /* read length */
- f->track[f->total_tracks - 1]->decoderConfigLen = mp4ff_read_mp4_descr_length(f);
-
- if (f->track[f->total_tracks - 1]->decoderConfig)
- free(f->track[f->total_tracks - 1]->decoderConfig);
- f->track[f->total_tracks - 1]->decoderConfig = malloc(f->track[f->total_tracks - 1]->decoderConfigLen);
- if (f->track[f->total_tracks - 1]->decoderConfig)
- {
- mp4ff_read_data(f, f->track[f->total_tracks - 1]->decoderConfig, f->track[f->total_tracks - 1]->decoderConfigLen);
- } else {
- f->track[f->total_tracks - 1]->decoderConfigLen = 0;
- }
-
- /* will skip the remainder of the atom */
- return 0;
-}
-
-static int32_t mp4ff_read_mp4a(mp4ff_t *f)
-{
- uint64_t size;
- int32_t i;
- uint8_t atom_type = 0;
- uint8_t header_size = 0;
-
- for (i = 0; i < 6; i++)
- {
- mp4ff_read_char(f); /* reserved */
- }
- /* data_reference_index */ mp4ff_read_int16(f);
-
- mp4ff_read_int32(f); /* reserved */
- mp4ff_read_int32(f); /* reserved */
-
- f->track[f->total_tracks - 1]->channelCount = mp4ff_read_int16(f);
- f->track[f->total_tracks - 1]->sampleSize = mp4ff_read_int16(f);
-
- mp4ff_read_int16(f);
- mp4ff_read_int16(f);
-
- f->track[f->total_tracks - 1]->sampleRate = mp4ff_read_int16(f);
-
- mp4ff_read_int16(f);
-
- size = mp4ff_atom_read_header(f, &atom_type, &header_size);
- if (atom_type == ATOM_ESDS)
- {
- mp4ff_read_esds(f);
- }
-
- return 0;
-}
-
-#ifdef ITUNES_DRM
-static int32_t mp4ff_read_drms(mp4ff_t *f, uint64_t skip)
-{
- uint64_t size;
- int32_t i;
- uint8_t atom_type = 0;
- uint8_t header_size = 0;
- uint32_t drms_user_key[4];
-
- if (drms_get_user_key(NULL, drms_user_key) == 0)
- {
- f->track[f->total_tracks - 1]->p_drms = drms_alloc();
-
- drms_init( f->track[f->total_tracks - 1]->p_drms,
- DRMS_INIT_UKEY, (uint8_t *)drms_user_key,
- sizeof(drms_user_key) );
- }
-
- for (i = 0; i < 6; i++)
- {
- mp4ff_read_char(f); /* reserved */
- }
- /* data_reference_index */ mp4ff_read_int16(f);
-
- mp4ff_read_int32(f); /* reserved */
- mp4ff_read_int32(f); /* reserved */
-
- f->track[f->total_tracks - 1]->channelCount = mp4ff_read_int16(f);
- f->track[f->total_tracks - 1]->sampleSize = mp4ff_read_int16(f);
-
- mp4ff_read_int16(f);
- mp4ff_read_int16(f);
-
- f->track[f->total_tracks - 1]->sampleRate = mp4ff_read_int16(f);
-
- mp4ff_read_int16(f);
-
- size = mp4ff_atom_read_header(f, &atom_type, &header_size);
- if (atom_type == ATOM_ESDS)
- {
- mp4ff_read_esds(f);
- }
- mp4ff_set_position(f, skip+size+28);
-
- size = mp4ff_atom_read_header(f, &atom_type, &header_size);
- if (atom_type == ATOM_SINF)
- {
- parse_sub_atoms(f, size-header_size);
- }
-
- return 0;
-}
-
-static int32_t mp4ff_read_frma(mp4ff_t *f)
-{
- uint8_t atom_type;
- int8_t type[4];
-
- mp4ff_read_data(f, type, 4);
-
- atom_type = mp4ff_atom_name_to_type(type[0], type[1], type[2], type[3]);
-
- if (atom_type == ATOM_MP4A)
- {
- f->track[f->total_tracks - 1]->type = TRACK_AUDIO;
- } else if (atom_type == ATOM_MP4V) {
- f->track[f->total_tracks - 1]->type = TRACK_VIDEO;
- } else if (atom_type == ATOM_MP4S) {
- f->track[f->total_tracks - 1]->type = TRACK_SYSTEM;
- } else {
- f->track[f->total_tracks - 1]->type = TRACK_UNKNOWN;
- }
-
- return 0;
-}
-
-static int32_t mp4ff_read_name(mp4ff_t *f, uint64_t size)
-{
- uint8_t *data = malloc(size);
- mp4ff_read_data(f, data, size);
-
- if (f->track[f->total_tracks - 1]->p_drms != NULL)
- {
- drms_init(f->track[f->total_tracks - 1]->p_drms,
- DRMS_INIT_NAME, data, strlen(data) );
- }
-
- if (data)
- free(data);
-
- return 0;
-}
-
-static int32_t mp4ff_read_priv(mp4ff_t *f, uint64_t size)
-{
- uint8_t *data = malloc(size);
- mp4ff_read_data(f, data, size);
-
- if (f->track[f->total_tracks - 1]->p_drms != 0)
- {
- drms_init(f->track[f->total_tracks - 1]->p_drms,
- DRMS_INIT_PRIV, data, size );
- }
-
- if (data)
- free(data);
-
- return 0;
-}
-
-static int32_t mp4ff_read_iviv(mp4ff_t *f, uint64_t size)
-{
- uint8_t *data = malloc(size);
- mp4ff_read_data(f, data, size);
-
- if (f->track[f->total_tracks - 1]->p_drms != 0)
- {
- drms_init(f->track[f->total_tracks - 1]->p_drms,
- DRMS_INIT_IVIV, data, sizeof(uint32_t) * 4 );
- }
-
- if (data)
- free(data);
-
- return 0;
-}
-#endif
-
-static int32_t mp4ff_read_stsd(mp4ff_t *f)
-{
- int32_t i;
- uint8_t header_size = 0;
-
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
-
- f->track[f->total_tracks - 1]->stsd_entry_count = mp4ff_read_int32(f);
-
- for (i = 0; i < f->track[f->total_tracks - 1]->stsd_entry_count; i++)
- {
- uint64_t skip = mp4ff_position(f);
- uint64_t size;
- uint8_t atom_type = 0;
- size = mp4ff_atom_read_header(f, &atom_type, &header_size);
- skip += size;
-
- if (atom_type == ATOM_MP4A)
- {
- f->track[f->total_tracks - 1]->type = TRACK_AUDIO;
- mp4ff_read_mp4a(f);
- } else if (atom_type == ATOM_MP4V) {
- f->track[f->total_tracks - 1]->type = TRACK_VIDEO;
- } else if (atom_type == ATOM_MP4S) {
- f->track[f->total_tracks - 1]->type = TRACK_SYSTEM;
-#ifdef ITUNES_DRM
- } else if (atom_type == ATOM_DRMS) {
- // track type is read from the "frma" atom
- f->track[f->total_tracks - 1]->type = TRACK_UNKNOWN;
- mp4ff_read_drms(f, skip-size+header_size);
-#endif
- } else {
- f->track[f->total_tracks - 1]->type = TRACK_UNKNOWN;
- }
-
- mp4ff_set_position(f, skip);
- }
-
- return 0;
-}
-
-static int32_t mp4ff_read_stsc(mp4ff_t *f)
-{
- int32_t i;
-
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
- f->track[f->total_tracks - 1]->stsc_entry_count = mp4ff_read_int32(f);
-
- f->track[f->total_tracks - 1]->stsc_first_chunk =
- (int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t));
- f->track[f->total_tracks - 1]->stsc_samples_per_chunk =
- (int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t));
- f->track[f->total_tracks - 1]->stsc_sample_desc_index =
- (int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t));
-
- for (i = 0; i < f->track[f->total_tracks - 1]->stsc_entry_count; i++)
- {
- f->track[f->total_tracks - 1]->stsc_first_chunk[i] = mp4ff_read_int32(f);
- f->track[f->total_tracks - 1]->stsc_samples_per_chunk[i] = mp4ff_read_int32(f);
- f->track[f->total_tracks - 1]->stsc_sample_desc_index[i] = mp4ff_read_int32(f);
- }
-
- return 0;
-}
-
-static int32_t mp4ff_read_stco(mp4ff_t *f)
-{
- int32_t i;
-
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
- f->track[f->total_tracks - 1]->stco_entry_count = mp4ff_read_int32(f);
-
- f->track[f->total_tracks - 1]->stco_chunk_offset =
- (int32_t*)malloc(f->track[f->total_tracks - 1]->stco_entry_count*sizeof(int32_t));
-
- for (i = 0; i < f->track[f->total_tracks - 1]->stco_entry_count; i++)
- {
- f->track[f->total_tracks - 1]->stco_chunk_offset[i] = mp4ff_read_int32(f);
- }
-
- return 0;
-}
-
-static int32_t mp4ff_read_ctts(mp4ff_t *f)
-{
- int32_t i;
- mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
-
- if (p_track->ctts_entry_count) return 0;
-
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
- p_track->ctts_entry_count = mp4ff_read_int32(f);
-
- p_track->ctts_sample_count = (int32_t*)malloc(p_track->ctts_entry_count * sizeof(int32_t));
- p_track->ctts_sample_offset = (int32_t*)malloc(p_track->ctts_entry_count * sizeof(int32_t));
-
- if (p_track->ctts_sample_count == 0 || p_track->ctts_sample_offset == 0)
- {
- if (p_track->ctts_sample_count) {free(p_track->ctts_sample_count);p_track->ctts_sample_count=0;}
- if (p_track->ctts_sample_offset) {free(p_track->ctts_sample_offset);p_track->ctts_sample_offset=0;}
- p_track->ctts_entry_count = 0;
- return 0;
- }
- else
- {
- for (i = 0; i < f->track[f->total_tracks - 1]->ctts_entry_count; i++)
- {
- p_track->ctts_sample_count[i] = mp4ff_read_int32(f);
- p_track->ctts_sample_offset[i] = mp4ff_read_int32(f);
- }
- return 1;
- }
-}
-
-static int32_t mp4ff_read_stts(mp4ff_t *f)
-{
- int32_t i;
- mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
-
- if (p_track->stts_entry_count) return 0;
-
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
- p_track->stts_entry_count = mp4ff_read_int32(f);
-
- p_track->stts_sample_count = (int32_t*)malloc(p_track->stts_entry_count * sizeof(int32_t));
- p_track->stts_sample_delta = (int32_t*)malloc(p_track->stts_entry_count * sizeof(int32_t));
-
- if (p_track->stts_sample_count == 0 || p_track->stts_sample_delta == 0)
- {
- if (p_track->stts_sample_count) {free(p_track->stts_sample_count);p_track->stts_sample_count=0;}
- if (p_track->stts_sample_delta) {free(p_track->stts_sample_delta);p_track->stts_sample_delta=0;}
- p_track->stts_entry_count = 0;
- return 0;
- }
- else
- {
- for (i = 0; i < f->track[f->total_tracks - 1]->stts_entry_count; i++)
- {
- p_track->stts_sample_count[i] = mp4ff_read_int32(f);
- p_track->stts_sample_delta[i] = mp4ff_read_int32(f);
- }
- return 1;
- }
-}
-
-static int32_t mp4ff_read_mvhd(mp4ff_t *f)
-{
- int32_t i;
-
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
- /* creation_time */ mp4ff_read_int32(f);
- /* modification_time */ mp4ff_read_int32(f);
- f->time_scale = mp4ff_read_int32(f);
- f->duration = mp4ff_read_int32(f);
- /* preferred_rate */ mp4ff_read_int32(f); /*mp4ff_read_fixed32(f);*/
- /* preferred_volume */ mp4ff_read_int16(f); /*mp4ff_read_fixed16(f);*/
- for (i = 0; i < 10; i++)
- {
- /* reserved */ mp4ff_read_char(f);
- }
- for (i = 0; i < 9; i++)
- {
- mp4ff_read_int32(f); /* matrix */
- }
- /* preview_time */ mp4ff_read_int32(f);
- /* preview_duration */ mp4ff_read_int32(f);
- /* poster_time */ mp4ff_read_int32(f);
- /* selection_time */ mp4ff_read_int32(f);
- /* selection_duration */ mp4ff_read_int32(f);
- /* current_time */ mp4ff_read_int32(f);
- /* next_track_id */ mp4ff_read_int32(f);
-
- return 0;
-}
-
-#if 0
-static int32_t mp4ff_read_tkhd(mp4ff_t *f)
-{
- uint8_t version;
- uint32_t flags;
- version = mp4ff_read_char(f); /* version */
- flags = mp4ff_read_int24(f); /* flags */
- if (version==1)
- {
- mp4ff_read_int64(f);//creation-time
- mp4ff_read_int64(f);//modification-time
- mp4ff_read_int32(f);//track-id
- mp4ff_read_int32(f);//reserved
- f->track[f->total_tracks - 1]->duration = mp4ff_read_int64(f);//duration
- }
- else //version == 0
- {
- mp4ff_read_int32(f);//creation-time
- mp4ff_read_int32(f);//modification-time
- mp4ff_read_int32(f);//track-id
- mp4ff_read_int32(f);//reserved
- f->track[f->total_tracks - 1]->duration = mp4ff_read_int32(f);//duration
- if (f->track[f->total_tracks - 1]->duration == 0xFFFFFFFF)
- f->track[f->total_tracks - 1]->duration = 0xFFFFFFFFFFFFFFFF;
-
- }
- mp4ff_read_int32(f);//reserved
- mp4ff_read_int32(f);//reserved
- mp4ff_read_int16(f);//layer
- mp4ff_read_int16(f);//pre-defined
- mp4ff_read_int16(f);//volume
- mp4ff_read_int16(f);//reserved
-
- //matrix
- mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
- mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
- mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
- mp4ff_read_int32(f);//width
- mp4ff_read_int32(f);//height
- return 1;
-}
-#endif
-
-static int32_t mp4ff_read_mdhd(mp4ff_t *f)
-{
- uint32_t version;
-
- version = mp4ff_read_int32(f);
- if (version==1)
- {
- mp4ff_read_int64(f);//creation-time
- mp4ff_read_int64(f);//modification-time
- f->track[f->total_tracks - 1]->timeScale = mp4ff_read_int32(f);//timescale
- f->track[f->total_tracks - 1]->duration = mp4ff_read_int64(f);//duration
- }
- else //version == 0
- {
- uint32_t temp;
-
- mp4ff_read_int32(f);//creation-time
- mp4ff_read_int32(f);//modification-time
- f->track[f->total_tracks - 1]->timeScale = mp4ff_read_int32(f);//timescale
- temp = mp4ff_read_int32(f);
- f->track[f->total_tracks - 1]->duration = (temp == (uint32_t)(-1)) ? (uint64_t)(-1) : (uint64_t)(temp);
- }
- mp4ff_read_int16(f);
- mp4ff_read_int16(f);
- return 1;
-}
-#ifdef USE_TAGGING
-static int32_t mp4ff_read_meta(mp4ff_t *f, const uint64_t size)
-{
- uint64_t subsize, sumsize = 0;
- uint8_t atom_type;
- uint8_t header_size = 0;
-
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
-
- while (sumsize < (size-12))
- {
- subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
- if (atom_type == ATOM_ILST)
- {
- mp4ff_parse_metadata(f, (uint32_t)(subsize-(header_size+4)));
- } else {
- mp4ff_set_position(f, mp4ff_position(f)+subsize-header_size);
- }
- sumsize += subsize;
- }
-
- return 0;
-}
-#endif
-
-int32_t mp4ff_atom_read(mp4ff_t *f, const int32_t size, const uint8_t atom_type)
-{
- uint64_t dest_position = mp4ff_position(f)+size-8;
- if (atom_type == ATOM_STSZ)
- {
- /* sample size box */
- mp4ff_read_stsz(f);
- } else if (atom_type == ATOM_STTS) {
- /* time to sample box */
- mp4ff_read_stts(f);
- } else if (atom_type == ATOM_CTTS) {
- /* composition offset box */
- mp4ff_read_ctts(f);
- } else if (atom_type == ATOM_STSC) {
- /* sample to chunk box */
- mp4ff_read_stsc(f);
- } else if (atom_type == ATOM_STCO) {
- /* chunk offset box */
- mp4ff_read_stco(f);
- } else if (atom_type == ATOM_STSD) {
- /* sample description box */
- mp4ff_read_stsd(f);
- } else if (atom_type == ATOM_MVHD) {
- /* movie header box */
- mp4ff_read_mvhd(f);
- } else if (atom_type == ATOM_MDHD) {
- /* track header */
- mp4ff_read_mdhd(f);
-#ifdef ITUNES_DRM
- } else if (atom_type == ATOM_FRMA) {
- /* DRM track format */
- mp4ff_read_frma(f);
- } else if (atom_type == ATOM_IVIV) {
- mp4ff_read_iviv(f, size-8);
- } else if (atom_type == ATOM_NAME) {
- mp4ff_read_name(f, size-8);
- } else if (atom_type == ATOM_PRIV) {
- mp4ff_read_priv(f, size-8);
-#endif
-#ifdef USE_TAGGING
- } else if (atom_type == ATOM_META) {
- /* iTunes Metadata box */
- mp4ff_read_meta(f, size);
-#endif
- }
-
- mp4ff_set_position(f, dest_position);
-
-
- return 0;
-}
diff --git a/trunk/src/mp4ff/mp4ff.c b/trunk/src/mp4ff/mp4ff.c
deleted file mode 100644
index e0bb781e8..000000000
--- a/trunk/src/mp4ff/mp4ff.c
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-**
-** Any non-GPL usage of this software or parts of this software is strictly
-** forbidden.
-**
-** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
-**
-** $Id: mp4ff.c,v 1.15 2004/01/11 15:52:18 menno Exp $
-**/
-
-#include <stdlib.h>
-#include <string.h>
-#include "mp4ffint.h"
-
-#include "drms.h"
-
-int64_t mp4ff_get_track_duration_use_offsets(const mp4ff_t *f, const int32_t track);
-
-mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f)
-{
- mp4ff_t *ff = malloc(sizeof(mp4ff_t));
-
- memset(ff, 0, sizeof(mp4ff_t));
-
- ff->stream = f;
-
- parse_atoms(ff);
-
- return ff;
-}
-
-void mp4ff_close(mp4ff_t *ff)
-{
- int32_t i;
-
- for (i = 0; i < ff->total_tracks; i++)
- {
- if (ff->track[i])
- {
- if (ff->track[i]->stsz_table)
- free(ff->track[i]->stsz_table);
- if (ff->track[i]->stts_sample_count)
- free(ff->track[i]->stts_sample_count);
- if (ff->track[i]->stts_sample_delta)
- free(ff->track[i]->stts_sample_delta);
- if (ff->track[i]->stsc_first_chunk)
- free(ff->track[i]->stsc_first_chunk);
- if (ff->track[i]->stsc_samples_per_chunk)
- free(ff->track[i]->stsc_samples_per_chunk);
- if (ff->track[i]->stsc_sample_desc_index)
- free(ff->track[i]->stsc_sample_desc_index);
- if (ff->track[i]->stco_chunk_offset)
- free(ff->track[i]->stco_chunk_offset);
- if (ff->track[i]->decoderConfig)
- free(ff->track[i]->decoderConfig);
- if (ff->track[i]->ctts_sample_count)
- free(ff->track[i]->ctts_sample_count);
- if (ff->track[i]->ctts_sample_offset)
- free(ff->track[i]->ctts_sample_offset);
-#ifdef ITUNES_DRM
- if (ff->track[i]->p_drms)
- drms_free(ff->track[i]->p_drms);
-#endif
- free(ff->track[i]);
- }
- }
-
-#ifdef USE_TAGGING
- mp4ff_tag_delete(&(ff->tags));
-#endif
-
- if (ff) free(ff);
-}
-
-static void mp4ff_track_add(mp4ff_t *f)
-{
- f->total_tracks++;
-
- f->track[f->total_tracks - 1] = malloc(sizeof(mp4ff_track_t));
-
- memset(f->track[f->total_tracks - 1], 0, sizeof(mp4ff_track_t));
-}
-
-/* parse atoms that are sub atoms of other atoms */
-int32_t parse_sub_atoms(mp4ff_t *f, const uint64_t total_size)
-{
- uint64_t size;
- uint8_t atom_type = 0;
- uint64_t counted_size = 0;
- uint8_t header_size = 0;
-
- while (counted_size < total_size)
- {
- size = mp4ff_atom_read_header(f, &atom_type, &header_size);
- counted_size += size;
-
- /* check for end of file */
- if (size == 0)
- break;
-
- /* we're starting to read a new track, update index,
- * so that all data and tables get written in the right place
- */
- if (atom_type == ATOM_TRAK)
- {
- mp4ff_track_add(f);
- }
-
- /* parse subatoms */
- if (atom_type < SUBATOMIC)
- {
- parse_sub_atoms(f, size-header_size);
- } else {
- mp4ff_atom_read(f, (uint32_t)size, atom_type);
- }
- }
-
- return 0;
-}
-
-/* parse root atoms */
-int32_t parse_atoms(mp4ff_t *f)
-{
- uint64_t size;
- uint8_t atom_type = 0;
- uint8_t header_size = 0;
-
- f->file_size = 0;
-
- while ((size = mp4ff_atom_read_header(f, &atom_type, &header_size)) != 0)
- {
- f->file_size += size;
- f->last_atom = atom_type;
-
- if (atom_type == ATOM_MDAT && f->moov_read)
- {
- /* moov atom is before mdat, we can stop reading when mdat is encountered */
- /* file position will stay at beginning of mdat data */
-// break;
- }
-
- if (atom_type == ATOM_MOOV && size > header_size)
- {
- f->moov_read = 1;
- f->moov_offset = mp4ff_position(f)-header_size;
- f->moov_size = size;
- }
-
- /* parse subatoms */
- if (atom_type < SUBATOMIC)
- {
- parse_sub_atoms(f, size-header_size);
- } else {
- /* skip this atom */
- mp4ff_set_position(f, mp4ff_position(f)+size-header_size);
- }
- }
-
- return 0;
-}
-
-int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int32_t track,
- uint8_t** ppBuf, uint32_t* pBufSize)
-{
- if (track >= f->total_tracks)
- {
- *ppBuf = NULL;
- *pBufSize = 0;
- return 1;
- }
-
- if (f->track[track]->decoderConfig == NULL || f->track[track]->decoderConfigLen == 0)
- {
- *ppBuf = NULL;
- *pBufSize = 0;
- } else {
- *ppBuf = malloc(f->track[track]->decoderConfigLen);
- if (*ppBuf == NULL)
- {
- *pBufSize = 0;
- return 1;
- }
- memcpy(*ppBuf, f->track[track]->decoderConfig, f->track[track]->decoderConfigLen);
- *pBufSize = f->track[track]->decoderConfigLen;
- }
-
- return 0;
-}
-
-static int32_t mp4ff_get_track_type(const mp4ff_t *f, const int track)
-{
- return f->track[track]->type;
-}
-
-int32_t mp4ff_total_tracks(const mp4ff_t *f)
-{
- return f->total_tracks;
-}
-
-int32_t mp4ff_time_scale(const mp4ff_t *f, const int32_t track)
-{
- return f->track[track]->timeScale;
-}
-
-static uint32_t mp4ff_get_avg_bitrate(const mp4ff_t *f, const int32_t track)
-{
- return f->track[track]->avgBitrate;
-}
-
-static uint32_t mp4ff_get_max_bitrate(const mp4ff_t *f, const int32_t track)
-{
- return f->track[track]->maxBitrate;
-}
-
-static int64_t mp4ff_get_track_duration(const mp4ff_t *f, const int32_t track)
-{
- return f->track[track]->duration;
-}
-
-int64_t mp4ff_get_track_duration_use_offsets(const mp4ff_t *f, const int32_t track)
-{
- int64_t duration = mp4ff_get_track_duration(f,track);
- if (duration!=-1)
- {
- int64_t offset = mp4ff_get_sample_offset(f,track,0);
- if (offset > duration) duration = 0;
- else duration -= offset;
- }
- return duration;
-}
-
-
-int32_t mp4ff_num_samples(const mp4ff_t *f, const int32_t track)
-{
- int32_t i;
- int32_t total = 0;
-
- for (i = 0; i < f->track[track]->stts_entry_count; i++)
- {
- total += f->track[track]->stts_sample_count[i];
- }
- return total;
-}
-
-
-
-
-static uint32_t mp4ff_get_sample_rate(const mp4ff_t *f, const int32_t track)
-{
- return f->track[track]->sampleRate;
-}
-
-static uint32_t mp4ff_get_channel_count(const mp4ff_t * f,const int32_t track)
-{
- return f->track[track]->channelCount;
-}
-
-static uint32_t mp4ff_get_audio_type(const mp4ff_t * f,const int32_t track)
-{
- return f->track[track]->audioType;
-}
-
-static int32_t mp4ff_get_sample_duration_use_offsets(const mp4ff_t *f, const int32_t track, const int32_t sample)
-{
- int32_t d,o;
- d = mp4ff_get_sample_duration(f,track,sample);
- if (d!=-1)
- {
- o = mp4ff_get_sample_offset(f,track,sample);
- if (o>d) d = 0;
- else d -= o;
- }
- return d;
-}
-
-int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample)
-{
- int32_t i, co = 0;
-
- for (i = 0; i < f->track[track]->stts_entry_count; i++)
- {
- int32_t delta = f->track[track]->stts_sample_count[i];
- if (sample < co + delta)
- return f->track[track]->stts_sample_delta[i];
- co += delta;
- }
- return (int32_t)(-1);
-}
-
-int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample)
-{
- int32_t i, co = 0;
- int64_t acc = 0;
-
- for (i = 0; i < f->track[track]->stts_entry_count; i++)
- {
- int32_t delta = f->track[track]->stts_sample_count[i];
- if (sample < co + delta)
- {
- acc += f->track[track]->stts_sample_delta[i] * (sample - co);
- return acc;
- }
- else
- {
- acc += f->track[track]->stts_sample_delta[i] * delta;
- }
- co += delta;
- }
- return (int64_t)(-1);
-}
-
-int32_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample)
-{
- int32_t i, co = 0;
-
- for (i = 0; i < f->track[track]->ctts_entry_count; i++)
- {
- int32_t delta = f->track[track]->ctts_sample_count[i];
- if (sample < co + delta)
- return f->track[track]->ctts_sample_offset[i];
- co += delta;
- }
- return 0;
-}
-
-int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip)
-{
- int32_t i, co = 0;
- int64_t offset_total = 0;
- mp4ff_track_t * p_track = f->track[track];
-
- for (i = 0; i < p_track->stts_entry_count; i++)
- {
- int32_t sample_count = p_track->stts_sample_count[i];
- int32_t sample_delta = p_track->stts_sample_delta[i];
- int64_t offset_delta = (int64_t)sample_delta * (int64_t)sample_count;
- if (offset < offset_total + offset_delta)
- {
- int64_t offset_fromstts = offset - offset_total;
- if (toskip) *toskip = (int32_t)(offset_fromstts % sample_delta);
- return co + (int32_t)(offset_fromstts / sample_delta);
- }
- else
- {
- offset_total += offset_delta;
- }
- co += sample_count;
- }
- return (int32_t)(-1);
-}
-
-static int32_t mp4ff_find_sample_use_offsets(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip)
-{
- return mp4ff_find_sample(f,track,offset + mp4ff_get_sample_offset(f,track,0),toskip);
-}
-
-int32_t mp4ff_read_sample(mp4ff_t *f, const int32_t track, const int32_t sample,
- uint8_t **audio_buffer, uint32_t *bytes)
-{
- int32_t result = 0;
-
- *bytes = mp4ff_audio_frame_size(f, track, sample);
-
- if (*bytes==0) return 0;
-
- *audio_buffer = (uint8_t*)malloc(*bytes);
-
- mp4ff_set_sample_position(f, track, sample);
-
- result = mp4ff_read_data(f, *audio_buffer, *bytes);
-
- if (!result)
- {
- free(*audio_buffer);
- *audio_buffer = 0;
- return 0;
- }
-
-#ifdef ITUNES_DRM
- if (f->track[track]->p_drms != NULL)
- {
- drms_decrypt(f->track[track]->p_drms, (uint32_t*)*audio_buffer, *bytes);
- }
-#endif
-
- return *bytes;
-}
-
-
-static int32_t mp4ff_read_sample_v2(mp4ff_t *f, const int track, const int sample,unsigned char *buffer)
-{
- int32_t result = 0;
- int32_t size = mp4ff_audio_frame_size(f,track,sample);
- if (size<=0) return 0;
- mp4ff_set_sample_position(f, track, sample);
- result = mp4ff_read_data(f,buffer,size);
-
-#ifdef ITUNES_DRM
- if (f->track[track]->p_drms != NULL)
- {
- drms_decrypt(f->track[track]->p_drms, (uint32_t*)buffer, size);
- }
-#endif
-
- return result;
-}
-
-static int32_t mp4ff_read_sample_getsize(mp4ff_t *f, const int track, const int sample)
-{
- int32_t temp = mp4ff_audio_frame_size(f, track, sample);
- if (temp<0) temp = 0;
- return temp;
-}
diff --git a/trunk/src/mp4ff/mp4ff.dsp b/trunk/src/mp4ff/mp4ff.dsp
deleted file mode 100644
index e3a2d0899..000000000
--- a/trunk/src/mp4ff/mp4ff.dsp
+++ /dev/null
@@ -1,144 +0,0 @@
-# Microsoft Developer Studio Project File - Name="mp4ff" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=mp4ff - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "mp4ff.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "mp4ff.mak" CFG="mp4ff - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "mp4ff - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "mp4ff - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=xicl6.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "mp4ff - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-F90=df.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "USE_TAGGING" /YX /FD /c
-# ADD BASE RSC /l 0x413 /d "NDEBUG"
-# ADD RSC /l 0x413 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=xilink6.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ELSEIF "$(CFG)" == "mp4ff - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-F90=df.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "USE_TAGGING" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x413 /d "_DEBUG"
-# ADD RSC /l 0x413 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=xilink6.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ENDIF
-
-# Begin Target
-
-# Name "mp4ff - Win32 Release"
-# Name "mp4ff - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\drms.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp4atom.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp4ff.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp4meta.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp4sample.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp4tagupdate.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp4util.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\drms.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\drmstables.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp4ff.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp4ff_int_types.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp4ffint.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/trunk/src/mp4ff/mp4ff.h b/trunk/src/mp4ff/mp4ff.h
deleted file mode 100644
index 5fb485d77..000000000
--- a/trunk/src/mp4ff/mp4ff.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-**
-** Any non-GPL usage of this software or parts of this software is strictly
-** forbidden.
-**
-** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
-**
-** $Id: mp4ff.h,v 1.19 2004/01/11 15:52:18 menno Exp $
-**/
-
-#ifndef MP4FF_H
-#define MP4FF_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#include "mp4ff_int_types.h"
-
-/* file callback structure */
-typedef struct
-{
- uint32_t (*read)(void *user_data, void *buffer, uint32_t length);
- uint32_t (*write)(void *udata, void *buffer, uint32_t length);
- uint32_t (*seek)(void *user_data, uint64_t position);
- uint32_t (*truncate)(void *user_data);
- void *user_data;
-} mp4ff_callback_t;
-
-/* mp4 main file structure */
-typedef void* mp4ff_t;
-
-
-/* API */
-
-mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f);
-void mp4ff_close(mp4ff_t *f);
-int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int32_t mp4ff_get_sample_duration_use_offsets(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int32_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip);
-int32_t mp4ff_find_sample_use_offsets(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip);
-
-int32_t mp4ff_read_sample(mp4ff_t *f, const int track, const int sample,
- unsigned char **audio_buffer, unsigned int *bytes);
-
-int32_t mp4ff_read_sample_v2(mp4ff_t *f, const int track, const int sample,unsigned char *buffer);//returns 0 on error, number of bytes read on success, use mp4ff_read_sample_getsize() to check buffer size needed
-int32_t mp4ff_read_sample_getsize(mp4ff_t *f, const int track, const int sample);//returns 0 on error, buffer size needed for mp4ff_read_sample_v2() on success
-
-
-
-int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int track,
- unsigned char** ppBuf, unsigned int* pBufSize);
-int32_t mp4ff_get_track_type(const mp4ff_t *f, const int track);
-int32_t mp4ff_total_tracks(const mp4ff_t *f);
-int32_t mp4ff_num_samples(const mp4ff_t *f, const int track);
-int32_t mp4ff_time_scale(const mp4ff_t *f, const int track);
-
-uint32_t mp4ff_get_avg_bitrate(const mp4ff_t *f, const int32_t track);
-uint32_t mp4ff_get_max_bitrate(const mp4ff_t *f, const int32_t track);
-int64_t mp4ff_get_track_duration(const mp4ff_t *f, const int32_t track); //returns (-1) if unknown
-int64_t mp4ff_get_track_duration_use_offsets(const mp4ff_t *f, const int32_t track); //returns (-1) if unknown
-uint32_t mp4ff_get_sample_rate(const mp4ff_t *f, const int32_t track);
-uint32_t mp4ff_get_channel_count(const mp4ff_t * f,const int32_t track);
-uint32_t mp4ff_get_audio_type(const mp4ff_t * f,const int32_t track);
-
-
-/* metadata */
-int mp4ff_meta_get_num_items(const mp4ff_t *f);
-int mp4ff_meta_get_by_index(const mp4ff_t *f, unsigned int index,
- char **item, char **value);
-int mp4ff_meta_get_title(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_artist(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_writer(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_album(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_date(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_tool(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_comment(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_genre(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_track(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_disc(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_compilation(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_tempo(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value);
-#ifdef USE_TAGGING
-
-/* metadata tag structure */
-typedef struct
-{
- char *item;
- char *value;
-} mp4ff_tag_t;
-
-/* metadata list structure */
-typedef struct
-{
- mp4ff_tag_t *tags;
- uint32_t count;
-} mp4ff_metadata_t;
-
-int32_t mp4ff_meta_update(mp4ff_callback_t *f,const mp4ff_metadata_t * data);
-
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif
diff --git a/trunk/src/mp4ff/mp4ff_int_types.h b/trunk/src/mp4ff/mp4ff_int_types.h
deleted file mode 100644
index 2da8fee6e..000000000
--- a/trunk/src/mp4ff/mp4ff_int_types.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _MP4FF_INT_TYPES_H_
-#define _MP4FF_INT_TYPES_H_
-
-#ifdef _WIN32
-
-typedef char int8_t;
-typedef unsigned char uint8_t;
-typedef short int16_t;
-typedef unsigned short uint16_t;
-typedef long int32_t;
-typedef unsigned long uint32_t;
-
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-
-#else
-
-#include "config.h"
-
-#if defined(HAVE_STDINT_H)
-#include <stdint.h>
-#elif defined(HAVE_INTTYPES_H)
-#include <inttypes.h>
-#elif defined(HAVE_SYS_INTTYPES_H)
-#include <sys/inttypes.h>
-#elif defined(HAVE_SYS_TYPES_H)
-#include <sys/types.h>
-#endif
-
-#endif
-
-#endif
diff --git a/trunk/src/mp4ff/mp4ffint.h b/trunk/src/mp4ff/mp4ffint.h
deleted file mode 100644
index fc13f469d..000000000
--- a/trunk/src/mp4ff/mp4ffint.h
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-**
-** Any non-GPL usage of this software or parts of this software is strictly
-** forbidden.
-**
-** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
-**
-** $Id: mp4ffint.h,v 1.15 2004/01/14 20:50:22 menno Exp $
-**/
-
-#ifndef MP4FF_INTERNAL_H
-#define MP4FF_INTERNAL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#include "mp4ff_int_types.h"
-
-
-#ifdef _WIN32
-#define ITUNES_DRM
-#endif
-
-
-#define MAX_TRACKS 1024
-#define TRACK_UNKNOWN 0
-#define TRACK_AUDIO 1
-#define TRACK_VIDEO 2
-#define TRACK_SYSTEM 3
-
-
-#define SUBATOMIC 128
-
-/* atoms without subatoms */
-#define ATOM_FTYP 129
-#define ATOM_MDAT 130
-#define ATOM_MVHD 131
-#define ATOM_TKHD 132
-#define ATOM_TREF 133
-#define ATOM_MDHD 134
-#define ATOM_VMHD 135
-#define ATOM_SMHD 136
-#define ATOM_HMHD 137
-#define ATOM_STSD 138
-#define ATOM_STTS 139
-#define ATOM_STSZ 140
-#define ATOM_STZ2 141
-#define ATOM_STCO 142
-#define ATOM_STSC 143
-#define ATOM_MP4A 144
-#define ATOM_MP4V 145
-#define ATOM_MP4S 146
-#define ATOM_ESDS 147
-#define ATOM_META 148 /* iTunes Metadata box */
-#define ATOM_NAME 149 /* iTunes Metadata name box */
-#define ATOM_DATA 150 /* iTunes Metadata data box */
-#define ATOM_CTTS 151
-#define ATOM_FRMA 152
-#define ATOM_IVIV 153
-#define ATOM_PRIV 154
-
-#define ATOM_UNKNOWN 255
-#define ATOM_FREE ATOM_UNKNOWN
-#define ATOM_SKIP ATOM_UNKNOWN
-
-/* atoms with subatoms */
-#define ATOM_MOOV 1
-#define ATOM_TRAK 2
-#define ATOM_EDTS 3
-#define ATOM_MDIA 4
-#define ATOM_MINF 5
-#define ATOM_STBL 6
-#define ATOM_UDTA 7
-#define ATOM_ILST 8 /* iTunes Metadata list */
-#define ATOM_TITLE 9
-#define ATOM_ARTIST 10
-#define ATOM_WRITER 11
-#define ATOM_ALBUM 12
-#define ATOM_DATE 13
-#define ATOM_TOOL 14
-#define ATOM_COMMENT 15
-#define ATOM_GENRE1 16
-#define ATOM_TRACK 17
-#define ATOM_DISC 18
-#define ATOM_COMPILATION 19
-#define ATOM_GENRE2 20
-#define ATOM_TEMPO 21
-#define ATOM_COVER 22
-#define ATOM_DRMS 23
-#define ATOM_SINF 24
-#define ATOM_SCHI 25
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifndef _WIN32
-#define stricmp strcasecmp
-#endif
-
-/* file callback structure */
-typedef struct
-{
- uint32_t (*read)(void *user_data, void *buffer, uint32_t length);
- uint32_t (*write)(void *udata, void *buffer, uint32_t length);
- uint32_t (*seek)(void *user_data, uint64_t position);
- uint32_t (*truncate)(void *user_data);
- void *user_data;
-} mp4ff_callback_t;
-
-
-/* metadata tag structure */
-typedef struct
-{
- char *item;
- char *value;
-} mp4ff_tag_t;
-
-/* metadata list structure */
-typedef struct
-{
- mp4ff_tag_t *tags;
- uint32_t count;
-} mp4ff_metadata_t;
-
-
-typedef struct
-{
- int32_t type;
- int32_t channelCount;
- int32_t sampleSize;
- uint16_t sampleRate;
- int32_t audioType;
-
- /* stsd */
- int32_t stsd_entry_count;
-
- /* stsz */
- int32_t stsz_sample_size;
- int32_t stsz_sample_count;
- int32_t *stsz_table;
-
- /* stts */
- int32_t stts_entry_count;
- int32_t *stts_sample_count;
- int32_t *stts_sample_delta;
-
- /* stsc */
- int32_t stsc_entry_count;
- int32_t *stsc_first_chunk;
- int32_t *stsc_samples_per_chunk;
- int32_t *stsc_sample_desc_index;
-
- /* stsc */
- int32_t stco_entry_count;
- int32_t *stco_chunk_offset;
-
- /* ctts */
- int32_t ctts_entry_count;
- int32_t *ctts_sample_count;
- int32_t *ctts_sample_offset;
-
- /* esde */
- uint8_t *decoderConfig;
- int32_t decoderConfigLen;
-
- uint32_t maxBitrate;
- uint32_t avgBitrate;
-
- uint32_t timeScale;
- uint64_t duration;
-
-#ifdef ITUNES_DRM
- /* drms */
- void *p_drms;
-#endif
-
-} mp4ff_track_t;
-
-/* mp4 main file structure */
-typedef struct
-{
- /* stream to read from */
- mp4ff_callback_t *stream;
- int64_t current_position;
-
- int32_t moov_read;
- uint64_t moov_offset;
- uint64_t moov_size;
- uint8_t last_atom;
- uint64_t file_size;
-
- /* mvhd */
- int32_t time_scale;
- int32_t duration;
-
- /* incremental track index while reading the file */
- int32_t total_tracks;
-
- /* track data */
- mp4ff_track_t *track[MAX_TRACKS];
-
- /* metadata */
- mp4ff_metadata_t tags;
-} mp4ff_t;
-
-
-
-
-/* mp4util.c */
-int32_t mp4ff_read_data(mp4ff_t *f, int8_t *data, uint32_t size);
-int32_t mp4ff_write_data(mp4ff_t *f, int8_t *data, uint32_t size);
-uint64_t mp4ff_read_int64(mp4ff_t *f);
-uint32_t mp4ff_read_int32(mp4ff_t *f);
-uint32_t mp4ff_read_int24(mp4ff_t *f);
-uint16_t mp4ff_read_int16(mp4ff_t *f);
-uint8_t mp4ff_read_char(mp4ff_t *f);
-int32_t mp4ff_write_int32(mp4ff_t *f,const uint32_t data);
-uint32_t mp4ff_read_mp4_descr_length(mp4ff_t *f);
-int64_t mp4ff_position(const mp4ff_t *f);
-int32_t mp4ff_set_position(mp4ff_t *f, const int64_t position);
-int32_t mp4ff_truncate(mp4ff_t * f);
-char * mp4ff_read_string(mp4ff_t * f,uint32_t length);
-
-/* mp4atom.c */
-static int32_t mp4ff_atom_get_size(const int8_t *data);
-static int32_t mp4ff_atom_compare(const int8_t a1, const int8_t b1, const int8_t c1, const int8_t d1,
- const int8_t a2, const int8_t b2, const int8_t c2, const int8_t d2);
-static uint8_t mp4ff_atom_name_to_type(const int8_t a, const int8_t b, const int8_t c, const int8_t d);
-uint64_t mp4ff_atom_read_header(mp4ff_t *f, uint8_t *atom_type, uint8_t *header_size);
-static int32_t mp4ff_read_stsz(mp4ff_t *f);
-static int32_t mp4ff_read_esds(mp4ff_t *f);
-static int32_t mp4ff_read_mp4a(mp4ff_t *f);
-static int32_t mp4ff_read_stsd(mp4ff_t *f);
-static int32_t mp4ff_read_stsc(mp4ff_t *f);
-static int32_t mp4ff_read_stco(mp4ff_t *f);
-static int32_t mp4ff_read_stts(mp4ff_t *f);
-#ifdef USE_TAGGING
-static int32_t mp4ff_read_meta(mp4ff_t *f, const uint64_t size);
-#endif
-int32_t mp4ff_atom_read(mp4ff_t *f, const int32_t size, const uint8_t atom_type);
-
-/* mp4sample.c */
-static int32_t mp4ff_chunk_of_sample(const mp4ff_t *f, const int32_t track, const int32_t sample,
- int32_t *chunk_sample, int32_t *chunk);
-static int32_t mp4ff_chunk_to_offset(const mp4ff_t *f, const int32_t track, const int32_t chunk);
-static int32_t mp4ff_sample_range_size(const mp4ff_t *f, const int32_t track,
- const int32_t chunk_sample, const int32_t sample);
-static int32_t mp4ff_sample_to_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int32_t mp4ff_audio_frame_size(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int32_t mp4ff_set_sample_position(mp4ff_t *f, const int32_t track, const int32_t sample);
-
-#ifdef USE_TAGGING
-/* mp4meta.c */
-static int32_t mp4ff_tag_add_field(mp4ff_metadata_t *tags, const char *item, const char *value);
-static int32_t mp4ff_tag_set_field(mp4ff_metadata_t *tags, const char *item, const char *value);
-static int32_t mp4ff_set_metadata_name(mp4ff_t *f, const uint8_t atom_type, char **name);
-static int32_t mp4ff_parse_tag(mp4ff_t *f, const uint8_t parent_atom_type, const int32_t size);
-static int32_t mp4ff_meta_find_by_name(const mp4ff_t *f, const char *item, char **value);
-int32_t mp4ff_parse_metadata(mp4ff_t *f, const int32_t size);
-int32_t mp4ff_tag_delete(mp4ff_metadata_t *tags);
-int32_t mp4ff_meta_get_num_items(const mp4ff_t *f);
-int32_t mp4ff_meta_get_by_index(const mp4ff_t *f, uint32_t index,
- char **item, char **value);
-int32_t mp4ff_meta_get_title(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_artist(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_writer(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_album(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_date(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_tool(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_comment(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_genre(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_track(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_disc(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_compilation(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_tempo(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value);
-#endif
-
-/* mp4ff.c */
-mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f);
-#ifdef USE_TAGGING
-mp4ff_t *mp4ff_open_edit(mp4ff_callback_t *f);
-#endif
-void mp4ff_close(mp4ff_t *ff);
-/*void mp4ff_track_add(mp4ff_t *f);*/
-int32_t parse_sub_atoms(mp4ff_t *f, const uint64_t total_size);
-int32_t parse_atoms(mp4ff_t *f);
-
-int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int32_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip);
-
-int32_t mp4ff_read_sample(mp4ff_t *f, const int32_t track, const int32_t sample,
- uint8_t **audio_buffer, uint32_t *bytes);
-int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int32_t track,
- uint8_t** ppBuf, uint32_t* pBufSize);
-int32_t mp4ff_total_tracks(const mp4ff_t *f);
-int32_t mp4ff_time_scale(const mp4ff_t *f, const int32_t track);
-int32_t mp4ff_num_samples(const mp4ff_t *f, const int32_t track);
-
-uint32_t mp4ff_meta_genre_to_index(const char * genrestr);//returns 1-based index, 0 if not found
-const char * mp4ff_meta_index_to_genre(uint32_t idx);//returns pointer to static string
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif
diff --git a/trunk/src/mp4ff/mp4meta.c b/trunk/src/mp4ff/mp4meta.c
deleted file mode 100644
index 762f5dee7..000000000
--- a/trunk/src/mp4ff/mp4meta.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-**
-** Any non-GPL usage of this software or parts of this software is strictly
-** forbidden.
-**
-** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
-**
-** $Id: mp4meta.c,v 1.13 2004/01/11 15:52:18 menno Exp $
-**/
-
-#ifdef USE_TAGGING
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "mp4ffint.h"
-
-static int32_t mp4ff_tag_add_field(mp4ff_metadata_t *tags, const char *item, const char *value)
-{
- void *backup = (void *)tags->tags;
-
- if (!item || (item && !*item) || !value) return 0;
-
- tags->tags = (mp4ff_tag_t*)realloc(tags->tags, (tags->count+1) * sizeof(mp4ff_tag_t));
- if (!tags->tags)
- {
- if (backup) free(backup);
- return 0;
- } else {
- tags->tags[tags->count].item = strdup(item);
- tags->tags[tags->count].value = strdup(value);
-
- if (!tags->tags[tags->count].item || !tags->tags[tags->count].value)
- {
- if (!tags->tags[tags->count].item) free (tags->tags[tags->count].item);
- if (!tags->tags[tags->count].value) free (tags->tags[tags->count].value);
- tags->tags[tags->count].item = NULL;
- tags->tags[tags->count].value = NULL;
- return 0;
- }
-
- tags->count++;
- return 1;
- }
-}
-
-static int32_t mp4ff_tag_set_field(mp4ff_metadata_t *tags, const char *item, const char *value)
-{
- unsigned int i;
-
- if (!item || (item && !*item) || !value) return 0;
-
- for (i = 0; i < tags->count; i++)
- {
- if (!stricmp(tags->tags[i].item, item))
- {
- free(tags->tags[i].value);
- tags->tags[i].value = strdup(value);
- return 1;
- }
- }
-
- return mp4ff_tag_add_field(tags, item, value);
-}
-
-int32_t mp4ff_tag_delete(mp4ff_metadata_t *tags)
-{
- uint32_t i;
-
- for (i = 0; i < tags->count; i++)
- {
- if (tags->tags[i].item) free(tags->tags[i].item);
- if (tags->tags[i].value) free(tags->tags[i].value);
- }
-
- if (tags->tags) free(tags->tags);
-
- tags->tags = NULL;
- tags->count = 0;
-
- return 0;
-}
-
-static const char* ID3v1GenreList[] = {
- "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk",
- "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies",
- "Other", "Pop", "R&B", "Rap", "Reggae", "Rock",
- "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks",
- "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk",
- "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House",
- "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass",
- "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock",
- "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk",
- "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta",
- "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret",
- "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi",
- "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical",
- "Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing",
- "Fast-Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde",
- "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band",
- "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson",
- "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus",
- "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba",
- "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet",
- "Punk Rock", "Drum Solo", "A capella", "Euro-House", "Dance Hall",
- "Goa", "Drum & Bass", "Club House", "Hardcore", "Terror",
- "Indie", "BritPop", "NegerPunk", "Polsk Punk", "Beat",
- "Christian Gangsta", "Heavy Metal", "Black Metal", "Crossover", "Contemporary C",
- "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop",
- "SynthPop",
-};
-
-uint32_t mp4ff_meta_genre_to_index(const char * genrestr)
-{
- unsigned n;
- for(n=0;n<sizeof(ID3v1GenreList)/sizeof(ID3v1GenreList[0]);n++)
- {
- if (!stricmp(genrestr,ID3v1GenreList[n])) return n+1;
- }
- return 0;
-}
-
-const char * mp4ff_meta_index_to_genre(uint32_t idx)
-{
- if (idx>0 && idx<=sizeof(ID3v1GenreList)/sizeof(ID3v1GenreList[0]))
- {
- return ID3v1GenreList[idx-1];
- }
- else
- {
- return 0;
- }
-}
-
-
-static int32_t TrackToString(char** str, const uint16_t track, const uint16_t totalTracks)
-{
- char temp[32];
- sprintf(temp, "%.5u of %.5u", track, totalTracks);
- *str = strdup(temp);
- return 0;
-}
-
-static int32_t mp4ff_set_metadata_name(mp4ff_t *f, const uint8_t atom_type, char **name)
-{
- static char *tag_names[] = {
- "unknown", "title", "artist", "writer", "album",
- "date", "tool", "comment", "genre", "track",
- "disc", "compilation", "genre", "tempo", "cover"
- };
- uint8_t tag_idx = 0;
-
- switch (atom_type)
- {
- case ATOM_TITLE: tag_idx = 1; break;
- case ATOM_ARTIST: tag_idx = 2; break;
- case ATOM_WRITER: tag_idx = 3; break;
- case ATOM_ALBUM: tag_idx = 4; break;
- case ATOM_DATE: tag_idx = 5; break;
- case ATOM_TOOL: tag_idx = 6; break;
- case ATOM_COMMENT: tag_idx = 7; break;
- case ATOM_GENRE1: tag_idx = 8; break;
- case ATOM_TRACK: tag_idx = 9; break;
- case ATOM_DISC: tag_idx = 10; break;
- case ATOM_COMPILATION: tag_idx = 11; break;
- case ATOM_GENRE2: tag_idx = 12; break;
- case ATOM_TEMPO: tag_idx = 13; break;
- case ATOM_COVER: tag_idx = 14; break;
- default: tag_idx = 0; break;
- }
-
- *name = strdup(tag_names[tag_idx]);
-
- return 0;
-}
-
-static int32_t mp4ff_parse_tag(mp4ff_t *f, const uint8_t parent_atom_type, const int32_t size)
-{
- uint8_t atom_type;
- uint8_t header_size = 0;
- uint64_t subsize, sumsize = 0;
- char * name = NULL;
- char * data = NULL;
- uint32_t done = 0;
-
-
- while (sumsize < size)
- {
- uint64_t destpos;
- subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
- destpos = mp4ff_position(f)+subsize-header_size;
- if (!done)
- {
- if (atom_type == ATOM_DATA)
- {
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
- mp4ff_read_int32(f); /* reserved */
-
- /* some need special attention */
- if (parent_atom_type == ATOM_GENRE2 || parent_atom_type == ATOM_TEMPO)
- {
- if (subsize - header_size >= 8 + 2)
- {
- uint16_t val = mp4ff_read_int16(f);
-
- if (parent_atom_type == ATOM_TEMPO)
- {
- char temp[16];
- sprintf(temp, "%.5u BPM", val);
- mp4ff_tag_add_field(&(f->tags), "tempo", temp);
- }
- else
- {
- const char * temp = mp4ff_meta_index_to_genre(val);
- if (temp)
- {
- mp4ff_tag_add_field(&(f->tags), "genre", temp);
- }
- }
- done = 1;
- }
- } else if (parent_atom_type == ATOM_TRACK || parent_atom_type == ATOM_DISC) {
- if (!done && subsize - header_size >= 8 + 8)
- {
- uint16_t index,total;
- char temp[32];
- mp4ff_read_int16(f);
- index = mp4ff_read_int16(f);
- total = mp4ff_read_int16(f);
- mp4ff_read_int16(f);
-
- sprintf(temp,"%d",index);
- mp4ff_tag_add_field(&(f->tags), parent_atom_type == ATOM_TRACK ? "track" : "disc", temp);
- if (total>0)
- {
- sprintf(temp,"%d",total);
- mp4ff_tag_add_field(&(f->tags), parent_atom_type == ATOM_TRACK ? "totaltracks" : "totaldiscs", temp);
- }
- done = 1;
- }
- } else
- {
- if (data) {free(data);data = NULL;}
- data = mp4ff_read_string(f,(uint32_t)(subsize-(header_size+8)));
- }
- } else if (atom_type == ATOM_NAME) {
- if (!done)
- {
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
- if (name) free(name);
- name = mp4ff_read_string(f,(uint32_t)(subsize-(header_size+4)));
- }
- }
- mp4ff_set_position(f, destpos);
- sumsize += subsize;
- }
- }
-
- if (data)
- {
- if (!done)
- {
- if (name == NULL) mp4ff_set_metadata_name(f, parent_atom_type, &name);
- if (name) mp4ff_tag_add_field(&(f->tags), name, data);
- }
-
- free(data);
- }
- if (name) free(name);
- return 1;
-}
-
-int32_t mp4ff_parse_metadata(mp4ff_t *f, const int32_t size)
-{
- uint64_t subsize, sumsize = 0;
- uint8_t atom_type;
- uint8_t header_size = 0;
-
- while (sumsize < size)
- {
- subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
- mp4ff_parse_tag(f, atom_type, (uint32_t)(subsize-header_size));
- sumsize += subsize;
- }
-
- return 0;
-}
-
-/* find a metadata item by name */
-/* returns 0 if item found, 1 if no such item */
-static int32_t mp4ff_meta_find_by_name(const mp4ff_t *f, const char *item, char **value)
-{
- uint32_t i;
-
- for (i = 0; i < f->tags.count; i++)
- {
- if (!stricmp(f->tags.tags[i].item, item))
- {
- *value = strdup(f->tags.tags[i].value);
- return 1;
- }
- }
-
- *value = NULL;
-
- /* not found */
- return 0;
-}
-
-int32_t mp4ff_meta_get_num_items(const mp4ff_t *f)
-{
- return f->tags.count;
-}
-
-int32_t mp4ff_meta_get_by_index(const mp4ff_t *f, uint32_t index,
- char **item, char **value)
-{
- if (index >= f->tags.count)
- {
- *item = NULL;
- *value = NULL;
- return 0;
- } else {
- *item = strdup(f->tags.tags[index].item);
- *value = strdup(f->tags.tags[index].value);
- return 1;
- }
-}
-
-int32_t mp4ff_meta_get_title(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "title", value);
-}
-
-int32_t mp4ff_meta_get_artist(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "artist", value);
-}
-
-int32_t mp4ff_meta_get_writer(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "writer", value);
-}
-
-int32_t mp4ff_meta_get_album(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "album", value);
-}
-
-int32_t mp4ff_meta_get_date(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "date", value);
-}
-
-int32_t mp4ff_meta_get_tool(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "tool", value);
-}
-
-int32_t mp4ff_meta_get_comment(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "comment", value);
-}
-
-int32_t mp4ff_meta_get_genre(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "genre", value);
-}
-
-int32_t mp4ff_meta_get_track(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "track", value);
-}
-
-int32_t mp4ff_meta_get_disc(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "disc", value);
-}
-
-int32_t mp4ff_meta_get_compilation(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "compilation", value);
-}
-
-int32_t mp4ff_meta_get_tempo(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "tempo", value);
-}
-
-int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "cover", value);
-}
-
-#endif
diff --git a/trunk/src/mp4ff/mp4sample.c b/trunk/src/mp4ff/mp4sample.c
deleted file mode 100644
index 5688a3a8f..000000000
--- a/trunk/src/mp4ff/mp4sample.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-**
-** Any non-GPL usage of this software or parts of this software is strictly
-** forbidden.
-**
-** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
-**
-** $Id: mp4sample.c,v 1.15 2004/01/11 15:52:19 menno Exp $
-**/
-
-#include <stdlib.h>
-#include "mp4ffint.h"
-
-
-static int32_t mp4ff_chunk_of_sample(const mp4ff_t *f, const int32_t track, const int32_t sample,
- int32_t *chunk_sample, int32_t *chunk)
-{
- int32_t total_entries = 0;
- int32_t chunk2entry;
- int32_t chunk1, chunk2, chunk1samples, range_samples, total = 0;
-
- if (f->track[track] == NULL)
- {
- return -1;
- }
-
- total_entries = f->track[track]->stsc_entry_count;
-
- chunk1 = 1;
- chunk1samples = 0;
- chunk2entry = 0;
-
- do
- {
- chunk2 = f->track[track]->stsc_first_chunk[chunk2entry];
- *chunk = chunk2 - chunk1;
- range_samples = *chunk * chunk1samples;
-
- if (sample < total + range_samples) break;
-
- chunk1samples = f->track[track]->stsc_samples_per_chunk[chunk2entry];
- chunk1 = chunk2;
-
- if(chunk2entry < total_entries)
- {
- chunk2entry++;
- total += range_samples;
- }
- } while (chunk2entry < total_entries);
-
- if (chunk1samples)
- *chunk = (sample - total) / chunk1samples + chunk1;
- else
- *chunk = 1;
-
- *chunk_sample = total + (*chunk - chunk1) * chunk1samples;
-
- return 0;
-}
-
-static int32_t mp4ff_chunk_to_offset(const mp4ff_t *f, const int32_t track, const int32_t chunk)
-{
- const mp4ff_track_t * p_track = f->track[track];
-
- if (p_track->stco_entry_count && (chunk > p_track->stco_entry_count))
- {
- return p_track->stco_chunk_offset[p_track->stco_entry_count - 1];
- } else if (p_track->stco_entry_count) {
- return p_track->stco_chunk_offset[chunk - 1];
- } else {
- return 8;
- }
-
- return 0;
-}
-
-static int32_t mp4ff_sample_range_size(const mp4ff_t *f, const int32_t track,
- const int32_t chunk_sample, const int32_t sample)
-{
- int32_t i, total;
- const mp4ff_track_t * p_track = f->track[track];
-
- if (p_track->stsz_sample_size)
- {
- return (sample - chunk_sample) * p_track->stsz_sample_size;
- }
- else
- {
- if (sample>=p_track->stsz_sample_count) return 0;//error
-
- for(i = chunk_sample, total = 0; i < sample; i++)
- {
- total += p_track->stsz_table[i];
- }
- }
-
- return total;
-}
-
-static int32_t mp4ff_sample_to_offset(const mp4ff_t *f, const int32_t track, const int32_t sample)
-{
- int32_t chunk, chunk_sample, chunk_offset1, chunk_offset2;
-
- mp4ff_chunk_of_sample(f, track, sample, &chunk_sample, &chunk);
-
- chunk_offset1 = mp4ff_chunk_to_offset(f, track, chunk);
- chunk_offset2 = chunk_offset1 + mp4ff_sample_range_size(f, track, chunk_sample, sample);
-
- return chunk_offset2;
-}
-
-int32_t mp4ff_audio_frame_size(const mp4ff_t *f, const int32_t track, const int32_t sample)
-{
- int32_t bytes;
- const mp4ff_track_t * p_track = f->track[track];
-
- if (p_track->stsz_sample_size)
- {
- bytes = p_track->stsz_sample_size;
- } else {
- bytes = p_track->stsz_table[sample];
- }
-
- return bytes;
-}
-
-int32_t mp4ff_set_sample_position(mp4ff_t *f, const int32_t track, const int32_t sample)
-{
- int32_t offset;
-
- offset = mp4ff_sample_to_offset(f, track, sample);
- mp4ff_set_position(f, offset);
-
- return 0;
-}
diff --git a/trunk/src/mp4ff/mp4tagupdate.c b/trunk/src/mp4ff/mp4tagupdate.c
deleted file mode 100644
index c999fa5ee..000000000
--- a/trunk/src/mp4ff/mp4tagupdate.c
+++ /dev/null
@@ -1,645 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include "mp4ffint.h"
-
-#ifdef USE_TAGGING
-
-static uint32_t fix_byte_order_32(uint32_t src)
-{
- uint32_t result;
- uint32_t a, b, c, d;
- int8_t data[4];
-
- memcpy(data,&src,sizeof(src));
- a = (uint8_t)data[0];
- b = (uint8_t)data[1];
- c = (uint8_t)data[2];
- d = (uint8_t)data[3];
-
- result = (a<<24) | (b<<16) | (c<<8) | d;
- return (uint32_t)result;
-}
-
-static uint16_t fix_byte_order_16(uint16_t src)
-{
- uint16_t result;
- uint16_t a, b;
- int8_t data[2];
-
- memcpy(data,&src,sizeof(src));
- a = (uint8_t)data[0];
- b = (uint8_t)data[1];
-
- result = (a<<8) | b;
- return (uint16_t)result;
-}
-
-
-typedef struct
-{
- void * data;
- unsigned written;
- unsigned allocated;
- unsigned error;
-} membuffer;
-
-static unsigned membuffer_write(membuffer * buf,const void * ptr,unsigned bytes)
-{
- unsigned dest_size = buf->written + bytes;
-
- if (buf->error) return 0;
- if (dest_size > buf->allocated)
- {
- do
- {
- buf->allocated <<= 1;
- } while(dest_size > buf->allocated);
-
- {
- void * newptr = realloc(buf->data,buf->allocated);
- if (newptr==0)
- {
- free(buf->data);
- buf->data = 0;
- buf->error = 1;
- return 0;
- }
- buf->data = newptr;
- }
- }
-
- if (ptr) memcpy((char*)buf->data + buf->written,ptr,bytes);
- buf->written += bytes;
- return bytes;
-}
-
-#define membuffer_write_data membuffer_write
-
-static unsigned membuffer_write_int32(membuffer * buf,uint32_t data)
-{
- uint8_t temp[4] = {(uint8_t)(data>>24),(uint8_t)(data>>16),(uint8_t)(data>>8),(uint8_t)data};
- return membuffer_write_data(buf,temp,4);
-}
-
-static unsigned membuffer_write_int24(membuffer * buf,uint32_t data)
-{
- uint8_t temp[3] = {(uint8_t)(data>>16),(uint8_t)(data>>8),(uint8_t)data};
- return membuffer_write_data(buf,temp,3);
-}
-
-static unsigned membuffer_write_int16(membuffer * buf,uint16_t data)
-{
- uint8_t temp[2] = {(uint8_t)(data>>8),(uint8_t)data};
- return membuffer_write_data(buf,temp,2);
-}
-
-static unsigned membuffer_write_atom_name(membuffer * buf,const char * data)
-{
- return membuffer_write_data(buf,data,4)==4 ? 1 : 0;
-}
-
-static void membuffer_write_atom(membuffer * buf,const char * name,unsigned size,const void * data)
-{
- membuffer_write_int32(buf,size + 8);
- membuffer_write_atom_name(buf,name);
- membuffer_write_data(buf,data,size);
-}
-
-static unsigned membuffer_write_string(membuffer * buf,const char * data)
-{
- return membuffer_write_data(buf,data,strlen(data));
-}
-
-static unsigned membuffer_write_int8(membuffer * buf,uint8_t data)
-{
- return membuffer_write_data(buf,&data,1);
-}
-
-static void * membuffer_get_ptr(const membuffer * buf)
-{
- return buf->data;
-}
-
-static unsigned membuffer_get_size(const membuffer * buf)
-{
- return buf->written;
-}
-
-static unsigned membuffer_error(const membuffer * buf)
-{
- return buf->error;
-}
-
-static void membuffer_set_error(membuffer * buf) {buf->error = 1;}
-
-static unsigned membuffer_transfer_from_file(membuffer * buf,mp4ff_t * src,unsigned bytes)
-{
- unsigned oldsize;
- void * bufptr;
-
- oldsize = membuffer_get_size(buf);
- if (membuffer_write_data(buf,0,bytes) != bytes) return 0;
-
- bufptr = membuffer_get_ptr(buf);
- if (bufptr==0) return 0;
-
- if ((unsigned)mp4ff_read_data(src,(char*)bufptr + oldsize,bytes)!=bytes)
- {
- membuffer_set_error(buf);
- return 0;
- }
-
- return bytes;
-}
-
-
-static membuffer * membuffer_create()
-{
- const unsigned initial_size = 256;
-
- membuffer * buf = (membuffer *) malloc(sizeof(membuffer));
- buf->data = malloc(initial_size);
- buf->written = 0;
- buf->allocated = initial_size;
- buf->error = buf->data == 0 ? 1 : 0;
-
- return buf;
-}
-
-static void membuffer_free(membuffer * buf)
-{
- if (buf->data) free(buf->data);
- free(buf);
-}
-
-static void * membuffer_detach(membuffer * buf)
-{
- void * ret;
-
- if (buf->error) return 0;
-
- ret = realloc(buf->data,buf->written);
-
- if (ret == 0) free(buf->data);
-
- buf->data = 0;
- buf->error = 1;
-
- return ret;
-}
-
-#if 0
-/* metadata tag structure */
-typedef struct
-{
- char *item;
- char *value;
-} mp4ff_tag_t;
-
-/* metadata list structure */
-typedef struct
-{
- mp4ff_tag_t *tags;
- uint32_t count;
-} mp4ff_metadata_t;
-#endif
-
-typedef struct
-{
- const char * atom;
- const char * name;
-} stdmeta_entry;
-
-static stdmeta_entry stdmetas[] =
-{
- {"©nam","title"},
- {"©ART","artist"},
- {"©wrt","writer"},
- {"©alb","album"},
- {"©day","date"},
- {"©too","tool"},
- {"©cmt","comment"},
-// {"©gen","genre"},
- {"cpil","compilation"},
-// {"trkn","track"},
-// {"disk","disc"},
-// {"gnre","genre"},
- {"covr","cover"},
-};
-
-
-static const char* find_standard_meta(const char * name) //returns atom name if found, 0 if not
-{
- unsigned n;
- for(n=0;n<sizeof(stdmetas)/sizeof(stdmetas[0]);n++)
- {
- if (!stricmp(name,stdmetas[n].name)) return stdmetas[n].atom;
- }
- return 0;
-}
-
-static void membuffer_write_track_tag(membuffer * buf,const char * name,uint32_t index,uint32_t total)
-{
- membuffer_write_int32(buf,8 /*atom header*/ + 8 /*data atom header*/ + 8 /*flags + reserved*/ + 8 /*actual data*/ );
- membuffer_write_atom_name(buf,name);
- membuffer_write_int32(buf,8 /*data atom header*/ + 8 /*flags + reserved*/ + 8 /*actual data*/ );
- membuffer_write_atom_name(buf,"data");
- membuffer_write_int32(buf,0);//flags
- membuffer_write_int32(buf,0);//reserved
- membuffer_write_int16(buf,0);
- membuffer_write_int16(buf,(uint16_t)index);//track number
- membuffer_write_int16(buf,(uint16_t)total);//total tracks
- membuffer_write_int16(buf,0);
-}
-
-static void membuffer_write_int16_tag(membuffer * buf,const char * name,uint16_t value)
-{
- membuffer_write_int32(buf,8 /*atom header*/ + 8 /*data atom header*/ + 8 /*flags + reserved*/ + 2 /*actual data*/ );
- membuffer_write_atom_name(buf,name);
- membuffer_write_int32(buf,8 /*data atom header*/ + 8 /*flags + reserved*/ + 2 /*actual data*/ );
- membuffer_write_atom_name(buf,"data");
- membuffer_write_int32(buf,0);//flags
- membuffer_write_int32(buf,0);//reserved
- membuffer_write_int16(buf,value);//value
-}
-
-static void membuffer_write_std_tag(membuffer * buf,const char * name,const char * value)
-{
- membuffer_write_int32(buf,8 /*atom header*/ + 8 /*data atom header*/ + 8 /*flags + reserved*/ + strlen(value) );
- membuffer_write_atom_name(buf,name);
- membuffer_write_int32(buf,8 /*data atom header*/ + 8 /*flags + reserved*/ + strlen(value));
- membuffer_write_atom_name(buf,"data");
- membuffer_write_int32(buf,1);//flags
- membuffer_write_int32(buf,0);//reserved
- membuffer_write_data(buf,value,strlen(value));
-}
-
-static void membuffer_write_custom_tag(membuffer * buf,const char * name,const char * value)
-{
- membuffer_write_int32(buf,8 /*atom header*/ + 0x1C /*weirdo itunes atom*/ + 12 /*name atom header*/ + strlen(name) + 16 /*data atom header + flags*/ + strlen(value) );
- membuffer_write_atom_name(buf,"----");
- membuffer_write_int32(buf,0x1C);//weirdo itunes atom
- membuffer_write_atom_name(buf,"mean");
- membuffer_write_int32(buf,0);
- membuffer_write_data(buf,"com.apple.iTunes",16);
- membuffer_write_int32(buf,12 + strlen(name));
- membuffer_write_atom_name(buf,"name");
- membuffer_write_int32(buf,0);
- membuffer_write_data(buf,name,strlen(name));
- membuffer_write_int32(buf,8 /*data atom header*/ + 8 /*flags + reserved*/ + strlen(value));
- membuffer_write_atom_name(buf,"data");
- membuffer_write_int32(buf,1);//flags
- membuffer_write_int32(buf,0);//reserved
- membuffer_write_data(buf,value,strlen(value));
-
-}
-
-static uint32_t myatoi(const char * param)
-{
- return param ? atoi(param) : 0;
-}
-
-static uint32_t create_ilst(const mp4ff_metadata_t * data,void ** out_buffer,uint32_t * out_size)
-{
- membuffer * buf = membuffer_create();
- unsigned metaptr;
- char * mask = (char*)malloc(data->count);
- memset(mask,0,data->count);
-
- {
- const char * tracknumber_ptr = 0, * totaltracks_ptr = 0;
- const char * discnumber_ptr = 0, * totaldiscs_ptr = 0;
- const char * genre_ptr = 0, * tempo_ptr = 0;
- for(metaptr = 0; metaptr < data->count; metaptr++)
- {
- mp4ff_tag_t * tag = &data->tags[metaptr];
- if (!stricmp(tag->item,"tracknumber") || !stricmp(tag->item,"track"))
- {
- if (tracknumber_ptr==0) tracknumber_ptr = tag->value;
- mask[metaptr] = 1;
- }
- else if (!stricmp(tag->item,"totaltracks"))
- {
- if (totaltracks_ptr==0) totaltracks_ptr = tag->value;
- mask[metaptr] = 1;
- }
- else if (!stricmp(tag->item,"discnumber") || !stricmp(tag->item,"disc"))
- {
- if (discnumber_ptr==0) discnumber_ptr = tag->value;
- mask[metaptr] = 1;
- }
- else if (!stricmp(tag->item,"totaldiscs"))
- {
- if (totaldiscs_ptr==0) totaldiscs_ptr = tag->value;
- mask[metaptr] = 1;
- }
- else if (!stricmp(tag->item,"genre"))
- {
- if (genre_ptr==0) genre_ptr = tag->value;
- mask[metaptr] = 1;
- }
- else if (!stricmp(tag->item,"tempo"))
- {
- if (tempo_ptr==0) tempo_ptr = tag->value;
- mask[metaptr] = 1;
- }
-
- }
-
- if (tracknumber_ptr) membuffer_write_track_tag(buf,"trkn",myatoi(tracknumber_ptr),myatoi(totaltracks_ptr));
- if (discnumber_ptr) membuffer_write_track_tag(buf,"disk",myatoi(discnumber_ptr),myatoi(totaldiscs_ptr));
- if (tempo_ptr) membuffer_write_int16_tag(buf,"tmpo",(uint16_t)myatoi(tempo_ptr));
-
- if (genre_ptr)
- {
- uint32_t index = mp4ff_meta_genre_to_index(genre_ptr);
- if (index==0)
- membuffer_write_std_tag(buf,"©gen",genre_ptr);
- else
- membuffer_write_int16_tag(buf,"gnre",(uint16_t)index);
- }
- }
-
- for(metaptr = 0; metaptr < data->count; metaptr++)
- {
- if (!mask[metaptr])
- {
- mp4ff_tag_t * tag = &data->tags[metaptr];
- const char * std_meta_atom = find_standard_meta(tag->item);
- if (std_meta_atom)
- {
- membuffer_write_std_tag(buf,std_meta_atom,tag->value);
- }
- else
- {
- membuffer_write_custom_tag(buf,tag->item,tag->value);
- }
- }
- }
-
- free(mask);
-
- if (membuffer_error(buf))
- {
- membuffer_free(buf);
- return 0;
- }
-
- *out_size = membuffer_get_size(buf);
- *out_buffer = membuffer_detach(buf);
- membuffer_free(buf);
-
- return 1;
-}
-
-static uint32_t find_atom(mp4ff_t * f,uint64_t base,uint32_t size,const char * name)
-{
- uint32_t remaining = size;
- uint64_t atom_offset = base;
- for(;;)
- {
- char atom_name[4];
- uint32_t atom_size;
-
- mp4ff_set_position(f,atom_offset);
-
- if (remaining < 8) break;
- atom_size = mp4ff_read_int32(f);
- if (atom_size > remaining || atom_size < 8) break;
- mp4ff_read_data(f,atom_name,4);
-
- if (!memcmp(atom_name,name,4))
- {
- mp4ff_set_position(f,atom_offset);
- return 1;
- }
-
- remaining -= atom_size;
- atom_offset += atom_size;
- }
- return 0;
-}
-
-static uint32_t find_atom_v2(mp4ff_t * f,uint64_t base,uint32_t size,const char * name,uint32_t extraheaders,const char * name_inside)
-{
- uint64_t first_base = (uint64_t)(-1);
- while(find_atom(f,base,size,name))//try to find atom <name> with atom <name_inside> in it
- {
- uint64_t mybase = mp4ff_position(f);
- uint32_t mysize = mp4ff_read_int32(f);
-
- if (first_base == (uint64_t)(-1)) first_base = mybase;
-
- if (mysize < 8 + extraheaders) break;
-
- if (find_atom(f,mybase+(8+extraheaders),mysize-(8+extraheaders),name_inside))
- {
- mp4ff_set_position(f,mybase);
- return 2;
- }
- base += mysize;
- if (size<=mysize) {size=0;break;}
- size -= mysize;
- }
-
- if (first_base != (uint64_t)(-1))//wanted atom inside not found
- {
- mp4ff_set_position(f,first_base);
- return 1;
- }
- else return 0;
-}
-
-static uint32_t create_meta(const mp4ff_metadata_t * data,void ** out_buffer,uint32_t * out_size)
-{
- membuffer * buf;
- uint32_t ilst_size;
- void * ilst_buffer;
-
- if (!create_ilst(data,&ilst_buffer,&ilst_size)) return 0;
-
- buf = membuffer_create();
-
- membuffer_write_int32(buf,0);
- membuffer_write_atom(buf,"ilst",ilst_size,ilst_buffer);
- free(ilst_buffer);
-
- *out_size = membuffer_get_size(buf);
- *out_buffer = membuffer_detach(buf);
- membuffer_free(buf);
- return 1;
-}
-
-static uint32_t create_udta(const mp4ff_metadata_t * data,void ** out_buffer,uint32_t * out_size)
-{
- membuffer * buf;
- uint32_t meta_size;
- void * meta_buffer;
-
- if (!create_meta(data,&meta_buffer,&meta_size)) return 0;
-
- buf = membuffer_create();
-
- membuffer_write_atom(buf,"meta",meta_size,meta_buffer);
-
- free(meta_buffer);
-
- *out_size = membuffer_get_size(buf);
- *out_buffer = membuffer_detach(buf);
- membuffer_free(buf);
- return 1;
-}
-
-static uint32_t modify_moov(mp4ff_t * f,const mp4ff_metadata_t * data,void ** out_buffer,uint32_t * out_size)
-{
- uint64_t total_base = f->moov_offset + 8;
- uint32_t total_size = (uint32_t)(f->moov_size - 8);
-
- uint64_t udta_offset,meta_offset,ilst_offset;
- uint32_t udta_size, meta_size, ilst_size;
-
- uint32_t new_ilst_size;
- void * new_ilst_buffer;
-
- uint8_t * p_out;
- int32_t size_delta;
-
-
- if (!find_atom_v2(f,total_base,total_size,"udta",0,"meta"))
- {
- membuffer * buf;
- void * new_udta_buffer;
- uint32_t new_udta_size;
- if (!create_udta(data,&new_udta_buffer,&new_udta_size)) return 0;
-
- buf = membuffer_create();
- mp4ff_set_position(f,total_base);
- membuffer_transfer_from_file(buf,f,total_size);
-
- membuffer_write_atom(buf,"udta",new_udta_size,new_udta_buffer);
-
- free(new_udta_buffer);
-
- *out_size = membuffer_get_size(buf);
- *out_buffer = membuffer_detach(buf);
- membuffer_free(buf);
- return 1;
- }
- else
- {
- udta_offset = mp4ff_position(f);
- udta_size = mp4ff_read_int32(f);
- if (find_atom_v2(f,udta_offset+8,udta_size-8,"meta",4,"ilst")<2)
- {
- membuffer * buf;
- void * new_meta_buffer;
- uint32_t new_meta_size;
- if (!create_meta(data,&new_meta_buffer,&new_meta_size)) return 0;
-
- buf = membuffer_create();
- mp4ff_set_position(f,total_base);
- membuffer_transfer_from_file(buf,f,(uint32_t)(udta_offset - total_base));
-
- membuffer_write_int32(buf,udta_size + 8 + new_meta_size);
- membuffer_write_atom_name(buf,"udta");
- membuffer_transfer_from_file(buf,f,udta_size);
-
- membuffer_write_atom(buf,"meta",new_meta_size,new_meta_buffer);
- free(new_meta_buffer);
-
- *out_size = membuffer_get_size(buf);
- *out_buffer = membuffer_detach(buf);
- membuffer_free(buf);
- return 1;
- }
- meta_offset = mp4ff_position(f);
- meta_size = mp4ff_read_int32(f);
- if (!find_atom(f,meta_offset+12,meta_size-12,"ilst")) return 0;//shouldn't happen, find_atom_v2 above takes care of it
- ilst_offset = mp4ff_position(f);
- ilst_size = mp4ff_read_int32(f);
-
- if (!create_ilst(data,&new_ilst_buffer,&new_ilst_size)) return 0;
-
- size_delta = new_ilst_size - (ilst_size - 8);
-
- *out_size = total_size + size_delta;
- *out_buffer = malloc(*out_size);
- if (*out_buffer == 0)
- {
- free(new_ilst_buffer);
- return 0;
- }
-
- p_out = (uint8_t*)*out_buffer;
-
- mp4ff_set_position(f,total_base);
- mp4ff_read_data(f,p_out,(uint32_t)(udta_offset - total_base )); p_out += (uint32_t)(udta_offset - total_base );
- *(uint32_t*)p_out = fix_byte_order_32(mp4ff_read_int32(f) + size_delta); p_out += 4;
- mp4ff_read_data(f,p_out,4); p_out += 4;
- mp4ff_read_data(f,p_out,(uint32_t)(meta_offset - udta_offset - 8)); p_out += (uint32_t)(meta_offset - udta_offset - 8);
- *(uint32_t*)p_out = fix_byte_order_32(mp4ff_read_int32(f) + size_delta); p_out += 4;
- mp4ff_read_data(f,p_out,4); p_out += 4;
- mp4ff_read_data(f,p_out,(uint32_t)(ilst_offset - meta_offset - 8)); p_out += (uint32_t)(ilst_offset - meta_offset - 8);
- *(uint32_t*)p_out = fix_byte_order_32(mp4ff_read_int32(f) + size_delta); p_out += 4;
- mp4ff_read_data(f,p_out,4); p_out += 4;
-
- memcpy(p_out,new_ilst_buffer,new_ilst_size);
- p_out += new_ilst_size;
-
- mp4ff_set_position(f,ilst_offset + ilst_size);
- mp4ff_read_data(f,p_out,(uint32_t)(total_size - (ilst_offset - total_base) - ilst_size));
-
- free(new_ilst_buffer);
- }
- return 1;
-
-}
-
-static int32_t mp4ff_meta_update(mp4ff_callback_t *f,const mp4ff_metadata_t * data)
-{
- void * new_moov_data;
- uint32_t new_moov_size;
-
- mp4ff_t *ff = malloc(sizeof(mp4ff_t));
-
- memset(ff, 0, sizeof(mp4ff_t));
- ff->stream = f;
- mp4ff_set_position(ff,0);
-
- parse_atoms(ff);
-
-
- if (!modify_moov(ff,data,&new_moov_data,&new_moov_size))
- {
- mp4ff_close(ff);
- return 0;
- }
-
- /* copy moov atom to end of the file */
- if (ff->last_atom != ATOM_MOOV)
- {
- char *free_data = "free";
-
- /* rename old moov to free */
- mp4ff_set_position(ff, ff->moov_offset + 4);
- mp4ff_write_data(ff, free_data, 4);
-
- mp4ff_set_position(ff, ff->file_size);
- mp4ff_write_int32(ff,new_moov_size + 8);
- mp4ff_write_data(ff,"moov",4);
- mp4ff_write_data(ff, new_moov_data, new_moov_size);
- }
- else
- {
- mp4ff_set_position(ff, ff->moov_offset);
- mp4ff_write_int32(ff,new_moov_size + 8);
- mp4ff_write_data(ff,"moov",4);
- mp4ff_write_data(ff, new_moov_data, new_moov_size);
- }
-
- mp4ff_truncate(ff);
-
- mp4ff_close(ff);
- return 1;
-}
-#endif
diff --git a/trunk/src/mp4ff/mp4util.c b/trunk/src/mp4ff/mp4util.c
deleted file mode 100644
index 1a77c97ae..000000000
--- a/trunk/src/mp4ff/mp4util.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-**
-** Any non-GPL usage of this software or parts of this software is strictly
-** forbidden.
-**
-** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
-**
-** $Id: mp4util.c,v 1.15 2004/01/11 15:52:19 menno Exp $
-**/
-
-#include "mp4ffint.h"
-#include <stdlib.h>
-
-int32_t mp4ff_read_data(mp4ff_t *f, int8_t *data, uint32_t size)
-{
- int32_t result = 1;
-
- result = f->stream->read(f->stream->user_data, data, size);
-
- f->current_position += size;
-
- return result;
-}
-
-int32_t mp4ff_truncate(mp4ff_t * f)
-{
- return f->stream->truncate(f->stream->user_data);
-}
-
-int32_t mp4ff_write_data(mp4ff_t *f, int8_t *data, uint32_t size)
-{
- int32_t result = 1;
-
- result = f->stream->write(f->stream->user_data, data, size);
-
- f->current_position += size;
-
- return result;
-}
-
-int32_t mp4ff_write_int32(mp4ff_t *f,const uint32_t data)
-{
- uint32_t result;
- uint32_t a, b, c, d;
- int8_t temp[4];
-
- *(uint32_t*)temp = data;
- a = (uint8_t)temp[0];
- b = (uint8_t)temp[1];
- c = (uint8_t)temp[2];
- d = (uint8_t)temp[3];
-
- result = (a<<24) | (b<<16) | (c<<8) | d;
-
- return mp4ff_write_data(f,(uint8_t*)&result,sizeof(result));
-}
-
-int32_t mp4ff_set_position(mp4ff_t *f, const int64_t position)
-{
- f->stream->seek(f->stream->user_data, position);
- f->current_position = position;
-
- return 0;
-}
-
-int64_t mp4ff_position(const mp4ff_t *f)
-{
- return f->current_position;
-}
-
-uint64_t mp4ff_read_int64(mp4ff_t *f)
-{
- uint8_t data[8];
- uint64_t result = 0;
- int8_t i;
-
- mp4ff_read_data(f, data, 8);
-
- for (i = 0; i < 8; i++)
- {
- result |= ((uint64_t)data[i]) << ((7 - i) * 8);
- }
-
- return result;
-}
-
-uint32_t mp4ff_read_int32(mp4ff_t *f)
-{
- uint32_t result;
- uint32_t a, b, c, d;
- int8_t data[4];
-
- mp4ff_read_data(f, data, 4);
- a = (uint8_t)data[0];
- b = (uint8_t)data[1];
- c = (uint8_t)data[2];
- d = (uint8_t)data[3];
-
- result = (a<<24) | (b<<16) | (c<<8) | d;
- return (uint32_t)result;
-}
-
-uint32_t mp4ff_read_int24(mp4ff_t *f)
-{
- uint32_t result;
- uint32_t a, b, c;
- int8_t data[4];
-
- mp4ff_read_data(f, data, 3);
- a = (uint8_t)data[0];
- b = (uint8_t)data[1];
- c = (uint8_t)data[2];
-
- result = (a<<16) | (b<<8) | c;
- return (uint32_t)result;
-}
-
-uint16_t mp4ff_read_int16(mp4ff_t *f)
-{
- uint32_t result;
- uint32_t a, b;
- int8_t data[2];
-
- mp4ff_read_data(f, data, 2);
- a = (uint8_t)data[0];
- b = (uint8_t)data[1];
-
- result = (a<<8) | b;
- return (uint16_t)result;
-}
-
-char * mp4ff_read_string(mp4ff_t * f,uint32_t length)
-{
- char * str = (char*)malloc(length + 1);
- if (str!=0)
- {
- if ((uint32_t)mp4ff_read_data(f,str,length)!=length)
- {
- free(str);
- str = 0;
- }
- else
- {
- str[length] = 0;
- }
- }
- return str;
-}
-
-uint8_t mp4ff_read_char(mp4ff_t *f)
-{
- uint8_t output;
- mp4ff_read_data(f, &output, 1);
- return output;
-}
-
-uint32_t mp4ff_read_mp4_descr_length(mp4ff_t *f)
-{
- uint8_t b;
- uint8_t numBytes = 0;
- uint32_t length = 0;
-
- do
- {
- b = mp4ff_read_char(f);
- numBytes++;
- length = (length << 7) | (b & 0x7F);
- } while ((b & 0x80) && numBytes < 4);
-
- return length;
-}
diff --git a/trunk/src/mpd_types.h b/trunk/src/mpd_types.h
deleted file mode 100644
index dbdfc6865..000000000
--- a/trunk/src/mpd_types.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef MPD_TYPES_H
-#define MPD_TYPES_H
-
-#include "../config.h"
-
-typedef unsigned char mpd_uint8;
-typedef signed char mpd_sint8;
-
-#if SIZEOF_SHORT == 2
-typedef unsigned short mpd_uint16;
-typedef signed short mpd_sint16;
-#elif SIZEOF_INT == 2
-typedef unsigned int mpd_uint16;
-typedef signed int mpd_sint16;
-#endif
-
-#if SIZEOF_INT == 4
-typedef unsigned int mpd_uint32;
-typedef signed int mpd_sint32;
-#elif SIZEOF_LONG == 4
-typedef unsigned long mpd_uint32;
-typedef signed long mpd_sint32;
-#endif
-
-#endif
diff --git a/trunk/src/myfprintf.c b/trunk/src/myfprintf.c
deleted file mode 100644
index a09ae4324..000000000
--- a/trunk/src/myfprintf.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "myfprintf.h"
-#include "interface.h"
-#include "path.h"
-#include "log.h"
-#include "conf.h"
-#include "utils.h"
-
-#include <stdarg.h>
-#include <sys/param.h>
-#include <unistd.h>
-#include <sys/select.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-
-#define BUFFER_LENGTH MAXPATHLEN+1024
-
-static void blockingWrite(const int fd, const char *string, size_t len)
-{
- while (len) {
- ssize_t ret = xwrite(fd, string, len);
- if (ret == len)
- return;
- if (ret >= 0) {
- len -= ret;
- string += ret;
- continue;
- }
- return; /* error */
- }
-}
-
-void vfdprintf(const int fd, const char *fmt, va_list args)
-{
- static char buffer[BUFFER_LENGTH];
- char *buf = buffer;
- size_t len;
-
- vsnprintf(buf, BUFFER_LENGTH, fmt, args);
- len = strlen(buf);
- if (fd == STDERR_FILENO ||
- fd == STDOUT_FILENO ||
- interfacePrintWithFD(fd, buf, len) < 0)
- blockingWrite(fd, buf, len);
-}
-
-mpd_fprintf void fdprintf(const int fd, const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- vfdprintf(fd, fmt, args);
- va_end(args);
-}
-
diff --git a/trunk/src/myfprintf.h b/trunk/src/myfprintf.h
deleted file mode 100644
index 287902f9b..000000000
--- a/trunk/src/myfprintf.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef MYFPRINTF_H
-#define MYFPRINTF_H
-
-#include "../config.h"
-#include "gcc.h"
-
-#include <stdarg.h>
-#include <stdio.h>
-
-mpd_fprintf void fdprintf(const int fd, const char *fmt, ...);
-void vfdprintf(const int fd, const char *fmt, va_list arglist);
-
-#endif
diff --git a/trunk/src/normalize.c b/trunk/src/normalize.c
deleted file mode 100644
index fb62e7a4e..000000000
--- a/trunk/src/normalize.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "compress.h"
-#include "conf.h"
-#include "normalize.h"
-
-#include <stdlib.h>
-
-int normalizationEnabled;
-
-void initNormalization(void)
-{
- normalizationEnabled = getBoolConfigParam(CONF_VOLUME_NORMALIZATION);
- if (normalizationEnabled == -1) normalizationEnabled = 0;
- else if (normalizationEnabled < 0) exit(EXIT_FAILURE);
-
- if (normalizationEnabled)
- CompressCfg(0, ANTICLIP, TARGET, GAINMAX, GAINSMOOTH, BUCKETS);
-}
-
-void finishNormalization(void)
-{
- if (normalizationEnabled) CompressFree();
-}
-
-void normalizeData(char *buffer, int bufferSize, AudioFormat *format)
-{
- if ((format->bits != 16) || (format->channels != 2)) return;
-
- CompressDo(buffer, bufferSize);
-}
diff --git a/trunk/src/normalize.h b/trunk/src/normalize.h
deleted file mode 100644
index ddbefab08..000000000
--- a/trunk/src/normalize.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef NORMALIZE_H
-#define NORMALIZE_H
-
-#include "audio.h"
-
-extern int normalizationEnabled;
-
-void initNormalization(void);
-
-void finishNormalization(void);
-
-void normalizeData(char *buffer, int bufferSize, AudioFormat *format);
-
-#endif /* !NORMALIZE_H */
diff --git a/trunk/src/outputBuffer.c b/trunk/src/outputBuffer.c
deleted file mode 100644
index c7ff8b479..000000000
--- a/trunk/src/outputBuffer.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "outputBuffer.h"
-
-#include "pcm_utils.h"
-#include "playerData.h"
-#include "utils.h"
-#include "log.h"
-#include "normalize.h"
-#include "conf.h"
-
-#include <string.h>
-
-static mpd_sint16 currentChunk = -1;
-
-static mpd_sint8 currentMetaChunk = -1;
-static mpd_sint8 sendMetaChunk;
-
-void clearAllMetaChunkSets(OutputBuffer * cb)
-{
- memset(cb->metaChunkSet, 0, BUFFERED_METACHUNKS);
-}
-
-void clearOutputBuffer(OutputBuffer * cb)
-{
- int currentSet = 1;
-
- cb->end = cb->begin;
-
- /* be sure to reset metaChunkSets cause we are skipping over audio
- * audio chunks, and thus skipping over metadata */
- if (currentChunk >= 0 && sendMetaChunk == 0 && currentMetaChunk >= 0) {
- currentSet = cb->metaChunkSet[currentChunk];
- }
- clearAllMetaChunkSets(cb);
- if (currentChunk >= 0 && sendMetaChunk == 0 && currentMetaChunk >= 0) {
- cb->metaChunkSet[currentChunk] = currentSet;
- }
- currentChunk = -1;
-}
-
-void flushOutputBuffer(OutputBuffer * cb)
-{
- if (currentChunk == cb->end) {
- if ((cb->end + 1) >= buffered_chunks) {
- cb->end = 0;
- }
- else cb->end++;
- currentChunk = -1;
- }
-}
-
-int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
- DecoderControl * dc, int seekable, void *dataIn,
- long dataInLen, float time, mpd_uint16 bitRate,
- ReplayGainInfo * replayGainInfo)
-{
- mpd_uint16 dataToSend;
- mpd_uint16 chunkLeft;
- char *data;
- size_t datalen;
- static char *convBuffer;
- static long convBufferLen;
-
- if (cmpAudioFormat(&(cb->audioFormat), &(dc->audioFormat)) == 0) {
- data = dataIn;
- datalen = dataInLen;
- } else {
- datalen = pcm_sizeOfConvBuffer(&(dc->audioFormat), dataInLen,
- &(cb->audioFormat));
- if (datalen > convBufferLen) {
- convBuffer = xrealloc(convBuffer, datalen);
- convBufferLen = datalen;
- }
- data = convBuffer;
- datalen = pcm_convertAudioFormat(&(dc->audioFormat), dataIn,
- dataInLen, &(cb->audioFormat),
- data, &(cb->convState));
- }
-
- if (replayGainInfo && (replayGainState != REPLAYGAIN_OFF))
- doReplayGain(replayGainInfo, data, datalen, &cb->audioFormat);
- else if (normalizationEnabled)
- normalizeData(data, datalen, &cb->audioFormat);
-
- while (datalen) {
- if (currentChunk != cb->end) {
- int next = cb->end + 1;
- if (next >= buffered_chunks) {
- next = 0;
- }
- while (cb->begin == next && !dc->stop) {
- if (dc->seek) {
- if (seekable) {
- return OUTPUT_BUFFER_DC_SEEK;
- } else {
- dc->seekError = 1;
- dc->seek = 0;
- }
- }
- if (!inStream ||
- bufferInputStream(inStream) <= 0) {
- my_usleep(10000);
- }
- }
- if (dc->stop)
- return OUTPUT_BUFFER_DC_STOP;
-
- currentChunk = cb->end;
- cb->chunkSize[currentChunk] = 0;
-
- if (sendMetaChunk) {
- cb->metaChunk[currentChunk] = currentMetaChunk;
- } else
- cb->metaChunk[currentChunk] = -1;
- cb->bitRate[currentChunk] = bitRate;
- cb->times[currentChunk] = time;
- }
-
- chunkLeft = CHUNK_SIZE - cb->chunkSize[currentChunk];
- dataToSend = datalen > chunkLeft ? chunkLeft : datalen;
-
- memcpy(cb->chunks + currentChunk * CHUNK_SIZE +
- cb->chunkSize[currentChunk], data, dataToSend);
- cb->chunkSize[currentChunk] += dataToSend;
- datalen -= dataToSend;
- data += dataToSend;
-
- if (cb->chunkSize[currentChunk] == CHUNK_SIZE) {
- flushOutputBuffer(cb);
- }
- }
-
- return 0;
-}
-
-int copyMpdTagToOutputBuffer(OutputBuffer * cb, MpdTag * tag)
-{
- int nextChunk;
- static MpdTag *last;
-
- if (!cb->acceptMetadata || !tag) {
- sendMetaChunk = 0;
- if (last)
- freeMpdTag(last);
- last = NULL;
- DEBUG("copyMpdTagToOB: !acceptMetadata || !tag\n");
- return 0;
- }
-
- if (last && mpdTagsAreEqual(last, tag)) {
- DEBUG("copyMpdTagToOB: same as last\n");
- return 0;
- }
-
- if (last)
- freeMpdTag(last);
- last = NULL;
-
- nextChunk = currentMetaChunk + 1;
- if (nextChunk >= BUFFERED_METACHUNKS)
- nextChunk = 0;
-
- if (cb->metaChunkSet[nextChunk]) {
- sendMetaChunk = 0;
- DEBUG("copyMpdTagToOB: metachunk in use!\n");
- return -1;
- }
-
- sendMetaChunk = 1;
- currentMetaChunk = nextChunk;
-
- last = mpdTagDup(tag);
-
- copyMpdTagToMetadataChunk(tag, &(cb->metadataChunks[currentMetaChunk]));
-
- cb->metaChunkSet[nextChunk] = 1;
-
- DEBUG("copyMpdTagToOB: copiedTag\n");
-
- return 0;
-}
diff --git a/trunk/src/outputBuffer.h b/trunk/src/outputBuffer.h
deleted file mode 100644
index f690941d4..000000000
--- a/trunk/src/outputBuffer.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef OUTPUT_BUFFER_H
-#define OUTPUT_BUFFER_H
-
-#include "pcm_utils.h"
-#include "mpd_types.h"
-#include "decode.h"
-#include "audio.h"
-#include "inputStream.h"
-#include "metadataChunk.h"
-#include "replayGain.h"
-
-#define OUTPUT_BUFFER_DC_STOP -1
-#define OUTPUT_BUFFER_DC_SEEK -2
-
-#define BUFFERED_METACHUNKS 25
-
-typedef struct _OutputBuffer {
- char *volatile chunks;
- mpd_uint16 *volatile chunkSize;
- mpd_uint16 *volatile bitRate;
- float *volatile times;
- mpd_sint16 volatile begin;
- mpd_sint16 volatile end;
- AudioFormat audioFormat;
- ConvState convState;
- MetadataChunk metadataChunks[BUFFERED_METACHUNKS];
- mpd_sint8 metaChunkSet[BUFFERED_METACHUNKS];
- mpd_sint8 *volatile metaChunk;
- volatile mpd_sint8 acceptMetadata;
-} OutputBuffer;
-
-void clearOutputBuffer(OutputBuffer * cb);
-
-void flushOutputBuffer(OutputBuffer * cb);
-
-/* we send inStream for buffering the inputStream while waiting to
- send the next chunk */
-int sendDataToOutputBuffer(OutputBuffer * cb,
- InputStream * inStream,
- DecoderControl * dc,
- int seekable,
- void *data,
- long datalen,
- float time,
- mpd_uint16 bitRate, ReplayGainInfo * replayGainInfo);
-
-int copyMpdTagToOutputBuffer(OutputBuffer * cb, MpdTag * tag);
-
-void clearAllMetaChunkSets(OutputBuffer * cb);
-
-#endif
diff --git a/trunk/src/path.c b/trunk/src/path.c
deleted file mode 100644
index f30eb0793..000000000
--- a/trunk/src/path.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "path.h"
-#include "log.h"
-#include "charConv.h"
-#include "conf.h"
-#include "utf8.h"
-#include "utils.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include <dirent.h>
-
-#ifdef HAVE_LOCALE
-#ifdef HAVE_LANGINFO_CODESET
-#include <locale.h>
-#include <langinfo.h>
-#endif
-#endif
-
-const char *musicDir;
-static const char *playlistDir;
-static char *fsCharset;
-
-static char *pathConvCharset(char *to, char *from, char *str, char *ret)
-{
- if (ret)
- free(ret);
- return setCharSetConversion(to, from) ? NULL : convStrDup(str);
-}
-
-char *fsCharsetToUtf8(char *str)
-{
- static char *ret;
-
- ret = pathConvCharset("UTF-8", fsCharset, str, ret);
-
- if (ret && !validUtf8String(ret)) {
- free(ret);
- ret = NULL;
- }
-
- return ret;
-}
-
-char *utf8ToFsCharset(char *str)
-{
- static char *ret;
-
- ret = pathConvCharset(fsCharset, "UTF-8", str, ret);
-
- if (!ret)
- ret = xstrdup(str);
-
- return ret;
-}
-
-void setFsCharset(char *charset)
-{
- int error = 0;
-
- if (fsCharset)
- free(fsCharset);
-
- fsCharset = xstrdup(charset);
-
- DEBUG("setFsCharset: fs charset is: %s\n", fsCharset);
-
- if (setCharSetConversion("UTF-8", fsCharset) != 0) {
- WARNING("fs charset conversion problem: "
- "not able to convert from \"%s\" to \"%s\"\n",
- fsCharset, "UTF-8");
- error = 1;
- }
- if (setCharSetConversion(fsCharset, "UTF-8") != 0) {
- WARNING("fs charset conversion problem: "
- "not able to convert from \"%s\" to \"%s\"\n",
- "UTF-8", fsCharset);
- error = 1;
- }
-
- if (error) {
- free(fsCharset);
- WARNING("setting fs charset to ISO-8859-1!\n");
- fsCharset = xstrdup("ISO-8859-1");
- }
-}
-
-char *getFsCharset(void)
-{
- return fsCharset;
-}
-
-static char *appendSlash(char **path)
-{
- char *temp = *path;
- int len = strlen(temp);
-
- if (temp[len - 1] != '/') {
- temp = xmalloc(len + 2);
- memset(temp, 0, len + 2);
- memcpy(temp, *path, len);
- temp[len] = '/';
- free(*path);
- *path = temp;
- }
-
- return temp;
-}
-
-void initPaths(void)
-{
- ConfigParam *musicParam = parseConfigFilePath(CONF_MUSIC_DIR, 1);
- ConfigParam *playlistParam = parseConfigFilePath(CONF_PLAYLIST_DIR, 1);
- ConfigParam *fsCharsetParam = getConfigParam(CONF_FS_CHARSET);
-
- char *charset = NULL;
- char *originalLocale;
- DIR *dir;
-
- musicDir = appendSlash(&(musicParam->value));
- playlistDir = appendSlash(&(playlistParam->value));
-
- if ((dir = opendir(playlistDir)) == NULL) {
- FATAL("cannot open %s \"%s\" (config line %i): %s\n",
- CONF_PLAYLIST_DIR, playlistParam->value,
- playlistParam->line, strerror(errno));
- }
- closedir(dir);
-
- if ((dir = opendir(musicDir)) == NULL) {
- FATAL("cannot open %s \"%s\" (config line %i): %s\n",
- CONF_MUSIC_DIR, musicParam->value,
- musicParam->line, strerror(errno));
- }
- closedir(dir);
-
- if (fsCharsetParam) {
- charset = xstrdup(fsCharsetParam->value);
- }
-#ifdef HAVE_LOCALE
-#ifdef HAVE_LANGINFO_CODESET
- else if ((originalLocale = setlocale(LC_CTYPE, NULL))) {
- char *temp;
- char *currentLocale;
- originalLocale = xstrdup(originalLocale);
-
- if (!(currentLocale = setlocale(LC_CTYPE, ""))) {
- WARNING("problems setting current locale with "
- "setlocale()\n");
- } else {
- if (strcmp(currentLocale, "C") == 0 ||
- strcmp(currentLocale, "POSIX") == 0) {
- WARNING("current locale is \"%s\"\n",
- currentLocale);
- } else if ((temp = nl_langinfo(CODESET))) {
- charset = xstrdup(temp);
- } else
- WARNING
- ("problems getting charset for locale\n");
- if (!setlocale(LC_CTYPE, originalLocale)) {
- WARNING
- ("problems resetting locale with setlocale()\n");
- }
- }
-
- free(originalLocale);
- } else
- WARNING("problems getting locale with setlocale()\n");
-#endif
-#endif
-
- if (charset) {
- setFsCharset(charset);
- free(charset);
- } else {
- WARNING("setting filesystem charset to ISO-8859-1\n");
- setFsCharset("ISO-8859-1");
- }
-}
-
-void finishPaths(void)
-{
- free(fsCharset);
- fsCharset = NULL;
-}
-
-static char *pfx_path(const char *path, const char *pfx, const size_t pfx_len)
-{
- static char ret[MAXPATHLEN+1];
- size_t rp_len = strlen(path);
-
- /* check for the likely condition first: */
- if (mpd_likely((pfx_len + rp_len) < MAXPATHLEN)) {
- memcpy(ret, pfx, pfx_len);
- memcpy(ret + pfx_len, path, rp_len + 1);
- return ret;
- }
-
- /* unlikely, return an empty string because truncating would
- * also be wrong... break early and break loudly (the system
- * headers are likely screwed, not mpd) */
- ERROR("Cannot prefix '%s' to '%s', max: %d", pfx, path, MAXPATHLEN);
- ret[0] = '\0';
- return ret;
-}
-
-char *rmp2amp(char *relativePath)
-{
- size_t pfx_len = strlen(musicDir);
- return pfx_path(relativePath, musicDir, pfx_len);
-}
-
-char *rpp2app(char *relativePath)
-{
- size_t pfx_len = strlen(playlistDir);
- return pfx_path(relativePath, playlistDir, pfx_len);
-}
-
-/* this is actually like strlcpy (OpenBSD), but we don't actually want to
- * blindly use it everywhere, only for paths that are OK to truncate (for
- * error reporting and such */
-void pathcpy_trunc(char *dest, const char *src)
-{
- size_t len = strlen(src);
-
- if (mpd_unlikely(len > MAXPATHLEN))
- len = MAXPATHLEN;
- memcpy(dest, src, len);
- dest[len] = '\0';
-}
-
-char *parentPath(char *path)
-{
- static char parentPath[MAXPATHLEN+1];
- char *c;
-
- pathcpy_trunc(parentPath, path);
- c = strrchr(parentPath,'/');
-
- if (c == NULL)
- parentPath[0] = '\0';
- else {
- while ((parentPath <= c) && *(--c) == '/') /* nothing */
- ;
- c[1] = '\0';
- }
-
- return parentPath;
-}
-
-char *sanitizePathDup(char *path)
-{
- int len = strlen(path) + 1;
- char *ret = xmalloc(len);
- char *cp = ret;
-
- memset(ret, 0, len);
-
- len = 0;
-
- /* eliminate more than one '/' in a row, like "///" */
- while (*path) {
- while (*path == '/')
- path++;
- if (*path == '.') {
- /* we don't want to have hidden directories, or '.' or
- ".." in our path */
- free(ret);
- return NULL;
- }
- while (*path && *path != '/') {
- *(cp++) = *(path++);
- len++;
- }
- if (*path == '/') {
- *(cp++) = *(path++);
- len++;
- }
- }
-
- if (len && ret[len - 1] == '/') {
- len--;
- ret[len] = '\0';
- }
-
- DEBUG("sanitized: %s\n", ret);
-
- return xrealloc(ret, len + 1);
-}
diff --git a/trunk/src/path.h b/trunk/src/path.h
deleted file mode 100644
index 2357aa25d..000000000
--- a/trunk/src/path.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef PATH_H
-#define PATH_H
-
-#include "../config.h"
-
-#include <sys/param.h>
-
-extern const char *musicDir;
-
-void initPaths(void);
-
-void finishPaths(void);
-
-/* utf8ToFsCharset() and fsCharsetToUtf8()
- * Each returns a static pointer to a dynamically allocated buffer
- * which means:
- * - Do not manually free the return value of these functions, it'll be
- * automatically freed the next time it is called.
- * - They are not reentrant, xstrdup the return value immediately if
- * you expect to call one of these functions again, but still need the
- * previous result.
- * - The static pointer is unique to each function.
- */
-char *utf8ToFsCharset(char *str);
-char *fsCharsetToUtf8(char *str);
-
-void setFsCharset(char *charset);
-
-char *getFsCharset(void);
-
-/* relative music path to absolute music path
- * char * passed is a static variable, so don't free it
- */
-char *rmp2amp(char *file);
-
-/* static char * returned */
-char *rpp2app(char *file);
-
-/* static char * returned */
-char *parentPath(char *path);
-
-/* strips extra "///" and leading "/" and trailing "/" */
-char *sanitizePathDup(char *path);
-
-/* this is actually like strlcpy (OpenBSD), but we don't actually want to
- * blindly use it everywhere, only for paths that are OK to truncate (for
- * error reporting and such.
- * dest must be MAXPATHLEN+1 bytes large (which is standard in mpd) */
-void pathcpy_trunc(char *dest, const char *src);
-
-#endif
diff --git a/trunk/src/pcm_utils.c b/trunk/src/pcm_utils.c
deleted file mode 100644
index 534095620..000000000
--- a/trunk/src/pcm_utils.c
+++ /dev/null
@@ -1,470 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "pcm_utils.h"
-
-#include "mpd_types.h"
-#include "log.h"
-#include "utils.h"
-#include "conf.h"
-
-#include <string.h>
-#include <math.h>
-#include <assert.h>
-
-void pcm_volumeChange(char *buffer, int bufferSize, AudioFormat * format,
- int volume)
-{
- mpd_sint32 temp32;
- mpd_sint8 *buffer8 = (mpd_sint8 *) buffer;
- mpd_sint16 *buffer16 = (mpd_sint16 *) buffer;
-
- if (volume >= 1000)
- return;
-
- if (volume <= 0) {
- memset(buffer, 0, bufferSize);
- return;
- }
-
- switch (format->bits) {
- case 16:
- while (bufferSize > 0) {
- temp32 = *buffer16;
- temp32 *= volume;
- temp32 += rand() & 511;
- temp32 -= rand() & 511;
- temp32 += 500;
- temp32 /= 1000;
- *buffer16 = temp32 > 32767 ? 32767 :
- (temp32 < -32768 ? -32768 : temp32);
- buffer16++;
- bufferSize -= 2;
- }
- break;
- case 8:
- while (bufferSize > 0) {
- temp32 = *buffer8;
- temp32 *= volume;
- temp32 += rand() & 511;
- temp32 -= rand() & 511;
- temp32 += 500;
- temp32 /= 1000;
- *buffer8 = temp32 > 127 ? 127 :
- (temp32 < -128 ? -128 : temp32);
- buffer8++;
- bufferSize--;
- }
- break;
- default:
- FATAL("%i bits not supported by pcm_volumeChange!\n",
- format->bits);
- }
-}
-
-static void pcm_add(char *buffer1, char *buffer2, size_t bufferSize1,
- size_t bufferSize2, int vol1, int vol2,
- AudioFormat * format)
-{
- mpd_sint32 temp32;
- mpd_sint8 *buffer8_1 = (mpd_sint8 *) buffer1;
- mpd_sint8 *buffer8_2 = (mpd_sint8 *) buffer2;
- mpd_sint16 *buffer16_1 = (mpd_sint16 *) buffer1;
- mpd_sint16 *buffer16_2 = (mpd_sint16 *) buffer2;
-
- switch (format->bits) {
- case 16:
- while (bufferSize1 > 0 && bufferSize2 > 0) {
- temp32 =
- (vol1 * (*buffer16_1) +
- vol2 * (*buffer16_2));
- temp32 += rand() & 511;
- temp32 -= rand() & 511;
- temp32 += 500;
- temp32 /= 1000;
- *buffer16_1 =
- temp32 > 32767 ? 32767 : (temp32 <
- -32768 ? -32768 : temp32);
- buffer16_1++;
- buffer16_2++;
- bufferSize1 -= 2;
- bufferSize2 -= 2;
- }
- if (bufferSize2 > 0)
- memcpy(buffer16_1, buffer16_2, bufferSize2);
- break;
- case 8:
- while (bufferSize1 > 0 && bufferSize2 > 0) {
- temp32 =
- (vol1 * (*buffer8_1) + vol2 * (*buffer8_2));
- temp32 += rand() & 511;
- temp32 -= rand() & 511;
- temp32 += 500;
- temp32 /= 1000;
- *buffer8_1 =
- temp32 > 127 ? 127 : (temp32 <
- -128 ? -128 : temp32);
- buffer8_1++;
- buffer8_2++;
- bufferSize1--;
- bufferSize2--;
- }
- if (bufferSize2 > 0)
- memcpy(buffer8_1, buffer8_2, bufferSize2);
- break;
- default:
- FATAL("%i bits not supported by pcm_add!\n", format->bits);
- }
-}
-
-void pcm_mix(char *buffer1, char *buffer2, size_t bufferSize1,
- size_t bufferSize2, AudioFormat * format, float portion1)
-{
- int vol1;
- float s = sin(M_PI_2 * portion1);
- s *= s;
-
- vol1 = s * 1000 + 0.5;
- vol1 = vol1 > 1000 ? 1000 : (vol1 < 0 ? 0 : vol1);
-
- pcm_add(buffer1, buffer2, bufferSize1, bufferSize2, vol1, 1000 - vol1,
- format);
-}
-
-#ifdef HAVE_LIBSAMPLERATE
-static int pcm_getSampleRateConverter(void)
-{
- const char *conf = getConfigParamValue(CONF_SAMPLERATE_CONVERTER);
- long convalgo;
- char *test;
- size_t len;
-
- if (!conf) {
- convalgo = SRC_SINC_FASTEST;
- goto out;
- }
-
- convalgo = strtol(conf, &test, 10);
- if (*test == '\0' && src_get_name(convalgo))
- goto out;
-
- len = strlen(conf);
- for (convalgo = 0 ; ; convalgo++) {
- test = (char *)src_get_name(convalgo);
- if (!test) {
- convalgo = SRC_SINC_FASTEST;
- break;
- }
- if (strncasecmp(test, conf, len) == 0)
- goto out;
- }
-
- ERROR("unknown samplerate converter \"%s\"\n", conf);
-out:
- DEBUG("selecting samplerate converter \"%s\"\n",
- src_get_name(convalgo));
-
- return convalgo;
-}
-#endif
-
-#ifdef HAVE_LIBSAMPLERATE
-static size_t pcm_convertSampleRate(mpd_sint8 channels, mpd_uint32 inSampleRate,
- char *inBuffer, size_t inSize,
- mpd_uint32 outSampleRate, char *outBuffer,
- size_t outSize, ConvState *convState)
-{
- static int convalgo = -1;
- SRC_DATA *data = &convState->data;
- size_t dataInSize;
- size_t dataOutSize;
- int error;
-
- if (convalgo < 0)
- convalgo = pcm_getSampleRateConverter();
-
- /* (re)set the state/ratio if the in or out format changed */
- if ((channels != convState->lastChannels) ||
- (inSampleRate != convState->lastInSampleRate) ||
- (outSampleRate != convState->lastOutSampleRate)) {
- convState->error = 0;
- convState->lastChannels = channels;
- convState->lastInSampleRate = inSampleRate;
- convState->lastOutSampleRate = outSampleRate;
-
- if (convState->state)
- convState->state = src_delete(convState->state);
-
- convState->state = src_new(convalgo, channels, &error);
- if (!convState->state) {
- ERROR("cannot create new libsamplerate state: %s\n",
- src_strerror(error));
- convState->error = 1;
- return 0;
- }
-
- data->src_ratio = (double)outSampleRate / (double)inSampleRate;
- DEBUG("setting samplerate conversion ratio to %.2lf\n",
- data->src_ratio);
- src_set_ratio(convState->state, data->src_ratio);
- }
-
- /* there was an error previously, and nothing has changed */
- if (convState->error)
- return 0;
-
- data->input_frames = inSize / 2 / channels;
- dataInSize = data->input_frames * sizeof(float) * channels;
- if (dataInSize > convState->dataInSize) {
- convState->dataInSize = dataInSize;
- data->data_in = xrealloc(data->data_in, dataInSize);
- }
-
- data->output_frames = outSize / 2 / channels;
- dataOutSize = data->output_frames * sizeof(float) * channels;
- if (dataOutSize > convState->dataOutSize) {
- convState->dataOutSize = dataOutSize;
- data->data_out = xrealloc(data->data_out, dataOutSize);
- }
-
- src_short_to_float_array((short *)inBuffer, data->data_in,
- data->input_frames * channels);
-
- error = src_process(convState->state, data);
- if (error) {
- ERROR("error processing samples with libsamplerate: %s\n",
- src_strerror(error));
- convState->error = 1;
- return 0;
- }
-
- src_float_to_short_array(data->data_out, (short *)outBuffer,
- data->output_frames_gen * channels);
-
- return data->output_frames_gen * 2 * channels;
-}
-#else /* !HAVE_LIBSAMPLERATE */
-/* resampling code blatantly ripped from ESD */
-static size_t pcm_convertSampleRate(mpd_sint8 channels, mpd_uint32 inSampleRate,
- char *inBuffer, size_t inSize,
- mpd_uint32 outSampleRate, char *outBuffer,
- size_t outSize, ConvState *convState)
-{
- mpd_uint32 rd_dat = 0;
- mpd_uint32 wr_dat = 0;
- mpd_sint16 *in = (mpd_sint16 *)inBuffer;
- mpd_sint16 *out = (mpd_sint16 *)outBuffer;
- mpd_uint32 nlen = outSize / 2;
- mpd_sint16 lsample, rsample;
-
- switch (channels) {
- case 1:
- while (wr_dat < nlen) {
- rd_dat = wr_dat * inSampleRate / outSampleRate;
-
- lsample = in[rd_dat++];
-
- out[wr_dat++] = lsample;
- }
- break;
- case 2:
- while (wr_dat < nlen) {
- rd_dat = wr_dat * inSampleRate / outSampleRate;
- rd_dat &= ~1;
-
- lsample = in[rd_dat++];
- rsample = in[rd_dat++];
-
- out[wr_dat++] = lsample;
- out[wr_dat++] = rsample;
- }
- break;
- }
-
- return outSize;
-}
-#endif /* !HAVE_LIBSAMPLERATE */
-
-static char *pcm_convertChannels(mpd_sint8 channels, char *inBuffer,
- size_t inSize, size_t *outSize)
-{
- static char *buf;
- static size_t len;
- char *outBuffer = NULL;;
- mpd_sint16 *in;
- mpd_sint16 *out;
- int inSamples, i;
-
- switch (channels) {
- /* convert from 1 -> 2 channels */
- case 1:
- *outSize = (inSize >> 1) << 2;
- if (*outSize > len) {
- len = *outSize;
- buf = xrealloc(buf, len);
- }
- outBuffer = buf;
-
- inSamples = inSize >> 1;
- in = (mpd_sint16 *)inBuffer;
- out = (mpd_sint16 *)outBuffer;
- for (i = 0; i < inSamples; i++) {
- *out++ = *in;
- *out++ = *in++;
- }
-
- break;
- /* convert from 2 -> 1 channels */
- case 2:
- *outSize = inSize >> 1;
- if (*outSize > len) {
- len = *outSize;
- buf = xrealloc(buf, len);
- }
- outBuffer = buf;
-
- inSamples = inSize >> 2;
- in = (mpd_sint16 *)inBuffer;
- out = (mpd_sint16 *)outBuffer;
- for (i = 0; i < inSamples; i++) {
- *out = (*in++) / 2;
- *out++ += (*in++) / 2;
- }
-
- break;
- default:
- ERROR("only 1 or 2 channels are supported for conversion!\n");
- }
-
- return outBuffer;
-}
-
-static char *pcm_convertTo16bit(mpd_sint8 bits, char *inBuffer, size_t inSize,
- size_t *outSize)
-{
- static char *buf;
- static size_t len;
- char *outBuffer = NULL;
- mpd_sint8 *in;
- mpd_sint16 *out;
- int i;
-
- switch (bits) {
- case 8:
- *outSize = inSize << 1;
- if (*outSize > len) {
- len = *outSize;
- buf = xrealloc(buf, len);
- }
- outBuffer = buf;
-
- in = (mpd_sint8 *)inBuffer;
- out = (mpd_sint16 *)outBuffer;
- for (i = 0; i < inSize; i++)
- *out++ = (*in++) << 8;
-
- break;
- case 16:
- *outSize = inSize;
- outBuffer = inBuffer;
- break;
- case 24:
- /* put dithering code from mp3_decode here */
- default:
- ERROR("only 8 or 16 bits are supported for conversion!\n");
- }
-
- return outBuffer;
-}
-
-/* outFormat bits must be 16 and channels must be 1 or 2! */
-size_t pcm_convertAudioFormat(AudioFormat * inFormat, char *inBuffer,
- size_t inSize, AudioFormat * outFormat,
- char *outBuffer, ConvState *convState)
-{
- char *buf;
- size_t len;
- size_t outSize = pcm_sizeOfConvBuffer(inFormat, inSize, outFormat);
-
- assert(outFormat->bits == 16);
- assert(outFormat->channels == 2 || outFormat->channels == 1);
-
- /* everything else supports 16 bit only, so convert to that first */
- buf = pcm_convertTo16bit(inFormat->bits, inBuffer, inSize, &len);
- if (!buf)
- exit(EXIT_FAILURE);
-
- if (inFormat->channels != outFormat->channels) {
- buf = pcm_convertChannels(inFormat->channels, buf, len, &len);
- if (!buf)
- exit(EXIT_FAILURE);
- }
-
- if (inFormat->sampleRate == outFormat->sampleRate) {
- assert(outSize >= len);
- memcpy(outBuffer, buf, len);
- } else {
- len = pcm_convertSampleRate(outFormat->channels,
- inFormat->sampleRate, buf, len,
- outFormat->sampleRate, outBuffer,
- outSize, convState);
- if (len == 0)
- exit(EXIT_FAILURE);
- }
-
- return len;
-}
-
-size_t pcm_sizeOfConvBuffer(AudioFormat * inFormat, size_t inSize,
- AudioFormat * outFormat)
-{
- const double ratio = (double)outFormat->sampleRate /
- (double)inFormat->sampleRate;
- const int shift = 2 * outFormat->channels;
- size_t outSize = inSize;
-
- switch (inFormat->bits) {
- case 8:
- outSize <<= 1;
- break;
- case 16:
- break;
- default:
- FATAL("only 8 or 16 bits are supported for conversion!\n");
- }
-
- if (inFormat->channels != outFormat->channels) {
- switch (inFormat->channels) {
- case 1:
- outSize = (outSize >> 1) << 2;
- break;
- case 2:
- outSize >>= 1;
- break;
- default:
- FATAL("only 1 or 2 channels are supported "
- "for conversion!\n");
- }
- }
-
- outSize /= shift;
- outSize = floor(0.5 + (double)outSize * ratio);
- outSize *= shift;
-
- return outSize;
-}
diff --git a/trunk/src/pcm_utils.h b/trunk/src/pcm_utils.h
deleted file mode 100644
index 2c6610a75..000000000
--- a/trunk/src/pcm_utils.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef PCM_UTILS_H
-#define PCM_UTILS_H
-
-#include "../config.h"
-
-#include "audio.h"
-
-#include <stdlib.h>
-
-#ifdef HAVE_LIBSAMPLERATE
-#include <samplerate.h>
-#endif
-
-typedef struct _ConvState {
-#ifdef HAVE_LIBSAMPLERATE
- SRC_STATE *state;
- SRC_DATA data;
- size_t dataInSize;
- size_t dataOutSize;
- mpd_sint8 lastChannels;
- mpd_sint32 lastInSampleRate;
- mpd_sint32 lastOutSampleRate;
- int error;
-#endif
-} ConvState;
-
-void pcm_volumeChange(char *buffer, int bufferSize, AudioFormat * format,
- int volume);
-
-void pcm_mix(char *buffer1, char *buffer2, size_t bufferSize1,
- size_t bufferSize2, AudioFormat * format, float portion1);
-
-size_t pcm_convertAudioFormat(AudioFormat * inFormat, char *inBuffer,
- size_t inSize, AudioFormat * outFormat,
- char *outBuffer, ConvState *convState);
-
-size_t pcm_sizeOfConvBuffer(AudioFormat * inFormat, size_t inSize,
- AudioFormat * outFormat);
-#endif
diff --git a/trunk/src/permission.c b/trunk/src/permission.c
deleted file mode 100644
index 3d597052c..000000000
--- a/trunk/src/permission.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "permission.h"
-
-#include "conf.h"
-#include "list.h"
-#include "log.h"
-#include "utils.h"
-
-#include <string.h>
-
-#define PERMISSION_PASSWORD_CHAR "@"
-#define PERMISSION_SEPERATOR ","
-
-#define PERMISSION_READ_STRING "read"
-#define PERMISSION_ADD_STRING "add"
-#define PERMISSION_CONTROL_STRING "control"
-#define PERMISSION_ADMIN_STRING "admin"
-
-static List *permission_passwords;
-
-static int permission_default;
-
-static int parsePermissions(char *string)
-{
- int permission = 0;
- char *temp;
- char *tok;
-
- if (!string)
- return 0;
-
- temp = strtok_r(string, PERMISSION_SEPERATOR, &tok);
- while (temp) {
- if (strcmp(temp, PERMISSION_READ_STRING) == 0) {
- permission |= PERMISSION_READ;
- } else if (strcmp(temp, PERMISSION_ADD_STRING) == 0) {
- permission |= PERMISSION_ADD;
- } else if (strcmp(temp, PERMISSION_CONTROL_STRING) == 0) {
- permission |= PERMISSION_CONTROL;
- } else if (strcmp(temp, PERMISSION_ADMIN_STRING) == 0) {
- permission |= PERMISSION_ADMIN;
- } else {
- FATAL("unknown permission \"%s\"\n", temp);
- }
-
- temp = strtok_r(NULL, PERMISSION_SEPERATOR, &tok);
- }
-
- return permission;
-}
-
-void initPermissions(void)
-{
- char *temp;
- char *cp2;
- char *password;
- int *permission;
- ConfigParam *param;
-
- permission_passwords = makeList(free, 1);
-
- permission_default = PERMISSION_READ | PERMISSION_ADD |
- PERMISSION_CONTROL | PERMISSION_ADMIN;
-
- param = getNextConfigParam(CONF_PASSWORD, NULL);
-
- if (param) {
- permission_default = 0;
-
- do {
- if (!strstr(param->value, PERMISSION_PASSWORD_CHAR)) {
- FATAL("\"%s\" not found in password string "
- "\"%s\", line %i\n",
- PERMISSION_PASSWORD_CHAR,
- param->value, param->line);
- }
-
- if (!(temp = strtok_r(param->value,
- PERMISSION_PASSWORD_CHAR,
- &cp2))) {
- FATAL("something weird just happened in permission.c\n");
- }
-
- password = temp;
-
- permission = xmalloc(sizeof(int));
- *permission =
- parsePermissions(strtok_r(NULL, "", &cp2));
-
- insertInList(permission_passwords, password,
- permission);
- } while ((param = getNextConfigParam(CONF_PASSWORD, param)));
- }
-
- param = getConfigParam(CONF_DEFAULT_PERMS);
-
- if (param)
- permission_default = parsePermissions(param->value);
-
- sortList(permission_passwords);
-}
-
-int getPermissionFromPassword(char *password, int *permission)
-{
- void *foundPermission;
-
- if (findInList(permission_passwords, password, &foundPermission)) {
- *permission = *((int *)foundPermission);
- return 0;
- }
-
- return -1;
-}
-
-void finishPermissions(void)
-{
- freeList(permission_passwords);
-}
-
-int getDefaultPermissions(void)
-{
- return permission_default;
-}
diff --git a/trunk/src/permission.h b/trunk/src/permission.h
deleted file mode 100644
index bd4257080..000000000
--- a/trunk/src/permission.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef PERMISSION_H
-#define PERMISSION_H
-
-#include "../config.h"
-
-#define PERMISSION_NONE 0
-#define PERMISSION_READ 1
-#define PERMISSION_ADD 2
-#define PERMISSION_CONTROL 4
-#define PERMISSION_ADMIN 8
-
-
-int getPermissionFromPassword(char *password, int *permission);
-
-void finishPermissions(void);
-
-int getDefaultPermissions(void);
-
-void initPermissions(void);
-
-#endif
diff --git a/trunk/src/player.c b/trunk/src/player.c
deleted file mode 100644
index 7c92d088e..000000000
--- a/trunk/src/player.c
+++ /dev/null
@@ -1,530 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "player.h"
-#include "path.h"
-#include "decode.h"
-#include "command.h"
-#include "interface.h"
-#include "playlist.h"
-#include "ls.h"
-#include "listen.h"
-#include "log.h"
-#include "utils.h"
-#include "directory.h"
-#include "volume.h"
-#include "playerData.h"
-#include "permission.h"
-#include "sig_handlers.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-
-volatile int player_pid = 0;
-
-void clearPlayerPid(void)
-{
- player_pid = 0;
-}
-
-static void resetPlayerMetadata(void)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- if (pc->metadataState == PLAYER_METADATA_STATE_READ) {
- pc->metadataState = PLAYER_METADATA_STATE_WRITE;
- }
-}
-
-static void resetPlayer(void)
-{
- int pid;
-
- clearPlayerPid();
- getPlayerData()->playerControl.stop = 0;
- getPlayerData()->playerControl.play = 0;
- getPlayerData()->playerControl.pause = 0;
- getPlayerData()->playerControl.lockQueue = 0;
- getPlayerData()->playerControl.unlockQueue = 0;
- getPlayerData()->playerControl.state = PLAYER_STATE_STOP;
- getPlayerData()->playerControl.queueState = PLAYER_QUEUE_UNLOCKED;
- getPlayerData()->playerControl.seek = 0;
- getPlayerData()->playerControl.metadataState =
- PLAYER_METADATA_STATE_WRITE;
- pid = getPlayerData()->playerControl.decode_pid;
- if (pid > 0)
- kill(pid, SIGTERM);
- getPlayerData()->playerControl.decode_pid = 0;
-}
-
-void player_sigChldHandler(int pid, int status)
-{
- if (player_pid == pid)
- {
- DEBUG("SIGCHLD caused by player process\n");
- if (WIFSIGNALED(status) &&
- WTERMSIG(status) != SIGTERM &&
- WTERMSIG(status) != SIGINT)
- {
- ERROR("player process died from signal: %i\n",
- WTERMSIG(status));
- }
- resetPlayer();
- }
- else if (pid == getPlayerData()->playerControl.decode_pid &&
- player_pid <= 0)
- {
- if (WIFSIGNALED(status) && WTERMSIG(status) != SIGTERM)
- {
- ERROR("(caught by master parent) "
- "decode process died from a "
- "non-TERM signal: %i\n", WTERMSIG(status));
- }
- getPlayerData()->playerControl.decode_pid = 0;
- }
-}
-
-int playerInit(void)
-{
- blockSignals();
- player_pid = fork();
- if (player_pid==0)
- {
- clock_t start = clock();
-
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- unblockSignals();
-
- setSigHandlersForDecoder();
-
- closeAllListenSockets();
- freeAllInterfaces();
- finishPlaylist();
- closeMp3Directory();
- finishPermissions();
- finishCommands();
- finishVolume();
-
- DEBUG("took %f to init player\n",
- (float)(clock()-start)/CLOCKS_PER_SEC);
-
- while (1) {
- if (pc->play)
- decode();
- else if (pc->stop)
- pc->stop = 0;
- else if (pc->seek)
- pc->seek = 0;
- else if (pc->pause)
- pc->pause = 0;
- else if (pc->closeAudio) {
- closeAudioDevice();
- pc->closeAudio = 0;
- kill(getppid(), SIGUSR1);
- } else if (pc->lockQueue) {
- pc->queueLockState = PLAYER_QUEUE_LOCKED;
- pc->lockQueue = 0;
- } else if (pc->unlockQueue) {
- pc->queueLockState = PLAYER_QUEUE_UNLOCKED;
- pc->unlockQueue = 0;
- } else if (pc->cycleLogFiles) {
- cycle_log_files();
- pc->cycleLogFiles = 0;
- } else
- my_usleep(10000);
- }
-
- exit(EXIT_SUCCESS);
- }
- else if (player_pid < 0)
- {
- unblockSignals();
- ERROR("player Problems fork()'ing\n");
- player_pid = 0;
- return -1;
- }
-
- unblockSignals();
-
- return 0;
-}
-
-int playerPlay(int fd, Song * song)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- if (playerStop(fd) < 0)
- return -1;
-
- if (song->tag)
- pc->fileTime = song->tag->time;
- else
- pc->fileTime = 0;
-
- copyMpdTagToMetadataChunk(song->tag, &(pc->fileMetadataChunk));
-
- pathcpy_trunc(pc->utf8url, getSongUrl(song));
-
- pc->play = 1;
- if (player_pid == 0 && playerInit() < 0) {
- pc->play = 0;
- return -1;
- }
-
- resetPlayerMetadata();
- while (player_pid > 0 && pc->play)
- my_usleep(1000);
-
- return 0;
-}
-
-int playerStop(int fd)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- if (player_pid > 0 && pc->state != PLAYER_STATE_STOP) {
- pc->stop = 1;
- while (player_pid > 0 && pc->stop)
- my_usleep(1000);
- }
-
- pc->queueState = PLAYER_QUEUE_BLANK;
- playerQueueUnlock();
-
- return 0;
-}
-
-void playerKill(void)
-{
- int pid;
- /*PlayerControl * pc = &(getPlayerData()->playerControl);
-
- playerStop(stderr);
- playerCloseAudio(stderr);
- if(player_pid>0 && pc->closeAudio) sleep(1); */
-
- pid = player_pid;
- if (pid > 0)
- kill(pid, SIGTERM);
-}
-
-int playerPause(int fd)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- if (player_pid > 0 && pc->state != PLAYER_STATE_STOP) {
- pc->pause = 1;
- while (player_pid > 0 && pc->pause)
- my_usleep(1000);
- }
-
- return 0;
-}
-
-int playerSetPause(int fd, int pause)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- if (player_pid <= 0)
- return 0;
-
- switch (pc->state) {
- case PLAYER_STATE_PLAY:
- if (pause)
- playerPause(fd);
- break;
- case PLAYER_STATE_PAUSE:
- if (!pause)
- playerPause(fd);
- break;
- }
-
- return 0;
-}
-
-int getPlayerElapsedTime(void)
-{
- return (int)(getPlayerData()->playerControl.elapsedTime + 0.5);
-}
-
-unsigned long getPlayerBitRate(void)
-{
- return getPlayerData()->playerControl.bitRate;
-}
-
-int getPlayerTotalTime(void)
-{
- return (int)(getPlayerData()->playerControl.totalTime + 0.5);
-}
-
-int getPlayerState(void)
-{
- return getPlayerData()->playerControl.state;
-}
-
-void clearPlayerError(void)
-{
- getPlayerData()->playerControl.error = 0;
-}
-
-int getPlayerError(void)
-{
- return getPlayerData()->playerControl.error;
-}
-
-char *getPlayerErrorStr(void)
-{
- static char *error;
- int errorlen = MAXPATHLEN + 1024;
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- error = xrealloc(error, errorlen);
- error[0] = '\0';
-
- switch (pc->error) {
- case PLAYER_ERROR_FILENOTFOUND:
- snprintf(error, errorlen,
- "file \"%s\" does not exist or is inaccessible",
- pc->erroredUrl);
- break;
- case PLAYER_ERROR_FILE:
- snprintf(error, errorlen, "problems decoding \"%s\"",
- pc->erroredUrl);
- break;
- case PLAYER_ERROR_AUDIO:
- snprintf(error, errorlen, "problems opening audio device");
- break;
- case PLAYER_ERROR_SYSTEM:
- snprintf(error, errorlen, "system error occured");
- break;
- case PLAYER_ERROR_UNKTYPE:
- snprintf(error, errorlen, "file type of \"%s\" is unknown",
- pc->erroredUrl);
- default:
- break;
- }
-
- errorlen = strlen(error);
- error = xrealloc(error, errorlen + 1);
-
- if (errorlen)
- return error;
-
- return NULL;
-}
-
-void playerCloseAudio(void)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- if (player_pid > 0) {
- if (playerStop(STDERR_FILENO) < 0)
- return;
- pc->closeAudio = 1;
- }
-}
-
-int queueSong(Song * song)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- if (pc->queueState == PLAYER_QUEUE_BLANK) {
- pathcpy_trunc(pc->utf8url, getSongUrl(song));
-
- if (song->tag)
- pc->fileTime = song->tag->time;
- else
- pc->fileTime = 0;
-
- copyMpdTagToMetadataChunk(song->tag, &(pc->fileMetadataChunk));
-
- pc->queueState = PLAYER_QUEUE_FULL;
- return 0;
- }
-
- return -1;
-}
-
-int getPlayerQueueState(void)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- return pc->queueState;
-}
-
-void setQueueState(int queueState)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- pc->queueState = queueState;
-}
-
-void playerQueueLock(void)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- if (player_pid > 0 && pc->queueLockState == PLAYER_QUEUE_UNLOCKED) {
- pc->lockQueue = 1;
- while (player_pid > 0 && pc->lockQueue)
- my_usleep(1000);
- }
-}
-
-void playerQueueUnlock(void)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- if (player_pid > 0 && pc->queueLockState == PLAYER_QUEUE_LOCKED) {
- pc->unlockQueue = 1;
- while (player_pid > 0 && pc->unlockQueue)
- my_usleep(1000);
- }
-}
-
-int playerSeek(int fd, Song * song, float time)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- if (pc->state == PLAYER_STATE_STOP) {
- commandError(fd, ACK_ERROR_PLAYER_SYNC,
- "player not currently playing");
- return -1;
- }
-
- if (strcmp(pc->utf8url, getSongUrl(song)) != 0) {
- if (song->tag)
- pc->fileTime = song->tag->time;
- else
- pc->fileTime = 0;
-
- copyMpdTagToMetadataChunk(song->tag, &(pc->fileMetadataChunk));
-
- pathcpy_trunc(pc->utf8url, getSongUrl(song));
- }
-
- if (pc->error == PLAYER_ERROR_NOERROR) {
- resetPlayerMetadata();
- pc->seekWhere = time;
- pc->seek = 1;
- while (player_pid > 0 && pc->seek)
- my_usleep(1000);
- }
-
- return 0;
-}
-
-float getPlayerCrossFade(void)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- return pc->crossFade;
-}
-
-void setPlayerCrossFade(float crossFadeInSeconds)
-{
- PlayerControl *pc;
- if (crossFadeInSeconds < 0)
- crossFadeInSeconds = 0;
-
- pc = &(getPlayerData()->playerControl);
-
- pc->crossFade = crossFadeInSeconds;
-}
-
-void setPlayerSoftwareVolume(int volume)
-{
- PlayerControl *pc;
- volume = (volume > 1000) ? 1000 : (volume < 0 ? 0 : volume);
-
- pc = &(getPlayerData()->playerControl);
-
- pc->softwareVolume = volume;
-}
-
-double getPlayerTotalPlayTime(void)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- return pc->totalPlayTime;
-}
-
-unsigned int getPlayerSampleRate(void)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- return pc->sampleRate;
-}
-
-int getPlayerBits(void)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- return pc->bits;
-}
-
-int getPlayerChannels(void)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- return pc->channels;
-}
-
-void playerCycleLogFiles(void)
-{
- PlayerControl *pc = &(getPlayerData()->playerControl);
- DecoderControl *dc = &(getPlayerData()->decoderControl);
-
- pc->cycleLogFiles = 1;
- dc->cycleLogFiles = 1;
-}
-
-/* this actually creates a dupe of the current metadata */
-Song *playerCurrentDecodeSong(void)
-{
- static Song *song;
- static MetadataChunk *prev;
- Song *ret = NULL;
- PlayerControl *pc = &(getPlayerData()->playerControl);
-
- if (pc->metadataState == PLAYER_METADATA_STATE_READ) {
- DEBUG("playerCurrentDecodeSong: caught new metadata!\n");
- if (prev)
- free(prev);
- prev = xmalloc(sizeof(MetadataChunk));
- memcpy(prev, &(pc->metadataChunk), sizeof(MetadataChunk));
- if (song)
- freeJustSong(song);
- song = newNullSong();
- song->url = xstrdup(pc->currentUrl);
- song->tag = metadataChunkToMpdTagDup(prev);
- ret = song;
- resetPlayerMetadata();
- }
-
- return ret;
-}
diff --git a/trunk/src/player.h b/trunk/src/player.h
deleted file mode 100644
index b62fab2ea..000000000
--- a/trunk/src/player.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef PLAYER_H
-#define PLAYER_H
-
-#include "../config.h"
-
-#include "decode.h"
-#include "mpd_types.h"
-#include "song.h"
-#include "metadataChunk.h"
-
-#include <stdio.h>
-#include <sys/param.h>
-
-#define PLAYER_STATE_STOP 0
-#define PLAYER_STATE_PAUSE 1
-#define PLAYER_STATE_PLAY 2
-
-#define PLAYER_ERROR_NOERROR 0
-#define PLAYER_ERROR_FILE 1
-#define PLAYER_ERROR_AUDIO 2
-#define PLAYER_ERROR_SYSTEM 3
-#define PLAYER_ERROR_UNKTYPE 4
-#define PLAYER_ERROR_FILENOTFOUND 5
-
-/* 0->1->2->3->5 regular playback
- * ->4->0 don't play queued song
- */
-#define PLAYER_QUEUE_BLANK 0
-#define PLAYER_QUEUE_FULL 1
-#define PLAYER_QUEUE_DECODE 2
-#define PLAYER_QUEUE_PLAY 3
-#define PLAYER_QUEUE_STOP 4
-#define PLAYER_QUEUE_EMPTY 5
-
-#define PLAYER_QUEUE_UNLOCKED 0
-#define PLAYER_QUEUE_LOCKED 1
-
-#define PLAYER_METADATA_STATE_READ 1
-#define PLAYER_METADATA_STATE_WRITE 2
-
-typedef struct _PlayerControl {
- volatile mpd_sint8 stop;
- volatile mpd_sint8 play;
- volatile mpd_sint8 pause;
- volatile mpd_sint8 state;
- volatile mpd_sint8 closeAudio;
- volatile mpd_sint8 error;
- volatile mpd_uint16 bitRate;
- volatile mpd_sint8 bits;
- volatile mpd_sint8 channels;
- volatile mpd_uint32 sampleRate;
- volatile float totalTime;
- volatile float elapsedTime;
- volatile float fileTime;
- char utf8url[MAXPATHLEN + 1];
- char currentUrl[MAXPATHLEN + 1];
- char erroredUrl[MAXPATHLEN + 1];
- volatile mpd_sint8 queueState;
- volatile mpd_sint8 queueLockState;
- volatile mpd_sint8 lockQueue;
- volatile mpd_sint8 unlockQueue;
- volatile mpd_sint8 seek;
- volatile double seekWhere;
- volatile float crossFade;
- volatile mpd_uint16 softwareVolume;
- volatile double totalPlayTime;
- volatile int decode_pid;
- volatile mpd_sint8 cycleLogFiles;
- volatile mpd_sint8 metadataState;
- MetadataChunk metadataChunk;
- MetadataChunk fileMetadataChunk;
-} PlayerControl;
-
-void clearPlayerPid(void);
-
-void player_sigChldHandler(int pid, int status);
-
-int playerPlay(int fd, Song * song);
-
-int playerSetPause(int fd, int pause);
-
-int playerPause(int fd);
-
-int playerStop(int fd);
-
-void playerCloseAudio(void);
-
-void playerKill(void);
-
-int getPlayerTotalTime(void);
-
-int getPlayerElapsedTime(void);
-
-unsigned long getPlayerBitRate(void);
-
-int getPlayerState(void);
-
-void clearPlayerError(void);
-
-char *getPlayerErrorStr(void);
-
-int getPlayerError(void);
-
-int playerInit(void);
-
-int queueSong(Song * song);
-
-int getPlayerQueueState(void);
-
-void setQueueState(int queueState);
-
-void playerQueueLock(void);
-
-void playerQueueUnlock(void);
-
-int playerSeek(int fd, Song * song, float time);
-
-void setPlayerCrossFade(float crossFadeInSeconds);
-
-float getPlayerCrossFade(void);
-
-void setPlayerSoftwareVolume(int volume);
-
-double getPlayerTotalPlayTime(void);
-
-unsigned int getPlayerSampleRate(void);
-
-int getPlayerBits(void);
-
-int getPlayerChannels(void);
-
-void playerCycleLogFiles(void);
-
-Song *playerCurrentDecodeSong(void);
-
-#endif
diff --git a/trunk/src/playerData.c b/trunk/src/playerData.c
deleted file mode 100644
index 30ff6d6d6..000000000
--- a/trunk/src/playerData.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "playerData.h"
-#include "conf.h"
-#include "log.h"
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-int buffered_before_play;
-int buffered_chunks;
-
-#define DEFAULT_BUFFER_SIZE 2048
-#define DEFAULT_BUFFER_BEFORE_PLAY 10
-
-static PlayerData *playerData_pd;
-
-void initPlayerData(void)
-{
- float perc = DEFAULT_BUFFER_BEFORE_PLAY;
- char *test;
- int shmid;
- int crossfade = 0;
- size_t bufferSize = DEFAULT_BUFFER_SIZE;
- size_t allocationSize;
- OutputBuffer *buffer;
- ConfigParam *param;
- size_t device_array_size = audio_device_count() * sizeof(mpd_sint8);
-
- param = getConfigParam(CONF_AUDIO_BUFFER_SIZE);
-
- if (param) {
- bufferSize = strtol(param->value, &test, 10);
- if (*test != '\0' || bufferSize <= 0) {
- FATAL("buffer size \"%s\" is not a positive integer, "
- "line %i\n", param->value, param->line);
- }
- }
-
- bufferSize *= 1024;
-
- buffered_chunks = bufferSize / CHUNK_SIZE;
-
- if (buffered_chunks >= 1 << 15) {
- FATAL("buffer size \"%li\" is too big\n", (long)bufferSize);
- }
-
- param = getConfigParam(CONF_BUFFER_BEFORE_PLAY);
-
- if (param) {
- perc = strtod(param->value, &test);
- if (*test != '%' || perc < 0 || perc > 100) {
- FATAL("buffered before play \"%s\" is not a positive "
- "percentage and less than 100 percent, line %i"
- "\n", param->value, param->line);
- }
- }
-
- buffered_before_play = (perc / 100) * buffered_chunks;
- if (buffered_before_play > buffered_chunks) {
- buffered_before_play = buffered_chunks;
- } else if (buffered_before_play < 0)
- buffered_before_play = 0;
-
- allocationSize = buffered_chunks * CHUNK_SIZE; /*actual buffer */
- allocationSize += buffered_chunks * sizeof(float); /*for times */
- allocationSize += buffered_chunks * sizeof(mpd_sint16); /*for chunkSize */
- allocationSize += buffered_chunks * sizeof(mpd_sint16); /*for bitRate */
- allocationSize += buffered_chunks * sizeof(mpd_sint8); /*for metaChunk */
- allocationSize += sizeof(PlayerData); /*for playerData struct */
-
- /* for audioDeviceStates[] */
- allocationSize += device_array_size;
-
- if ((shmid = shmget(IPC_PRIVATE, allocationSize, IPC_CREAT | 0600)) < 0)
- FATAL("problems shmget'ing\n");
- if (!(playerData_pd = shmat(shmid, NULL, 0)))
- FATAL("problems shmat'ing\n");
- if (shmctl(shmid, IPC_RMID, NULL) < 0)
- FATAL("problems shmctl'ing\n");
-
- playerData_pd->audioDeviceStates = (mpd_uint8 *)playerData_pd +
- allocationSize - device_array_size;
- buffer = &(playerData_pd->buffer);
-
- memset(&buffer->convState, 0, sizeof(ConvState));
- buffer->chunks = ((char *)playerData_pd) + sizeof(PlayerData);
- buffer->chunkSize = (mpd_uint16 *) (((char *)buffer->chunks) +
- buffered_chunks * CHUNK_SIZE);
- buffer->bitRate = (mpd_uint16 *) (((char *)buffer->chunkSize) +
- buffered_chunks * sizeof(mpd_sint16));
- buffer->metaChunk = (mpd_sint8 *) (((char *)buffer->bitRate) +
- buffered_chunks *
- sizeof(mpd_sint16));
- buffer->times =
- (float *)(((char *)buffer->metaChunk) +
- buffered_chunks * sizeof(mpd_sint8));
- buffer->acceptMetadata = 0;
-
- playerData_pd->playerControl.stop = 0;
- playerData_pd->playerControl.pause = 0;
- playerData_pd->playerControl.play = 0;
- playerData_pd->playerControl.error = PLAYER_ERROR_NOERROR;
- playerData_pd->playerControl.lockQueue = 0;
- playerData_pd->playerControl.unlockQueue = 0;
- playerData_pd->playerControl.state = PLAYER_STATE_STOP;
- playerData_pd->playerControl.queueState = PLAYER_QUEUE_BLANK;
- playerData_pd->playerControl.queueLockState = PLAYER_QUEUE_UNLOCKED;
- playerData_pd->playerControl.seek = 0;
- playerData_pd->playerControl.closeAudio = 0;
- memset(playerData_pd->playerControl.utf8url, 0, MAXPATHLEN + 1);
- memset(playerData_pd->playerControl.erroredUrl, 0, MAXPATHLEN + 1);
- memset(playerData_pd->playerControl.currentUrl, 0, MAXPATHLEN + 1);
- playerData_pd->playerControl.crossFade = crossfade;
- playerData_pd->playerControl.softwareVolume = 1000;
- playerData_pd->playerControl.totalPlayTime = 0;
- playerData_pd->playerControl.decode_pid = 0;
- playerData_pd->playerControl.metadataState =
- PLAYER_METADATA_STATE_WRITE;
-
- playerData_pd->decoderControl.stop = 0;
- playerData_pd->decoderControl.start = 0;
- playerData_pd->decoderControl.state = DECODE_STATE_STOP;
- playerData_pd->decoderControl.seek = 0;
- playerData_pd->decoderControl.error = DECODE_ERROR_NOERROR;
- memset(playerData_pd->decoderControl.utf8url, 0, MAXPATHLEN + 1);
-}
-
-PlayerData *getPlayerData(void)
-{
- return playerData_pd;
-}
-
-void freePlayerData(void)
-{
- /* We don't want to release this memory until we know our player and
- * decoder have exited. Otherwise, their signal handlers will want to
- * access playerData_pd and we need to keep it available for them */
- waitpid(-1, NULL, 0);
- shmdt(playerData_pd);
-}
diff --git a/trunk/src/playerData.h b/trunk/src/playerData.h
deleted file mode 100644
index 00e4040be..000000000
--- a/trunk/src/playerData.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef PLAYER_DATA_H
-#define PLAYER_DATA_H
-
-#include "../config.h"
-
-#include "audio.h"
-#include "player.h"
-#include "decode.h"
-#include "mpd_types.h"
-#include "outputBuffer.h"
-
-/* pick 1020 since its devisible for 8,16,24, and 32-bit audio */
-#define CHUNK_SIZE 1020
-
-extern int buffered_before_play;
-extern int buffered_chunks;
-
-typedef struct _PlayerData {
- OutputBuffer buffer;
- PlayerControl playerControl;
- DecoderControl decoderControl;
- mpd_uint8 *audioDeviceStates;
-} PlayerData;
-
-void initPlayerData(void);
-
-PlayerData *getPlayerData(void);
-
-void freePlayerData(void);
-
-#endif
diff --git a/trunk/src/playlist.c b/trunk/src/playlist.c
deleted file mode 100644
index d8f2c6b65..000000000
--- a/trunk/src/playlist.c
+++ /dev/null
@@ -1,1499 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "playlist.h"
-#include "player.h"
-#include "command.h"
-#include "ls.h"
-#include "tag.h"
-#include "conf.h"
-#include "directory.h"
-#include "log.h"
-#include "path.h"
-#include "utils.h"
-#include "sig_handlers.h"
-#include "state_file.h"
-#include "storedPlaylist.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-
-#define PLAYLIST_STATE_STOP 0
-#define PLAYLIST_STATE_PLAY 1
-
-#define PLAYLIST_PREV_UNLESS_ELAPSED 10
-
-#define PLAYLIST_STATE_FILE_STATE "state: "
-#define PLAYLIST_STATE_FILE_RANDOM "random: "
-#define PLAYLIST_STATE_FILE_REPEAT "repeat: "
-#define PLAYLIST_STATE_FILE_CURRENT "current: "
-#define PLAYLIST_STATE_FILE_TIME "time: "
-#define PLAYLIST_STATE_FILE_CROSSFADE "crossfade: "
-#define PLAYLIST_STATE_FILE_PLAYLIST_BEGIN "playlist_begin"
-#define PLAYLIST_STATE_FILE_PLAYLIST_END "playlist_end"
-
-#define PLAYLIST_STATE_FILE_STATE_PLAY "play"
-#define PLAYLIST_STATE_FILE_STATE_PAUSE "pause"
-#define PLAYLIST_STATE_FILE_STATE_STOP "stop"
-
-#define PLAYLIST_BUFFER_SIZE 2*MAXPATHLEN
-
-#define PLAYLIST_HASH_MULT 4
-
-#define DEFAULT_PLAYLIST_MAX_LENGTH (1024*16)
-#define DEFAULT_PLAYLIST_SAVE_ABSOLUTE_PATHS 0
-
-static Playlist playlist;
-static int playlist_state = PLAYLIST_STATE_STOP;
-static int playlist_max_length = DEFAULT_PLAYLIST_MAX_LENGTH;
-static int playlist_stopOnError;
-static int playlist_errorCount;
-static int playlist_queueError;
-static int playlist_noGoToNext;
-
-int playlist_saveAbsolutePaths = DEFAULT_PLAYLIST_SAVE_ABSOLUTE_PATHS;
-
-static void swapOrder(int a, int b);
-static int playPlaylistOrderNumber(int fd, int orderNum);
-static void randomizeOrder(int start, int end);
-
-static void incrPlaylistVersion(void)
-{
- static unsigned long max = ((mpd_uint32) 1 << 31) - 1;
- playlist.version++;
- if (playlist.version >= max) {
- int i;
-
- for (i = 0; i < playlist.length; i++) {
- playlist.songMod[i] = 0;
- }
-
- playlist.version = 1;
- }
-}
-
-void playlistVersionChange(void)
-{
- int i = 0;
-
- for (i = 0; i < playlist.length; i++) {
- playlist.songMod[i] = playlist.version;
- }
-
- incrPlaylistVersion();
-}
-
-static void incrPlaylistCurrent(void)
-{
- if (playlist.current < 0)
- return;
-
- if (playlist.current >= playlist.length - 1) {
- if (playlist.repeat)
- playlist.current = 0;
- else
- playlist.current = -1;
- } else
- playlist.current++;
-}
-
-void initPlaylist(void)
-{
- char *test;
- int i;
- ConfigParam *param;
-
- playlist.length = 0;
- playlist.repeat = 0;
- playlist.version = 1;
- playlist.random = 0;
- playlist.queued = -1;
- playlist.current = -1;
-
- param = getConfigParam(CONF_MAX_PLAYLIST_LENGTH);
-
- if (param) {
- playlist_max_length = strtol(param->value, &test, 10);
- if (*test != '\0') {
- FATAL("max playlist length \"%s\" is not an integer, "
- "line %i\n", param->value, param->line);
- }
- }
-
- playlist_saveAbsolutePaths = getBoolConfigParam(CONF_SAVE_ABSOLUTE_PATHS);
- if (playlist_saveAbsolutePaths == -1) playlist_saveAbsolutePaths = DEFAULT_PLAYLIST_SAVE_ABSOLUTE_PATHS;
- else if (playlist_saveAbsolutePaths < 0) exit(EXIT_FAILURE);
-
- playlist.songs = xmalloc(sizeof(Song *) * playlist_max_length);
- playlist.songMod = xmalloc(sizeof(mpd_uint32) * playlist_max_length);
- playlist.order = xmalloc(sizeof(int) * playlist_max_length);
- playlist.idToPosition = xmalloc(sizeof(int) * playlist_max_length *
- PLAYLIST_HASH_MULT);
- playlist.positionToId = xmalloc(sizeof(int) * playlist_max_length);
-
- memset(playlist.songs, 0, sizeof(char *) * playlist_max_length);
-
- srandom(time(NULL));
-
- for (i = 0; i < playlist_max_length * PLAYLIST_HASH_MULT; i++) {
- playlist.idToPosition[i] = -1;
- }
-}
-
-static int getNextId(void)
-{
- static int cur = -1;
-
- do {
- cur++;
- if (cur >= playlist_max_length * PLAYLIST_HASH_MULT) {
- cur = 0;
- }
- } while (playlist.idToPosition[cur] != -1);
-
- return cur;
-}
-
-void finishPlaylist(void)
-{
- int i;
- for (i = 0; i < playlist.length; i++) {
- if (playlist.songs[i]->type == SONG_TYPE_URL) {
- freeJustSong(playlist.songs[i]);
- }
- }
-
- playlist.length = 0;
-
- free(playlist.songs);
- playlist.songs = NULL;
- free(playlist.songMod);
- playlist.songMod = NULL;
- free(playlist.order);
- playlist.order = NULL;
- free(playlist.idToPosition);
- playlist.idToPosition = NULL;
- free(playlist.positionToId);
- playlist.positionToId = NULL;
-}
-
-int clearPlaylist(int fd)
-{
- int i;
-
- if (stopPlaylist(fd) < 0)
- return -1;
-
- for (i = 0; i < playlist.length; i++) {
- if (playlist.songs[i]->type == SONG_TYPE_URL) {
- freeJustSong(playlist.songs[i]);
- }
- playlist.idToPosition[playlist.positionToId[i]] = -1;
- playlist.songs[i] = NULL;
- }
- playlist.length = 0;
- playlist.current = -1;
-
- incrPlaylistVersion();
-
- return 0;
-}
-
-int clearStoredPlaylist(int fd, char *utf8file)
-{
- removeAllFromStoredPlaylistByPath(fd, utf8file);
- return 0;
-}
-
-int showPlaylist(int fd)
-{
- int i;
-
- for (i = 0; i < playlist.length; i++) {
- fdprintf(fd, "%i:%s\n", i, getSongUrl(playlist.songs[i]));
- }
-
- return 0;
-}
-
-void savePlaylistState(FILE *fp)
-{
- fprintf(fp, "%s", PLAYLIST_STATE_FILE_STATE);
- switch (playlist_state) {
- case PLAYLIST_STATE_PLAY:
- switch (getPlayerState()) {
- case PLAYER_STATE_PAUSE:
- fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_STATE_PAUSE);
- break;
- default:
- fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_STATE_PLAY);
- }
- fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_CURRENT,
- playlist.order[playlist.current]);
- fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_TIME,
- getPlayerElapsedTime());
- break;
- default:
- fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_STATE_STOP);
- break;
- }
- fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_RANDOM, playlist.random);
- fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_REPEAT, playlist.repeat);
- fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_CROSSFADE,
- (int)(getPlayerCrossFade()));
- fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_PLAYLIST_BEGIN);
- fflush(fp);
- showPlaylist(fileno(fp));
- fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_PLAYLIST_END);
-}
-
-static void loadPlaylistFromStateFile(FILE *fp, char *buffer,
- int state, int current, int time)
-{
- char *temp;
- int song;
-
- if (!myFgets(buffer, PLAYLIST_BUFFER_SIZE, fp))
- state_file_fatal();
- while (strcmp(buffer, PLAYLIST_STATE_FILE_PLAYLIST_END)) {
- song = atoi(strtok(buffer, ":"));
- if (!(temp = strtok(NULL, "")))
- state_file_fatal();
- if (!addToPlaylist(STDERR_FILENO, temp, 0) && current == song) {
- if (state != PLAYER_STATE_STOP) {
- playPlaylist(STDERR_FILENO,
- playlist.length - 1, 0);
- }
- if (state == PLAYER_STATE_PAUSE) {
- playerPause(STDERR_FILENO);
- }
- if (state != PLAYER_STATE_STOP) {
- seekSongInPlaylist(STDERR_FILENO,
- playlist.length - 1, time);
- }
- }
- if (!myFgets(buffer, PLAYLIST_BUFFER_SIZE, fp))
- state_file_fatal();
- }
-}
-
-void readPlaylistState(FILE *fp)
-{
- int current = -1;
- int time = 0;
- int state = PLAYER_STATE_STOP;
- char buffer[PLAYLIST_BUFFER_SIZE];
-
- while (myFgets(buffer, PLAYLIST_BUFFER_SIZE, fp)) {
- if (strncmp(buffer, PLAYLIST_STATE_FILE_STATE,
- strlen(PLAYLIST_STATE_FILE_STATE)) == 0) {
- if (strcmp(&(buffer[strlen(PLAYLIST_STATE_FILE_STATE)]),
- PLAYLIST_STATE_FILE_STATE_PLAY) == 0) {
- state = PLAYER_STATE_PLAY;
- } else
- if (strcmp
- (&(buffer[strlen(PLAYLIST_STATE_FILE_STATE)]),
- PLAYLIST_STATE_FILE_STATE_PAUSE)
- == 0) {
- state = PLAYER_STATE_PAUSE;
- }
- } else if (strncmp(buffer, PLAYLIST_STATE_FILE_TIME,
- strlen(PLAYLIST_STATE_FILE_TIME)) == 0) {
- time =
- atoi(&(buffer[strlen(PLAYLIST_STATE_FILE_TIME)]));
- } else
- if (strncmp
- (buffer, PLAYLIST_STATE_FILE_REPEAT,
- strlen(PLAYLIST_STATE_FILE_REPEAT)) == 0) {
- if (strcmp
- (&(buffer[strlen(PLAYLIST_STATE_FILE_REPEAT)]),
- "1") == 0) {
- setPlaylistRepeatStatus(STDERR_FILENO, 1);
- } else
- setPlaylistRepeatStatus(STDERR_FILENO, 0);
- } else
- if (strncmp
- (buffer, PLAYLIST_STATE_FILE_CROSSFADE,
- strlen(PLAYLIST_STATE_FILE_CROSSFADE)) == 0) {
- setPlayerCrossFade(atoi
- (&
- (buffer
- [strlen
- (PLAYLIST_STATE_FILE_CROSSFADE)])));
- } else
- if (strncmp
- (buffer, PLAYLIST_STATE_FILE_RANDOM,
- strlen(PLAYLIST_STATE_FILE_RANDOM)) == 0) {
- if (strcmp
- (&
- (buffer
- [strlen(PLAYLIST_STATE_FILE_RANDOM)]),
- "1") == 0) {
- setPlaylistRandomStatus(STDERR_FILENO, 1);
- } else
- setPlaylistRandomStatus(STDERR_FILENO, 0);
- } else if (strncmp(buffer, PLAYLIST_STATE_FILE_CURRENT,
- strlen(PLAYLIST_STATE_FILE_CURRENT))
- == 0) {
- if (strlen(buffer) ==
- strlen(PLAYLIST_STATE_FILE_CURRENT))
- state_file_fatal();
- current = atoi(&(buffer
- [strlen
- (PLAYLIST_STATE_FILE_CURRENT)]));
- } else
- if (strncmp
- (buffer, PLAYLIST_STATE_FILE_PLAYLIST_BEGIN,
- strlen(PLAYLIST_STATE_FILE_PLAYLIST_BEGIN)
- ) == 0) {
- if (state == PLAYER_STATE_STOP)
- current = -1;
- loadPlaylistFromStateFile(fp, buffer, state,
- current, time);
- }
- }
-}
-
-static void printPlaylistSongInfo(int fd, int song)
-{
- printSongInfo(fd, playlist.songs[song]);
- fdprintf(fd, "Pos: %i\nId: %i\n", song, playlist.positionToId[song]);
-}
-
-int playlistChanges(int fd, mpd_uint32 version)
-{
- int i;
-
- for (i = 0; i < playlist.length; i++) {
- if (version > playlist.version ||
- playlist.songMod[i] >= version ||
- playlist.songMod[i] == 0) {
- printPlaylistSongInfo(fd, i);
- }
- }
-
- return 0;
-}
-
-int playlistChangesPosId(int fd, mpd_uint32 version)
-{
- int i;
-
- for (i = 0; i < playlist.length; i++) {
- if (version > playlist.version ||
- playlist.songMod[i] >= version ||
- playlist.songMod[i] == 0) {
- fdprintf(fd, "cpos: %i\nId: %i\n",
- i, playlist.positionToId[i]);
- }
- }
-
- return 0;
-}
-
-int playlistInfo(int fd, int song)
-{
- int i;
- int begin = 0;
- int end = playlist.length;
-
- if (song >= 0) {
- begin = song;
- end = song + 1;
- }
- if (song >= playlist.length) {
- commandError(fd, ACK_ERROR_NO_EXIST,
- "song doesn't exist: \"%i\"", song);
- return -1;
- }
-
- for (i = begin; i < end; i++)
- printPlaylistSongInfo(fd, i);
-
- return 0;
-}
-
-# define checkSongId(id) { \
- if(id < 0 || id >= PLAYLIST_HASH_MULT*playlist_max_length || \
- playlist.idToPosition[id] == -1 ) \
- { \
- commandError(fd, ACK_ERROR_NO_EXIST, \
- "song id doesn't exist: \"%i\"", id); \
- return -1; \
- } \
-}
-
-int playlistId(int fd, int id)
-{
- int i;
- int begin = 0;
- int end = playlist.length;
-
- if (id >= 0) {
- checkSongId(id);
- begin = playlist.idToPosition[id];
- end = begin + 1;
- }
-
- for (i = begin; i < end; i++)
- printPlaylistSongInfo(fd, i);
-
- return 0;
-}
-
-static void swapSongs(int song1, int song2)
-{
- Song *sTemp;
- int iTemp;
-
- sTemp = playlist.songs[song1];
- playlist.songs[song1] = playlist.songs[song2];
- playlist.songs[song2] = sTemp;
-
- playlist.songMod[song1] = playlist.version;
- playlist.songMod[song2] = playlist.version;
-
- playlist.idToPosition[playlist.positionToId[song1]] = song2;
- playlist.idToPosition[playlist.positionToId[song2]] = song1;
-
- iTemp = playlist.positionToId[song1];
- playlist.positionToId[song1] = playlist.positionToId[song2];
- playlist.positionToId[song2] = iTemp;
-}
-
-static void queueNextSongInPlaylist(void)
-{
- if (playlist.current < playlist.length - 1) {
- playlist.queued = playlist.current + 1;
- DEBUG("playlist: queue song %i:\"%s\"\n",
- playlist.queued,
- getSongUrl(playlist.
- songs[playlist.order[playlist.queued]]));
- if (queueSong(playlist.songs[playlist.order[playlist.queued]]) <
- 0) {
- playlist.queued = -1;
- playlist_queueError = 1;
- }
- } else if (playlist.length && playlist.repeat) {
- if (playlist.length > 1 && playlist.random) {
- randomizeOrder(0, playlist.length - 1);
- }
- playlist.queued = 0;
- DEBUG("playlist: queue song %i:\"%s\"\n",
- playlist.queued,
- getSongUrl(playlist.
- songs[playlist.order[playlist.queued]]));
- if (queueSong(playlist.songs[playlist.order[playlist.queued]]) <
- 0) {
- playlist.queued = -1;
- playlist_queueError = 1;
- }
- }
-}
-
-static void syncPlaylistWithQueue(int queue)
-{
- if (queue && getPlayerQueueState() == PLAYER_QUEUE_BLANK) {
- queueNextSongInPlaylist();
- } else if (getPlayerQueueState() == PLAYER_QUEUE_DECODE) {
- if (playlist.queued != -1)
- setQueueState(PLAYER_QUEUE_PLAY);
- else
- setQueueState(PLAYER_QUEUE_STOP);
- } else if (getPlayerQueueState() == PLAYER_QUEUE_EMPTY) {
- setQueueState(PLAYER_QUEUE_BLANK);
- if (playlist.queued >= 0) {
- DEBUG("playlist: now playing queued song\n");
- playlist.current = playlist.queued;
- }
- playlist.queued = -1;
- if (queue)
- queueNextSongInPlaylist();
- }
-}
-
-static void lockPlaylistInteraction(void)
-{
- if (getPlayerQueueState() == PLAYER_QUEUE_PLAY ||
- getPlayerQueueState() == PLAYER_QUEUE_FULL) {
- playerQueueLock();
- syncPlaylistWithQueue(0);
- }
-}
-
-static void unlockPlaylistInteraction(void)
-{
- playerQueueUnlock();
-}
-
-static void clearPlayerQueue(void)
-{
- playlist.queued = -1;
- switch (getPlayerQueueState()) {
- case PLAYER_QUEUE_FULL:
- DEBUG("playlist: dequeue song\n");
- setQueueState(PLAYER_QUEUE_BLANK);
- break;
- case PLAYER_QUEUE_PLAY:
- DEBUG("playlist: stop decoding queued song\n");
- setQueueState(PLAYER_QUEUE_STOP);
- break;
- }
-}
-
-int addToPlaylist(int fd, char *url, int printId)
-{
- Song *song;
-
- DEBUG("add to playlist: %s\n", url);
-
- if ((song = getSongFromDB(url))) {
- } else if (!(isValidRemoteUtf8Url(url) &&
- (song = newSong(url, SONG_TYPE_URL, NULL)))) {
- commandError(fd, ACK_ERROR_NO_EXIST,
- "\"%s\" is not in the music db or is "
- "not a valid url", url);
- return -1;
- }
-
- return addSongToPlaylist(fd, song, printId);
-}
-
-int addToStoredPlaylist(int fd, char *url, char *utf8file)
-{
- Song *song;
-
- DEBUG("add to stored playlist: %s\n", url);
-
- song = getSongFromDB(url);
- if (song) {
- appendSongToStoredPlaylistByPath(fd, utf8file, song);
- return 0;
- }
-
- if (!isValidRemoteUtf8Url(url))
- goto fail;
-
- song = newSong(url, SONG_TYPE_URL, NULL);
- if (song) {
- appendSongToStoredPlaylistByPath(fd, utf8file, song);
- freeJustSong(song);
- return 0;
- }
-
-fail:
- commandError(fd, ACK_ERROR_NO_EXIST, "\"%s\" is not in the music db"
- "or is not a valid url", url);
- return -1;
-}
-
-int addSongToPlaylist(int fd, Song * song, int printId)
-{
- int id;
-
- if (playlist.length == playlist_max_length) {
- commandError(fd, ACK_ERROR_PLAYLIST_MAX,
- "playlist is at the max size");
- return -1;
- }
-
- if (playlist_state == PLAYLIST_STATE_PLAY) {
- if (playlist.queued >= 0
- && playlist.current == playlist.length - 1) {
- lockPlaylistInteraction();
- clearPlayerQueue();
- unlockPlaylistInteraction();
- }
- }
-
- id = getNextId();
-
- playlist.songs[playlist.length] = song;
- playlist.songMod[playlist.length] = playlist.version;
- playlist.order[playlist.length] = playlist.length;
- playlist.positionToId[playlist.length] = id;
- playlist.idToPosition[playlist.positionToId[playlist.length]] =
- playlist.length;
- playlist.length++;
-
- if (playlist.random) {
- int swap;
- int start;
- /*if(playlist_state==PLAYLIST_STATE_STOP) start = 0;
- else */ if (playlist.queued >= 0)
- start = playlist.queued + 1;
- else
- start = playlist.current + 1;
- if (start < playlist.length) {
- swap = random() % (playlist.length - start);
- swap += start;
- swapOrder(playlist.length - 1, swap);
- }
- }
-
- incrPlaylistVersion();
-
- if (printId)
- fdprintf(fd, "Id: %i\n", id);
-
- return 0;
-}
-
-int swapSongsInPlaylist(int fd, int song1, int song2)
-{
- int queuedSong = -1;
- int currentSong = -1;
-
- if (song1 < 0 || song1 >= playlist.length) {
- commandError(fd, ACK_ERROR_NO_EXIST,
- "song doesn't exist: \"%i\"", song1);
- return -1;
- }
- if (song2 < 0 || song2 >= playlist.length) {
- commandError(fd, ACK_ERROR_NO_EXIST,
- "song doesn't exist: \"%i\"", song2);
- return -1;
- }
-
- if (playlist_state == PLAYLIST_STATE_PLAY) {
- if (playlist.queued >= 0) {
- queuedSong = playlist.order[playlist.queued];
- }
- currentSong = playlist.order[playlist.current];
-
- if (queuedSong == song1 || queuedSong == song2
- || currentSong == song1 || currentSong == song2) {
- lockPlaylistInteraction();
- clearPlayerQueue();
- unlockPlaylistInteraction();
- }
- }
-
- swapSongs(song1, song2);
- if (playlist.random) {
- int i;
- int k;
- int j = -1;
- for (i = 0; playlist.order[i] != song1; i++) {
- if (playlist.order[i] == song2)
- j = i;
- }
- k = i;
- for (; j == -1; i++)
- if (playlist.order[i] == song2)
- j = i;
- swapOrder(k, j);
- } else {
- if (playlist.current == song1)
- playlist.current = song2;
- else if (playlist.current == song2)
- playlist.current = song1;
- }
-
- incrPlaylistVersion();
-
- return 0;
-}
-
-int swapSongsInPlaylistById(int fd, int id1, int id2)
-{
- checkSongId(id1);
- checkSongId(id2);
-
- return swapSongsInPlaylist(fd, playlist.idToPosition[id1],
- playlist.idToPosition[id2]);
-}
-
-#define moveSongFromTo(from, to) { \
- playlist.idToPosition[playlist.positionToId[from]] = to; \
- playlist.positionToId[to] = playlist.positionToId[from]; \
- playlist.songs[to] = playlist.songs[from]; \
- playlist.songMod[to] = playlist.version; \
-}
-
-int deleteFromPlaylist(int fd, int song)
-{
- int i;
- int songOrder;
-
- if (song < 0 || song >= playlist.length) {
- commandError(fd, ACK_ERROR_NO_EXIST,
- "song doesn't exist: \"%i\"", song);
- return -1;
- }
-
- if (playlist_state == PLAYLIST_STATE_PLAY) {
- if (playlist.queued >= 0
- && (playlist.order[playlist.queued] == song
- || playlist.order[playlist.current] == song)) {
- lockPlaylistInteraction();
- clearPlayerQueue();
- unlockPlaylistInteraction();
- }
- }
-
- if (playlist.songs[song]->type == SONG_TYPE_URL) {
- freeJustSong(playlist.songs[song]);
- }
-
- playlist.idToPosition[playlist.positionToId[song]] = -1;
-
- /* delete song from songs array */
- for (i = song; i < playlist.length - 1; i++) {
- moveSongFromTo(i + 1, i);
- }
- /* now find it in the order array */
- for (i = 0; i < playlist.length - 1; i++) {
- if (playlist.order[i] == song)
- break;
- }
- songOrder = i;
- /* delete the entry from the order array */
- for (; i < playlist.length - 1; i++)
- playlist.order[i] = playlist.order[i + 1];
- /* readjust values in the order array */
- for (i = 0; i < playlist.length - 1; i++) {
- if (playlist.order[i] > song)
- playlist.order[i]--;
- }
- /* now take care of other misc stuff */
- playlist.songs[playlist.length - 1] = NULL;
- playlist.length--;
-
- incrPlaylistVersion();
-
- if (playlist_state != PLAYLIST_STATE_STOP
- && playlist.current == songOrder) {
- /*if(playlist.current>=playlist.length) return playerStop(fd);
- else return playPlaylistOrderNumber(fd,playlist.current); */
- playerStop(STDERR_FILENO);
- playlist_noGoToNext = 1;
- }
-
- if (playlist.current > songOrder) {
- playlist.current--;
- } else if (playlist.current >= playlist.length) {
- incrPlaylistCurrent();
- }
-
- if (playlist.queued > songOrder) {
- playlist.queued--;
- }
-
- return 0;
-}
-
-int deleteFromPlaylistById(int fd, int id)
-{
- checkSongId(id);
-
- return deleteFromPlaylist(fd, playlist.idToPosition[id]);
-}
-
-void deleteASongFromPlaylist(Song * song)
-{
- int i;
-
- if (NULL == playlist.songs)
- return;
-
- for (i = 0; i < playlist.length; i++) {
- if (song == playlist.songs[i]) {
- deleteFromPlaylist(STDERR_FILENO, i);
- }
- }
-}
-
-int stopPlaylist(int fd)
-{
- DEBUG("playlist: stop\n");
- if (playerStop(fd) < 0)
- return -1;
- playerCloseAudio();
- playlist.queued = -1;
- playlist_state = PLAYLIST_STATE_STOP;
- playlist_noGoToNext = 0;
- if (playlist.random)
- randomizeOrder(0, playlist.length - 1);
- return 0;
-}
-
-static int playPlaylistOrderNumber(int fd, int orderNum)
-{
-
- if (playerStop(fd) < 0)
- return -1;
-
- playlist_state = PLAYLIST_STATE_PLAY;
- playlist_noGoToNext = 0;
- playlist.queued = -1;
- playlist_queueError = 0;
-
- DEBUG("playlist: play %i:\"%s\"\n", orderNum,
- getSongUrl(playlist.songs[playlist.order[orderNum]]));
-
- if (playerPlay(fd, (playlist.songs[playlist.order[orderNum]])) < 0) {
- stopPlaylist(fd);
- return -1;
- }
-
- playlist.current = orderNum;
-
- return 0;
-}
-
-int playPlaylist(int fd, int song, int stopOnError)
-{
- int i = song;
-
- clearPlayerError();
-
- if (song == -1) {
- if (playlist.length == 0)
- return 0;
-
- if (playlist_state == PLAYLIST_STATE_PLAY) {
- return playerSetPause(fd, 0);
- }
- if (playlist.current >= 0 && playlist.current < playlist.length) {
- i = playlist.current;
- } else {
- i = 0;
- }
- } else if (song < 0 || song >= playlist.length) {
- commandError(fd, ACK_ERROR_NO_EXIST,
- "song doesn't exist: \"%i\"", song);
- return -1;
- }
-
- if (playlist.random) {
- if (song == -1 && playlist_state == PLAYLIST_STATE_PLAY) {
- randomizeOrder(0, playlist.length - 1);
- } else {
- if (song >= 0)
- for (i = 0; song != playlist.order[i]; i++) ;
- if (playlist_state == PLAYLIST_STATE_STOP) {
- playlist.current = 0;
- }
- swapOrder(i, playlist.current);
- i = playlist.current;
- }
- }
-
- playlist_stopOnError = stopOnError;
- playlist_errorCount = 0;
-
- return playPlaylistOrderNumber(fd, i);
-}
-
-int playPlaylistById(int fd, int id, int stopOnError)
-{
- if (id == -1) {
- return playPlaylist(fd, id, stopOnError);
- }
-
- checkSongId(id);
-
- return playPlaylist(fd, playlist.idToPosition[id], stopOnError);
-}
-
-static void syncCurrentPlayerDecodeMetadata(void)
-{
- Song *songPlayer = playerCurrentDecodeSong();
- Song *song;
- int songNum;
-
- if (!songPlayer)
- return;
-
- if (playlist_state != PLAYLIST_STATE_PLAY)
- return;
-
- songNum = playlist.order[playlist.current];
- song = playlist.songs[songNum];
-
- if (song->type == SONG_TYPE_URL &&
- 0 == strcmp(getSongUrl(song), songPlayer->url) &&
- !mpdTagsAreEqual(song->tag, songPlayer->tag)) {
- if (song->tag)
- freeMpdTag(song->tag);
- song->tag = mpdTagDup(songPlayer->tag);
- playlist.songMod[songNum] = playlist.version;
- incrPlaylistVersion();
- }
-}
-
-void syncPlayerAndPlaylist(void)
-{
- if (playlist_state != PLAYLIST_STATE_PLAY)
- return;
-
- if (getPlayerState() == PLAYER_STATE_STOP)
- playPlaylistIfPlayerStopped();
- else
- syncPlaylistWithQueue(!playlist_queueError);
-
- syncCurrentPlayerDecodeMetadata();
-}
-
-static int currentSongInPlaylist(int fd)
-{
- if (playlist_state != PLAYLIST_STATE_PLAY)
- return 0;
-
- playlist_stopOnError = 0;
-
- syncPlaylistWithQueue(0);
-
- if (playlist.current >= 0 && playlist.current < playlist.length) {
- return playPlaylistOrderNumber(fd, playlist.current);
- } else
- return stopPlaylist(fd);
-
- return 0;
-}
-
-int nextSongInPlaylist(int fd)
-{
- if (playlist_state != PLAYLIST_STATE_PLAY)
- return 0;
-
- syncPlaylistWithQueue(0);
-
- playlist_stopOnError = 0;
-
- if (playlist.current < playlist.length - 1) {
- return playPlaylistOrderNumber(fd, playlist.current + 1);
- } else if (playlist.length && playlist.repeat) {
- if (playlist.random)
- randomizeOrder(0, playlist.length - 1);
- return playPlaylistOrderNumber(fd, 0);
- } else {
- incrPlaylistCurrent();
- return stopPlaylist(fd);
- }
-
- return 0;
-}
-
-void playPlaylistIfPlayerStopped(void)
-{
- if (getPlayerState() == PLAYER_STATE_STOP) {
- int error = getPlayerError();
-
- if (error == PLAYER_ERROR_NOERROR)
- playlist_errorCount = 0;
- else
- playlist_errorCount++;
-
- if (playlist_state == PLAYLIST_STATE_PLAY
- && ((playlist_stopOnError && error != PLAYER_ERROR_NOERROR)
- || error == PLAYER_ERROR_AUDIO
- || error == PLAYER_ERROR_SYSTEM
- || playlist_errorCount >= playlist.length)) {
- stopPlaylist(STDERR_FILENO);
- } else if (playlist_noGoToNext)
- currentSongInPlaylist(STDERR_FILENO);
- else
- nextSongInPlaylist(STDERR_FILENO);
- }
-}
-
-int getPlaylistRepeatStatus(void)
-{
- return playlist.repeat;
-}
-
-int getPlaylistRandomStatus(void)
-{
- return playlist.random;
-}
-
-int setPlaylistRepeatStatus(int fd, int status)
-{
- if (status != 0 && status != 1) {
- commandError(fd, ACK_ERROR_ARG, "\"%i\" is not 0 or 1", status);
- return -1;
- }
-
- if (playlist_state == PLAYLIST_STATE_PLAY) {
- if (playlist.repeat && !status && playlist.queued == 0) {
- lockPlaylistInteraction();
- clearPlayerQueue();
- unlockPlaylistInteraction();
- }
- }
-
- playlist.repeat = status;
-
- return 0;
-}
-
-int moveSongInPlaylist(int fd, int from, int to)
-{
- int i;
- Song *tmpSong;
- int tmpId;
- int queuedSong = -1;
- int currentSong = -1;
-
- if (from < 0 || from >= playlist.length) {
- commandError(fd, ACK_ERROR_NO_EXIST,
- "song doesn't exist: \"%i\"", from);
- return -1;
- }
-
- if (to < 0 || to >= playlist.length) {
- commandError(fd, ACK_ERROR_NO_EXIST,
- "song doesn't exist: \"%i\"", to);
- return -1;
- }
-
- if (playlist_state == PLAYLIST_STATE_PLAY) {
- if (playlist.queued >= 0) {
- queuedSong = playlist.order[playlist.queued];
- }
- currentSong = playlist.order[playlist.current];
- if (queuedSong == from || queuedSong == to
- || currentSong == from || currentSong == to) {
- lockPlaylistInteraction();
- clearPlayerQueue();
- unlockPlaylistInteraction();
- }
- }
-
- tmpSong = playlist.songs[from];
- tmpId = playlist.positionToId[from];
- /* move songs to one less in from->to */
- for (i = from; i < to; i++) {
- moveSongFromTo(i + 1, i);
- }
- /* move songs to one more in to->from */
- for (i = from; i > to; i--) {
- moveSongFromTo(i - 1, i);
- }
- /* put song at _to_ */
- playlist.idToPosition[tmpId] = to;
- playlist.positionToId[to] = tmpId;
- playlist.songs[to] = tmpSong;
- playlist.songMod[to] = playlist.version;
- /* now deal with order */
- if (playlist.random) {
- for (i = 0; i < playlist.length; i++) {
- if (playlist.order[i] > from && playlist.order[i] <= to) {
- playlist.order[i]--;
- } else if (playlist.order[i] < from &&
- playlist.order[i] >= to) {
- playlist.order[i]++;
- } else if (from == playlist.order[i]) {
- playlist.order[i] = to;
- }
- }
- }
- else
- {
- if (playlist.current == from)
- playlist.current = to;
- else if (playlist.current > from && playlist.current <= to) {
- playlist.current--;
- } else if (playlist.current >= to && playlist.current < from) {
- playlist.current++;
- }
-
- /* this first if statement isn't necessary since the queue
- * would have been cleared out if queued == from */
- if (playlist.queued == from)
- playlist.queued = to;
- else if (playlist.queued > from && playlist.queued <= to) {
- playlist.queued--;
- } else if (playlist.queued>= to && playlist.queued < from) {
- playlist.queued++;
- }
- }
-
- incrPlaylistVersion();
-
- return 0;
-}
-
-int moveSongInPlaylistById(int fd, int id1, int to)
-{
- checkSongId(id1);
-
- return moveSongInPlaylist(fd, playlist.idToPosition[id1], to);
-}
-
-static void orderPlaylist(void)
-{
- int i;
-
- if (playlist.current >= 0 && playlist.current < playlist.length) {
- playlist.current = playlist.order[playlist.current];
- }
-
- if (playlist_state == PLAYLIST_STATE_PLAY) {
- if (playlist.queued >= 0) {
- lockPlaylistInteraction();
- clearPlayerQueue();
- unlockPlaylistInteraction();
- }
- }
-
- for (i = 0; i < playlist.length; i++) {
- playlist.order[i] = i;
- }
-
-}
-
-static void swapOrder(int a, int b)
-{
- int bak = playlist.order[a];
- playlist.order[a] = playlist.order[b];
- playlist.order[b] = bak;
-}
-
-static void randomizeOrder(int start, int end)
-{
- int i;
- int ri;
-
- DEBUG("playlist: randomize from %i to %i\n", start, end);
-
- if (playlist_state == PLAYLIST_STATE_PLAY) {
- if (playlist.queued >= start && playlist.queued <= end) {
- lockPlaylistInteraction();
- clearPlayerQueue();
- unlockPlaylistInteraction();
- }
- }
-
- for (i = start; i <= end; i++) {
- ri = random() % (end - start + 1) + start;
- if (ri == playlist.current)
- playlist.current = i;
- else if (i == playlist.current)
- playlist.current = ri;
- swapOrder(i, ri);
- }
-
-}
-
-int setPlaylistRandomStatus(int fd, int status)
-{
- int statusWas = playlist.random;
-
- if (status != 0 && status != 1) {
- commandError(fd, ACK_ERROR_ARG, "\"%i\" is not 0 or 1", status);
- return -1;
- }
-
- playlist.random = status;
-
- if (status != statusWas) {
- if (playlist.random) {
- /*if(playlist_state==PLAYLIST_STATE_PLAY) {
- randomizeOrder(playlist.current+1,
- playlist.length-1);
- }
- else */ randomizeOrder(0, playlist.length - 1);
- if (playlist.current >= 0 &&
- playlist.current < playlist.length) {
- swapOrder(playlist.current, 0);
- playlist.current = 0;
- }
- } else
- orderPlaylist();
- }
-
- return 0;
-}
-
-int previousSongInPlaylist(int fd)
-{
- static time_t lastTime;
- time_t diff = time(NULL) - lastTime;
-
- lastTime += diff;
-
- if (playlist_state != PLAYLIST_STATE_PLAY)
- return 0;
-
- syncPlaylistWithQueue(0);
-
- if (diff && getPlayerElapsedTime() > PLAYLIST_PREV_UNLESS_ELAPSED) {
- return playPlaylistOrderNumber(fd, playlist.current);
- } else {
- if (playlist.current > 0) {
- return playPlaylistOrderNumber(fd,
- playlist.current - 1);
- } else if (playlist.repeat) {
- return playPlaylistOrderNumber(fd, playlist.length - 1);
- } else {
- return playPlaylistOrderNumber(fd, playlist.current);
- }
- }
-
- return 0;
-}
-
-int shufflePlaylist(int fd)
-{
- int i;
- int ri;
-
- if (playlist.length > 1) {
- if (playlist_state == PLAYLIST_STATE_PLAY) {
- lockPlaylistInteraction();
- clearPlayerQueue();
- unlockPlaylistInteraction();
- /* put current playing song first */
- swapSongs(0, playlist.order[playlist.current]);
- if (playlist.random) {
- int j;
- for (j = 0; 0 != playlist.order[j]; j++) ;
- playlist.current = j;
- } else
- playlist.current = 0;
- i = 1;
- } else {
- i = 0;
- playlist.current = -1;
- }
- /* shuffle the rest of the list */
- for (; i < playlist.length; i++) {
- ri = random() % (playlist.length - 1) + 1;
- swapSongs(i, ri);
- }
-
- incrPlaylistVersion();
- }
-
- return 0;
-}
-
-int deletePlaylist(int fd, char *utf8file)
-{
- char *file = utf8ToFsCharset(utf8file);
- char *rfile = xmalloc(strlen(file) + strlen(".") +
- strlen(PLAYLIST_FILE_SUFFIX) + 1);
- char *actualFile;
-
- strcpy(rfile, file);
- strcat(rfile, ".");
- strcat(rfile, PLAYLIST_FILE_SUFFIX);
-
- if ((actualFile = rpp2app(rfile)) && isPlaylist(actualFile))
- free(rfile);
- else {
- free(rfile);
- commandError(fd, ACK_ERROR_NO_EXIST,
- "playlist \"%s\" not found", utf8file);
- return -1;
- }
-
- if (unlink(actualFile) < 0) {
- commandError(fd, ACK_ERROR_SYSTEM,
- "problems deleting file");
- return -1;
- }
-
- return 0;
-}
-
-int savePlaylist(int fd, char *utf8file)
-{
- StoredPlaylist *sp = newStoredPlaylist(utf8file, fd, 0);
- if (!sp)
- return -1;
-
- appendPlaylistToStoredPlaylist(sp, &playlist);
- if (writeStoredPlaylist(sp) != 0) {
- freeStoredPlaylist(sp);
- return -1;
- }
-
- freeStoredPlaylist(sp);
- return 0;
-}
-
-int getPlaylistCurrentSong(void)
-{
- if (playlist.current >= 0 && playlist.current < playlist.length) {
- return playlist.order[playlist.current];
- }
-
- return -1;
-}
-
-unsigned long getPlaylistVersion(void)
-{
- return playlist.version;
-}
-
-int getPlaylistLength(void)
-{
- return playlist.length;
-}
-
-int seekSongInPlaylist(int fd, int song, float time)
-{
- int i = song;
-
- if (song < 0 || song >= playlist.length) {
- commandError(fd, ACK_ERROR_NO_EXIST,
- "song doesn't exist: \"%i\"", song);
- return -1;
- }
-
- if (playlist.random)
- for (i = 0; song != playlist.order[i]; i++) ;
-
- clearPlayerError();
- playlist_stopOnError = 1;
- playlist_errorCount = 0;
-
- if (playlist_state == PLAYLIST_STATE_PLAY) {
- if (playlist.queued >= 0) {
- lockPlaylistInteraction();
- clearPlayerQueue();
- unlockPlaylistInteraction();
- }
- } else if (playPlaylistOrderNumber(fd, i) < 0)
- return -1;
-
- if (playlist.current != i) {
- if (playPlaylistOrderNumber(fd, i) < 0)
- return -1;
- }
-
- return playerSeek(fd, playlist.songs[playlist.order[i]], time);
-}
-
-int seekSongInPlaylistById(int fd, int id, float time)
-{
- checkSongId(id);
-
- return seekSongInPlaylist(fd, playlist.idToPosition[id], time);
-}
-
-int getPlaylistSongId(int song)
-{
- return playlist.positionToId[song];
-}
-
-int PlaylistInfo(int fd, char *utf8file, int detail)
-{
- ListNode *node;
- StoredPlaylist *sp = loadStoredPlaylist(utf8file, fd);
- if (sp == NULL)
- return -1;
-
- node = sp->list->firstNode;
- while (node != NULL) {
- char *temp = node->data;
- int wrote = 0;
-
- if (detail) {
- Song *song = getSongFromDB(temp);
- if (song) {
- printSongInfo(fd, song);
- wrote = 1;
- }
- }
-
- if (!wrote) {
- fdprintf(fd, SONG_FILE "%s\n", temp);
- }
-
- node = node->nextNode;
- }
-
- freeStoredPlaylist(sp);
- return 0;
-}
-
-int loadPlaylist(int fd, char *utf8file)
-{
- ListNode *node;
- StoredPlaylist *sp = loadStoredPlaylist(utf8file, fd);
- if (sp == NULL)
- return -1;
-
- node = sp->list->firstNode;
- while (node != NULL) {
- char *temp = node->data;
- if ((addToPlaylist(STDERR_FILENO, temp, 0)) < 0) {
- /* for windows compatibility, convert slashes */
- char *temp2 = xstrdup(temp);
- char *p = temp2;
- while (*p) {
- if (*p == '\\')
- *p = '/';
- p++;
- }
- if ((addToPlaylist(STDERR_FILENO, temp2, 0)) < 0) {
- commandError(fd, ACK_ERROR_PLAYLIST_LOAD,
- "can't add file \"%s\"", temp2);
- }
- free(temp2);
- }
-
- node = node->nextNode;
- }
-
- freeStoredPlaylist(sp);
- return 0;
-}
-
-void searchForSongsInPlaylist(int fd, int numItems, LocateTagItem * items)
-{
- int i;
- char **originalNeedles = xmalloc(numItems * sizeof(char *));
-
- for (i = 0; i < numItems; i++) {
- originalNeedles[i] = items[i].needle;
- items[i].needle = strDupToUpper(originalNeedles[i]);
- }
-
- for (i = 0; i < playlist.length; i++) {
- if (strstrSearchTags(playlist.songs[i], numItems, items))
- printPlaylistSongInfo(fd, i);
- }
-
- for (i = 0; i < numItems; i++) {
- free(items[i].needle);
- items[i].needle = originalNeedles[i];
- }
-
- free(originalNeedles);
-}
-
-void findSongsInPlaylist(int fd, int numItems, LocateTagItem * items)
-{
- int i;
-
- for (i = 0; i < playlist.length; i++) {
- if (tagItemsFoundAndMatches(playlist.songs[i], numItems, items))
- printPlaylistSongInfo(fd, i);
- }
-}
diff --git a/trunk/src/playlist.h b/trunk/src/playlist.h
deleted file mode 100644
index 0ae3a677f..000000000
--- a/trunk/src/playlist.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef PLAYLIST_H
-#define PLAYLIST_H
-
-#include "../config.h"
-
-#include "dbUtils.h"
-
-#include <stdio.h>
-#include <sys/param.h>
-#include <time.h>
-
-#define PLAYLIST_FILE_SUFFIX "m3u"
-#define PLAYLIST_COMMENT '#'
-
-typedef struct _Playlist {
- Song **songs;
- /* holds version a song was modified on */
- mpd_uint32 *songMod;
- int *order;
- int *positionToId;
- int *idToPosition;
- int length;
- int current;
- int queued;
- int repeat;
- int random;
- mpd_uint32 version;
-} Playlist;
-
-extern int playlist_saveAbsolutePaths;
-
-void initPlaylist(void);
-
-void finishPlaylist(void);
-
-void readPlaylistState(FILE *);
-
-void savePlaylistState(FILE *);
-
-int clearPlaylist(int fd);
-
-int clearStoredPlaylist(int fd, char *utf8file);
-
-int addToPlaylist(int fd, char *file, int printId);
-
-int addToStoredPlaylist(int fd, char *file, char *utf8file);
-
-int addSongToPlaylist(int fd, Song * song, int printId);
-
-int showPlaylist(int fd);
-
-int deleteFromPlaylist(int fd, int song);
-
-int deleteFromPlaylistById(int fd, int song);
-
-int playlistInfo(int fd, int song);
-
-int playlistId(int fd, int song);
-
-int stopPlaylist(int fd);
-
-int playPlaylist(int fd, int song, int stopOnError);
-
-int playPlaylistById(int fd, int song, int stopOnError);
-
-int nextSongInPlaylist(int fd);
-
-void syncPlayerAndPlaylist(void);
-
-int previousSongInPlaylist(int fd);
-
-int shufflePlaylist(int fd);
-
-int savePlaylist(int fd, char *utf8file);
-
-int deletePlaylist(int fd, char *utf8file);
-
-int deletePlaylistById(int fd, char *utf8file);
-
-void deleteASongFromPlaylist(Song * song);
-
-int moveSongInPlaylist(int fd, int from, int to);
-
-int moveSongInPlaylistById(int fd, int id, int to);
-
-int swapSongsInPlaylist(int fd, int song1, int song2);
-
-int swapSongsInPlaylistById(int fd, int id1, int id2);
-
-int loadPlaylist(int fd, char *utf8file);
-
-int getPlaylistRepeatStatus(void);
-
-int setPlaylistRepeatStatus(int fd, int status);
-
-int getPlaylistRandomStatus(void);
-
-int setPlaylistRandomStatus(int fd, int status);
-
-int getPlaylistCurrentSong(void);
-
-int getPlaylistSongId(int song);
-
-int getPlaylistLength(void);
-
-unsigned long getPlaylistVersion(void);
-
-void playPlaylistIfPlayerStopped(void);
-
-int seekSongInPlaylist(int fd, int song, float time);
-
-int seekSongInPlaylistById(int fd, int id, float time);
-
-void playlistVersionChange(void);
-
-int playlistChanges(int fd, mpd_uint32 version);
-
-int playlistChangesPosId(int fd, mpd_uint32 version);
-
-int PlaylistInfo(int fd, char *utf8file, int detail);
-
-void searchForSongsInPlaylist(int fd, int numItems, LocateTagItem * items);
-
-void findSongsInPlaylist(int fd, int numItems, LocateTagItem * items);
-
-#endif
diff --git a/trunk/src/replayGain.c b/trunk/src/replayGain.c
deleted file mode 100644
index 7c20919b8..000000000
--- a/trunk/src/replayGain.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * (c)2004 replayGain code by AliasMrJones
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "replayGain.h"
-#include "utils.h"
-
-#include "log.h"
-#include "conf.h"
-
-#include <string.h>
-#include <math.h>
-#include <stdlib.h>
-
-/* Added 4/14/2004 by AliasMrJones */
-int replayGainState = REPLAYGAIN_OFF;
-
-static float replayGainPreamp = 1.0;
-
-void initReplayGainState(void)
-{
- ConfigParam *param = getConfigParam(CONF_REPLAYGAIN);
-
- if (!param)
- return;
-
- if (strcmp(param->value, "track") == 0) {
- replayGainState = REPLAYGAIN_TRACK;
- } else if (strcmp(param->value, "album") == 0) {
- replayGainState = REPLAYGAIN_ALBUM;
- } else {
- FATAL("replaygain value \"%s\" at line %i is invalid\n",
- param->value, param->line);
- }
-
- param = getConfigParam(CONF_REPLAYGAIN_PREAMP);
-
- if (param) {
- char *test;
- float f = strtod(param->value, &test);
-
- if (*test != '\0') {
- FATAL("Replaygain preamp \"%s\" is not a number at "
- "line %i\n", param->value, param->line);
- }
-
- if (f < -15 || f > 15) {
- FATAL("Replaygain preamp \"%s\" is not between -15 and"
- "15 at line %i\n", param->value, param->line);
- }
-
- replayGainPreamp = pow(10, f / 20.0);
- }
-}
-
-static float computeReplayGainScale(float gain, float peak)
-{
- float scale;
-
- if (gain == 0.0)
- return (1);
- scale = pow(10.0, gain / 20.0);
- scale *= replayGainPreamp;
- if (scale > 15.0)
- scale = 15.0;
-
- if (scale * peak > 1.0) {
- scale = 1.0 / peak;
- }
- return (scale);
-}
-
-ReplayGainInfo *newReplayGainInfo(void)
-{
- ReplayGainInfo *ret = xmalloc(sizeof(ReplayGainInfo));
-
- ret->albumGain = 0.0;
- ret->albumPeak = 0.0;
-
- ret->trackGain = 0.0;
- ret->trackPeak = 0.0;
-
- /* set to -1 so that we know in doReplayGain to compute the scale */
- ret->scale = -1.0;
-
- return ret;
-}
-
-void freeReplayGainInfo(ReplayGainInfo * info)
-{
- free(info);
-}
-
-void doReplayGain(ReplayGainInfo * info, char *buffer, int bufferSize,
- AudioFormat * format)
-{
- mpd_sint16 *buffer16;
- mpd_sint8 *buffer8;
- mpd_sint32 temp32;
- float scale;
-
- if (replayGainState == REPLAYGAIN_OFF || !info)
- return;
-
- if (info->scale < 0) {
- switch (replayGainState) {
- case REPLAYGAIN_TRACK:
- info->scale = computeReplayGainScale(info->trackGain,
- info->trackPeak);
- break;
- default:
- info->scale = computeReplayGainScale(info->albumGain,
- info->albumPeak);
- break;
- }
- }
-
- if (info->scale <= 1.01 && info->scale >= 0.99)
- return;
-
- buffer16 = (mpd_sint16 *) buffer;
- buffer8 = (mpd_sint8 *) buffer;
-
- scale = info->scale;
-
- switch (format->bits) {
- case 16:
- while (bufferSize > 0) {
- temp32 = *buffer16;
- temp32 *= scale;
- *buffer16 = temp32 > 32767 ? 32767 :
- (temp32 < -32768 ? -32768 : temp32);
- buffer16++;
- bufferSize -= 2;
- }
- break;
- case 8:
- while (bufferSize > 0) {
- temp32 = *buffer8;
- temp32 *= scale;
- *buffer8 = temp32 > 127 ? 127 :
- (temp32 < -128 ? -128 : temp32);
- buffer8++;
- bufferSize--;
- }
- break;
- default:
- ERROR("%i bits not supported by doReplaygain!\n", format->bits);
- }
-}
diff --git a/trunk/src/replayGain.h b/trunk/src/replayGain.h
deleted file mode 100644
index c2d471464..000000000
--- a/trunk/src/replayGain.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * (c)2004 replayGain code by AliasMrJones
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef REPLAYGAIN_H
-#define REPLAYGAIN_H
-
-#include "audio.h"
-
-#define REPLAYGAIN_OFF 0
-#define REPLAYGAIN_TRACK 1
-#define REPLAYGAIN_ALBUM 2
-
-extern int replayGainState;
-
-typedef struct _ReplayGainInfo {
- float albumGain;
- float albumPeak;
- float trackGain;
- float trackPeak;
-
- /* used internally by mpd, to mess with it */
- float scale;
-} ReplayGainInfo;
-
-ReplayGainInfo *newReplayGainInfo(void);
-
-void freeReplayGainInfo(ReplayGainInfo * info);
-
-void initReplayGainState(void);
-
-void doReplayGain(ReplayGainInfo * info, char *buffer, int bufferSize,
- AudioFormat * format);
-
-#endif
diff --git a/trunk/src/sig_handlers.c b/trunk/src/sig_handlers.c
deleted file mode 100644
index fc29d2522..000000000
--- a/trunk/src/sig_handlers.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * (c) 2004 Nick Welch (mack@incise.org)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "sig_handlers.h"
-#include "player.h"
-#include "playerData.h"
-#include "playlist.h"
-#include "directory.h"
-#include "command.h"
-#include "signal_check.h"
-#include "log.h"
-#include "player.h"
-#include "decode.h"
-
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <unistd.h>
-
-int handlePendingSignals(void)
-{
- if (signal_is_pending(SIGINT) || signal_is_pending(SIGTERM)) {
- DEBUG("main process got SIGINT or SIGTERM, exiting\n");
- return COMMAND_RETURN_KILL;
- }
-
- if (signal_is_pending(SIGHUP)) {
- DEBUG("got SIGHUP, rereading DB\n");
- signal_clear(SIGHUP);
- if (!isUpdatingDB()) {
- readDirectoryDB();
- playlistVersionChange();
- }
- if (cycle_log_files() < 0)
- return COMMAND_RETURN_KILL;
- playerCycleLogFiles();
- }
-
- return 0;
-}
-
-static void chldSigHandler(int signal)
-{
- int status;
- int pid;
- DEBUG("main process got SIGCHLD\n");
- while (0 != (pid = wait3(&status, WNOHANG, NULL))) {
- if (pid < 0) {
- if (errno == EINTR)
- continue;
- else
- break;
- }
- player_sigChldHandler(pid, status);
- directory_sigChldHandler(pid, status);
- }
-}
-
-void initSigHandlers(void)
-{
- struct sigaction sa;
-
- sa.sa_flags = 0;
- sigemptyset(&sa.sa_mask);
- sa.sa_handler = SIG_IGN;
- while (sigaction(SIGPIPE, &sa, NULL) < 0 && errno == EINTR) ;
- sa.sa_handler = chldSigHandler;
- while (sigaction(SIGCHLD, &sa, NULL) < 0 && errno == EINTR) ;
- signal_handle(SIGUSR1);
- signal_handle(SIGINT);
- signal_handle(SIGTERM);
- signal_handle(SIGHUP);
-}
-
-void finishSigHandlers(void)
-{
- signal_unhandle(SIGINT);
- signal_unhandle(SIGUSR1);
- signal_unhandle(SIGTERM);
- signal_unhandle(SIGHUP);
-}
-
-void setSigHandlersForDecoder(void)
-{
- struct sigaction sa;
-
- finishSigHandlers();
-
- sa.sa_flags = 0;
- sigemptyset(&sa.sa_mask);
- sa.sa_handler = SIG_IGN;
- while (sigaction(SIGHUP, &sa, NULL) < 0 && errno == EINTR) ;
- while (sigaction(SIGINT, &sa, NULL) < 0 && errno == EINTR) ;
- sa.sa_flags = SA_SIGINFO;
- sa.sa_sigaction = decodeSigHandler;
- while (sigaction(SIGCHLD, &sa, NULL) < 0 && errno == EINTR) ;
- while (sigaction(SIGTERM, &sa, NULL) < 0 && errno == EINTR) ;
-}
-
-void ignoreSignals(void)
-{
- struct sigaction sa;
-
- sa.sa_flags = 0;
- sigemptyset(&sa.sa_mask);
- sa.sa_handler = SIG_IGN;
- sa.sa_sigaction = NULL;
- while (sigaction(SIGPIPE, &sa, NULL) < 0 && errno == EINTR) ;
- while (sigaction(SIGCHLD, &sa, NULL) < 0 && errno == EINTR) ;
- while (sigaction(SIGUSR1, &sa, NULL) < 0 && errno == EINTR) ;
- while (sigaction(SIGINT, &sa, NULL) < 0 && errno == EINTR) ;
- while (sigaction(SIGTERM, &sa, NULL) < 0 && errno == EINTR) ;
- while (sigaction(SIGHUP, &sa, NULL) < 0 && errno == EINTR) ;
-}
-
-void blockSignals(void)
-{
- sigset_t sset;
-
- sigemptyset(&sset);
- sigaddset(&sset, SIGCHLD);
- sigaddset(&sset, SIGUSR1);
- sigaddset(&sset, SIGHUP);
- sigaddset(&sset, SIGINT);
- sigaddset(&sset, SIGTERM);
- while (sigprocmask(SIG_BLOCK, &sset, NULL) < 0 && errno == EINTR) ;
-}
-
-void unblockSignals(void)
-{
- sigset_t sset;
-
- sigemptyset(&sset);
- sigaddset(&sset, SIGCHLD);
- sigaddset(&sset, SIGUSR1);
- sigaddset(&sset, SIGHUP);
- sigaddset(&sset, SIGINT);
- sigaddset(&sset, SIGTERM);
- while (sigprocmask(SIG_UNBLOCK, &sset, NULL) < 0 && errno == EINTR) ;
-}
diff --git a/trunk/src/sig_handlers.h b/trunk/src/sig_handlers.h
deleted file mode 100644
index 15fa181ee..000000000
--- a/trunk/src/sig_handlers.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef SIG_HANDLERS_H
-#define SIG_HANDLERS_H
-
-#include "../config.h"
-
-int handlePendingSignals(void);
-
-void initSigHandlers(void);
-
-void finishSigHandlers(void);
-
-void setSigHandlersForDecoder(void);
-
-void ignoreSignals(void);
-
-void blockSignals(void);
-
-void unblockSignals(void);
-
-void blockTermSignal(void);
-
-void unblockTermSignal(void);
-
-#endif
diff --git a/trunk/src/signal_check.c b/trunk/src/signal_check.c
deleted file mode 100644
index 77a2b1251..000000000
--- a/trunk/src/signal_check.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * (c)2004 by mackstann
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "signal_check.h"
-
-#include <errno.h>
-#include <stddef.h>
-
-static volatile sig_atomic_t __caught_signals[NSIG];
-
-static void __signal_handler(int sig)
-{
- __caught_signals[sig] = 1;
-}
-
-static void __set_signal_handler(int sig, void (*handler) (int))
-{
- struct sigaction act;
- act.sa_flags = 0;
- sigemptyset(&act.sa_mask);
- act.sa_handler = handler;
- while (sigaction(sig, &act, NULL) && errno == EINTR) ;
-}
-
-void signal_handle(int sig)
-{
- __set_signal_handler(sig, __signal_handler);
-}
-
-void signal_unhandle(int sig)
-{
- signal_clear(sig);
- __set_signal_handler(sig, SIG_DFL);
-}
-
-int signal_is_pending(int sig)
-{
- return __caught_signals[sig];
-}
-
-void signal_clear(int sig)
-{
- __caught_signals[sig] = 0;
-}
diff --git a/trunk/src/signal_check.h b/trunk/src/signal_check.h
deleted file mode 100644
index 58c9f3c3e..000000000
--- a/trunk/src/signal_check.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * (c)2004 by mackstann
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef SIGNAL_CHECK_H
-#define SIGNAL_CHECK_H
-
-#include <signal.h>
-
-void signal_handle(int sig);
-void signal_unhandle(int sig);
-int signal_is_pending(int sig);
-void signal_clear(int sig);
-
-#endif /* SIGNAL_CHECK_H */
diff --git a/trunk/src/sllist.c b/trunk/src/sllist.c
deleted file mode 100644
index 00408a3cd..000000000
--- a/trunk/src/sllist.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* a very simple singly-linked-list structure for queues/buffers */
-
-#include <string.h>
-#include "sllist.h"
-#include "utils.h"
-
-static void init_strnode(struct strnode *x, char *s)
-{
- x->data = s;
- x->next = NULL;
-}
-
-struct strnode *new_strnode(char *s)
-{
- struct strnode *x = xmalloc(sizeof(struct strnode));
- init_strnode(x, s);
- return x;
-}
-
-struct strnode *new_strnode_dup(char *s, const size_t size)
-{
- struct strnode *x = xmalloc(sizeof(struct strnode) + size);
- x->next = NULL;
- x->data = ((char *)x + sizeof(struct strnode));
- memcpy((void *)x->data, (void*)s, size);
- return x;
-}
-
-struct sllnode *new_sllnode(void *s, const size_t size)
-{
- struct sllnode *x = xmalloc(sizeof(struct sllnode) + size);
- x->next = NULL;
- x->size = size;
- x->data = ((char *)x + sizeof(struct sllnode));
- memcpy(x->data, (void *)s, size);
- return x;
-}
-
-struct strnode *dup_strlist(struct strnode *old)
-{
- struct strnode *tmp, *new, *cur;
-
- tmp = old;
- cur = new = new_strnode_dup(tmp->data, strlen(tmp->data) + 1);
- tmp = tmp->next;
- while (tmp) {
- cur->next = new_strnode_dup(tmp->data, strlen(tmp->data) + 1);
- cur = cur->next;
- tmp = tmp->next;
- }
- return new;
-}
-
-
diff --git a/trunk/src/sllist.h b/trunk/src/sllist.h
deleted file mode 100644
index 1e81abef3..000000000
--- a/trunk/src/sllist.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* a very simple singly-linked-list structure for queues/buffers */
-
-#ifndef SLLIST_H
-#define SLLIST_H
-
-#include <stddef.h>
-
-/* just free the entire structure if it's free-able, the 'data' member
- * should _NEVER_ be explicitly freed
- *
- * there's no free command, iterate through them yourself and just
- * call free() on it iff you xmalloc'd them */
-
-struct strnode {
- struct strnode *next;
- char *data;
-};
-
-struct sllnode {
- struct sllnode *next;
- void *data;
- size_t size;
-};
-
-struct strnode *new_strnode(char *s);
-
-struct strnode *new_strnode_dup(char *s, const size_t size);
-
-struct strnode *dup_strlist(struct strnode *old);
-
-struct sllnode *new_sllnode(void *s, const size_t size);
-
-
-#endif /* SLLIST_H */
diff --git a/trunk/src/song.c b/trunk/src/song.c
deleted file mode 100644
index 9bcb1a0b4..000000000
--- a/trunk/src/song.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "song.h"
-#include "ls.h"
-#include "directory.h"
-#include "utils.h"
-#include "tag.h"
-#include "log.h"
-#include "path.h"
-#include "playlist.h"
-#include "inputPlugin.h"
-#include "myfprintf.h"
-
-#define SONG_KEY "key: "
-#define SONG_MTIME "mtime: "
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-Song *newNullSong(void)
-{
- Song *song = xmalloc(sizeof(Song));
-
- song->tag = NULL;
- song->url = NULL;
- song->type = SONG_TYPE_FILE;
- song->parentDir = NULL;
-
- return song;
-}
-
-Song *newSong(char *url, int type, Directory * parentDir)
-{
- Song *song = NULL;
-
- if (strchr(url, '\n')) {
- DEBUG("newSong: '%s' is not a valid uri\n", url);
- return NULL;
- }
-
- song = newNullSong();
-
- song->url = xstrdup(url);
- song->type = type;
- song->parentDir = parentDir;
-
- assert(type == SONG_TYPE_URL || parentDir);
-
- if (song->type == SONG_TYPE_FILE) {
- InputPlugin *plugin;
- unsigned int next = 0;
- char *song_url = getSongUrl(song);
- char *abs_path = rmp2amp(utf8ToFsCharset(song_url));
- while (!song->tag && (plugin = isMusic(song_url,
- &(song->mtime),
- next++))) {
- song->tag = plugin->tagDupFunc(abs_path);
- }
- if (!song->tag || song->tag->time < 0) {
- freeSong(song);
- song = NULL;
- }
- }
-
- return song;
-}
-
-void freeSong(Song * song)
-{
- deleteASongFromPlaylist(song);
- freeJustSong(song);
-}
-
-void freeJustSong(Song * song)
-{
- free(song->url);
- if (song->tag)
- freeMpdTag(song->tag);
- free(song);
- getSongUrl(NULL);
-}
-
-SongList *newSongList(void)
-{
- return makeList((ListFreeDataFunc *) freeSong, 0);
-}
-
-Song *addSongToList(SongList * list, char *url, char *utf8path,
- int songType, Directory * parentDirectory)
-{
- Song *song = NULL;
-
- switch (songType) {
- case SONG_TYPE_FILE:
- if (isMusic(utf8path, NULL, 0)) {
- song = newSong(url, songType, parentDirectory);
- }
- break;
- case SONG_TYPE_URL:
- song = newSong(url, songType, parentDirectory);
- break;
- default:
- DEBUG("addSongToList: Trying to add an invalid song type\n");
- }
-
- if (song == NULL)
- return NULL;
-
- insertInList(list, song->url, (void *)song);
-
- return song;
-}
-
-void freeSongList(SongList * list)
-{
- freeList(list);
-}
-
-void printSongUrl(int fd, Song * song)
-{
- if (song->parentDir && song->parentDir->path) {
- fdprintf(fd, "%s%s/%s\n", SONG_FILE,
- getDirectoryPath(song->parentDir), song->url);
- } else {
- fdprintf(fd, "%s%s\n", SONG_FILE, song->url);
- }
-}
-
-int printSongInfo(int fd, Song * song)
-{
- printSongUrl(fd, song);
-
- if (song->tag)
- printMpdTag(fd, song->tag);
-
- return 0;
-}
-
-int printSongInfoFromList(int fd, SongList * list)
-{
- ListNode *tempNode = list->firstNode;
-
- while (tempNode != NULL) {
- printSongInfo(fd, (Song *) tempNode->data);
- tempNode = tempNode->nextNode;
- }
-
- return 0;
-}
-
-void writeSongInfoFromList(FILE * fp, SongList * list)
-{
- ListNode *tempNode = list->firstNode;
-
- fprintf(fp, "%s\n", SONG_BEGIN);
-
- while (tempNode != NULL) {
- fprintf(fp, "%s%s\n", SONG_KEY, tempNode->key);
- fflush(fp);
- printSongInfo(fileno(fp), (Song *) tempNode->data);
- fprintf(fp, "%s%li\n", SONG_MTIME,
- (long)((Song *) tempNode->data)->mtime);
- tempNode = tempNode->nextNode;
- }
-
- fprintf(fp, "%s\n", SONG_END);
-}
-
-static void insertSongIntoList(SongList * list, ListNode ** nextSongNode,
- char *key, Song * song)
-{
- ListNode *nodeTemp;
- int cmpRet = 0;
-
- while (*nextSongNode
- && (cmpRet = strcmp(key, (*nextSongNode)->key)) > 0) {
- nodeTemp = (*nextSongNode)->nextNode;
- deleteNodeFromList(list, *nextSongNode);
- *nextSongNode = nodeTemp;
- }
-
- if (!(*nextSongNode)) {
- insertInList(list, song->url, (void *)song);
- } else if (cmpRet == 0) {
- Song *tempSong = (Song *) ((*nextSongNode)->data);
- if (tempSong->mtime != song->mtime) {
- freeMpdTag(tempSong->tag);
- tempSong->tag = song->tag;
- tempSong->mtime = song->mtime;
- song->tag = NULL;
- }
- freeJustSong(song);
- *nextSongNode = (*nextSongNode)->nextNode;
- } else {
- insertInListBeforeNode(list, *nextSongNode, -1, song->url,
- (void *)song);
- }
-}
-
-static int matchesAnMpdTagItemKey(char *buffer, int *itemType)
-{
- int i;
-
- for (i = 0; i < TAG_NUM_OF_ITEM_TYPES; i++) {
- if (0 == strncmp(mpdTagItemKeys[i], buffer,
- strlen(mpdTagItemKeys[i]))) {
- *itemType = i;
- return 1;
- }
- }
-
- return 0;
-}
-
-void readSongInfoIntoList(FILE * fp, SongList * list, Directory * parentDir)
-{
- char buffer[MAXPATHLEN + 1024];
- int bufferSize = MAXPATHLEN + 1024;
- Song *song = NULL;
- ListNode *nextSongNode = list->firstNode;
- ListNode *nodeTemp;
- int itemType;
-
- while (myFgets(buffer, bufferSize, fp) && 0 != strcmp(SONG_END, buffer)) {
- if (0 == strncmp(SONG_KEY, buffer, strlen(SONG_KEY))) {
- if (song) {
- insertSongIntoList(list, &nextSongNode,
- song->url, song);
- song = NULL;
- }
-
- song = newNullSong();
- song->url = xstrdup(buffer + strlen(SONG_KEY));
- song->type = SONG_TYPE_FILE;
- song->parentDir = parentDir;
- } else if (0 == strncmp(SONG_FILE, buffer, strlen(SONG_FILE))) {
- if (!song)
- FATAL("Problems reading song info\n");
- /* we don't need this info anymore
- song->url = xstrdup(&(buffer[strlen(SONG_FILE)]));
- */
- } else if (matchesAnMpdTagItemKey(buffer, &itemType)) {
- if (!song->tag)
- song->tag = newMpdTag();
- addItemToMpdTag(song->tag, itemType,
- &(buffer
- [strlen(mpdTagItemKeys[itemType]) +
- 2]));
- } else if (0 == strncmp(SONG_TIME, buffer, strlen(SONG_TIME))) {
- if (!song->tag)
- song->tag = newMpdTag();
- song->tag->time = atoi(&(buffer[strlen(SONG_TIME)]));
- } else if (0 == strncmp(SONG_MTIME, buffer, strlen(SONG_MTIME))) {
- song->mtime = atoi(&(buffer[strlen(SONG_MTIME)]));
- }
- /* ignore empty lines (starting with '\0') */
- else if (*buffer)
- FATAL("songinfo: unknown line in db: %s\n", buffer);
- }
-
- if (song) {
- insertSongIntoList(list, &nextSongNode, song->url, song);
- song = NULL;
- }
-
- while (nextSongNode) {
- nodeTemp = nextSongNode->nextNode;
- deleteNodeFromList(list, nextSongNode);
- nextSongNode = nodeTemp;
- }
-}
-
-int updateSongInfo(Song * song)
-{
- if (song->type == SONG_TYPE_FILE) {
- InputPlugin *plugin;
- unsigned int next = 0;
- char *song_url = getSongUrl(song);
- char *abs_path = rmp2amp(song_url);
-
- if (song->tag)
- freeMpdTag(song->tag);
-
- song->tag = NULL;
-
- while (!song->tag && (plugin = isMusic(song_url,
- &(song->mtime),
- next++))) {
- song->tag = plugin->tagDupFunc(abs_path);
- }
- if (!song->tag || song->tag->time < 0)
- return -1;
- }
-
- return 0;
-}
-
-/* pass song = NULL to reset, we do this freeJustSong(), so that if
- * we free and recreate this memory we make sure to print it correctly*/
-char *getSongUrl(Song * song)
-{
- static char *buffer;
- static int bufferSize;
- static Song *lastSong;
- int slen;
- int dlen;
- int size;
-
- if (!song) {
- lastSong = song;
- return NULL;
- }
-
- if (!song->parentDir || !song->parentDir->path)
- return song->url;
-
- /* be careful with this! */
- if (song == lastSong)
- return buffer;
-
- slen = strlen(song->url);
- dlen = strlen(getDirectoryPath(song->parentDir));
-
- size = slen + dlen + 2;
-
- if (size > bufferSize) {
- buffer = xrealloc(buffer, size);
- bufferSize = size;
- }
-
- strcpy(buffer, getDirectoryPath(song->parentDir));
- buffer[dlen] = '/';
- strcpy(buffer + dlen + 1, song->url);
-
- return buffer;
-}
diff --git a/trunk/src/song.h b/trunk/src/song.h
deleted file mode 100644
index c4100d2a2..000000000
--- a/trunk/src/song.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef SONG_H
-#define SONG_H
-
-#include "../config.h"
-
-#include <sys/param.h>
-#include <time.h>
-
-#include "tag.h"
-#include "list.h"
-
-#define SONG_BEGIN "songList begin"
-#define SONG_END "songList end"
-
-#define SONG_TYPE_FILE 1
-#define SONG_TYPE_URL 2
-
-#define SONG_FILE "file: "
-#define SONG_TIME "Time: "
-
-typedef struct _Song {
- char *url;
- mpd_sint8 type;
- MpdTag *tag;
- struct _Directory *parentDir;
- time_t mtime;
-} Song;
-
-typedef List SongList;
-
-Song *newNullSong(void);
-
-Song *newSong(char *url, int songType, struct _Directory *parentDir);
-
-void freeSong(Song *);
-
-void freeJustSong(Song *);
-
-SongList *newSongList(void);
-
-void freeSongList(SongList * list);
-
-Song *addSongToList(SongList * list, char *url, char *utf8path,
- int songType, struct _Directory *parentDir);
-
-int printSongInfo(int fd, Song * song);
-
-int printSongInfoFromList(int fd, SongList * list);
-
-void writeSongInfoFromList(FILE * fp, SongList * list);
-
-void readSongInfoIntoList(FILE * fp, SongList * list,
- struct _Directory *parent);
-
-int updateSongInfo(Song * song);
-
-void printSongUrl(int fd, Song * song);
-
-char *getSongUrl(Song * song);
-
-#endif
diff --git a/trunk/src/state_file.c b/trunk/src/state_file.c
deleted file mode 100644
index ac2fcde7a..000000000
--- a/trunk/src/state_file.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "../config.h"
-#include "state_file.h"
-#include "conf.h"
-#include "gcc.h"
-#include "log.h"
-#include "audio.h"
-#include "playlist.h"
-#include "utils.h"
-#include "volume.h"
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-static struct _sf_cb {
- void (*reader)(FILE *);
- void (*writer)(FILE *);
-} sf_callbacks [] = {
- { read_sw_volume_state, save_sw_volume_state },
- { readAudioDevicesState, saveAudioDevicesState },
- { readPlaylistState, savePlaylistState },
-};
-
-static const char *sfpath;
-
-static void get_state_file_path(void)
-{
- ConfigParam *param;
- if (sfpath)
- return;
- param = parseConfigFilePath(CONF_STATE_FILE, 0);
- if (param)
- sfpath = (const char *)param->value;
-}
-
-void write_state_file(void)
-{
- int i;
- FILE *fp;
-
- if (!sfpath)
- return;
- while (!(fp = fopen(sfpath, "w")) && errno == EINTR);
-
- if (mpd_unlikely(!fp)) {
- ERROR("problems opening state file \"%s\" for writing: %s\n",
- sfpath, strerror(errno));
- return;
- }
-
- for (i = 0; i < ARRAY_SIZE(sf_callbacks); i++)
- sf_callbacks[i].writer(fp);
-
- while(fclose(fp) && errno == EINTR) /* nothing */;
-}
-
-void read_state_file(void)
-{
- struct stat st;
- int i;
- FILE *fp;
-
- get_state_file_path();
- if (!sfpath)
- return;
- if (stat(sfpath, &st) < 0) {
- DEBUG("failed to stat state file: %s\n", sfpath);
- return;
- }
- if (!S_ISREG(st.st_mode))
- FATAL("state file \"%s\" is not a regular file\n", sfpath);
-
- while (!(fp = fopen(sfpath, "r")) && errno == EINTR);
- if (mpd_unlikely(!fp)) {
- FATAL("problems opening state file \"%s\" for reading: %s\n",
- sfpath, strerror(errno));
- }
- for (i = 0; i < ARRAY_SIZE(sf_callbacks); i++) {
- sf_callbacks[i].reader(fp);
- rewind(fp);
- }
-
- while(fclose(fp) && errno == EINTR) /* nothing */;
-}
-
-void mpd_noreturn state_file_fatal(void)
-{
- FATAL("error parsing state file \"%s\"\n", sfpath);
- exit(EXIT_FAILURE);
-}
-
diff --git a/trunk/src/state_file.h b/trunk/src/state_file.h
deleted file mode 100644
index 4a7d012ec..000000000
--- a/trunk/src/state_file.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef STATE_FILE_H
-#define STATE_FILE_H
-
-#include "gcc.h"
-
-#include <stdio.h>
-
-void write_state_file(void);
-void read_state_file(void);
-void mpd_noreturn state_file_fatal(void);
-
-#endif /* STATE_FILE_H */
diff --git a/trunk/src/stats.c b/trunk/src/stats.c
deleted file mode 100644
index 5045077c0..000000000
--- a/trunk/src/stats.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "stats.h"
-
-#include "directory.h"
-#include "myfprintf.h"
-#include "player.h"
-#include "tag.h"
-#include "tagTracker.h"
-
-#include <time.h>
-
-Stats stats;
-
-void initStats(void)
-{
- stats.daemonStart = time(NULL);
- stats.numberOfSongs = 0;
-}
-
-int printStats(int fd)
-{
- fdprintf(fd, "artists: %i\n", getNumberOfTagItems(TAG_ITEM_ARTIST));
- fdprintf(fd, "albums: %i\n", getNumberOfTagItems(TAG_ITEM_ALBUM));
- fdprintf(fd, "songs: %i\n", stats.numberOfSongs);
- fdprintf(fd, "uptime: %li\n", time(NULL) - stats.daemonStart);
- fdprintf(fd, "playtime: %li\n",
- (long)(getPlayerTotalPlayTime() + 0.5));
- fdprintf(fd, "db_playtime: %li\n", stats.dbPlayTime);
- fdprintf(fd, "db_update: %li\n", getDbModTime());
- return 0;
-}
diff --git a/trunk/src/stats.h b/trunk/src/stats.h
deleted file mode 100644
index cd7d0122c..000000000
--- a/trunk/src/stats.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef STATS_H
-#define STATS_H
-
-#include "../config.h"
-
-#include <stdio.h>
-
-typedef struct _Stats {
- unsigned long daemonStart;
- int numberOfSongs;
- unsigned long dbPlayTime;
- /*unsigned long playTime;
- unsigned long songsPlayed; */
-} Stats;
-
-extern Stats stats;
-
-void initStats(void);
-
-int printStats(int fd);
-
-#endif
diff --git a/trunk/src/storedPlaylist.c b/trunk/src/storedPlaylist.c
deleted file mode 100644
index 322cb1b5b..000000000
--- a/trunk/src/storedPlaylist.c
+++ /dev/null
@@ -1,501 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "storedPlaylist.h"
-#include "log.h"
-#include "path.h"
-#include "utils.h"
-#include "playlist.h"
-#include "ack.h"
-#include "command.h"
-#include "ls.h"
-#include "directory.h"
-
-#include <string.h>
-#include <errno.h>
-
-static char *utf8pathToFsPathInStoredPlaylist(const char *utf8path, int fd)
-{
- char *file;
- char *rfile;
- char *actualFile;
-
- if (strstr(utf8path, "/")) {
- commandError(fd, ACK_ERROR_ARG, "playlist name \"%s\" is "
- "invalid: playlist names may not contain slashes",
- utf8path);
- return NULL;
- }
-
- file = utf8ToFsCharset((char *)utf8path);
-
- rfile = xmalloc(strlen(file) + strlen(".") +
- strlen(PLAYLIST_FILE_SUFFIX) + 1);
-
- strcpy(rfile, file);
- strcat(rfile, ".");
- strcat(rfile, PLAYLIST_FILE_SUFFIX);
-
- actualFile = rpp2app(rfile);
-
- free(rfile);
-
- return actualFile;
-}
-
-static unsigned int lengthOfStoredPlaylist(StoredPlaylist *sp)
-{
- return sp->list->numberOfNodes;
-}
-
-static ListNode *nodeOfStoredPlaylist(StoredPlaylist *sp, int index)
-{
- int forward;
- ListNode *node;
- int i;
-
- if (index >= lengthOfStoredPlaylist(sp) || index < 0)
- return NULL;
-
- if (index > lengthOfStoredPlaylist(sp)/2) {
- forward = 0;
- node = sp->list->lastNode;
- i = lengthOfStoredPlaylist(sp) - 1;
- } else {
- forward = 1;
- node = sp->list->firstNode;
- i = 0;
- }
-
- while (node != NULL) {
- if (i == index)
- return node;
-
- if (forward) {
- i++;
- node = node->nextNode;
- } else {
- i--;
- node = node->prevNode;
- }
- }
-
- return NULL;
-}
-
-static void appendSongToStoredPlaylist(StoredPlaylist *sp, Song *song)
-{
- insertInListWithoutKey(sp->list, xstrdup(getSongUrl(song)));
-}
-
-StoredPlaylist *newStoredPlaylist(const char *utf8name, int fd, int ignoreExisting)
-{
- struct stat buf;
- char *filename = NULL;
- StoredPlaylist *sp = calloc(1, sizeof(*sp));
- if (!sp)
- return NULL;
-
- if (utf8name) {
- filename = utf8pathToFsPathInStoredPlaylist(utf8name, fd);
-
- if (filename && stat(filename, &buf) == 0 &&
- ignoreExisting == 0) {
- commandError(fd, ACK_ERROR_EXIST,
- "a file or directory already exists with "
- "the name \"%s\"", utf8name);
- free(sp);
- return NULL;
- }
- }
-
- sp->list = makeList(DEFAULT_FREE_DATA_FUNC, 0);
- sp->fd = fd;
-
- if (filename)
- sp->fspath = xstrdup(filename);
-
- return sp;
-}
-
-StoredPlaylist *loadStoredPlaylist(const char *utf8path, int fd)
-{
- char *filename;
- StoredPlaylist *sp;
- FILE *file;
- char s[MAXPATHLEN + 1];
- int slength = 0;
- char *temp = utf8ToFsCharset((char *)utf8path);
- char *parent = parentPath(temp);
- int parentlen = strlen(parent);
- int tempInt;
- int commentCharFound = 0;
- Song *song;
-
- filename = utf8pathToFsPathInStoredPlaylist(utf8path, fd);
- if (!filename)
- return NULL;
-
- while (!(file = fopen(filename, "r")) && errno == EINTR);
- if (file == NULL) {
- commandError(fd, ACK_ERROR_NO_EXIST, "could not open file "
- "\"%s\": %s", filename, strerror(errno));
- return NULL;
- }
-
- sp = newStoredPlaylist(utf8path, fd, 1);
- if (!sp)
- goto out;
-
- while ((tempInt = fgetc(file)) != EOF) {
- s[slength] = tempInt;
- if (s[slength] == '\n' || s[slength] == '\0') {
- commentCharFound = 0;
- s[slength] = '\0';
- if (s[0] == PLAYLIST_COMMENT)
- commentCharFound = 1;
- if (strncmp(s, musicDir, strlen(musicDir)) == 0) {
- strcpy(s, &(s[strlen(musicDir)]));
- } else if (parentlen) {
- temp = xstrdup(s);
- memset(s, 0, MAXPATHLEN + 1);
- strcpy(s, parent);
- strncat(s, "/", MAXPATHLEN - parentlen);
- strncat(s, temp, MAXPATHLEN - parentlen - 1);
- if (strlen(s) >= MAXPATHLEN) {
- commandError(sp->fd,
- ACK_ERROR_PLAYLIST_LOAD,
- "\"%s\" is too long", temp);
- free(temp);
- freeStoredPlaylist(sp);
- sp = NULL;
- goto out;
- }
- free(temp);
- }
- slength = 0;
- temp = fsCharsetToUtf8(s);
- if (temp && !commentCharFound) {
- song = getSongFromDB(temp);
- if (song) {
- appendSongToStoredPlaylist(sp, song);
- continue;
- }
-
- if (!isValidRemoteUtf8Url(temp))
- continue;
-
- song = newSong(temp, SONG_TYPE_URL, NULL);
- if (song) {
- appendSongToStoredPlaylist(sp, song);
- freeJustSong(song);
- }
- }
- } else if (slength == MAXPATHLEN) {
- s[slength] = '\0';
- commandError(sp->fd, ACK_ERROR_PLAYLIST_LOAD,
- "line \"%s\" in playlist \"%s\" "
- "is too long", s, utf8path);
- freeStoredPlaylist(sp);
- sp = NULL;
- goto out;
- } else if (s[slength] != '\r') {
- slength++;
- }
- }
-
-out:
- while (fclose(file) && errno == EINTR);
- return sp;
-}
-
-void freeStoredPlaylist(StoredPlaylist *sp)
-{
- if (sp->list)
- freeList(sp->list);
- if (sp->fspath)
- free(sp->fspath);
-
- free(sp);
-}
-
-static int moveSongInStoredPlaylist(int fd, StoredPlaylist *sp, int src, int dest)
-{
- ListNode *srcNode, *destNode;
-
- if (src >= lengthOfStoredPlaylist(sp) || dest >= lengthOfStoredPlaylist(sp) || src < 0 || dest < 0 || src == dest) {
- commandError(fd, ACK_ERROR_ARG, "argument out of range");
- return -1;
- }
-
- srcNode = nodeOfStoredPlaylist(sp, src);
- if (!srcNode)
- return -1;
-
- destNode = nodeOfStoredPlaylist(sp, dest);
-
- /* remove src */
- if (srcNode->prevNode)
- srcNode->prevNode->nextNode = srcNode->nextNode;
- else
- sp->list->firstNode = srcNode->nextNode;
-
- if (srcNode->nextNode)
- srcNode->nextNode->prevNode = srcNode->prevNode;
- else
- sp->list->lastNode = srcNode->prevNode;
-
- /* this is all a bit complicated - but I tried to
- * maintain the same order stuff is moved as in the
- * real playlist */
- if (dest == 0) {
- sp->list->firstNode->prevNode = srcNode;
- srcNode->nextNode = sp->list->firstNode;
- srcNode->prevNode = NULL;
- sp->list->firstNode = srcNode;
- } else if ((dest + 1) == lengthOfStoredPlaylist(sp)) {
- sp->list->lastNode->nextNode = srcNode;
- srcNode->nextNode = NULL;
- srcNode->prevNode = sp->list->lastNode;
- sp->list->lastNode = srcNode;
- } else {
- if (destNode == NULL) {
- /* this shouldn't be happening. */
- return -1;
- }
-
- if (src > dest) {
- destNode->prevNode->nextNode = srcNode;
- srcNode->prevNode = destNode->prevNode;
- srcNode->nextNode = destNode;
- destNode->prevNode = srcNode;
- } else {
- destNode->nextNode->prevNode = srcNode;
- srcNode->prevNode = destNode;
- srcNode->nextNode = destNode->nextNode;
- destNode->nextNode = srcNode;
- }
- }
-
- return 0;
-}
-
-int moveSongInStoredPlaylistByPath(int fd, const char *utf8path, int src, int dest)
-{
- StoredPlaylist *sp = loadStoredPlaylist(utf8path, fd);
- if (!sp) {
- commandError(fd, ACK_ERROR_UNKNOWN, "could not open playlist");
- return -1;
- }
-
- if (moveSongInStoredPlaylist(fd, sp, src, dest) != 0) {
- freeStoredPlaylist(sp);
- return -1;
- }
-
- if (writeStoredPlaylist(sp) != 0) {
- commandError(fd, ACK_ERROR_UNKNOWN, "failed to save playlist");
- freeStoredPlaylist(sp);
- return -1;
- }
-
- freeStoredPlaylist(sp);
- return 0;
-}
-
-/* Not used currently
-static void removeAllFromStoredPlaylist(StoredPlaylist *sp)
-{
- freeList(sp->list);
- sp->list = makeList(DEFAULT_FREE_DATA_FUNC, 0);
-}
-*/
-
-int removeAllFromStoredPlaylistByPath(int fd, const char *utf8path)
-{
- char *filename;
- FILE *file;
-
- filename = utf8pathToFsPathInStoredPlaylist(utf8path, fd);
- if (!filename)
- return -1;
-
- while (!(file = fopen(filename, "w")) && errno == EINTR);
- if (file == NULL) {
- commandError(fd, ACK_ERROR_NO_EXIST, "could not open file "
- "\"%s\": %s", filename, strerror(errno));
- return -1;
- }
-
- while (fclose(file) != 0 && errno == EINTR);
- return 0;
-}
-
-static int removeOneSongFromStoredPlaylist(int fd, StoredPlaylist *sp, int pos)
-{
- ListNode *node = nodeOfStoredPlaylist(sp, pos);
- if (!node) {
- commandError(fd, ACK_ERROR_ARG,
- "could not find song at position");
- return -1;
- }
-
- deleteNodeFromList(sp->list, node);
-
- return 0;
-}
-
-int removeOneSongFromStoredPlaylistByPath(int fd, const char *utf8path, int pos)
-{
- StoredPlaylist *sp = loadStoredPlaylist(utf8path, fd);
- if (!sp) {
- commandError(fd, ACK_ERROR_UNKNOWN, "could not open playlist");
- return -1;
- }
-
- if (removeOneSongFromStoredPlaylist(fd, sp, pos) != 0) {
- freeStoredPlaylist(sp);
- return -1;
- }
-
- if (writeStoredPlaylist(sp) != 0) {
- commandError(fd, ACK_ERROR_UNKNOWN, "failed to save playlist");
- freeStoredPlaylist(sp);
- return -1;
- }
-
- freeStoredPlaylist(sp);
- return 0;
-}
-
-static int writeStoredPlaylistToPath(StoredPlaylist *sp, const char *fspath)
-{
- ListNode *node;
- FILE *file;
- char *s;
-
- if (fspath == NULL)
- return -1;
-
- while (!(file = fopen(fspath, "w")) && errno == EINTR);
- if (file == NULL) {
- commandError(sp->fd, ACK_ERROR_NO_EXIST, "could not open file "
- "\"%s\": %s", fspath, strerror(errno));
- return -1;
- }
-
- node = sp->list->firstNode;
- while (node != NULL) {
- s = (char *)node->data;
- if (isValidRemoteUtf8Url(s) || !playlist_saveAbsolutePaths)
- s = utf8ToFsCharset(s);
- else
- s = rmp2amp(utf8ToFsCharset(s));
- fprintf(file, "%s\n", s);
- node = node->nextNode;
- }
-
- while (fclose(file) != 0 && errno == EINTR);
- return 0;
-}
-
-int writeStoredPlaylist(StoredPlaylist *sp)
-{
- return writeStoredPlaylistToPath(sp, sp->fspath);
-}
-
-int appendSongToStoredPlaylistByPath(int fd, const char *utf8path, Song *song)
-{
- char *filename;
- FILE *file;
- char *s;
-
- filename = utf8pathToFsPathInStoredPlaylist(utf8path, fd);
- if (!filename)
- return -1;
-
- while (!(file = fopen(filename, "a")) && errno == EINTR);
- if (file == NULL) {
- commandError(fd, ACK_ERROR_NO_EXIST, "could not open file "
- "\"%s\": %s", filename, strerror(errno));
- return -1;
- }
-
- if (playlist_saveAbsolutePaths && song->type == SONG_TYPE_FILE)
- s = rmp2amp(utf8ToFsCharset(getSongUrl(song)));
- else
- s = utf8ToFsCharset(getSongUrl(song));
-
- fprintf(file, "%s\n", s);
-
- while (fclose(file) != 0 && errno == EINTR);
- return 0;
-}
-
-void appendPlaylistToStoredPlaylist(StoredPlaylist *sp, Playlist *playlist)
-{
- int i;
- for (i = 0; i < playlist->length; i++)
- appendSongToStoredPlaylist(sp, playlist->songs[i]);
-}
-
-int renameStoredPlaylist(int fd, const char *utf8from, const char *utf8to)
-{
- struct stat st;
- char *from;
- char *to;
- int ret = 0;
-
- from = xstrdup(utf8pathToFsPathInStoredPlaylist(utf8from, fd));
- if (!from)
- return -1;
-
- to = xstrdup(utf8pathToFsPathInStoredPlaylist(utf8to, fd));
- if (!to) {
- free(from);
- return -1;
- }
-
- if (stat(from, &st) != 0) {
- commandError(fd, ACK_ERROR_NO_EXIST,
- "no playlist named \"%s\"", utf8from);
- ret = -1;
- goto out;
- }
-
- if (stat(to, &st) == 0) {
- commandError(fd, ACK_ERROR_EXIST, "a file or directory "
- "already exists with the name \"%s\"", utf8to);
- ret = -1;
- goto out;
- }
-
- if (rename(from, to) < 0) {
- commandError(fd, ACK_ERROR_UNKNOWN,
- "could not rename playlist \"%s\" to \"%s\": %s",
- utf8from, utf8to, strerror(errno));
- ret = -1;
- goto out;
- }
-
-out:
- free(from);
- free(to);
-
- return ret;
-}
diff --git a/trunk/src/storedPlaylist.h b/trunk/src/storedPlaylist.h
deleted file mode 100644
index 1c30e814a..000000000
--- a/trunk/src/storedPlaylist.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef STORED_PLAYLIST_H
-#define STORED_PLAYLIST_H
-
-#include "song.h"
-#include "list.h"
-#include "playlist.h"
-
-typedef struct _storedPlaylist {
- List *list;
- unsigned int length;
- char *fspath;
- int fd;
-} StoredPlaylist;
-
-StoredPlaylist *newStoredPlaylist(const char *filename, int fd, int ignoreExisting);
-StoredPlaylist *loadStoredPlaylist(const char *utf8path, int fd);
-void freeStoredPlaylist(StoredPlaylist *sp);
-
-int moveSongInStoredPlaylistByPath(int fd, const char *utf8path, int src, int dest);
-int removeAllFromStoredPlaylistByPath(int fd, const char *utf8path);
-int removeOneSongFromStoredPlaylistByPath(int fd, const char *utf8path, int pos);
-
-int writeStoredPlaylist(StoredPlaylist *sp);
-
-int appendSongToStoredPlaylistByPath(int fd, const char *utf8path, Song *song);
-void appendPlaylistToStoredPlaylist(StoredPlaylist *sp, Playlist *playlist);
-
-int renameStoredPlaylist(int fd, const char *utf8from, const char *utf8to);
-
-#endif
diff --git a/trunk/src/tag.c b/trunk/src/tag.c
deleted file mode 100644
index 92a597d0e..000000000
--- a/trunk/src/tag.c
+++ /dev/null
@@ -1,646 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "tag.h"
-#include "path.h"
-#include "myfprintf.h"
-#include "utils.h"
-#include "utf8.h"
-#include "log.h"
-#include "inputStream.h"
-#include "conf.h"
-#include "charConv.h"
-#include "tagTracker.h"
-#include "mpd_types.h"
-#include "gcc.h"
-#include "song.h"
-
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <errno.h>
-
-#ifdef HAVE_ID3TAG
-# define isId3v1(tag) (id3_tag_options(tag, 0, 0) & ID3_TAG_OPTION_ID3V1)
-# ifndef ID3_FRAME_COMPOSER
-# define ID3_FRAME_COMPOSER "TCOM"
-# endif
-# ifndef ID3_FRAME_PERFORMER
-# define ID3_FRAME_PERFORMER "TOPE"
-# endif
-# ifndef ID3_FRAME_DISC
-# define ID3_FRAME_DISC "TPOS"
-# endif
-#endif
-
-char *mpdTagItemKeys[TAG_NUM_OF_ITEM_TYPES] = {
- "Artist",
- "Album",
- "Title",
- "Track",
- "Name",
- "Genre",
- "Date",
- "Composer",
- "Performer",
- "Comment",
- "Disc"
-};
-
-static mpd_sint8 ignoreTagItems[TAG_NUM_OF_ITEM_TYPES];
-
-void initTagConfig(void)
-{
- int quit = 0;
- char *temp;
- char *s;
- char *c;
- ConfigParam *param;
- int i;
-
- /* parse the "metadata_to_use" config parameter below */
-
- memset(ignoreTagItems, 0, TAG_NUM_OF_ITEM_TYPES);
- ignoreTagItems[TAG_ITEM_COMMENT] = 1; /* ignore comments by default */
-
- param = getConfigParam(CONF_METADATA_TO_USE);
-
- if (!param)
- return;
-
- memset(ignoreTagItems, 1, TAG_NUM_OF_ITEM_TYPES);
-
- if (0 == strcasecmp(param->value, "none"))
- return;
-
- temp = c = s = xstrdup(param->value);
- while (!quit) {
- if (*s == ',' || *s == '\0') {
- if (*s == '\0')
- quit = 1;
- *s = '\0';
- for (i = 0; i < TAG_NUM_OF_ITEM_TYPES; i++) {
- if (strcasecmp(c, mpdTagItemKeys[i]) == 0) {
- ignoreTagItems[i] = 0;
- break;
- }
- }
- if (strlen(c) && i == TAG_NUM_OF_ITEM_TYPES) {
- FATAL("error parsing metadata item \"%s\" at "
- "line %i\n", c, param->line);
- }
- s++;
- c = s;
- }
- s++;
- }
-
- free(temp);
-}
-
-void printTagTypes(int fd)
-{
- int i;
-
- for (i = 0; i < TAG_NUM_OF_ITEM_TYPES; i++) {
- if (ignoreTagItems[i] == 0)
- fdprintf(fd, "tagtype: %s\n", mpdTagItemKeys[i]);
- }
-}
-
-void printMpdTag(int fd, MpdTag * tag)
-{
- int i;
-
- if (tag->time >= 0)
- fdprintf(fd, SONG_TIME "%i\n", tag->time);
-
- for (i = 0; i < tag->numOfItems; i++) {
- fdprintf(fd, "%s: %s\n", mpdTagItemKeys[tag->items[i].type],
- tag->items[i].value);
- }
-}
-
-#ifdef HAVE_ID3TAG
-static MpdTag *getID3Info(struct id3_tag *tag, char *id, int type, MpdTag * mpdTag)
-{
- struct id3_frame const *frame;
- id3_ucs4_t const *ucs4;
- id3_utf8_t *utf8;
- id3_latin1_t *isostr;
- union id3_field const *field;
- unsigned int nstrings;
- int i;
- char *encoding;
-
- frame = id3_tag_findframe(tag, id, 0);
- if (!frame || frame->nfields < 2)
- return mpdTag;
-
- field = &frame->fields[1];
- nstrings = id3_field_getnstrings(field);
-
- for (i = 0; i < nstrings; i++) {
- ucs4 = id3_field_getstrings(field, i);
- if (!ucs4)
- continue;
-
- if (type == TAG_ITEM_GENRE)
- ucs4 = id3_genre_name(ucs4);
-
- if (isId3v1(tag) &&
- (encoding = getConfigParamValue(CONF_ID3V1_ENCODING))) {
- isostr = id3_ucs4_latin1duplicate(ucs4);
- if (mpd_unlikely(!isostr))
- continue;
- setCharSetConversion("UTF-8", encoding);
- utf8 = (id3_utf8_t *)convStrDup((char *)isostr);
- if (!utf8) {
- DEBUG("Unable to convert %s string to UTF-8: "
- "'%s'\n", encoding, isostr);
- free(isostr);
- continue;
- }
- free(isostr);
- } else {
- utf8 = id3_ucs4_utf8duplicate(ucs4);
- if (mpd_unlikely(!utf8))
- continue;
- }
-
- if (mpdTag == NULL)
- mpdTag = newMpdTag();
- addItemToMpdTag(mpdTag, type, (char *)utf8);
-
- free(utf8);
- }
-
- return mpdTag;
-}
-#endif
-
-#ifdef HAVE_ID3TAG
-MpdTag *parseId3Tag(struct id3_tag * tag)
-{
- MpdTag *ret = NULL;
-
- ret = getID3Info(tag, ID3_FRAME_ARTIST, TAG_ITEM_ARTIST, ret);
- ret = getID3Info(tag, ID3_FRAME_TITLE, TAG_ITEM_TITLE, ret);
- ret = getID3Info(tag, ID3_FRAME_ALBUM, TAG_ITEM_ALBUM, ret);
- ret = getID3Info(tag, ID3_FRAME_TRACK, TAG_ITEM_TRACK, ret);
- ret = getID3Info(tag, ID3_FRAME_YEAR, TAG_ITEM_DATE, ret);
- ret = getID3Info(tag, ID3_FRAME_GENRE, TAG_ITEM_GENRE, ret);
- ret = getID3Info(tag, ID3_FRAME_COMPOSER, TAG_ITEM_COMPOSER, ret);
- ret = getID3Info(tag, ID3_FRAME_PERFORMER, TAG_ITEM_PERFORMER, ret);
- ret = getID3Info(tag, ID3_FRAME_COMMENT, TAG_ITEM_COMMENT, ret);
- ret = getID3Info(tag, ID3_FRAME_DISC, TAG_ITEM_DISC, ret);
-
- return ret;
-}
-#endif
-
-#ifdef HAVE_ID3TAG
-static int fillBuffer(void *buf, size_t size, FILE * stream,
- long offset, int whence)
-{
- if (fseek(stream, offset, whence) != 0) return 0;
- return fread(buf, 1, size, stream);
-}
-#endif
-
-#ifdef HAVE_ID3TAG
-static int getId3v2FooterSize(FILE * stream, long offset, int whence)
-{
- id3_byte_t buf[ID3_TAG_QUERYSIZE];
- int bufsize;
-
- bufsize = fillBuffer(buf, ID3_TAG_QUERYSIZE, stream, offset, whence);
- if (bufsize <= 0) return 0;
- return id3_tag_query(buf, bufsize);
-}
-#endif
-
-#ifdef HAVE_ID3TAG
-static struct id3_tag *getId3Tag(FILE * stream, long offset, int whence)
-{
- struct id3_tag *tag;
- id3_byte_t queryBuf[ID3_TAG_QUERYSIZE];
- id3_byte_t *tagBuf;
- int tagSize;
- int queryBufSize;
- int tagBufSize;
-
- /* It's ok if we get less than we asked for */
- queryBufSize = fillBuffer(queryBuf, ID3_TAG_QUERYSIZE,
- stream, offset, whence);
- if (queryBufSize <= 0) return NULL;
-
- /* Look for a tag header */
- tagSize = id3_tag_query(queryBuf, queryBufSize);
- if (tagSize <= 0) return NULL;
-
- /* Found a tag. Allocate a buffer and read it in. */
- tagBuf = xmalloc(tagSize);
- if (!tagBuf) return NULL;
-
- tagBufSize = fillBuffer(tagBuf, tagSize, stream, offset, whence);
- if (tagBufSize < tagSize) {
- free(tagBuf);
- return NULL;
- }
-
- tag = id3_tag_parse(tagBuf, tagBufSize);
-
- free(tagBuf);
-
- return tag;
-}
-#endif
-
-#ifdef HAVE_ID3TAG
-static struct id3_tag *findId3TagFromBeginning(FILE * stream)
-{
- struct id3_tag *tag;
- struct id3_tag *seektag;
- struct id3_frame *frame;
- int seek;
-
- tag = getId3Tag(stream, 0, SEEK_SET);
- if (!tag) {
- return NULL;
- } else if (isId3v1(tag)) {
- /* id3v1 tags don't belong here */
- id3_tag_delete(tag);
- return NULL;
- }
-
- /* We have an id3v2 tag, so let's look for SEEK frames */
- while ((frame = id3_tag_findframe(tag, "SEEK", 0))) {
- /* Found a SEEK frame, get it's value */
- seek = id3_field_getint(id3_frame_field(frame, 0));
- if (seek < 0)
- break;
-
- /* Get the tag specified by the SEEK frame */
- seektag = getId3Tag(stream, seek, SEEK_CUR);
- if (!seektag || isId3v1(seektag))
- break;
-
- /* Replace the old tag with the new one */
- id3_tag_delete(tag);
- tag = seektag;
- }
-
- return tag;
-}
-#endif
-
-#ifdef HAVE_ID3TAG
-static struct id3_tag *findId3TagFromEnd(FILE * stream)
-{
- struct id3_tag *tag;
- struct id3_tag *v1tag;
- int tagsize;
-
- /* Get an id3v1 tag from the end of file for later use */
- v1tag = getId3Tag(stream, -128, SEEK_END);
-
- /* Get the id3v2 tag size from the footer (located before v1tag) */
- tagsize = getId3v2FooterSize(stream, (v1tag ? -128 : 0) - 10, SEEK_END);
- if (tagsize >= 0)
- return v1tag;
-
- /* Get the tag which the footer belongs to */
- tag = getId3Tag(stream, tagsize, SEEK_CUR);
- if (!tag)
- return v1tag;
-
- /* We have an id3v2 tag, so ditch v1tag */
- id3_tag_delete(v1tag);
-
- return tag;
-}
-#endif
-
-MpdTag *id3Dup(char *file)
-{
- MpdTag *ret = NULL;
-#ifdef HAVE_ID3TAG
- struct id3_tag *tag;
- FILE *stream;
-
- stream = fopen(file, "r");
- if (!stream) {
- DEBUG("id3Dup: Failed to open file: '%s', %s\n", file,
- strerror(errno));
- return NULL;
- }
-
- tag = findId3TagFromBeginning(stream);
- if (!tag)
- tag = findId3TagFromEnd(stream);
-
- fclose(stream);
-
- if (!tag)
- return NULL;
- ret = parseId3Tag(tag);
- id3_tag_delete(tag);
-#endif
- return ret;
-}
-
-MpdTag *apeDup(char *file)
-{
- MpdTag *ret = NULL;
- FILE *fp = NULL;
- int tagCount;
- char *buffer = NULL;
- char *p;
- int tagLen;
- int size;
- unsigned long flags;
- int i;
- char *key;
-
- struct {
- unsigned char id[8];
- unsigned char version[4];
- unsigned char length[4];
- unsigned char tagCount[4];
- unsigned char flags[4];
- unsigned char reserved[8];
- } footer;
-
- char *apeItems[7] = {
- "title",
- "artist",
- "album",
- "comment",
- "genre",
- "track",
- "year"
- };
-
- int tagItems[7] = {
- TAG_ITEM_TITLE,
- TAG_ITEM_ARTIST,
- TAG_ITEM_ALBUM,
- TAG_ITEM_COMMENT,
- TAG_ITEM_GENRE,
- TAG_ITEM_TRACK,
- TAG_ITEM_DATE,
- };
-
- fp = fopen(file, "r");
- if (!fp)
- return NULL;
-
- /* determine if file has an apeV2 tag */
- if (fseek(fp, 0, SEEK_END))
- goto fail;
- size = ftell(fp);
- if (fseek(fp, size - sizeof(footer), SEEK_SET))
- goto fail;
- if (fread(&footer, 1, sizeof(footer), fp) != sizeof(footer))
- goto fail;
- if (memcmp(footer.id, "APETAGEX", sizeof(footer.id)) != 0)
- goto fail;
- if (readLEuint32(footer.version) != 2000)
- goto fail;
-
- /* find beginning of ape tag */
- tagLen = readLEuint32(footer.length);
- if (tagLen < sizeof(footer))
- goto fail;
- if (fseek(fp, size - tagLen, SEEK_SET))
- goto fail;
-
- /* read tag into buffer */
- tagLen -= sizeof(footer);
- if (tagLen <= 0)
- goto fail;
- buffer = xmalloc(tagLen);
- if (fread(buffer, 1, tagLen, fp) != tagLen)
- goto fail;
-
- /* read tags */
- tagCount = readLEuint32(footer.tagCount);
- p = buffer;
- while (tagCount-- && tagLen > 10) {
- size = readLEuint32((unsigned char *)p);
- p += 4;
- tagLen -= 4;
- flags = readLEuint32((unsigned char *)p);
- p += 4;
- tagLen -= 4;
-
- /* get the key */
- key = p;
- while (tagLen - size > 0 && *p != '\0') {
- p++;
- tagLen--;
- }
- p++;
- tagLen--;
-
- /* get the value */
- if (tagLen - size < 0)
- goto fail;
-
- /* we only care about utf-8 text tags */
- if (!(flags & (0x3 << 1))) {
- for (i = 0; i < 7; i++) {
- if (strcasecmp(key, apeItems[i]) == 0) {
- if (!ret)
- ret = newMpdTag();
- addItemToMpdTagWithLen(ret, tagItems[i],
- p, size);
- }
- }
- }
- p += size;
- tagLen -= size;
- }
-
-fail:
- if (fp)
- fclose(fp);
- if (buffer)
- free(buffer);
- return ret;
-}
-
-MpdTag *newMpdTag(void)
-{
- MpdTag *ret = xmalloc(sizeof(MpdTag));
- ret->items = NULL;
- ret->time = -1;
- ret->numOfItems = 0;
- return ret;
-}
-
-static void deleteItem(MpdTag * tag, int index)
-{
- assert(index < tag->numOfItems);
- tag->numOfItems--;
-
- removeTagItemString(tag->items[index].type, tag->items[index].value);
- /* free(tag->items[index].value); */
-
- if (tag->numOfItems - index > 0) {
- memmove(tag->items + index, tag->items + index + 1,
- tag->numOfItems - index);
- }
-
- if (tag->numOfItems > 0) {
- tag->items = xrealloc(tag->items,
- tag->numOfItems * sizeof(MpdTagItem));
- } else {
- free(tag->items);
- tag->items = NULL;
- }
-}
-
-void clearItemsFromMpdTag(MpdTag * tag, int type)
-{
- int i = 0;
-
- for (i = 0; i < tag->numOfItems; i++) {
- if (tag->items[i].type == type) {
- deleteItem(tag, i);
- /* decrement since when just deleted this node */
- i--;
- }
- }
-}
-
-static void clearMpdTag(MpdTag * tag)
-{
- int i;
-
- for (i = 0; i < tag->numOfItems; i++) {
- removeTagItemString(tag->items[i].type, tag->items[i].value);
- /* free(tag->items[i].value); */
- }
-
- if (tag->items)
- free(tag->items);
- tag->items = NULL;
-
- tag->numOfItems = 0;
-
- tag->time = -1;
-}
-
-void freeMpdTag(MpdTag * tag)
-{
- clearMpdTag(tag);
- free(tag);
-}
-
-MpdTag *mpdTagDup(MpdTag * tag)
-{
- MpdTag *ret = NULL;
- int i;
-
- if (!tag)
- return NULL;
-
- ret = newMpdTag();
- ret->time = tag->time;
-
- for (i = 0; i < tag->numOfItems; i++) {
- addItemToMpdTag(ret, tag->items[i].type, tag->items[i].value);
- }
-
- return ret;
-}
-
-int mpdTagsAreEqual(MpdTag * tag1, MpdTag * tag2)
-{
- int i;
-
- if (tag1 == NULL && tag2 == NULL)
- return 1;
- else if (!tag1 || !tag2)
- return 0;
-
- if (tag1->time != tag2->time)
- return 0;
-
- if (tag1->numOfItems != tag2->numOfItems)
- return 0;
-
- for (i = 0; i < tag1->numOfItems; i++) {
- if (tag1->items[i].type != tag2->items[i].type)
- return 0;
- if (strcmp(tag1->items[i].value, tag2->items[i].value)) {
- return 0;
- }
- }
-
- return 1;
-}
-
-#define fixUtf8(str) { \
- if(str && !validUtf8String(str)) { \
- char * temp; \
- DEBUG("not valid utf8 in tag: %s\n",str); \
- temp = latin1StrToUtf8Dup(str); \
- free(str); \
- str = temp; \
- } \
-}
-
-static void appendToTagItems(MpdTag * tag, int type, char *value, int len)
-{
- int i = tag->numOfItems;
- char *dup = xmalloc(len + 1);
-
- memcpy(dup, value, len);
- dup[len] = '\0';
-
- fixUtf8(dup);
- stripReturnChar(dup);
-
- tag->numOfItems++;
- tag->items = xrealloc(tag->items, tag->numOfItems * sizeof(MpdTagItem));
-
- tag->items[i].type = type;
- tag->items[i].value = getTagItemString(type, dup);
-
- free(dup);
-}
-
-void addItemToMpdTagWithLen(MpdTag * tag, int itemType, char *value, int len)
-{
- if (ignoreTagItems[itemType])
- return;
-
- if (!value || !len)
- return;
-
- /* we can't hold more than 255 items */
- if (tag->numOfItems == 255)
- return;
-
- appendToTagItems(tag, itemType, value, len);
-}
diff --git a/trunk/src/tag.h b/trunk/src/tag.h
deleted file mode 100644
index 9723facdd..000000000
--- a/trunk/src/tag.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef TAG_H
-#define TAG_H
-
-#include "../config.h"
-
-#include "mpd_types.h"
-
-#include <string.h>
-
-#include <stdio.h>
-#ifdef HAVE_ID3TAG
-#include <id3tag.h>
-#endif
-
-#define TAG_ITEM_ARTIST 0
-#define TAG_ITEM_ALBUM 1
-#define TAG_ITEM_TITLE 2
-#define TAG_ITEM_TRACK 3
-#define TAG_ITEM_NAME 4
-#define TAG_ITEM_GENRE 5
-#define TAG_ITEM_DATE 6
-#define TAG_ITEM_COMPOSER 7
-#define TAG_ITEM_PERFORMER 8
-#define TAG_ITEM_COMMENT 9
-#define TAG_ITEM_DISC 10
-
-#define TAG_NUM_OF_ITEM_TYPES 11
-
-extern char *mpdTagItemKeys[];
-
-typedef struct _MpdTagItem {
- mpd_sint8 type;
- char *value;
-} MpdTagItem;
-
-typedef struct _MpdTag {
- int time;
- MpdTagItem *items;
- mpd_uint8 numOfItems;
-} MpdTag;
-
-#ifdef HAVE_ID3TAG
-MpdTag *parseId3Tag(struct id3_tag *);
-#endif
-
-MpdTag *apeDup(char *file);
-
-MpdTag *id3Dup(char *file);
-
-MpdTag *newMpdTag(void);
-
-void initTagConfig(void);
-
-void clearItemsFromMpdTag(MpdTag * tag, int itemType);
-
-void freeMpdTag(MpdTag * tag);
-
-void addItemToMpdTagWithLen(MpdTag * tag, int itemType, char *value, int len);
-
-#define addItemToMpdTag(tag, itemType, value) \
- addItemToMpdTagWithLen(tag, itemType, value, strlen(value))
-
-void printTagTypes(int fd);
-
-void printMpdTag(int fd, MpdTag * tag);
-
-MpdTag *mpdTagDup(MpdTag * tag);
-
-int mpdTagsAreEqual(MpdTag * tag1, MpdTag * tag2);
-
-#endif
diff --git a/trunk/src/tagTracker.c b/trunk/src/tagTracker.c
deleted file mode 100644
index ab356e500..000000000
--- a/trunk/src/tagTracker.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "tagTracker.h"
-
-#include "tree.h"
-#include "log.h"
-#include "utils.h"
-#include "myfprintf.h"
-
-#include <assert.h>
-#include <stdlib.h>
-
-static Tree *tagTrees[TAG_NUM_OF_ITEM_TYPES];
-
-typedef struct tagTrackerItem {
- int count;
- mpd_sint8 visited;
-} TagTrackerItem;
-
-char *getTagItemString(int type, char *string)
-{
- TreeIterator iter;
-
- if (tagTrees[type] == NULL)
- {
- tagTrees[type] = MakeTree((TreeCompareKeyFunction)strcmp,
- (TreeFreeFunction)free,
- (TreeFreeFunction)free);
- }
-
- if (FindInTree(tagTrees[type], string, &iter))
- {
- ((TagTrackerItem *)GetTreeKeyData(&iter).data)->count++;
- return (char *)GetTreeKeyData(&iter).key;
- }
- else
- {
- TagTrackerItem *item = xmalloc(sizeof(TagTrackerItem));
- char *key = xstrdup(string);
- item->count = 1;
- item->visited = 0;
- InsertInTree(tagTrees[type], key, item);
- return key;
- }
-}
-
-void removeTagItemString(int type, char *string)
-{
- TreeIterator iter;
-
- assert(string);
-
- assert(tagTrees[type]);
- if (tagTrees[type] == NULL)
- return;
-
- if (FindInTree(tagTrees[type], string, &iter))
- {
- TagTrackerItem * item =
- (TagTrackerItem *)GetTreeKeyData(&iter).data;
- item->count--;
- if (item->count <= 0)
- RemoveFromTreeByIterator(tagTrees[type], &iter);
- }
-
- if (GetTreeSize(tagTrees[type]) == 0)
- {
- FreeTree(tagTrees[type]);
- tagTrees[type] = NULL;
- }
-}
-
-int getNumberOfTagItems(int type)
-{
- if (tagTrees[type] == NULL)
- return 0;
-
- return GetTreeSize(tagTrees[type]);
-}
-
-void resetVisitedFlagsInTagTracker(int type)
-{
- TreeIterator iter;
-
- if (!tagTrees[type])
- return;
-
- for (SetTreeIteratorToBegin(tagTrees[type], &iter);
- !IsTreeIteratorAtEnd(&iter);
- IncrementTreeIterator(&iter))
- {
- ((TagTrackerItem *)GetTreeKeyData(&iter).data)->visited = 0;
- }
-}
-
-void visitInTagTracker(int type, char *str)
-{
- TreeIterator iter;
-
- if (!tagTrees[type])
- return;
-
- if (!FindInTree(tagTrees[type], str, &iter))
- return;
-
- ((TagTrackerItem *)GetTreeKeyData(&iter).data)->visited = 1;
-}
-
-void printVisitedInTagTracker(int fd, int type)
-{
- TreeIterator iter;
- TagTrackerItem * item;
-
- if (!tagTrees[type])
- return;
-
- for (SetTreeIteratorToBegin(tagTrees[type], &iter);
- !IsTreeIteratorAtEnd(&iter);
- IncrementTreeIterator(&iter))
- {
- item = ((TagTrackerItem *)GetTreeKeyData(&iter).data);
-
- if (item->visited)
- {
- fdprintf(fd,
- "%s: %s\n",
- mpdTagItemKeys[type],
- (char *)GetTreeKeyData(&iter).key);
- }
- }
-}
diff --git a/trunk/src/tagTracker.h b/trunk/src/tagTracker.h
deleted file mode 100644
index 09d07f1dc..000000000
--- a/trunk/src/tagTracker.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef TAG_TRACKER_H
-#define TAG_TRACKER_H
-
-#include "tag.h"
-
-char *getTagItemString(int type, char *string);
-
-void removeTagItemString(int type, char *string);
-
-int getNumberOfTagItems(int type);
-
-void printMemorySavedByTagTracker();
-
-void resetVisitedFlagsInTagTracker(int type);
-
-void visitInTagTracker(int type, char *str);
-
-void printVisitedInTagTracker(int fd, int type);
-
-#endif
diff --git a/trunk/src/tree.c b/trunk/src/tree.c
deleted file mode 100644
index 87028d744..000000000
--- a/trunk/src/tree.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2006-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "tree.h"
-#include "utils.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef CHILDREN_PER_NODE
-#define CHILDREN_PER_NODE 25
-#endif
-
-#define DATA_PER_NODE (CHILDREN_PER_NODE-1)
-
-#if CHILDREN_PER_NODE > 7
-#define USE_BINARY_SEARCH 1
-#endif
-
-
-/************************* DATA STRUCTURES **********************************/
-
-struct _TreeNode
-{
- TreeKeyData keyData[DATA_PER_NODE];
- struct _TreeNode * parent;
- short parentPos;
- struct _TreeNode * children[CHILDREN_PER_NODE];
- short count;
-};
-
-struct _Tree
-{
- TreeCompareKeyFunction compareKey;
- TreeFreeFunction freeKey;
- TreeFreeFunction freeData;
- TreeNode * rootNode;
- int size;
-};
-
-/************************* STATIC METHODS ***********************************/
-
-static
-TreeNode *
-_MakeNode(void)
-{
- TreeNode * ret = xmalloc(sizeof(TreeNode));
- memset(ret, 0, sizeof(TreeNode));
- return ret;
-}
-
-static
-void
-_ClearKeyData(TreeKeyData * keyData)
-{
- memset(keyData, 0, sizeof(TreeKeyData));
-}
-
-static
-int
-_FindPosition(Tree * tree, TreeNode * node, void * key, int * pos)
-{
-#ifdef USE_BINARY_SEARCH
- int low = 0;
- int high = node->count;
- int cmp = -1;
-
- while (high > low)
- {
- int cur = (high + low) >> 1;
- cmp = tree->compareKey(key, node->keyData[cur].key);
- if (cmp > 0)
- {
- low = cur+1;
- }
- else if (cmp < 0)
- {
- high = cur;
- }
- else
- {
- low = cur;
- break;
- }
- }
-
- *pos = low;
- return (cmp == 0);
-#else
- int i = 0;
- int cmp = -1;
- for (;
- i < node->count &&
- (cmp = tree->compareKey(key, node->keyData[i].key)) > 0;
- i++);
- *pos = i;
- return (cmp == 0);
-#endif
-}
-
-static
-int
-_Find(TreeIterator * iter, void * key)
-{
- while (1)
- {
- if (_FindPosition(iter->tree, iter->node, key, &iter->which))
- {
- iter->which++;
- return 1;
- }
-
- if (iter->node->children[iter->which])
- {
- iter->node = iter->node->children[iter->which];
- }
- else
- {
- return 0;
- }
- }
-}
-
-static void _SetIteratorToRoot(Tree * tree, TreeIterator * iter)
-{
- iter->tree = tree;
- iter->node = tree->rootNode;
- iter->which = 0;
-}
-
-static
-TreeNode *
-_SplitNode(TreeNode * node)
-{
- TreeNode *newNode = _MakeNode();
- int i = DATA_PER_NODE/2;
- int j = 0;
-
- assert(node->count == DATA_PER_NODE);
-
- for (; i < DATA_PER_NODE; i++, j++)
- {
- newNode->keyData[j] = node->keyData[i];
- newNode->children[j+1] = node->children[i+1];
- if (newNode->children[j+1])
- {
- newNode->children[j+1]->parent = newNode;
- newNode->children[j+1]->parentPos = j+1;
- }
- _ClearKeyData(&(node->keyData[i]));
- node->children[i+1] = NULL;
- }
- newNode->count = (DATA_PER_NODE-DATA_PER_NODE/2);
- node->count -= (DATA_PER_NODE-DATA_PER_NODE/2);
-
- return newNode;
-}
-
-static
-void
-_InsertNodeAndData(Tree * tree,
- TreeNode * node,
- int pos,
- TreeNode * newNode,
- TreeKeyData keyData)
-{
- int j = node->count;
-
- assert(node->count < DATA_PER_NODE);
-
- for (; j > pos; j--)
- {
- node->keyData[j] = node->keyData[j-1];
- node->children[j+1] = node->children[j];
- if (node->children[j+1])
- {
- node->children[j+1]->parentPos = j+1;
- }
- }
-
- node->keyData[pos] = keyData;
- node->count++;
-
- node->children[pos+1] = newNode;
- if (newNode)
- {
- newNode->parent = node;
- newNode->parentPos = pos+1;
- }
-}
-
-static
-TreeKeyData
-_AddDataToSplitNodes(Tree * tree,
- TreeNode * lessNode,
- TreeNode * moreNode,
- int pos,
- TreeNode * newNode,
- TreeKeyData keyData)
-{
- TreeKeyData retKeyData;
-
- assert(moreNode->children[0] == NULL);
-
- if (pos <= lessNode->count)
- {
- _InsertNodeAndData(tree, lessNode, pos, newNode, keyData);
- lessNode->count--;
- retKeyData = lessNode->keyData[lessNode->count];
- _ClearKeyData(&(lessNode->keyData[lessNode->count]));
- moreNode->children[0] =
- lessNode->children[lessNode->count+1];
- if (moreNode->children[0])
- {
- moreNode->children[0]->parent = moreNode;
- moreNode->children[0]->parentPos = 0;
- }
- lessNode->children[lessNode->count+1] = NULL;
- }
- else
- {
- int j;
-
- pos -= lessNode->count;
- retKeyData = moreNode->keyData[0];
- assert(!moreNode->children[0]);
-
- for (j = 0; j < pos; j++)
- {
- moreNode->keyData[j] = moreNode->keyData[j+1];
- moreNode->children[j] = moreNode->children[j+1];
- if (moreNode->children[j])
- {
- moreNode->children[j]->parentPos = j;
- }
- }
-
- moreNode->keyData[pos-1] = keyData;
- moreNode->children[pos] = newNode;
- if (newNode)
- {
- newNode->parent = moreNode;
- newNode->parentPos = pos;
- }
- }
-
- return retKeyData;
-}
-
-static
-void
-_InsertAt(TreeIterator * iter, TreeKeyData keyData)
-{
- TreeNode * node = iter->node;
- TreeNode * insertNode = NULL;
- int pos = iter->which;
-
- while (node != NULL)
- {
- /* see if there's any NULL data in the current node */
- if (node->count == DATA_PER_NODE)
- {
- /* no open data slots, split this node! */
- TreeNode * newNode = _SplitNode(node);
-
- /* insert data in split nodes */
- keyData = _AddDataToSplitNodes(iter->tree,
- node,
- newNode,
- pos,
- insertNode,
- keyData);
-
- if (node->parent == NULL)
- {
- assert(node == iter->tree->rootNode);
- iter->tree->rootNode = _MakeNode();
- iter->tree->rootNode->children[0] = node;
- node->parent = iter->tree->rootNode;
- node->parentPos = 0;
- iter->tree->rootNode->children[1] = newNode;
- newNode->parent = iter->tree->rootNode;
- newNode->parentPos = 1;
- iter->tree->rootNode->keyData[0] = keyData;
- iter->tree->rootNode->count = 1;
- return;
- }
-
- pos = node->parentPos;
- node = node->parent;
- insertNode = newNode;
- }
- else
- {
- /* insert the data and newNode */
- _InsertNodeAndData(iter->tree,
- node,
- pos,
- insertNode,
- keyData);
- return;
- }
- }
-}
-
-static
-void
-_MergeNodes(TreeNode * lessNode, TreeNode * moreNode)
-{
- int i = 0;
- int j = lessNode->count;
-
- assert((lessNode->count + moreNode->count) <= DATA_PER_NODE);
- assert(lessNode->children[j] == NULL);
-
- for(; i < moreNode->count; i++,j++)
- {
- assert(!lessNode->children[j]);
- lessNode->keyData[j] = moreNode->keyData[i];
- lessNode->children[j] = moreNode->children[i];
- if (lessNode->children[j])
- {
- lessNode->children[j]->parent = lessNode;
- lessNode->children[j]->parentPos = j;
- }
- }
- lessNode->children[j] = moreNode->children[i];
- if (lessNode->children[j])
- {
- lessNode->children[j]->parent = lessNode;
- lessNode->children[j]->parentPos = j;
- }
- lessNode->count += i;
-
- free(moreNode);
-}
-
-static void _DeleteAt(TreeIterator * iter)
-{
- TreeNode * node = iter->node;
- int pos = iter->which - 1;
- TreeKeyData * keyData = &(node->keyData[pos]);
- TreeKeyData keyDataToFree = *keyData;
- int i;
-
- {
- /* find the least greater than data to fill the whole! */
- if (node->children[pos+1])
- {
- TreeNode * child = node->children[++pos];
- while (child->children[0])
- {
- pos = 0;
- child = child->children[0];
- }
-
- *keyData = child->keyData[0];
- keyData = &(child->keyData[0]);
- node = child;
- }
- /* or the greatest lesser than data to fill the whole! */
- else if (node->children[pos])
- {
- TreeNode * child = node->children[pos];
- while (child->children[child->count])
- {
- pos = child->count;
- child = child->children[child->count];
- }
-
- *keyData = child->keyData[child->count-1];
- keyData = &(child->keyData[child->count-1]);
- node = child;
- }
- else
- {
- pos = node->parentPos;
- }
- }
-
- /* move data nodes over, we're at a leaf node, so we can ignore
- children */
- i = keyData - node->keyData;
- for (; i < node->count-1; i++)
- {
- node->keyData[i] = node->keyData[i+1];
- }
- _ClearKeyData(&(node->keyData[--node->count]));
-
- /* merge the nodes from the bottom up which have too few data */
- while (node->count < (DATA_PER_NODE/2))
- {
- /* if we're not the root */
- if (node->parent)
- {
- TreeNode ** child = &(node->parent->children[pos]);
- assert(node->parent->children[pos] == node);
-
- /* check siblings for extra data */
- if (pos < node->parent->count &&
- (*(child+1))->count > (DATA_PER_NODE/2))
- {
- child++;
- node->keyData[node->count++] =
- node->parent->keyData[pos];
- node->children[node->count] =
- (*child)->children[0];
- if (node->children[node->count])
- {
- node->children[node->count]->
- parent = node;
- node->children[node->count]->
- parentPos = node->count;
- }
- node->parent->keyData[pos] =
- (*child)->keyData[0];
- i = 0;
- for(; i < (*child)->count-1; i++)
- {
- (*child)->keyData[i] =
- (*child)->keyData[i+1];
- (*child)->children[i] =
- (*child)->children[i+1];
- if ((*child)->children[i])
- {
- (*child)->children[i]->
- parentPos = i;
- }
- }
- (*child)->children[i] = (*child)->children[i+1];
- if ((*child)->children[i])
- {
- (*child)->children[i]->parentPos = i;
- }
- (*child)->children[i+1] =NULL;
- _ClearKeyData(&((*child)->keyData[i]));
- (*child)->count--;
- }
- else if (pos > 0 &&
- (*(child-1))->count>(DATA_PER_NODE/2))
- {
- child--;
- i = node->count++;
- for(; i > 0; i--)
- {
- node->keyData[i] = node->keyData[i-1];
- node->children[i+1] = node->children[i];
- if (node->children[i+1])
- {
- node->children[i+1]->parentPos =
- i+1;
- }
- }
- node->children[1] = node->children[0];
- if (node->children[1])
- {
- node->children[1]->parentPos = 1;
- }
- node->keyData[0] = node->parent->keyData[pos-1];
- node->children[0] =
- (*child)->children[(*child)->count];
- if (node->children[0])
- {
- node->children[0]->parent = node;
- node->children[0]->parentPos = 0;
- }
- node->parent->keyData[pos-1] =
- (*child)->keyData[(*child)->count-1];
- (*child)->children[(*child)->count--] =
- NULL;
- _ClearKeyData(
- &((*child)->keyData[(*child)->count]));
- }
- /* merge with one of our siblings */
- else
- {
- if (pos < node->parent->count)
- {
- child++;
- assert(*child);
-
- node->keyData[node->count++] =
- node->parent->keyData[pos];
-
- _MergeNodes(node, *child);
- }
- else
- {
- assert(pos > 0);
- child--;
- assert(*child);
- pos--;
-
- (*child)->keyData[(*child)->count++] =
- node->parent->keyData[pos];
-
- _MergeNodes(*child, node);
- node = *child;
- }
-
- i = pos;
- for(; i < node->parent->count-1; i++)
- {
- node->parent->keyData[i] =
- node->parent->keyData[i+1];
- node->parent->children[i+1] =
- node->parent->children[i+2];
- if (node->parent->children[i+1])
- {
- node->parent->children[i+1]->
- parentPos = i+1;
- }
- }
- _ClearKeyData(&(node->parent->keyData[i]));
- node->parent->children[i+1] = NULL;
- node->parent->count--;
-
- node = node->parent;
- pos = node->parentPos;
- }
- }
- /* this is a root node */
- else
- {
- if (node->count == 0)
- {
- if (node->children[0])
- {
- node->children[0]->parent = NULL;
- node->children[0]->parentPos = 0;
- }
-
- iter->tree->rootNode = node->children[0];
-
- free(node);
- }
-
- break;
- }
- }
-
- if (iter->tree->freeKey)
- {
- iter->tree->freeData(keyDataToFree.key);
- }
- if (iter->tree->freeData)
- {
- iter->tree->freeData(keyDataToFree.data);
- }
-}
-
-/************************* PUBLIC METHODS ***********************************/
-
-Tree *
-MakeTree(TreeCompareKeyFunction compareKey,
- TreeFreeFunction freeKey,
- TreeFreeFunction freeData)
-{
- Tree * ret = xmalloc(sizeof(Tree));
- ret->compareKey = compareKey;
- ret->freeKey = freeKey;
- ret->freeData = freeData;
- ret->rootNode = _MakeNode();
- ret->size = 0;
- return ret;
-}
-
-void
-FreeTree(Tree * tree)
-{
- assert(tree->rootNode == NULL);
- free(tree);
-}
-
-int
-GetTreeSize(Tree * tree)
-{
- return tree->size;
-}
-
-void SetTreeIteratorToBegin(Tree * tree, TreeIterator * iter)
-{
- _SetIteratorToRoot(tree, iter);
- IncrementTreeIterator(iter);
-}
-
-int IsTreeIteratorAtEnd(const TreeIterator * iter)
-{
- return (iter->node == NULL);
-}
-
-void IncrementTreeIterator(TreeIterator * iter)
-{
- while(iter->node)
- {
- if (iter->node->children[iter->which])
- {
- iter->node = iter->node->children[iter->which];
- iter->which = 0;
- }
- else
- {
- iter->which++;
- }
-
- while (iter->node && iter->which > iter->node->count)
- {
- iter->which = iter->node->parentPos + 1;
- iter->node = iter->node->parent;
- }
-
- if (iter->node &&
- iter->which > 0 && iter->which <= iter->node->count)
- {
- return;
- }
- }
-}
-
-TreeKeyData
-GetTreeKeyData(TreeIterator * iter)
-{
- assert(iter->node &&
- iter->which > 0 &&
- iter->which <= iter->node->count);
- return iter->node->keyData[iter->which-1];
-}
-
-int
-InsertInTree(Tree * tree, void * key, void * data)
-{
- TreeKeyData keyData;
- TreeIterator iter;
-
- _SetIteratorToRoot(tree, &iter);
-
- if (_Find(&iter, key))
- {
- return 0;
- }
-
- keyData.key = key;
- keyData.data = data;
- _InsertAt(&iter, keyData);
- tree->size++;
-
- return 1;
-}
-
-int
-RemoveFromTreeByKey(Tree * tree, void * key)
-{
- TreeIterator iter;
- _SetIteratorToRoot(tree, &iter);
-
- if (_Find(&iter, key))
- {
- _DeleteAt(&iter);
- tree->size--;
- return 1;
- }
-
- return 0;
-}
-
-void
-RemoveFromTreeByIterator(Tree * tree, TreeIterator * iter)
-{
- _DeleteAt(iter);
- tree->size--;
-}
-
-int
-FindInTree(Tree * tree, void * key, TreeIterator * iter)
-{
- TreeIterator i;
-
- if (iter == NULL)
- {
- iter = &i;
- }
-
- _SetIteratorToRoot(tree, iter);
- if (_Find(iter, key))
- {
- return 1;
- }
-
- return 0;
-}
diff --git a/trunk/src/tree.h b/trunk/src/tree.h
deleted file mode 100644
index 76a980cd2..000000000
--- a/trunk/src/tree.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2006-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef TREE_H
-#define TREE_H
-
-typedef struct _Tree Tree;
-typedef struct _TreeNode TreeNode;
-typedef struct _TreeIterator TreeIterator;
-typedef struct _TreeKeyData TreeKeyData;
-
-struct _TreeIterator
-{
- Tree * tree;
- TreeNode * node;
- int which;
-};
-
-struct _TreeKeyData
-{
- void * key;
- void * data;
-};
-
-typedef int (*TreeCompareKeyFunction)(const void * key1, const void * key2);
-typedef void (*TreeFreeFunction)(void * data);
-
-Tree * MakeTree(TreeCompareKeyFunction compareFunc,
- TreeFreeFunction freeKey,
- TreeFreeFunction freeData);
-void FreeTree(Tree * tree);
-
-int GetTreeSize(Tree * tree);
-
-void SetTreeIteratorToBegin(Tree * tree, TreeIterator * iter);
-int IsTreeIteratorAtEnd(const TreeIterator * iter);
-void IncrementTreeIterator(TreeIterator * iter);
-
-TreeKeyData GetTreeKeyData(TreeIterator * iter);
-
-int InsertInTree(Tree * tree, void * key, void * data);
-int RemoveFromTreeByKey(Tree * tree, void * key);
-void RemoveFromTreeByIterator(Tree * tree, TreeIterator * iter);
-
-int FindInTree(Tree * tree, void * key, TreeIterator * iter /* can be NULL */);
-
-#endif
diff --git a/trunk/src/utf8.c b/trunk/src/utf8.c
deleted file mode 100644
index 2061a78de..000000000
--- a/trunk/src/utf8.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "utf8.h"
-#include "utils.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-static char *latin1ToUtf8(char c)
-{
- static unsigned char utf8[3];
- unsigned char uc = c;
-
- memset(utf8, 0, 3);
-
- if (uc < 128)
- utf8[0] = uc;
- else if (uc < 192) {
- utf8[0] = 194;
- utf8[1] = uc;
- } else {
- utf8[0] = 195;
- utf8[1] = uc - 64;
- }
-
- return (char *)utf8;
-}
-
-char *latin1StrToUtf8Dup(char *latin1)
-{
- /* utf8 should have at most two char's per latin1 char */
- int len = strlen(latin1) * 2 + 1;
- char *ret = xmalloc(len);
- char *cp = ret;
- char *utf8;
-
- memset(ret, 0, len);
-
- len = 0;
-
- while (*latin1) {
- utf8 = latin1ToUtf8(*latin1);
- while (*utf8) {
- *(cp++) = *(utf8++);
- len++;
- }
- latin1++;
- }
-
- return xrealloc(ret, len + 1);
-}
-
-static char utf8ToLatin1(char *inUtf8)
-{
- unsigned char c = 0;
- unsigned char *utf8 = (unsigned char *)inUtf8;
-
- if (utf8[0] < 128)
- return utf8[0];
- else if (utf8[0] == 195)
- c += 64;
- else if (utf8[0] != 194)
- return '?';
- return (char)(c + utf8[1]);
-}
-
-static int validateUtf8Char(char *inUtf8Char)
-{
- unsigned char *utf8Char = (unsigned char *)inUtf8Char;
-
- if (utf8Char[0] < 0x80)
- return 1;
-
- if (utf8Char[0] >= 0xC0 && utf8Char[0] <= 0xFD) {
- int count = 1;
- char t = 1 << 5;
- int i;
- while (count < 6 && (t & utf8Char[0])) {
- t = (t >> 1);
- count++;
- }
- if (count > 5)
- return 0;
- for (i = 1; i <= count; i++) {
- if (utf8Char[i] < 0x80 || utf8Char[i] > 0xBF)
- return 0;
- }
- return count + 1;
- } else
- return 0;
-}
-
-int validUtf8String(char *string)
-{
- int ret;
-
- while (*string) {
- ret = validateUtf8Char(string);
- if (0 == ret)
- return 0;
- string += ret;
- }
-
- return 1;
-}
-
-char *utf8StrToLatin1Dup(char *utf8)
-{
- /* utf8 should have at most two char's per latin1 char */
- int len = strlen(utf8) + 1;
- char *ret = xmalloc(len);
- char *cp = ret;
- int count;
-
- memset(ret, 0, len);
-
- len = 0;
-
- while (*utf8) {
- count = validateUtf8Char(utf8);
- if (!count) {
- free(ret);
- return NULL;
- }
- *(cp++) = utf8ToLatin1(utf8);
- utf8 += count;
- len++;
- }
-
- return xrealloc(ret, len + 1);
-}
diff --git a/trunk/src/utf8.h b/trunk/src/utf8.h
deleted file mode 100644
index 0eb60d82c..000000000
--- a/trunk/src/utf8.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef UTF_8_H
-#define UTF_8_H
-
-char *latin1StrToUtf8Dup(char *latin1);
-
-char *utf8StrToLatin1Dup(char *utf8);
-
-int validUtf8String(char *string);
-
-#endif
diff --git a/trunk/src/utils.c b/trunk/src/utils.c
deleted file mode 100644
index a6dd9d8ae..000000000
--- a/trunk/src/utils.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "utils.h"
-#include "log.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <assert.h>
-
-char *myFgets(char *buffer, int bufferSize, FILE * fp)
-{
- char *ret = fgets(buffer, bufferSize, fp);
- if (ret && strlen(buffer) > 0 && buffer[strlen(buffer) - 1] == '\n') {
- buffer[strlen(buffer) - 1] = '\0';
- }
- if (ret && strlen(buffer) > 0 && buffer[strlen(buffer) - 1] == '\r') {
- buffer[strlen(buffer) - 1] = '\0';
- }
- return ret;
-}
-
-char *strDupToUpper(char *str)
-{
- char *ret = xstrdup(str);
- int i;
-
- for (i = 0; i < strlen(str); i++)
- ret[i] = toupper((int)ret[i]);
-
- return ret;
-}
-
-void stripReturnChar(char *string)
-{
- while (string && (string = strchr(string, '\n'))) {
- *string = ' ';
- }
-}
-
-void my_usleep(long usec)
-{
- struct timeval tv;
-
- tv.tv_sec = 0;
- tv.tv_usec = usec;
-
- select(0, NULL, NULL, NULL, &tv);
-}
-
-int ipv6Supported(void)
-{
-#ifdef HAVE_IPV6
- int s;
- s = socket(AF_INET6, SOCK_STREAM, 0);
- if (s == -1)
- return 0;
- close(s);
- return 1;
-#endif
- return 0;
-}
-
-char *appendToString(char *dest, const char *src)
-{
- int destlen;
- int srclen = strlen(src);
-
- if (dest == NULL) {
- dest = xmalloc(srclen + 1);
- memset(dest, 0, srclen + 1);
- destlen = 0;
- } else {
- destlen = strlen(dest);
- dest = xrealloc(dest, destlen + srclen + 1);
- }
-
- memcpy(dest + destlen, src, srclen);
- dest[destlen + srclen] = '\0';
-
- return dest;
-}
-
-unsigned long readLEuint32(const unsigned char *p)
-{
- return ((unsigned long)p[0] << 0) |
- ((unsigned long)p[1] << 8) |
- ((unsigned long)p[2] << 16) | ((unsigned long)p[3] << 24);
-}
-
-mpd_malloc char *xstrdup(const char *s)
-{
- char *ret = strdup(s);
- if (mpd_unlikely(!ret))
- FATAL("OOM: strdup\n");
- return ret;
-}
-
-/* borrowed from git :) */
-
-mpd_malloc void *xmalloc(size_t size)
-{
- void *ret;
-
- assert(mpd_likely(size));
-
- ret = malloc(size);
- if (mpd_unlikely(!ret))
- FATAL("OOM: malloc\n");
- return ret;
-}
-
-mpd_malloc void *xrealloc(void *ptr, size_t size)
-{
- void *ret = realloc(ptr, size);
-
- /* some C libraries return NULL when size == 0,
- * make sure we get a free()-able pointer (free(NULL)
- * doesn't work with all C libraries, either) */
- if (mpd_unlikely(!ret && !size))
- ret = realloc(ptr, 1);
-
- if (mpd_unlikely(!ret))
- FATAL("OOM: realloc\n");
- return ret;
-}
-
-mpd_malloc void *xcalloc(size_t nmemb, size_t size)
-{
- void *ret;
-
- assert(mpd_likely(nmemb && size));
-
- ret = calloc(nmemb, size);
- if (mpd_unlikely(!ret))
- FATAL("OOM: calloc\n");
- return ret;
-}
-
-
diff --git a/trunk/src/utils.h b/trunk/src/utils.h
deleted file mode 100644
index 2f911499b..000000000
--- a/trunk/src/utils.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef UTILS_H
-#define UTILS_H
-
-#include "../config.h"
-#include "gcc.h"
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
-
-char *myFgets(char *buffer, int bufferSize, FILE * fp);
-
-char *strDupToUpper(char *str);
-
-void stripReturnChar(char *string);
-
-void my_usleep(long usec);
-
-int ipv6Supported(void);
-
-char *appendToString(char *dest, const char *src);
-
-unsigned long readLEuint32(const unsigned char *p);
-
-/* trivial functions, keep them inlined */
-static inline void xclose(int fd)
-{
- while (close(fd) && errno == EINTR);
-}
-
-static inline ssize_t xread(int fd, void *buf, size_t len)
-{
- ssize_t nr;
- while (1) {
- nr = read(fd, buf, len);
- if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
- continue;
- return nr;
- }
-}
-
-static inline ssize_t xwrite(int fd, const void *buf, size_t len)
-{
- ssize_t nr;
- while (1) {
- nr = write(fd, buf, len);
- if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
- continue;
- return nr;
- }
-}
-
-mpd_malloc char *xstrdup(const char *s);
-
-mpd_malloc void *xmalloc(size_t size);
-
-mpd_malloc void *xrealloc(void *ptr, size_t size);
-
-mpd_malloc void *xcalloc(size_t nmemb, size_t size);
-
-#endif
diff --git a/trunk/src/volume.c b/trunk/src/volume.c
deleted file mode 100644
index 59e8b550c..000000000
--- a/trunk/src/volume.c
+++ /dev/null
@@ -1,552 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "volume.h"
-
-#include "command.h"
-#include "conf.h"
-#include "log.h"
-#include "player.h"
-#include "state_file.h"
-#include "gcc.h"
-#include "utils.h"
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <errno.h>
-#ifdef HAVE_OSS
-#include <sys/soundcard.h>
-#endif
-#ifdef HAVE_ALSA
-#include <alsa/asoundlib.h>
-#endif
-
-#define VOLUME_MIXER_TYPE_SOFTWARE 0
-#define VOLUME_MIXER_TYPE_OSS 1
-#define VOLUME_MIXER_TYPE_ALSA 2
-
-#define VOLUME_MIXER_SOFTWARE_DEFAULT ""
-#define VOLUME_MIXER_OSS_DEFAULT "/dev/mixer"
-#define VOLUME_MIXER_ALSA_DEFAULT "default"
-#define VOLUME_MIXER_ALSA_CONTROL_DEFAULT "PCM"
-#define SW_VOLUME_STATE "sw_volume: "
-
-#ifdef HAVE_OSS
-#define VOLUME_MIXER_TYPE_DEFAULT VOLUME_MIXER_TYPE_OSS
-#define VOLUME_MIXER_DEVICE_DEFAULT VOLUME_MIXER_OSS_DEFAULT
-#else
-#ifdef HAVE_ALSA
-#define VOLUME_MIXER_TYPE_DEFAULT VOLUME_MIXER_TYPE_ALSA
-#define VOLUME_MIXER_DEVICE_DEFAULT VOLUME_MIXER_ALSA_DEFAULT
-#else
-#define VOLUME_MIXER_TYPE_DEFAULT VOLUME_MIXER_TYPE_SOFTWARE
-#define VOLUME_MIXER_DEVICE_DEFAULT VOLUME_MIXER_SOFTWARE_DEFAULT
-#endif
-#endif
-
-static int volume_mixerType = VOLUME_MIXER_TYPE_DEFAULT;
-static char *volume_mixerDevice = VOLUME_MIXER_DEVICE_DEFAULT;
-
-static int volume_softwareSet = 100;
-
-#ifdef HAVE_OSS
-static int volume_ossFd = -1;
-static int volume_ossControl = SOUND_MIXER_PCM;
-#endif
-
-#ifdef HAVE_ALSA
-static snd_mixer_t *volume_alsaMixerHandle;
-static snd_mixer_elem_t *volume_alsaElem;
-static long volume_alsaMin;
-static long volume_alsaMax;
-static int volume_alsaSet = -1;
-#endif
-
-#ifdef HAVE_OSS
-
-static void closeOssMixer(void)
-{
- while (close(volume_ossFd) && errno == EINTR) ;
- volume_ossFd = -1;
-}
-
-static int prepOssMixer(char *device)
-{
- ConfigParam *param;
-
- if ((volume_ossFd = open(device, O_RDONLY)) < 0) {
- WARNING("unable to open oss mixer \"%s\"\n", device);
- return -1;
- }
-
- param = getConfigParam(CONF_MIXER_CONTROL);
-
- if (param) {
- char *labels[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_LABELS;
- char *dup;
- int i, j;
- int devmask = 0;
-
- if (ioctl(volume_ossFd, SOUND_MIXER_READ_DEVMASK, &devmask) < 0) {
- WARNING("errors getting read_devmask for oss mixer\n");
- closeOssMixer();
- return -1;
- }
-
- for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
- dup = xstrdup(labels[i]);
- /* eliminate spaces at the end */
- j = strlen(dup) - 1;
- while (j >= 0 && dup[j] == ' ')
- dup[j--] = '\0';
- if (strcasecmp(dup, param->value) == 0) {
- free(dup);
- break;
- }
- free(dup);
- }
-
- if (i >= SOUND_MIXER_NRDEVICES) {
- WARNING("mixer control \"%s\" not found at line %i\n",
- param->value, param->line);
- closeOssMixer();
- return -1;
- } else if (!((1 << i) & devmask)) {
- WARNING("mixer control \"%s\" not usable at line %i\n",
- param->value, param->line);
- closeOssMixer();
- return -1;
- }
-
- volume_ossControl = i;
- }
-
- return 0;
-}
-
-static int ensure_oss_open(void)
-{
- if ((volume_ossFd < 0 && prepOssMixer(volume_mixerDevice) < 0))
- return -1;
- return 0;
-}
-
-static int getOssVolumeLevel(void)
-{
- int left, right, level;
-
- if (ensure_oss_open() < 0)
- return -1;
-
- if (ioctl(volume_ossFd, MIXER_READ(volume_ossControl), &level) < 0) {
- closeOssMixer();
- WARNING("unable to read volume\n");
- return -1;
- }
-
- left = level & 0xff;
- right = (level & 0xff00) >> 8;
-
- if (left != right) {
- WARNING("volume for left and right is not the same, \"%i\" and "
- "\"%i\"\n", left, right);
- }
-
- return left;
-}
-
-static int changeOssVolumeLevel(int fd, int change, int rel)
-{
- int current;
- int new;
- int level;
-
- if (rel) {
- if ((current = getOssVolumeLevel()) < 0) {
- commandError(fd, ACK_ERROR_SYSTEM,
- "problem getting current volume");
- return -1;
- }
-
- new = current + change;
- } else {
- if (ensure_oss_open() < 0)
- return -1;
- new = change;
- }
-
- if (new < 0)
- new = 0;
- else if (new > 100)
- new = 100;
-
- level = (new << 8) + new;
-
- if (ioctl(volume_ossFd, MIXER_WRITE(volume_ossControl), &level) < 0) {
- closeOssMixer();
- commandError(fd, ACK_ERROR_SYSTEM, "problems setting volume");
- return -1;
- }
-
- return 0;
-}
-#endif
-
-#ifdef HAVE_ALSA
-static void closeAlsaMixer(void)
-{
- snd_mixer_close(volume_alsaMixerHandle);
- volume_alsaMixerHandle = NULL;
-}
-
-static int prepAlsaMixer(char *card)
-{
- int err;
- snd_mixer_elem_t *elem;
- char *controlName = VOLUME_MIXER_ALSA_CONTROL_DEFAULT;
- ConfigParam *param;
-
- err = snd_mixer_open(&volume_alsaMixerHandle, 0);
- snd_config_update_free_global();
- if (err < 0) {
- WARNING("problems opening alsa mixer: %s\n", snd_strerror(err));
- return -1;
- }
-
- if ((err = snd_mixer_attach(volume_alsaMixerHandle, card)) < 0) {
- closeAlsaMixer();
- WARNING("problems attaching alsa mixer: %s\n",
- snd_strerror(err));
- return -1;
- }
-
- if ((err =
- snd_mixer_selem_register(volume_alsaMixerHandle, NULL,
- NULL)) < 0) {
- closeAlsaMixer();
- WARNING("problems snd_mixer_selem_register'ing: %s\n",
- snd_strerror(err));
- return -1;
- }
-
- if ((err = snd_mixer_load(volume_alsaMixerHandle)) < 0) {
- closeAlsaMixer();
- WARNING("problems snd_mixer_selem_register'ing: %s\n",
- snd_strerror(err));
- return -1;
- }
-
- elem = snd_mixer_first_elem(volume_alsaMixerHandle);
-
- param = getConfigParam(CONF_MIXER_CONTROL);
-
- if (param) {
- controlName = param->value;
- }
-
- while (elem) {
- if (snd_mixer_elem_get_type(elem) == SND_MIXER_ELEM_SIMPLE) {
- if (strcasecmp(controlName,
- snd_mixer_selem_get_name(elem)) == 0) {
- break;
- }
- }
- elem = snd_mixer_elem_next(elem);
- }
-
- if (elem) {
- volume_alsaElem = elem;
- snd_mixer_selem_get_playback_volume_range(volume_alsaElem,
- &volume_alsaMin,
- &volume_alsaMax);
- return 0;
- }
-
- WARNING("can't find alsa mixer_control \"%s\"\n", controlName);
-
- closeAlsaMixer();
- return -1;
-}
-
-static int prep_alsa_get_level(long *level)
-{
- const char *cmd;
- int err;
-
- if (!volume_alsaMixerHandle && prepAlsaMixer(volume_mixerDevice) < 0)
- return -1;
-
- if ((err = snd_mixer_handle_events(volume_alsaMixerHandle)) < 0) {
- cmd = "handle_events";
- goto error;
- }
- if ((err = snd_mixer_selem_get_playback_volume(volume_alsaElem,
- SND_MIXER_SCHN_FRONT_LEFT,
- level)) < 0) {
- cmd = "selem_get_playback_volume";
- goto error;
- }
- return 0;
-
-error:
- WARNING("problems getting alsa volume: %s (snd_mixer_%s)\n",
- snd_strerror(err), cmd);
- closeAlsaMixer();
- return -1;
-}
-
-static int getAlsaVolumeLevel(void)
-{
- int ret;
- long level;
- long max = volume_alsaMax;
- long min = volume_alsaMin;
-
- if (prep_alsa_get_level(&level) < 0)
- return -1;
-
- ret = ((volume_alsaSet / 100.0) * (max - min) + min) + 0.5;
- if (volume_alsaSet > 0 && ret == level) {
- ret = volume_alsaSet;
- } else
- ret = (int)(100 * (((float)(level - min)) / (max - min)) + 0.5);
-
- return ret;
-}
-
-static int changeAlsaVolumeLevel(int fd, int change, int rel)
-{
- float vol;
- long level;
- long test;
- long max = volume_alsaMax;
- long min = volume_alsaMin;
- int err;
-
- if (prep_alsa_get_level(&level) < 0)
- return -1;
-
- if (rel) {
- test = ((volume_alsaSet / 100.0) * (max - min) + min) + 0.5;
- if (volume_alsaSet >= 0 && level == test) {
- vol = volume_alsaSet;
- } else
- vol = 100.0 * (((float)(level - min)) / (max - min));
- vol += change;
- } else
- vol = change;
-
- volume_alsaSet = vol + 0.5;
- volume_alsaSet = volume_alsaSet > 100 ? 100 :
- (volume_alsaSet < 0 ? 0 : volume_alsaSet);
-
- level = (long)(((vol / 100.0) * (max - min) + min) + 0.5);
- level = level > max ? max : level;
- level = level < min ? min : level;
-
- if ((err =
- snd_mixer_selem_set_playback_volume_all(volume_alsaElem,
- level)) < 0) {
- commandError(fd, ACK_ERROR_SYSTEM, "problems setting volume");
- WARNING("problems setting alsa volume: %s\n",
- snd_strerror(err));
- closeAlsaMixer();
- return -1;
- }
-
- return 0;
-}
-#endif
-
-static int prepMixer(char *device)
-{
- switch (volume_mixerType) {
-#ifdef HAVE_ALSA
- case VOLUME_MIXER_TYPE_ALSA:
- return prepAlsaMixer(device);
-#endif
-#ifdef HAVE_OSS
- case VOLUME_MIXER_TYPE_OSS:
- return prepOssMixer(device);
-#endif
- }
-
- return 0;
-}
-
-void finishVolume(void)
-{
- switch (volume_mixerType) {
-#ifdef HAVE_ALSA
- case VOLUME_MIXER_TYPE_ALSA:
- closeAlsaMixer();
- break;
-#endif
-#ifdef HAVE_OSS
- case VOLUME_MIXER_TYPE_OSS:
- closeOssMixer();
- break;
-#endif
- }
-}
-
-void initVolume(void)
-{
- ConfigParam *param = getConfigParam(CONF_MIXER_TYPE);
-
- if (param) {
- if (0) ;
-#ifdef HAVE_ALSA
- else if (strcmp(param->value, VOLUME_MIXER_ALSA) == 0) {
- volume_mixerType = VOLUME_MIXER_TYPE_ALSA;
- volume_mixerDevice = VOLUME_MIXER_ALSA_DEFAULT;
- }
-#endif
-#ifdef HAVE_OSS
- else if (strcmp(param->value, VOLUME_MIXER_OSS) == 0) {
- volume_mixerType = VOLUME_MIXER_TYPE_OSS;
- volume_mixerDevice = VOLUME_MIXER_OSS_DEFAULT;
- }
-#endif
- else if (strcmp(param->value, VOLUME_MIXER_SOFTWARE) == 0) {
- volume_mixerType = VOLUME_MIXER_TYPE_SOFTWARE;
- volume_mixerDevice = VOLUME_MIXER_SOFTWARE_DEFAULT;
- } else {
- FATAL("unknown mixer type %s at line %i\n",
- param->value, param->line);
- }
- }
-
- param = getConfigParam(CONF_MIXER_DEVICE);
-
- if (param) {
- volume_mixerDevice = param->value;
- }
-}
-
-void openVolumeDevice(void)
-{
- if (prepMixer(volume_mixerDevice) < 0) {
- WARNING("using software volume\n");
- volume_mixerType = VOLUME_MIXER_TYPE_SOFTWARE;
- }
-}
-
-static int getSoftwareVolume(void)
-{
- return volume_softwareSet;
-}
-
-int getVolumeLevel(void)
-{
- switch (volume_mixerType) {
-#ifdef HAVE_ALSA
- case VOLUME_MIXER_TYPE_ALSA:
- return getAlsaVolumeLevel();
-#endif
-#ifdef HAVE_OSS
- case VOLUME_MIXER_TYPE_OSS:
- return getOssVolumeLevel();
-#endif
- case VOLUME_MIXER_TYPE_SOFTWARE:
- return getSoftwareVolume();
- default:
- return -1;
- }
-}
-
-static int changeSoftwareVolume(int fd, int change, int rel)
-{
- int new = change;
-
- if (rel)
- new += volume_softwareSet;
-
- if (new > 100)
- new = 100;
- else if (new < 0)
- new = 0;
-
- volume_softwareSet = new;
-
- /*new = 100.0*(exp(new/50.0)-1)/(M_E*M_E-1)+0.5; */
- if (new >= 100)
- new = 1000;
- else if (new <= 0)
- new = 0;
- else
- new =
- 1000.0 * (exp(new / 25.0) - 1) / (54.5981500331F - 1) + 0.5;
-
- setPlayerSoftwareVolume(new);
-
- return 0;
-}
-
-int changeVolumeLevel(int fd, int change, int rel)
-{
- switch (volume_mixerType) {
-#ifdef HAVE_ALSA
- case VOLUME_MIXER_TYPE_ALSA:
- return changeAlsaVolumeLevel(fd, change, rel);
-#endif
-#ifdef HAVE_OSS
- case VOLUME_MIXER_TYPE_OSS:
- return changeOssVolumeLevel(fd, change, rel);
-#endif
- case VOLUME_MIXER_TYPE_SOFTWARE:
- return changeSoftwareVolume(fd, change, rel);
- default:
- return 0;
- break;
- }
-}
-
-void read_sw_volume_state(FILE *fp)
-{
- /* strlen(SW_VOLUME_STATE) + strlen('100') + '\0' */
- #define bufsize 16
- char buf[bufsize];
- const size_t len = strlen(SW_VOLUME_STATE);
- char *end = NULL;
- long int sv;
-
- if (volume_mixerType != VOLUME_MIXER_TYPE_SOFTWARE)
- return;
- while (myFgets(buf, bufsize, fp)) {
- if (strncmp(buf, SW_VOLUME_STATE, len))
- continue;
- sv = strtol(buf + len, &end, 10);
- if (mpd_likely(!*end))
- changeSoftwareVolume(STDERR_FILENO, sv, 0);
- else
- ERROR("Can't parse software volume: %s\n", buf);
- return;
- }
- #undef bufsize
-}
-
-void save_sw_volume_state(FILE *fp)
-{
- if (volume_mixerType == VOLUME_MIXER_TYPE_SOFTWARE)
- fprintf(fp, SW_VOLUME_STATE "%d\n", volume_softwareSet);
-}
-
diff --git a/trunk/src/volume.h b/trunk/src/volume.h
deleted file mode 100644
index fcaefc64d..000000000
--- a/trunk/src/volume.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef VOLUME_H
-#define VOLUME_H
-
-#include "../config.h"
-
-#include <stdio.h>
-
-#define VOLUME_MIXER_OSS "oss"
-#define VOLUME_MIXER_ALSA "alsa"
-#define VOLUME_MIXER_SOFTWARE "software"
-
-void initVolume(void);
-
-void openVolumeDevice(void);
-
-void finishVolume(void);
-
-int getVolumeLevel(void);
-
-int changeVolumeLevel(int fd, int change, int rel);
-
-void read_sw_volume_state(FILE *fp);
-
-void save_sw_volume_state(FILE *fp);
-
-#endif
diff --git a/trunk/src/zeroconf.c b/trunk/src/zeroconf.c
deleted file mode 100644
index eeec794cd..000000000
--- a/trunk/src/zeroconf.c
+++ /dev/null
@@ -1,498 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-#include "zeroconf.h"
-#include "conf.h"
-#include "log.h"
-#include "listen.h"
-#include "ioops.h"
-#include "utils.h"
-
-/* The dns-sd service type qualifier to publish */
-#define SERVICE_TYPE "_mpd._tcp"
-
-/* The default service name to publish
- * (overridden by 'zeroconf_name' config parameter)
- */
-#define SERVICE_NAME "Music Player"
-
-/* Here is the implementation for Avahi (http://avahi.org) Zeroconf support */
-#ifdef HAVE_AVAHI
-
-#include <avahi-client/client.h>
-#include <avahi-client/publish.h>
-
-#include <avahi-common/alternative.h>
-#include <avahi-common/domain.h>
-#include <avahi-common/malloc.h>
-#include <avahi-common/error.h>
-
-/* Static avahi data */
-static AvahiEntryGroup *avahiGroup;
-static char *avahiName;
-static AvahiClient* avahiClient;
-static AvahiPoll avahiPoll;
-static int avahiRunning;
-
-static int avahiFdset( fd_set* rfds, fd_set* wfds, fd_set* efds );
-static int avahiFdconsume( int fdCount, fd_set* rfds, fd_set* wfds, fd_set* efds );
-static struct ioOps avahiIo = {
- .fdset = avahiFdset,
- .consume = avahiFdconsume,
-};
-
-/* Forward Declaration */
-static void avahiRegisterService(AvahiClient *c);
-
-struct AvahiWatch {
- struct AvahiWatch* prev;
- struct AvahiWatch* next;
- int fd;
- AvahiWatchEvent requestedEvent;
- AvahiWatchEvent observedEvent;
- AvahiWatchCallback callback;
- void* userdata;
-};
-
-struct AvahiTimeout {
- struct AvahiTimeout* prev;
- struct AvahiTimeout* next;
- struct timeval expiry;
- int enabled;
- AvahiTimeoutCallback callback;
- void* userdata;
-};
-
-static AvahiWatch* avahiWatchList;
-static AvahiTimeout* avahiTimeoutList;
-
-static AvahiWatch* avahiWatchNew( const AvahiPoll *api, int fd, AvahiWatchEvent event, AvahiWatchCallback callback, void *userdata )
-{
- struct AvahiWatch* newWatch = xmalloc( sizeof(struct AvahiWatch) );
-
- newWatch->fd = fd;
- newWatch->requestedEvent = event;
- newWatch->observedEvent = 0;
- newWatch->callback = callback;
- newWatch->userdata = userdata;
-
- /* Insert at front of list */
- newWatch->next = avahiWatchList;
- avahiWatchList = newWatch;
- newWatch->prev = NULL;
- if( newWatch->next )
- newWatch->next->prev = newWatch;
-
- return newWatch;
-}
-
-static void avahiWatchUpdate( AvahiWatch *w, AvahiWatchEvent event )
-{
- assert( w != NULL );
- w->requestedEvent = event;
-}
-
-static AvahiWatchEvent avahiWatchGetEvents( AvahiWatch *w )
-{
- assert( w != NULL );
- return w->observedEvent;
-}
-
-static void avahiWatchFree( AvahiWatch *w )
-{
- assert( w != NULL );
-
- if( avahiWatchList == w )
- avahiWatchList = w->next;
- else if( w->prev != NULL )
- w->prev->next = w->next;
-
- free( w );
-}
-
-static void avahiCheckExpiry( AvahiTimeout *t )
-{
- assert( t != NULL );
- if( t->enabled ) {
- struct timeval now;
- gettimeofday( &now, NULL );
- if( timercmp( &now, &(t->expiry), > ) ) {
- t->enabled = 0;
- t->callback( t, t->userdata );
- }
- }
-}
-
-static void avahiTimeoutUpdate( AvahiTimeout *t, const struct timeval *tv )
-{
- assert( t != NULL );
- if( tv ) {
- t->enabled = 1;
- t->expiry.tv_sec = tv->tv_sec;
- t->expiry.tv_usec = tv->tv_usec;
- } else {
- t->enabled = 0;
- }
-}
-
-static void avahiTimeoutFree( AvahiTimeout *t )
-{
- assert( t != NULL );
-
- if( avahiTimeoutList == t )
- avahiTimeoutList = t->next;
- else if( t->prev != NULL )
- t->prev->next = t->next;
-
- free( t );
-}
-
-static AvahiTimeout* avahiTimeoutNew( const AvahiPoll *api, const struct timeval *tv, AvahiTimeoutCallback callback, void *userdata )
-{
- struct AvahiTimeout* newTimeout = xmalloc( sizeof(struct AvahiTimeout) );
-
- newTimeout->callback = callback;
- newTimeout->userdata = userdata;
-
- avahiTimeoutUpdate( newTimeout, tv );
-
- /* Insert at front of list */
- newTimeout->next = avahiTimeoutList;
- avahiTimeoutList = newTimeout;
- newTimeout->prev = NULL;
- if( newTimeout->next )
- newTimeout->next->prev = newTimeout;
-
- return newTimeout;
-}
-
-/* Callback when the EntryGroup changes state */
-static void avahiGroupCallback(
- AvahiEntryGroup *g,
- AvahiEntryGroupState state,
- void *userdata)
-{
- assert(g);
-
- DEBUG( "Avahi: Service group changed to state %d\n", state );
-
- switch (state) {
- case AVAHI_ENTRY_GROUP_ESTABLISHED :
- /* The entry group has been established successfully */
- LOG( "Avahi: Service '%s' successfully established.\n", avahiName );
- break;
-
- case AVAHI_ENTRY_GROUP_COLLISION : {
- char *n;
-
- /* A service name collision happened. Let's pick a new name */
- n = avahi_alternative_service_name(avahiName);
- avahi_free(avahiName);
- avahiName = n;
-
- LOG( "Avahi: Service name collision, renaming service to '%s'\n", avahiName );
-
- /* And recreate the services */
- avahiRegisterService(avahi_entry_group_get_client(g));
- break;
- }
-
- case AVAHI_ENTRY_GROUP_FAILURE :
- ERROR( "Avahi: Entry group failure: %s\n",
- avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g))) );
- /* Some kind of failure happened while we were registering our services */
- avahiRunning = 0;
- break;
-
- case AVAHI_ENTRY_GROUP_UNCOMMITED:
- DEBUG( "Avahi: Service group is UNCOMMITED\n" );
- break;
- case AVAHI_ENTRY_GROUP_REGISTERING:
- DEBUG( "Avahi: Service group is REGISTERING\n" );
- ;
- }
-}
-
-/* Registers a new service with avahi */
-static void avahiRegisterService(AvahiClient *c)
-{
- int ret;
- assert(c);
- DEBUG( "Avahi: Registering service %s/%s\n", SERVICE_TYPE, avahiName );
-
- /* If this is the first time we're called, let's create a new entry group */
- if (!avahiGroup) {
- avahiGroup = avahi_entry_group_new(c, avahiGroupCallback, NULL);
- if( !avahiGroup ) {
- ERROR( "Avahi: Failed to create avahi EntryGroup: %s\n", avahi_strerror(avahi_client_errno(c)) );
- goto fail;
- }
- }
-
- /* Add the service */
- /* TODO: This currently binds to ALL interfaces.
- * We could maybe add a service per actual bound interface, if that's better. */
- ret = avahi_entry_group_add_service(avahiGroup,
- AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0,
- avahiName, SERVICE_TYPE,
- NULL, NULL,
- getBoundPort(),
- NULL);
- if( ret < 0 ) {
- ERROR( "Avahi: Failed to add service %s: %s\n", SERVICE_TYPE, avahi_strerror(ret) );
- goto fail;
- }
-
- /* Tell the server to register the service group */
- ret = avahi_entry_group_commit(avahiGroup);
- if( ret < 0 ) {
- ERROR( "Avahi: Failed to commit service group: %s\n", avahi_strerror(ret) );
- goto fail;
- }
- return;
-
-fail:
- avahiRunning = 0;
-}
-
-/* Callback when avahi changes state */
-static void avahiClientCallback(AvahiClient *c, AvahiClientState state, void *userdata)
-{
- assert(c);
-
- /* Called whenever the client or server state changes */
- DEBUG( "Avahi: Client changed to state %d\n", state );
-
- switch (state) {
- case AVAHI_CLIENT_S_RUNNING:
- DEBUG( "Avahi: Client is RUNNING\n" );
-
- /* The server has startup successfully and registered its host
- * name on the network, so it's time to create our services */
- if (!avahiGroup)
- avahiRegisterService(c);
- break;
-
- case AVAHI_CLIENT_FAILURE:
- {
- int reason = avahi_client_errno(c);
- if( reason == AVAHI_ERR_DISCONNECTED ) {
- LOG( "Avahi: Client Disconnected, will reconnect shortly\n");
- avahi_entry_group_free( avahiGroup );
- avahiGroup = NULL;
- avahi_client_free( avahiClient );
- avahiClient = NULL;
- avahiClient = avahi_client_new( &avahiPoll, AVAHI_CLIENT_NO_FAIL,
- avahiClientCallback, NULL, &reason );
- if( !avahiClient ) {
- ERROR( "Avahi: Could not reconnect: %s\n", avahi_strerror(reason) );
- avahiRunning = 0;
- }
- } else {
- ERROR( "Avahi: Client failure: %s (terminal)\n", avahi_strerror(reason));
- avahiRunning = 0;
- }
- }
- break;
-
- case AVAHI_CLIENT_S_COLLISION:
- DEBUG( "Avahi: Client is COLLISION\n" );
- /* Let's drop our registered services. When the server is back
- * in AVAHI_SERVER_RUNNING state we will register them
- * again with the new host name. */
- if (avahiGroup) {
- DEBUG( "Avahi: Resetting group\n" );
- avahi_entry_group_reset(avahiGroup);
- }
-
- case AVAHI_CLIENT_S_REGISTERING:
- DEBUG( "Avahi: Client is REGISTERING\n" );
- /* The server records are now being established. This
- * might be caused by a host name change. We need to wait
- * for our own records to register until the host name is
- * properly esatblished. */
-
- if (avahiGroup) {
- DEBUG( "Avahi: Resetting group\n" );
- avahi_entry_group_reset(avahiGroup);
- }
-
- break;
-
- case AVAHI_CLIENT_CONNECTING:
- DEBUG( "Avahi: Client is CONNECTING\n" );
- ;
- }
-}
-
-static int avahiFdset( fd_set* rfds, fd_set* wfds, fd_set* efds )
-{
- AvahiWatch* w;
- int maxfd = -1;
- if( !avahiRunning )
- return maxfd;
- for( w = avahiWatchList; w != NULL; w = w->next ) {
- if( w->requestedEvent & AVAHI_WATCH_IN ) {
- FD_SET( w->fd, rfds );
- }
- if( w->requestedEvent & AVAHI_WATCH_OUT ) {
- FD_SET( w->fd, wfds );
- }
- if( w->requestedEvent & AVAHI_WATCH_ERR ) {
- FD_SET( w->fd, efds );
- }
- if( w->requestedEvent & AVAHI_WATCH_HUP ) {
- ERROR( "Avahi: No support for HUP events! (ignoring)\n" );
- }
-
- if( w->fd > maxfd )
- maxfd = w->fd;
- }
- return maxfd;
-}
-
-static int avahiFdconsume( int fdCount, fd_set* rfds, fd_set* wfds, fd_set* efds )
-{
- int retval = fdCount;
- AvahiTimeout* t;
- AvahiWatch* w = avahiWatchList;
-
- while( w != NULL && retval > 0 ) {
- AvahiWatch* current = w;
- current->observedEvent = 0;
- if( FD_ISSET( current->fd, rfds ) ) {
- current->observedEvent |= AVAHI_WATCH_IN;
- FD_CLR( current->fd, rfds );
- retval--;
- }
- if( FD_ISSET( current->fd, wfds ) ) {
- current->observedEvent |= AVAHI_WATCH_OUT;
- FD_CLR( current->fd, wfds );
- retval--;
- }
- if( FD_ISSET( current->fd, efds ) ) {
- current->observedEvent |= AVAHI_WATCH_ERR;
- FD_CLR( current->fd, efds );
- retval--;
- }
-
- /* Advance to the next one right now, in case the callback
- * removes itself
- */
- w = w->next;
-
- if( current->observedEvent && avahiRunning ) {
- current->callback( current, current->fd,
- current->observedEvent, current->userdata );
- }
- }
-
- t = avahiTimeoutList;
- while( t != NULL && avahiRunning ) {
- AvahiTimeout* current = t;
-
- /* Advance to the next one right now, in case the callback
- * removes itself
- */
- t = t->next;
- avahiCheckExpiry( current );
- }
-
- return retval;
-}
-
-static void init_avahi(const char *serviceName)
-{
- int error;
- DEBUG( "Avahi: Initializing interface\n" );
-
- if( avahi_is_valid_service_name( serviceName ) ) {
- avahiName = avahi_strdup( serviceName );
- } else {
- ERROR( "Invalid zeroconf_name \"%s\", defaulting to \"%s\" instead.\n", serviceName, SERVICE_NAME );
- avahiName = avahi_strdup( SERVICE_NAME );
- }
-
- avahiRunning = 1;
-
- avahiPoll.userdata = NULL;
- avahiPoll.watch_new = avahiWatchNew;
- avahiPoll.watch_update = avahiWatchUpdate;
- avahiPoll.watch_get_events = avahiWatchGetEvents;
- avahiPoll.watch_free = avahiWatchFree;
- avahiPoll.timeout_new = avahiTimeoutNew;
- avahiPoll.timeout_update = avahiTimeoutUpdate;
- avahiPoll.timeout_free = avahiTimeoutFree;
-
- avahiClient = avahi_client_new( &avahiPoll, AVAHI_CLIENT_NO_FAIL,
- avahiClientCallback, NULL, &error );
-
- if( !avahiClient ) {
- ERROR( "Avahi: Failed to create client: %s\n", avahi_strerror(error) );
- goto fail;
- }
-
- avahiIo.fdset = avahiFdset;
- avahiIo.consume = avahiFdconsume;
- registerIO( &avahiIo );
-
- return;
-
-fail:
- finishZeroconf();
-}
-#else /* !HAVE_AVAHI */
-static void init_avahi(const char *serviceName) { }
-#endif /* HAVE_AVAHI */
-
-void initZeroconf(void)
-{
- const char* serviceName = SERVICE_NAME;
- ConfigParam *param;
-
- param = getConfigParam(CONF_ZEROCONF_NAME);
-
- if (param && strlen(param->value) > 0)
- serviceName = param->value;
- init_avahi(serviceName);
-}
-
-void finishZeroconf(void)
-{
-#ifdef HAVE_AVAHI
- DEBUG( "Avahi: Shutting down interface\n" );
- deregisterIO( &avahiIo );
-
- if( avahiGroup ) {
- avahi_entry_group_free( avahiGroup );
- avahiGroup = NULL;
- }
-
- if( avahiClient ) {
- avahi_client_free( avahiClient );
- avahiClient = NULL;
- }
-
- avahi_free( avahiName );
- avahiName = NULL;
-#endif /* HAVE_AVAHI */
-}
diff --git a/trunk/src/zeroconf.h b/trunk/src/zeroconf.h
deleted file mode 100644
index ef7167d53..000000000
--- a/trunk/src/zeroconf.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* the Music Player Daemon (MPD)
- * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
- * This project's homepage is: http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef ZEROCONF_H
-#define ZEROCONF_H
-
-#include "../config.h"
-
-void initZeroconf(void);
-void finishZeroconf(void);
-
-#endif