changeset 862:011ba70e271e

Major cleanups, make SIDPlayFP backend compile with libSIDPlayFP v1.0.0 alphas .. does not work for some reason yet, though. (Only plays silence.)
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 09 Nov 2012 02:11:21 +0200
parents c6cf203be443
children fa926296e161
files Makefile.am src/xs_sidplay.h src/xs_sidplay1.cpp src/xs_sidplay2.cpp src/xs_sidplayfp.cpp
diffstat 5 files changed, 358 insertions(+), 234 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.am	Fri Nov 09 00:19:21 2012 +0200
+++ b/Makefile.am	Fri Nov 09 02:11:21 2012 +0200
@@ -107,13 +107,13 @@
 	@XMMS_LIBS@ @SIDPLAY1_LIBS@ @SIDPLAY2_LIBS@ @BUILDERS_LIBS@ @SIDPLAYFP_LIBS@
 
 # Backend interface sources
-libxs_sidplay1_la_SOURCES = src/xmms-sid.h src/xs_player.h src/xs_sidplay.h src/xs_sidplay1.cpp src/xs_sidplay1.h
+libxs_sidplay1_la_SOURCES = src/xmms-sid.h src/xs_player.h src/xs_sidplay1.cpp src/xs_sidplay1.h
 libxs_sidplay1_la_CFLAGS = @SIDPLAY1_CFLAGS@
 
-libxs_sidplay2_la_SOURCES = src/xmms-sid.h src/xs_player.h src/xs_sidplay.h src/xs_sidplay2.cpp src/xs_sidplay2.h
+libxs_sidplay2_la_SOURCES = src/xmms-sid.h src/xs_player.h src/xs_sidplay2.cpp src/xs_sidplay2.h
 libxs_sidplay2_la_CFLAGS = @SIDPLAY2_CFLAGS@ @BUILDERS_CFLAGS@
 
-libxs_sidplayfp_la_SOURCES = src/xmms-sid.h src/xs_player.h src/xs_sidplay.h src/xs_sidplayfp.cpp src/xs_sidplayfp.h
+libxs_sidplayfp_la_SOURCES = src/xmms-sid.h src/xs_player.h src/xs_sidplayfp.cpp src/xs_sidplayfp.h
 libxs_sidplayfp_la_CFLAGS = @SIDPLAYFP_CFLAGS@
 
 # Plugin sources
