~ubuntu-branches/ubuntu/oneiric/audacious-plugins/oneiric

« back to all changes in this revision

Viewing changes to src/sid/xmms-sid.c

  • Committer: Bazaar Package Importer
  • Author(s): Benjamin Drung
  • Date: 2010-04-13 22:48:07 UTC
  • mfrom: (1.1.12 upstream) (2.1.5 experimental)
  • Revision ID: james.westby@ubuntu.com-20100413224807-imw9qnn26cxcgefq
Tags: 2.3-1ubuntu1
* Merge from Debian experimental (LP: #494604), remaining change:
  - audacious-plugins suggests timidiy for midi playback
* Build-Depend on libav* for ffaudio.
* Break and replace audacious (<< 2.3).
* Drop audacious-plugins-dev package. "apt-get build-dep audacious-plugins"
  will do the same job.
* audacious-plugins recommends audacious instead of depending on it to break
  the circular dependency (Closes: #528588).

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
   Main source file
5
5
 
6
6
   Programmed and designed by Matti 'ccr' Hamalainen <ccr@tnsp.org>
7
 
   (C) Copyright 1999-2007 Tecnic Software productions (TNSP)
 
7
   (C) Copyright 1999-2009 Tecnic Software productions (TNSP)
8
8
 
9
9
   This program is free software; you can redistribute it and/or modify
10
10
   it under the terms of the GNU General Public License as published by
43
43
 */
44
44
xs_status_t xs_status;
45
45
XS_MUTEX(xs_status);
46
 
static XS_THREAD_T xs_decode_thread;
47
46
 
48
47
static void xs_get_song_tuple_info(Tuple *pResult, xs_tuneinfo_t *pInfo, gint subTune);
49
48
 
50
49
/*
51
50
 * Error messages
52
51
 */
53
 
void xs_error(const char *fmt, ...)
 
52
void xs_verror(const gchar *fmt, va_list ap)
54
53
{
55
 
    va_list ap;
56
 
    va_start(ap, fmt);
57
54
    g_logv("AUD-SID", G_LOG_LEVEL_WARNING, fmt, ap);
 
55
}
 
56
 
 
57
void xs_error(const gchar *fmt, ...)
 
58
{
 
59
    va_list ap;
 
60
    va_start(ap, fmt);
 
61
    xs_verror(fmt, ap);
58
62
    va_end(ap);
59
63
}
60
64
 
61
65
#ifdef DEBUG
62
 
void XSDEBUG(const char *fmt, ...)
 
66
void XSDEBUG(const gchar *fmt, ...)
63
67
{
64
68
    va_list ap;
65
69
    va_start(ap, fmt);
77
81
    XSDEBUG("xs_reinit() thread = %p\n", g_thread_self());
78
82
 
79
83
    /* Stop playing, if we are */
80
 
    XS_MUTEX_LOCK(xs_status);
81
 
    if (xs_status.isPlaying) {
82
 
        XS_MUTEX_UNLOCK(xs_status);
83
 
        xs_stop(NULL);
84
 
    } else {
85
 
        XS_MUTEX_UNLOCK(xs_status);
86
 
    }
 
84
    xs_stop(NULL);
87
85
 
88
86
    XS_MUTEX_LOCK(xs_status);
89
87
    XS_MUTEX_LOCK(xs_cfg);
111
109
 
112
110
    /* Try to initialize emulator engine */
113
111
    xs_init_emu_engine(&xs_cfg.playerEngine, &xs_status);
114
 
    
 
112
 
115
113
    /* Get settings back, in case the chosen emulator backend changed them */
116
114
    xs_cfg.audioFrequency = xs_status.audioFrequency;
117
115
    xs_cfg.audioBitsPerSample = xs_status.audioBitsPerSample;
177
175
 
178
176
 
179
177
/*
180
 
 * Check whether the given file is handled by this plugin
181
 
 */
182
 
static gchar * xs_has_tracknumber(gchar *filename)
183
 
{
184
 
    gchar *sep = xs_strrchr(filename, '?');
185
 
    if (sep && g_ascii_isdigit(*(sep + 1)))
186
 
        return sep;
187
 
    else
188
 
        return NULL;
189
 
}
190
 
 
191
 
gboolean xs_get_trackinfo(const gchar *filename, gchar **result, gint *track)
192
 
{
193
 
    gchar *sep;
194
 
 
195
 
    *result = g_strdup(filename);
196
 
    sep = xs_has_tracknumber(*result);
197
 
 
198
 
    if (sep) {
199
 
        *sep = '\0';
200
 
        *track = atoi(sep + 1);
201
 
        return TRUE;
202
 
    } else {
203
 
        *track = -1;
204
 
        return FALSE;
205
 
    }
206
 
}
207
 
 
208
 
 
209
 
/*
210
178
 * Start playing the given file
211
179
 */
212
180
void xs_play_file(InputPlayback *pb)
213
181
{
214
182
    xs_tuneinfo_t *tmpTune;
215
183
    gboolean audioOpen = FALSE;
216
 
    gint audioGot, tmpLength, subTune;
217
 
    gchar *tmpFilename, *audioBuffer = NULL, *oversampleBuffer = NULL, *tmpTitle;
 
184
    gint audioBufSize, bufChunkSize, bufRemaining, tmpLength, subTune = -1;
 
185
    gchar *tmpFilename, *bufPointer,
 
186
        *audioBuffer = NULL, *oversampleBuffer = NULL;
218
187
    Tuple *tmpTuple;
219
188
 
220
189
    assert(pb);
221
190
    assert(xs_status.sidPlayer != NULL);
222
 
    
 
191
 
223
192
    XSDEBUG("play '%s'\n", pb->filename);
224
193
 
225
 
    XS_MUTEX_LOCK(xs_status);
 
194
    tmpFilename = aud_filename_split_subtune(pb->filename, &subTune);
 
195
    if (tmpFilename == NULL) return;
226
196
 
227
197
    /* Get tune information */
228
 
    xs_get_trackinfo(pb->filename, &tmpFilename, &subTune);
 
198
    XS_MUTEX_LOCK(xs_status);
229
199
    if ((xs_status.tuneInfo = xs_status.sidPlayer->plrGetSIDInfo(tmpFilename)) == NULL) {
230
200
        XS_MUTEX_UNLOCK(xs_status);
231
201
        g_free(tmpFilename);
240
210
        xs_status.tuneInfo = NULL;
241
211
        return;
242
212
    }
243
 
    
 
213
 
244
214
    g_free(tmpFilename);
245
215
    tmpFilename = NULL;
246
216
 
248
218
 
249
219
    /* Set general status information */
250
220
    pb->playing = TRUE;
251
 
    xs_status.isPlaying = TRUE;
252
221
    pb->error = FALSE;
253
222
    pb->eof = FALSE;
254
223
    tmpTune = xs_status.tuneInfo;
261
230
    XSDEBUG("subtune #%i selected (#%d wanted), initializing...\n", xs_status.currSong, subTune);
262
231
 
263
232
 
264
 
    /* We are ready */
265
 
    xs_decode_thread = g_thread_self();
266
 
    XSDEBUG("playing thread = %p\n", xs_decode_thread);
267
 
 
268
 
 
269
233
    /* Allocate audio buffer */
270
 
    audioBuffer = (gchar *) g_malloc(XS_AUDIOBUF_SIZE);
 
234
    audioBufSize = (xs_status.audioFrequency * xs_status.audioChannels * xs_status.audioBitsPerSample) / (8 * 4);
 
235
    if (audioBufSize < 512) audioBufSize = 512;
 
236
    bufChunkSize = (xs_status.audioFrequency * xs_status.audioChannels * xs_status.audioBitsPerSample) / (8 * 50);
 
237
    if (bufChunkSize < 512) bufChunkSize = 512;
 
238
 
 
239
    audioBuffer = (gchar *) g_malloc(audioBufSize);
271
240
    if (audioBuffer == NULL) {
272
241
        xs_error("Couldn't allocate memory for audio data buffer!\n");
273
242
        XS_MUTEX_UNLOCK(xs_status);
274
243
        goto xs_err_exit;
275
244
    }
276
 
    
 
245
 
277
246
    if (xs_status.oversampleEnable) {
278
 
        oversampleBuffer = (gchar *) g_malloc(XS_AUDIOBUF_SIZE * xs_status.oversampleFactor);
 
247
        oversampleBuffer = (gchar *) g_malloc(audioBufSize * xs_status.oversampleFactor);
279
248
        if (oversampleBuffer == NULL) {
280
249
            xs_error("Couldn't allocate memory for audio oversampling buffer!\n");
281
250
            XS_MUTEX_UNLOCK(xs_status);
298
267
        XS_MUTEX_UNLOCK(xs_status);
299
268
        goto xs_err_exit;
300
269
    }
301
 
        
 
270
 
302
271
    /* Open the audio output */
303
272
    XSDEBUG("open audio output (%d, %d, %d)\n",
304
273
        xs_status.audioFormat, xs_status.audioFrequency, xs_status.audioChannels);
305
 
        
 
274
 
306
275
    if (!pb->output->open_audio(xs_status.audioFormat, xs_status.audioFrequency, xs_status.audioChannels)) {
307
276
        xs_error("Couldn't open audio output (fmt=%x, freq=%i, nchan=%i)!\n",
308
277
            xs_status.audioFormat,
316
285
 
317
286
    audioOpen = TRUE;
318
287
 
319
 
    pb->set_pb_ready(pb);
320
 
 
321
288
    /* Set song information for current subtune */
322
289
    XSDEBUG("foobar #1\n");
323
290
    xs_status.sidPlayer->plrUpdateSIDInfo(&xs_status);
324
 
    XS_MUTEX_UNLOCK(xs_status);
325
291
    tmpTuple = aud_tuple_new_from_filename(tmpTune->sidFilename);
326
292
    xs_get_song_tuple_info(tmpTuple, tmpTune, xs_status.currSong);
 
293
    XS_MUTEX_UNLOCK(xs_status);
 
294
    pb->set_tuple(pb, tmpTuple);
 
295
    pb->set_params(pb, NULL, 0, -1, xs_status.audioFrequency, xs_status.audioChannels);
 
296
    pb->set_pb_ready(pb);
327
297
 
328
 
    tmpTitle = aud_tuple_formatter_process_string(tmpTuple,
329
 
        xs_cfg.titleOverride ? xs_cfg.titleFormat : aud_get_gentitle_format());
330
 
    
331
 
    XSDEBUG("foobar #4\n");
332
 
    XS_MUTEX_LOCK(xs_status);
333
 
    pb->set_params(pb,
334
 
        tmpTitle,
335
 
        (tmpLength > 0) ? (tmpLength * 1000) : 0,
336
 
        -1,
337
 
        xs_status.audioFrequency,
338
 
        xs_status.audioChannels);
339
 
        
340
 
    g_free(tmpTitle);
341
 
    
342
298
    XS_MUTEX_UNLOCK(xs_status);
343
299
    XSDEBUG("playing\n");
344
300
    while (pb->playing) {
345
301
        /* Render audio data */
346
 
        XS_MUTEX_LOCK(xs_status);
347
302
        if (xs_status.oversampleEnable) {
348
303
            /* Perform oversampled rendering */
349
 
            audioGot = xs_status.sidPlayer->plrFillBuffer(
 
304
            bufRemaining = xs_status.sidPlayer->plrFillBuffer(
350
305
                &xs_status,
351
306
                oversampleBuffer,
352
 
                (XS_AUDIOBUF_SIZE * xs_status.oversampleFactor));
 
307
                (audioBufSize * xs_status.oversampleFactor));
353
308
 
354
 
            audioGot /= xs_status.oversampleFactor;
 
309
            bufRemaining /= xs_status.oversampleFactor;
355
310
 
356
311
            /* Execute rate-conversion with filtering */
357
312
            if (xs_filter_rateconv(audioBuffer, oversampleBuffer,
358
 
                xs_status.audioFormat, xs_status.oversampleFactor, audioGot) < 0) {
 
313
                xs_status.audioFormat, xs_status.oversampleFactor, bufRemaining) < 0) {
359
314
                xs_error("Oversampling rate-conversion pass failed.\n");
360
315
                pb->error = TRUE;
361
 
                XS_MUTEX_UNLOCK(xs_status);
362
316
                goto xs_err_exit;
363
317
            }
364
318
        } else {
365
 
            audioGot = xs_status.sidPlayer->plrFillBuffer(
366
 
                &xs_status, audioBuffer, XS_AUDIOBUF_SIZE);
 
319
            bufRemaining = xs_status.sidPlayer->plrFillBuffer(
 
320
                &xs_status, audioBuffer, audioBufSize);
367
321
        }
368
322
 
369
323
        /* I <3 visualice/haujobb */
370
 
        pb->pass_audio(pb, xs_status.audioFormat, xs_status.audioChannels,
371
 
            audioGot, audioBuffer, NULL);
372
 
        
373
 
        XS_MUTEX_UNLOCK(xs_status);
 
324
        bufPointer = audioBuffer;
 
325
        while (bufRemaining > 0 && pb->playing) {
 
326
            gint blockSize = MIN(bufChunkSize, bufRemaining);
 
327
            
 
328
            pb->pass_audio(pb, xs_status.audioFormat,
 
329
                xs_status.audioChannels,
 
330
                blockSize, bufPointer, NULL);
374
331
 
375
 
        /* Wait a little */
376
 
        while (pb->playing && pb->output->buffer_free() < audioGot)
377
 
            g_usleep(500);
 
332
            bufPointer += blockSize;
 
333
            bufRemaining -= blockSize;
 
334
        }
378
335
 
379
336
        /* Check if we have played enough */
380
 
        XS_MUTEX_LOCK(xs_status);
381
337
        if (xs_cfg.playMaxTimeEnable) {
382
338
            if (xs_cfg.playMaxTimeUnknown) {
383
339
                if (tmpLength < 0 &&
384
 
                    pb->output->output_time() >= xs_cfg.playMaxTime * 1000) {
 
340
                    pb->output->written_time() >= xs_cfg.playMaxTime * 1000)
385
341
                    pb->playing = FALSE;
386
 
                    xs_status.isPlaying = FALSE;
387
 
                    pb->eof = TRUE;
388
 
                }
389
342
            } else {
390
 
                if (pb->output->output_time() >= xs_cfg.playMaxTime * 1000) {
 
343
                if (pb->output->written_time() >= xs_cfg.playMaxTime * 1000)
391
344
                    pb->playing = FALSE;
392
 
                    xs_status.isPlaying = FALSE;
393
 
                    pb->eof = TRUE;
394
 
                }
395
345
            }
396
346
        }
397
347
 
398
348
        if (tmpLength >= 0) {
399
 
            if (pb->output->output_time() >= tmpLength * 1000) {
 
349
            if (pb->output->written_time() >= tmpLength * 1000)
400
350
                pb->playing = FALSE;
401
 
                xs_status.isPlaying = FALSE;
402
 
                pb->eof = TRUE;
403
 
            }
404
351
        }
405
 
        XS_MUTEX_UNLOCK(xs_status);
406
352
    }
407
353
 
408
354
xs_err_exit:
409
355
    XSDEBUG("out of playing loop\n");
410
 
    
 
356
 
411
357
    /* Close audio output plugin */
412
358
    if (audioOpen) {
413
359
        XSDEBUG("close audio #2\n");
425
371
     */
426
372
    XS_MUTEX_LOCK(xs_status);
427
373
    pb->playing = FALSE;
428
 
    xs_status.isPlaying = FALSE;
429
374
    pb->eof = TRUE;
 
375
 
 
376
    /* Free tune information */
 
377
    xs_status.sidPlayer->plrDeleteSID(&xs_status);
 
378
    xs_tuneinfo_free(xs_status.tuneInfo);
 
379
    xs_status.tuneInfo = NULL;
430
380
    XS_MUTEX_UNLOCK(xs_status);
431
381
 
432
382
    /* Exit the playing thread */
446
396
 */
447
397
void xs_stop(InputPlayback *pb)
448
398
{
449
 
    (void) pb;
450
 
    
451
399
    XSDEBUG("stop requested\n");
452
400
 
453
401
    /* Lock xs_status and stop playing thread */
455
403
    if (pb != NULL && pb->playing) {
456
404
        XSDEBUG("stopping...\n");
457
405
        pb->playing = FALSE;
458
 
        xs_status.isPlaying = FALSE;
459
406
        XS_MUTEX_UNLOCK(xs_status);
460
 
        XS_THREAD_JOIN(xs_decode_thread);
461
407
    } else {
462
408
        XS_MUTEX_UNLOCK(xs_status);
463
409
    }
464
410
 
465
 
    XSDEBUG("done, updating status\n");
466
 
    
467
 
    /* Free tune information */
468
 
    XS_MUTEX_LOCK(xs_status);
469
 
    xs_status.sidPlayer->plrDeleteSID(&xs_status);
470
 
    xs_tuneinfo_free(xs_status.tuneInfo);
471
 
    xs_status.tuneInfo = NULL;
472
 
    XS_MUTEX_UNLOCK(xs_status);
473
411
    XSDEBUG("ok\n");
474
412
}
475
413
 
479
417
 */
480
418
void xs_pause(InputPlayback *pb, short pauseState)
481
419
{
 
420
    XS_MUTEX_LOCK(xs_status);
482
421
    pb->output->pause(pauseState);
 
422
    XS_MUTEX_UNLOCK(xs_status);
483
423
}
484
424
 
485
425
 
493
433
 
494
434
 
495
435
/*
496
 
 * Return the playing "position/time"
497
 
 * Determine current position/time in song. Used by XMMS to update
498
 
 * the song clock and position slider and MOST importantly to determine
499
 
 * END OF SONG! Return value of -2 means error, XMMS opens an audio
500
 
 * error dialog. -1 means end of song (if one was playing currently).
501
 
 */
502
 
gint xs_get_time(InputPlayback *pb)
503
 
{
504
 
    /* If errorflag is set, return -2 to signal it to XMMS's idle callback */
505
 
    XS_MUTEX_LOCK(xs_status);
506
 
    if (pb->error) {
507
 
        XS_MUTEX_UNLOCK(xs_status);
508
 
        return -2;
509
 
    }
510
 
 
511
 
    /* If there is no tune, return -1 */
512
 
    if (!xs_status.tuneInfo) {
513
 
        XS_MUTEX_UNLOCK(xs_status);
514
 
        return -1;
515
 
    }
516
 
 
517
 
    /* If tune has ended, return -1 */
518
 
    if (!pb->playing) {
519
 
        XS_MUTEX_UNLOCK(xs_status);
520
 
        return -1;
521
 
    }
522
 
 
523
 
    XS_MUTEX_UNLOCK(xs_status);
524
 
 
525
 
    /* Return output time reported by audio output plugin */
526
 
    return pb->output->output_time();
527
 
}
528
 
 
529
 
 
530
 
/*
531
436
 * Return song information Tuple
532
437
 */
533
 
static void xs_get_song_tuple_info(Tuple *pResult, xs_tuneinfo_t *pInfo, gint subTune)
 
438
static void xs_get_song_tuple_info(Tuple *tuple, xs_tuneinfo_t *info, gint subTune)
534
439
{
535
440
    gchar *tmpStr, tmpStr2[64];
536
441
 
537
 
    aud_tuple_associate_string(pResult, FIELD_TITLE, NULL, pInfo->sidName);
538
 
    aud_tuple_associate_string(pResult, FIELD_ARTIST, NULL, pInfo->sidComposer);
539
 
    aud_tuple_associate_string(pResult, FIELD_GENRE, NULL, "SID-tune");
540
 
    aud_tuple_associate_string(pResult, FIELD_COPYRIGHT, NULL, pInfo->sidCopyright);
541
 
    aud_tuple_associate_string(pResult, -1, "sid-format", pInfo->sidFormat);
 
442
    aud_tuple_associate_string_rel(tuple, FIELD_TITLE, NULL, aud_str_to_utf8(info->sidName));
 
443
    aud_tuple_associate_string_rel(tuple, FIELD_ARTIST, NULL, aud_str_to_utf8(info->sidComposer));
 
444
    aud_tuple_associate_string_rel(tuple, FIELD_COPYRIGHT, NULL, aud_str_to_utf8(info->sidCopyright));
 
445
    aud_tuple_associate_string(tuple, -1, "sid-format", info->sidFormat);
 
446
    aud_tuple_associate_string(tuple, FIELD_CODEC, NULL, "Commodore 64 SID PlaySID/RSID");
542
447
 
543
 
    switch (pInfo->sidModel) {
 
448
    switch (info->sidModel) {
544
449
        case XS_SIDMODEL_6581: tmpStr = "6581"; break;
545
450
        case XS_SIDMODEL_8580: tmpStr = "8580"; break;
546
451
        case XS_SIDMODEL_ANY: tmpStr = "ANY"; break;
547
452
        default: tmpStr = "?"; break;
548
453
    }
549
 
    aud_tuple_associate_string(pResult, -1, "sid-model", tmpStr);
550
 
    
 
454
    aud_tuple_associate_string(tuple, -1, "sid-model", tmpStr);
 
455
 
551
456
    /* Get sub-tune information, if available */
552
 
    if (subTune < 0 || pInfo->startTune > pInfo->nsubTunes)
553
 
        subTune = pInfo->startTune;
554
 
    
555
 
    if ((subTune > 0) && (subTune <= pInfo->nsubTunes)) {
556
 
        gint tmpInt = pInfo->subTunes[subTune - 1].tuneLength;
557
 
        aud_tuple_associate_int(pResult, FIELD_LENGTH, NULL, (tmpInt < 0) ? -1 : tmpInt * 1000);
558
 
        
559
 
        tmpInt = pInfo->subTunes[subTune - 1].tuneSpeed;
 
457
    if (subTune < 0 || info->startTune > info->nsubTunes)
 
458
        subTune = info->startTune;
 
459
 
 
460
    if (subTune > 0 && subTune <= info->nsubTunes) {
 
461
        gint tmpInt = info->subTunes[subTune - 1].tuneLength;
 
462
        aud_tuple_associate_int(tuple, FIELD_LENGTH, NULL, (tmpInt < 0) ? -1 : tmpInt * 1000);
 
463
 
 
464
        tmpInt = info->subTunes[subTune - 1].tuneSpeed;
560
465
        if (tmpInt > 0) {
561
466
            switch (tmpInt) {
562
467
            case XS_CLOCK_PAL: tmpStr = "PAL"; break;
572
477
        } else
573
478
            tmpStr = "?";
574
479
 
575
 
        aud_tuple_associate_string(pResult, -1, "sid-speed", tmpStr);
 
480
        aud_tuple_associate_string(tuple, -1, "sid-speed", tmpStr);
576
481
    } else
577
482
        subTune = 1;
578
 
    
579
 
    aud_tuple_associate_int(pResult, FIELD_SUBSONG_NUM, NULL, pInfo->nsubTunes);
580
 
    aud_tuple_associate_int(pResult, FIELD_SUBSONG_ID, NULL, subTune);
581
 
    aud_tuple_associate_int(pResult, FIELD_TRACK_NUMBER, NULL, subTune);
 
483
 
 
484
    aud_tuple_associate_int(tuple, FIELD_SUBSONG_NUM, NULL, info->nsubTunes);
 
485
    aud_tuple_associate_int(tuple, FIELD_SUBSONG_ID, NULL, subTune);
 
486
    aud_tuple_associate_int(tuple, FIELD_TRACK_NUMBER, NULL, subTune);
582
487
 
583
488
    if (xs_cfg.titleOverride)
584
 
        aud_tuple_associate_string(pResult, FIELD_FORMATTER, NULL, xs_cfg.titleFormat);
585
 
}
586
 
 
587
 
 
588
 
Tuple * xs_get_song_tuple(gchar *filename)
589
 
{
590
 
    Tuple *result;
 
489
        aud_tuple_associate_string(tuple, FIELD_FORMATTER, NULL, xs_cfg.titleFormat);
 
490
}
 
491
 
 
492
 
 
493
static void xs_fill_subtunes(Tuple *tuple, xs_tuneinfo_t *info)
 
494
{
 
495
    gint count, found;
 
496
    
 
497
    tuple->subtunes = g_new(gint, info->nsubTunes);
 
498
    
 
499
    for (found = count = 0; count < info->nsubTunes; count++) {
 
500
        if (count + 1 == info->startTune || !xs_cfg.subAutoMinOnly ||
 
501
            info->subTunes[count].tuneLength >= xs_cfg.subAutoMinTime)
 
502
            tuple->subtunes[found++] = count + 1;
 
503
    }
 
504
 
 
505
    tuple->nsubtunes = found;
 
506
}
 
507
 
 
508
 
 
509
Tuple * xs_get_song_tuple(const gchar *filename)
 
510
{
 
511
    Tuple *tuple;
591
512
    gchar *tmpFilename;
592
 
    xs_tuneinfo_t *tmpInfo;
593
 
    gint tmpTune;
 
513
    xs_tuneinfo_t *info;
 
514
    gint tune = -1;
594
515
 
595
516
    /* Get information from URL */
596
 
    xs_get_trackinfo(filename, &tmpFilename, &tmpTune);
 
517
    tmpFilename = aud_filename_split_subtune(filename, &tune);
 
518
    if (tmpFilename == NULL) return NULL;
597
519
 
598
 
    result = aud_tuple_new_from_filename(tmpFilename);
599
 
    if (!result) {
 
520
    tuple = aud_tuple_new_from_filename(tmpFilename);
 
521
    if (tuple == NULL) {
600
522
        g_free(tmpFilename);
601
523
        return NULL;
602
524
    }
603
525
 
 
526
    if (xs_status.sidPlayer == NULL)
 
527
        return tuple;
 
528
 
604
529
    /* Get tune information from emulation engine */
605
530
    XS_MUTEX_LOCK(xs_status);
606
 
    tmpInfo = xs_status.sidPlayer->plrGetSIDInfo(tmpFilename);
 
531
    info = xs_status.sidPlayer->plrGetSIDInfo(tmpFilename);
607
532
    XS_MUTEX_UNLOCK(xs_status);
608
533
    g_free(tmpFilename);
609
534
 
610
 
    if (!tmpInfo)
611
 
        return result;
612
 
    
613
 
    xs_get_song_tuple_info(result, tmpInfo, tmpTune);
614
 
    xs_tuneinfo_free(tmpInfo);
615
 
 
616
 
    return result;
 
535
    if (info == NULL)
 
536
        return tuple;
 
537
 
 
538
    xs_get_song_tuple_info(tuple, info, tune);
 
539
 
 
540
    if (xs_cfg.subAutoEnable && info->nsubTunes > 1 && tune < 0)
 
541
        xs_fill_subtunes(tuple, info);
 
542
 
 
543
    xs_tuneinfo_free(info);
 
544
 
 
545
    return tuple;
617
546
}
618
547
 
619
548
 
620
 
Tuple *xs_probe_for_tuple(gchar *filename, xs_file_t *fd)
 
549
Tuple * xs_probe_for_tuple(const gchar *filename, xs_file_t *fd)
621
550
{
622
 
    Tuple *result;
 
551
    Tuple *tuple;
623
552
    gchar *tmpFilename;
624
 
    xs_tuneinfo_t *tmpInfo;
625
 
    gint tmpTune;
626
 
 
627
 
    assert(xs_status.sidPlayer != NULL);
628
 
 
629
 
    if (filename == NULL)
 
553
    xs_tuneinfo_t *info;
 
554
    gint tune = -1;
 
555
 
 
556
    if (xs_status.sidPlayer == NULL || filename == NULL)
630
557
        return NULL;
631
558
 
632
559
    XS_MUTEX_LOCK(xs_status);
636
563
    }
637
564
    XS_MUTEX_UNLOCK(xs_status);
638
565
 
639
 
 
640
566
    /* Get information from URL */
641
 
    xs_get_trackinfo(filename, &tmpFilename, &tmpTune);
642
 
    result = aud_tuple_new_from_filename(tmpFilename);
643
 
    if (!result) {
 
567
    tmpFilename = aud_filename_split_subtune(filename, &tune);
 
568
    if (tmpFilename == NULL) return NULL;
 
569
 
 
570
    tuple = aud_tuple_new_from_filename(tmpFilename);
 
571
    if (tuple == NULL) {
644
572
        g_free(tmpFilename);
645
573
        return NULL;
646
574
    }
647
575
 
648
576
    /* Get tune information from emulation engine */
649
577
    XS_MUTEX_LOCK(xs_status);
650
 
    tmpInfo = xs_status.sidPlayer->plrGetSIDInfo(tmpFilename);
 
578
    info = xs_status.sidPlayer->plrGetSIDInfo(tmpFilename);
651
579
    XS_MUTEX_UNLOCK(xs_status);
652
580
    g_free(tmpFilename);
653
581
 
654
 
    if (!tmpInfo)
655
 
        return result;
656
 
    
657
 
    xs_get_song_tuple_info(result, tmpInfo, tmpTune);
658
 
 
659
 
    /* Set subtunes */
660
 
    if (xs_cfg.subAutoEnable && tmpInfo->nsubTunes > 1 && tmpTune < 0) {
661
 
        gint i, n;
662
 
        result->subtunes = g_new(gint, tmpInfo->nsubTunes);
663
 
        for (n = 0, i = 1; i <= tmpInfo->nsubTunes; i++) {
664
 
            gboolean doAdd = FALSE;
665
 
                    
666
 
            if (xs_cfg.subAutoMinOnly) {
667
 
                if (i == tmpInfo->startTune ||
668
 
                    tmpInfo->subTunes[i - 1].tuneLength >= xs_cfg.subAutoMinTime)
669
 
                    doAdd = TRUE;
670
 
            } else
671
 
                doAdd = TRUE;
672
 
                    
673
 
            if (doAdd) result->subtunes[n++] = i;
674
 
        }
675
 
        result->nsubtunes = n;
676
 
    } else
677
 
        result->nsubtunes = 0;
678
 
    
679
 
    xs_tuneinfo_free(tmpInfo);
680
 
 
681
 
    return result;
 
582
    if (info == NULL)
 
583
        return tuple;
 
584
 
 
585
    xs_get_song_tuple_info(tuple, info, tune);
 
586
 
 
587
    if (xs_cfg.subAutoEnable && info->nsubTunes > 1 && tune < 0)
 
588
        xs_fill_subtunes(tuple, info);
 
589
 
 
590
    xs_tuneinfo_free(info);
 
591
 
 
592
    return tuple;
682
593
}