comparison src/xmms-sid.cc @ 40:1788f4ce6a44

Numerous changes towards 0.8
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 19 Jun 2003 22:38:01 +0000
parents 15250dd0c326
children 0f00ebab063d
comparison
equal deleted inserted replaced
39:85a7753e2a9a 40:1788f4ce6a44
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 22 extern "C" {
23 #include <pthread.h> 23 #include <pthread.h>
24 #include <stdlib.h> 24 #include <stdlib.h>
25 #include <string.h> 25 #include <string.h>
26 #include <stdio.h> 26 #include <stdio.h>
27 #include <errno.h> 27 #include <errno.h>
28 #include <xmms/plugin.h> 28 #include <xmms/plugin.h>
29 #include <xmms/util.h> 29 #include <xmms/util.h>
30 #include <xmms/titlestring.h>
30 #include "xmms-sid.h" 31 #include "xmms-sid.h"
32 #include "xs_support.h"
31 #include "xs_config.h" 33 #include "xs_config.h"
32 #include "xs_length.h" 34 #include "xs_length.h"
33 #include "xs_title.h" 35 }
34 36
35 extern "C++" { 37 #ifdef HAVE_SIDPLAY1
36 #include <sidplay/player.h> 38 #include <sidplay/player.h>
37 #include <sidplay/myendian.h> 39 #include <sidplay/myendian.h>
38 #include <sidplay/fformat.h> 40 #include <sidplay/fformat.h>
39 } 41 #endif
42
43 #ifdef HAVE_SIDPLAY2
44 #include <sidplay/sidplay2.h>
45 #endif
40 46
41 47
42 /* 48 /*
43 * Global variables 49 * Global variables
44 */ 50 */
51 #ifdef HAVE_SIDPLAY1
45 static struct emuConfig xs_emuConf; 52 static struct emuConfig xs_emuConf;
46 static emuEngine xs_emuEngine; 53 static emuEngine xs_emuEngine;
54 typedef sidTune t_xs_tune;
55 #endif
56
57 #ifdef HAVE_SIDPLAY2
58 #endif
59
47 static pthread_t xs_decode_thread; 60 static pthread_t xs_decode_thread;
48 struct t_xs_cfg xs_cfg; 61 struct t_xs_cfg xs_cfg;
49 62
50 struct { 63 struct {
51 int s_error, s_playing, s_songs, s_allownext; 64 gboolean isError, isPlaying, allowNext;
52 sidTune *s_tune; 65 gint currSong, nSongs;
53 gchar *s_fname; 66 t_xs_tune *currTune;
67 gchar *currFilename;
54 } xs_status; 68 } xs_status;
55 69
56 pthread_mutex_t xs_mutex = PTHREAD_MUTEX_INITIALIZER; 70 pthread_mutex_t xs_mutex = PTHREAD_MUTEX_INITIALIZER;
57 71
58 72
64 XSDEBUG("xs_init()\n"); 78 XSDEBUG("xs_init()\n");
65 79
66 /* Initialize and get configuration */ 80 /* Initialize and get configuration */
67 memset(&xs_cfg, 0, sizeof(xs_cfg)); 81 memset(&xs_cfg, 0, sizeof(xs_cfg));
68 82
69 xs_get_configure(); 83 xs_read_configuration();
70 84
71 xs_status.s_error = 0; 85 xs_status.isError = FALSE;
72 xs_status.s_playing = 0; 86 xs_status.isPlaying = FALSE;
73 xs_status.s_songs = 0; 87 xs_status.nSongs = 0;
74 xs_status.s_allownext = 1; // Initialize to TRUE to allow first song 88 xs_status.currSong = 0;
75 xs_status.s_tune = NULL; 89 xs_status.allowNext = TRUE; // Initialize to TRUE to allow first song
76 xs_status.s_fname = NULL; 90 xs_status.currTune = NULL;
77 91 xs_status.currFilename = NULL;
78 /* Try to initialize libSIDPlay */ 92
79 if (!xs_emuEngine) 93
80 { 94 /* Try to initialize libSIDPlay(s) */
81 XSERR("Couldn't start SIDPlay emulator engine!\n"); 95 #ifdef HAVE_SIDPLAY1
96 if (!xs_emuEngine || !xs_emuEngine.verifyEndianess())
97 {
98 XSERR("Couldn't start SIDPlay1 emulator engine!\n");
82 return; 99 return;
83 } 100 }
84 101 #endif
85 if (!xs_emuEngine.verifyEndianess()) 102
86 { 103 #ifdef HAVE_SIDPLAY2
87 XSERR("Wrong hardware endianess (SIDPlay error)!\n"); 104 #endif
88 return;
89 }
90 105
91 /* Read song-length database */ 106 /* Read song-length database */
107 if (xs_cfg.songlenDBEnable)
92 if (xs_songlen_init() < 0) 108 if (xs_songlen_init() < 0)
93 { 109 {
94 XSERR("Error initializing song-length database!\n"); 110 XSERR("Error initializing song-length database!\n");
95 } 111 }
96 112
110 XSDEBUG("shutting down...\n"); 126 XSDEBUG("shutting down...\n");
111 127
112 /* Stop playing */ 128 /* Stop playing */
113 xs_plugin_ip.stop(); 129 xs_plugin_ip.stop();
114 130
131 /* Shutdown libSIDPlay(s) */
132 #ifdef HAVE_SIDPLAY1
133 #endif
134
135 #ifdef HAVE_SIDPLAY2
136 #endif
137
115 /* Close sub-song control window */ 138 /* Close sub-song control window */
116 139
117 /* Free allocated memory */ 140 /* Free allocated memory */
118 xs_songlen_close(); 141 xs_songlen_close();
119 142
133 return FALSE; 156 return FALSE;
134 157
135 /* Try to detect via libSIDPlay's detection routine, if required */ 158 /* Try to detect via libSIDPlay's detection routine, if required */
136 if (xs_cfg.detectMagic) 159 if (xs_cfg.detectMagic)
137 { 160 {
138 sidTune *testTune = new sidTune(fileName); 161 #ifdef HAVE_SIDPLAY1
139 162 t_xs_tune *testTune = new sidTune(fileName);
140 if (!testTune) return FALSE; 163 if (!testTune) return FALSE;
141 if (!testTune->getStatus()) 164 if (!testTune->getStatus())
142 { 165 {
143 delete testTune; 166 delete testTune;
144 return FALSE; 167 return FALSE;
145 } 168 }
146 169
147 delete testTune; 170 delete testTune;
148 return TRUE; 171 return TRUE;
149 } 172 #endif
150 173 #ifdef HAVE_SIDPLAY2
174 #endif
175 }
151 176
152 /* Detect just by checking filename extension */ 177 /* Detect just by checking filename extension */
153 pcExt = strrchr(fileName, '.'); 178 pcExt = strrchr(fileName, '.');
154 if (pcExt) 179 if (pcExt)
155 { 180 {
168 /* 193 /*
169 * Main playing thread loop 194 * Main playing thread loop
170 */ 195 */
171 static void *xs_play_loop(void *argPointer) 196 static void *xs_play_loop(void *argPointer)
172 { 197 {
173 guchar plr_data[XS_BUFSIZE];
174 struct sidTuneInfo plr_sidInf;
175 gchar *plr_tune_title = NULL;
176 gint plr_fxlen;
177 enum AFormat plr_fmt;
178 gint plr_tune_num;
179 gint32 plr_tune_len;
180
181
182 /* Don't allow next song to be set yet */ 198 /* Don't allow next song to be set yet */
183 pthread_mutex_lock(&xs_mutex); 199 pthread_mutex_lock(&xs_mutex);
184 xs_status.s_allownext = 0; 200 xs_status.allowNext = FALSE;
185 pthread_mutex_unlock(&xs_mutex); 201 pthread_mutex_unlock(&xs_mutex);
186 202
187 203
188 /* Check tune number */ 204
189 plr_tune_num = xs_status.s_playing; 205 XSDEBUG("exiting thread, bye.\n");
190 206 return NULL;
191 if (plr_tune_num <= 0) 207 }
192 plr_tune_num = 1; 208
193 209
194 XSDEBUG("xs_play_loop(%d, %d)\n", plr_tune_num, xs_status.s_playing); 210 /*
195 211 * Start playing the given file
196 /* Get song information */ 212 */
197 xs_status.s_tune->getInfo(plr_sidInf); 213 void xs_play_file(char *fileName)
198 plr_tune_len = xs_songlen_get(xs_status.s_fname, plr_tune_num); 214 {
199 plr_tune_title = xs_filetitle_get(&plr_sidInf, plr_tune_num); 215 t_xs_tune *newTune;
200 216 struct sidTuneInfo sidInf;
201 XSDEBUG("title='%s', len=%d\n", plr_tune_title, plr_tune_len); 217
218 XSDEBUG("request to load '%s'\n", fileName);
202 219
203 220
204 /* Initialize audio output */ 221 /* Initialize audio output */
205 // FIXME FIXME: FMT_S16_XXX -- different architechtures?? 222 XSDEBUG("opening audio output plugin...\n");
206 // the patch may break something ... 223 if (!xs_plugin_ip.output->open_audio(
207 plr_fmt = (xs_emuConf.bitsPerSample == 16) ? FMT_S16_NE : FMT_U8; 224 ((xs_cfg.fmtBitsPerSample == 16) ? FMT_S16_NE : FMT_U8), xs_cfg.fmtFrequency,
208 225 ((xs_cfg.fmtChannels == XS_CHN_MONO) ? 1 : 2)))
209 226 {
210 if (!xs_plugin_ip.output->open_audio(plr_fmt, xs_emuConf.frequency, xs_emuConf.channels)) 227 XSERR("Couldn't open audio output plugin!\n");
211 { 228 delete newTune;
212 pthread_mutex_lock(&xs_mutex); 229 return;
213 xs_status.s_error = 1; 230 }
214 if (plr_tune_title) g_free(plr_tune_title); 231
215 if (xs_status.s_tune) delete xs_status.s_tune;
216 xs_status.s_allownext = 1;
217 pthread_mutex_unlock(&xs_mutex);
218 return NULL;
219 }
220
221
222 /* Initialize the SIDPlay-emulator for song */
223 if (!sidEmuInitializeSong(xs_emuEngine, *xs_status.s_tune, plr_tune_num))
224 {
225 XSERR("Couldn't initialize SIDPlay emulator engine! This may be a problem with your sound settings, or possibly a bug in XMMS-SID.\n");
226 pthread_mutex_lock(&xs_mutex);
227 xs_status.s_error = 1;
228 pthread_mutex_unlock(&xs_mutex);
229 goto pl_cleanup;
230 }
231
232
233 /* Set song title information */
234 xs_plugin_ip.set_info(
235 plr_tune_title,
236 (plr_tune_len * 1000),
237 (1000 * (plr_sidInf.songSpeed ? plr_sidInf.songSpeed : (plr_sidInf.clockSpeed == SIDTUNE_CLOCK_NTSC) ? 60 : 50)),
238 xs_emuConf.frequency,
239 xs_emuConf.channels);
240
241
242 /* Run playing loop: loop as long as xs_playing is same as current tune number */
243 while (xs_status.s_playing == plr_tune_num)
244 {
245 plr_fxlen = XS_BUFSIZE;
246
247 /* Run emulator to fill output buffer with audio data */
248 sidEmuFillBuffer(xs_emuEngine, *xs_status.s_tune, plr_data, plr_fxlen);
249
250 /* If Max Playtime option set, check playtime */
251 if (xs_cfg.playUseMaxTime)
252 {
253 if ((xs_plugin_ip.output->output_time() / 1000) >= xs_cfg.playMaxTime)
254 {
255 pthread_mutex_lock(&xs_mutex);
256 xs_status.s_playing = 0;
257 pthread_mutex_unlock(&xs_mutex);
258 }
259 }
260
261 /* Check playtime against database */
262 if (xs_cfg.playMethod == XMMS_SID_PMETHOD_DATABASE)
263 {
264 if ((xs_plugin_ip.output->output_time() / 1000) >= plr_tune_len)
265 {
266 pthread_mutex_lock(&xs_mutex);
267 xs_status.s_playing = 0;
268 pthread_mutex_unlock(&xs_mutex);
269 }
270
271 }
272 #if 0
273 else
274
275 /* Check for silence */
276 if (xs_cfg.playMethod == XMMS_SID_PMETHOD_MAXSILENCE)
277 {
278 }
279
280 /* Add static noise */
281
282 /* Muffle waveform (low-pass filter) */
283
284 #endif
285
286
287 /* Send audio data to visualization plugin */
288 xs_plugin_ip.add_vis_pcm(xs_plugin_ip.output->written_time(),
289 plr_fmt, xs_emuConf.channels, plr_fxlen, plr_data);
290
291 /* Wait for a while */
292 while ((xs_status.s_playing == plr_tune_num) && (xs_plugin_ip.output->buffer_free() < plr_fxlen))
293 xmms_usleep(10000);
294
295
296 /* If playing, send final audio data to output plugin */
297 if (xs_status.s_playing == plr_tune_num)
298 xs_plugin_ip.output->write_audio(plr_data, plr_fxlen);
299
300 } /* End of playerloop */
301
302
303 pl_cleanup:
304 XSDEBUG("cleaning up...\n");
305
306 /* Cleanup & shutdown */
307 xs_plugin_ip.output->close_audio();
308
309 if (plr_tune_title) g_free(plr_tune_title);
310
311 pthread_mutex_lock(&xs_mutex);
312 xs_status.s_playing = 0;
313 if (xs_status.s_tune) delete xs_status.s_tune;
314 xs_status.s_allownext = 1;
315 pthread_mutex_unlock(&xs_mutex);
316
317 XSDEBUG("exiting thread, bye.\n");
318 return NULL;
319 }
320
321
322 /*
323 * Start playing the given file
324 */
325 void xs_play_file(char *fileName)
326 {
327 sidTune *newTune;
328 struct sidTuneInfo sidInf;
329
330 XSDEBUG("request to start '%s'\n", fileName);
331
332 /* Wait until the previous song has finished for sure */
333 if (!xs_status.s_allownext)
334 pthread_join(xs_decode_thread, NULL);
335 232
336 /* Try to get the tune */ 233 /* Try to get the tune */
337 newTune = new sidTune(fileName); 234 newTune = new sidTune(fileName);
338 if (newTune == NULL) return; 235 if (newTune == NULL) return;
339 236
340 XSDEBUG("tune ok, status %i\n", xs_status.s_playing); 237 XSDEBUG("tune ok, configuring SIDPlay engine\n");
341 238
342 239
343 /* Get current configuration */ 240 /* Get current configuration */
344 xs_emuEngine.getConfig(xs_emuConf); 241 xs_emuEngine.getConfig(xs_emuConf);
345 242
346 243
347 /* Configure channels and stuff */ 244 /* Configure channels and stuff */
348 switch (xs_cfg.fmtChannels) { 245 switch (xs_cfg.fmtChannels) {
349 246
350 case XMMS_SID_CHN_AUTOPAN: 247 case XS_CHN_AUTOPAN:
351 xs_emuConf.channels = SIDEMU_STEREO; 248 xs_emuConf.channels = SIDEMU_STEREO;
352 xs_emuConf.autoPanning = SIDEMU_CENTEREDAUTOPANNING; 249 xs_emuConf.autoPanning = SIDEMU_CENTEREDAUTOPANNING;
353 xs_emuConf.volumeControl = SIDEMU_FULLPANNING; 250 xs_emuConf.volumeControl = SIDEMU_FULLPANNING;
354 break; 251 break;
355 252
356 case XMMS_SID_CHN_STEREO: 253 case XS_CHN_STEREO:
357 xs_emuConf.channels = SIDEMU_STEREO; 254 xs_emuConf.channels = SIDEMU_STEREO;
358 xs_emuConf.autoPanning = SIDEMU_NONE; 255 xs_emuConf.autoPanning = SIDEMU_NONE;
359 xs_emuConf.volumeControl = SIDEMU_NONE; 256 xs_emuConf.volumeControl = SIDEMU_NONE;
360 break; 257 break;
361 258
362 case XMMS_SID_CHN_MONO: 259 case XS_CHN_MONO:
363 xs_emuConf.channels = SIDEMU_MONO; 260 xs_emuConf.channels = SIDEMU_MONO;
364 xs_emuConf.autoPanning = SIDEMU_NONE; 261 xs_emuConf.autoPanning = SIDEMU_NONE;
365 xs_emuConf.volumeControl = SIDEMU_NONE; 262 xs_emuConf.volumeControl = SIDEMU_NONE;
366 break; 263 break;
367 264
372 } 269 }
373 270
374 271
375 /* Memory mode settings */ 272 /* Memory mode settings */
376 switch (xs_cfg.memoryMode) { 273 switch (xs_cfg.memoryMode) {
377 case XMMS_SID_MPU_BANK_SWITCHING: 274 case XS_MPU_BANK_SWITCHING:
378 xs_emuConf.memoryMode = MPU_BANK_SWITCHING; 275 xs_emuConf.memoryMode = MPU_BANK_SWITCHING;
379 break; 276 break;
380 277
381 case XMMS_SID_MPU_TRANSPARENT_ROM: 278 case XS_MPU_TRANSPARENT_ROM:
382 xs_emuConf.memoryMode = MPU_TRANSPARENT_ROM; 279 xs_emuConf.memoryMode = MPU_TRANSPARENT_ROM;
383 break; 280 break;
384 281
385 case XMMS_SID_MPU_PLAYSID_ENVIRONMENT: 282 case XS_MPU_PLAYSID_ENVIRONMENT:
386 xs_emuConf.memoryMode = MPU_PLAYSID_ENVIRONMENT; 283 xs_emuConf.memoryMode = MPU_PLAYSID_ENVIRONMENT;
387 break; 284 break;
388 285
389 default: 286 default:
390 XSERR("Internal: Invalid memoryMode setting. Possibly corrupted configuration file.\n"); 287 XSERR("Internal: Invalid memoryMode setting. Possibly corrupted configuration file.\n");
393 } 290 }
394 291
395 292
396 /* Clockspeed settings */ 293 /* Clockspeed settings */
397 switch (xs_cfg.clockSpeed) { 294 switch (xs_cfg.clockSpeed) {
398 case XMMS_SID_CLOCK_PAL: 295 case XS_CLOCK_PAL:
399 xs_emuConf.clockSpeed = SIDTUNE_CLOCK_PAL; 296 xs_emuConf.clockSpeed = SIDTUNE_CLOCK_PAL;
400 break; 297 break;
401 298
402 case XMMS_SID_CLOCK_NTSC: 299 case XS_CLOCK_NTSC:
403 xs_emuConf.clockSpeed = SIDTUNE_CLOCK_NTSC; 300 xs_emuConf.clockSpeed = SIDTUNE_CLOCK_NTSC;
404 break; 301 break;
405 302
406 default: 303 default:
407 XSERR("Internal: Invalid clockSpeed setting. Possibly corrupted configuration file.\n"); 304 XSERR("Internal: Invalid clockSpeed setting. Possibly corrupted configuration file.\n");
413 /* Configure rest of the emulation */ 310 /* Configure rest of the emulation */
414 xs_emuConf.bitsPerSample = xs_cfg.fmtBitsPerSample; 311 xs_emuConf.bitsPerSample = xs_cfg.fmtBitsPerSample;
415 xs_emuConf.frequency = xs_cfg.fmtFrequency; 312 xs_emuConf.frequency = xs_cfg.fmtFrequency;
416 xs_emuConf.sampleFormat = SIDEMU_SIGNED_PCM; 313 xs_emuConf.sampleFormat = SIDEMU_SIGNED_PCM;
417 xs_emuConf.mos8580 = xs_cfg.mos8580; 314 xs_emuConf.mos8580 = xs_cfg.mos8580;
418 xs_emuConf.emulateFilter = xs_cfg.emulateFilter; 315 xs_emuConf.emulateFilter = xs_cfg.emulateFilters;
419 xs_emuConf.filterFs = xs_cfg.filterFs; 316 xs_emuConf.filterFs = xs_cfg.filterFs;
420 xs_emuConf.filterFm = xs_cfg.filterFm; 317 xs_emuConf.filterFm = xs_cfg.filterFm;
421 xs_emuConf.filterFt = xs_cfg.filterFt; 318 xs_emuConf.filterFt = xs_cfg.filterFt;
422 319
423 XSDEBUG("configuring engine..\n"); 320 XSDEBUG("configuring engine..\n");
427 xs_emuEngine.setConfig(xs_emuConf); 324 xs_emuEngine.setConfig(xs_emuConf);
428 newTune->getInfo(sidInf); 325 newTune->getInfo(sidInf);
429 326
430 327
431 /* Initialize status information */ 328 /* Initialize status information */
432 XSDEBUG("starting thread!\n"); 329 XSDEBUG("initializing and starting playing thread!\n");
433 330
434 pthread_mutex_lock(&xs_mutex); 331 xs_status.isError = FALSE;
435 xs_status.s_error = 0; 332 xs_status.isPlaying = TRUE;
436 xs_status.s_playing = sidInf.startSong; 333 xs_status.allowNext = TRUE;
437 xs_status.s_songs = sidInf.songs; 334 xs_status.currSong = sidInf.startSong;
438 xs_status.s_tune = newTune; 335 xs_status.nSongs = sidInf.songs;
439 pthread_mutex_unlock(&xs_mutex); 336 xs_status.currTune = newTune;
337
440 338
441 /* Start the playing thread! */ 339 /* Start the playing thread! */
442 if (pthread_create(&xs_decode_thread, NULL, xs_play_loop, NULL) < 0) 340 if (pthread_create(&xs_decode_thread, NULL, xs_play_loop, NULL) < 0)
443 { 341 {
444 XSERR("Couldn't start playing thread! Possible reason reported by system: %s\n", strerror(errno)); 342 XSERR("Couldn't start playing thread! Possible reason reported by system: %s\n", strerror(errno));
453 * Stop playing 351 * Stop playing
454 */ 352 */
455 void xs_stop(void) 353 void xs_stop(void)
456 { 354 {
457 /* If playing, stop. */ 355 /* If playing, stop. */
458 if (xs_status.s_playing) 356 XSDEBUG("request to stop.\n");
459 { 357
358 if (xs_status.isPlaying)
359 {
360 XSDEBUG("stopping...\n");
460 pthread_mutex_lock(&xs_mutex); 361 pthread_mutex_lock(&xs_mutex);
461 xs_status.s_playing = 0; 362 xs_status.isPlaying = 0;
462 pthread_mutex_unlock(&xs_mutex); 363 pthread_mutex_unlock(&xs_mutex);
463 364
464 pthread_join(xs_decode_thread, NULL); 365 pthread_join(xs_decode_thread, NULL);
366
367 xs_plugin_ip.output->close_audio();
465 } 368 }
466 } 369 }
467 370
468 371
469 /* 372 /*
480 * (the playing thread will do the "seeking" aka song-change) 383 * (the playing thread will do the "seeking" aka song-change)
481 */ 384 */
482 void xs_seek(int iTime) 385 void xs_seek(int iTime)
483 { 386 {
484 #ifdef HAVE_SONG_POSITION 387 #ifdef HAVE_SONG_POSITION
485 if ((iTime > 0) && (iTime <= xs_songs)) 388 pthread_mutex_lock(&xs_mutex);
486 { 389
487 pthread_mutex_lock(&xs_mutex); 390 if ((iTime > 0) && (iTime <= xs_status.nSongs) && xs_status.isPlaying)
488 xs_status.s_playing = iTime; 391 {
489 pthread_mutex_unlock(&xs_mutex); 392 xs_status.currSong = iTime;
490 } 393 }
394
395 pthread_mutex_unlock(&xs_mutex);
491 #endif 396 #endif
492 } 397 }
493 398
494 399
495 /* 400 /*
496 * Return the playing "position/time" 401 * Return the playing "position/time"
497 */ 402 */
498 int xs_get_time(void) 403 int xs_get_time(void)
499 { 404 {
500 if (xs_status.s_error) 405 pthread_mutex_lock(&xs_mutex);
406 if (xs_status.isError)
501 return -2; 407 return -2;
502 408
503 if (!xs_status.s_playing) 409 if (!xs_status.isPlaying)
504 return -1; 410 return -1;
505 411
506 #ifdef HAVE_SONG_POSITION 412 #ifdef HAVE_SONG_POSITION
507 set_song_position(xs_status.s_playing, 1, xs_status.s_songs); 413 set_song_position(xs_status.currSong, 1, xs_status.nSongs);
508 #endif 414 #endif
415
416 pthread_mutex_unlock(&xs_mutex);
509 417
510 return xs_plugin_ip.output->output_time(); 418 return xs_plugin_ip.output->output_time();
511 } 419 }
512 420
513 421
515 * Return song information 423 * Return song information
516 */ 424 */
517 void xs_get_song_info(char *songFilename, char **songTitle, int *songLength) 425 void xs_get_song_info(char *songFilename, char **songTitle, int *songLength)
518 { 426 {
519 struct sidTuneInfo sidInf; 427 struct sidTuneInfo sidInf;
520 sidTune *testTune = new sidTune(songFilename); 428 t_xs_tune *testTune = new sidTune(songFilename);
521 429
522 /* Check if the tune exists and is readable */ 430 /* Check if the tune exists and is readable */
523 if (!testTune) return; 431 if (!testTune) return;
524 if (!testTune->getStatus()) 432 if (!testTune->getStatus())
525 { 433 {
530 /* Get general tune information */ 438 /* Get general tune information */
531 testTune->getInfo(sidInf); 439 testTune->getInfo(sidInf);
532 delete testTune; 440 delete testTune;
533 441
534 /* Get titlestring */ 442 /* Get titlestring */
535 *songTitle = xs_filetitle_get(&sidInf, sidInf.startSong); 443 *songTitle = NULL;
536 444
537 /* Get song length (in seconds), negative if no known length */ 445 /* Get song length (in milliseconds), negative if no known length */
538 *songLength = xs_songlen_get(songFilename, sidInf.startSong); 446 *songLength = xs_songlen_get(songFilename, sidInf.startSong) * 1000;
539 } 447 }
540 448
449
450 /*
451 * Create the SID-tune description string from the tune's information
452 * formatted by the user-specified format-string.
453 */
454 gchar *xs_filetitle_get(gchar *pcFilename, void *pfInfo, gint iSubTune)
455 {
456 gint i, j, iLength;
457 gchar *pcResult;
458 struct sidTuneInfo *finfo = (struct sidTuneInfo *) pfInfo;
459 #ifdef HAVE_XMMSEXTRA
460 TitleInput *ptInput;
461 #endif
462
463 // FIXME FIXME: get STIL-info
464
465
466 #ifdef HAVE_XMMSEXTRA
467 /* Check if the titles are overridden or not */
468 if (!xs_cfg.titleOverride)
469 {
470 /* Use generic XMMS titles */
471 /* XMMS_NEW_TITLEINPUT(ptInput);
472 * We duplicate and add typecast to the code here due to XMMS's braindead headers
473 */
474 ptInput = (TitleInput *) g_malloc0(sizeof(TitleInput));
475 ptInput->__size = XMMS_TITLEINPUT_SIZE;
476 ptInput->__version = XMMS_TITLEINPUT_VERSION;
477
478 /* Create the input fields */
479 ptInput->file_name = pcFilename;
480 ptInput->file_ext = pcFilename;
481 ptInput->file_path = pcFilename;
482
483 ptInput->track_name = finfo->nameString;
484 ptInput->track_number = iSubTune;
485 ptInput->album_name = NULL;
486 ptInput->performer = finfo->authorString;
487 xs_strcalloc(&ptInput->date, "");
488 ptInput->year = 0;
489 xs_strcalloc(&ptInput->genre, "SID-tune");
490 ptInput->comment = finfo->copyrightString;
491
492 /* Create the string */
493 pcResult = xmms_get_titlestring(xmms_get_gentitle_format(), ptInput);
494
495 /* Dispose all allocated memory */
496 g_free(ptInput->date);
497 g_free(ptInput->genre);
498 g_free(ptInput);
499 } else {
500 #endif
501 /* Check the info strings */
502 if (finfo->numberOfInfoStrings != 3)
503 {
504 if (finfo->numberOfInfoStrings < 1)
505 return 0;
506
507 return g_strdup(finfo->infoString[0]);
508 }
509
510 /* Check the format-string for NULL */
511 if (xs_cfg.titleFormat == NULL)
512 return g_strdup_printf("%s - %s", finfo->nameString, finfo->authorString);
513
514 /* Construct the final result info */
515 for (j = i = 0; i < strlen(xs_cfg.titleFormat); i++)
516 {
517 if (xs_cfg.titleFormat[i] == '%')
518 {
519 switch (xs_cfg.titleFormat[++i]) {
520 case '1':
521 xs_strpcat(&pcResult, &j, finfo->authorString);
522 break;
523
524 case '2':
525 xs_strpcat(&pcResult, &j, finfo->nameString);
526 break;
527
528 case '3':
529 xs_strpcat(&pcResult, &j, finfo->copyrightString);
530 break;
531
532 case '4':
533 xs_strpcat(&pcResult, &j, finfo->formatString);
534 break;
535 } /* case */
536 } else
537 pcResult[j++] = xs_cfg.titleFormat[i];
538 }
539
540 pcResult[j] = 0;
541 #ifdef HAVE_XMMSEXTRA
542 }
543 #endif
544
545 return pcResult;
546 }
547