--- a/src/xs_sidplay.h	Fri Nov 09 00:19:21 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-/*
-   XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS)
-
-   libSIDPlay skeleton functions used both by v1 and 2 of the backends
-
-   Programmed and designed by Matti 'ccr' Hamalainen <ccr@tnsp.org>
-   (C) Copyright 2005-2009 Tecnic Software productions (TNSP)
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License along
-   with this program; if not, write to the Free Software Foundation, Inc.,
-   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-
-/* This function gets most of the information, though we do miss some
- * (those variables that are only set by libSIDPlay when tune is initialized).
- * Rest of the information is acquired in TFUNCTION2()
- */
-XSTuneInfo *TFUNCTION(const gchar *filename)
-{
-    XSTuneInfo *res;
-    TTUNEINFO info;
-    TTUNE *tune;
-
-    /* Check if the tune exists and is readable */
-    if ((tune = new TTUNE(filename)) == NULL)
-    {
-        XSDEBUG("could not initialize tune from '%s'.\n", filename);
-        return NULL;
-    }
-
-    if (!tune->getStatus())
-    {
-        XSDEBUG("tune->getStatus() returned false for '%s'.\n", filename);
-        delete tune;
-        return NULL;
-    }
-
-    /* Get general tune information */
-#if defined(XS_SIDPLAY1_H)
-    tune->getInfo(info);
-#elif defined(XS_SIDPLAY2_H)
-    info = tune->getInfo();
-#elif defined(XS_SIDPLAYFP_H)
-    info = tune->getInfo();
-#endif
-
-    /* Allocate tuneinfo structure and set information */
-    res = xs_tuneinfo_new(filename,
-        info.songs, info.startSong,
-        info.infoString[0], info.infoString[1], info.infoString[2],
-        info.loadAddr, info.initAddr, info.playAddr,
-        info.dataFileLen, info.formatString,
-#if defined(XS_SIDPLAYFP_H) && defined(HAVE_SIDPLAYFP)
-        info.sidModel1
-#else
-        info.sidModel
-#endif
-        );
-    
-    /* NOTICE! libSIDPlay[12] headers specifically state that sidModel,
-     * songSpeed and clockSpeed are "undefined" before song initialization,
-     * but in practice sidModel is known after getInfo() invocation...
-     * This of course does not take the sub-tune specific changes into account,
-     * but at least we have a reasonable guesstimate.
-     */
-
-    delete tune;
-
-    return res;
-}
-
-
-/* Updates the information of currently playing tune
- */
-gboolean TFUNCTION2(XSEngineState *state)
-{
-    TTUNEINFO info;
-    TENGINE *engine;
-    
-    /* Check if we have required structures initialized */
-    if (!state || !state->tuneInfo || !state->internal)
-        return FALSE;
-
-    engine = (TENGINE *) state->internal;
-    if (!(engine->tune))
-        return FALSE;
-
-    /* Get currently playing tune information */
-#if defined(XS_SIDPLAY1_H)
-    engine->tune->getInfo(info);
-#elif defined(XS_SIDPLAY2_H)
-    info = engine->tune.getInfo();
-#elif defined(XS_SIDPLAYFP_H)
-    info = engine->tune.getInfo();
-#endif
-
-    /* NOTICE! Here we assume that libSIDPlay[12] headers define
-     * SIDTUNE_SIDMODEL_* similarly to our enums in xs_config.h ...
-     */
-#if defined(XS_SIDPLAYFP_H) && defined(HAVE_SIDPLAYFP)
-    state->tuneInfo->sidModel = info.sidModel1;
-#else
-    state->tuneInfo->sidModel = info.sidModel;
-#endif
-
-    if (state->currSong > 0 && state->currSong <= state->tuneInfo->nsubTunes)
-    {
-        gint tmpSpeed = -1;
-        
-        switch (info.clockSpeed)
-        {
-            case SIDTUNE_CLOCK_PAL:
-                tmpSpeed = XS_CLOCK_PAL;
-                break;
-            case SIDTUNE_CLOCK_NTSC:
-                tmpSpeed = XS_CLOCK_NTSC;
-                break;
-            case SIDTUNE_CLOCK_ANY:
-                tmpSpeed = XS_CLOCK_ANY;
-                break;
-            case SIDTUNE_CLOCK_UNKNOWN:
-                switch (info.songSpeed)
-                {
-                    case SIDTUNE_SPEED_VBI:
-                        tmpSpeed = XS_CLOCK_VBI;
-                        break;
-                    case SIDTUNE_SPEED_CIA_1A:
-                        tmpSpeed = XS_CLOCK_CIA;
-                        break;
-                    default:
-                        tmpSpeed = info.songSpeed;
-                        break;
-                }
-            default:
-                tmpSpeed = info.clockSpeed;
-                break;
-        }
-            
-        state->tuneInfo->subTunes[state->currSong - 1].tuneSpeed = tmpSpeed;
-    }
-
-    return TRUE;
-}
-
-/* Undefine these */
-#undef TFUNCTION
-#undef TFUNCTION2
-#undef TTUNEINFO
-#undef TTUNE
--- a/src/xs_sidplay1.cpp	Fri Nov 09 00:19:21 2012 +0200
+++ b/src/xs_sidplay1.cpp	Fri Nov 09 02:11:21 2012 +0200
@@ -41,8 +41,6 @@
     emuEngine *emu;
     emuConfig currConfig;
     sidTune *tune;
-    guint8 *buf;
-    size_t bufSize;
 } XSSIDPlay1;
 
 
