view src/xmms-sid.h @ 957:0e60e5d56fdd

Change how the backend emulator library is initialized for libSIDPlay2 and FP, as it seems the engine configuration has some persistence despite reconfiguration between loaded files if same engine object is retained. This caused, for example, 2SID stereo tunes being played "mono" if played after a normal 1-SID tune. Duh.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 20 Nov 2012 22:13:48 +0200
parents 2a50d36215c3
children be2a8436461a
line wrap: on
line source

/*  
   XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS)

   Main header file

   Programmed and designed by Matti 'ccr' Hamalainen <ccr@tnsp.org>
   (C) Copyright 1999-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.
*/
#ifndef XMMS_SID_H
#define XMMS_SID_H

#include "xs_support.h"

#ifdef __cplusplus
extern "C" {
#endif

/* Define to ISO C99 macro for debugging instead of varargs function.
 * This provides more useful information, but is incompatible with
 * older standards. If #undef'd, a varargs function is used instead.
 */
#define DEBUG_NP

/* Define to enable non-portable thread and mutex debugging code.
 * You need to #define DEBUG also to make this useful.
 * (Works probably with GNU/Linux pthreads implementation only)
 */
#undef XS_MUTEX_DEBUG

/* Size for some small buffers (always static variables) */
#define XS_BUF_SIZE            (512)

#define XS_BUF2_SIZE           (4096)

/* If defined, some dynamically allocated temp. buffers are used.
 * Static (#undef) might give slight performance gain,
 * but fails on systems with limited stack space. */
#define XS_BUF_DYNAMIC

/* Configuration section identifier
 */
#define XS_PACKAGE_STRING      PACKAGE_STRING
#define XS_CONFIG_IDENT        "XMMS-SID"

/* Default audio rendering frequency in Hz
 */
#define XS_AUDIO_FREQ          (44100)

/* Size of audio buffer. If you are experiencing lots of audio
 * "underruns" or clicks/gaps in output, try increasing this value.
 * Do notice, however, that it also affects the update frequency of
 * XMMS's visualization plugins... 
 */
#define XS_AUDIOBUF_SIZE       (4*1024)

/* Size of data buffer used for SID-file loading and MD5 hash calculation.
 * If this is too small, the computed hash will be incorrect.
 * Largest SID files I've seen are ~70kB.
 */
#define XS_SIDBUF_SIZE         (256*1024)

/* libSIDPlay1/2 constants (copied from internal headers/source)
 * For some stupid reason these are not available in public
 * headers, so we have to duplicate them here...
 */
#define XS_SIDPLAY1_FS         (400.0f)
#define XS_SIDPLAY1_FM         (60.0f)
#define XS_SIDPLAY1_FT         (0.05f)

#define XS_SIDPLAY2_NFPOINTS   (0x800)
#define XS_SIDPLAY2_FMAX       (24000)


/* Macros for mutexes and threads. These exist to be able to
 * easily change from pthreads to glib threads, etc, if necessary.
 */
#define XS_THREAD_T            pthread_t
#define XS_THREAD_EXIT(M)      pthread_exit(M)
#define XS_THREAD_JOIN(M)      pthread_join(M, NULL)
#define XS_MPP(M)              M ## _mutex
#ifdef XS_MUTEX_DEBUG
#  ifndef __USE_GNU
#    define __USE_GNU
#  endif
#  define XS_MUTEX(M)          pthread_mutex_t    XS_MPP(M) = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; gint M ## _qq
#  define XS_MUTEX_H(M)        extern pthread_mutex_t XS_MPP(M); extern gint M ## _qq
#  define XS_MUTEX_LOCK(M)     { M ## _qq = pthread_mutex_lock(&XS_MPP(M)); if (M ## _qq) XSDEBUG("XS_MUTEX_LOCK(" #M ") == %i\n", M ## _qq); }
#  define XS_MUTEX_UNLOCK(M)   { M ## _qq = pthread_mutex_unlock(&XS_MPP(M)); if (M ## _qq) XSDEBUG("XS_MUTEX_UNLOCK(" #M ") == %i\n", M ## _qq); }
#else
#  define XS_MUTEX(M)          pthread_mutex_t    XS_MPP(M) = PTHREAD_MUTEX_INITIALIZER
#  define XS_MUTEX_H(M)        extern pthread_mutex_t XS_MPP(M)
#  define XS_MUTEX_LOCK(M)     pthread_mutex_lock(&XS_MPP(M))
#  define XS_MUTEX_UNLOCK(M)   pthread_mutex_unlock(&XS_MPP(M))
#endif
#include <pthread.h>

/* Character set conversion helper macros
 */
#define XS_CS_FILENAME(M)      g_strdup(M)
#define XS_CS_SID(M)           g_strdup(M)
#define XS_CS_STIL(M)          M
#define XS_CS_FREE(M)


/* Plugin-wide typedefs
 */
typedef struct {
    gint         tuneSpeed,
                 tuneLength;
    gboolean     tunePlayed;
} XSSubTuneInfo;


typedef struct {
    gchar        *sidFilename,
                 *sidName,
                 *sidComposer,
                 *sidCopyright,
                 *sidFormat;
    gint         loadAddr,
                 initAddr,
                 playAddr,
                 dataFileLen,
                 sidModel;
    gint         nsubTunes, startTune;
    XSSubTuneInfo    *subTunes;
} XSTuneInfo;


/* Global variables
 */
extern InputPlugin    xs_plugin_ip;


/* Plugin function prototypes
 */
void    xs_init(void);
void    xs_reinit(void);
void    xs_close(void);
gint    xs_is_our_file(gchar *);
void    xs_play_file(gchar *);
void    xs_stop(void);
void    xs_pause(short);
void    xs_seek(gint);
gint    xs_get_time(void);
void    xs_get_song_info(gchar *, gchar **, gint *);
void    xs_about(void);


#ifndef DEBUG_NP
void    XSDEBUG(const char *, ...);
#else
#  ifdef DEBUG
#    define XSDEBUG(...) { fprintf(stderr, "XS[%s:%s:%d]: ", __FILE__, __FUNCTION__, (int) __LINE__); fprintf(stderr, __VA_ARGS__); }
#  else
#    define XSDEBUG(...) /* stub */
#  endif
#endif


/* And even some Gtk+ macro crap here, yay.
 */
#define XS_DEF_WINDOW_DELETE(ME, MV)			\
gboolean xs_ ## ME ## _delete(GtkWidget *w, GdkEvent *e, gpointer d) {	\
    (void) w; (void) e; (void) d;			\
    if (xs_ ## MV ) {					\
        gtk_widget_destroy(xs_ ## MV );			\
        xs_ ## MV = NULL;				\
    }							\
    return FALSE;					\
}

#define XS_DEF_WINDOW_CLOSE(ME, MV)			\
void xs_ ## ME (GtkButton *b, gpointer d) {		\
    (void) b; (void) d;					\
    gtk_widget_destroy(xs_ ## MV );			\
    xs_ ## MV = NULL;					\
}

#define XS_SIGNAL_CONNECT(SOBJ, SNAME, SFUNC, SDATA)			\
    gtk_signal_connect(GTK_OBJECT(SOBJ), SNAME, GTK_SIGNAL_FUNC(SFUNC), SDATA)

#define XS_WINDOW_PRESENT(SWIN) gdk_window_raise(SWIN ->window)

#ifdef __cplusplus
}
#endif
#endif /* XMMS_SID_H */