diff options
Diffstat (limited to 'src/combined')
-rw-r--r-- | src/combined/Makefile.am | 31 | ||||
-rw-r--r-- | src/combined/demux_flac.h | 28 | ||||
-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.c | 46 | ||||
-rw-r--r-- | src/combined/nsf_decoder.c | 268 | ||||
-rw-r--r-- | src/combined/nsf_demuxer.c | 391 | ||||
-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; |