@@ -50,16 +48,6 @@
 extern "C" {
 
 
-/* Return song information
- */
-#define TFUNCTION   xs_sidplay1_getinfo
-#define TFUNCTION2  xs_sidplay1_updateinfo
-#define TTUNEINFO   sidTuneInfo
-#define TTUNE       sidTune
-#define TENGINE     XSSIDPlay1
-#include "xs_sidplay.h"
-
-
 /* Check if we can play the given file
  */
 gboolean xs_sidplay1_probe(XSFile *f)
@@ -337,15 +325,13 @@
     assert(state);
 
     engine = (XSSIDPlay1 *) state->internal;
-    if (!engine) return FALSE;
+    if (!engine)
+        return FALSE;
 
-    /* Try to get the tune */
-    if (!filename) return FALSE;
-    
-    if (xs_fload_buffer(filename, &(engine->buf), &(engine->bufSize)) != 0)
+    if (!filename)
         return FALSE;
     
-    if (!engine->tune->load(engine->buf, engine->bufSize))
+    if (!engine->tune->open(filename))
         return FALSE;
 
     return TRUE;
@@ -356,17 +342,96 @@
  */
 void xs_sidplay1_delete(XSEngineState * state)
 {
-    XSSIDPlay1 *engine;
-    assert(state);
+    (void) state;
+}
+
+
+/* This function gets most of the information, though we do miss some
+ * (those variables that are only set by libSIDPlay when tune is initialized).
+ * Rest of the information is acquired in xs_sidplay1_updateinfo()
+ */
+XSTuneInfo *xs_sidplay1_getinfo(const gchar *filename)
+{
+    XSTuneInfo *res;
+    sidTune *tune;
+    sidTuneInfo info;
+
+    /* Check if the tune exists and is readable */
+    if ((tune = new sidTune(filename)) == NULL)
+    {
+        XSDEBUG("could not initialize tune from '%s'.\n", filename);
+        return NULL;
+    }
 
-    engine = (XSSIDPlay1 *) state->internal;
-    if (!engine) return;
+    if (!tune->getStatus())
+    {
+        XSDEBUG("tune->getStatus() returned false for '%s'.\n", filename);
+        delete tune;
+        return NULL;
+    }
+
+    /* Get general tune information */
+    tune->getInfo(info);
+
+    /* Allocate tuneinfo structure and set information */
+    res = xs_tuneinfo_new(filename,
+        info.songs, info.startSong,
+        info.infoString[0], info.infoString[1], info.infoString[2],
+        info.loadAddr, info.initAddr, info.playAddr,
+        info.dataFileLen, info.formatString,
+        info.sidModel
+        );
     
-    g_free(engine->buf);
-    engine->buf = NULL;
-    engine->bufSize = 0;
+    delete tune;
+    return res;
 }
 
 
+/* Updates the information of currently playing tune
+ */
+gboolean xs_sidplay1_updateinfo(XSEngineState *state)
+{
+    XSSIDPlay1 *engine;
+    sidTuneInfo info;
+    
+    /* Check if we have required structures initialized */
+    if (!state || !state->tuneInfo || !state->internal)
+        return FALSE;
+
+    engine = (XSSIDPlay1 *) state->internal;
+    if (!(engine->tune))
+        return FALSE;
+
+    /* Get general tune information */
+    engine->tune->getInfo(info);
+
+    /* NOTICE! Here we assume that libSIDPlay[12] headers define
+     * SIDTUNE_SIDMODEL_* similarly to our enums in xs_config.h ...
+     */
+    state->tuneInfo->sidModel = info.sidModel;
+
+    if (state->currSong > 0 && state->currSong <= state->tuneInfo->nsubTunes)
+    {
+        gint tmpSpeed = info.clockSpeed;
+        switch (info.clockSpeed)
+        {
+            case SIDTUNE_CLOCK_PAL:      tmpSpeed = XS_CLOCK_PAL; break;
+            case SIDTUNE_CLOCK_NTSC:     tmpSpeed = XS_CLOCK_NTSC; break;
+            case SIDTUNE_CLOCK_ANY:      tmpSpeed = XS_CLOCK_ANY; break;
+            case SIDTUNE_CLOCK_UNKNOWN:
+                switch (info.songSpeed)
+                {
+                    case SIDTUNE_SPEED_VBI:      tmpSpeed = XS_CLOCK_VBI; break;
+                    case SIDTUNE_SPEED_CIA_1A:   tmpSpeed = XS_CLOCK_CIA; break;
+                    default:                     tmpSpeed = info.songSpeed; break;
+                }
+                break;
+        }
+        state->tuneInfo->subTunes[state->currSong - 1].tuneSpeed = tmpSpeed;
+    }
+
+    return TRUE;
+}
+
 }    /* extern "C" */
 #endif    /* HAVE_SIDPLAY1 */
