Mercurial > audlegacy
annotate Plugins/Input/console/Audacious_Driver.cpp @ 149:908ef215f340 trunk
[svn] basic resampling code.
author | nenolod |
---|---|
date | Thu, 10 Nov 2005 18:15:39 -0800 |
parents | fe9cb5132263 |
children | 1997ecd9dcb1 |
rev | line source |
---|---|
90
252843aac42f
[svn] Import the initial sources for console music support.
nenolod
parents:
diff
changeset
|
1 /* |
252843aac42f
[svn] Import the initial sources for console music support.
nenolod
parents:
diff
changeset
|
2 * Audacious: Cross platform multimedia player |
252843aac42f
[svn] Import the initial sources for console music support.
nenolod
parents:
diff
changeset
|
3 * Copyright (c) 2005 Audacious Team |
252843aac42f
[svn] Import the initial sources for console music support.
nenolod
parents:
diff
changeset
|
4 * |
252843aac42f
[svn] Import the initial sources for console music support.
nenolod
parents:
diff
changeset
|
5 * Driver for Game_Music_Emu library. See details at: |
252843aac42f
[svn] Import the initial sources for console music support.
nenolod
parents:
diff
changeset
|
6 * http://www.slack.net/~ant/libs/ |
252843aac42f
[svn] Import the initial sources for console music support.
nenolod
parents:
diff
changeset
|
7 */ |
252843aac42f
[svn] Import the initial sources for console music support.
nenolod
parents:
diff
changeset
|
8 |
94 | 9 #include "Audacious_Driver.h" |
90
252843aac42f
[svn] Import the initial sources for console music support.
nenolod
parents:
diff
changeset
|
10 |
98
e42694a28331
[svn] More progress -- now loads as an audacious module. :)
nenolod
parents:
96
diff
changeset
|
11 extern "C" { |
e42694a28331
[svn] More progress -- now loads as an audacious module. :)
nenolod
parents:
96
diff
changeset
|
12 |
109 | 13 #include <glib.h> |
96 | 14 #include <glib/gi18n.h> |
109 | 15 #include <gtk/gtk.h> |
94 | 16 #include "libaudacious/configfile.h" |
17 #include "libaudacious/util.h" | |
18 #include "libaudacious/titlestring.h" | |
145 | 19 #include "audacious/input.h" |
95 | 20 #include "audacious/output.h" |
145 | 21 #include "audacious/playback.h" |
94 | 22 |
98
e42694a28331
[svn] More progress -- now loads as an audacious module. :)
nenolod
parents:
96
diff
changeset
|
23 }; |
e42694a28331
[svn] More progress -- now loads as an audacious module. :)
nenolod
parents:
96
diff
changeset
|
24 |
145 | 25 struct AudaciousConsoleConfig audcfg = { 180, FALSE, 32000 }; |
26 | |
94 | 27 #include <cstring> |
28 | |
101
59ba6595fdf1
[svn] More accurate sound reproduction, but there is warbling. Still locks up player on completion.
nenolod
parents:
100
diff
changeset
|
29 #ifdef WORDS_BIGENDIAN |
59ba6595fdf1
[svn] More accurate sound reproduction, but there is warbling. Still locks up player on completion.
nenolod
parents:
100
diff
changeset
|
30 # define MY_FMT FMT_S16_BE |
59ba6595fdf1
[svn] More accurate sound reproduction, but there is warbling. Still locks up player on completion.
nenolod
parents:
100
diff
changeset
|
31 #else |
59ba6595fdf1
[svn] More accurate sound reproduction, but there is warbling. Still locks up player on completion.
nenolod
parents:
100
diff
changeset
|
32 # define MY_FMT FMT_S16_LE |
59ba6595fdf1
[svn] More accurate sound reproduction, but there is warbling. Still locks up player on completion.
nenolod
parents:
100
diff
changeset
|
33 #endif |
59ba6595fdf1
[svn] More accurate sound reproduction, but there is warbling. Still locks up player on completion.
nenolod
parents:
100
diff
changeset
|
34 |
94 | 35 static Spc_Emu *spc = NULL; |
95 | 36 static GThread *decode_thread; |
37 | |
147
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
38 static void *play_loop_spc(gpointer arg); |
100 | 39 static void console_init(void); |
109 | 40 extern "C" void console_aboutbox(void); |
96 | 41 static void console_stop(void); |
42 static void console_pause(gshort p); | |
43 static int get_time(void); | |
103 | 44 static gboolean console_ip_is_going; |
100 | 45 extern InputPlugin console_ip; |
147
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
46 static int playing_type; |
100 | 47 |
94 | 48 static int is_our_file(gchar *filename) |
49 { | |
50 gchar *ext; | |
51 | |
52 ext = strrchr(filename, '.'); | |
53 | |
54 if (ext) | |
55 { | |
56 if (!strcasecmp(ext, ".spc")) | |
57 return 1; | |
58 } | |
59 | |
60 return 0; | |
61 } | |
62 | |
148 | 63 static gchar *get_title_spc(gchar *filename) |
94 | 64 { |
65 gchar *title; | |
66 Emu_Std_Reader reader; | |
67 Spc_Emu::header_t header; | |
68 | |
69 reader.open(filename); | |
70 reader.read(&header, sizeof(header)); | |
71 | |
104 | 72 if (header.song) |
73 { | |
74 TitleInput *tinput; | |
75 | |
76 tinput = bmp_title_input_new(); | |
77 | |
105
18fe59468510
[svn] Use header.game, over header.author, as most SPC files do not contain the composer information.
nenolod
parents:
104
diff
changeset
|
78 tinput->performer = g_strdup(header.game); |
104 | 79 tinput->album_name = g_strdup(header.game); |
80 tinput->track_name = g_strdup(header.song); | |
94 | 81 |
104 | 82 tinput->file_name = g_path_get_basename(filename); |
83 tinput->file_path = g_path_get_dirname(filename); | |
84 | |
85 title = xmms_get_titlestring(xmms_get_gentitle_format(), | |
86 tinput); | |
87 | |
88 g_free(tinput); | |
89 } | |
90 else | |
91 title = g_strdup(filename); | |
99 | 92 |
94 | 93 return title; |
94 } | |
95 | 95 |
148 | 96 static gchar *get_title(gchar *filename) |
97 { | |
98 gchar *ext; | |
99 | |
100 ext = strrchr(filename, '.'); | |
101 | |
102 if (ext) | |
103 { | |
104 if (!strcasecmp(ext, ".spc")) | |
105 return get_title_spc(filename); | |
106 } | |
107 | |
108 return NULL; | |
109 } | |
110 | |
95 | 111 static void get_song_info(char *filename, char **title, int *length) |
112 { | |
113 (*title) = get_title(filename); | |
145 | 114 |
115 if (audcfg.loop_length) | |
116 (*length) = audcfg.loop_length; | |
117 else | |
118 (*length) = -1; | |
95 | 119 } |
120 | |
147
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
121 static void play_file_spc(char *filename) |
95 | 122 { |
106
d2b88d78ccd7
[svn] Tell the player that the decoder has fired up :)
nenolod
parents:
105
diff
changeset
|
123 gchar *name; |
95 | 124 Emu_Std_Reader reader; |
125 Spc_Emu::header_t header; | |
149 | 126 gint samplerate; |
127 | |
128 if (audcfg.resample == TRUE) | |
129 samplerate = audcfg.resample_rate; | |
130 else | |
131 samplerate = Spc_Emu::native_sample_rate; | |
95 | 132 |
133 reader.open(filename); | |
134 reader.read(&header, sizeof(header)); | |
135 | |
136 spc = new Spc_Emu; | |
149 | 137 spc->init(samplerate); |
95 | 138 spc->load(header, reader); |
139 spc->start_track(0); | |
140 | |
103 | 141 console_ip_is_going = TRUE; |
142 | |
106
d2b88d78ccd7
[svn] Tell the player that the decoder has fired up :)
nenolod
parents:
105
diff
changeset
|
143 name = get_title(filename); |
d2b88d78ccd7
[svn] Tell the player that the decoder has fired up :)
nenolod
parents:
105
diff
changeset
|
144 |
145 | 145 if (audcfg.loop_length) |
146 console_ip.set_info(name, audcfg.loop_length * 1000, | |
149 | 147 spc->voice_count() * 1000, samplerate, 2); |
145 | 148 else |
149 | 149 console_ip.set_info(name, -1, spc->voice_count() * 1000, |
150 samplerate, 2); | |
106
d2b88d78ccd7
[svn] Tell the player that the decoder has fired up :)
nenolod
parents:
105
diff
changeset
|
151 |
d2b88d78ccd7
[svn] Tell the player that the decoder has fired up :)
nenolod
parents:
105
diff
changeset
|
152 g_free(name); |
d2b88d78ccd7
[svn] Tell the player that the decoder has fired up :)
nenolod
parents:
105
diff
changeset
|
153 |
149 | 154 if (!console_ip.output->open_audio(MY_FMT, samplerate, 2)) |
100 | 155 return; |
133
3fb426494de8
[svn] Open the output channel before firing up the thread.
nenolod
parents:
109
diff
changeset
|
156 |
147
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
157 playing_type = PLAY_TYPE_SPC; |
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
158 |
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
159 decode_thread = g_thread_create(play_loop_spc, spc, TRUE, NULL); |
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
160 } |
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
161 |
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
162 static void play_file(char *filename) |
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
163 { |
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
164 gchar *ext; |
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
165 |
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
166 ext = strrchr(filename, '.'); |
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
167 |
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
168 if (ext) |
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
169 { |
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
170 if (!strcasecmp(ext, ".spc")) |
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
171 play_file_spc(filename); |
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
172 } |
95 | 173 } |
174 | |
96 | 175 static void seek(gint time) |
176 { | |
177 // XXX: Not yet implemented | |
178 } | |
179 | |
180 InputPlugin console_ip = { | |
181 NULL, | |
182 NULL, | |
183 NULL, | |
184 console_init, | |
109 | 185 console_aboutbox, |
96 | 186 NULL, |
187 is_our_file, | |
188 NULL, | |
189 play_file, | |
190 console_stop, | |
191 console_pause, | |
192 seek, | |
193 NULL, | |
194 get_time, | |
195 NULL, | |
196 NULL, | |
197 NULL, | |
198 NULL, | |
199 NULL, | |
200 NULL, | |
201 NULL, | |
104 | 202 get_song_info, |
96 | 203 NULL, |
204 NULL | |
205 }; | |
206 | |
207 static void console_stop(void) | |
208 { | |
103 | 209 console_ip_is_going = FALSE; |
96 | 210 g_thread_join(decode_thread); |
211 console_ip.output->close_audio(); | |
212 } | |
213 | |
98
e42694a28331
[svn] More progress -- now loads as an audacious module. :)
nenolod
parents:
96
diff
changeset
|
214 extern "C" InputPlugin *get_iplugin_info(void) |
96 | 215 { |
109 | 216 console_ip.description = g_strdup_printf(_("SPC, GYM, NSF, VGM and GBS module decoder")); |
96 | 217 return &console_ip; |
218 } | |
219 | |
220 static void console_pause(gshort p) | |
221 { | |
222 console_ip.output->pause(p); | |
223 } | |
224 | |
147
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
225 static void *play_loop_spc(gpointer arg) |
95 | 226 { |
99 | 227 Spc_Emu *my_spc = (Spc_Emu *) arg; |
108 | 228 Music_Emu::sample_t buf[1024]; |
95 | 229 |
145 | 230 for (;;) |
231 { | |
232 if (!console_ip_is_going) | |
233 break; | |
234 | |
235 my_spc->play(1024, buf); | |
236 | |
237 if ((console_ip.output->output_time() / 1000) > | |
238 audcfg.loop_length && audcfg.loop_length != 0) | |
239 break; | |
100 | 240 console_ip.add_vis_pcm(console_ip.output->written_time(), |
108 | 241 MY_FMT, 1, 2048, buf); |
242 while(console_ip.output->buffer_free() < 2048) | |
101
59ba6595fdf1
[svn] More accurate sound reproduction, but there is warbling. Still locks up player on completion.
nenolod
parents:
100
diff
changeset
|
243 xmms_usleep(10000); |
108 | 244 console_ip.output->write_audio(buf, 2048); |
100 | 245 } |
95 | 246 |
96 | 247 delete spc; |
145 | 248 console_ip.output->close_audio(); |
249 console_ip_is_going = FALSE; | |
147
6fe2bfbe6fc2
[svn] Move SPC-specific code into SPC-specific routines.
nenolod
parents:
146
diff
changeset
|
250 playing_type = PLAY_TYPE_NONE; |
96 | 251 g_thread_exit(NULL); |
95 | 252 |
96 | 253 return NULL; |
95 | 254 } |
255 | |
96 | 256 static int get_time(void) |
257 { | |
145 | 258 if (console_ip_is_going == TRUE) |
259 return console_ip.output->output_time(); | |
260 else | |
261 return -1; | |
96 | 262 } |
95 | 263 |
100 | 264 static void console_init(void) |
265 { | |
266 | |
267 } | |
268 | |
109 | 269 extern "C" void console_aboutbox(void) |
270 { | |
271 xmms_show_message(_("About the Console Music Decoder"), | |
272 _("Console music decoder engine based on Game_Music_Emu 0.2.4.\n" | |
273 "Audacious implementation by: William Pitcock <nenolod@nenolod.net>"), | |
274 _("Ok"), | |
275 FALSE, NULL, NULL); | |
276 } |