diff src/crossfade/crossfade.h @ 3059:2e241e90494a

Import work in progress xmms-crossfade rewrite.
author William Pitcock <nenolod@atheme.org>
date Fri, 24 Apr 2009 05:57:35 -0500
parents
children 6a6a731fdaf8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/crossfade/crossfade.h	Fri Apr 24 05:57:35 2009 -0500
@@ -0,0 +1,581 @@
+/* 
+ *  XMMS Crossfade Plugin
+ *  Copyright (C) 2000-2007  Peter Eisenlohr <peter@eisenlohr.org>
+ *
+ *  based on the original OSS Output Plugin
+ *  Copyright (C) 1998-2000  Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies
+ *
+ *  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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ *  USA.
+ */
+
+#ifndef _CROSSFADE_H_
+#define _CROSSFADE_H_
+
+#define COMPILE_FOR_AUDACIOUS
+#define AUDACIOUS_ABI_VERSION 2
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#if !defined(HAVE_GLIB_THREADS)
+#  include <pthread.h>
+#endif
+#include <glib.h>
+
+#include <audacious/plugin.h>
+#include <audacious/playlist.h>
+#include <audacious/auddrct.h>
+#include <audacious/configdb.h>
+#include <audacious/util.h>
+
+#include "debug.h"
+
+#undef  VOLUME_NORMALIZER
+#define TIMING_COMMENTS
+
+#define OUTPUT_RATE the_rate
+#define OUTPUT_NCH  2
+#define OUTPUT_BPS (OUTPUT_RATE * OUTPUT_NCH * 2)
+
+#if defined(HAVE_LIBSAMPLERATE)
+#  define MAX_RATE 192000
+#else
+#  define MAX_RATE 48000
+#endif
+
+#define SYNC_OUTPUT_TIMEOUT 2000
+
+#define OUTPUT_METHOD_BUILTIN_OSS  0
+#define OUTPUT_METHOD_PLUGIN       1
+#define OUTPUT_METHOD_BUILTIN_NULL 2
+
+#define FADE_CONFIG_XFADE   0
+#define FADE_CONFIG_MANUAL  1
+#define FADE_CONFIG_ALBUM   2
+#define FADE_CONFIG_START   3
+#define FADE_CONFIG_STOP    4
+#define FADE_CONFIG_EOP     5
+#define FADE_CONFIG_SEEK    6
+#define FADE_CONFIG_PAUSE   7
+#define FADE_CONFIG_TIMING  8
+#define MAX_FADE_CONFIGS    9
+
+#define FADE_TYPE_REOPEN      0
+#define FADE_TYPE_FLUSH       1
+#define FADE_TYPE_NONE        2
+#define FADE_TYPE_PAUSE       3
+#define FADE_TYPE_SIMPLE_XF   4
+#define FADE_TYPE_ADVANCED_XF 5
+#define FADE_TYPE_FADEIN      6
+#define FADE_TYPE_FADEOUT     7
+#define FADE_TYPE_PAUSE_NONE  8
+#define FADE_TYPE_PAUSE_ADV   9
+#define MAX_FADE_TYPES        10
+
+#define TYPEMASK_XFADE ((1 << FADE_TYPE_REOPEN) |	\
+			(1 << FADE_TYPE_NONE) |		\
+			(1 << FADE_TYPE_PAUSE) |	\
+			(1 << FADE_TYPE_SIMPLE_XF) |	\
+			(1 << FADE_TYPE_ADVANCED_XF))
+
+#define TYPEMASK_MANUAL ((1 << FADE_TYPE_REOPEN) |	\
+			 (1 << FADE_TYPE_FLUSH) |	\
+		         (1 << FADE_TYPE_NONE) |	\
+			 (1 << FADE_TYPE_PAUSE) |	\
+			 (1 << FADE_TYPE_SIMPLE_XF) |	\
+			 (1 << FADE_TYPE_ADVANCED_XF))
+
+#define TYPEMASK_ALBUM ((1 << FADE_TYPE_NONE))
+
+#define TYPEMASK_START ((1 << FADE_TYPE_NONE) |	\
+			(1 << FADE_TYPE_FADEIN))
+
+#define TYPEMASK_STOP ((1 << FADE_TYPE_NONE) | \
+		       (1 << FADE_TYPE_FADEOUT))
+
+#define TYPEMASK_EOP ((1 << FADE_TYPE_NONE) | \
+		      (1 << FADE_TYPE_FADEOUT))
+
+#define TYPEMASK_SEEK ((1 << FADE_TYPE_FLUSH) | \
+		       (1 << FADE_TYPE_NONE)  | \
+		       (1 << FADE_TYPE_SIMPLE_XF))
+
+#define TYPEMASK_PAUSE ((1 << FADE_TYPE_PAUSE_NONE) | \
+                        (1 << FADE_TYPE_PAUSE_ADV))
+
+#define TYPEMASK_TIMING (0)
+
+#define FC_OFFSET_NONE     0
+#define FC_OFFSET_LOCK_IN  1
+#define FC_OFFSET_LOCK_OUT 2
+#define FC_OFFSET_CUSTOM   3
+
+#define DEFAULT_OSS_ALT_AUDIO_DEVICE "/dev/dsp"
+#define DEFAULT_OSS_ALT_MIXER_DEVICE "/dev/mixer"
+#define DEFAULT_OP_CONFIG_STRING     "libOSS.so=0,1,2304,0; libdisk_writer.so=1,0,2304,1"
+#define DEFAULT_OP_NAME              "libALSA.so"
+#define DEFAULT_EP_NAME              "libnormvol.so"
+
+#define DEFAULT_OP_CONFIG			\
+{ FALSE, FALSE, 2304, FALSE }
+
+#define CONFIG_DEFAULT							\
+{ 0,                            /* output_method */			\
+  44100,                        /* output_rate */			\
+  2,                            /* output_quality */			\
+  0,                            /* oss_audio_device */			\
+  FALSE,                        /* oss_use_alt_audio_device */		\
+  NULL,                         /* oss_alt_audio_device */		\
+  0,                            /* oss_mixer_device */			\
+  FALSE,                        /* oss_use_alt_mixer_device */		\
+  NULL,                         /* oss_alt_mixer_device */		\
+  FALSE,                        /* oss_mixer_use_master */		\
+  0,                            /* oss_buffer_size_ms */		\
+  250,                          /* oss_preload_size_ms */		\
+  22,                           /* oss_fragments */			\
+  12,                           /* oss_fragment_size */			\
+  FALSE,                        /* oss_maxbuf_enable */			\
+  NULL,                         /* op_config_string */			\
+  NULL,                         /* op_name */				\
+  NULL,                         /* ep_name */				\
+  FALSE,                        /* ep_enable */				\
+  TRUE,                         /* volnorm_enable */			\
+  8000,                         /* volnorm_target */			\
+  FALSE,                        /* volnorm_use_qa */			\
+  10000,                        /* mix_size_ms */			\
+  TRUE,                         /* mix_size_auto */			\
+									\
+  {                             /* fc[MAX_FADE_CONFIGS] */		\
+    { FADE_CONFIG_XFADE,        /* config */				\
+      FADE_TYPE_ADVANCED_XF,    /* type */				\
+      2000,                     /* pause_len_ms */			\
+      6000,                     /* simple_len_ms */			\
+      TRUE, 4000, 0,            /* out_enable, _len_ms, _volume */	\
+      FC_OFFSET_CUSTOM,         /* ofs_type */				\
+      FC_OFFSET_CUSTOM, -6000,  /* ofs_type_wanted, ofs_custom_ms */	\
+      TRUE,                     /* in_locked */				\
+      FALSE, 4000, 33,          /* in_enable, _len_ms, _volume */	\
+      FALSE,                    /* - */					\
+      0,                        /* - */					\
+      FALSE,                    /* - */					\
+      0, 0,                     /* - */					\
+      FALSE,                    /* flush */				\
+      TYPEMASK_XFADE            /* type_mask */				\
+    },									\
+    { FADE_CONFIG_MANUAL,       /* config */				\
+      FADE_TYPE_SIMPLE_XF,      /* type */				\
+      2000,                     /* pause_len_ms */			\
+      1000,                     /* simple_len_ms */			\
+      TRUE, 500, 0,             /* out_enable, _len_ms, _volume */	\
+      FC_OFFSET_CUSTOM,         /* ofs_type */				\
+      FC_OFFSET_CUSTOM, -500,   /* ofs_type_wanted, ofs_custom_ms */	\
+      TRUE,                     /* in_locked */				\
+      FALSE, 500, 50,           /* in_enable, _len_ms, _volume */	\
+      FALSE,                    /* flush_pause_enable */		\
+      500,                      /* flush_in_len_ms */			\
+      FALSE,                    /* flush_in_enable */			\
+      500, 0,                   /* flush_in_len_ms, _volume */		\
+      TRUE,                     /* flush */				\
+      TYPEMASK_MANUAL           /* type_mask */				\
+    },									\
+    { FADE_CONFIG_ALBUM,        /* config */				\
+      FADE_TYPE_NONE,           /* type */				\
+      0,                        /* - */					\
+      0,                        /* - */					\
+      FALSE, 0, 0,              /* - */					\
+      FC_OFFSET_NONE,           /* - */					\
+      FC_OFFSET_NONE, 0,        /* - */					\
+      FALSE,                    /* - */					\
+      FALSE, 1000, 0,           /* - */					\
+      FALSE,                    /* - */					\
+      0,                        /* - */					\
+      FALSE,                    /* - */					\
+      0, 0,                     /* - */					\
+      FALSE,                    /* flush */				\
+      TYPEMASK_ALBUM            /* type_mask */				\
+    },									\
+    { FADE_CONFIG_START,        /* config */				\
+      FADE_TYPE_FADEIN,         /* type */				\
+      0,                        /* - */					\
+      0,                        /* - */					\
+      FALSE, 0, 0,              /* - */					\
+      FC_OFFSET_NONE,           /* - */					\
+      FC_OFFSET_NONE, 0,        /* - */					\
+      FALSE,                    /* - */					\
+      FALSE, 100, 0,            /* - in_len_ms, _volume */		\
+      FALSE,                    /* - */					\
+      0,                        /* - */					\
+      FALSE,                    /* - */					\
+      0, 0,                     /* - */					\
+      TRUE,                     /* flush */				\
+      TYPEMASK_START            /* type_mask */				\
+    },									\
+    { FADE_CONFIG_STOP,         /* config */				\
+      FADE_TYPE_FADEOUT,        /* type */				\
+      0,                        /* - */					\
+      0,                        /* - */					\
+      FALSE, 100, 0,            /* - out_len_ms, _volume */		\
+      FC_OFFSET_NONE,           /* - */					\
+      FC_OFFSET_NONE, 500,      /* - ofs_custom_ms */			\
+      FALSE,                    /* - */					\
+      FALSE, 0, 0,              /* - */					\
+      FALSE,                    /* - */					\
+      0,                        /* - */					\
+      FALSE,                    /* - */					\
+      0, 0,                     /* - */					\
+      TRUE,                     /* flush */				\
+      TYPEMASK_STOP             /* type_mask */				\
+    },									\
+    { FADE_CONFIG_EOP,          /* config */				\
+      FADE_TYPE_FADEOUT,        /* type */				\
+      0,                        /* - */					\
+      0,                        /* - */					\
+      FALSE, 100, 0,            /* - out_len_ms, _volume */		\
+      FC_OFFSET_NONE,           /* - */					\
+      FC_OFFSET_NONE, 500,      /* - ofs_custom_ms  */			\
+      FALSE,                    /* - */					\
+      FALSE, 0, 0,              /* - */					\
+      FALSE,                    /* - */					\
+      0,                        /* - */					\
+      FALSE,                    /* - */					\
+      0, 0,                     /* - */					\
+      FALSE,                    /* flush */				\
+      TYPEMASK_EOP              /* type_mask */				\
+    },									\
+    { FADE_CONFIG_SEEK,         /* config */				\
+      FADE_TYPE_SIMPLE_XF,      /* type */				\
+      0,                        /* - */					\
+      50,                       /* simple_len_ms */			\
+      FALSE, 0, 0,              /* - */					\
+      FC_OFFSET_NONE,           /* - */					\
+      FC_OFFSET_NONE, 0,        /* - */					\
+      FALSE,                    /* - */					\
+      FALSE, 1000, 0,           /* - */					\
+      FALSE,                    /* - */					\
+      0,                        /* - */					\
+      FALSE,                    /* - */					\
+      0, 0,                     /* - */					\
+      TRUE,                     /* flush */				\
+      TYPEMASK_SEEK             /* type_mask */				\
+    },									\
+    { FADE_CONFIG_PAUSE,        /* config */				\
+      FADE_TYPE_PAUSE_ADV,      /* type */				\
+      0,                        /* - */					\
+      0,                        /* - */					\
+      TRUE, 100, 0,             /* - out_len_ms, - */			\
+      FC_OFFSET_NONE,           /* - */					\
+      FC_OFFSET_NONE, 100,      /* - ofs_custom_ms */			\
+      FALSE,                    /* - */					\
+      TRUE, 100, 0,             /* - in_len_ms, - */			\
+      FALSE,                    /* - */					\
+      0,                        /* - */					\
+      FALSE,                    /* - */					\
+      0, 0,                     /* - */					\
+      FALSE,                    /* - */					\
+      TYPEMASK_PAUSE            /* type_mask */				\
+    },									\
+    { FADE_CONFIG_TIMING,       /* config */				\
+      FADE_TYPE_ADVANCED_XF,    /* type */				\
+      0,                        /* - */					\
+      0,                        /* - */					\
+      TRUE, 0, 0,               /* out_enable, _len_ms, _volume */	\
+      FC_OFFSET_CUSTOM,         /* - */					\
+      FC_OFFSET_CUSTOM, 0,      /* - ofs_custom_ms */			\
+      FALSE,                    /* - */					\
+      TRUE, 0, 0,               /* in_enable, _len_ms, _volume */	\
+      FALSE,                    /* - */					\
+      0,                        /* - */					\
+      FALSE,                    /* - */					\
+      0, 0,                     /* - */					\
+      FALSE,                    /* flush */				\
+      TYPEMASK_TIMING,          /* type_mask */				\
+      500,                      /* out_skip_ms */			\
+      500                       /* in_skip_ms */			\
+    }									\
+  },									\
+  TRUE,                         /* gap_lead_enable */			\
+  500,                          /* gap_lead_len_ms */			\
+  512,                          /* gap_lead_level */			\
+  TRUE,                         /* gap_trail_enable */			\
+  500,                          /* gap_trail_len_ms */			\
+  512,                          /* gap_trail_level */			\
+  TRUE,                         /* gap_trail_locked */			\
+  TRUE,                         /* gap_crossing */			\
+  FALSE,                        /* enable_debug */			\
+  FALSE,                        /* enable_monitor */			\
+  TRUE,                         /* enable_mixer */			\
+  FALSE,                        /* mixer_reverse */			\
+  FALSE,                        /* mixer_software */			\
+  75,                           /* mixer_vol_left */			\
+  75,                           /* mixer_vol_right */			\
+  500,                          /* songchange_timeout */		\
+  0,                            /* preload_size_ms */			\
+  TRUE,                         /* album detection */			\
+  FALSE,                        /* no_xfade_if_same_file */		\
+  FALSE,                        /* enable_http_workaround */		\
+  FALSE,                        /* enable_op_max_used */		\
+  250,                          /* op_max_used_ms */			\
+  FALSE,                        /* output_keep_opened */		\
+  NULL,                         /* presets */				\
+  250                           /* sync_size_ms */			\
+}
+
+
+#define DEBUG(x)  { if (config->enable_debug) debug x; }
+#define PERROR(x) { if (config->enable_debug) perror(x); }
+
+#define WRAP(x,n) (((x)<0)?((n)-(x))%(n):((x)%(n)))
+#define B2MS(x)   ((gint)((gint64)(x)*1000/OUTPUT_BPS))
+#define MS2B(x)   ((gint)((gint64)(x)*OUTPUT_BPS/1000))
+
+
+/* get plugin info (imported by XMMS) */
+OutputPlugin *get_oplugin_info();
+OutputPlugin *get_crossfade_oplugin_info();
+
+#include "player.h"
+
+/* utilities */
+void xfade_usleep(gint usec);
+
+/* config change callbacks */
+void xfade_realize_config();
+void xfade_realize_ep_config();
+
+
+typedef struct
+{
+	gint mix_size;		/* mixing buffer length */
+	gint sync_size;		/* additional buffer space for mix timing */
+	gint preload_size;	/* preload buffer length */
+
+	/* ---------------------------------------------------------------------- */
+
+	gpointer data;		/* buffer */
+	gint size;		/* total buffer length */
+
+	/* ---------------------------------------------------------------------- */
+
+	gint used;		/* length */
+	gint rd_index;		/* offset */
+
+	gint preload;		/* > 0: preloading */
+
+	/* ---------------------------------------------------------------------- */
+
+	gint mix;		/* > 0: mixing new data into buffer */
+
+	gint fade;		/* > 0: fading in new data */
+	gint fade_len;		/* length of fadein */
+	gfloat fade_scale;	/* 1.0f - in_level */
+
+#define GAP_SKIPPING_POSITIVE -1
+#define GAP_SKIPPING_NEGATIVE -2
+#define GAP_SKIPPING_DONE     -3
+	gint gap;		/* > 0: removing (leading) gap */
+	gint gap_len;		/* max. len of gap, 0=disabled */
+	gint gap_level;		/* max. sample value+1 to be considered "silent" */
+	gint gap_killed;	/* number of bytes that were killed last time */
+	gint gap_skipped;	/* negative/positive samples skipped */
+
+	gint skip;		/* > 0: skipping beginning of song */
+	gint skip_len;		/* total number of samples to skip */
+
+	/* ---------------------------------------------------------------------- */
+
+	gint silence;		/* > 0: delay until start of silence */
+	gint silence_len;	/* > 0: inserting silence */
+
+	gint reopen;		/* >= 0: countdown to reopen device (disk_writer hack) */
+	gboolean reopen_sync;	/* TRUE: sync output plugin before reopening */
+
+	gint pause;		/* >= 0: countdown to pause output plugin */
+}
+buffer_t;
+
+typedef struct
+{
+	gint config;		// one of FADE_CONFIG_*, constant
+	gint type;		// one of FADE_TYPE_*
+
+	gint pause_len_ms;	// PAUSE
+
+	gint simple_len_ms;	// SIMPLE_XF
+
+	gboolean out_enable;	// ADVANCED_XF
+	gint out_len_ms;	// ADVANCED_XF, FADEOUT, PAUSE
+	gint out_volume;	// ADVANCED_XF, FADEOUT
+
+	gint ofs_type;		// ADVANCED_XF
+	gint ofs_type_wanted;	// ADVANCED_XF
+	gint ofs_custom_ms;	// ADVANCED_XF, FADEOUT (additional silence), PAUSE
+
+	gboolean in_locked;	// ADVANCED_XF
+	gboolean in_enable;	// ADVANCED_XF, FLUSH
+	gint in_len_ms;		// ADVANCED_XF, FLUSH, FADEIN, PAUSE
+	gint in_volume;		// ADVANCED_XF, FLUSH, FADEIN
+
+	gboolean flush_pause_enable;	// FLUSH
+	gint flush_pause_len_ms;	// FLUSH
+	gboolean flush_in_enable;	// FLUSH
+	gint flush_in_len_ms;	// FLUSH
+	gint flush_in_volume;	// FLUSH
+
+	/* additional stuff which is not configureable by the user */
+	gboolean flush;		// TRUE for manual, FALSE for xfade config
+	guint32 type_mask;	// bitmask for FADE_TYPEs
+	
+	/* new fields as of v0.3.11: skip beginning/end of song */
+	gint out_skip_ms;
+	gint in_skip_ms;
+}
+fade_config_t;
+
+typedef struct
+{
+	gboolean throttle_enable;
+	gboolean max_write_enable;
+	gint max_write_len;
+	gboolean force_reopen;
+}
+plugin_config_t;
+
+typedef struct
+{
+	/* output: method */
+	gint output_method;
+	gint output_rate;
+	gint output_quality;
+
+	/* output: builtin OSS */
+	gint oss_audio_device;
+	gboolean oss_use_alt_audio_device;
+	gchar *oss_alt_audio_device;
+
+	gint oss_mixer_device;
+	gboolean oss_use_alt_mixer_device;
+	gchar *oss_alt_mixer_device;
+	gboolean oss_mixer_use_master;
+
+	gint oss_buffer_size_ms;
+	gint oss_preload_size_ms;
+
+	gint oss_fragments;
+	gint oss_fragment_size;
+	gboolean oss_maxbuf_enable;
+
+	/* output: plugin */
+	gchar *op_config_string;  /* stores configs for all plugins */
+	gchar *op_name;           /* name of the current plugin */
+
+	/* effects */
+	gchar *ep_name;
+	gboolean ep_enable;
+	gboolean volnorm_enable;
+	gboolean volnorm_use_qa;
+	gint volnorm_target;
+
+	/* crossfader */
+	gint mix_size_ms;
+	gboolean mix_size_auto;
+	fade_config_t fc[MAX_FADE_CONFIGS];
+
+	/* gap killer */
+	gboolean gap_lead_enable;
+	gint gap_lead_len_ms;
+	gint gap_lead_level;
+
+	gboolean gap_trail_enable;
+	gint gap_trail_len_ms;
+	gint gap_trail_level;
+	gboolean gap_trail_locked;
+
+	gboolean gap_crossing;
+
+	/* misc */
+	gboolean enable_debug;
+	gboolean enable_monitor;
+
+	gboolean enable_mixer;
+	gboolean mixer_reverse;
+	gboolean mixer_software;
+	gint mixer_vol_left;
+	gint mixer_vol_right;
+
+	gint songchange_timeout;
+	gint preload_size_ms;
+	gboolean album_detection;
+	gboolean no_xfade_if_same_file;
+	gboolean enable_http_workaround;
+	gboolean enable_op_max_used;
+	gint op_max_used_ms;
+	gboolean output_keep_opened;
+
+	/* presets */
+	GList *presets;
+
+	/* additional stuff which is not configureable by the user */
+	gint sync_size_ms;
+
+	/* additional stuff which is not saved to the config file */
+	gint page;
+	gint oss_page;
+	gint xf_index;
+}
+config_t;
+
+
+/* some global vars... we should really get rid of those somehow */
+extern config_t *config;
+extern config_t  config_default;
+extern buffer_t *buffer;
+
+#if defined(HAVE_GLIB_THREADS)
+#  define MUTEX GStaticMutex
+#  define MUTEX_LOCK(mutex)   g_static_mutex_lock(mutex)
+#  define MUTEX_UNLOCK(mutex) g_static_mutex_unlock(mutex)
+#  define MUTEX_INITIALIZER   G_STATIC_MUTEX_INIT
+#  define THREAD GThread *
+#  define THREAD_CREATE(thread,func) !(thread = g_thread_create(func, NULL, TRUE, NULL))
+#  define THREAD_EXIT(rval)          g_thread_exit(rval)
+#  define THREAD_JOIN(thread)        g_thread_join(thread)
+#  define SCHED_YIELD                g_thread_yield()
+#else
+#  define MUTEX pthread_mutex_t
+#  define MUTEX_LOCK(mutex)   pthread_mutex_lock(mutex)
+#  define MUTEX_UNLOCK(mutex) pthread_mutex_unlock(mutex)
+#  define MUTEX_INITIALIZER   PTHREAD_MUTEX_INITIALIZER
+#  define THREAD pthread_t
+#  define THREAD_CREATE(thread,func) pthread_create(&thread,NULL,func,NULL)
+#  define THREAD_EXIT(rval)          pthread_exit(rval)
+#  define THREAD_JOIN(thread)        pthread_join(thread,NULL)
+#  if defined(_POSIX_PRIORITY_SCHEDULING)
+#    define SCHED_YIELD sched_yield()
+#  else
+#    define SCHED_YIELD { }
+#  endif
+#endif
+
+extern gboolean opened;		/* XMMS-crossfade is opened */
+extern gboolean output_opened;	/* the output plugin is opened */
+extern gint     output_offset;
+extern gint64   output_streampos;
+
+extern OutputPlugin *the_op;
+extern gint          the_rate;
+
+#endif /* _CROSSFADE_H_ */