--- a/src/xs_sidplay2.cpp	Fri Nov 09 00:19:21 2012 +0200
+++ b/src/xs_sidplay2.cpp	Fri Nov 09 02:11:21 2012 +0200
@@ -75,16 +75,6 @@
 extern "C" {
 
 
-/* Return song information
- */
-#define TFUNCTION   xs_sidplay2_getinfo
-#define TFUNCTION2  xs_sidplay2_updateinfo
-#define TENGINE     XSSIDPlay2
-#define TTUNEINFO   SidTuneInfo
-#define TTUNE       SidTune
-#include "xs_sidplay.h"
-
-
 /* Check if we can play the given file
  */
 gboolean xs_sidplay2_probe(XSFile *f)
@@ -445,6 +435,94 @@
 }
 
 
+/* This function gets most of the information, though we do miss some
+ * (those variables that are only set by libSIDPlay when tune is initialized).
+ * Rest of the information is acquired in xs_sidplay2_updateinfo()
+ */
+XSTuneInfo *xs_sidplay2_getinfo(const gchar *filename)
+{
+    XSTuneInfo *res;
+    SidTune *tune;
+    SidTuneInfo info;
+
+    /* Check if the tune exists and is readable */
+    if ((tune = new SidTune(filename)) == NULL)
+    {
+        XSDEBUG("could not initialize tune from '%s'.\n", filename);
+        return NULL;
+    }
+
+    if (!tune->getStatus())
+    {
+        XSDEBUG("tune->getStatus() returned false for '%s'.\n", filename);
+        delete tune;
+        return NULL;
+    }
+
+    /* Get general tune information */
+    tune->getInfo(info);
+
+    /* Allocate tuneinfo structure and set information */
+    res = xs_tuneinfo_new(filename,
+        info.songs, info.startSong,
+        info.infoString[0], info.infoString[1], info.infoString[2],
+        info.loadAddr, info.initAddr, info.playAddr,
+        info.dataFileLen, info.formatString,
+        info.sidModel
+        );
+    
+    delete tune;
+    return res;
+}
+
+
+/* Updates the information of currently playing tune
+ */
+gboolean xs_sidplay2_updateinfo(XSEngineState *state)
+{
+    XSSIDPlay2 *engine;
+    SidTuneInfo info;
+    
+    /* Check if we have required structures initialized */
+    if (!state || !state->tuneInfo || !state->internal)
+        return FALSE;
+
+    engine = (XSSIDPlay2 *) state->internal;
+    if (!(engine->tune))
+        return FALSE;
+
+    /* Get general tune information */
+    engine->tune.getInfo(info);
+
+    /* NOTICE! Here we assume that libSIDPlay[12] headers define
+     * SIDTUNE_SIDMODEL_* similarly to our enums in xs_config.h ...
+     */
+    state->tuneInfo->sidModel = info.sidModel;
+
+    if (state->currSong > 0 && state->currSong <= state->tuneInfo->nsubTunes)
+    {
+        gint tmpSpeed = info.clockSpeed;
+        switch (info.clockSpeed)
+        {
+            case SIDTUNE_CLOCK_PAL:      tmpSpeed = XS_CLOCK_PAL; break;
+            case SIDTUNE_CLOCK_NTSC:     tmpSpeed = XS_CLOCK_NTSC; break;
+            case SIDTUNE_CLOCK_ANY:      tmpSpeed = XS_CLOCK_ANY; break;
+            case SIDTUNE_CLOCK_UNKNOWN:
+                switch (info.songSpeed)
+                {
+                    case SIDTUNE_SPEED_VBI:      tmpSpeed = XS_CLOCK_VBI; break;
+                    case SIDTUNE_SPEED_CIA_1A:   tmpSpeed = XS_CLOCK_CIA; break;
+                    default:                     tmpSpeed = info.songSpeed; break;
+                }
+                break;
+        }
+        state->tuneInfo->subTunes[state->currSong - 1].tuneSpeed = tmpSpeed;
+    }
+
+    return TRUE;
+}
+
+
 }    /* extern "C" */
 #endif    /* HAVE_SIDPLAY2
  */
