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/ | ||||
| Multi-codec library. | ||||
|  | ||||
| libsidplay2 - http://sidplay2.sourceforge.net/ | ||||
| For C64 SID support. | ||||
|  | ||||
|  | ||||
| Optional Miscellaneous Dependencies | ||||
| ----------------------------------- | ||||
|   | ||||
							
								
								
									
										1
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								NEWS
									
									
									
									
									
								
							| @@ -10,6 +10,7 @@ ver 0.15 - (200?/??/??) | ||||
|   - audiofile: streaming support added | ||||
|   - modplug: another MOD plugin, based on libmodplug | ||||
|   - mikmod disabled by default, due to severe security issues in libmikmod | ||||
|   - sidplay: new decoder plugin for C64 SID (using libsidplay2) | ||||
| * audio outputs: | ||||
|   - shout: enlarged buffer size to 32 kB | ||||
|   - 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-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, | ||||
| 	AS_HELP_STRING([--disable-wavpack], | ||||
| 		[disable WavPack support (default: enable)]), | ||||
| @@ -1004,6 +1009,20 @@ fi | ||||
|  | ||||
| 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 Documentation | ||||
| @@ -1283,6 +1302,12 @@ else | ||||
| 	echo " MODPLUG support ...............disabled" | ||||
| 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 | ||||
| 	echo " FFMPEG support ................enabled" | ||||
| else | ||||
| @@ -1300,6 +1325,7 @@ if | ||||
| 	test x$enable_wavpack = xno && | ||||
| 	test x$enable_ffmpeg = xno && | ||||
| 	test x$enable_modplug = xno && | ||||
| 	test x$enable_sidplay = xno && | ||||
| 	test x$enable_mod = xno; then | ||||
| 	AC_MSG_ERROR([No input plugins supported!]) | ||||
| fi | ||||
|   | ||||
| @@ -11,6 +11,7 @@ mpd_CPPFLAGS = \ | ||||
| 	$(patsubst -I%/FLAC,-I%,$(FLAC_CFLAGS)) \ | ||||
| 	$(AUDIOFILE_CFLAGS) $(LIBMIKMOD_CFLAGS) \ | ||||
| 	$(MODPLUG_CFLAGS) \ | ||||
| 	$(SIDPLAY_CFLAGS) \ | ||||
| 	$(ID3TAG_CFLAGS) \ | ||||
| 	$(MAD_CFLAGS) \ | ||||
| 	$(FFMPEG_CFLAGS) \ | ||||
| @@ -24,6 +25,7 @@ mpd_LDADD = $(MPD_LIBS) \ | ||||
| 	$(OGGVORBIS_LIBS) $(VORBISENC_LIBS) $(FLAC_LIBS) \ | ||||
| 	$(AUDIOFILE_LIBS) $(LIBMIKMOD_LIBS) \ | ||||
| 	$(MODPLUG_LIBS) \ | ||||
| 	$(SIDPLAY_LIBS) \ | ||||
| 	$(ID3TAG_LIBS) \ | ||||
| 	$(MAD_LIBS) \ | ||||
| 	$(MP4FF_LIBS) \ | ||||
| @@ -311,6 +313,10 @@ if HAVE_MODPLUG | ||||
| mpd_SOURCES += decoder/modplug_plugin.c | ||||
| endif | ||||
|  | ||||
| if ENABLE_SIDPLAY | ||||
| mpd_SOURCES += decoder/sidplay_plugin.cxx | ||||
| endif | ||||
|  | ||||
| if HAVE_FFMPEG | ||||
| mpd_SOURCES += decoder/ffmpeg_plugin.c | ||||
| 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 modplug_plugin; | ||||
| extern const struct decoder_plugin mikmod_decoder_plugin; | ||||
| extern const struct decoder_plugin sidplay_decoder_plugin; | ||||
| extern const struct decoder_plugin ffmpeg_plugin; | ||||
|  | ||||
| static const struct decoder_plugin *const decoder_plugins[] = { | ||||
| @@ -70,6 +71,9 @@ static const struct decoder_plugin *const decoder_plugins[] = { | ||||
| #ifdef HAVE_MIKMOD | ||||
| 	&mikmod_decoder_plugin, | ||||
| #endif | ||||
| #ifdef ENABLE_SIDPLAY | ||||
| 	&sidplay_decoder_plugin, | ||||
| #endif | ||||
| #ifdef HAVE_FFMPEG | ||||
| 	&ffmpeg_plugin, | ||||
| #endif | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann