diff --git a/configure.ac b/configure.ac index 95e9eec1a..b8fefa06b 100644 --- a/configure.ac +++ b/configure.ac @@ -589,6 +589,8 @@ AM_CONDITIONAL(HAVE_SHOUT, test x$enable_shout = xyes) AM_CONDITIONAL(HAVE_SHOUT_OGG, test x$enable_shout_ogg = xyes) AM_CONDITIONAL(HAVE_SHOUT_MP3, test x$enable_shout_mp3 = xyes) +AM_CONDITIONAL(ENABLE_ENCODER, test x$enable_shout = xyes) + if test x$enable_ao = xyes; then PKG_CHECK_MODULES(AO, [ao], AC_DEFINE(HAVE_AO, 1, [Define to play with ao]), diff --git a/src/Makefile.am b/src/Makefile.am index 237d313f0..2ec4c9ccc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -73,6 +73,9 @@ mpd_headers = \ directory_save.h \ directory_print.h \ database.h \ + encoder_plugin.h \ + encoder_list.h \ + encoder_api.h \ update.h \ dirvec.h \ gcc.h \ @@ -341,6 +344,12 @@ if HAVE_FFMPEG mpd_SOURCES += decoder/ffmpeg_plugin.c endif +# encoder plugins + +if ENABLE_ENCODER +mpd_SOURCES += encoder_list.c +endif + if HAVE_ZEROCONF mpd_SOURCES += zeroconf.c diff --git a/src/encoder_api.h b/src/encoder_api.h new file mode 100644 index 000000000..badeae5f7 --- /dev/null +++ b/src/encoder_api.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2003-2009 The Music Player Daemon Project + * 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 + */ + +/* + * This header is included by encoder plugins. + * + */ + +#ifndef MPD_ENCODER_API_H +#define MPD_ENCODER_API_H + +#include "encoder_plugin.h" +#include "audio_format.h" +#include "tag.h" +#include "conf.h" + +#endif diff --git a/src/encoder_list.c b/src/encoder_list.c new file mode 100644 index 000000000..4108b97a0 --- /dev/null +++ b/src/encoder_list.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2003-2009 The Music Player Daemon Project + * 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 "encoder_list.h" +#include "encoder_plugin.h" +#include "config.h" + +#include + +static const struct encoder_plugin *encoder_plugins[] = { + NULL +}; + +const struct encoder_plugin * +encoder_plugin_get(const char *name) +{ + for (unsigned i = 0; encoder_plugins[i] != NULL; ++i) + if (strcmp(encoder_plugins[i]->name, name) == 0) + return encoder_plugins[i]; + + return NULL; +} diff --git a/src/encoder_list.h b/src/encoder_list.h new file mode 100644 index 000000000..589319e1d --- /dev/null +++ b/src/encoder_list.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2003-2009 The Music Player Daemon Project + * 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_ENCODER_LIST_H +#define MPD_ENCODER_LIST_H + +struct encoder_plugin; + +/** + * Looks up an encoder plugin by its name. + * + * @param name the encoder name to look for + * @return the encoder plugin with the specified name, or NULL if none + * was found + */ +const struct encoder_plugin * +encoder_plugin_get(const char *name); + +#endif diff --git a/src/encoder_plugin.h b/src/encoder_plugin.h new file mode 100644 index 000000000..7fbdf321f --- /dev/null +++ b/src/encoder_plugin.h @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2003-2009 The Music Player Daemon Project + * 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_ENCODER_PLUGIN_H +#define MPD_ENCODER_PLUGIN_H + +#include + +#include +#include + +struct encoder_plugin; +struct audio_format; +struct config_param; +struct tag; + +struct encoder { + const struct encoder_plugin *plugin; +}; + +struct encoder_plugin { + const char *name; + + struct encoder *(*init)(const struct config_param *param, + GError **error); + + void (*finish)(struct encoder *encoder); + + bool (*open)(struct encoder *encoder, + struct audio_format *audio_format, + GError **error); + + void (*close)(struct encoder *encoder); + + bool (*flush)(struct encoder *encoder, GError **error); + + bool (*tag)(struct encoder *encoder, const struct tag *tag, + GError **error); + + bool (*write)(struct encoder *encoder, + const void *data, size_t length, + GError **error); + + size_t (*read)(struct encoder *encoder, void *dest, size_t length); +}; + +/** + * Initializes an encoder object. This should be used by encoder + * plugins to initialize their base class. + */ +static inline void +encoder_struct_init(struct encoder *encoder, + const struct encoder_plugin *plugin) +{ + encoder->plugin = plugin; +} + +/** + * Creates a new encoder object. + * + * @param plugin the encoder plugin + * @param param optional configuration + * @param error location to store the error occuring, or NULL to ignore errors. + * @return an encoder object on success, NULL on failure + */ +static inline struct encoder * +encoder_init(const struct encoder_plugin *plugin, + const struct config_param *param, GError **error) +{ + return plugin->init(param, error); +} + +/** + * Frees an encoder object. + * + * @param encoder the encoder + */ +static inline void +encoder_finish(struct encoder *encoder) +{ + encoder->plugin->finish(encoder); +} + +/** + * Opens an encoder object. You must call this prior to using it. + * Before you free it, you must call encoder_close(). You may open + * and close (reuse) one encoder any number of times. + * + * @param encoder the encoder + * @param audio_format the encoder's input audio format; the plugin + * may modify the struct to adapt it to its abilities + * @param error location to store the error occuring, or NULL to ignore errors. + * @return true on success + */ +static inline bool +encoder_open(struct encoder *encoder, struct audio_format *audio_format, + GError **error) +{ + return encoder->plugin->open(encoder, audio_format, error); +} + +/** + * Closes an encoder object. This disables the encoder, and readies + * it for reusal by calling encoder_open() again. + * + * @param encoder the encoder + */ +static inline void +encoder_close(struct encoder *encoder) +{ + if (encoder->plugin->close != NULL) + encoder->plugin->close(encoder); +} + +/** + * Flushes an encoder object, make everything which might currently be + * buffered available by encoder_read(). + * + * @param encoder the encoder + * @param error location to store the error occuring, or NULL to ignore errors. + * @return true on success + */ +static inline bool +encoder_flush(struct encoder *encoder, GError **error) +{ + /* this method is optional */ + return encoder->plugin->flush != NULL + ? encoder->plugin->flush(encoder, error) + : true; +} + +/** + * Sends a tag to the encoder. + * + * @param encoder the encoder + * @param tag the tag object + * @param error location to store the error occuring, or NULL to ignore errors. + * @return true on success + */ +static inline bool +encoder_tag(struct encoder *encoder, const struct tag *tag, GError **error) +{ + /* this method is optional */ + return encoder->plugin->tag != NULL + ? encoder->plugin->tag(encoder, tag, error) + : true; +} + +/** + * Writes raw PCM data to the encoder. + * + * @param encoder the encoder + * @param data the buffer containing PCM samples + * @param length the length of the buffer in bytes + * @param error location to store the error occuring, or NULL to ignore errors. + * @return true on success + */ +static inline bool +encoder_write(struct encoder *encoder, const void *data, size_t length, + GError **error) +{ + return encoder->plugin->write(encoder, data, length, error); +} + +/** + * Reads encoded data from the encoder. + * + * @param encoder the encoder + * @param dest the destination buffer to copy to + * @param length the maximum length of the destination buffer + * @return the number of bytes written to #dest + */ +static inline size_t +encoder_read(struct encoder *encoder, void *dest, size_t length) +{ + return encoder->plugin->read(encoder, dest, length); +} + +#endif