--- a/src/xs_sidplayfp.cpp	Fri Nov 09 00:19:21 2012 +0200
+++ b/src/xs_sidplayfp.cpp	Fri Nov 09 02:11:21 2012 +0200
@@ -34,7 +34,7 @@
 #  include <sidplayfp/sidplayfp.h>
 #  include <sidplayfp/event.h>
 #  include <sidplayfp/SidConfig.h>
-#  include <sidplayfp/SidTuneInfo.h>
+#  include <sidplayfp/SidInfo.h>
 #else
 #  include <sidplayfp/sidplay2.h>
 #  include <sidplayfp/SidTuneMod.h>
@@ -51,7 +51,7 @@
     sidplay2 emu;
     sid2_config_t config;
 #endif
-    SidTuneMod tune;
+    SidTune tune;
 
     XSSIDPlayFP(void);
     virtual ~XSSIDPlayFP(void);
@@ -73,6 +73,7 @@
 
 XSSIDPlayFP::XSSIDPlayFP(void) : tune(0)
 {
+    emu.load(NULL);
 }
 
 
@@ -88,19 +89,19 @@
 
 /* Return song information
  */
-#define TFUNCTION              xs_sidplayfp_getinfo
-#define TFUNCTION2             xs_sidplayfp_updateinfo
-#define TENGINE                XSSIDPlayFP
-#define TTUNEINFO              SidTuneInfo
-#define TTUNE                  SidTune
-
 #ifdef HAVE_SIDPLAYFP_V1
 #define sid2_mono              SidConfig::MONO
 #define sid2_stereo            SidConfig::STEREO
+
+#define SID2_INTERPOLATE       SidConfig::INTERPOLATE
+#define SID2_RESAMPLE_INTERPOLATE SidConfig::RESAMPLE_INTERPOLATE
+
 #define SID2_MOS8580           SidConfig::MOS8580
 #define SID2_MOS6581           SidConfig::MOS6581
+
 #define SID2_CLOCK_PAL         SidConfig::CLOCK_PAL
 #define SID2_CLOCK_NTSC        SidConfig::CLOCK_NTSC
+
 #define SIDTUNE_CLOCK_UNKNOWN  SidTuneInfo::CLOCK_UNKNOWN
 #define SIDTUNE_CLOCK_PAL      SidTuneInfo::CLOCK_PAL
 #define SIDTUNE_CLOCK_NTSC     SidTuneInfo::CLOCK_NTSC
@@ -109,8 +110,6 @@
 #define SIDTUNE_SPEED_CIA_1A   SidTuneInfo::SPEED_CIA_1A
 #endif
 
-#include "xs_sidplay.h"
-
 
 /* Check if we can play the given file
  */
@@ -181,10 +180,12 @@
     engine->config.sidSamples  = TRUE;
     engine->config.sidModel    = xs_cfg.forceModel ? engine->config.sidDefault : SID2_MODEL_CORRECT;
     engine->config.clockSpeed  = xs_cfg.forceSpeed ? engine->config.clockDefault : SID2_CLOCK_CORRECT;
-#endif
 
     /* Initialize builder object */
     XSDEBUG("init builder #%i, maxsids=%i\n", xs_cfg.sid2Builder, (engine->emu.info()).maxsids);
+#else
+    XSDEBUG("init builder #%i, maxsids=%i\n", xs_cfg.sid2Builder, (engine->emu.info()).maxsids());
+#endif
 
     switch (xs_cfg.sid2Builder)
     {
@@ -195,17 +196,21 @@
 #ifdef HAVE_SIDPLAYFP_V1
                 if (rs && rs->getStatus())
                 {
+                    engine->config.sidEmulation = rs;
+                    if (!rs->getStatus()) return FALSE;
+                    rs->create((engine->emu.info()).maxsids());
+                    if (!rs->getStatus()) return FALSE;
                 }
 #else
                 if (rs && *rs)
                 {
                     engine->config.sidEmulation = rs;
-                    if (!(*rs)) return FALSE;
+                    if (!*rs) return FALSE;
                     rs->create((engine->emu.info()).maxsids);
-                    if (!(*rs)) return FALSE;
-                    rs->bias(0.0f);
+                    if (!*rs) return FALSE;
                 }
-#endif // HAVE_SIDPLAYFP_V1
+#endif
+                rs->bias(0.0f);
             }
             break;
 #endif // HAVE_RESID_BUILDER
