Mercurial > hg > xmms-sid
comparison src/xmms-sid.cc @ 65:bf7b647b3239
The fabled 0.8-rewrite now works to some extent
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 29 Jun 2003 22:16:04 +0000 |
parents | d3bb914e3af3 |
children | bf6a524cf7ca |
comparison
equal
deleted
inserted
replaced
64:d3bb914e3af3 | 65:bf7b647b3239 |
---|---|
17 | 17 |
18 You should have received a copy of the GNU General Public License | 18 You should have received a copy of the GNU General Public License |
19 along with this program; if not, write to the Free Software | 19 along with this program; if not, write to the Free Software |
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21 */ | 21 */ |
22 extern "C" { | |
23 #include <pthread.h> | 22 #include <pthread.h> |
24 #include <stdlib.h> | 23 #include <stdlib.h> |
25 #include <string.h> | 24 #include <string.h> |
26 #include <stdio.h> | 25 #include <stdio.h> |
27 #include <errno.h> | 26 #include <errno.h> |
27 | |
28 extern "C" { | |
28 #include <xmms/plugin.h> | 29 #include <xmms/plugin.h> |
29 #include <xmms/util.h> | 30 #include <xmms/util.h> |
30 #include <xmms/titlestring.h> | 31 #include <xmms/titlestring.h> |
31 #include "xmms-sid.h" | |
32 #include "xs_interface.h" | 32 #include "xs_interface.h" |
33 #include "xs_glade.h" | 33 #include "xs_glade.h" |
34 } | |
35 | |
36 #include "xmms-sid.h" | |
34 #include "xs_support.h" | 37 #include "xs_support.h" |
35 #include "xs_config.h" | 38 #include "xs_config.h" |
36 #include "xs_length.h" | 39 #include "xs_length.h" |
37 } | 40 |
38 | 41 |
39 #ifdef HAVE_SIDPLAY1 | 42 #ifdef HAVE_SIDPLAY1 |
40 #include <sidplay/player.h> | 43 #include <sidplay/player.h> |
41 #include <sidplay/myendian.h> | 44 #include <sidplay/myendian.h> |
42 #include <sidplay/fformat.h> | 45 #include <sidplay/fformat.h> |
49 | 52 |
50 /* | 53 /* |
51 * Global variables | 54 * Global variables |
52 */ | 55 */ |
53 #ifdef HAVE_SIDPLAY1 | 56 #ifdef HAVE_SIDPLAY1 |
54 static struct emuConfig xs_emuConf; | |
55 static emuEngine xs_emuEngine; | |
56 typedef sidTune t_xs_tune; | 57 typedef sidTune t_xs_tune; |
57 typedef struct sidTuneInfo t_xs_tuneinfo; | 58 typedef struct sidTuneInfo t_xs_tuneinfo; |
58 #endif | 59 #endif |
59 | 60 |
60 #ifdef HAVE_SIDPLAY2 | 61 #ifdef HAVE_SIDPLAY2 |
61 static struct sid2_config_t xs_emuConf; | |
62 static sidplay2 xs_emuEngine; | |
63 typedef SidTune t_xs_tune; | 62 typedef SidTune t_xs_tune; |
64 typedef struct SidTuneInfo t_xs_tuneinfo; | 63 typedef struct SidTuneInfo t_xs_tuneinfo; |
65 #endif | 64 #endif |
66 | 65 |
67 static GtkWidget *xs_ctrlwin = NULL; | 66 #ifdef HAVE_SIDPLAY1 |
68 static pthread_t xs_decode_thread; | 67 struct emuConfig xs_emuConf; |
69 struct t_xs_cfg xs_cfg; | 68 emuEngine xs_emuEngine; |
70 | 69 #endif |
71 struct { | 70 #ifdef HAVE_SIDPLAY2 |
71 struct sid2_config_t xs_emuConf; | |
72 sidplay2 xs_emuEngine; | |
73 #endif | |
74 | |
75 typedef struct { | |
72 gboolean isError, isPlaying, allowNext; | 76 gboolean isError, isPlaying, allowNext; |
73 gint currSong, nSongs; | 77 gint currSong, nSongs; |
74 t_xs_tune *currTune; | 78 t_xs_tune *currTune; |
75 gchar *currFilename; | 79 gchar *currFileName; |
76 } xs_status; | 80 } t_xs_status; |
77 | 81 |
78 pthread_mutex_t xs_mutex = PTHREAD_MUTEX_INITIALIZER; | 82 static GtkWidget *xs_ctrlwin = NULL; |
83 static pthread_t xs_decode_thread; | |
84 static pthread_mutex_t xs_mutex = PTHREAD_MUTEX_INITIALIZER; | |
85 struct t_xs_cfg xs_cfg; | |
86 t_xs_status xs_status; | |
87 | |
79 | 88 |
80 gchar *xs_filetitle_get(gchar *, t_xs_tuneinfo *, gint); | 89 gchar *xs_filetitle_get(gchar *, t_xs_tuneinfo *, gint); |
90 | |
81 | 91 |
82 /* | 92 /* |
83 * Create sub-song control window | 93 * Create sub-song control window |
84 */ | 94 */ |
85 void xs_ctrlwin_open(void) | 95 void xs_ctrlwin_open(void) |
108 memset(&xs_cfg, 0, sizeof(xs_cfg)); | 118 memset(&xs_cfg, 0, sizeof(xs_cfg)); |
109 | 119 |
110 xs_read_configuration(); | 120 xs_read_configuration(); |
111 | 121 |
112 /* Initialize status */ | 122 /* Initialize status */ |
113 xs_status.isError = FALSE; | 123 memset(&xs_status, 0, sizeof(xs_status)); |
114 xs_status.isPlaying = FALSE; | 124 xs_status.allowNext = TRUE; // Initialize to TRUE to allow first song |
115 xs_status.nSongs = 0; | 125 |
116 xs_status.currSong = 0; | 126 /* Try to initialize emulator engine(s) */ |
117 xs_status.allowNext = TRUE; // Initialize to TRUE to allow first song | 127 XSDEBUG("initializing emulator engine(s)...\n"); |
118 xs_status.currTune = NULL; | 128 |
119 xs_status.currFilename = NULL; | |
120 | |
121 | |
122 /* Try to initialize libSIDPlay(s) */ | |
123 #ifdef HAVE_SIDPLAY1 | 129 #ifdef HAVE_SIDPLAY1 |
124 if (!xs_emuEngine || !xs_emuEngine.verifyEndianess()) | 130 if (!xs_emuEngine || !xs_emuEngine.verifyEndianess()) |
125 { | 131 { |
126 XSERR("Couldn't start SIDPlay1 emulator engine!\n"); | 132 XSERR("Couldn't initialize SIDPlay1 emulator engine!\n"); |
127 return; | 133 return; |
128 } | 134 } |
129 #endif | |
130 | |
131 #ifdef HAVE_SIDPLAY2 | |
132 #endif | 135 #endif |
133 | 136 |
134 /* Read song-length database */ | 137 /* Read song-length database */ |
135 if (xs_cfg.songlenDBEnable) | 138 if (xs_cfg.songlenDBEnable) |
136 if (xs_songlen_init() < 0) | 139 if (xs_songlen_init() < 0) |
142 | 145 |
143 // xs_ctrlwin_open(); | 146 // xs_ctrlwin_open(); |
144 | 147 |
145 // FIXME FIXME FIx ME | 148 // FIXME FIXME FIx ME |
146 | 149 |
150 XSDEBUG("xs_init() done\n"); | |
147 } | 151 } |
148 | 152 |
149 | 153 |
150 /* | 154 /* |
151 * Shut down XMMS-SID | 155 * Shut down XMMS-SID |
152 */ | 156 */ |
153 void xs_close(void) | 157 void xs_close(void) |
154 { | 158 { |
155 XSDEBUG("shutting down...\n"); | 159 XSDEBUG("xs_close(): shutting down...\n"); |
156 | 160 |
157 /* Stop playing */ | 161 /* Stop playing */ |
158 xs_plugin_ip.stop(); | 162 xs_stop(); |
159 | 163 |
160 /* Shutdown libSIDPlay(s) */ | 164 /* Shutdown libSIDPlay(s) */ |
161 #ifdef HAVE_SIDPLAY1 | 165 #ifdef HAVE_SIDPLAY1 |
162 #endif | 166 #endif |
163 | 167 |
168 | 172 |
169 /* Free allocated memory */ | 173 /* Free allocated memory */ |
170 xs_songlen_close(); | 174 xs_songlen_close(); |
171 | 175 |
172 // FIXME FIXME: STIL-entries | 176 // FIXME FIXME: STIL-entries |
177 XSDEBUG("shutdown finished.\n"); | |
173 } | 178 } |
174 | 179 |
175 | 180 |
176 /* | 181 /* |
177 * Check whether the given file is handled by this plugin | 182 * Check whether the given file is handled by this plugin |
178 */ | 183 */ |
179 gint xs_is_our_file(char *fileName) | 184 gint xs_is_our_file(gchar *pcFileName) |
180 { | 185 { |
181 char *pcExt; | 186 char *pcExt; |
187 t_xs_tune *testTune; | |
182 | 188 |
183 /* Check the filename */ | 189 /* Check the filename */ |
184 if (fileName == NULL) | 190 if (pcFileName == NULL) |
185 return FALSE; | 191 return FALSE; |
192 | |
193 XSDEBUG("testFile('%s')\n", pcFileName); | |
186 | 194 |
187 /* Try to detect via libSIDPlay's detection routine, if required */ | 195 /* Try to detect via libSIDPlay's detection routine, if required */ |
188 if (xs_cfg.detectMagic) | 196 if (xs_cfg.detectMagic) |
189 { | 197 { |
190 #ifdef HAVE_SIDPLAY1 | 198 testTune = new t_xs_tune(pcFileName); |
191 t_xs_tune *testTune = new sidTune(fileName); | 199 if (testTune == NULL) return FALSE; |
192 if (!testTune) return FALSE; | 200 if (testTune->getStatus()) |
193 if (!testTune->getStatus()) | |
194 { | 201 { |
195 delete testTune; | 202 delete testTune; |
196 return FALSE; | 203 XSDEBUG("file = OK\n"); |
204 return TRUE; | |
197 } | 205 } |
198 | 206 |
207 /* We DON'T fall back to filename extension checking ... */ | |
199 delete testTune; | 208 delete testTune; |
200 return TRUE; | 209 XSDEBUG("file = kyrpe\n"); |
201 #endif | 210 return FALSE; |
202 | |
203 #ifdef HAVE_SIDPLAY2 | |
204 #endif | |
205 } | 211 } |
206 | 212 |
207 /* Detect just by checking filename extension */ | 213 /* Detect just by checking filename extension */ |
208 pcExt = xs_strrchr(fileName, '.'); | 214 pcExt = xs_strrchr(pcFileName, '.'); |
209 if (pcExt) | 215 if (pcExt) |
210 { | 216 { |
211 pcExt++; | 217 pcExt++; |
212 if (!g_strcasecmp(pcExt, "psid")) return TRUE; | 218 if (!g_strcasecmp(pcExt, "psid")) return TRUE; |
213 if (!g_strcasecmp(pcExt, "sid")) return TRUE; | 219 if (!g_strcasecmp(pcExt, "sid")) return TRUE; |
214 if (!g_strcasecmp(pcExt, "dat")) return TRUE; | 220 if (!g_strcasecmp(pcExt, "dat")) return TRUE; |
215 if (!g_strcasecmp(pcExt, "inf")) return TRUE; | 221 if (!g_strcasecmp(pcExt, "inf")) return TRUE; |
216 if (!g_strcasecmp(pcExt, "info")) return TRUE; | 222 if (!g_strcasecmp(pcExt, "info")) return TRUE; |
217 } | 223 } |
218 | 224 |
225 XSDEBUG("file was KYRPE\n"); | |
219 return FALSE; | 226 return FALSE; |
220 } | 227 } |
221 | 228 |
222 | 229 |
223 /* | 230 /* |
224 * Main playing thread loop | 231 * Main playing thread loop |
225 */ | 232 */ |
226 static void *xs_play_loop(void *argPointer) | 233 void *xs_play_loop(void *argPointer) |
227 { | 234 { |
235 t_xs_status myStatus; | |
236 t_xs_tuneinfo tuneInfo; | |
237 gboolean audioOpen; | |
238 gint audioFreq, audioChannels, songLength; | |
239 enum AFormat audioFmt; | |
240 gchar audioBuffer[XS_BUFSIZE]; | |
241 | |
242 /* Check status */ | |
243 XSDEBUG("entering play thread\n"); | |
244 pthread_mutex_lock(&xs_mutex); | |
245 if (!xs_status.allowNext) | |
246 { | |
247 pthread_mutex_unlock(&xs_mutex); | |
248 pthread_exit(NULL); | |
249 } | |
250 | |
228 /* Don't allow next song to be set yet */ | 251 /* Don't allow next song to be set yet */ |
252 xs_status.allowNext = FALSE; | |
253 xs_status.isPlaying = TRUE; | |
254 memcpy(&myStatus, &xs_status, sizeof(t_xs_status)); | |
255 pthread_mutex_unlock(&xs_mutex); | |
256 | |
257 /* Copy and check audio options here (they might change in config while running) */ | |
258 #ifdef HAVE_UNSIGNEDPCM | |
259 audioFmt = (xs_cfg.fmtBitsPerSample == XS_RES_16BIT) ? FMT_U16_NE : FMT_U8; | |
260 #else | |
261 audioFmt = (xs_cfg.fmtBitsPerSample == XS_RES_16BIT) ? FMT_S16_NE : FMT_S8; | |
262 #endif | |
263 audioFreq = xs_cfg.fmtFrequency; | |
264 audioChannels = (xs_cfg.fmtChannels == XS_CHN_MONO) ? 1 : 2; | |
265 audioOpen = FALSE; | |
266 | |
267 /* | |
268 * Main player loop: while not stopped, loop here - play subtunes | |
269 */ | |
270 while (xs_status.isPlaying) | |
271 { | |
229 pthread_mutex_lock(&xs_mutex); | 272 pthread_mutex_lock(&xs_mutex); |
230 xs_status.allowNext = FALSE; | 273 myStatus.currSong = xs_status.currSong; |
231 pthread_mutex_unlock(&xs_mutex); | 274 pthread_mutex_unlock(&xs_mutex); |
232 | 275 |
276 XSDEBUG("sub-song %i selected, initializing...\n", myStatus.currSong); | |
277 | |
278 /* Get song length for current subtune */ | |
279 songLength = xs_songlen_get(myStatus.currFileName, myStatus.currSong); | |
280 | |
281 /* Initialize song */ | |
282 #ifdef HAVE_SIDPLAY1 | |
283 if ((myStatus.currTune == NULL) || !myStatus.currTune->getStatus() || | |
284 !sidEmuInitializeSong(xs_emuEngine, *myStatus.currTune, myStatus.currSong)) | |
285 #endif | |
286 #ifdef HAVE_SIDPLAY2 | |
287 if () | |
288 #endif | |
289 { | |
290 XSERR("Couldn't initialize SID-tune!\n"); | |
291 pthread_mutex_lock(&xs_mutex); | |
292 xs_status.isError = TRUE; | |
293 pthread_mutex_unlock(&xs_mutex); | |
294 goto err_exit; | |
295 } | |
296 | |
297 myStatus.currTune->getInfo(tuneInfo); | |
298 | |
299 /* Open the audio output */ | |
300 if (!xs_plugin_ip.output->open_audio(audioFmt, audioFreq, audioChannels)) | |
301 { | |
302 XSERR("Couldn't open XMMS audio output!\n"); | |
303 pthread_mutex_lock(&xs_mutex); | |
304 xs_status.isError = TRUE; | |
305 pthread_mutex_unlock(&xs_mutex); | |
306 goto err_exit; | |
307 } | |
308 | |
309 audioOpen = TRUE; | |
310 | |
311 /* Set some infoz */ | |
312 xs_plugin_ip.set_info(tuneInfo.infoString[0], (songLength > 0) ? songLength * 1000 : -1, | |
313 1000 * (tuneInfo.songSpeed ? tuneInfo.songSpeed : (tuneInfo.clockSpeed == SIDTUNE_CLOCK_NTSC) ? 60 : 50), | |
314 audioFreq, audioChannels); | |
315 | |
316 XSDEBUG("rendering audio...\n"); | |
317 | |
318 /* Play the tune */ | |
319 while (xs_status.isPlaying && (xs_status.currSong == myStatus.currSong)) | |
320 { | |
321 #ifdef HAVE_SIDPLAY1 | |
322 sidEmuFillBuffer(xs_emuEngine, *myStatus.currTune, audioBuffer, XS_BUFSIZE); | |
323 #endif | |
324 | |
325 #ifdef HAVE_SIDPLAY2 | |
326 #endif | |
327 | |
328 /* Visualice/haujobb */ | |
329 xs_plugin_ip.add_vis_pcm( | |
330 xs_plugin_ip.output->written_time(), | |
331 audioFmt, audioChannels, XS_BUFSIZE, audioBuffer); | |
332 | |
333 /* Wait a little */ | |
334 while (xs_status.isPlaying && | |
335 (xs_status.currSong == myStatus.currSong) && | |
336 (xs_plugin_ip.output->buffer_free() < XS_BUFSIZE)) | |
337 xmms_usleep(10000); | |
338 | |
339 /* Output audio */ | |
340 if (xs_status.isPlaying && (xs_status.currSong == myStatus.currSong)) | |
341 xs_plugin_ip.output->write_audio(audioBuffer, XS_BUFSIZE); | |
342 | |
343 /* Check if we have played enough */ | |
344 if (xs_cfg.playMaxTimeEnable) | |
345 { | |
346 if (xs_cfg.playMaxTimeUnknown) | |
347 { | |
348 if ((songLength == -1) && | |
349 (xs_plugin_ip.output->output_time() >= (xs_cfg.playMaxTime * 1000))) | |
350 xs_status.isPlaying = FALSE; | |
351 } else { | |
352 if (xs_plugin_ip.output->output_time() >= (xs_cfg.playMaxTime * 1000)) | |
353 xs_status.isPlaying = FALSE; | |
354 } | |
355 } | |
356 | |
357 if (songLength > 0) | |
358 { | |
359 if (xs_plugin_ip.output->output_time() >= (songLength * 1000)) | |
360 xs_status.isPlaying = FALSE; | |
361 } | |
362 } | |
363 | |
364 XSDEBUG("tune ended/stopped\n"); | |
365 | |
366 /* Close audio */ | |
367 if (audioOpen) | |
368 { | |
369 XSDEBUG("close audio #1\n"); | |
370 xs_plugin_ip.output->close_audio(); | |
371 audioOpen = FALSE; | |
372 } | |
373 } | |
374 | |
375 /* When exiting, delete data */ | |
376 err_exit: | |
377 pthread_mutex_lock(&xs_mutex); | |
378 xs_status.isPlaying = FALSE; | |
379 pthread_mutex_unlock(&xs_mutex); | |
380 | |
381 if (audioOpen) | |
382 { | |
383 XSDEBUG("close audio #2\n"); | |
384 xs_plugin_ip.output->close_audio(); | |
385 } | |
386 | |
387 if (myStatus.currTune != NULL) | |
388 { | |
389 delete myStatus.currTune; | |
390 myStatus.currTune = NULL; | |
391 } | |
392 | |
393 g_free(myStatus.currFileName); | |
233 | 394 |
234 /* Exit the playing thread */ | 395 /* Exit the playing thread */ |
235 XSDEBUG("exiting thread, bye.\n"); | 396 XSDEBUG("exiting thread, bye.\n"); |
236 return NULL; | 397 pthread_mutex_lock(&xs_mutex); |
398 xs_status.allowNext = TRUE; | |
399 pthread_mutex_unlock(&xs_mutex); | |
400 | |
401 pthread_exit(NULL); | |
237 } | 402 } |
238 | 403 |
239 | 404 |
240 /* | 405 /* |
241 * Start playing the given file | 406 * Start playing the given file |
242 */ | 407 */ |
243 void xs_play_file(char *fileName) | 408 void xs_play_file(char *pcFileName) |
244 { | 409 { |
245 t_xs_tune *newTune; | 410 t_xs_tune *newTune; |
246 t_xs_tuneinfo sidInf; | 411 t_xs_tuneinfo tuneInfo; |
247 | 412 |
248 XSDEBUG("request to load '%s'\n", fileName); | 413 /* Can we set the next tune? */ |
249 | 414 XSDEBUG("request to play '%s'\n", pcFileName); |
250 | |
251 /* Initialize audio output */ | |
252 XSDEBUG("opening audio output plugin...\n"); | |
253 if (!xs_plugin_ip.output->open_audio( | |
254 ((xs_cfg.fmtBitsPerSample == 16) ? FMT_S16_NE : FMT_U8), xs_cfg.fmtFrequency, | |
255 ((xs_cfg.fmtChannels == XS_CHN_MONO) ? 1 : 2))) | |
256 { | |
257 XSERR("Couldn't open audio output plugin!\n"); | |
258 delete newTune; | |
259 return; | |
260 } | |
261 | |
262 | 415 |
263 /* Try to get the tune */ | 416 /* Try to get the tune */ |
264 newTune = new t_xs_tune(fileName); | 417 XSDEBUG("initializing tune from file\n"); |
418 newTune = new t_xs_tune(pcFileName); | |
265 if (newTune == NULL) return; | 419 if (newTune == NULL) return; |
266 | 420 |
267 XSDEBUG("tune ok, configuring SIDPlay engine\n"); | 421 XSDEBUG("status: allowNext=%i, isPlaying=%i\n", xs_status.allowNext, xs_status.isPlaying); |
268 | |
269 | 422 |
270 #ifdef HAVE_SIDPLAY1 | 423 #ifdef HAVE_SIDPLAY1 |
271 /* Get current configuration */ | 424 /* Get current configuration */ |
272 xs_emuEngine.getConfig(xs_emuConf); | 425 xs_emuEngine.getConfig(xs_emuConf); |
273 | 426 |
285 xs_emuConf.autoPanning = SIDEMU_NONE; | 438 xs_emuConf.autoPanning = SIDEMU_NONE; |
286 xs_emuConf.volumeControl = SIDEMU_NONE; | 439 xs_emuConf.volumeControl = SIDEMU_NONE; |
287 break; | 440 break; |
288 | 441 |
289 case XS_CHN_MONO: | 442 case XS_CHN_MONO: |
443 default: | |
290 xs_emuConf.channels = SIDEMU_MONO; | 444 xs_emuConf.channels = SIDEMU_MONO; |
291 xs_emuConf.autoPanning = SIDEMU_NONE; | 445 xs_emuConf.autoPanning = SIDEMU_NONE; |
292 xs_emuConf.volumeControl = SIDEMU_NONE; | 446 xs_emuConf.volumeControl = SIDEMU_NONE; |
293 break; | 447 break; |
294 | |
295 default: | |
296 XSERR("Internal: Invalid channels setting. Possibly corrupted configuration file.\n"); | |
297 delete newTune; | |
298 return; | |
299 } | 448 } |
300 | 449 |
301 | 450 |
302 /* Memory mode settings */ | 451 /* Memory mode settings */ |
303 switch (xs_cfg.memoryMode) { | 452 switch (xs_cfg.memoryMode) { |
312 case XS_MPU_PLAYSID_ENVIRONMENT: | 461 case XS_MPU_PLAYSID_ENVIRONMENT: |
313 xs_emuConf.memoryMode = MPU_PLAYSID_ENVIRONMENT; | 462 xs_emuConf.memoryMode = MPU_PLAYSID_ENVIRONMENT; |
314 break; | 463 break; |
315 | 464 |
316 default: | 465 default: |
317 XSERR("Internal: Invalid memoryMode setting. Possibly corrupted configuration file.\n"); | 466 xs_emuConf.memoryMode = MPU_BANK_SWITCHING; |
318 delete newTune; | 467 break; |
319 return; | |
320 } | 468 } |
321 | 469 |
322 | 470 |
323 /* Clockspeed settings */ | 471 /* Clockspeed settings */ |
324 switch (xs_cfg.clockSpeed) { | 472 switch (xs_cfg.clockSpeed) { |
325 case XS_CLOCK_PAL: | |
326 xs_emuConf.clockSpeed = SIDTUNE_CLOCK_PAL; | |
327 break; | |
328 | |
329 case XS_CLOCK_NTSC: | 473 case XS_CLOCK_NTSC: |
330 xs_emuConf.clockSpeed = SIDTUNE_CLOCK_NTSC; | 474 xs_emuConf.clockSpeed = SIDTUNE_CLOCK_NTSC; |
331 break; | 475 break; |
332 | 476 |
477 case XS_CLOCK_PAL: | |
333 default: | 478 default: |
334 XSERR("Internal: Invalid clockSpeed setting. Possibly corrupted configuration file.\n"); | 479 xs_emuConf.clockSpeed = SIDTUNE_CLOCK_PAL; |
335 delete newTune; | 480 break; |
336 return; | |
337 } | 481 } |
338 | 482 |
339 | 483 |
340 /* Configure rest of the emulation */ | 484 /* Configure rest of the emulation */ |
341 xs_emuConf.bitsPerSample = xs_cfg.fmtBitsPerSample; | 485 xs_emuConf.bitsPerSample = xs_cfg.fmtBitsPerSample; |
354 /* Now set the emulator configuration */ | 498 /* Now set the emulator configuration */ |
355 xs_emuEngine.setConfig(xs_emuConf); | 499 xs_emuEngine.setConfig(xs_emuConf); |
356 #endif | 500 #endif |
357 | 501 |
358 | 502 |
359 | |
360 #ifdef HAVE_SIDPLAY2 | 503 #ifdef HAVE_SIDPLAY2 |
361 /* Get current configuration */ | 504 /* Get current configuration */ |
362 xs_emuConf = xs_emuEngine.config(); | 505 xs_emuConf = xs_emuEngine.config(); |
363 | 506 |
364 /* Configure channels and stuff */ | 507 /* Configure channels and stuff */ |
371 case XS_CHN_STEREO: | 514 case XS_CHN_STEREO: |
372 xs_emuConf.playback = sid2_stereo; | 515 xs_emuConf.playback = sid2_stereo; |
373 break; | 516 break; |
374 | 517 |
375 case XS_CHN_MONO: | 518 case XS_CHN_MONO: |
519 default: | |
376 xs_emuConf.playback = sid2_mono; | 520 xs_emuConf.playback = sid2_mono; |
377 break; | 521 break; |
378 | |
379 default: | |
380 XSERR("Internal: Invalid channels setting. Possibly corrupted configuration file.\n"); | |
381 delete newTune; | |
382 return; | |
383 } | 522 } |
384 | 523 |
385 | 524 |
386 /* Memory mode settings */ | 525 /* Memory mode settings */ |
387 switch (xs_cfg.memoryMode) { | 526 switch (xs_cfg.memoryMode) { |
396 case XS_MPU_PLAYSID_ENVIRONMENT: | 535 case XS_MPU_PLAYSID_ENVIRONMENT: |
397 xs_emuConf.environment = sid2_envPS; | 536 xs_emuConf.environment = sid2_envPS; |
398 break; | 537 break; |
399 | 538 |
400 case XS_MPU_REAL: | 539 case XS_MPU_REAL: |
540 default: | |
401 xs_emuConf.environment = sid2_envR; | 541 xs_emuConf.environment = sid2_envR; |
402 break; | 542 break; |
403 | |
404 default: | |
405 XSERR("Internal: Invalid memoryMode setting. Possibly corrupted configuration file.\n"); | |
406 delete newTune; | |
407 return; | |
408 } | 543 } |
409 | 544 |
410 | 545 |
411 /* Clockspeed settings */ | 546 /* Clockspeed settings */ |
412 switch (xs_cfg.clockSpeed) { | 547 switch (xs_cfg.clockSpeed) { |
413 case XS_CLOCK_PAL: | |
414 xs_emuConf.clockSpeed = xs_emuConf.clockDefault = SID2_CLOCK_PAL; | |
415 break; | |
416 | |
417 case XS_CLOCK_NTSC: | 548 case XS_CLOCK_NTSC: |
418 xs_emuConf.clockSpeed = xs_emuConf.clockDefault = SID2_CLOCK_NTSC; | 549 xs_emuConf.clockSpeed = xs_emuConf.clockDefault = SID2_CLOCK_NTSC; |
419 break; | 550 break; |
420 | 551 |
552 case XS_CLOCK_PAL: | |
421 default: | 553 default: |
422 XSERR("Internal: Invalid clockSpeed setting. Possibly corrupted configuration file.\n"); | 554 xs_emuConf.clockSpeed = xs_emuConf.clockDefault = SID2_CLOCK_PAL; |
423 delete newTune; | 555 break; |
424 return; | |
425 } | 556 } |
426 | 557 |
427 | 558 |
428 /* Configure rest of the emulation */ | 559 /* Configure rest of the emulation */ |
429 xs_emuConf.precision = xs_cfg.fmtBitsPerSample; | 560 xs_emuConf.precision = xs_cfg.fmtBitsPerSample; |
451 xs_emuEngine.config(xs_emuConf); | 582 xs_emuEngine.config(xs_emuConf); |
452 #endif | 583 #endif |
453 | 584 |
454 | 585 |
455 /* Initialize status information */ | 586 /* Initialize status information */ |
456 XSDEBUG("initializing and starting playing thread!\n"); | 587 XSDEBUG("starting playing thread!\n"); |
457 | 588 |
458 newTune->getInfo(sidInf); | 589 newTune->getInfo(tuneInfo); |
459 | 590 |
591 xs_status.isPlaying = TRUE; | |
460 xs_status.isError = FALSE; | 592 xs_status.isError = FALSE; |
461 xs_status.isPlaying = TRUE; | 593 xs_status.currSong = tuneInfo.startSong; |
462 xs_status.allowNext = TRUE; | 594 xs_status.nSongs = tuneInfo.songs; |
463 xs_status.currSong = sidInf.startSong; | |
464 xs_status.nSongs = sidInf.songs; | |
465 xs_status.currTune = newTune; | 595 xs_status.currTune = newTune; |
466 | 596 xs_status.currFileName = g_strdup(pcFileName); |
467 | 597 |
468 /* Start the playing thread! */ | 598 /* Start the playing thread! */ |
469 if (pthread_create(&xs_decode_thread, NULL, xs_play_loop, NULL) < 0) | 599 if (pthread_create(&xs_decode_thread, NULL, xs_play_loop, NULL) < 0) |
470 { | 600 { |
471 XSERR("Couldn't start playing thread! Possible reason reported by system: %s\n", strerror(errno)); | 601 XSERR("Couldn't start playing thread! Possible reason reported by system: %s\n", strerror(errno)); |
472 delete newTune; | 602 delete newTune; |
473 } | 603 } |
474 | 604 |
605 XSDEBUG("systems should be up?\n"); | |
606 | |
475 /* Exit */ | 607 /* Exit */ |
476 } | 608 } |
477 | 609 |
478 | 610 |
479 /* | 611 /* |
480 * Stop playing | 612 * Stop playing |
481 */ | 613 */ |
482 void xs_stop(void) | 614 void xs_stop(void) |
483 { | 615 { |
484 /* If playing, stop. */ | 616 /* If playing, stop. */ |
485 XSDEBUG("request to stop.\n"); | 617 XSDEBUG("STOP_REQ\n"); |
486 | 618 if (xs_status.isPlaying || !xs_status.allowNext) |
487 if (xs_status.isPlaying) | |
488 { | 619 { |
489 XSDEBUG("stopping...\n"); | 620 XSDEBUG("stopping...\n"); |
490 pthread_mutex_lock(&xs_mutex); | 621 pthread_mutex_lock(&xs_mutex); |
491 xs_status.isPlaying = 0; | 622 xs_status.isPlaying = FALSE; |
492 pthread_mutex_unlock(&xs_mutex); | 623 pthread_mutex_unlock(&xs_mutex); |
493 | |
494 pthread_join(xs_decode_thread, NULL); | 624 pthread_join(xs_decode_thread, NULL); |
495 | |
496 xs_plugin_ip.output->close_audio(); | |
497 } | 625 } |
498 } | 626 } |
499 | 627 |
500 | 628 |
501 /* | 629 /* |
509 | 637 |
510 /* | 638 /* |
511 * Set the time-seek position | 639 * Set the time-seek position |
512 * (the playing thread will do the "seeking" aka song-change) | 640 * (the playing thread will do the "seeking" aka song-change) |
513 */ | 641 */ |
514 void xs_seek(int iTime) | 642 void xs_seek(gint iTime) |
515 { | 643 { |
516 #ifdef HAVE_SONG_POSITION | 644 #ifdef HAVE_SONG_POSITION |
517 pthread_mutex_lock(&xs_mutex); | 645 pthread_mutex_lock(&xs_mutex); |
518 | 646 |
519 if ((iTime > 0) && (iTime <= xs_status.nSongs) && xs_status.isPlaying) | 647 if ((iTime > 0) && (iTime <= xs_status.nSongs) && xs_status.isPlaying) |
527 | 655 |
528 | 656 |
529 /* | 657 /* |
530 * Return the playing "position/time" | 658 * Return the playing "position/time" |
531 */ | 659 */ |
532 int xs_get_time(void) | 660 gint xs_get_time(void) |
533 { | 661 { |
534 pthread_mutex_lock(&xs_mutex); | 662 XSDEBUG("kyrve? %i : %i\n", xs_status.isError, xs_status.isPlaying); |
535 if (xs_status.isError) | 663 if (xs_status.isError) |
536 return -2; | 664 return -2; |
537 | 665 |
538 if (!xs_status.isPlaying) | 666 if (!xs_status.isPlaying) |
539 return -1; | 667 return -1; |
540 | 668 |
669 | |
541 #ifdef HAVE_SONG_POSITION | 670 #ifdef HAVE_SONG_POSITION |
671 pthread_mutex_lock(&xs_mutex); | |
542 set_song_position(xs_status.currSong, 1, xs_status.nSongs); | 672 set_song_position(xs_status.currSong, 1, xs_status.nSongs); |
543 #endif | |
544 | |
545 pthread_mutex_unlock(&xs_mutex); | 673 pthread_mutex_unlock(&xs_mutex); |
674 #endif | |
546 | 675 |
547 return xs_plugin_ip.output->output_time(); | 676 return xs_plugin_ip.output->output_time(); |
548 } | 677 } |
549 | 678 |
550 | 679 |
551 /* | 680 /* |
552 * Return song information | 681 * Return song information |
553 */ | 682 */ |
554 void xs_get_song_info(char *songFilename, char **songTitle, int *songLength) | 683 void xs_get_song_info(gchar *songFileName, gchar **songTitle, gint *songLength) |
555 { | 684 { |
556 t_xs_tuneinfo sidInf; | 685 t_xs_tuneinfo tuneInfo; |
557 t_xs_tune *testTune = new t_xs_tune(songFilename); | 686 t_xs_tune *testTune; |
558 gint tmpInt; | 687 gint tmpInt; |
559 | 688 |
560 /* Check if the tune exists and is readable */ | 689 /* Check if the tune exists and is readable */ |
561 if (!testTune) return; | 690 testTune = new t_xs_tune(songFileName); |
691 if (testTune == NULL) return; | |
562 if (!testTune->getStatus()) | 692 if (!testTune->getStatus()) |
563 { | 693 { |
564 delete testTune; | 694 delete testTune; |
565 return; | 695 return; |
566 } | 696 } |
567 | 697 |
568 /* Get general tune information */ | 698 /* Get general tune information */ |
569 testTune->getInfo(sidInf); | 699 testTune->getInfo(tuneInfo); |
570 delete testTune; | 700 delete testTune; |
571 | 701 |
572 /* Get titlestring */ | 702 /* Get titlestring */ |
573 *songTitle = xs_filetitle_get(songFilename, &sidInf, sidInf.startSong); | 703 *songTitle = xs_filetitle_get(songFileName, &tuneInfo, tuneInfo.startSong); |
574 | 704 |
575 /* Get song length (in milliseconds), negative if no known length */ | 705 /* Get song length (in milliseconds), negative if no known length */ |
576 tmpInt = xs_songlen_get(songFilename, sidInf.startSong); | 706 tmpInt = xs_songlen_get(songFileName, tuneInfo.startSong); |
577 if (tmpInt >= 0) | 707 if (tmpInt >= 0) |
578 *songLength = (tmpInt * 1000); | 708 *songLength = (tmpInt * 1000); |
579 else | 709 else |
580 *songLength = -1; | 710 *songLength = -1; |
581 } | 711 } |
583 | 713 |
584 /* | 714 /* |
585 * Create the SID-tune description string from the tune's information | 715 * Create the SID-tune description string from the tune's information |
586 * formatted by the user-specified format-string. | 716 * formatted by the user-specified format-string. |
587 */ | 717 */ |
588 gchar *xs_filetitle_get(gchar *pcFilename, t_xs_tuneinfo *pfInfo, gint iSubTune) | 718 gchar *xs_filetitle_get(gchar *pcFileName, t_xs_tuneinfo *pfInfo, gint iSubTune) |
589 { | 719 { |
590 gint j, iLength; | 720 gint j, iLength; |
591 gchar *pcStr, *pcResult; | 721 gchar *pcStr, *pcResult; |
592 #ifdef HAVE_XMMSEXTRA | 722 #ifdef HAVE_XMMSEXTRA |
593 TitleInput *ptInput; | 723 TitleInput *ptInput; |
594 #endif | 724 #endif |
595 | 725 |
596 // FIXME FIXME: get STIL-info | 726 // FIXME FIXME: get STIL-info |
727 | |
597 | 728 |
598 /* Check the info strings */ | 729 /* Check the info strings */ |
599 if (pfInfo->numberOfInfoStrings < 3) | 730 if (pfInfo->numberOfInfoStrings < 3) |
600 { | 731 { |
601 if (pfInfo->numberOfInfoStrings < 1) | 732 if (pfInfo->numberOfInfoStrings < 1) |
657 case '4': iLength += strlen(pfInfo->formatString); break; | 788 case '4': iLength += strlen(pfInfo->formatString); break; |
658 case '%': iLength++; | 789 case '%': iLength++; |
659 } | 790 } |
660 } else | 791 } else |
661 iLength++; | 792 iLength++; |
793 | |
794 pcStr++; | |
662 } | 795 } |
663 | 796 |
664 /* Allocate memory */ | 797 /* Allocate memory */ |
665 pcResult = (gchar *) g_malloc(iLength + 2); | 798 pcResult = (gchar *) g_malloc(iLength + 2); |
666 if (pcResult == NULL) | 799 if (pcResult == NULL) |
680 case '4': xs_strpcat(pcResult, &j, pfInfo->formatString); break; | 813 case '4': xs_strpcat(pcResult, &j, pfInfo->formatString); break; |
681 case '%': pcResult[j++] = '%'; break; | 814 case '%': pcResult[j++] = '%'; break; |
682 } | 815 } |
683 } else | 816 } else |
684 pcResult[j++] = *pcStr; | 817 pcResult[j++] = *pcStr; |
818 | |
819 pcStr++; | |
685 } | 820 } |
686 | 821 |
687 pcResult[j] = 0; | 822 pcResult[j] = 0; |
688 } | 823 } |
689 | 824 |