summaryrefslogtreecommitdiff
path: root/src/combined
diff options
context:
space:
mode:
Diffstat (limited to 'src/combined')
-rw-r--r--src/combined/Makefile.am31
-rw-r--r--src/combined/demux_flac.h28
-rw-r--r--src/combined/flac_decoder.c (renamed from src/combined/decoder_flac.c)29
-rw-r--r--src/combined/flac_demuxer.c (renamed from src/combined/demux_flac.c)0
-rw-r--r--src/combined/nsf_combined.c46
-rw-r--r--src/combined/nsf_decoder.c268
-rw-r--r--src/combined/nsf_demuxer.c391
-rw-r--r--src/combined/wavpack_combined.c (renamed from src/combined/combined_wavpack.c)2
-rw-r--r--src/combined/wavpack_combined.h (renamed from src/combined/combined_wavpack.h)9
-rw-r--r--src/combined/wavpack_decoder.c (renamed from src/combined/decoder_wavpack.c)4
-rw-r--r--src/combined/wavpack_demuxer.c (renamed from src/combined/demux_wavpack.c)2
11 files changed, 745 insertions, 65 deletions
diff --git a/src/combined/Makefile.am b/src/combined/Makefile.am
index 884fcf0cc..cf88795ba 100644
--- a/src/combined/Makefile.am
+++ b/src/combined/Makefile.am
@@ -1,21 +1,34 @@
include $(top_srcdir)/misc/Makefile.common
-if HAVE_WAVPACK
+AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG)
+AM_LDFLAGS = $(xineplug_ldflags)
+
+if ENABLE_WAVPACK
xineplug_wavpack = xineplug_wavpack.la
endif
-if HAVE_LIBFLAC
+if ENABLE_LIBFLAC
xineplug_flac = xineplug_flac.la
endif
-xineplug_LTLIBRARIES = $(xineplug_wavpack) $(xineplug_flac)
+$(top_builddir)/contrib/nosefart/libnosefart.la:
+ $(MAKE) -C $(top_builddir)/contrib/nosefart
+
+xineplug_LTLIBRARIES = \
+ $(xineplug_wavpack) \
+ $(xineplug_flac) \
+ xineplug_nsf.la
-xineplug_wavpack_la_SOURCES = demux_wavpack.c decoder_wavpack.c combined_wavpack.c combined_wavpack.h
-xineplug_wavpack_la_CFLAGS = $(VISIBILITY_FLAG) $(WAVPACK_CFLAGS) -I$(srcdir)/../demuxers
+xineplug_wavpack_la_SOURCES = wavpack_demuxer.c wavpack_decoder.c wavpack_combined.c wavpack_combined.h
xineplug_wavpack_la_LIBADD = $(XINE_LIB) $(WAVPACK_LIBS)
-xineplug_wavpack_la_LDFLAGS = $(xineplug_ldflags)
+xineplug_wavpack_la_CFLAGS = $(AM_CFLAGS) $(WAVPACK_CFLAGS)
+xineplug_wavpack_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/demuxers
-xineplug_flac_la_SOURCES = demux_flac.c decoder_flac.c demux_flac.h
-xineplug_flac_la_CFLAGS = $(VISIBILITY_FLAG) $(LIBFLAC_CFLAGS)
+xineplug_flac_la_SOURCES = flac_demuxer.c flac_decoder.c
xineplug_flac_la_LIBADD = $(XINE_LIB) $(LIBFLAC_LIBS)
-xineplug_flac_la_LDFLAGS = $(xineplug_ldflags)
+xineplug_flac_la_CFLAGS = $(AM_CFLAGS) $(LIBFLAC_CFLAGS)
+
+xineplug_nsf_la_SOURCES = nsf_decoder.c nsf_demuxer.c nsf_combined.c
+xineplug_nsf_la_LIBADD = $(XINE_LIB) $(top_builddir)/contrib/nosefart/libnosefart.la -lm
+xineplug_nsf_la_CFLAGS = $(AM_CFLAGS) -fno-strict-aliasing
+xineplug_nsf_la_CPPFLAGS = $(AM_CPPFLAGS) -DNSF_PLAYER -I$(top_srcdir)/contrib/nosefart -I$(top_srcdir)/src/demuxers
diff --git a/src/combined/demux_flac.h b/src/combined/demux_flac.h
deleted file mode 100644
index 6086781d1..000000000
--- a/src/combined/demux_flac.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2000-2003 the xine project
- *
- * This file is part of xine, a free video player.
- *
- * xine 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.
- *
- * xine 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
- *
- * $Id: demux_flac.h,v 1.2 2003/12/09 00:02:32 f1rmb Exp $
- */
-
-#ifndef HAVE_DEMUX_FLAC_H
-#define HAVE_DEMUX_FLAC_H
-
-void *demux_flac_init_class (xine_t *xine, void *data);
-
-#endif
diff --git a/src/combined/decoder_flac.c b/src/combined/flac_decoder.c
index 9b77cc27d..babfde6ae 100644
--- a/src/combined/decoder_flac.c
+++ b/src/combined/flac_decoder.c
@@ -48,8 +48,6 @@
#include "audio_out.h"
#include "buffer.h"
-#include "demux_flac.h"
-
typedef struct {
audio_decoder_class_t decoder_class;
} flac_class_t;
@@ -59,23 +57,17 @@ typedef struct flac_decoder_s {
int64_t pts;
- int output_sampling_rate;
- int output_open;
- int output_mode;
-
xine_stream_t *stream;
FLAC__StreamDecoder *flac_decoder;
- int sample_rate;
- int bits_per_sample;
- int channels;
-
unsigned char *buf;
int buf_size;
int buf_pos;
int min_size;
+ int output_open;
+
} flac_decoder_t;
/*
@@ -249,21 +241,18 @@ flac_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
*/
if (buf->decoder_flags & BUF_FLAG_STDHEADER)
{
- int mode = AO_CAP_MODE_MONO;
-
- this->sample_rate = buf->decoder_info[1];
- this->bits_per_sample = buf->decoder_info[2];
- this->channels = buf->decoder_info[3];
-
- mode = _x_ao_channels2mode(this->channels);
+ const int sample_rate = buf->decoder_info[1];
+ const int bits_per_sample = buf->decoder_info[2];
+ const int channels = buf->decoder_info[3];
+ const int mode = _x_ao_channels2mode(channels);
if (!this->output_open)
{
this->output_open = this->stream->audio_out->open (
this->stream->audio_out,
this->stream,
- this->bits_per_sample,
- this->sample_rate,
+ bits_per_sample,
+ sample_rate,
mode);
@@ -418,6 +407,8 @@ init_plugin (xine_t *xine, void *data) {
return this;
}
+void *demux_flac_init_class (xine_t *xine, void *data);
+
static uint32_t audio_types[] = {
BUF_AUDIO_FLAC, 0
};
diff --git a/src/combined/demux_flac.c b/src/combined/flac_demuxer.c
index 43ee17d5c..43ee17d5c 100644
--- a/src/combined/demux_flac.c
+++ b/src/combined/flac_demuxer.c
diff --git a/src/combined/nsf_combined.c b/src/combined/nsf_combined.c
new file mode 100644
index 000000000..855b8d2a5
--- /dev/null
+++ b/src/combined/nsf_combined.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine 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.
+ *
+ * xine 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
+ *
+ * $Id: combined_wavpack.c,v 1.3 2007/03/17 07:34:02 dgp85 Exp $
+ */
+
+#include "xine_internal.h"
+
+void *decoder_nsf_init_plugin (xine_t *xine, void *data);
+void *demux_nsf_init_plugin (xine_t *xine, void *data);
+
+static const demuxer_info_t demux_info_nsf = {
+ 10 /* priority */
+};
+
+static uint32_t audio_types[] = {
+ BUF_AUDIO_NSF,
+ 0
+};
+
+static const decoder_info_t decoder_info_nsf = {
+ audio_types, /* supported types */
+ 5 /* priority */
+};
+
+const plugin_info_t xine_plugin_info[] EXPORTED = {
+ { PLUGIN_DEMUX, 26, "nsfdemux", XINE_VERSION_CODE, &demux_info_nsf, demux_nsf_init_plugin },
+ { PLUGIN_AUDIO_DECODER, 15, "nsfdec", XINE_VERSION_CODE, &decoder_info_nsf, decoder_nsf_init_plugin },
+ { PLUGIN_NONE, 0, NULL, 0, NULL, NULL }
+};
diff --git a/src/combined/nsf_decoder.c b/src/combined/nsf_decoder.c
new file mode 100644
index 000000000..e8b5dd96a
--- /dev/null
+++ b/src/combined/nsf_decoder.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine 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.
+ *
+ * xine 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
+ *
+ * NSF Audio "Decoder" using the Nosefart NSF engine by Matt Conte
+ * http://www.baisoku.org/
+ *
+ * $Id: nsf.c,v 1.13 2006/09/25 23:56:31 dgp85 Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "xine_internal.h"
+#include "audio_out.h"
+#include "buffer.h"
+#include "xineutils.h"
+#include "bswap.h"
+
+/* Nosefart includes */
+#include "types.h"
+#include "nsf.h"
+
+typedef struct {
+ audio_decoder_class_t decoder_class;
+} nsf_class_t;
+
+typedef struct nsf_decoder_s {
+ audio_decoder_t audio_decoder;
+
+ xine_stream_t *stream;
+
+ int sample_rate; /* audio sample rate */
+ int bits_per_sample; /* bits/sample, usually 8 or 16 */
+ int channels; /* 1 or 2, usually */
+
+ int output_open; /* flag to indicate audio is ready */
+
+ int nsf_size;
+ unsigned char *nsf_file;
+ int nsf_index;
+ int song_number;
+
+ /* nsf-specific variables */
+ int64_t last_pts;
+ unsigned int iteration;
+
+ nsf_t *nsf;
+} nsf_decoder_t;
+
+/**************************************************************************
+ * xine audio plugin functions
+ *************************************************************************/
+
+static void nsf_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
+
+ nsf_decoder_t *this = (nsf_decoder_t *) this_gen;
+ audio_buffer_t *audio_buffer;
+
+ if (buf->decoder_flags & BUF_FLAG_HEADER) {
+
+ /* When the engine sends a BUF_FLAG_HEADER flag, it is time to initialize
+ * the decoder. The buffer element type has 4 decoder_info fields,
+ * 0..3. Field 1 is the sample rate. Field 2 is the bits/sample. Field
+ * 3 is the number of channels. */
+ this->sample_rate = buf->decoder_info[1];
+ this->bits_per_sample = buf->decoder_info[2];
+ this->channels = buf->decoder_info[3];
+
+ /* take this opportunity to initialize stream/meta information */
+ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC,
+ "NES Music (Nosefart)");
+
+ this->song_number = buf->content[4];
+ /* allocate a buffer for the file */
+ this->nsf_size = BE_32(&buf->content[0]);
+ this->nsf_file = xine_xmalloc(this->nsf_size);
+ this->nsf_index = 0;
+
+ /* peform any other required initialization */
+ this->last_pts = -1;
+ this->iteration = 0;
+
+ return;
+ }
+
+ /* accumulate chunks from the NSF file until whole file is received */
+ if (this->nsf_index < this->nsf_size) {
+ xine_fast_memcpy(&this->nsf_file[this->nsf_index], buf->content,
+ buf->size);
+ this->nsf_index += buf->size;
+
+ if (this->nsf_index == this->nsf_size) {
+ /* file has been received, proceed to initialize engine */
+ nsf_init();
+ this->nsf = nsf_load(NULL, this->nsf_file, this->nsf_size);
+ if (!this->nsf) {
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "nsf: could not initialize NSF\n");
+ /* make the decoder return on every subsequent buffer */
+ this->nsf_index = 0;
+ return;
+ }
+ this->nsf->current_song = this->song_number;
+ nsf_playtrack(this->nsf, this->nsf->current_song, this->sample_rate,
+ this->bits_per_sample, this->channels);
+ }
+ return;
+ }
+
+ /* if the audio output is not open yet, open the audio output */
+ if (!this->output_open) {
+ this->output_open = this->stream->audio_out->open(
+ this->stream->audio_out,
+ this->stream,
+ this->bits_per_sample,
+ this->sample_rate,
+ _x_ao_channels2mode(this->channels));
+ }
+
+ /* if the audio still isn't open, do not go any further with the decode */
+ if (!this->output_open)
+ return;
+
+ /* check if a song change was requested */
+ if (buf->decoder_info[1]) {
+ this->nsf->current_song = buf->decoder_info[1];
+ nsf_playtrack(this->nsf, this->nsf->current_song, this->sample_rate,
+ this->bits_per_sample, this->channels);
+ }
+
+ /* time to decode a frame */
+ if (this->last_pts != -1) {
+
+ /* process a frame */
+ nsf_frame(this->nsf);
+
+ /* get an audio buffer */
+ audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out);
+ if (audio_buffer->mem_size == 0) {
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "nsf: Help! Allocated audio buffer with nothing in it!\n");
+ return;
+ }
+
+ apu_process(audio_buffer->mem, this->sample_rate / this->nsf->playback_rate);
+ audio_buffer->vpts = buf->pts;
+ audio_buffer->num_frames = this->sample_rate / this->nsf->playback_rate;
+ this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream);
+ }
+ this->last_pts = buf->pts;
+}
+
+/* This function resets the state of the audio decoder. This usually
+ * entails resetting the data accumulation buffer. */
+static void nsf_reset (audio_decoder_t *this_gen) {
+
+ nsf_decoder_t *this = (nsf_decoder_t *) this_gen;
+
+ this->last_pts = -1;
+}
+
+/* This function resets the last pts value of the audio decoder. */
+static void nsf_discontinuity (audio_decoder_t *this_gen) {
+
+ nsf_decoder_t *this = (nsf_decoder_t *) this_gen;
+
+ this->last_pts = -1;
+}
+
+/* This function closes the audio output and frees the private audio decoder
+ * structure. */
+static void nsf_dispose (audio_decoder_t *this_gen) {
+
+ nsf_decoder_t *this = (nsf_decoder_t *) this_gen;
+
+ /* close the audio output */
+ if (this->output_open)
+ this->stream->audio_out->close (this->stream->audio_out, this->stream);
+ this->output_open = 0;
+
+ /* free anything that was allocated during operation */
+ nsf_free(&this->nsf);
+ free(this->nsf_file);
+ free(this);
+}
+
+/* This function allocates, initializes, and returns a private audio
+ * decoder structure. */
+static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) {
+
+ nsf_decoder_t *this ;
+
+ this = (nsf_decoder_t *) xine_xmalloc (sizeof (nsf_decoder_t));
+
+ /* connect the member functions */
+ this->audio_decoder.decode_data = nsf_decode_data;
+ this->audio_decoder.reset = nsf_reset;
+ this->audio_decoder.discontinuity = nsf_discontinuity;
+ this->audio_decoder.dispose = nsf_dispose;
+
+ /* connect the stream */
+ this->stream = stream;
+
+ /* audio output is not open at the start */
+ this->output_open = 0;
+
+ /* initialize the basic audio parameters */
+ this->channels = 0;
+ this->sample_rate = 0;
+ this->bits_per_sample = 0;
+
+ /* return the newly-initialized audio decoder */
+ return &this->audio_decoder;
+}
+
+/* This function returns a brief string that describes (usually with the
+ * decoder's most basic name) the audio decoder plugin. */
+static char *get_identifier (audio_decoder_class_t *this) {
+ return "NSF";
+}
+
+/* This function returns a slightly longer string describing the audio
+ * decoder plugin. */
+static char *get_description (audio_decoder_class_t *this) {
+ return "NES Music audio decoder plugin";
+}
+
+/* This function frees the audio decoder class and any other memory that was
+ * allocated. */
+static void dispose_class (audio_decoder_class_t *this_gen) {
+
+ nsf_class_t *this = (nsf_class_t *)this_gen;
+
+ free (this);
+}
+
+/* This function allocates a private audio decoder class and initializes
+ * the class's member functions. */
+void *decoder_nsf_init_plugin (xine_t *xine, void *data) {
+
+ nsf_class_t *this ;
+
+ this = (nsf_class_t *) xine_xmalloc (sizeof (nsf_class_t));
+
+ this->decoder_class.open_plugin = open_plugin;
+ this->decoder_class.get_identifier = get_identifier;
+ this->decoder_class.get_description = get_description;
+ this->decoder_class.dispose = dispose_class;
+
+ return this;
+}
diff --git a/src/combined/nsf_demuxer.c b/src/combined/nsf_demuxer.c
new file mode 100644
index 000000000..b598b9e1c
--- /dev/null
+++ b/src/combined/nsf_demuxer.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2000-2003 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine 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.
+ *
+ * xine 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
+ */
+
+/*
+ * NSF File "Demuxer" by Mike Melanson (melanson@pcisys.net)
+ * This is really just a loader for NES Music File Format (extension NSF)
+ * which loads an entire NSF file and passes it over to the NSF audio
+ * decoder.
+ *
+ * After the file is sent over, the demuxer controls the playback by
+ * sending empty buffers with incrementing pts values.
+ *
+ * For more information regarding the NSF format, visit:
+ * http://www.tripoint.org/kevtris/nes/nsfspec.txt
+ *
+ * $Id: demux_nsf.c,v 1.24 2007/03/29 17:03:06 dgp85 Exp $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+/********** logging **********/
+#define LOG_MODULE "demux_nsf"
+/* #define LOG_VERBOSE */
+/* #define LOG */
+
+#include "xine_internal.h"
+#include "xineutils.h"
+#include "compat.h"
+#include "demux.h"
+#include "bswap.h"
+
+#define NSF_HEADER_SIZE 0x80
+#define NSF_SAMPLERATE 44100
+#define NSF_BITS 8
+#define NSF_CHANNELS 1
+#define NSF_REFRESH_RATE 60
+#define NSF_PTS_INC (90000 / NSF_REFRESH_RATE)
+
+typedef struct {
+ demux_plugin_t demux_plugin;
+
+ xine_stream_t *stream;
+ fifo_buffer_t *video_fifo;
+ fifo_buffer_t *audio_fifo;
+ input_plugin_t *input;
+ int status;
+
+ int total_songs;
+ int current_song;
+ int new_song; /* indicates song change */
+
+ char *title;
+ char *artist;
+ char *copyright;
+
+ off_t filesize;
+
+ int64_t current_pts;
+ int file_sent;
+} demux_nsf_t;
+
+typedef struct {
+ demux_class_t demux_class;
+} demux_nsf_class_t;
+
+/* returns 1 if the NSF file was opened successfully, 0 otherwise */
+static int open_nsf_file(demux_nsf_t *this) {
+ unsigned char header[NSF_HEADER_SIZE];
+
+ this->input->seek(this->input, 0, SEEK_SET);
+ if (this->input->read(this->input, header, NSF_HEADER_SIZE) !=
+ NSF_HEADER_SIZE)
+ return 0;
+
+ /* check for the signature */
+ if ((header[0] != 'N') ||
+ (header[1] != 'E') ||
+ (header[2] != 'S') ||
+ (header[3] != 'M') ||
+ (header[4] != 0x1A))
+ return 0;
+
+ this->total_songs = header[6];
+ this->current_song = header[7];
+ this->title = strdup(&header[0x0E]);
+ this->artist = strdup(&header[0x2E]);
+ this->copyright = strdup(&header[0x4E]);
+
+ this->filesize = this->input->get_length(this->input);
+
+ return 1;
+}
+
+static int demux_nsf_send_chunk(demux_plugin_t *this_gen) {
+ demux_nsf_t *this = (demux_nsf_t *) this_gen;
+ buf_element_t *buf;
+ int bytes_read;
+ char title[100];
+
+ /* send chunks of the file to the decoder until file is completely
+ * loaded; then send control buffers */
+ if (!this->file_sent) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_AUDIO_NSF;
+ bytes_read = this->input->read(this->input, buf->content, buf->max_size);
+
+ if (bytes_read == 0) {
+ /* the file has been completely loaded, free the buffer and start
+ * sending control buffers */
+ buf->free_buffer(buf);
+ this->file_sent = 1;
+
+ } else {
+
+ /* keep loading the file */
+ if (bytes_read < buf->max_size)
+ buf->size = bytes_read;
+ else
+ buf->size = buf->max_size;
+
+ buf->extra_info->input_normpos = 0;
+ buf->extra_info->input_time = 0;
+ buf->pts = 0;
+
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
+ }
+
+ /* this is not an 'else' because control might fall through from above */
+ if (this->file_sent) {
+ /* send a control buffer */
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+
+ if (this->new_song) {
+
+ buf->decoder_info[1] = this->current_song;
+ this->new_song = 0;
+ sprintf(title, "%s, song %d/%d",
+ this->title, this->current_song, this->total_songs);
+
+ _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, title);
+
+ _x_demux_control_newpts(this->stream, this->current_pts, 0);
+
+ } else
+ buf->decoder_info[1] = 0;
+
+ buf->type = BUF_AUDIO_NSF;
+ if(this->total_songs)
+ buf->extra_info->input_normpos = (this->current_song - 1) * 65535 / this->total_songs;
+ buf->extra_info->input_time = this->current_pts / 90;
+ buf->pts = this->current_pts;
+ buf->size = 0;
+ this->audio_fifo->put (this->audio_fifo, buf);
+
+ this->current_pts += NSF_PTS_INC;
+ }
+
+ return this->status;
+}
+
+static void demux_nsf_send_headers(demux_plugin_t *this_gen) {
+ demux_nsf_t *this = (demux_nsf_t *) this_gen;
+ buf_element_t *buf;
+ char copyright[100];
+
+ this->video_fifo = this->stream->video_fifo;
+ this->audio_fifo = this->stream->audio_fifo;
+
+ this->status = DEMUX_OK;
+
+ /* load stream information */
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0);
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1);
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS,
+ NSF_CHANNELS);
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE,
+ NSF_SAMPLERATE);
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS,
+ NSF_BITS);
+
+ _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, this->title);
+ _x_meta_info_set(this->stream, XINE_META_INFO_ARTIST, this->artist);
+ sprintf(copyright, "(C) %s", this->copyright);
+ _x_meta_info_set(this->stream, XINE_META_INFO_COMMENT, copyright);
+
+ /* send start buffers */
+ _x_demux_control_start(this->stream);
+
+ /* send init info to the audio decoder */
+ if (this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_AUDIO_NSF;
+ buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_FRAME_END;
+ buf->decoder_info[0] = 5;
+ buf->decoder_info[1] = NSF_SAMPLERATE;
+ buf->decoder_info[2] = NSF_BITS;
+ buf->decoder_info[3] = NSF_CHANNELS;
+
+ /* send the NSF filesize in the body, big endian format */
+ buf->content[0] = (this->filesize >> 24) & 0xFF;
+ buf->content[1] = (this->filesize >> 16) & 0xFF;
+ buf->content[2] = (this->filesize >> 8) & 0xFF;
+ buf->content[3] = (this->filesize >> 0) & 0xFF;
+ /* send the requested song */
+ buf->content[4] = this->current_song + 5;
+
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
+}
+
+static int demux_nsf_seek (demux_plugin_t *this_gen,
+ off_t start_pos, int start_time, int playing) {
+
+ demux_nsf_t *this = (demux_nsf_t *) this_gen;
+ start_pos = (off_t) ( (double) start_pos / 65535 *
+ this->total_songs );
+
+ /* if thread is not running, initialize demuxer */
+ if( !playing ) {
+
+ /* send new pts */
+ _x_demux_control_newpts(this->stream, 0, 0);
+
+ this->status = DEMUX_OK;
+
+ /* reposition stream at the start for loading */
+ this->input->seek(this->input, 0, SEEK_SET);
+
+ this->file_sent = 0;
+ this->current_pts = 0;
+ this->new_song = 1;
+ } else {
+ this->current_song = start_pos + 1;
+ this->new_song = 1;
+ this->current_pts = 0;
+ _x_demux_flush_engine(this->stream);
+ }
+
+ return this->status;
+}
+
+static void demux_nsf_dispose (demux_plugin_t *this_gen) {
+ demux_nsf_t *this = (demux_nsf_t *) this_gen;
+
+ free(this->title);
+ free(this->artist);
+ free(this->copyright);
+ free(this);
+}
+
+static int demux_nsf_get_status (demux_plugin_t *this_gen) {
+ demux_nsf_t *this = (demux_nsf_t *) this_gen;
+
+ return this->status;
+}
+
+/* return the approximate length in miliseconds */
+static int demux_nsf_get_stream_length (demux_plugin_t *this_gen) {
+ return 0;
+}
+
+static uint32_t demux_nsf_get_capabilities(demux_plugin_t *this_gen) {
+ return DEMUX_CAP_NOCAP;
+}
+
+static int demux_nsf_get_optional_data(demux_plugin_t *this_gen,
+ void *data, int data_type) {
+ return DEMUX_OPTIONAL_UNSUPPORTED;
+}
+
+static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream,
+ input_plugin_t *input) {
+
+ demux_nsf_t *this;
+
+ if (!INPUT_IS_SEEKABLE(input)) {
+ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "input not seekable, can not handle!\n");
+ return NULL;
+ }
+
+ this = xine_xmalloc (sizeof (demux_nsf_t));
+ this->stream = stream;
+ this->input = input;
+
+ this->demux_plugin.send_headers = demux_nsf_send_headers;
+ this->demux_plugin.send_chunk = demux_nsf_send_chunk;
+ this->demux_plugin.seek = demux_nsf_seek;
+ this->demux_plugin.dispose = demux_nsf_dispose;
+ this->demux_plugin.get_status = demux_nsf_get_status;
+ this->demux_plugin.get_stream_length = demux_nsf_get_stream_length;
+ this->demux_plugin.get_capabilities = demux_nsf_get_capabilities;
+ this->demux_plugin.get_optional_data = demux_nsf_get_optional_data;
+ this->demux_plugin.demux_class = class_gen;
+
+ this->status = DEMUX_FINISHED;
+
+ switch (stream->content_detection_method) {
+
+ case METHOD_BY_EXTENSION: {
+ const char *extensions, *mrl;
+
+ mrl = input->get_mrl (input);
+ extensions = class_gen->get_extensions (class_gen);
+
+ if (!_x_demux_check_extension (mrl, extensions)) {
+ free (this);
+ return NULL;
+ }
+ }
+ /* falling through is intended */
+
+ case METHOD_BY_CONTENT:
+ case METHOD_EXPLICIT:
+
+ if (!open_nsf_file(this)) {
+ free (this);
+ return NULL;
+ }
+
+ break;
+
+ default:
+ free (this);
+ return NULL;
+ }
+
+ return &this->demux_plugin;
+}
+
+static const char *get_description (demux_class_t *this_gen) {
+ return "NES Music file demux plugin";
+}
+
+static const char *get_identifier (demux_class_t *this_gen) {
+ return "NSF";
+}
+
+static const char *get_extensions (demux_class_t *this_gen) {
+ return "nsf";
+}
+
+static const char *get_mimetypes (demux_class_t *this_gen) {
+ return NULL;
+}
+
+static void class_dispose (demux_class_t *this_gen) {
+ demux_nsf_class_t *this = (demux_nsf_class_t *) this_gen;
+
+ free (this);
+}
+
+void *demux_nsf_init_plugin (xine_t *xine, void *data) {
+ demux_nsf_class_t *this;
+
+ this = xine_xmalloc (sizeof (demux_nsf_class_t));
+
+ this->demux_class.open_plugin = open_plugin;
+ this->demux_class.get_description = get_description;
+ this->demux_class.get_identifier = get_identifier;
+ this->demux_class.get_mimetypes = get_mimetypes;
+ this->demux_class.get_extensions = get_extensions;
+ this->demux_class.dispose = class_dispose;
+
+ return this;
+}
diff --git a/src/combined/combined_wavpack.c b/src/combined/wavpack_combined.c
index 7a334b15c..110de2b2e 100644
--- a/src/combined/combined_wavpack.c
+++ b/src/combined/wavpack_combined.c
@@ -23,7 +23,7 @@
*/
#include "xine_internal.h"
-#include "combined_wavpack.h"
+#include "wavpack_combined.h"
static const demuxer_info_t demux_info_wv = {
0 /* priority */
diff --git a/src/combined/combined_wavpack.h b/src/combined/wavpack_combined.h
index b7bf32acb..7688f91df 100644
--- a/src/combined/combined_wavpack.h
+++ b/src/combined/wavpack_combined.h
@@ -23,6 +23,7 @@
*/
#include "os_types.h"
+#include "bswap.h"
typedef struct {
uint32_t idcode; /* This should always be the string "wvpk" */
@@ -37,13 +38,9 @@ typedef struct {
uint32_t samples_count; /* Count of samples in the current frame */
uint32_t flags; /* Misc flags */
uint32_t decoded_crc32; /* CRC32 of the decoded data */
-} __attribute__((packed)) wvheader_t;
+} XINE_PACKED wvheader_t;
-#ifdef WORDS_BIGENDIAN
-static const uint32_t wvpk_signature = ('k' + ('p' << 8) + ('v' << 16) + ('w' << 24));
-#else
-static const uint32_t wvpk_signature = ('w' + ('v' << 8) + ('p' << 16) + ('k' << 24));
-#endif
+static const uint32_t wvpk_signature = ME_FOURCC('w', 'v', 'p', 'k');
void *demux_wv_init_plugin (xine_t *const xine, void *const data);
void *decoder_wavpack_init_plugin (xine_t *xine, void *data);
diff --git a/src/combined/decoder_wavpack.c b/src/combined/wavpack_decoder.c
index ec14dfbf5..1fceb3137 100644
--- a/src/combined/decoder_wavpack.c
+++ b/src/combined/wavpack_decoder.c
@@ -34,7 +34,7 @@
#include "bswap.h"
#include <wavpack/wavpack.h>
-#include "combined_wavpack.h"
+#include "wavpack_combined.h"
typedef struct {
audio_decoder_class_t decoder_class;
@@ -104,6 +104,8 @@ static int xine_buffer_set_pos_rel(void *const this_gen, const int32_t delta,
return 0;
}
+
+ return -1;
}
static int xine_buffer_set_pos_abs(void *const this_gen, const uint32_t pos) {
diff --git a/src/combined/demux_wavpack.c b/src/combined/wavpack_demuxer.c
index 6a0e33e19..da69731b1 100644
--- a/src/combined/demux_wavpack.c
+++ b/src/combined/wavpack_demuxer.c
@@ -36,7 +36,7 @@
#include "attributes.h"
#include <wavpack/wavpack.h>
-#include "combined_wavpack.h"
+#include "wavpack_combined.h"
typedef struct {
demux_plugin_t demux_plugin;