@@ -215,16 +220,25 @@
         case XS_BLD_RESID_FP:
             {
                 ReSIDfpBuilder *rs = new ReSIDfpBuilder("ReSID builder FP!");
+#ifdef HAVE_SIDPLAYFP_V1
+                if (rs && rs->getStatus())
+                {
+                    engine->config.sidEmulation = rs;
+                    if (!rs->getStatus()) return FALSE;
+                    rs->create((engine->emu.info()).maxsids());
+                    if (!rs->getStatus()) return FALSE;
+                }
+#else
                 if (rs && *rs)
                 {
                     engine->config.sidEmulation = rs;
-                    if (!(*rs)) return FALSE;
+                    if (!*rs) return FALSE;
                     rs->create((engine->emu.info()).maxsids);
-                    if (!(*rs)) return FALSE;
-
-                    rs->filter6581Curve(0.0);
-                    rs->filter8580Curve(0.0);
+                    if (!*rs) return FALSE;
                 }
+#endif
+                rs->filter6581Curve(0.0);
+                rs->filter8580Curve(0.0);
             }
             break;
 #endif
@@ -234,15 +248,19 @@
             {
                 HardSIDBuilder *hs = new HardSIDBuilder("HardSID builder (FP)");
                 engine->config.sidEmulation = (sidbuilder *) hs;
-                if (hs)
+#ifdef HAVE_SIDPLAYFP_V1
+                if (hs && hs->getStatus())
+                {
+                    hs->create((engine->emu.info()).maxsids());
+                    if (!hs->getStatus()) return FALSE;
+                }
+#else
+                if (hs && *hs)
                 {
                     hs->create((engine->emu.info()).maxsids);
-                    if (!*hs)
-                    {
-                        xs_error("hardSID->create() failed.\n");
-                        return FALSE;
-                    }
+                    if (!*hs) return FALSE;
                 }
+#endif
             }
             break;
 #endif
@@ -260,7 +278,11 @@
 
     // Setup filter
     engine->config.sidEmulation->filter(xs_cfg.emulateFilters);
+#ifdef HAVE_SIDPLAYFP_V1
+    if (!engine->config.sidEmulation->getStatus())
+#else
     if (!*(engine->config.sidEmulation))
+#endif
     {
         xs_error("builder->filter(%d) failed.\n", xs_cfg.emulateFilters);
         return FALSE;
@@ -333,14 +355,7 @@
     if (!engine)
         return 0;
 
-#if 1
-    int nsamples = audioBufSize / sizeof(short);
-    return engine->emu.play((short *) audioBuffer, nsamples) * sizeof(short);
-#else
-    int nsamples = audioBufSize / sizeof(short);
-    fprintf(stderr, "%p, %d -> %d\n", audioBuffer, audioBufSize, nsamples);
-    return 0;
-#endif
+    return engine->emu.play((short *) audioBuffer, audioBufSize / sizeof(short)) * sizeof(short);
 }
 
 
@@ -354,10 +369,13 @@
         return FALSE;
     
     engine->tune.load(filename);
+#ifdef HAVE_SIDPLAYFP_V1
+    if (!engine->tune.getStatus())
+#else
     if (!engine->tune)
+#endif
     {
-        xs_error("Could not load file '%s': %s\n",
-            filename, (engine->tune.getInfo()).statusString);
+        xs_error("Could not load file '%s'\n", filename);
         return FALSE;
     }
 
@@ -389,5 +407,128 @@
 }
 
 
+/* This function gets most of the information, though we do miss some
+ * (those variables that are only set by libSIDPlay when tune is initialized).
+ * Rest of the information is acquired in xs_sidplayfp_updateinfo()
+ */
+XSTuneInfo *xs_sidplayfp_getinfo(const gchar *filename)
+{
+    XSTuneInfo *res;
+    SidTune *tune;
+
+    /* Check if the tune exists and is readable */
+    if ((tune = new SidTune(filename)) == NULL)
+    {
+        XSDEBUG("could not initialize tune from '%s'.\n", filename);
+        return NULL;
+    }
+
+    if (!tune->getStatus())
+    {
+        XSDEBUG("tune->getStatus() returned false for '%s'.\n", filename);
+        delete tune;
+        return NULL;
+    }
+
+    /* Get general tune information */
+#ifdef HAVE_SIDPLAYFP_V1
+    const SidTuneInfo *info = tune->getInfo();
+
+    res = xs_tuneinfo_new(filename,
+        info->songs(), info->startSong(),
+        info->infoString(0), info->infoString(1), info->infoString(2),
+        info->loadAddr(), info->initAddr(), info->playAddr(),
+        info->dataFileLen(), info->formatString(),
+        info->sidModel1()
+        );
+#else
+    const SidTuneInfo info = tune->getInfo();
+
+    res = xs_tuneinfo_new(filename,
+        info.songs, info.startSong,
+        info.infoString[0], info.infoString[1], info.infoString[2],
+        info.loadAddr, info.initAddr, info.playAddr,
+        info.dataFileLen, info.formatString,
+        info.sidModel1
+        );
+#endif
+
+    delete tune;
+    return res;
+}
+
+
+/* Updates the information of currently playing tune
+ */
+gboolean xs_sidplayfp_updateinfo(XSEngineState *state)
+{
+    XSSIDPlayFP *engine;
+    
+    /* Check if we have required structures initialized */
+    if (!state || !state->tuneInfo || !state->internal)
+        return FALSE;
+
+    engine = (XSSIDPlayFP *) state->internal;
+
+#ifdef HAVE_SIDPLAYFP_V1
+    if (!engine->tune.getStatus())
+        return FALSE;
+
+    const SidTuneInfo *info = engine->tune.getInfo();
+
+    state->tuneInfo->sidModel = info.sidModel1();
+
+    if (state->currSong > 0 && state->currSong <= state->tuneInfo->nsubTunes)
+    {
+        gint tmpSpeed = info->clockSpeed();
+        switch (info->clockSpeed())
+        {
+            case SIDTUNE_CLOCK_PAL:      tmpSpeed = XS_CLOCK_PAL; break;
+            case SIDTUNE_CLOCK_NTSC:     tmpSpeed = XS_CLOCK_NTSC; break;
+            case SIDTUNE_CLOCK_ANY:      tmpSpeed = XS_CLOCK_ANY; break;
+            case SIDTUNE_CLOCK_UNKNOWN:
+                switch (info->songSpeed())
+                {
+                    case SIDTUNE_SPEED_VBI:      tmpSpeed = XS_CLOCK_VBI; break;
+                    case SIDTUNE_SPEED_CIA_1A:   tmpSpeed = XS_CLOCK_CIA; break;
+                    default:                     tmpSpeed = info->songSpeed(); break;
+                }
+                break;
+        }
+        state->tuneInfo->subTunes[state->currSong - 1].tuneSpeed = tmpSpeed;
+    }
+#else
+    if (!(engine->tune))
+        return FALSE;
+
+    const SidTuneInfo info = engine->tune.getInfo();
+
+    state->tuneInfo->sidModel = info.sidModel1;
+
+    if (state->currSong > 0 && state->currSong <= state->tuneInfo->nsubTunes)
+    {
+        gint tmpSpeed = info.clockSpeed;
+        switch (info.clockSpeed)
+        {
+            case SIDTUNE_CLOCK_PAL:      tmpSpeed = XS_CLOCK_PAL; break;
+            case SIDTUNE_CLOCK_NTSC:     tmpSpeed = XS_CLOCK_NTSC; break;
+            case SIDTUNE_CLOCK_ANY:      tmpSpeed = XS_CLOCK_ANY; break;
+            case SIDTUNE_CLOCK_UNKNOWN:
+                switch (info.songSpeed)
+                {
+                    case SIDTUNE_SPEED_VBI:      tmpSpeed = XS_CLOCK_VBI; break;
+                    case SIDTUNE_SPEED_CIA_1A:   tmpSpeed = XS_CLOCK_CIA; break;
+                    default:                     tmpSpeed = info.songSpeed; break;
+                }
+                break;
+        }
+        state->tuneInfo->subTunes[state->currSong - 1].tuneSpeed = tmpSpeed;
+    }
+#endif
+
+    return TRUE;
+}
+
+
 }    /* extern "C" */
 #endif    /* HAVE_SIDPLAYFP */