changeset 213:ab8ce2fb05d0 trunk

[svn] Implement NSF playback.
author chainsaw
date Sun, 20 Nov 2005 10:57:10 -0800
parents 12b1fe51852e
children 03d9180e3c87
files Plugins/Input/console/Audacious_Driver.cpp
diffstat 1 files changed, 104 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/Plugins/Input/console/Audacious_Driver.cpp	Sun Nov 20 06:44:16 2005 -0800
+++ b/Plugins/Input/console/Audacious_Driver.cpp	Sun Nov 20 10:57:10 2005 -0800
@@ -25,6 +25,7 @@
 struct AudaciousConsoleConfig audcfg = { 180, FALSE, 32000 };
 
 #include <cstring>
+#include <stdio.h>
 
 #ifdef WORDS_BIGENDIAN
 # define MY_FMT FMT_S16_BE
@@ -33,9 +34,12 @@
 #endif
 
 static Spc_Emu *spc = NULL;
+static Nsf_Emu *nsf = NULL;
 static GThread *decode_thread;
+GStaticMutex playback_mutex = G_STATIC_MUTEX_INIT;
 
 static void *play_loop_spc(gpointer arg);
+static void *play_loop_nsf(gpointer arg);
 static void console_init(void);
 extern "C" void console_aboutbox(void);
 static void console_stop(void);
@@ -54,7 +58,9 @@
 	if (ext)
 	{
 		if (!strcasecmp(ext, ".spc"))
-			return 1;
+			return PLAY_TYPE_SPC;
+		if (!strcasecmp(ext, ".nsf"))
+			return PLAY_TYPE_NSF;
 	}
 
 	return 0;
@@ -88,21 +94,28 @@
 		g_free(tinput);
 	}
 	else
-		title = g_strdup(filename);
+		title = g_path_get_basename(filename);
+
+	return title;
+}
 
+static gchar *get_title_nsf(gchar *filename)
+{
+	gchar *title;
+	title = g_path_get_basename(filename);
 	return title;
 }
 
 static gchar *get_title(gchar *filename)
 {
-	gchar *ext;
-
-	ext = strrchr(filename, '.');
-
-	if (ext)
+	switch (is_our_file(filename))
 	{
-		if (!strcasecmp(ext, ".spc"))
+		case PLAY_TYPE_SPC:
 			return get_title_spc(filename);
+			break;
+		case PLAY_TYPE_NSF:
+			return get_title_nsf(filename);
+			break;
 	}
 
 	return NULL;
@@ -159,16 +172,57 @@
 	decode_thread = g_thread_create(play_loop_spc, spc, TRUE, NULL);
 }
 
+static void play_file_nsf(char *filename)
+{
+	gchar *name;
+	Emu_Std_Reader reader;
+	Nsf_Emu::header_t header;
+	gint samplerate;
+
+	if (audcfg.resample == TRUE)
+		samplerate = audcfg.resample_rate;
+	else
+		samplerate = 44100;
+
+	reader.open(filename);
+	reader.read(&header, sizeof(header));
+
+	nsf = new Nsf_Emu;
+	nsf->init(samplerate);
+	nsf->load(header, reader);
+	nsf->start_track(0);
+
+	console_ip_is_going = TRUE;
+
+	name = get_title(filename);
+
+	if (audcfg.loop_length)
+		console_ip.set_info(name, audcfg.loop_length * 1000, 
+			nsf->voice_count() * 1000, samplerate, 2);
+	else
+		console_ip.set_info(name, -1, nsf->voice_count() * 1000,
+			samplerate, 2);
+
+	g_free(name);
+
+        if (!console_ip.output->open_audio(MY_FMT, samplerate, 2))
+                 return;
+
+	playing_type = PLAY_TYPE_NSF;
+
+	decode_thread = g_thread_create(play_loop_nsf, nsf, TRUE, NULL);
+}
+
 static void play_file(char *filename)
 {
-	gchar *ext;
-
-	ext = strrchr(filename, '.');
-
-	if (ext)
+	switch (is_our_file(filename))
 	{
-		if (!strcasecmp(ext, ".spc"))
+		case PLAY_TYPE_SPC:
 			play_file_spc(filename);
+			break;
+		case PLAY_TYPE_NSF:
+			play_file_nsf(filename);
+			break;
 	}
 }
 
@@ -224,8 +278,9 @@
 
 static void *play_loop_spc(gpointer arg)
 {
+	g_static_mutex_lock(&playback_mutex);
 	Spc_Emu *my_spc = (Spc_Emu *) arg;
-        Music_Emu::sample_t buf[1024];
+	Music_Emu::sample_t buf[1024];
 
 	for (;;)
 	{
@@ -248,6 +303,40 @@
         console_ip.output->close_audio();
 	console_ip_is_going = FALSE;
 	playing_type = PLAY_TYPE_NONE;
+	g_static_mutex_unlock(&playback_mutex);
+        g_thread_exit(NULL);
+
+        return NULL;
+}
+
+static void *play_loop_nsf(gpointer arg)
+{
+	g_static_mutex_lock(&playback_mutex);
+	Nsf_Emu *my_nsf = (Nsf_Emu *) arg;
+        Music_Emu::sample_t buf[1024];
+
+	for (;;)
+	{
+		if (!console_ip_is_going)
+			break;
+
+		my_nsf->play(1024, buf);
+
+		if ((console_ip.output->output_time() / 1000) > 
+			audcfg.loop_length && audcfg.loop_length != 0)
+			break;
+		console_ip.add_vis_pcm(console_ip.output->written_time(),
+			MY_FMT, 1, 2048, buf);
+	        while(console_ip.output->buffer_free() < 2048)
+			xmms_usleep(10000);
+		console_ip.output->write_audio(buf, 2048);
+	}
+
+        delete nsf;
+        console_ip.output->close_audio();
+	console_ip_is_going = FALSE;
+	playing_type = PLAY_TYPE_NONE;
+	g_static_mutex_unlock(&playback_mutex);
         g_thread_exit(NULL);
 
         return NULL;