sidplay: new decoder plugin for playing C64 SID files
This commit is contained in:
		
							
								
								
									
										3
									
								
								INSTALL
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								INSTALL
									
									
									
									
									
								
							| @@ -95,6 +95,9 @@ For MOD support.  You will need libmikmod. | |||||||
| libavcodec, libavformat (ffmpeg) - http://ffmpeg.mplayerhq.hu/ | libavcodec, libavformat (ffmpeg) - http://ffmpeg.mplayerhq.hu/ | ||||||
| Multi-codec library. | Multi-codec library. | ||||||
|  |  | ||||||
|  | libsidplay2 - http://sidplay2.sourceforge.net/ | ||||||
|  | For C64 SID support. | ||||||
|  |  | ||||||
|  |  | ||||||
| Optional Miscellaneous Dependencies | Optional Miscellaneous Dependencies | ||||||
| ----------------------------------- | ----------------------------------- | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								NEWS
									
									
									
									
									
								
							| @@ -10,6 +10,7 @@ ver 0.15 - (200?/??/??) | |||||||
|   - audiofile: streaming support added |   - audiofile: streaming support added | ||||||
|   - modplug: another MOD plugin, based on libmodplug |   - modplug: another MOD plugin, based on libmodplug | ||||||
|   - mikmod disabled by default, due to severe security issues in libmikmod |   - mikmod disabled by default, due to severe security issues in libmikmod | ||||||
|  |   - sidplay: new decoder plugin for C64 SID (using libsidplay2) | ||||||
| * audio outputs: | * audio outputs: | ||||||
|   - shout: enlarged buffer size to 32 kB |   - shout: enlarged buffer size to 32 kB | ||||||
|   - null: allow disabling synchronization |   - null: allow disabling synchronization | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								configure.ac
									
									
									
									
									
								
							| @@ -412,6 +412,11 @@ AC_ARG_WITH(tremor,[[  --with-tremor[=PFX]         Use Tremor(vorbisidec) intege | |||||||
| AC_ARG_WITH(tremor-libraries,[  --with-tremor-libraries=DIR Directory where Tremor library is installed (optional)], tremor_libraries="$withval", tremor_libraries="") | AC_ARG_WITH(tremor-libraries,[  --with-tremor-libraries=DIR Directory where Tremor library is installed (optional)], tremor_libraries="$withval", tremor_libraries="") | ||||||
| AC_ARG_WITH(tremor-includes,[  --with-tremor-includes=DIR  Directory where Tremor header files are installed (optional)], tremor_includes="$withval", tremor_includes="") | AC_ARG_WITH(tremor-includes,[  --with-tremor-includes=DIR  Directory where Tremor header files are installed (optional)], tremor_includes="$withval", tremor_includes="") | ||||||
|  |  | ||||||
|  | AC_ARG_ENABLE(sidplay, | ||||||
|  | 	AS_HELP_STRING([--enable-sidplay], | ||||||
|  | 		[enable C64 SID support via libsidplay2 (default: disable)]),, | ||||||
|  | 	enable_sidplay=no) | ||||||
|  |  | ||||||
| AC_ARG_ENABLE(wavpack, | AC_ARG_ENABLE(wavpack, | ||||||
| 	AS_HELP_STRING([--disable-wavpack], | 	AS_HELP_STRING([--disable-wavpack], | ||||||
| 		[disable WavPack support (default: enable)]), | 		[disable WavPack support (default: enable)]), | ||||||
| @@ -1004,6 +1009,20 @@ fi | |||||||
|  |  | ||||||
| AM_CONDITIONAL(HAVE_FFMPEG, test x$enable_ffmpeg = xyes) | AM_CONDITIONAL(HAVE_FFMPEG, test x$enable_ffmpeg = xyes) | ||||||
|  |  | ||||||
|  | if test x$enable_sidplay = xyes; then | ||||||
|  | 	# libsidplay2 exposes a C++ interface | ||||||
|  | 	AC_PROG_CXX | ||||||
|  |  | ||||||
|  | 	# we have no test yet.. we're not using pkg-config here | ||||||
|  | 	# because libsidplay2's .pc file requires libtool | ||||||
|  | 	AC_SUBST(SIDPLAY_LIBS,"-lsidplay2 -lresid-builder") | ||||||
|  | 	AC_SUBST(SIDPLAY_CFLAGS,) | ||||||
|  |  | ||||||
|  | 	AC_DEFINE(ENABLE_SIDPLAY, 1, [Define for libsidplay2 support]), | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | AM_CONDITIONAL(ENABLE_SIDPLAY, test x$enable_sidplay = xyes) | ||||||
|  |  | ||||||
|  |  | ||||||
| dnl | dnl | ||||||
| dnl Documentation | dnl Documentation | ||||||
| @@ -1283,6 +1302,12 @@ else | |||||||
| 	echo " MODPLUG support ...............disabled" | 	echo " MODPLUG support ...............disabled" | ||||||
| fi | fi | ||||||
|  |  | ||||||
|  | if test x$enable_sidplay = xyes; then | ||||||
|  | 	echo " C64 SID support ...............enabled" | ||||||
|  | else | ||||||
|  | 	echo " C64 SID support ...............disabled" | ||||||
|  | fi | ||||||
|  |  | ||||||
| if test x$enable_ffmpeg = xyes; then | if test x$enable_ffmpeg = xyes; then | ||||||
| 	echo " FFMPEG support ................enabled" | 	echo " FFMPEG support ................enabled" | ||||||
| else | else | ||||||
| @@ -1300,6 +1325,7 @@ if | |||||||
| 	test x$enable_wavpack = xno && | 	test x$enable_wavpack = xno && | ||||||
| 	test x$enable_ffmpeg = xno && | 	test x$enable_ffmpeg = xno && | ||||||
| 	test x$enable_modplug = xno && | 	test x$enable_modplug = xno && | ||||||
|  | 	test x$enable_sidplay = xno && | ||||||
| 	test x$enable_mod = xno; then | 	test x$enable_mod = xno; then | ||||||
| 	AC_MSG_ERROR([No input plugins supported!]) | 	AC_MSG_ERROR([No input plugins supported!]) | ||||||
| fi | fi | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ mpd_CPPFLAGS = \ | |||||||
| 	$(patsubst -I%/FLAC,-I%,$(FLAC_CFLAGS)) \ | 	$(patsubst -I%/FLAC,-I%,$(FLAC_CFLAGS)) \ | ||||||
| 	$(AUDIOFILE_CFLAGS) $(LIBMIKMOD_CFLAGS) \ | 	$(AUDIOFILE_CFLAGS) $(LIBMIKMOD_CFLAGS) \ | ||||||
| 	$(MODPLUG_CFLAGS) \ | 	$(MODPLUG_CFLAGS) \ | ||||||
|  | 	$(SIDPLAY_CFLAGS) \ | ||||||
| 	$(ID3TAG_CFLAGS) \ | 	$(ID3TAG_CFLAGS) \ | ||||||
| 	$(MAD_CFLAGS) \ | 	$(MAD_CFLAGS) \ | ||||||
| 	$(FFMPEG_CFLAGS) \ | 	$(FFMPEG_CFLAGS) \ | ||||||
| @@ -24,6 +25,7 @@ mpd_LDADD = $(MPD_LIBS) \ | |||||||
| 	$(OGGVORBIS_LIBS) $(VORBISENC_LIBS) $(FLAC_LIBS) \ | 	$(OGGVORBIS_LIBS) $(VORBISENC_LIBS) $(FLAC_LIBS) \ | ||||||
| 	$(AUDIOFILE_LIBS) $(LIBMIKMOD_LIBS) \ | 	$(AUDIOFILE_LIBS) $(LIBMIKMOD_LIBS) \ | ||||||
| 	$(MODPLUG_LIBS) \ | 	$(MODPLUG_LIBS) \ | ||||||
|  | 	$(SIDPLAY_LIBS) \ | ||||||
| 	$(ID3TAG_LIBS) \ | 	$(ID3TAG_LIBS) \ | ||||||
| 	$(MAD_LIBS) \ | 	$(MAD_LIBS) \ | ||||||
| 	$(MP4FF_LIBS) \ | 	$(MP4FF_LIBS) \ | ||||||
| @@ -311,6 +313,10 @@ if HAVE_MODPLUG | |||||||
| mpd_SOURCES += decoder/modplug_plugin.c | mpd_SOURCES += decoder/modplug_plugin.c | ||||||
| endif | endif | ||||||
|  |  | ||||||
|  | if ENABLE_SIDPLAY | ||||||
|  | mpd_SOURCES += decoder/sidplay_plugin.cxx | ||||||
|  | endif | ||||||
|  |  | ||||||
| if HAVE_FFMPEG | if HAVE_FFMPEG | ||||||
| mpd_SOURCES += decoder/ffmpeg_plugin.c | mpd_SOURCES += decoder/ffmpeg_plugin.c | ||||||
| endif | endif | ||||||
|   | |||||||
							
								
								
									
										161
									
								
								src/decoder/sidplay_plugin.cxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								src/decoder/sidplay_plugin.cxx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,161 @@ | |||||||
|  | /* | ||||||
|  |  * 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 | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | extern "C" { | ||||||
|  | #include "../decoder_api.h" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #include <glib.h> | ||||||
|  |  | ||||||
|  | #include <sidplay/sidplay2.h> | ||||||
|  | #include <sidplay/builders/resid.h> | ||||||
|  |  | ||||||
|  | #undef G_LOG_DOMAIN | ||||||
|  | #define G_LOG_DOMAIN "sidplay" | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | sidplay_file_decode(struct decoder *decoder, const char *path_fs) | ||||||
|  | { | ||||||
|  | 	int ret; | ||||||
|  |  | ||||||
|  | 	/* load the tune */ | ||||||
|  |  | ||||||
|  | 	SidTune tune(path_fs, NULL, true); | ||||||
|  | 	if (!tune) { | ||||||
|  | 		g_warning("failed to load file"); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tune.selectSong(1); | ||||||
|  |  | ||||||
|  | 	/* initialize the player */ | ||||||
|  |  | ||||||
|  | 	sidplay2 player; | ||||||
|  | 	int iret = player.load(&tune); | ||||||
|  | 	if (iret != 0) { | ||||||
|  | 		g_warning("sidplay2.load() failed: %s", player.error()); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* initialize the builder */ | ||||||
|  |  | ||||||
|  | 	ReSIDBuilder builder("ReSID"); | ||||||
|  | 	if (!builder) { | ||||||
|  | 		g_warning("failed to initialize ReSIDBuilder"); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	builder.create(player.info().maxsids); | ||||||
|  | 	if (!builder) { | ||||||
|  | 		g_warning("ReSIDBuilder.create() failed"); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	builder.filter(false); | ||||||
|  | 	if (!builder) { | ||||||
|  | 		g_warning("ReSIDBuilder.filter() failed"); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* configure the player */ | ||||||
|  |  | ||||||
|  | 	sid2_config_t config = player.config(); | ||||||
|  |  | ||||||
|  | 	config.clockDefault = SID2_CLOCK_PAL; | ||||||
|  | 	config.clockForced = true; | ||||||
|  | 	config.clockSpeed = SID2_CLOCK_CORRECT; | ||||||
|  | 	config.frequency = 48000; | ||||||
|  | 	config.optimisation = SID2_DEFAULT_OPTIMISATION; | ||||||
|  | 	config.playback = sid2_stereo; | ||||||
|  | 	config.precision = 16; | ||||||
|  | 	config.sidDefault = SID2_MOS6581; | ||||||
|  | 	config.sidEmulation = &builder; | ||||||
|  | 	config.sidModel = SID2_MODEL_CORRECT; | ||||||
|  | 	config.sidSamples = true; | ||||||
|  | #if G_BYTE_ORDER == G_LITTLE_ENDIAN | ||||||
|  | 	config.sampleFormat = SID2_LITTLE_SIGNED; | ||||||
|  | #else | ||||||
|  | 	config.sampleFormat = SID2_BIG_SIGNED; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | 	iret = player.config(config); | ||||||
|  | 	if (iret != 0) { | ||||||
|  | 		g_warning("sidplay2.config() failed: %s", player.error()); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* initialize the MPD decoder */ | ||||||
|  |  | ||||||
|  | 	struct audio_format audio_format; | ||||||
|  | 	audio_format.sample_rate = 48000; | ||||||
|  | 	audio_format.bits = 16; | ||||||
|  | 	audio_format.channels = 2; | ||||||
|  |  | ||||||
|  | 	decoder_initialized(decoder, &audio_format, false, -1); | ||||||
|  |  | ||||||
|  | 	/* .. and play */ | ||||||
|  |  | ||||||
|  | 	enum decoder_command cmd; | ||||||
|  | 	do { | ||||||
|  | 		char buffer[4096]; | ||||||
|  | 		size_t nbytes; | ||||||
|  |  | ||||||
|  | 		nbytes = player.play(buffer, sizeof(buffer)); | ||||||
|  | 		if (nbytes == 0) | ||||||
|  | 			break; | ||||||
|  |  | ||||||
|  | 		cmd = decoder_data(decoder, NULL, buffer, nbytes, | ||||||
|  | 				   0, 0, NULL); | ||||||
|  | 	} while (cmd == DECODE_COMMAND_NONE); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static struct tag * | ||||||
|  | sidplay_tag_dup(const char *path_fs) | ||||||
|  | { | ||||||
|  | 	SidTune tune(path_fs, NULL, true); | ||||||
|  | 	if (!tune) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	const SidTuneInfo &info = tune.getInfo(); | ||||||
|  | 	struct tag *tag = tag_new(); | ||||||
|  |  | ||||||
|  | 	if (info.numberOfInfoStrings > 0 && info.infoString[0] != NULL) | ||||||
|  | 		tag_add_item(tag, TAG_ITEM_TITLE, info.infoString[0]); | ||||||
|  |  | ||||||
|  | 	if (info.numberOfInfoStrings > 1 && info.infoString[1] != NULL) | ||||||
|  | 		tag_add_item(tag, TAG_ITEM_ARTIST, info.infoString[1]); | ||||||
|  |  | ||||||
|  | 	return tag; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static const char *const sidplay_suffixes[] = { | ||||||
|  | 	"sid", | ||||||
|  | 	NULL | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | extern const struct decoder_plugin sidplay_decoder_plugin; | ||||||
|  | const struct decoder_plugin sidplay_decoder_plugin = { | ||||||
|  | 	"sidplay", | ||||||
|  | 	NULL, /* init() */ | ||||||
|  | 	NULL, /* finish() */ | ||||||
|  | 	NULL, /* stream_decode() */ | ||||||
|  | 	sidplay_file_decode, | ||||||
|  | 	sidplay_tag_dup, | ||||||
|  | 	sidplay_suffixes, | ||||||
|  | 	NULL, /* mime_types */ | ||||||
|  | }; | ||||||
| @@ -34,6 +34,7 @@ extern const struct decoder_plugin mpcPlugin; | |||||||
| extern const struct decoder_plugin wavpack_plugin; | extern const struct decoder_plugin wavpack_plugin; | ||||||
| extern const struct decoder_plugin modplug_plugin; | extern const struct decoder_plugin modplug_plugin; | ||||||
| extern const struct decoder_plugin mikmod_decoder_plugin; | extern const struct decoder_plugin mikmod_decoder_plugin; | ||||||
|  | extern const struct decoder_plugin sidplay_decoder_plugin; | ||||||
| extern const struct decoder_plugin ffmpeg_plugin; | extern const struct decoder_plugin ffmpeg_plugin; | ||||||
|  |  | ||||||
| static const struct decoder_plugin *const decoder_plugins[] = { | static const struct decoder_plugin *const decoder_plugins[] = { | ||||||
| @@ -70,6 +71,9 @@ static const struct decoder_plugin *const decoder_plugins[] = { | |||||||
| #ifdef HAVE_MIKMOD | #ifdef HAVE_MIKMOD | ||||||
| 	&mikmod_decoder_plugin, | 	&mikmod_decoder_plugin, | ||||||
| #endif | #endif | ||||||
|  | #ifdef ENABLE_SIDPLAY | ||||||
|  | 	&sidplay_decoder_plugin, | ||||||
|  | #endif | ||||||
| #ifdef HAVE_FFMPEG | #ifdef HAVE_FFMPEG | ||||||
| 	&ffmpeg_plugin, | 	&ffmpeg_plugin, | ||||||
| #endif | #endif | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann