# HG changeset patch # User chainsaw # Date 1132513030 28800 # Node ID ab8ce2fb05d0613e50717054f2516f6f35e62ea8 # Parent 12b1fe51852e9e1bca36add2557a20ba932c03ba [svn] Implement NSF playback. diff -r 12b1fe51852e -r ab8ce2fb05d0 Plugins/Input/console/Audacious_Driver.cpp --- 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 +#include #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;