diff options
Diffstat (limited to 'src/libxineadec')
50 files changed, 0 insertions, 15917 deletions
diff --git a/src/libxineadec/Makefile.am b/src/libxineadec/Makefile.am deleted file mode 100644 index ae261e60c..000000000 --- a/src/libxineadec/Makefile.am +++ /dev/null @@ -1,48 +0,0 @@ -include $(top_builddir)/misc/Makefile.plugins -include $(top_srcdir)/misc/Makefile.common - -EXTRA_DIST = fooaudio.c - -if BUILD_NOSEFART -nosefart_subdir = nosefart -nosefart_module = xineplug_decode_nsf.la -endif - -SUBDIRS = gsm610 $(nosefart_subdir) - -AM_LDFLAGS = $(xineplug_ldflags) - -if HAVE_VORBIS -vorbis_module = xineplug_decode_vorbis.la -endif - -if HAVE_SPEEX -speex_module = xineplug_decode_speex.la -endif - -xineplug_LTLIBRARIES = \ - xineplug_decode_gsm610.la \ - $(nosefart_module) \ - xineplug_decode_lpcm.la \ - $(vorbis_module) \ - $(speex_module) - -xineplug_decode_gsm610_la_SOURCES = gsm610.c -xineplug_decode_gsm610_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_decode_gsm610_la_LIBADD = $(XINE_LIB) gsm610/libgsm610.la - -xineplug_decode_nsf_la_SOURCES = nsf.c -xineplug_decode_nsf_la_CFLAGS = $(VISIBILITY_FLAG) -DNSF_PLAYER -fno-strict-aliasing -xineplug_decode_nsf_la_LIBADD = $(XINE_LIB) -lm nosefart/libnosefart.la - -xineplug_decode_lpcm_la_SOURCES = xine_lpcm_decoder.c -xineplug_decode_lpcm_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_decode_lpcm_la_LIBADD = $(XINE_LIB) - -xineplug_decode_vorbis_la_SOURCES = xine_vorbis_decoder.c -xineplug_decode_vorbis_la_LIBADD = $(XINE_LIB) $(VORBIS_LIBS) $(OGG_LIBS) $(LTLIBINTL) -xineplug_decode_vorbis_la_CFLAGS = $(VISIBILITY_FLAG) $(VORBIS_CFLAGS) - -xineplug_decode_speex_la_SOURCES = xine_speex_decoder.c -xineplug_decode_speex_la_LIBADD = $(XINE_LIB) $(SPEEX_LIBS) -xineplug_decode_speex_la_CFLAGS = $(VISIBILITY_FLAGS) $(SPEEX_CFLAGS) diff --git a/src/libxineadec/fooaudio.c b/src/libxineadec/fooaudio.c deleted file mode 100644 index 776136fc2..000000000 --- a/src/libxineadec/fooaudio.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * fooaudio.c: This is a reference audio decoder for the xine multimedia - * player. It really works too! It will output a continuous sine wave in - * place of the data it should actually send. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#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" - -/* math.h required for fooaudio sine wave generation */ -#include <math.h> - -#define AUDIOBUFSIZE 128*1024 - -typedef struct { - audio_decoder_class_t decoder_class; -} fooaudio_class_t; - -typedef struct fooaudio_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 */ - - unsigned char *buf; /* data accumulation buffer */ - int bufsize; /* maximum size of buf */ - int size; /* size of accumulated data in buf */ - - /* fooaudio-specific variables */ - int64_t last_pts; - unsigned int iteration; - -} fooaudio_decoder_t; - -/************************************************************************** - * fooaudio specific decode functions - *************************************************************************/ - -/************************************************************************** - * xine audio plugin functions - *************************************************************************/ - -static void fooaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { - - fooaudio_decoder_t *this = (fooaudio_decoder_t *) this_gen; - audio_buffer_t *audio_buffer; - int i; - int64_t samples_to_generate; - int samples_to_send; - - if (buf->decoder_flags & BUF_FLAG_STDHEADER) { - - /* 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]; - - /* initialize the data accumulation buffer */ - this->buf = calloc(1, AUDIOBUFSIZE); - this->bufsize = AUDIOBUFSIZE; - this->size = 0; - - /* take this opportunity to initialize stream/meta information */ - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "fooaudio"); - - /* perform any other required initialization */ - this->last_pts = -1; - this->iteration = 0; - - return; - } - - /* if the audio output is not open yet, open the audio output */ -#warning: Audio output is hardcoded to mono 16-bit PCM - if (!this->output_open) { - this->output_open = (this->stream->audio_out->open) ( - this->stream->audio_out, - this->stream, -/* this->bits_per_sample, */ - 16, - this->sample_rate, -/* _x_ao_channels2mode(this->channels));*/ - AO_CAP_MODE_MONO); - } - - /* if the audio still isn't open, do not go any further with the decode */ - if (!this->output_open) - return; - - /* accumulate the data passed through the buffer element type; increase - * the accumulator buffer size as necessary */ - if( this->size + buf->size > this->bufsize ) { - this->bufsize = this->size + 2 * buf->size; - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "fooaudio: increasing source buffer to %d to avoid overflow.\n", this->bufsize); - this->buf = realloc( this->buf, this->bufsize ); - } - xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); - this->size += buf->size; - - /* When a buffer element type has the BUF_FLAG_FRAME_END flag set, it is - * time to decode the data in the buffer. */ - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - - /* This is where the real meat of the audio decoder is implemented. - * The general strategy is to decode the data in the accumulation buffer - * into raw PCM data and then dispatch the PCM to the engine in smaller - * buffers. What follows in the inside of this scope is the meat of - * this particular audio decoder. */ - - /* Operation of the fooaudio decoder: - * This decoder generates a continuous sine pattern based on the pts - * values sent by the xine engine. Two pts values are needed to know - * how long to make the audio. Thus, If this is the first frame or - * a seek has occurred (indicated by this->last_pts = -1), - * log the pts but do not create any audio. - * - * When a valid pts delta is generated, create n audio samples, where - * n is given as: - * - * n pts delta - * ----------- = --------- => n = (pts delta * sample rate) / 90000 - * sample rate 90000 - * - */ - - if (this->last_pts != -1) { - - /* no real reason to set this variable to 0 first; I just wanted the - * novelty of using all 4 basic arithmetic ops in a row (+ - * /) */ - samples_to_generate = 0; - samples_to_generate += buf->pts; - samples_to_generate -= this->last_pts; - samples_to_generate *= this->sample_rate; - samples_to_generate /= 90000; - - /* save the pts now since it will likely be trashed later */ - this->last_pts = buf->pts; - - while (samples_to_generate) { - - /* 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, - "fooaudio: Help! Allocated audio buffer with nothing in it!\n"); - return; - } - - /* samples_to_generate is a sample count; mem_size is a byte count */ - if (samples_to_generate > audio_buffer->mem_size / 2) - samples_to_send = audio_buffer->mem_size / 2; - else - samples_to_send = samples_to_generate; - samples_to_generate -= samples_to_send; - -#define WAVE_HZ 300 - /* fill up the samples in the buffer */ - for (i = 0; i < samples_to_send; i++) - audio_buffer->mem[i] = - (short)(sin(2 * M_PI * this->iteration++ / WAVE_HZ) * 32767); - - /* final prep for audio buffer dispatch */ - audio_buffer->num_frames = samples_to_send; - audio_buffer->vpts = buf->pts; - buf->pts = 0; /* only first buffer gets the real pts */ - this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); - - } - } else { - /* log the pts for the next time */ - this->last_pts = buf->pts; - } - - /* reset data accumulation buffer */ - this->size = 0; - } -} - -/* This function resets the state of the audio decoder. This usually - * entails resetting the data accumulation buffer. */ -static void fooaudio_reset (audio_decoder_t *this_gen) { - - fooaudio_decoder_t *this = (fooaudio_decoder_t *) this_gen; - - this->size = 0; - - /* this is specific to fooaudio */ - this->last_pts = -1; -} - -/* This function resets the last pts value of the audio decoder. */ -static void fooaudio_discontinuity (audio_decoder_t *this_gen) { - - fooaudio_decoder_t *this = (fooaudio_decoder_t *) this_gen; - - /* this is specific to fooaudio */ - this->last_pts = -1; -} - -/* This function closes the audio output and frees the private audio decoder - * structure. */ -static void fooaudio_dispose (audio_decoder_t *this_gen) { - - fooaudio_decoder_t *this = (fooaudio_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 */ - free(this->buf); - 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) { - - fooaudio_decoder_t *this ; - - this = (fooaudio_decoder_t *) calloc(1, sizeof(fooaudio_decoder_t)); - - /* connect the member functions */ - this->audio_decoder.decode_data = fooaudio_decode_data; - this->audio_decoder.reset = fooaudio_reset; - this->audio_decoder.discontinuity = fooaudio_discontinuity; - this->audio_decoder.dispose = fooaudio_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; - - /* initialize the data accumulation buffer */ - this->buf = NULL; - this->bufsize = 0; - this->size = 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 "fooaudio"; -} - -/* This function returns a slightly longer string describing the audio - * decoder plugin. */ -static char *get_description (audio_decoder_class_t *this) { - return "fooaudio: reference xine 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) { - - fooaudio_class_t *this = (fooaudio_class_t *)this_gen; - - free (this); -} - -/* This function allocates a private audio decoder class and initializes - * the class's member functions. */ -static void *init_plugin (xine_t *xine, void *data) { - - fooaudio_class_t *this ; - - this = (fooaudio_class_t *) xine_malloc (sizeof (fooaudio_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; -} - -/* This is a list of all of the internal xine audio buffer types that - * this decoder is able to handle. Check src/xine-engine/buffer.h for a - * list of valid buffer types (and add a new one if the one you need does - * not exist). Terminate the list with a 0. */ -static uint32_t audio_types[] = { - /* BUF_AUDIO_FOO, */ - 0 -}; - -/* This data structure combines the list of supported xine buffer types and - * the priority that the plugin should be given with respect to other - * plugins that handle the same buffer type. A plugin with priority (n+1) - * will be used instead of a plugin with priority (n). */ -static const decoder_info_t dec_info_audio = { - audio_types, /* supported types */ - 5 /* priority */ -}; - -/* The plugin catalog entry. This is the only information that this plugin - * will export to the public. */ -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* { type, API version, "name", version, special_info, init_function }, */ - { PLUGIN_AUDIO_DECODER, 15, "fooaudio", XINE_VERSION_CODE, &dec_info_audio, &init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; - diff --git a/src/libxineadec/gsm610.c b/src/libxineadec/gsm610.c deleted file mode 100644 index c67382bc5..000000000 --- a/src/libxineadec/gsm610.c +++ /dev/null @@ -1,293 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * GSM 6.10 Audio Decoder - * This decoder is based on the GSM 6.10 codec library found at: - * http://kbs.cs.tu-berlin.de/~jutta/toast.html - * Additionally, here is an article regarding the software that appeared - * in Dr. Dobbs Journal: - * http://www.ddj.com/documents/s=1012/ddj9412b/9412b.htm - * - * This is the notice that comes with the software: - * -------------------------------------------------------------------- - * Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, - * Technische Universitaet Berlin - * - * Any use of this software is permitted provided that this notice is not - * removed and that neither the authors nor the Technische Universitaet Berlin - * are deemed to have made any representations as to the suitability of this - * software for any purpose nor are held responsible for any defects of - * this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - * - * As a matter of courtesy, the authors request to be informed about uses - * this software has found, about bugs in this software, and about any - * improvements that may be of general interest. - * - * Berlin, 28.11.1994 - * Jutta Degener - * Carsten Bormann - * -------------------------------------------------------------------- - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <string.h> - -#include "xine_internal.h" -#include "audio_out.h" -#include "buffer.h" -#include "xineutils.h" -#include "bswap.h" - -#include "gsm610/private.h" -#include "gsm610/gsm.h" - -#define AUDIOBUFSIZE 128*1024 - -#define GSM610_SAMPLE_SIZE 16 -#define GSM610_BLOCK_SIZE 160 - -typedef struct { - audio_decoder_class_t decoder_class; -} gsm610_class_t; - -typedef struct gsm610_decoder_s { - audio_decoder_t audio_decoder; - - xine_stream_t *stream; - - unsigned int buf_type; - int output_open; - int sample_rate; - - unsigned char *buf; - int bufsize; - int size; - - unsigned short decode_buffer[GSM610_BLOCK_SIZE]; - gsm gsm_state; - -} gsm610_decoder_t; - -/************************************************************************** - * xine audio plugin functions - *************************************************************************/ - -static void gsm610_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { - - gsm610_decoder_t *this = (gsm610_decoder_t *) this_gen; - audio_buffer_t *audio_buffer; - int in_ptr; - - if (buf->decoder_flags & BUF_FLAG_STDHEADER) { - this->sample_rate = buf->decoder_info[1]; - - this->buf = calloc(1, AUDIOBUFSIZE); - this->bufsize = AUDIOBUFSIZE; - this->size = 0; - - /* stream/meta info */ - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "GSM 6.10"); - - return; - } - - if (!this->output_open) { - - this->gsm_state = gsm_create(); - this->buf_type = buf->type; - - this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, - this->stream, GSM610_SAMPLE_SIZE, this->sample_rate, AO_CAP_MODE_MONO); - } - - /* if the audio still isn't open, bail */ - if (!this->output_open) - return; - - if( this->size + buf->size > this->bufsize ) { - this->bufsize = this->size + 2 * buf->size; - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "gsm610: increasing source buffer to %d to avoid overflow.\n", this->bufsize); - this->buf = realloc( this->buf, this->bufsize ); - } - - xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); - this->size += buf->size; - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */ - - /* handle the Microsoft variant of GSM data */ - if (this->buf_type == BUF_AUDIO_MSGSM) { - - this->gsm_state->wav_fmt = 1; - - /* the data should line up on a 65-byte boundary */ - if ((buf->size % 65) != 0) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, - "gsm610: received MS GSM block that does not line up\n"); - this->size = 0; - return; - } - - in_ptr = 0; - while (this->size) { - gsm_decode(this->gsm_state, &this->buf[in_ptr], this->decode_buffer); - if ((in_ptr % 65) == 0) { - in_ptr += 33; - this->size -= 33; - } else { - in_ptr += 32; - this->size -= 32; - } - - /* dispatch the decoded audio; assume that the audio buffer will - * always contain at least 160 samples */ - audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); - - xine_fast_memcpy(audio_buffer->mem, this->decode_buffer, - GSM610_BLOCK_SIZE * 2); - audio_buffer->num_frames = GSM610_BLOCK_SIZE; - - audio_buffer->vpts = buf->pts; - buf->pts = 0; /* only first buffer gets the real pts */ - this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); - } - } else { - - /* handle the other variant, which consists of 33-byte blocks */ - this->gsm_state->wav_fmt = 0; - - /* the data should line up on a 33-byte boundary */ - if ((buf->size % 33) != 0) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "gsm610: received GSM block that does not line up\n"); - this->size = 0; - return; - } - - in_ptr = 0; - while (this->size) { - gsm_decode(this->gsm_state, &this->buf[in_ptr], this->decode_buffer); - in_ptr += 33; - this->size -= 33; - - /* dispatch the decoded audio; assume that the audio buffer will - * always contain at least 160 samples */ - audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); - - xine_fast_memcpy(audio_buffer->mem, this->decode_buffer, - GSM610_BLOCK_SIZE * 2); - audio_buffer->num_frames = GSM610_BLOCK_SIZE; - - audio_buffer->vpts = buf->pts; - buf->pts = 0; /* only first buffer gets the real pts */ - this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); - } - } - } -} - -static void gsm610_reset (audio_decoder_t *this_gen) { -} - -static void gsm610_discontinuity (audio_decoder_t *this_gen) { -} - -static void gsm610_dispose (audio_decoder_t *this_gen) { - - gsm610_decoder_t *this = (gsm610_decoder_t *) this_gen; - - if (this->gsm_state) - gsm_destroy(this->gsm_state); - - if (this->output_open) - this->stream->audio_out->close (this->stream->audio_out, this->stream); - this->output_open = 0; - - if (this->buf) - free(this->buf); - - free (this_gen); -} - -static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { - - gsm610_decoder_t *this ; - - this = (gsm610_decoder_t *) calloc(1, sizeof(gsm610_decoder_t)); - - this->audio_decoder.decode_data = gsm610_decode_data; - this->audio_decoder.reset = gsm610_reset; - this->audio_decoder.discontinuity = gsm610_discontinuity; - this->audio_decoder.dispose = gsm610_dispose; - - this->output_open = 0; - this->sample_rate = 0; - this->stream = stream; - this->buf = NULL; - this->size = 0; - - return &this->audio_decoder; -} - -static char *get_identifier (audio_decoder_class_t *this) { - return "GSM 6.10"; -} - -static char *get_description (audio_decoder_class_t *this) { - return "GSM 6.10 audio decoder plugin"; -} - -static void dispose_class (audio_decoder_class_t *this) { - free (this); -} - -static void *init_plugin (xine_t *xine, void *data) { - - gsm610_class_t *this ; - - this = (gsm610_class_t *) calloc(1, sizeof(gsm610_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; -} - -static uint32_t audio_types[] = { - BUF_AUDIO_MSGSM, - BUF_AUDIO_GSM610, - 0 -}; - -static const decoder_info_t dec_info_audio = { - audio_types, /* supported types */ - 9 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_AUDIO_DECODER, 15, "gsm610", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxineadec/gsm610/Makefile.am b/src/libxineadec/gsm610/Makefile.am deleted file mode 100644 index 6ec2e0a5e..000000000 --- a/src/libxineadec/gsm610/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -include $(top_srcdir)/misc/Makefile.common - -noinst_LTLIBRARIES = libgsm610.la - -libgsm610_la_SOURCES = \ - add.c \ - decode.c \ - gsm_create.c \ - gsm_decode.c \ - gsm_destroy.c \ - long_term.c \ - lpc.c \ - rpe.c \ - short_term.c \ - table.c - -libgsm610_la_CFLAGS = $(VISIBILITY_FLAG) -libgsm610_la_LDFLAGS = $(xineplug_ldflags) - -noinst_HEADERS = \ - gsm_config.h \ - gsm.h \ - private.h \ - proto.h \ - unproto.h diff --git a/src/libxineadec/gsm610/add.c b/src/libxineadec/gsm610/add.c deleted file mode 100644 index cd4b5dd3b..000000000 --- a/src/libxineadec/gsm610/add.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische - * Universitaet Berlin. See the accompanying file "COPYRIGHT" for - * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - */ - -/* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/add.c,v 1.1 2002/10/12 19:12:49 tmmm Exp $ */ - -/* - * See private.h for the more commonly used macro versions. - */ - -#include <stdio.h> -#include <assert.h> - -#include "private.h" -#include "gsm.h" -#include "proto.h" - -#define saturate(x) \ - ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x)) - -word gsm_add P2((a,b), word a, word b) -{ - longword sum = (longword)a + (longword)b; - return saturate(sum); -} - -word gsm_sub P2((a,b), word a, word b) -{ - longword diff = (longword)a - (longword)b; - return saturate(diff); -} - -word gsm_mult P2((a,b), word a, word b) -{ - if (a == MIN_WORD && b == MIN_WORD) return MAX_WORD; - else return SASR( (longword)a * (longword)b, 15 ); -} - -word gsm_mult_r P2((a,b), word a, word b) -{ - if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD; - else { - longword prod = (longword)a * (longword)b + 16384; - prod >>= 15; - return prod & 0xFFFF; - } -} - -word gsm_abs P1((a), word a) -{ - return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a; -} - -longword gsm_L_mult P2((a,b),word a, word b) -{ - assert( a != MIN_WORD || b != MIN_WORD ); - return ((longword)a * (longword)b) << 1; -} - -longword gsm_L_add P2((a,b), longword a, longword b) -{ - if (a < 0) { - if (b >= 0) return a + b; - else { - ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1); - return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2; - } - } - else if (b <= 0) return a + b; - else { - ulongword A = (ulongword)a + (ulongword)b; - return A > MAX_LONGWORD ? MAX_LONGWORD : A; - } -} - -longword gsm_L_sub P2((a,b), longword a, longword b) -{ - if (a >= 0) { - if (b >= 0) return a - b; - else { - /* a>=0, b<0 */ - - ulongword A = (ulongword)a + -(b + 1); - return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1); - } - } - else if (b <= 0) return a - b; - else { - /* a<0, b>0 */ - - ulongword A = (ulongword)-(a + 1) + b; - return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1; - } -} - -static unsigned char const bitoff[ 256 ] = { - 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -word gsm_norm P1((a), longword a ) -/* - * the number of left shifts needed to normalize the 32 bit - * variable L_var1 for positive values on the interval - * - * with minimum of - * minimum of 1073741824 (01000000000000000000000000000000) and - * maximum of 2147483647 (01111111111111111111111111111111) - * - * - * and for negative values on the interval with - * minimum of -2147483648 (-10000000000000000000000000000000) and - * maximum of -1073741824 ( -1000000000000000000000000000000). - * - * in order to normalize the result, the following - * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 ); - * - * (That's 'ffs', only from the left, not the right..) - */ -{ - assert(a != 0); - - if (a < 0) { - if (a <= -1073741824) return 0; - a = ~a; - } - - return a & 0xffff0000 - ? ( a & 0xff000000 - ? -1 + bitoff[ 0xFF & (a >> 24) ] - : 7 + bitoff[ 0xFF & (a >> 16) ] ) - : ( a & 0xff00 - ? 15 + bitoff[ 0xFF & (a >> 8) ] - : 23 + bitoff[ 0xFF & a ] ); -} - -longword gsm_L_asl P2((a,n), longword a, int n) -{ - if (n >= 32) return 0; - if (n <= -32) return -(a < 0); - if (n < 0) return gsm_L_asr(a, -n); - return a << n; -} - -word gsm_asl P2((a,n), word a, int n) -{ - if (n >= 16) return 0; - if (n <= -16) return -(a < 0); - if (n < 0) return gsm_asr(a, -n); - return a << n; -} - -longword gsm_L_asr P2((a,n), longword a, int n) -{ - if (n >= 32) return -(a < 0); - if (n <= -32) return 0; - if (n < 0) return a << -n; - -# ifdef SASR - return a >> n; -# else - if (a >= 0) return a >> n; - else return -(longword)( -(ulongword)a >> n ); -# endif -} - -word gsm_asr P2((a,n), word a, int n) -{ - if (n >= 16) return -(a < 0); - if (n <= -16) return 0; - if (n < 0) return a << -n; - -# ifdef SASR - return a >> n; -# else - if (a >= 0) return a >> n; - else return -(word)( -(uword)a >> n ); -# endif -} - -/* - * (From p. 46, end of section 4.2.5) - * - * NOTE: The following lines gives [sic] one correct implementation - * of the div(num, denum) arithmetic operation. Compute div - * which is the integer division of num by denum: with denum - * >= num > 0 - */ - -word gsm_div P2((num,denum), word num, word denum) -{ - longword L_num = num; - longword L_denum = denum; - word div = 0; - int k = 15; - - /* The parameter num sometimes becomes zero. - * Although this is explicitly guarded against in 4.2.5, - * we assume that the result should then be zero as well. - */ - - /* assert(num != 0); */ - - assert(num >= 0 && denum >= num); - if (num == 0) - return 0; - - while (k--) { - div <<= 1; - L_num <<= 1; - - if (L_num >= L_denum) { - L_num -= L_denum; - div++; - } - } - - return div; -} diff --git a/src/libxineadec/gsm610/decode.c b/src/libxineadec/gsm610/decode.c deleted file mode 100644 index 66dcab665..000000000 --- a/src/libxineadec/gsm610/decode.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische - * Universitaet Berlin. See the accompanying file "COPYRIGHT" for - * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - */ - -/* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/decode.c,v 1.1 2002/10/12 19:12:49 tmmm Exp $ */ - -#include <stdio.h> - -#include "private.h" -#include "gsm.h" -#include "proto.h" - -/* - * 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER - */ - -static void Postprocessing P2((S,s), - struct gsm_state * S, - register word * s) -{ - register int k; - register word msr = S->msr; - register longword ltmp; /* for GSM_ADD */ - register word tmp; - - for (k = 160; k--; s++) { - tmp = GSM_MULT_R( msr, 28180 ); - msr = GSM_ADD(*s, tmp); /* Deemphasis */ - *s = GSM_ADD(msr, msr) & 0xFFF8; /* Truncation & Upscaling */ - } - S->msr = msr; -} - -void Gsm_Decoder P8((S,LARcr, Ncr,bcr,Mcr,xmaxcr,xMcr,s), - struct gsm_state * S, - - word * LARcr, /* [0..7] IN */ - - word * Ncr, /* [0..3] IN */ - word * bcr, /* [0..3] IN */ - word * Mcr, /* [0..3] IN */ - word * xmaxcr, /* [0..3] IN */ - word * xMcr, /* [0..13*4] IN */ - - word * s) /* [0..159] OUT */ -{ - int j, k; - word erp[40], wt[160]; - word * drp = S->dp0 + 120; - - for (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) { - - Gsm_RPE_Decoding( S, *xmaxcr, *Mcr, xMcr, erp ); - Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp ); - - for (k = 0; k <= 39; k++) wt[ j * 40 + k ] = drp[ k ]; - } - - Gsm_Short_Term_Synthesis_Filter( S, LARcr, wt, s ); - Postprocessing(S, s); -} diff --git a/src/libxineadec/gsm610/gsm.h b/src/libxineadec/gsm610/gsm.h deleted file mode 100644 index 34ad8f7a5..000000000 --- a/src/libxineadec/gsm610/gsm.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische - * Universitaet Berlin. See the accompanying file "COPYRIGHT" for - * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - */ - -/*$Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/gsm.h,v 1.1 2002/10/12 19:12:49 tmmm Exp $*/ - -#ifndef GSM_H -#define GSM_H - -#ifdef __cplusplus -# define NeedFunctionPrototypes 1 -#endif - -#if __STDC__ -# define NeedFunctionPrototypes 1 -#endif - -#ifdef _NO_PROTO -# undef NeedFunctionPrototypes -#endif - -#ifdef NeedFunctionPrototypes -# include <stdio.h> /* for FILE * */ -#endif - -#undef GSM_P -#if NeedFunctionPrototypes -# define GSM_P( protos ) protos -#else -# define GSM_P( protos ) ( /* protos */ ) -#endif - -/* - * Interface - */ - -typedef struct gsm_state * gsm; -typedef short gsm_signal; /* signed 16 bit */ -typedef unsigned char gsm_byte; -typedef gsm_byte gsm_frame[33]; /* 33 * 8 bits */ - -#define GSM_MAGIC 0xD /* 13 kbit/s RPE-LTP */ - -#define GSM_PATCHLEVEL 10 -#define GSM_MINOR 0 -#define GSM_MAJOR 1 - -#define GSM_OPT_VERBOSE 1 -#define GSM_OPT_FAST 2 -#define GSM_OPT_LTP_CUT 3 -#define GSM_OPT_WAV49 4 -#define GSM_OPT_FRAME_INDEX 5 -#define GSM_OPT_FRAME_CHAIN 6 - -extern gsm gsm_create GSM_P((void)); -extern void gsm_destroy GSM_P((gsm)); - -extern int gsm_print GSM_P((FILE *, gsm, gsm_byte *)); -extern int gsm_option GSM_P((gsm, int, int *)); - -extern void gsm_encode GSM_P((gsm, gsm_signal *, gsm_byte *)); -extern int gsm_decode GSM_P((gsm, gsm_byte *, gsm_signal *)); - -extern int gsm_explode GSM_P((gsm, gsm_byte *, gsm_signal *)); -extern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte *)); - -#undef GSM_P - -#endif /* GSM_H */ diff --git a/src/libxineadec/gsm610/gsm_config.h b/src/libxineadec/gsm610/gsm_config.h deleted file mode 100644 index a40004221..000000000 --- a/src/libxineadec/gsm610/gsm_config.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische - * Universitaet Berlin. See the accompanying file "COPYRIGHT" for - * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - */ - -/*$Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/gsm_config.h,v 1.2 2004/05/12 16:21:41 mroi Exp $*/ - -#ifndef CONFIG_H -#define CONFIG_H - -/*efine SIGHANDLER_T int / * signal handlers are void */ -/*efine HAS_SYSV_SIGNAL 1 / * sigs not blocked/reset? */ - -#define HAS_STDLIB_H 1 /* /usr/include/stdlib.h */ -/*efine HAS_LIMITS_H 1 / * /usr/include/limits.h */ -#define HAS_FCNTL_H 1 /* /usr/include/fcntl.h */ -/*efine HAS_ERRNO_DECL 1 / * errno.h declares errno */ - -#define HAS_FSTAT 1 /* fstat syscall */ -#define HAS_FCHMOD 1 /* fchmod syscall */ -#define HAS_CHMOD 1 /* chmod syscall */ -#define HAS_FCHOWN 1 /* fchown syscall */ -#define HAS_CHOWN 1 /* chown syscall */ -/*efine HAS__FSETMODE 1 / * _fsetmode -- set file mode */ - -#define HAS_STRING_H 1 /* /usr/include/string.h */ -/*efine HAS_STRINGS_H 1 / * /usr/include/strings.h */ - -#define HAS_UNISTD_H 1 /* /usr/include/unistd.h */ -#define HAS_UTIME 1 /* POSIX utime(path, times) */ -/*efine HAS_UTIMES 1 / * use utimes() syscall instead */ -#define HAS_UTIME_H 1 /* UTIME header file */ -/*efine HAS_UTIMBUF 1 / * struct utimbuf */ -/*efine HAS_UTIMEUSEC 1 / * microseconds in utimbuf? */ - -#endif /* CONFIG_H */ diff --git a/src/libxineadec/gsm610/gsm_create.c b/src/libxineadec/gsm610/gsm_create.c deleted file mode 100644 index df80758f0..000000000 --- a/src/libxineadec/gsm610/gsm_create.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische - * Universitaet Berlin. See the accompanying file "COPYRIGHT" for - * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - */ - -static char const ident[] = "$Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/gsm_create.c,v 1.1 2002/10/12 19:12:49 tmmm Exp $"; - -#include "gsm_config.h" - -#ifdef HAS_STRING_H -#include <string.h> -#else -# include "proto.h" - extern char * memset P((char *, int, int)); -#endif - -#ifdef HAS_STDLIB_H -# include <stdlib.h> -#else -# ifdef HAS_MALLOC_H -# include <malloc.h> -# else - extern char * malloc(); -# endif -#endif - -#include <stdio.h> - -#include "gsm.h" -#include "private.h" -#include "proto.h" - -gsm gsm_create P0() -{ - gsm r; - - r = (gsm)malloc(sizeof(struct gsm_state)); - if (!r) return r; - - memset((char *)r, 0, sizeof(*r)); - r->nrp = 40; - - return r; -} diff --git a/src/libxineadec/gsm610/gsm_decode.c b/src/libxineadec/gsm610/gsm_decode.c deleted file mode 100644 index 849818c14..000000000 --- a/src/libxineadec/gsm610/gsm_decode.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische - * Universitaet Berlin. See the accompanying file "COPYRIGHT" for - * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - */ - -/* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/gsm_decode.c,v 1.1 2002/10/12 19:12:49 tmmm Exp $ */ - -#include "private.h" - -#include "gsm.h" -#include "proto.h" - -int gsm_decode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target) -{ - word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; - - if (s->wav_fmt) { - - uword sr = 0; - - s->frame_index = !s->frame_index; - if (s->frame_index) { - - sr = *c++; - LARc[0] = sr & 0x3f; sr >>= 6; - sr |= (uword)*c++ << 2; - LARc[1] = sr & 0x3f; sr >>= 6; - sr |= (uword)*c++ << 4; - LARc[2] = sr & 0x1f; sr >>= 5; - LARc[3] = sr & 0x1f; sr >>= 5; - sr |= (uword)*c++ << 2; - LARc[4] = sr & 0xf; sr >>= 4; - LARc[5] = sr & 0xf; sr >>= 4; - sr |= (uword)*c++ << 2; /* 5 */ - LARc[6] = sr & 0x7; sr >>= 3; - LARc[7] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 4; - Nc[0] = sr & 0x7f; sr >>= 7; - bc[0] = sr & 0x3; sr >>= 2; - Mc[0] = sr & 0x3; sr >>= 2; - sr |= (uword)*c++ << 1; - xmaxc[0] = sr & 0x3f; sr >>= 6; - xmc[0] = sr & 0x7; sr >>= 3; - sr = *c++; - xmc[1] = sr & 0x7; sr >>= 3; - xmc[2] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 2; - xmc[3] = sr & 0x7; sr >>= 3; - xmc[4] = sr & 0x7; sr >>= 3; - xmc[5] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 1; /* 10 */ - xmc[6] = sr & 0x7; sr >>= 3; - xmc[7] = sr & 0x7; sr >>= 3; - xmc[8] = sr & 0x7; sr >>= 3; - sr = *c++; - xmc[9] = sr & 0x7; sr >>= 3; - xmc[10] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 2; - xmc[11] = sr & 0x7; sr >>= 3; - xmc[12] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 4; - Nc[1] = sr & 0x7f; sr >>= 7; - bc[1] = sr & 0x3; sr >>= 2; - Mc[1] = sr & 0x3; sr >>= 2; - sr |= (uword)*c++ << 1; - xmaxc[1] = sr & 0x3f; sr >>= 6; - xmc[13] = sr & 0x7; sr >>= 3; - sr = *c++; /* 15 */ - xmc[14] = sr & 0x7; sr >>= 3; - xmc[15] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 2; - xmc[16] = sr & 0x7; sr >>= 3; - xmc[17] = sr & 0x7; sr >>= 3; - xmc[18] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 1; - xmc[19] = sr & 0x7; sr >>= 3; - xmc[20] = sr & 0x7; sr >>= 3; - xmc[21] = sr & 0x7; sr >>= 3; - sr = *c++; - xmc[22] = sr & 0x7; sr >>= 3; - xmc[23] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 2; - xmc[24] = sr & 0x7; sr >>= 3; - xmc[25] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 4; /* 20 */ - Nc[2] = sr & 0x7f; sr >>= 7; - bc[2] = sr & 0x3; sr >>= 2; - Mc[2] = sr & 0x3; sr >>= 2; - sr |= (uword)*c++ << 1; - xmaxc[2] = sr & 0x3f; sr >>= 6; - xmc[26] = sr & 0x7; sr >>= 3; - sr = *c++; - xmc[27] = sr & 0x7; sr >>= 3; - xmc[28] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 2; - xmc[29] = sr & 0x7; sr >>= 3; - xmc[30] = sr & 0x7; sr >>= 3; - xmc[31] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 1; - xmc[32] = sr & 0x7; sr >>= 3; - xmc[33] = sr & 0x7; sr >>= 3; - xmc[34] = sr & 0x7; sr >>= 3; - sr = *c++; /* 25 */ - xmc[35] = sr & 0x7; sr >>= 3; - xmc[36] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 2; - xmc[37] = sr & 0x7; sr >>= 3; - xmc[38] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 4; - Nc[3] = sr & 0x7f; sr >>= 7; - bc[3] = sr & 0x3; sr >>= 2; - Mc[3] = sr & 0x3; sr >>= 2; - sr |= (uword)*c++ << 1; - xmaxc[3] = sr & 0x3f; sr >>= 6; - xmc[39] = sr & 0x7; sr >>= 3; - sr = *c++; - xmc[40] = sr & 0x7; sr >>= 3; - xmc[41] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 2; /* 30 */ - xmc[42] = sr & 0x7; sr >>= 3; - xmc[43] = sr & 0x7; sr >>= 3; - xmc[44] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 1; - xmc[45] = sr & 0x7; sr >>= 3; - xmc[46] = sr & 0x7; sr >>= 3; - xmc[47] = sr & 0x7; sr >>= 3; - sr = *c++; - xmc[48] = sr & 0x7; sr >>= 3; - xmc[49] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 2; - xmc[50] = sr & 0x7; sr >>= 3; - xmc[51] = sr & 0x7; sr >>= 3; - - s->frame_chain = sr & 0xf; - } - else { - sr = s->frame_chain; - sr |= (uword)*c++ << 4; /* 1 */ - LARc[0] = sr & 0x3f; sr >>= 6; - LARc[1] = sr & 0x3f; sr >>= 6; - sr = *c++; - LARc[2] = sr & 0x1f; sr >>= 5; - sr |= (uword)*c++ << 3; - LARc[3] = sr & 0x1f; sr >>= 5; - LARc[4] = sr & 0xf; sr >>= 4; - sr |= (uword)*c++ << 2; - LARc[5] = sr & 0xf; sr >>= 4; - LARc[6] = sr & 0x7; sr >>= 3; - LARc[7] = sr & 0x7; sr >>= 3; - sr = *c++; /* 5 */ - Nc[0] = sr & 0x7f; sr >>= 7; - sr |= (uword)*c++ << 1; - bc[0] = sr & 0x3; sr >>= 2; - Mc[0] = sr & 0x3; sr >>= 2; - sr |= (uword)*c++ << 5; - xmaxc[0] = sr & 0x3f; sr >>= 6; - xmc[0] = sr & 0x7; sr >>= 3; - xmc[1] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 1; - xmc[2] = sr & 0x7; sr >>= 3; - xmc[3] = sr & 0x7; sr >>= 3; - xmc[4] = sr & 0x7; sr >>= 3; - sr = *c++; - xmc[5] = sr & 0x7; sr >>= 3; - xmc[6] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 2; /* 10 */ - xmc[7] = sr & 0x7; sr >>= 3; - xmc[8] = sr & 0x7; sr >>= 3; - xmc[9] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 1; - xmc[10] = sr & 0x7; sr >>= 3; - xmc[11] = sr & 0x7; sr >>= 3; - xmc[12] = sr & 0x7; sr >>= 3; - sr = *c++; - Nc[1] = sr & 0x7f; sr >>= 7; - sr |= (uword)*c++ << 1; - bc[1] = sr & 0x3; sr >>= 2; - Mc[1] = sr & 0x3; sr >>= 2; - sr |= (uword)*c++ << 5; - xmaxc[1] = sr & 0x3f; sr >>= 6; - xmc[13] = sr & 0x7; sr >>= 3; - xmc[14] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 1; /* 15 */ - xmc[15] = sr & 0x7; sr >>= 3; - xmc[16] = sr & 0x7; sr >>= 3; - xmc[17] = sr & 0x7; sr >>= 3; - sr = *c++; - xmc[18] = sr & 0x7; sr >>= 3; - xmc[19] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 2; - xmc[20] = sr & 0x7; sr >>= 3; - xmc[21] = sr & 0x7; sr >>= 3; - xmc[22] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 1; - xmc[23] = sr & 0x7; sr >>= 3; - xmc[24] = sr & 0x7; sr >>= 3; - xmc[25] = sr & 0x7; sr >>= 3; - sr = *c++; - Nc[2] = sr & 0x7f; sr >>= 7; - sr |= (uword)*c++ << 1; /* 20 */ - bc[2] = sr & 0x3; sr >>= 2; - Mc[2] = sr & 0x3; sr >>= 2; - sr |= (uword)*c++ << 5; - xmaxc[2] = sr & 0x3f; sr >>= 6; - xmc[26] = sr & 0x7; sr >>= 3; - xmc[27] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 1; - xmc[28] = sr & 0x7; sr >>= 3; - xmc[29] = sr & 0x7; sr >>= 3; - xmc[30] = sr & 0x7; sr >>= 3; - sr = *c++; - xmc[31] = sr & 0x7; sr >>= 3; - xmc[32] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 2; - xmc[33] = sr & 0x7; sr >>= 3; - xmc[34] = sr & 0x7; sr >>= 3; - xmc[35] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 1; /* 25 */ - xmc[36] = sr & 0x7; sr >>= 3; - xmc[37] = sr & 0x7; sr >>= 3; - xmc[38] = sr & 0x7; sr >>= 3; - sr = *c++; - Nc[3] = sr & 0x7f; sr >>= 7; - sr |= (uword)*c++ << 1; - bc[3] = sr & 0x3; sr >>= 2; - Mc[3] = sr & 0x3; sr >>= 2; - sr |= (uword)*c++ << 5; - xmaxc[3] = sr & 0x3f; sr >>= 6; - xmc[39] = sr & 0x7; sr >>= 3; - xmc[40] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 1; - xmc[41] = sr & 0x7; sr >>= 3; - xmc[42] = sr & 0x7; sr >>= 3; - xmc[43] = sr & 0x7; sr >>= 3; - sr = *c++; /* 30 */ - xmc[44] = sr & 0x7; sr >>= 3; - xmc[45] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 2; - xmc[46] = sr & 0x7; sr >>= 3; - xmc[47] = sr & 0x7; sr >>= 3; - xmc[48] = sr & 0x7; sr >>= 3; - sr |= (uword)*c++ << 1; - xmc[49] = sr & 0x7; sr >>= 3; - xmc[50] = sr & 0x7; sr >>= 3; - xmc[51] = sr & 0x7; sr >>= 3; - } - } - else - { - /* GSM_MAGIC = (*c >> 4) & 0xF; */ - - if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1; - - LARc[0] = (*c++ & 0xF) << 2; /* 1 */ - LARc[0] |= (*c >> 6) & 0x3; - LARc[1] = *c++ & 0x3F; - LARc[2] = (*c >> 3) & 0x1F; - LARc[3] = (*c++ & 0x7) << 2; - LARc[3] |= (*c >> 6) & 0x3; - LARc[4] = (*c >> 2) & 0xF; - LARc[5] = (*c++ & 0x3) << 2; - LARc[5] |= (*c >> 6) & 0x3; - LARc[6] = (*c >> 3) & 0x7; - LARc[7] = *c++ & 0x7; - Nc[0] = (*c >> 1) & 0x7F; - bc[0] = (*c++ & 0x1) << 1; - bc[0] |= (*c >> 7) & 0x1; - Mc[0] = (*c >> 5) & 0x3; - xmaxc[0] = (*c++ & 0x1F) << 1; - xmaxc[0] |= (*c >> 7) & 0x1; - xmc[0] = (*c >> 4) & 0x7; - xmc[1] = (*c >> 1) & 0x7; - xmc[2] = (*c++ & 0x1) << 2; - xmc[2] |= (*c >> 6) & 0x3; - xmc[3] = (*c >> 3) & 0x7; - xmc[4] = *c++ & 0x7; - xmc[5] = (*c >> 5) & 0x7; - xmc[6] = (*c >> 2) & 0x7; - xmc[7] = (*c++ & 0x3) << 1; /* 10 */ - xmc[7] |= (*c >> 7) & 0x1; - xmc[8] = (*c >> 4) & 0x7; - xmc[9] = (*c >> 1) & 0x7; - xmc[10] = (*c++ & 0x1) << 2; - xmc[10] |= (*c >> 6) & 0x3; - xmc[11] = (*c >> 3) & 0x7; - xmc[12] = *c++ & 0x7; - Nc[1] = (*c >> 1) & 0x7F; - bc[1] = (*c++ & 0x1) << 1; - bc[1] |= (*c >> 7) & 0x1; - Mc[1] = (*c >> 5) & 0x3; - xmaxc[1] = (*c++ & 0x1F) << 1; - xmaxc[1] |= (*c >> 7) & 0x1; - xmc[13] = (*c >> 4) & 0x7; - xmc[14] = (*c >> 1) & 0x7; - xmc[15] = (*c++ & 0x1) << 2; - xmc[15] |= (*c >> 6) & 0x3; - xmc[16] = (*c >> 3) & 0x7; - xmc[17] = *c++ & 0x7; - xmc[18] = (*c >> 5) & 0x7; - xmc[19] = (*c >> 2) & 0x7; - xmc[20] = (*c++ & 0x3) << 1; - xmc[20] |= (*c >> 7) & 0x1; - xmc[21] = (*c >> 4) & 0x7; - xmc[22] = (*c >> 1) & 0x7; - xmc[23] = (*c++ & 0x1) << 2; - xmc[23] |= (*c >> 6) & 0x3; - xmc[24] = (*c >> 3) & 0x7; - xmc[25] = *c++ & 0x7; - Nc[2] = (*c >> 1) & 0x7F; - bc[2] = (*c++ & 0x1) << 1; /* 20 */ - bc[2] |= (*c >> 7) & 0x1; - Mc[2] = (*c >> 5) & 0x3; - xmaxc[2] = (*c++ & 0x1F) << 1; - xmaxc[2] |= (*c >> 7) & 0x1; - xmc[26] = (*c >> 4) & 0x7; - xmc[27] = (*c >> 1) & 0x7; - xmc[28] = (*c++ & 0x1) << 2; - xmc[28] |= (*c >> 6) & 0x3; - xmc[29] = (*c >> 3) & 0x7; - xmc[30] = *c++ & 0x7; - xmc[31] = (*c >> 5) & 0x7; - xmc[32] = (*c >> 2) & 0x7; - xmc[33] = (*c++ & 0x3) << 1; - xmc[33] |= (*c >> 7) & 0x1; - xmc[34] = (*c >> 4) & 0x7; - xmc[35] = (*c >> 1) & 0x7; - xmc[36] = (*c++ & 0x1) << 2; - xmc[36] |= (*c >> 6) & 0x3; - xmc[37] = (*c >> 3) & 0x7; - xmc[38] = *c++ & 0x7; - Nc[3] = (*c >> 1) & 0x7F; - bc[3] = (*c++ & 0x1) << 1; - bc[3] |= (*c >> 7) & 0x1; - Mc[3] = (*c >> 5) & 0x3; - xmaxc[3] = (*c++ & 0x1F) << 1; - xmaxc[3] |= (*c >> 7) & 0x1; - xmc[39] = (*c >> 4) & 0x7; - xmc[40] = (*c >> 1) & 0x7; - xmc[41] = (*c++ & 0x1) << 2; - xmc[41] |= (*c >> 6) & 0x3; - xmc[42] = (*c >> 3) & 0x7; - xmc[43] = *c++ & 0x7; /* 30 */ - xmc[44] = (*c >> 5) & 0x7; - xmc[45] = (*c >> 2) & 0x7; - xmc[46] = (*c++ & 0x3) << 1; - xmc[46] |= (*c >> 7) & 0x1; - xmc[47] = (*c >> 4) & 0x7; - xmc[48] = (*c >> 1) & 0x7; - xmc[49] = (*c++ & 0x1) << 2; - xmc[49] |= (*c >> 6) & 0x3; - xmc[50] = (*c >> 3) & 0x7; - xmc[51] = *c & 0x7; /* 33 */ - } - - Gsm_Decoder(s, LARc, Nc, bc, Mc, xmaxc, xmc, target); - - return 0; -} diff --git a/src/libxineadec/gsm610/gsm_destroy.c b/src/libxineadec/gsm610/gsm_destroy.c deleted file mode 100644 index 481a74660..000000000 --- a/src/libxineadec/gsm610/gsm_destroy.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische - * Universitaet Berlin. See the accompanying file "COPYRIGHT" for - * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - */ - -/* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/gsm_destroy.c,v 1.1 2002/10/12 19:12:49 tmmm Exp $ */ - -#include "gsm.h" -#include "gsm_config.h" -#include "proto.h" - -#ifdef HAS_STDLIB_H -# include <stdlib.h> -#else -# ifdef HAS_MALLOC_H -# include <malloc.h> -# else - extern void free(); -# endif -#endif - -void gsm_destroy P1((S), gsm S) -{ - if (S) free((char *)S); -} diff --git a/src/libxineadec/gsm610/long_term.c b/src/libxineadec/gsm610/long_term.c deleted file mode 100644 index d3ef1b63d..000000000 --- a/src/libxineadec/gsm610/long_term.c +++ /dev/null @@ -1,964 +0,0 @@ -/* - * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische - * Universitaet Berlin. See the accompanying file "COPYRIGHT" for - * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - */ - -/* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/long_term.c,v 1.3 2003/12/07 15:34:30 f1rmb Exp $ */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include "xineutils.h" - -#include "private.h" - -#include "gsm.h" -#include "proto.h" - -/* - * 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION - */ - - -/* - * This module computes the LTP gain (bc) and the LTP lag (Nc) - * for the long term analysis filter. This is done by calculating a - * maximum of the cross-correlation function between the current - * sub-segment short term residual signal d[0..39] (output of - * the short term analysis filter; for simplification the index - * of this array begins at 0 and ends at 39 for each sub-segment of the - * RPE-LTP analysis) and the previous reconstructed short term - * residual signal dp[ -120 .. -1 ]. A dynamic scaling must be - * performed to avoid overflow. - */ - - /* The next procedure exists in six versions. First two integer - * version (if USE_FLOAT_MUL is not defined); then four floating - * point versions, twice with proper scaling (USE_FLOAT_MUL defined), - * once without (USE_FLOAT_MUL and FAST defined, and fast run-time - * option used). Every pair has first a Cut version (see the -C - * option to toast or the LTP_CUT option to gsm_option()), then the - * uncut one. (For a detailed explanation of why this is altogether - * a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered - * Harmful''.) -a */ - -#ifndef USE_FLOAT_MUL - -#ifdef LTP_CUT - -static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out), - - struct gsm_state * st, - - register word * d, /* [0..39] IN */ - register word * dp, /* [-120..-1] IN */ - word * bc_out, /* OUT */ - word * Nc_out /* OUT */ -) -{ - register int k, lambda; - word Nc, bc; - word wt[40]; - - longword L_result; - longword L_max, L_power; - word R, S, dmax, scal, best_k; - word ltp_cut; - - register word temp, wt_k; - - /* Search of the optimum scaling of d[0..39]. - */ - dmax = 0; - for (k = 0; k <= 39; k++) { - temp = d[k]; - temp = GSM_ABS( temp ); - if (temp > dmax) { - dmax = temp; - best_k = k; - } - } - temp = 0; - if (dmax == 0) scal = 0; - else { - _x_assert(dmax > 0); - temp = gsm_norm( (longword)dmax << 16 ); - } - if (temp > 6) scal = 0; - else scal = 6 - temp; - - _x_assert(scal >= 0); - - /* Search for the maximum cross-correlation and coding of the LTP lag - */ - L_max = 0; - Nc = 40; /* index for the maximum cross-correlation */ - wt_k = SASR(d[best_k], scal); - - for (lambda = 40; lambda <= 120; lambda++) { - L_result = (longword)wt_k * dp[best_k - lambda]; - if (L_result > L_max) { - Nc = lambda; - L_max = L_result; - } - } - *Nc_out = Nc; - L_max <<= 1; - - /* Rescaling of L_max - */ - _x_assert((scal <= 100) && (scal >= -100)); - L_max = L_max >> (6 - scal); /* sub(6, scal) */ - - _x_assert(Nc <= 120 && Nc >= 40); - - /* Compute the power of the reconstructed short term residual - * signal dp[..] - */ - L_power = 0; - for (k = 0; k <= 39; k++) { - - register longword L_temp; - - L_temp = SASR( dp[k - Nc], 3 ); - L_power += L_temp * L_temp; - } - L_power <<= 1; /* from L_MULT */ - - /* Normalization of L_max and L_power - */ - - if (L_max <= 0) { - *bc_out = 0; - return; - } - if (L_max >= L_power) { - *bc_out = 3; - return; - } - - temp = gsm_norm( L_power ); - - R = SASR( L_max << temp, 16 ); - S = SASR( L_power << temp, 16 ); - - /* Coding of the LTP gain - */ - - /* Table 4.3a must be used to obtain the level DLB[i] for the - * quantization of the LTP gain b to get the coded version bc. - */ - for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; - *bc_out = bc; -} - -#endif /* LTP_CUT */ - -static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), - register word * d, /* [0..39] IN */ - register word * dp, /* [-120..-1] IN */ - word * bc_out, /* OUT */ - word * Nc_out /* OUT */ -) -{ - register int k, lambda; - word Nc, bc; - word wt[40]; - - longword L_max, L_power; - word R, S, dmax, scal; - register word temp; - - /* Search of the optimum scaling of d[0..39]. - */ - dmax = 0; - - for (k = 0; k <= 39; k++) { - temp = d[k]; - temp = GSM_ABS( temp ); - if (temp > dmax) dmax = temp; - } - - temp = 0; - if (dmax == 0) scal = 0; - else { - _x_assert(dmax > 0); - temp = gsm_norm( (longword)dmax << 16 ); - } - - if (temp > 6) scal = 0; - else scal = 6 - temp; - - _x_assert(scal >= 0); - - /* Initialization of a working array wt - */ - - for (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal ); - - /* Search for the maximum cross-correlation and coding of the LTP lag - */ - L_max = 0; - Nc = 40; /* index for the maximum cross-correlation */ - - for (lambda = 40; lambda <= 120; lambda++) { - -# undef STEP -# define STEP(k) (longword)wt[k] * dp[k - lambda] - - register longword L_result; - - L_result = STEP(0) ; L_result += STEP(1) ; - L_result += STEP(2) ; L_result += STEP(3) ; - L_result += STEP(4) ; L_result += STEP(5) ; - L_result += STEP(6) ; L_result += STEP(7) ; - L_result += STEP(8) ; L_result += STEP(9) ; - L_result += STEP(10) ; L_result += STEP(11) ; - L_result += STEP(12) ; L_result += STEP(13) ; - L_result += STEP(14) ; L_result += STEP(15) ; - L_result += STEP(16) ; L_result += STEP(17) ; - L_result += STEP(18) ; L_result += STEP(19) ; - L_result += STEP(20) ; L_result += STEP(21) ; - L_result += STEP(22) ; L_result += STEP(23) ; - L_result += STEP(24) ; L_result += STEP(25) ; - L_result += STEP(26) ; L_result += STEP(27) ; - L_result += STEP(28) ; L_result += STEP(29) ; - L_result += STEP(30) ; L_result += STEP(31) ; - L_result += STEP(32) ; L_result += STEP(33) ; - L_result += STEP(34) ; L_result += STEP(35) ; - L_result += STEP(36) ; L_result += STEP(37) ; - L_result += STEP(38) ; L_result += STEP(39) ; - - if (L_result > L_max) { - - Nc = lambda; - L_max = L_result; - } - } - - *Nc_out = Nc; - - L_max <<= 1; - - /* Rescaling of L_max - */ - _x_assert( (scal <= 100) && (scal >= -100)); - L_max = L_max >> (6 - scal); /* sub(6, scal) */ - - _x_assert( Nc <= 120 && Nc >= 40); - - /* Compute the power of the reconstructed short term residual - * signal dp[..] - */ - L_power = 0; - for (k = 0; k <= 39; k++) { - - register longword L_temp; - - L_temp = SASR( dp[k - Nc], 3 ); - L_power += L_temp * L_temp; - } - L_power <<= 1; /* from L_MULT */ - - /* Normalization of L_max and L_power - */ - - if (L_max <= 0) { - *bc_out = 0; - return; - } - if (L_max >= L_power) { - *bc_out = 3; - return; - } - - temp = gsm_norm( L_power ); - - R = SASR( L_max << temp, 16 ); - S = SASR( L_power << temp, 16 ); - - /* Coding of the LTP gain - */ - - /* Table 4.3a must be used to obtain the level DLB[i] for the - * quantization of the LTP gain b to get the coded version bc. - */ - for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; - *bc_out = bc; -} - -#else /* USE_FLOAT_MUL */ - -#ifdef LTP_CUT - -static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out), - struct gsm_state * st, /* IN */ - register word * d, /* [0..39] IN */ - register word * dp, /* [-120..-1] IN */ - word * bc_out, /* OUT */ - word * Nc_out /* OUT */ -) -{ - register int k, lambda; - word Nc, bc; - word ltp_cut; - - float wt_float[40]; - float dp_float_base[120], * dp_float = dp_float_base + 120; - - longword L_max, L_power; - word R, S, dmax, scal; - register word temp; - - /* Search of the optimum scaling of d[0..39]. - */ - dmax = 0; - - for (k = 0; k <= 39; k++) { - temp = d[k]; - temp = GSM_ABS( temp ); - if (temp > dmax) dmax = temp; - } - - temp = 0; - if (dmax == 0) scal = 0; - else { - _x_assert(dmax > 0); - - temp = gsm_norm( (longword)dmax << 16 ); - } - - if (temp > 6) scal = 0; - else scal = 6 - temp; - - _x_assert(scal >= 0); - - ltp_cut = (longword)SASR(dmax, scal) * st->ltp_cut / 100; - - - /* Initialization of a working array wt - */ - - for (k = 0; k < 40; k++) { - register word w = SASR( d[k], scal ); - if (w < 0 ? w > -ltp_cut : w < ltp_cut) { - wt_float[k] = 0.0; - } - else { - wt_float[k] = w; - } - } - for (k = -120; k < 0; k++) dp_float[k] = dp[k]; - - /* Search for the maximum cross-correlation and coding of the LTP lag - */ - L_max = 0; - Nc = 40; /* index for the maximum cross-correlation */ - - for (lambda = 40; lambda <= 120; lambda += 9) { - - /* Calculate L_result for l = lambda .. lambda + 9. - */ - register float *lp = dp_float - lambda; - - register float W; - register float a = lp[-8], b = lp[-7], c = lp[-6], - d = lp[-5], e = lp[-4], f = lp[-3], - g = lp[-2], h = lp[-1]; - register float E; - register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, - S5 = 0, S6 = 0, S7 = 0, S8 = 0; - -# undef STEP -# define STEP(K, a, b, c, d, e, f, g, h) \ - if ((W = wt_float[K]) != 0.0) { \ - E = W * a; S8 += E; \ - E = W * b; S7 += E; \ - E = W * c; S6 += E; \ - E = W * d; S5 += E; \ - E = W * e; S4 += E; \ - E = W * f; S3 += E; \ - E = W * g; S2 += E; \ - E = W * h; S1 += E; \ - a = lp[K]; \ - E = W * a; S0 += E; } else (a = lp[K]) - -# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) -# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) -# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) -# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) -# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) -# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) -# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) -# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) - - STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); - STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); - - STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); - STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); - - STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); - STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); - - STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); - STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); - - STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); - STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); - - if (S0 > L_max) { L_max = S0; Nc = lambda; } - if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } - if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } - if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } - if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } - if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } - if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } - if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } - if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } - - } - *Nc_out = Nc; - - L_max <<= 1; - - /* Rescaling of L_max - */ - _x_assert( (scal <= 100) && (scal >= -100)); - - L_max = L_max >> (6 - scal); /* sub(6, scal) */ - - _x_assert( Nc <= 120 && Nc >= 40); - - /* Compute the power of the reconstructed short term residual - * signal dp[..] - */ - L_power = 0; - for (k = 0; k <= 39; k++) { - - register longword L_temp; - - L_temp = SASR( dp[k - Nc], 3 ); - L_power += L_temp * L_temp; - } - L_power <<= 1; /* from L_MULT */ - - /* Normalization of L_max and L_power - */ - - if (L_max <= 0) { - *bc_out = 0; - return; - } - if (L_max >= L_power) { - *bc_out = 3; - return; - } - - temp = gsm_norm( L_power ); - - R = SASR( L_max << temp, 16 ); - S = SASR( L_power << temp, 16 ); - - /* Coding of the LTP gain - */ - - /* Table 4.3a must be used to obtain the level DLB[i] for the - * quantization of the LTP gain b to get the coded version bc. - */ - for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; - *bc_out = bc; -} - -#endif /* LTP_CUT */ - -static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), - register word * d, /* [0..39] IN */ - register word * dp, /* [-120..-1] IN */ - word * bc_out, /* OUT */ - word * Nc_out /* OUT */ -) -{ - register int k, lambda; - word Nc, bc; - - float wt_float[40]; - float dp_float_base[120], * dp_float = dp_float_base + 120; - - longword L_max, L_power; - word R, S, dmax, scal; - register word temp; - - /* Search of the optimum scaling of d[0..39]. - */ - dmax = 0; - - for (k = 0; k <= 39; k++) { - temp = d[k]; - temp = GSM_ABS( temp ); - if (temp > dmax) dmax = temp; - } - - temp = 0; - if (dmax == 0) scal = 0; - else { - _x_assert(dmax > 0); - temp = gsm_norm( (longword)dmax << 16 ); - } - - if (temp > 6) scal = 0; - else scal = 6 - temp; - - _x_assert(scal >= 0); - - /* Initialization of a working array wt - */ - - for (k = 0; k < 40; k++) wt_float[k] = SASR( d[k], scal ); - for (k = -120; k < 0; k++) dp_float[k] = dp[k]; - - /* Search for the maximum cross-correlation and coding of the LTP lag - */ - L_max = 0; - Nc = 40; /* index for the maximum cross-correlation */ - - for (lambda = 40; lambda <= 120; lambda += 9) { - - /* Calculate L_result for l = lambda .. lambda + 9. - */ - register float *lp = dp_float - lambda; - - register float W; - register float a = lp[-8], b = lp[-7], c = lp[-6], - d = lp[-5], e = lp[-4], f = lp[-3], - g = lp[-2], h = lp[-1]; - register float E; - register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, - S5 = 0, S6 = 0, S7 = 0, S8 = 0; - -# undef STEP -# define STEP(K, a, b, c, d, e, f, g, h) \ - W = wt_float[K]; \ - E = W * a; S8 += E; \ - E = W * b; S7 += E; \ - E = W * c; S6 += E; \ - E = W * d; S5 += E; \ - E = W * e; S4 += E; \ - E = W * f; S3 += E; \ - E = W * g; S2 += E; \ - E = W * h; S1 += E; \ - a = lp[K]; \ - E = W * a; S0 += E - -# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) -# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) -# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) -# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) -# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) -# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) -# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) -# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) - - STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); - STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); - - STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); - STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); - - STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); - STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); - - STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); - STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); - - STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); - STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); - - if (S0 > L_max) { L_max = S0; Nc = lambda; } - if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } - if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } - if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } - if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } - if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } - if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } - if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } - if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } - } - *Nc_out = Nc; - - L_max <<= 1; - - /* Rescaling of L_max - */ - - _x_assert( (scal <= 100) && (scal >= -100)); - - L_max = L_max >> (6 - scal); /* sub(6, scal) */ - - _x_assert( Nc <= 120 && Nc >= 40); - - - /* Compute the power of the reconstructed short term residual - * signal dp[..] - */ - L_power = 0; - for (k = 0; k <= 39; k++) { - - register longword L_temp; - - L_temp = SASR( dp[k - Nc], 3 ); - L_power += L_temp * L_temp; - } - L_power <<= 1; /* from L_MULT */ - - /* Normalization of L_max and L_power - */ - - if (L_max <= 0) { - *bc_out = 0; - return; - } - if (L_max >= L_power) { - *bc_out = 3; - return; - } - - temp = gsm_norm( L_power ); - - R = SASR( L_max << temp, 16 ); - S = SASR( L_power << temp, 16 ); - - /* Coding of the LTP gain - */ - - /* Table 4.3a must be used to obtain the level DLB[i] for the - * quantization of the LTP gain b to get the coded version bc. - */ - for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; - *bc_out = bc; -} - -#ifdef FAST -#ifdef LTP_CUT - -static void Cut_Fast_Calculation_of_the_LTP_parameters P5((st, - d,dp,bc_out,Nc_out), - struct gsm_state * st, /* IN */ - register word * d, /* [0..39] IN */ - register word * dp, /* [-120..-1] IN */ - word * bc_out, /* OUT */ - word * Nc_out /* OUT */ -) -{ - register int k, lambda; - register float wt_float; - word Nc, bc; - word wt_max, best_k, ltp_cut; - - float dp_float_base[120], * dp_float = dp_float_base + 120; - - register float L_result, L_max, L_power; - - wt_max = 0; - - for (k = 0; k < 40; ++k) { - if ( d[k] > wt_max) wt_max = d[best_k = k]; - else if (-d[k] > wt_max) wt_max = -d[best_k = k]; - } - - _x_assert(wt_max >= 0); - wt_float = (float)wt_max; - - for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k]; - - /* Search for the maximum cross-correlation and coding of the LTP lag - */ - L_max = 0; - Nc = 40; /* index for the maximum cross-correlation */ - - for (lambda = 40; lambda <= 120; lambda++) { - L_result = wt_float * dp_float[best_k - lambda]; - if (L_result > L_max) { - Nc = lambda; - L_max = L_result; - } - } - - *Nc_out = Nc; - if (L_max <= 0.) { - *bc_out = 0; - return; - } - - /* Compute the power of the reconstructed short term residual - * signal dp[..] - */ - dp_float -= Nc; - L_power = 0; - for (k = 0; k < 40; ++k) { - register float f = dp_float[k]; - L_power += f * f; - } - - if (L_max >= L_power) { - *bc_out = 3; - return; - } - - /* Coding of the LTP gain - * Table 4.3a must be used to obtain the level DLB[i] for the - * quantization of the LTP gain b to get the coded version bc. - */ - lambda = L_max / L_power * 32768.; - for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break; - *bc_out = bc; -} - -#endif /* LTP_CUT */ - -static void Fast_Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), - register word * d, /* [0..39] IN */ - register word * dp, /* [-120..-1] IN */ - word * bc_out, /* OUT */ - word * Nc_out /* OUT */ -) -{ - register int k, lambda; - word Nc, bc; - - float wt_float[40]; - float dp_float_base[120], * dp_float = dp_float_base + 120; - - register float L_max, L_power; - - for (k = 0; k < 40; ++k) wt_float[k] = (float)d[k]; - for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k]; - - /* Search for the maximum cross-correlation and coding of the LTP lag - */ - L_max = 0; - Nc = 40; /* index for the maximum cross-correlation */ - - for (lambda = 40; lambda <= 120; lambda += 9) { - - /* Calculate L_result for l = lambda .. lambda + 9. - */ - register float *lp = dp_float - lambda; - - register float W; - register float a = lp[-8], b = lp[-7], c = lp[-6], - d = lp[-5], e = lp[-4], f = lp[-3], - g = lp[-2], h = lp[-1]; - register float E; - register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, - S5 = 0, S6 = 0, S7 = 0, S8 = 0; - -# undef STEP -# define STEP(K, a, b, c, d, e, f, g, h) \ - W = wt_float[K]; \ - E = W * a; S8 += E; \ - E = W * b; S7 += E; \ - E = W * c; S6 += E; \ - E = W * d; S5 += E; \ - E = W * e; S4 += E; \ - E = W * f; S3 += E; \ - E = W * g; S2 += E; \ - E = W * h; S1 += E; \ - a = lp[K]; \ - E = W * a; S0 += E - -# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) -# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) -# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) -# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) -# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) -# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) -# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) -# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) - - STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); - STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); - - STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); - STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); - - STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); - STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); - - STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); - STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); - - STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); - STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); - - if (S0 > L_max) { L_max = S0; Nc = lambda; } - if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } - if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } - if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } - if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } - if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } - if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } - if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } - if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } - } - *Nc_out = Nc; - - if (L_max <= 0.) { - *bc_out = 0; - return; - } - - /* Compute the power of the reconstructed short term residual - * signal dp[..] - */ - dp_float -= Nc; - L_power = 0; - for (k = 0; k < 40; ++k) { - register float f = dp_float[k]; - L_power += f * f; - } - - if (L_max >= L_power) { - *bc_out = 3; - return; - } - - /* Coding of the LTP gain - * Table 4.3a must be used to obtain the level DLB[i] for the - * quantization of the LTP gain b to get the coded version bc. - */ - lambda = L_max / L_power * 32768.; - for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break; - *bc_out = bc; -} - -#endif /* FAST */ -#endif /* USE_FLOAT_MUL */ - - -/* 4.2.12 */ - -static void Long_term_analysis_filtering P6((bc,Nc,dp,d,dpp,e), - word bc, /* IN */ - word Nc, /* IN */ - register word * dp, /* previous d [-120..-1] IN */ - register word * d, /* d [0..39] IN */ - register word * dpp, /* estimate [0..39] OUT */ - register word * e /* long term res. signal [0..39] OUT */ -) -/* - * In this part, we have to decode the bc parameter to compute - * the samples of the estimate dpp[0..39]. The decoding of bc needs the - * use of table 4.3b. The long term residual signal e[0..39] - * is then calculated to be fed to the RPE encoding section. - */ -{ - register int k; - register longword ltmp; - -# undef STEP -# define STEP(BP) \ - for (k = 0; k <= 39; k++) { \ - dpp[k] = GSM_MULT_R( BP, dp[k - Nc]); \ - e[k] = GSM_SUB( d[k], dpp[k] ); \ - } - - switch (bc) { - case 0: STEP( 3277 ); break; - case 1: STEP( 11469 ); break; - case 2: STEP( 21299 ); break; - case 3: STEP( 32767 ); break; - } -} - -void Gsm_Long_Term_Predictor P7((S,d,dp,e,dpp,Nc,bc), /* 4x for 160 samples */ - - struct gsm_state * S, - - word * d, /* [0..39] residual signal IN */ - word * dp, /* [-120..-1] d' IN */ - - word * e, /* [0..39] OUT */ - word * dpp, /* [0..39] OUT */ - word * Nc, /* correlation lag OUT */ - word * bc /* gain factor OUT */ -) -{ - _x_assert( d ); - _x_assert( dp ); - _x_assert( e ); - _x_assert( dpp ); - _x_assert( Nc ); - _x_assert( bc ); - -#if defined(FAST) && defined(USE_FLOAT_MUL) - if (S->fast) -#if defined (LTP_CUT) - if (S->ltp_cut) - Cut_Fast_Calculation_of_the_LTP_parameters(S, - d, dp, bc, Nc); - else -#endif /* LTP_CUT */ - Fast_Calculation_of_the_LTP_parameters(d, dp, bc, Nc ); - else -#endif /* FAST & USE_FLOAT_MUL */ -#ifdef LTP_CUT - if (S->ltp_cut) - Cut_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc); - else -#endif - Calculation_of_the_LTP_parameters(d, dp, bc, Nc); - - Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e ); -} - -/* 4.3.2 */ -void Gsm_Long_Term_Synthesis_Filtering P5((S,Ncr,bcr,erp,drp), - struct gsm_state * S, - - word Ncr, - word bcr, - register word * erp, /* [0..39] IN */ - register word * drp /* [-120..-1] IN, [-120..40] OUT */ -) -/* - * This procedure uses the bcr and Ncr parameter to realize the - * long term synthesis filtering. The decoding of bcr needs - * table 4.3b. - */ -{ - register longword ltmp; /* for ADD */ - register int k; - word brp, drpp, Nr; - - /* Check the limits of Nr. - */ - Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr; - S->nrp = Nr; - _x_assert(Nr >= 40 && Nr <= 120); - - /* Decoding of the LTP gain bcr - */ - brp = gsm_QLB[ bcr ]; - - /* Computation of the reconstructed short term residual - * signal drp[0..39] - */ - _x_assert(brp != MIN_WORD); - - for (k = 0; k <= 39; k++) { - drpp = GSM_MULT_R( brp, drp[ k - Nr ] ); - drp[k] = GSM_ADD( erp[k], drpp ); - } - - /* - * Update of the reconstructed short term residual signal - * drp[ -1..-120 ] - */ - - for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ]; -} diff --git a/src/libxineadec/gsm610/lpc.c b/src/libxineadec/gsm610/lpc.c deleted file mode 100644 index 7a8a8e2bc..000000000 --- a/src/libxineadec/gsm610/lpc.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische - * Universitaet Berlin. See the accompanying file "COPYRIGHT" for - * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - */ - -/* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/lpc.c,v 1.3 2003/12/07 15:34:30 f1rmb Exp $ */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include "xineutils.h" - -#include "private.h" - -#include "gsm.h" -#include "proto.h" - -#undef P - -/* - * 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION - */ - -/* 4.2.4 */ - - -static void Autocorrelation P2((s, L_ACF), - word * s, /* [0..159] IN/OUT */ - longword * L_ACF) /* [0..8] OUT */ -/* - * The goal is to compute the array L_ACF[k]. The signal s[i] must - * be scaled in order to avoid an overflow situation. - */ -{ - register int k, i; - - word temp, smax, scalauto; - -#ifdef USE_FLOAT_MUL - float float_s[160]; -#endif - - /* Dynamic scaling of the array s[0..159] - */ - - /* Search for the maximum. - */ - smax = 0; - for (k = 0; k <= 159; k++) { - temp = GSM_ABS( s[k] ); - if (temp > smax) smax = temp; - } - - /* Computation of the scaling factor. - */ - if (smax == 0) scalauto = 0; - else { - _x_assert(smax > 0); - scalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */ - } - - /* Scaling of the array s[0...159] - */ - - if (scalauto > 0) { - -# ifdef USE_FLOAT_MUL -# define SCALE(n) \ - case n: for (k = 0; k <= 159; k++) \ - float_s[k] = (float) \ - (s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\ - break; -# else -# define SCALE(n) \ - case n: for (k = 0; k <= 159; k++) \ - s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\ - break; -# endif /* USE_FLOAT_MUL */ - - switch (scalauto) { - SCALE(1) - SCALE(2) - SCALE(3) - SCALE(4) - } -# undef SCALE - } -# ifdef USE_FLOAT_MUL - else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k]; -# endif - - /* Compute the L_ACF[..]. - */ - { -# ifdef USE_FLOAT_MUL - register float * sp = float_s; - register float sl = *sp; - -# define STEP(k) L_ACF[k] += (longword)(sl * sp[ -(k) ]); -# else - word * sp = s; - word sl = *sp; - -# define STEP(k) L_ACF[k] += ((longword)sl * sp[ -(k) ]); -# endif - -# define NEXTI sl = *++sp - - - for (k = 9; k--; L_ACF[k] = 0) ; - - STEP (0); - NEXTI; - STEP(0); STEP(1); - NEXTI; - STEP(0); STEP(1); STEP(2); - NEXTI; - STEP(0); STEP(1); STEP(2); STEP(3); - NEXTI; - STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); - NEXTI; - STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); - NEXTI; - STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); - NEXTI; - STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7); - - for (i = 8; i <= 159; i++) { - - NEXTI; - - STEP(0); - STEP(1); STEP(2); STEP(3); STEP(4); - STEP(5); STEP(6); STEP(7); STEP(8); - } - - for (k = 9; k--; L_ACF[k] <<= 1) ; - - } - /* Rescaling of the array s[0..159] - */ - if (scalauto > 0) { - _x_assert(scalauto <= 4); - for (k = 160; k--; *s++ <<= scalauto) ; - } -} - -#if defined(USE_FLOAT_MUL) && defined(FAST) - -static void Fast_Autocorrelation P2((s, L_ACF), - word * s, /* [0..159] IN/OUT */ - longword * L_ACF) /* [0..8] OUT */ -{ - register int k, i; - float f_L_ACF[9]; - float scale; - - float s_f[160]; - register float *sf = s_f; - - for (i = 0; i < 160; ++i) sf[i] = s[i]; - for (k = 0; k <= 8; k++) { - register float L_temp2 = 0; - register float *sfl = sf - k; - for (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i]; - f_L_ACF[k] = L_temp2; - } - scale = MAX_LONGWORD / f_L_ACF[0]; - - for (k = 0; k <= 8; k++) { - L_ACF[k] = f_L_ACF[k] * scale; - } -} -#endif /* defined (USE_FLOAT_MUL) && defined (FAST) */ - -/* 4.2.5 */ - -static void Reflection_coefficients P2( (L_ACF, r), - longword * L_ACF, /* 0...8 IN */ - register word * r /* 0...7 OUT */ -) -{ - register int i, m, n; - register word temp; - register longword ltmp; - word ACF[9]; /* 0..8 */ - word P[ 9]; /* 0..8 */ - word K[ 9]; /* 2..8 */ - - /* Schur recursion with 16 bits arithmetic. - */ - - if (L_ACF[0] == 0) { - for (i = 8; i--; *r++ = 0) ; - return; - } - - _x_assert( L_ACF[0] != 0 ); - temp = gsm_norm( L_ACF[0] ); - - _x_assert(temp >= 0 && temp < 32); - - /* ? overflow ? */ - for (i = 0; i <= 8; i++) ACF[i] = SASR( L_ACF[i] << temp, 16 ); - - /* Initialize array P[..] and K[..] for the recursion. - */ - - for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ]; - for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ]; - - /* Compute reflection coefficients - */ - for (n = 1; n <= 8; n++, r++) { - - temp = P[1]; - temp = GSM_ABS(temp); - if (P[0] < temp) { - for (i = n; i <= 8; i++) *r++ = 0; - return; - } - - *r = gsm_div( temp, P[0] ); - - _x_assert(*r >= 0); - - if (P[1] > 0) *r = -*r; /* r[n] = sub(0, r[n]) */ - - _x_assert(*r != MIN_WORD); - - if (n == 8) return; - - /* Schur recursion - */ - temp = GSM_MULT_R( P[1], *r ); - P[0] = GSM_ADD( P[0], temp ); - - for (m = 1; m <= 8 - n; m++) { - temp = GSM_MULT_R( K[ m ], *r ); - P[m] = GSM_ADD( P[ m+1 ], temp ); - - temp = GSM_MULT_R( P[ m+1 ], *r ); - K[m] = GSM_ADD( K[ m ], temp ); - } - } -} - -/* 4.2.6 */ - -static void Transformation_to_Log_Area_Ratios P1((r), - register word * r /* 0..7 IN/OUT */ -) -/* - * The following scaling for r[..] and LAR[..] has been used: - * - * r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1. - * LAR[..] = integer( real_LAR[..] * 16384 ); - * with -1.625 <= real_LAR <= 1.625 - */ -{ - register word temp; - register int i; - - - /* Computation of the LAR[0..7] from the r[0..7] - */ - for (i = 1; i <= 8; i++, r++) { - - temp = *r; - temp = GSM_ABS(temp); - - _x_assert(temp >= 0); - - if (temp < 22118) { - temp >>= 1; - } else if (temp < 31130) { - _x_assert(temp >= 11059); - temp -= 11059; - } else { - _x_assert(temp >= 26112); - temp -= 26112; - temp <<= 2; - } - - if (*r < 0) { - *r = -temp; - } - else { - *r = temp; - } - _x_assert(*r != MIN_WORD); - } -} - -/* 4.2.7 */ - -static void Quantization_and_coding P1((LAR), - register word * LAR /* [0..7] IN/OUT */ -) -{ - register word temp; - longword ltmp; - - - /* This procedure needs four tables; the following equations - * give the optimum scaling for the constants: - * - * A[0..7] = integer( real_A[0..7] * 1024 ) - * B[0..7] = integer( real_B[0..7] * 512 ) - * MAC[0..7] = maximum of the LARc[0..7] - * MIC[0..7] = minimum of the LARc[0..7] - */ - -# undef STEP -# define STEP( A, B, MAC, MIC ) \ - temp = GSM_MULT( A, *LAR ); \ - temp = GSM_ADD( temp, B ); \ - temp = GSM_ADD( temp, 256 ); \ - temp = SASR( temp, 9 ); \ - *LAR = temp>MAC ? MAC - MIC : (temp<MIC ? 0 : temp - MIC); \ - LAR++; - - STEP( 20480, 0, 31, -32 ); - STEP( 20480, 0, 31, -32 ); - STEP( 20480, 2048, 15, -16 ); - STEP( 20480, -2560, 15, -16 ); - - STEP( 13964, 94, 7, -8 ); - STEP( 15360, -1792, 7, -8 ); - STEP( 8534, -341, 3, -4 ); - STEP( 9036, -1144, 3, -4 ); - -# undef STEP -} - -void Gsm_LPC_Analysis P3((S, s,LARc), - struct gsm_state *S, - word * s, /* 0..159 signals IN/OUT */ - word * LARc) /* 0..7 LARc's OUT */ -{ - longword L_ACF[9]; - -#if defined(USE_FLOAT_MUL) && defined(FAST) - if (S->fast) Fast_Autocorrelation (s, L_ACF ); - else -#endif - Autocorrelation (s, L_ACF ); - Reflection_coefficients (L_ACF, LARc ); - Transformation_to_Log_Area_Ratios (LARc); - Quantization_and_coding (LARc); -} diff --git a/src/libxineadec/gsm610/private.h b/src/libxineadec/gsm610/private.h deleted file mode 100644 index 33a5172b0..000000000 --- a/src/libxineadec/gsm610/private.h +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische - * Universitaet Berlin. See the accompanying file "COPYRIGHT" for - * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - */ - -/*$Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/private.h,v 1.1 2002/10/12 19:12:49 tmmm Exp $*/ - -#ifndef PRIVATE_H -#define PRIVATE_H - -typedef short word; /* 16 bit signed int */ -typedef long longword; /* 32 bit signed int */ - -typedef unsigned short uword; /* unsigned word */ -typedef unsigned long ulongword; /* unsigned longword */ - -struct gsm_state { - - word dp0[ 280 ]; - - word z1; /* preprocessing.c, Offset_com. */ - longword L_z2; /* Offset_com. */ - int mp; /* Preemphasis */ - - word u[8]; /* short_term_aly_filter.c */ - word LARpp[2][8]; /* */ - word j; /* */ - - word ltp_cut; /* long_term.c, LTP crosscorr. */ - word nrp; /* 40 */ /* long_term.c, synthesis */ - word v[9]; /* short_term.c, synthesis */ - word msr; /* decoder.c, Postprocessing */ - - char verbose; /* only used if !NDEBUG */ - char fast; /* only used if FAST */ - - char wav_fmt; /* only used if WAV49 defined */ - unsigned char frame_index; /* odd/even chaining */ - unsigned char frame_chain; /* half-byte to carry forward */ -}; - - -#define MIN_WORD (-32767 - 1) -#define MAX_WORD 32767 - -#define MIN_LONGWORD (-2147483647 - 1) -#define MAX_LONGWORD 2147483647 - -#ifdef SASR /* flag: >> is a signed arithmetic shift right */ -#undef SASR -#define SASR(x, by) ((x) >> (by)) -#else -#define SASR(x, by) ((x) >= 0 ? (x) >> (by) : (~(-((x) + 1) >> (by)))) -#endif /* SASR */ - -#include "proto.h" - -/* - * Prototypes from add.c - */ -extern word gsm_mult P((word a, word b)); -extern longword gsm_L_mult P((word a, word b)); -extern word gsm_mult_r P((word a, word b)); - -extern word gsm_div P((word num, word denum)); - -extern word gsm_add P(( word a, word b )); -extern longword gsm_L_add P(( longword a, longword b )); - -extern word gsm_sub P((word a, word b)); -extern longword gsm_L_sub P((longword a, longword b)); - -extern word gsm_abs P((word a)); - -extern word gsm_norm P(( longword a )); - -extern longword gsm_L_asl P((longword a, int n)); -extern word gsm_asl P((word a, int n)); - -extern longword gsm_L_asr P((longword a, int n)); -extern word gsm_asr P((word a, int n)); - -/* - * Inlined functions from add.h - */ - -/* - * #define GSM_MULT_R(a, b) (* word a, word b, !(a == b == MIN_WORD) *) \ - * (0x0FFFF & SASR(((longword)(a) * (longword)(b) + 16384), 15)) - */ -#define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */ \ - (SASR( ((longword)(a) * (longword)(b) + 16384), 15 )) - -# define GSM_MULT(a,b) /* word a, word b, !(a == b == MIN_WORD) */ \ - (SASR( ((longword)(a) * (longword)(b)), 15 )) - -# define GSM_L_MULT(a, b) /* word a, word b */ \ - (((longword)(a) * (longword)(b)) << 1) - -# define GSM_L_ADD(a, b) \ - ( (a) < 0 ? ( (b) >= 0 ? (a) + (b) \ - : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \ - >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 ) \ - : ((b) <= 0 ? (a) + (b) \ - : (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \ - ? MAX_LONGWORD : utmp)) - -/* - * # define GSM_ADD(a, b) \ - * ((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD \ - * ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) - */ -/* Nonportable, but faster: */ - -#define GSM_ADD(a, b) \ - ((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \ - MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp) - -# define GSM_SUB(a, b) \ - ((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \ - ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) - -# define GSM_ABS(a) ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a)) - -/* Use these if necessary: - -# define GSM_MULT_R(a, b) gsm_mult_r(a, b) -# define GSM_MULT(a, b) gsm_mult(a, b) -# define GSM_L_MULT(a, b) gsm_L_mult(a, b) - -# define GSM_L_ADD(a, b) gsm_L_add(a, b) -# define GSM_ADD(a, b) gsm_add(a, b) -# define GSM_SUB(a, b) gsm_sub(a, b) - -# define GSM_ABS(a) gsm_abs(a) - -*/ - -/* - * More prototypes from implementations.. - */ -extern void Gsm_Coder P(( - struct gsm_state * S, - word * s, /* [0..159] samples IN */ - word * LARc, /* [0..7] LAR coefficients OUT */ - word * Nc, /* [0..3] LTP lag OUT */ - word * bc, /* [0..3] coded LTP gain OUT */ - word * Mc, /* [0..3] RPE grid selection OUT */ - word * xmaxc,/* [0..3] Coded maximum amplitude OUT */ - word * xMc /* [13*4] normalized RPE samples OUT */)); - -extern void Gsm_Long_Term_Predictor P(( /* 4x for 160 samples */ - struct gsm_state * S, - word * d, /* [0..39] residual signal IN */ - word * dp, /* [-120..-1] d' IN */ - word * e, /* [0..40] OUT */ - word * dpp, /* [0..40] OUT */ - word * Nc, /* correlation lag OUT */ - word * bc /* gain factor OUT */)); - -extern void Gsm_LPC_Analysis P(( - struct gsm_state * S, - word * s, /* 0..159 signals IN/OUT */ - word * LARc)); /* 0..7 LARc's OUT */ - -extern void Gsm_Preprocess P(( - struct gsm_state * S, - word * s, word * so)); - -extern void Gsm_Encoding P(( - struct gsm_state * S, - word * e, - word * ep, - word * xmaxc, - word * Mc, - word * xMc)); - -extern void Gsm_Short_Term_Analysis_Filter P(( - struct gsm_state * S, - word * LARc, /* coded log area ratio [0..7] IN */ - word * d /* st res. signal [0..159] IN/OUT */)); - -extern void Gsm_Decoder P(( - struct gsm_state * S, - word * LARcr, /* [0..7] IN */ - word * Ncr, /* [0..3] IN */ - word * bcr, /* [0..3] IN */ - word * Mcr, /* [0..3] IN */ - word * xmaxcr, /* [0..3] IN */ - word * xMcr, /* [0..13*4] IN */ - word * s)); /* [0..159] OUT */ - -extern void Gsm_Decoding P(( - struct gsm_state * S, - word xmaxcr, - word Mcr, - word * xMcr, /* [0..12] IN */ - word * erp)); /* [0..39] OUT */ - -extern void Gsm_Long_Term_Synthesis_Filtering P(( - struct gsm_state* S, - word Ncr, - word bcr, - word * erp, /* [0..39] IN */ - word * drp)); /* [-120..-1] IN, [0..40] OUT */ - -void Gsm_RPE_Decoding P(( - struct gsm_state *S, - word xmaxcr, - word Mcr, - word * xMcr, /* [0..12], 3 bits IN */ - word * erp)); /* [0..39] OUT */ - -void Gsm_RPE_Encoding P(( - struct gsm_state * S, - word * e, /* -5..-1][0..39][40..44 IN/OUT */ - word * xmaxc, /* OUT */ - word * Mc, /* OUT */ - word * xMc)); /* [0..12] OUT */ - -extern void Gsm_Short_Term_Synthesis_Filter P(( - struct gsm_state * S, - word * LARcr, /* log area ratios [0..7] IN */ - word * drp, /* received d [0...39] IN */ - word * s)); /* signal s [0..159] OUT */ - -extern void Gsm_Update_of_reconstructed_short_time_residual_signal P(( - word * dpp, /* [0...39] IN */ - word * ep, /* [0...39] IN */ - word * dp)); /* [-120...-1] IN/OUT */ - -/* - * Tables from table.c - */ -#ifndef GSM_TABLE_C - -extern word gsm_A[8], gsm_B[8], gsm_MIC[8], gsm_MAC[8]; -extern word gsm_INVA[8]; -extern word gsm_DLB[4], gsm_QLB[4]; -extern word gsm_H[11]; -extern word gsm_NRFAC[8]; -extern word gsm_FAC[8]; - -#endif /* GSM_TABLE_C */ - -/* - * Debugging - */ -#ifdef NDEBUG - -# define gsm_debug_words(a, b, c, d) /* nil */ -# define gsm_debug_longwords(a, b, c, d) /* nil */ -# define gsm_debug_word(a, b) /* nil */ -# define gsm_debug_longword(a, b) /* nil */ - -#else /* !NDEBUG => DEBUG */ - - extern void gsm_debug_words P((char * name, int, int, word *)); - extern void gsm_debug_longwords P((char * name, int, int, longword *)); - extern void gsm_debug_longword P((char * name, longword)); - extern void gsm_debug_word P((char * name, word)); - -#endif /* !NDEBUG */ - -#include "unproto.h" - -#endif /* PRIVATE_H */ diff --git a/src/libxineadec/gsm610/proto.h b/src/libxineadec/gsm610/proto.h deleted file mode 100644 index a80ebf9e4..000000000 --- a/src/libxineadec/gsm610/proto.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische - * Universitaet Berlin. See the accompanying file "COPYRIGHT" for - * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - */ - -/*$Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/proto.h,v 1.1 2002/10/12 19:12:49 tmmm Exp $*/ - -#ifndef PROTO_H -#define PROTO_H - -#if __cplusplus -# define NeedFunctionPrototypes 1 -#endif - -#if __STDC__ -# define NeedFunctionPrototypes 1 -#endif - -#ifdef _NO_PROTO -# undef NeedFunctionPrototypes -#endif - -#undef P /* gnu stdio.h actually defines this... */ -#undef P0 -#undef P1 -#undef P2 -#undef P3 -#undef P4 -#undef P5 -#undef P6 -#undef P7 -#undef P8 - -#if NeedFunctionPrototypes - -# define P( protos ) protos - -# define P0() (void) -# define P1(x, a) (a) -# define P2(x, a, b) (a, b) -# define P3(x, a, b, c) (a, b, c) -# define P4(x, a, b, c, d) (a, b, c, d) -# define P5(x, a, b, c, d, e) (a, b, c, d, e) -# define P6(x, a, b, c, d, e, f) (a, b, c, d, e, f) -# define P7(x, a, b, c, d, e, f, g) (a, b, c, d, e, f, g) -# define P8(x, a, b, c, d, e, f, g, h) (a, b, c, d, e, f, g, h) - -#else /* !NeedFunctionPrototypes */ - -# define P( protos ) ( /* protos */ ) - -# define P0() () -# define P1(x, a) x a; -# define P2(x, a, b) x a; b; -# define P3(x, a, b, c) x a; b; c; -# define P4(x, a, b, c, d) x a; b; c; d; -# define P5(x, a, b, c, d, e) x a; b; c; d; e; -# define P6(x, a, b, c, d, e, f) x a; b; c; d; e; f; -# define P7(x, a, b, c, d, e, f, g) x a; b; c; d; e; f; g; -# define P8(x, a, b, c, d, e, f, g, h) x a; b; c; d; e; f; g; h; - -#endif /* !NeedFunctionPrototypes */ - -#endif /* PROTO_H */ diff --git a/src/libxineadec/gsm610/rpe.c b/src/libxineadec/gsm610/rpe.c deleted file mode 100644 index be1b1529b..000000000 --- a/src/libxineadec/gsm610/rpe.c +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische - * Universitaet Berlin. See the accompanying file "COPYRIGHT" for - * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - */ - -/* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/rpe.c,v 1.3 2003/12/07 15:34:30 f1rmb Exp $ */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include "xineutils.h" -#include "private.h" - -#include "gsm.h" -#include "proto.h" - -/* 4.2.13 .. 4.2.17 RPE ENCODING SECTION - */ - -/* 4.2.13 */ - -static void Weighting_filter P2((e, x), - register word * e, /* signal [-5..0.39.44] IN */ - word * x /* signal [0..39] OUT */ -) -/* - * The coefficients of the weighting filter are stored in a table - * (see table 4.4). The following scaling is used: - * - * H[0..10] = integer( real_H[ 0..10] * 8192 ); - */ -{ - /* word wt[ 50 ]; */ - - register longword L_result; - register int k /* , i */ ; - - /* Initialization of a temporary working array wt[0...49] - */ - - /* for (k = 0; k <= 4; k++) wt[k] = 0; - * for (k = 5; k <= 44; k++) wt[k] = *e++; - * for (k = 45; k <= 49; k++) wt[k] = 0; - * - * (e[-5..-1] and e[40..44] are allocated by the caller, - * are initially zero and are not written anywhere.) - */ - e -= 5; - - /* Compute the signal x[0..39] - */ - for (k = 0; k <= 39; k++) { - - L_result = 8192 >> 1; - - /* for (i = 0; i <= 10; i++) { - * L_temp = GSM_L_MULT( wt[k+i], gsm_H[i] ); - * L_result = GSM_L_ADD( L_result, L_temp ); - * } - */ - -#undef STEP -#define STEP( i, H ) (e[ k + i ] * (longword)H) - - /* Every one of these multiplications is done twice -- - * but I don't see an elegant way to optimize this. - * Do you? - */ - -#ifdef STUPID_COMPILER - L_result += STEP( 0, -134 ) ; - L_result += STEP( 1, -374 ) ; - /* + STEP( 2, 0 ) */ - L_result += STEP( 3, 2054 ) ; - L_result += STEP( 4, 5741 ) ; - L_result += STEP( 5, 8192 ) ; - L_result += STEP( 6, 5741 ) ; - L_result += STEP( 7, 2054 ) ; - /* + STEP( 8, 0 ) */ - L_result += STEP( 9, -374 ) ; - L_result += STEP( 10, -134 ) ; -#else - L_result += - STEP( 0, -134 ) - + STEP( 1, -374 ) - /* + STEP( 2, 0 ) */ - + STEP( 3, 2054 ) - + STEP( 4, 5741 ) - + STEP( 5, 8192 ) - + STEP( 6, 5741 ) - + STEP( 7, 2054 ) - /* + STEP( 8, 0 ) */ - + STEP( 9, -374 ) - + STEP(10, -134 ) - ; -#endif - - /* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *) - * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *) - * - * x[k] = SASR( L_result, 16 ); - */ - - /* 2 adds vs. >>16 => 14, minus one shift to compensate for - * those we lost when replacing L_MULT by '*'. - */ - - L_result = SASR( L_result, 13 ); - x[k] = ( L_result < MIN_WORD ? MIN_WORD - : (L_result > MAX_WORD ? MAX_WORD : L_result )); - } -} - -/* 4.2.14 */ - -static void RPE_grid_selection P3((x,xM,Mc_out), - word * x, /* [0..39] IN */ - word * xM, /* [0..12] OUT */ - word * Mc_out /* OUT */ -) -/* - * The signal x[0..39] is used to select the RPE grid which is - * represented by Mc. - */ -{ - /* register word temp1; */ - register int /* m, */ i; - register longword L_result, L_temp; - longword EM; /* xxx should be L_EM? */ - word Mc; - - longword L_common_0_3; - - EM = 0; - Mc = 0; - - /* for (m = 0; m <= 3; m++) { - * L_result = 0; - * - * - * for (i = 0; i <= 12; i++) { - * - * temp1 = SASR( x[m + 3*i], 2 ); - * - * _x_assert(temp1 != MIN_WORD); - * - * L_temp = GSM_L_MULT( temp1, temp1 ); - * L_result = GSM_L_ADD( L_temp, L_result ); - * } - * - * if (L_result > EM) { - * Mc = m; - * EM = L_result; - * } - * } - */ - -#undef STEP -#define STEP( m, i ) L_temp = SASR( x[m + 3 * i], 2 ); \ - L_result += L_temp * L_temp; - - /* common part of 0 and 3 */ - - L_result = 0; - STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 ); - STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 ); - STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12); - L_common_0_3 = L_result; - - /* i = 0 */ - - STEP( 0, 0 ); - L_result <<= 1; /* implicit in L_MULT */ - EM = L_result; - - /* i = 1 */ - - L_result = 0; - STEP( 1, 0 ); - STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 ); - STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 ); - STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12); - L_result <<= 1; - if (L_result > EM) { - Mc = 1; - EM = L_result; - } - - /* i = 2 */ - - L_result = 0; - STEP( 2, 0 ); - STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 ); - STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 ); - STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12); - L_result <<= 1; - if (L_result > EM) { - Mc = 2; - EM = L_result; - } - - /* i = 3 */ - - L_result = L_common_0_3; - STEP( 3, 12 ); - L_result <<= 1; - if (L_result > EM) { - Mc = 3; - EM = L_result; - } - - /**/ - - /* Down-sampling by a factor 3 to get the selected xM[0..12] - * RPE sequence. - */ - for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i]; - *Mc_out = Mc; -} - -/* 4.12.15 */ - -static void APCM_quantization_xmaxc_to_exp_mant P3((xmaxc,exp_out,mant_out), - word xmaxc, /* IN */ - word * exp_out, /* OUT */ - word * mant_out ) /* OUT */ -{ - word exp, mant; - - /* Compute exponent and mantissa of the decoded version of xmaxc - */ - - exp = 0; - if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1; - mant = xmaxc - (exp << 3); - - if (mant == 0) { - exp = -4; - mant = 7; - } - else { - while (mant <= 7) { - mant = mant << 1 | 1; - exp--; - } - mant -= 8; - } - - _x_assert( exp >= -4 && exp <= 6 ); - _x_assert( mant >= 0 && mant <= 7 ); - - *exp_out = exp; - *mant_out = mant; -} - -static void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out), - word * xM, /* [0..12] IN */ - - word * xMc, /* [0..12] OUT */ - word * mant_out, /* OUT */ - word * exp_out, /* OUT */ - word * xmaxc_out /* OUT */ -) -{ - int i, itest; - - word xmax, xmaxc, temp, temp1, temp2; - word exp, mant; - - - /* Find the maximum absolute value xmax of xM[0..12]. - */ - - xmax = 0; - for (i = 0; i <= 12; i++) { - temp = xM[i]; - temp = GSM_ABS(temp); - if (temp > xmax) xmax = temp; - } - - /* Qantizing and coding of xmax to get xmaxc. - */ - - exp = 0; - temp = SASR( xmax, 9 ); - itest = 0; - - for (i = 0; i <= 5; i++) { - - itest |= (temp <= 0); - temp = SASR( temp, 1 ); - - _x_assert(exp <= 5); - if (itest == 0) exp++; /* exp = add (exp, 1) */ - } - - _x_assert(exp <= 6 && exp >= 0); - temp = exp + 5; - - _x_assert(temp <= 11 && temp >= 0); - xmaxc = gsm_add( SASR(xmax, temp), exp << 3 ); - - /* Quantizing and coding of the xM[0..12] RPE sequence - * to get the xMc[0..12] - */ - - APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant ); - - /* This computation uses the fact that the decoded version of xmaxc - * can be calculated by using the exponent and the mantissa part of - * xmaxc (logarithmic table). - * So, this method avoids any division and uses only a scaling - * of the RPE samples by a function of the exponent. A direct - * multiplication by the inverse of the mantissa (NRFAC[0..7] - * found in table 4.5) gives the 3 bit coded version xMc[0..12] - * of the RPE samples. - */ - - - /* Direct computation of xMc[0..12] using table 4.5 - */ - - _x_assert((exp <= 4096) && (exp >= -4096)); - _x_assert((mant >= 0) && (mant <= 7)); - - temp1 = 6 - exp; /* normalization by the exponent */ - temp2 = gsm_NRFAC[ mant ]; /* inverse mantissa */ - - for (i = 0; i <= 12; i++) { - - _x_assert(temp1 >= 0 && temp1 < 16); - - temp = xM[i] << temp1; - temp = GSM_MULT( temp, temp2 ); - temp = SASR(temp, 12); - xMc[i] = temp + 4; /* see note below */ - } - - /* NOTE: This equation is used to make all the xMc[i] positive. - */ - - *mant_out = mant; - *exp_out = exp; - *xmaxc_out = xmaxc; -} - -/* 4.2.16 */ - -static void APCM_inverse_quantization P4((xMc,mant,exp,xMp), - register word * xMc, /* [0..12] IN */ - word mant, - word exp, - register word * xMp) /* [0..12] OUT */ -/* - * This part is for decoding the RPE sequence of coded xMc[0..12] - * samples to obtain the xMp[0..12] array. Table 4.6 is used to get - * the mantissa of xmaxc (FAC[0..7]). - */ -{ - int i; - word temp, temp1, temp2, temp3; - longword ltmp; - - _x_assert((mant >= 0) && (mant <= 7)); - - temp1 = gsm_FAC[ mant ]; /* see 4.2-15 for mant */ - temp2 = gsm_sub( 6, exp ); /* see 4.2-15 for exp */ - temp3 = gsm_asl( 1, gsm_sub( temp2, 1 )); - - for (i = 13; i--;) { - _x_assert((mant >= 0) && (mant <= 7)); - - _x_assert((*xMc <= 7) && (*xMc >= 0)); /* 3 bit unsigned */ - - /* temp = gsm_sub( *xMc++ << 1, 7 ); */ - temp = (*xMc++ << 1) - 7; /* restore sign */ - - _x_assert((temp <= 7) && (temp >= -7)); /* 4 bit signed */ - - temp <<= 12; /* 16 bit signed */ - temp = GSM_MULT_R( temp1, temp ); - temp = GSM_ADD( temp, temp3 ); - *xMp++ = gsm_asr( temp, temp2 ); - } -} - -/* 4.2.17 */ - -static void RPE_grid_positioning P3((Mc,xMp,ep), - word Mc, /* grid position IN */ - register word * xMp, /* [0..12] IN */ - register word * ep /* [0..39] OUT */ -) -/* - * This procedure computes the reconstructed long term residual signal - * ep[0..39] for the LTP analysis filter. The inputs are the Mc - * which is the grid position selection and the xMp[0..12] decoded - * RPE samples which are upsampled by a factor of 3 by inserting zero - * values. - */ -{ - int i = 13; - - _x_assert((0 <= Mc) && (Mc <= 3)); - - switch (Mc) { - case 3: *ep++ = 0; - case 2: do { - *ep++ = 0; - case 1: *ep++ = 0; - case 0: *ep++ = *xMp++; - } while (--i); - } - while (++Mc < 4) *ep++ = 0; - - /* - - int i, k; - for (k = 0; k <= 39; k++) ep[k] = 0; - for (i = 0; i <= 12; i++) { - ep[ Mc + (3*i) ] = xMp[i]; - } - */ -} - -/* 4.2.18 */ - -/* This procedure adds the reconstructed long term residual signal - * ep[0..39] to the estimated signal dpp[0..39] from the long term - * analysis filter to compute the reconstructed short term residual - * signal dp[-40..-1]; also the reconstructed short term residual - * array dp[-120..-41] is updated. - */ - -#if 0 /* Has been inlined in code.c */ -void Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp), - word * dpp, /* [0...39] IN */ - word * ep, /* [0...39] IN */ - word * dp) /* [-120...-1] IN/OUT */ -{ - int k; - - for (k = 0; k <= 79; k++) - dp[ -120 + k ] = dp[ -80 + k ]; - - for (k = 0; k <= 39; k++) - dp[ -40 + k ] = gsm_add( ep[k], dpp[k] ); -} -#endif /* Has been inlined in code.c */ - -void Gsm_RPE_Encoding P5((S,e,xmaxc,Mc,xMc), - - struct gsm_state * S, - - word * e, /* -5..-1][0..39][40..44 IN/OUT */ - word * xmaxc, /* OUT */ - word * Mc, /* OUT */ - word * xMc) /* [0..12] OUT */ -{ - word x[40]; - word xM[13], xMp[13]; - word mant, exp; - - Weighting_filter(e, x); - RPE_grid_selection(x, xM, Mc); - - APCM_quantization( xM, xMc, &mant, &exp, xmaxc); - APCM_inverse_quantization( xMc, mant, exp, xMp); - - RPE_grid_positioning( *Mc, xMp, e ); - -} - -void Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp), - struct gsm_state * S, - - word xmaxcr, - word Mcr, - word * xMcr, /* [0..12], 3 bits IN */ - word * erp /* [0..39] OUT */ -) -{ - word exp, mant; - word xMp[ 13 ]; - - APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant ); - APCM_inverse_quantization( xMcr, mant, exp, xMp ); - RPE_grid_positioning( Mcr, xMp, erp ); - -} diff --git a/src/libxineadec/gsm610/short_term.c b/src/libxineadec/gsm610/short_term.c deleted file mode 100644 index c2d64853b..000000000 --- a/src/libxineadec/gsm610/short_term.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische - * Universitaet Berlin. See the accompanying file "COPYRIGHT" for - * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - */ - -/* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/short_term.c,v 1.3 2003/12/07 15:34:30 f1rmb Exp $ */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include "xineutils.h" -#include "private.h" - -#include "gsm.h" -#include "proto.h" - -/* - * SHORT TERM ANALYSIS FILTERING SECTION - */ - -/* 4.2.8 */ - -static void Decoding_of_the_coded_Log_Area_Ratios P2((LARc,LARpp), - word * LARc, /* coded log area ratio [0..7] IN */ - word * LARpp) /* out: decoded .. */ -{ - register word temp1 /* , temp2 */; - register long ltmp; /* for GSM_ADD */ - - /* This procedure requires for efficient implementation - * two tables. - * - * INVA[1..8] = integer( (32768 * 8) / real_A[1..8]) - * MIC[1..8] = minimum value of the LARc[1..8] - */ - - /* Compute the LARpp[1..8] - */ - - /* for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) { - * - * temp1 = GSM_ADD( *LARc, *MIC ) << 10; - * temp2 = *B << 1; - * temp1 = GSM_SUB( temp1, temp2 ); - * - * _x_assert(*INVA != MIN_WORD); - * - * temp1 = GSM_MULT_R( *INVA, temp1 ); - * *LARpp = GSM_ADD( temp1, temp1 ); - * } - */ - -#undef STEP -#define STEP( B, MIC, INVA ) \ - temp1 = GSM_ADD( *LARc++, MIC ) << 10; \ - temp1 = GSM_SUB( temp1, B << 1 ); \ - temp1 = GSM_MULT_R( INVA, temp1 ); \ - *LARpp++ = GSM_ADD( temp1, temp1 ); - - STEP( 0, -32, 13107 ); - STEP( 0, -32, 13107 ); - STEP( 2048, -16, 13107 ); - STEP( -2560, -16, 13107 ); - - STEP( 94, -8, 19223 ); - STEP( -1792, -8, 17476 ); - STEP( -341, -4, 31454 ); - STEP( -1144, -4, 29708 ); - - /* NOTE: the addition of *MIC is used to restore - * the sign of *LARc. - */ -} - -/* 4.2.9 */ -/* Computation of the quantized reflection coefficients - */ - -/* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8] - */ - -/* - * Within each frame of 160 analyzed speech samples the short term - * analysis and synthesis filters operate with four different sets of - * coefficients, derived from the previous set of decoded LARs(LARpp(j-1)) - * and the actual set of decoded LARs (LARpp(j)) - * - * (Initial value: LARpp(j-1)[1..8] = 0.) - */ - -static void Coefficients_0_12 P3((LARpp_j_1, LARpp_j, LARp), - register word * LARpp_j_1, - register word * LARpp_j, - register word * LARp) -{ - register int i; - register longword ltmp; - - for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) { - *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); - *LARp = GSM_ADD( *LARp, SASR( *LARpp_j_1, 1)); - } -} - -static void Coefficients_13_26 P3((LARpp_j_1, LARpp_j, LARp), - register word * LARpp_j_1, - register word * LARpp_j, - register word * LARp) -{ - register int i; - register longword ltmp; - for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { - *LARp = GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 )); - } -} - -static void Coefficients_27_39 P3((LARpp_j_1, LARpp_j, LARp), - register word * LARpp_j_1, - register word * LARpp_j, - register word * LARp) -{ - register int i; - register longword ltmp; - - for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { - *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); - *LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 )); - } -} - - -static void Coefficients_40_159 P2((LARpp_j, LARp), - register word * LARpp_j, - register word * LARp) -{ - register int i; - - for (i = 1; i <= 8; i++, LARp++, LARpp_j++) - *LARp = *LARpp_j; -} - -/* 4.2.9.2 */ - -static void LARp_to_rp P1((LARp), - register word * LARp) /* [0..7] IN/OUT */ -/* - * The input of this procedure is the interpolated LARp[0..7] array. - * The reflection coefficients, rp[i], are used in the analysis - * filter and in the synthesis filter. - */ -{ - register int i; - register word temp; - register longword ltmp; - - for (i = 1; i <= 8; i++, LARp++) { - - /* temp = GSM_ABS( *LARp ); - * - * if (temp < 11059) temp <<= 1; - * else if (temp < 20070) temp += 11059; - * else temp = GSM_ADD( temp >> 2, 26112 ); - * - * *LARp = *LARp < 0 ? -temp : temp; - */ - - if (*LARp < 0) { - temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp); - *LARp = - ((temp < 11059) ? temp << 1 - : ((temp < 20070) ? temp + 11059 - : GSM_ADD( temp >> 2, 26112 ))); - } else { - temp = *LARp; - *LARp = (temp < 11059) ? temp << 1 - : ((temp < 20070) ? temp + 11059 - : GSM_ADD( temp >> 2, 26112 )); - } - } -} - - -/* 4.2.10 */ -static void Short_term_analysis_filtering P4((S,rp,k_n,s), - struct gsm_state * S, - register word * rp, /* [0..7] IN */ - register int k_n, /* k_end - k_start */ - register word * s /* [0..n-1] IN/OUT */ -) -/* - * This procedure computes the short term residual signal d[..] to be fed - * to the RPE-LTP loop from the s[..] signal and from the local rp[..] - * array (quantized reflection coefficients). As the call of this - * procedure can be done in many ways (see the interpolation of the LAR - * coefficient), it is assumed that the computation begins with index - * k_start (for arrays d[..] and s[..]) and stops with index k_end - * (k_start and k_end are defined in 4.2.9.1). This procedure also - * needs to keep the array u[0..7] in memory for each call. - */ -{ - register word * u = S->u; - register int i; - register word di, zzz, ui, sav, rpi; - register longword ltmp; - - for (; k_n--; s++) { - - di = sav = *s; - - for (i = 0; i < 8; i++) { /* YYY */ - - ui = u[i]; - rpi = rp[i]; - u[i] = sav; - - zzz = GSM_MULT_R(rpi, di); - sav = GSM_ADD( ui, zzz); - - zzz = GSM_MULT_R(rpi, ui); - di = GSM_ADD( di, zzz ); - } - - *s = di; - } -} - -#if defined(USE_FLOAT_MUL) && defined(FAST) - -static void Fast_Short_term_analysis_filtering P4((S,rp,k_n,s), - struct gsm_state * S, - register word * rp, /* [0..7] IN */ - register int k_n, /* k_end - k_start */ - register word * s /* [0..n-1] IN/OUT */ -) -{ - register word * u = S->u; - register int i; - - float uf[8], - rpf[8]; - - register float scalef = 3.0517578125e-5; - register float sav, di, temp; - - for (i = 0; i < 8; ++i) { - uf[i] = u[i]; - rpf[i] = rp[i] * scalef; - } - for (; k_n--; s++) { - sav = di = *s; - for (i = 0; i < 8; ++i) { - register float rpfi = rpf[i]; - register float ufi = uf[i]; - - uf[i] = sav; - temp = rpfi * di + ufi; - di += rpfi * ufi; - sav = temp; - } - *s = di; - } - for (i = 0; i < 8; ++i) u[i] = uf[i]; -} -#endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */ - -static void Short_term_synthesis_filtering P5((S,rrp,k,wt,sr), - struct gsm_state * S, - register word * rrp, /* [0..7] IN */ - register int k, /* k_end - k_start */ - register word * wt, /* [0..k-1] IN */ - register word * sr /* [0..k-1] OUT */ -) -{ - register word * v = S->v; - register int i; - register word sri, tmp1, tmp2; - register longword ltmp; /* for GSM_ADD & GSM_SUB */ - - while (k--) { - sri = *wt++; - for (i = 8; i--;) { - - /* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) ); - */ - tmp1 = rrp[i]; - tmp2 = v[i]; - tmp2 = ( tmp1 == MIN_WORD && tmp2 == MIN_WORD - ? MAX_WORD - : 0x0FFFF & (( (longword)tmp1 * (longword)tmp2 - + 16384) >> 15)) ; - - sri = GSM_SUB( sri, tmp2 ); - - /* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) ); - */ - tmp1 = ( tmp1 == MIN_WORD && sri == MIN_WORD - ? MAX_WORD - : 0x0FFFF & (( (longword)tmp1 * (longword)sri - + 16384) >> 15)) ; - - v[i+1] = GSM_ADD( v[i], tmp1); - } - *sr++ = v[0] = sri; - } -} - - -#if defined(FAST) && defined(USE_FLOAT_MUL) - -static void Fast_Short_term_synthesis_filtering P5((S,rrp,k,wt,sr), - struct gsm_state * S, - register word * rrp, /* [0..7] IN */ - register int k, /* k_end - k_start */ - register word * wt, /* [0..k-1] IN */ - register word * sr /* [0..k-1] OUT */ -) -{ - register word * v = S->v; - register int i; - - float va[9], rrpa[8]; - register float scalef = 3.0517578125e-5, temp; - - for (i = 0; i < 8; ++i) { - va[i] = v[i]; - rrpa[i] = (float)rrp[i] * scalef; - } - while (k--) { - register float sri = *wt++; - for (i = 8; i--;) { - sri -= rrpa[i] * va[i]; - if (sri < -32768.) sri = -32768.; - else if (sri > 32767.) sri = 32767.; - - temp = va[i] + rrpa[i] * sri; - if (temp < -32768.) temp = -32768.; - else if (temp > 32767.) temp = 32767.; - va[i+1] = temp; - } - *sr++ = va[0] = sri; - } - for (i = 0; i < 9; ++i) v[i] = va[i]; -} - -#endif /* defined(FAST) && defined(USE_FLOAT_MUL) */ - -void Gsm_Short_Term_Analysis_Filter P3((S,LARc,s), - - struct gsm_state * S, - - word * LARc, /* coded log area ratio [0..7] IN */ - word * s /* signal [0..159] IN/OUT */ -) -{ - word * LARpp_j = S->LARpp[ S->j ]; - word * LARpp_j_1 = S->LARpp[ S->j ^= 1 ]; - - word LARp[8]; - -#undef FILTER -#if defined(FAST) && defined(USE_FLOAT_MUL) -# define FILTER (* (S->fast \ - ? Fast_Short_term_analysis_filtering \ - : Short_term_analysis_filtering )) - -#else -# define FILTER Short_term_analysis_filtering -#endif - - Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j ); - - Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); - LARp_to_rp( LARp ); - FILTER( S, LARp, 13, s); - - Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); - LARp_to_rp( LARp ); - FILTER( S, LARp, 14, s + 13); - - Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); - LARp_to_rp( LARp ); - FILTER( S, LARp, 13, s + 27); - - Coefficients_40_159( LARpp_j, LARp); - LARp_to_rp( LARp ); - FILTER( S, LARp, 120, s + 40); -} - -void Gsm_Short_Term_Synthesis_Filter P4((S, LARcr, wt, s), - struct gsm_state * S, - - word * LARcr, /* received log area ratios [0..7] IN */ - word * wt, /* received d [0..159] IN */ - - word * s /* signal s [0..159] OUT */ -) -{ - word * LARpp_j = S->LARpp[ S->j ]; - word * LARpp_j_1 = S->LARpp[ S->j ^=1 ]; - - word LARp[8]; - -#undef FILTER -#if defined(FAST) && defined(USE_FLOAT_MUL) - -# define FILTER (* (S->fast \ - ? Fast_Short_term_synthesis_filtering \ - : Short_term_synthesis_filtering )) -#else -# define FILTER Short_term_synthesis_filtering -#endif - - Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j ); - - Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); - LARp_to_rp( LARp ); - FILTER( S, LARp, 13, wt, s ); - - Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); - LARp_to_rp( LARp ); - FILTER( S, LARp, 14, wt + 13, s + 13 ); - - Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); - LARp_to_rp( LARp ); - FILTER( S, LARp, 13, wt + 27, s + 27 ); - - Coefficients_40_159( LARpp_j, LARp ); - LARp_to_rp( LARp ); - FILTER(S, LARp, 120, wt + 40, s + 40); -} diff --git a/src/libxineadec/gsm610/table.c b/src/libxineadec/gsm610/table.c deleted file mode 100644 index 797685c07..000000000 --- a/src/libxineadec/gsm610/table.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische - * Universitaet Berlin. See the accompanying file "COPYRIGHT" for - * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - */ - -/* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/table.c,v 1.1 2002/10/12 19:12:49 tmmm Exp $ */ - -/* Most of these tables are inlined at their point of use. - */ - -/* 4.4 TABLES USED IN THE FIXED POINT IMPLEMENTATION OF THE RPE-LTP - * CODER AND DECODER - * - * (Most of them inlined, so watch out.) - */ - -#define GSM_TABLE_C -#include "private.h" -#include "gsm.h" - -/* Table 4.1 Quantization of the Log.-Area Ratios - */ -/* i 1 2 3 4 5 6 7 8 */ -word gsm_A[8] = {20480, 20480, 20480, 20480, 13964, 15360, 8534, 9036}; -word gsm_B[8] = { 0, 0, 2048, -2560, 94, -1792, -341, -1144}; -word gsm_MIC[8] = { -32, -32, -16, -16, -8, -8, -4, -4 }; -word gsm_MAC[8] = { 31, 31, 15, 15, 7, 7, 3, 3 }; - - -/* Table 4.2 Tabulation of 1/A[1..8] - */ -word gsm_INVA[8]={ 13107, 13107, 13107, 13107, 19223, 17476, 31454, 29708 }; - - -/* Table 4.3a Decision level of the LTP gain quantizer - */ -/* bc 0 1 2 3 */ -word gsm_DLB[4] = { 6554, 16384, 26214, 32767 }; - - -/* Table 4.3b Quantization levels of the LTP gain quantizer - */ -/* bc 0 1 2 3 */ -word gsm_QLB[4] = { 3277, 11469, 21299, 32767 }; - - -/* Table 4.4 Coefficients of the weighting filter - */ -/* i 0 1 2 3 4 5 6 7 8 9 10 */ -word gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 }; - - -/* Table 4.5 Normalized inverse mantissa used to compute xM/xmax - */ -/* i 0 1 2 3 4 5 6 7 */ -word gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 }; - - -/* Table 4.6 Normalized direct mantissa used to compute xM/xmax - */ -/* i 0 1 2 3 4 5 6 7 */ -word gsm_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 }; diff --git a/src/libxineadec/gsm610/unproto.h b/src/libxineadec/gsm610/unproto.h deleted file mode 100644 index f49530c22..000000000 --- a/src/libxineadec/gsm610/unproto.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische - * Universitaet Berlin. See the accompanying file "COPYRIGHT" for - * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - */ - -/*$Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/unproto.h,v 1.1 2002/10/12 19:12:49 tmmm Exp $*/ - -#ifdef PROTO_H /* sic */ -#undef PROTO_H - -#undef P -#undef P0 -#undef P1 -#undef P2 -#undef P3 -#undef P4 -#undef P5 -#undef P6 -#undef P7 -#undef P8 - -#endif /* PROTO_H */ diff --git a/src/libxineadec/nosefart/Makefile.am b/src/libxineadec/nosefart/Makefile.am deleted file mode 100644 index 4ca4f75b6..000000000 --- a/src/libxineadec/nosefart/Makefile.am +++ /dev/null @@ -1,34 +0,0 @@ -include $(top_srcdir)/misc/Makefile.common - -noinst_LTLIBRARIES = libnosefart.la - -libnosefart_la_SOURCES = \ - fds_snd.c \ - log.c \ - mmc5_snd.c \ - nes_apu.c \ - vrc7_snd.c \ - dis6502.c \ - fmopl.c \ - memguard.c \ - nes6502.c \ - nsf.c \ - vrcvisnd.c - -libnosefart_la_CFLAGS = $(VISIBILITY_FLAG) -DNSF_PLAYER -fno-strict-aliasing - -noinst_HEADERS = \ - dis6502.h \ - fmopl.h \ - memguard.h \ - nes6502.h \ - nsf.h \ - types.h \ - vrc7_snd.h \ - fds_snd.h \ - log.h \ - mmc5_snd.h \ - nes_apu.h \ - osd.h \ - version.h \ - vrcvisnd.h diff --git a/src/libxineadec/nosefart/diff_to_nosefart_cvs.patch b/src/libxineadec/nosefart/diff_to_nosefart_cvs.patch deleted file mode 100644 index e46633478..000000000 --- a/src/libxineadec/nosefart/diff_to_nosefart_cvs.patch +++ /dev/null @@ -1,325 +0,0 @@ ---- a/src/libxineadec/nosefart/log.h 2010-11-28 19:57:41.000000000 +0100 -+++ b/src/libxineadec/nosefart/log.h 2010-10-10 21:03:43.000000000 +0200 -@@ -27,11 +27,12 @@ - #define _LOG_H_ - - #include <stdio.h> -+#include "attributes.h" - - extern int log_init(void); - extern void log_shutdown(void); - extern void log_print(const char *string); --extern void log_printf(const char *format, ...); -+extern void log_printf(const char *format, ...) XINE_FORMAT_PRINTF(1, 2); - - #endif /* _LOG_H_ */ - -diff -r fe4287194cac src/libxineadec/nosefart/nes_apu.h ---- /src/libxineadec/nosefart/nes_apu.h 2007-12-14 05:46:22.000000000 +0100 -+++ /src/libxineadec/nosefart/nes_apu.h 2010-11-28 20:13:05.000000000 +0100 -@@ -289,6 +289,7 @@ extern void apu_write(uint32 address, ui - /* for visualization */ - extern void apu_getpcmdata(void **data, int *num_samples, int *sample_bits); - -+extern void apu_setcontext(apu_t *src_apu); - - #ifdef __cplusplus - } -diff -r fe4287194cac src/libxineadec/nosefart/fmopl.c ---- a/src/libxineadec/nosefart/fmopl.c Sun Nov 28 20:32:56 2010 +0100 -+++ b/src/libxineadec/nosefart/fmopl.c Sun Nov 28 20:22:51 2010 +0100 -@@ -18,9 +18,9 @@ - #include <stdlib.h> - #include <string.h> - #include <stdarg.h> -+#include <math.h> - //#include "driver.h" /* use M.A.M.E. */ - #include "fmopl.h" --#include <math.h> - - /* MPC - hacks */ - #include "types.h" -@@ -218,19 +218,6 @@ static INT32 feedback2; /* connect for - - /* --------------------- subroutines --------------------- */ - --/* There's no good reason why I should have to do this, but using "pow" --(the POSIX fuction) causes it to not compile on my machine ----Matthew Strait */ --double mypow(float base, int power) --{ -- int ans = 1, k; -- -- for( k = 0; k < power; k++) -- ans *= (int)base; -- -- return ans; --} -- - INLINE int Limit( int val, int max, int min ) { - if ( val > max ) - val = max; -@@ -628,7 +615,7 @@ static int OPLOpenTable( void ) - } - /* make total level table */ - for (t = 0;t < EG_ENT-1 ;t++){ -- rate = ((1<<TL_BITS)-1)/mypow(10,EG_STEP*t/20); /* dB -> voltage */ -+ rate = ((1<<TL_BITS)-1)/pow(10,EG_STEP*t/20); /* dB -> voltage */ - TL_TABLE[ t] = (int)rate; - TL_TABLE[TL_MAX+t] = -TL_TABLE[t]; - /* LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/ -@@ -663,7 +650,7 @@ static int OPLOpenTable( void ) - for (i=0; i<EG_ENT; i++) - { - /* ATTACK curve */ -- pom = (float)mypow( ((double)(EG_ENT-1-i)/EG_ENT) , 8 ) * EG_ENT; -+ pom = pow( ((double)(EG_ENT-1-i)/EG_ENT) , 8 ) * EG_ENT; - /* if( pom >= EG_ENT ) pom = EG_ENT-1; */ - ENV_CURVE[i] = (int)pom; - /* DECAY ,RELEASE curve */ -@@ -1334,5 +1321,3 @@ int OPLTimerOver(FM_OPL *OPL,int c) - if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); - return OPL->status>>7; - } -- -- -diff -r d92191344055 src/libxineadec/nosefart/memguard.c ---- a/src/libxineadec/nosefart/memguard.c Sun Nov 28 20:42:19 2010 +0100 -+++ b/src/libxineadec/nosefart/memguard.c Sun Nov 28 20:47:08 2010 +0100 -@@ -33,6 +33,15 @@ - - #include <string.h> - #include <stdlib.h> -+ -+#if HAVE_INTTYPES_H -+# include <inttypes.h> -+#else -+# if HAVE_STDINT_H -+# include <stdint.h> -+# endif -+#endif -+ - #include "memguard.h" - #include "log.h" - -@@ -271,7 +280,7 @@ - char fail[256]; - - if (NULL == data || NULL == *data -- || 0xFFFFFFFF == (uint32) *data || 0xFFFFFFFF == (uint32) data) -+ || ((uintptr_t)-1) == (uintptr_t) *data || ((uintptr_t)-1) == (uintptr_t) data) - { - #ifdef NOFRENDO_DEBUG - sprintf(fail, "free: attempted to free NULL pointer at line %d of %s\n", -diff -r 075029931740 src/libxineadec/nosefart/osd.h ---- a/src/libxineadec/nosefart/osd.h Sun Nov 28 21:04:01 2010 +0100 -+++ b/src/libxineadec/nosefart/osd.h Sun Nov 28 15:12:02 2010 +0100 -@@ -27,7 +27,7 @@ - #define _OSD_H_ - - --#ifdef __GNUC__ -+#if defined(__GNUC__) || defined(__ICC) - #define __PACKED__ __attribute__ ((packed)) - #define PATH_SEP '/' - #ifdef __DJGPP__ -diff -r 075029931740 src/libxineadec/nosefart/types.h ---- a/src/libxineadec/nosefart/types.h 2010-11-28 21:11:10.000000000 +0100 -+++ b/src/libxineadec/nosefart/types.h 2010-11-28 21:07:45.000000000 +0100 -@@ -23,8 +23,12 @@ - ** $Id: types.h,v 1.4 2004/08/27 19:33:37 valtri Exp $ - */ - --#ifndef _TYPES_H_ --#define _TYPES_H_ -+#ifndef _NOSEFART_TYPES_H_ -+#define _NOSEFART_TYPES_H_ -+ -+#ifdef HAVE_CONFIG_H -+#include "config.h" -+#endif - - /* Define this if running on little-endian (x86) systems */ - -@@ -95,7 +99,7 @@ - #define ASSERT_MSG(msg) - #endif - --#endif /* _TYPES_H_ */ -+#endif /* _NOSEFART_TYPES_H_ */ - - /* - ** $Log: types.h,v $ -diff -r 075029931740 src/libxineadec/nosefart/nes6502.h ---- a/src/libxineadec/nosefart/nes6502.h Sun Nov 28 15:12:02 2010 +0100 -+++ b/src/libxineadec/nosefart/nes6502.h Sun Nov 28 21:18:28 2010 +0100 -@@ -23,6 +23,9 @@ - ** $Id: nes6502.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ - */ - -+/* straitm */ -+#include "types.h" -+ - /* NOTE: 16-bit addresses avoided like the plague: use 32-bit values - ** wherever humanly possible - */ -diff -r 075029931740 src/libxineadec/nosefart/nsf.c ---- a/src/libxineadec/nosefart/nsf.c 2007-12-14 05:46:22.000000000 +0100 -+++ b/src/libxineadec/nosefart/nsf.c 2010-11-28 21:31:22.000000000 +0100 -@@ -693,7 +693,7 @@ nsf_t * nsf_load_extended(struct nsf_loa - #if 0 - if (length <= NSF_HEADER_SIZE) { - log_printf("nsf : [%s] not an NSF format file\n", -- loader->fname(loader)); -+ loader->fname); - goto error; - } - #endif -@@ -701,14 +701,14 @@ nsf_t * nsf_load_extended(struct nsf_loa - /* Read magic */ - if (loader->read(loader, id, 5)) { - log_printf("nsf : [%s] error reading magic number\n", -- loader->fname(loader)); -+ loader->fname); - goto error; - } - - /* Check magic */ - if (memcmp(id, NSF_MAGIC, 5)) { - log_printf("nsf : [%s] is not an NSF format file\n", -- loader->fname(loader)); -+ loader->fname); - goto error; - } - -@@ -719,7 +719,7 @@ nsf_t * nsf_load_extended(struct nsf_loa - - if (NULL == temp_nsf) { - log_printf("nsf : [%s] error allocating nsf header\n", -- loader->fname(loader)); -+ loader->fname); - goto error; - } - /* $$$ ben : safety net */ -@@ -730,7 +730,7 @@ nsf_t * nsf_load_extended(struct nsf_loa - /* Read header (without MAGIC) */ - if (loader->read(loader, (int8 *)temp_nsf+5, NSF_HEADER_SIZE - 5)) { - log_printf("nsf : [%s] error reading nsf header\n", -- loader->fname(loader)); -+ loader->fname); - goto error; - } - -@@ -763,7 +763,7 @@ nsf_t * nsf_load_extended(struct nsf_loa - - if (temp_nsf->length <= 0) { - log_printf("nsf : [%s] not an NSF format file (missing data)\n", -- loader->fname(loader)); -+ loader->fname); - goto error; - } - -@@ -778,14 +778,14 @@ nsf_t * nsf_load_extended(struct nsf_loa - } - if (NULL == temp_nsf->data) { - log_printf("nsf : [%s] error allocating nsf data\n", -- loader->fname(loader)); -+ loader->fname); - goto error; - } - - /* Read data */ - if (loader->read(loader, temp_nsf->data, temp_nsf->length)) { - log_printf("nsf : [%s] error reading NSF data\n", -- loader->fname(loader)); -+ loader->fname); - goto error; - } - -@@ -805,7 +805,7 @@ nsf_t * nsf_load_extended(struct nsf_loa - - if (size < sizeof(nsf_file_ext)) { - log_printf("nsf : [%s] corrupt extension size (%d)\n", -- loader->fname(loader), size); -+ loader->fname, size); - /* Not a fatal error here. Just skip extension loading. */ - break; - } -@@ -827,7 +827,7 @@ nsf_t * nsf_load_extended(struct nsf_loa - - if (loader->read(loader, tmp_time, size)) { - log_printf("nsf : [%s] missing extension data\n", -- loader->fname(loader)); -+ loader->fname); - /* Not a fatal error here. Just skip extension loading. */ - break; - } -@@ -835,7 +835,7 @@ nsf_t * nsf_load_extended(struct nsf_loa - temp_nsf->song_frames = malloc(sizeof(*temp_nsf->song_frames) * songs); - if (!temp_nsf->song_frames) { - log_printf("nsf : [%s] extension alloc failed\n", -- loader->fname(loader)); -+ loader->fname); - /* Not a fatal error here. Just skip extension loading. */ - break; - } -@@ -858,7 +858,7 @@ nsf_t * nsf_load_extended(struct nsf_loa - } - } else if (loader->skip(loader, size)) { - log_printf("nsf : [%s] extension skip failed\n", -- loader->fname(loader)); -+ loader->fname); - /* Not a fatal error here. Just skip extension loading. */ - break; - } -diff -r 8bf4ad557dac src/libxineadec/nosefart/nsf.h ---- a/src/libxineadec/nosefart/nsf.h Tue Nov 30 23:30:19 2010 +0100 -+++ b/src/libxineadec/nosefart/nsf.h Tue Nov 30 23:38:15 2010 +0100 -@@ -67,22 +67,22 @@ - typedef struct nsf_s - { - /* NESM header */ -- uint8 id[5] __PACKED__; /* NESM\x1A */ -- uint8 version __PACKED__; /* spec version */ -- uint8 num_songs __PACKED__; /* total num songs */ -- uint8 start_song __PACKED__; /* first song */ -- uint16 load_addr __PACKED__; /* loc to load code */ -- uint16 init_addr __PACKED__; /* init call address */ -- uint16 play_addr __PACKED__; /* play call address */ -- uint8 song_name[32] __PACKED__; /* name of song */ -- uint8 artist_name[32] __PACKED__; /* artist name */ -- uint8 copyright[32] __PACKED__; /* copyright info */ -- uint16 ntsc_speed __PACKED__; /* playback speed (if NTSC) */ -- uint8 bankswitch_info[8] __PACKED__; /* initial code banking */ -- uint16 pal_speed __PACKED__; /* playback speed (if PAL) */ -- uint8 pal_ntsc_bits __PACKED__; /* NTSC/PAL determination bits */ -- uint8 ext_sound_type __PACKED__; /* type of external sound gen. */ -- uint8 reserved[4] __PACKED__; /* reserved */ -+ uint8 id[5]; /* NESM\x1A */ -+ uint8 version; /* spec version */ -+ uint8 num_songs; /* total num songs */ -+ uint8 start_song; /* first song */ -+ uint16 load_addr; /* loc to load code */ -+ uint16 init_addr; /* init call address */ -+ uint16 play_addr; /* play call address */ -+ uint8 song_name[32]; /* name of song */ -+ uint8 artist_name[32]; /* artist name */ -+ uint8 copyright[32]; /* copyright info */ -+ uint16 ntsc_speed; /* playback speed (if NTSC) */ -+ uint8 bankswitch_info[8]; /* initial code banking */ -+ uint16 pal_speed; /* playback speed (if PAL) */ -+ uint8 pal_ntsc_bits; /* NTSC/PAL determination bits */ -+ uint8 ext_sound_type; /* type of external sound gen. */ -+ uint8 reserved[4]; /* reserved */ - - /* things that the NSF player needs */ - uint8 *data; /* actual NSF data */ -@@ -105,7 +105,7 @@ - - /* our main processing routine, calls all external mixing routines */ - void (*process)(void *buffer, int num_samples); --} nsf_t; -+} __PACKED__ nsf_t; - - /* $$$ ben : Generic loader struct */ - struct nsf_loader_t { diff --git a/src/libxineadec/nosefart/dis6502.c b/src/libxineadec/nosefart/dis6502.c deleted file mode 100644 index ff552d219..000000000 --- a/src/libxineadec/nosefart/dis6502.c +++ /dev/null @@ -1,474 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** dis6502.c -** -** 6502 disassembler based on code from John Saeger -** $Id: dis6502.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ -*/ - -#include "types.h" -#include "log.h" -#include "nes6502.h" -#include "dis6502.h" - -#ifdef NES6502_DEBUG - -/* addressing modes */ -enum { _imp, _acc, _rel, _imm, _abs, _abs_x, _abs_y, _zero, _zero_x, _zero_y, _ind, _ind_x, _ind_y }; - -/* keep a filthy local copy of PC to -** reduce the amount of parameter passing -*/ -static uint32 pc_reg; - - -static uint8 dis_op8(void) -{ - return (nes6502_getbyte(pc_reg + 1)); -} - -static uint16 dis_op16(void) -{ - return (nes6502_getbyte(pc_reg + 1) + (nes6502_getbyte(pc_reg + 2) << 8)); -} - -static void dis_show_ind(void) -{ - log_printf("(%04X) ", dis_op16()); -} - -static void dis_show_ind_x(void) -{ - log_printf("(%02X,x) ", dis_op8()); -} - -static void dis_show_ind_y(void) -{ - log_printf("(%02X),y ", dis_op8()); -} - -static void dis_show_zero_x(void) -{ - log_printf(" %02X,x ", dis_op8()); -} - -static void dis_show_zero_y(void) -{ - log_printf(" %02X,y ", dis_op8()); -} - -static void dis_show_abs_y(void) -{ - log_printf(" %04X,y ", dis_op16()); -} - -static void dis_show_abs_x(void) -{ - log_printf(" %04X,x ", dis_op16()); -} - -static void dis_show_zero(void) -{ - log_printf(" %02X ", dis_op8()); -} - -static void dis_show_abs(void) -{ - log_printf(" %04X ", dis_op16()); -} - -static void dis_show_immediate(void) -{ - log_printf("#%02X ", dis_op8()); -} - -static void dis_show_acc(void) -{ - log_printf(" a "); -} - -static void dis_show_relative(void) -{ - int target; - - target = (int8) dis_op8(); - target += (pc_reg + 2); - log_printf(" %04X ", target); -} - -static void dis_show_code(int optype) -{ - log_printf("%02X ", nes6502_getbyte(pc_reg)); - - switch (optype) - { - case _imp: - case _acc: - log_printf(" "); - break; - - case _rel: - case _imm: - case _zero: - case _zero_x: - log_printf("%02X ", nes6502_getbyte(pc_reg + 1)); - break; - - case _abs: - case _abs_x: - case _abs_y: - case _ind: - case _ind_x: - case _ind_y: - log_printf("%02X %02X ", nes6502_getbyte(pc_reg + 1), nes6502_getbyte(pc_reg + 2)); - break; - } -} - -static void dis_show_op(char *opstr, int optype) -{ - dis_show_code(optype); - log_printf("%s ", opstr); - - switch(optype) - { - case _imp: log_printf(" "); break; - case _acc: dis_show_acc(); break; - case _rel: dis_show_relative(); break; - case _imm: dis_show_immediate(); break; - case _abs: dis_show_abs(); break; - case _abs_x: dis_show_abs_x(); break; - case _abs_y: dis_show_abs_y(); break; - case _zero: dis_show_zero(); break; - case _zero_x: dis_show_zero_x(); break; - case _ind: dis_show_ind(); break; - case _ind_x: dis_show_ind_x(); break; - case _ind_y: dis_show_ind_y(); break; - } -} - -void nes6502_disasm(uint32 PC, uint8 P, uint8 A, uint8 X, uint8 Y, uint8 S) -{ - pc_reg = PC; - - log_printf("%04X: ", pc_reg); - - switch(nes6502_getbyte(pc_reg)) - { - case 0x00: dis_show_op("brk",_imp); break; - case 0x01: dis_show_op("ora",_ind_x); break; - case 0x02: dis_show_op("jam",_imp); break; - case 0x03: dis_show_op("slo",_ind_x); break; - case 0x04: dis_show_op("nop",_zero); break; - case 0x05: dis_show_op("ora",_zero); break; - case 0x06: dis_show_op("asl",_zero); break; - case 0x07: dis_show_op("slo",_zero); break; - case 0x08: dis_show_op("php",_imp); break; - case 0x09: dis_show_op("ora",_imm); break; - case 0x0a: dis_show_op("asl",_acc); break; - case 0x0b: dis_show_op("anc",_imm); break; - case 0x0c: dis_show_op("nop",_abs); break; - case 0x0d: dis_show_op("ora",_abs); break; - case 0x0e: dis_show_op("asl",_abs); break; - case 0x0f: dis_show_op("slo",_abs); break; - - case 0x10: dis_show_op("bpl",_rel); break; - case 0x11: dis_show_op("ora",_ind_y); break; - case 0x12: dis_show_op("jam",_imp); break; - case 0x13: dis_show_op("slo",_ind_y); break; - case 0x14: dis_show_op("nop",_zero_x); break; - case 0x15: dis_show_op("ora",_zero_x); break; - case 0x16: dis_show_op("asl",_zero_x); break; - case 0x17: dis_show_op("slo",_zero_x); break; - case 0x18: dis_show_op("clc",_imp); break; - case 0x19: dis_show_op("ora",_abs_y); break; - case 0x1a: dis_show_op("nop",_imp); break; - case 0x1b: dis_show_op("slo",_abs_y); break; - case 0x1c: dis_show_op("nop",_abs_x); break; - case 0x1d: dis_show_op("ora",_abs_x); break; - case 0x1e: dis_show_op("asl",_abs_x); break; - case 0x1f: dis_show_op("slo",_abs_x); break; - - case 0x20: dis_show_op("jsr",_abs); break; - case 0x21: dis_show_op("and",_ind_x); break; - case 0x22: dis_show_op("jam",_imp); break; - case 0x23: dis_show_op("rla",_ind_x); break; - case 0x24: dis_show_op("bit",_zero); break; - case 0x25: dis_show_op("and",_zero); break; - case 0x26: dis_show_op("rol",_zero); break; - case 0x27: dis_show_op("rla",_zero); break; - case 0x28: dis_show_op("plp",_imp); break; - case 0x29: dis_show_op("and",_imm); break; - case 0x2a: dis_show_op("rol",_acc); break; - case 0x2b: dis_show_op("anc",_imm); break; - case 0x2c: dis_show_op("bit",_abs); break; - case 0x2d: dis_show_op("and",_abs); break; - case 0x2e: dis_show_op("rol",_abs); break; - case 0x2f: dis_show_op("rla",_abs); break; - - case 0x30: dis_show_op("bmi",_rel); break; - case 0x31: dis_show_op("and",_ind_y); break; - case 0x32: dis_show_op("jam",_imp); break; - case 0x33: dis_show_op("rla",_ind_y); break; -/* case 0x34: dis_show_op("nop",_zero); break;*/ - case 0x34: dis_show_op("nop",_imp); break; - case 0x35: dis_show_op("and",_zero_x); break; - case 0x36: dis_show_op("rol",_zero_x); break; - case 0x37: dis_show_op("rla",_zero_x); break; - case 0x38: dis_show_op("sec",_imp); break; - case 0x39: dis_show_op("and",_abs_y); break; - case 0x3a: dis_show_op("nop",_imp); break; - case 0x3b: dis_show_op("rla",_abs_y); break; -/* case 0x3c: dis_show_op("nop",_imp); break;*/ - case 0x3c: dis_show_op("nop",_abs_x); break; - case 0x3d: dis_show_op("and",_abs_x); break; - case 0x3e: dis_show_op("rol",_abs_x); break; - case 0x3f: dis_show_op("rla",_abs_x); break; - - case 0x40: dis_show_op("rti",_imp); break; - case 0x41: dis_show_op("eor",_ind_x); break; - case 0x42: dis_show_op("jam",_imp); break; - case 0x43: dis_show_op("sre",_ind_x); break; - case 0x44: dis_show_op("nop",_zero); break; - case 0x45: dis_show_op("eor",_zero); break; - case 0x46: dis_show_op("lsr",_zero); break; - case 0x47: dis_show_op("sre",_zero); break; - case 0x48: dis_show_op("pha",_imp); break; - case 0x49: dis_show_op("eor",_imm); break; - case 0x4a: dis_show_op("lsr",_acc); break; - case 0x4b: dis_show_op("asr",_imm); break; - case 0x4c: dis_show_op("jmp",_abs); break; - case 0x4d: dis_show_op("eor",_abs); break; - case 0x4e: dis_show_op("lsr",_abs); break; - case 0x4f: dis_show_op("sre",_abs); break; - - case 0x50: dis_show_op("bvc",_rel); break; - case 0x51: dis_show_op("eor",_ind_y); break; - case 0x52: dis_show_op("jam",_imp); break; - case 0x53: dis_show_op("sre",_ind_y); break; - case 0x54: dis_show_op("nop",_zero_x); break; - case 0x55: dis_show_op("eor",_zero_x); break; - case 0x56: dis_show_op("lsr",_zero_x); break; - case 0x57: dis_show_op("sre",_zero_x); break; - case 0x58: dis_show_op("cli",_imp); break; - case 0x59: dis_show_op("eor",_abs_y); break; - case 0x5a: dis_show_op("nop",_imp); break; - case 0x5b: dis_show_op("sre",_abs_y); break; - case 0x5c: dis_show_op("nop",_abs_x); break; - case 0x5d: dis_show_op("eor",_abs_x); break; - case 0x5e: dis_show_op("lsr",_abs_x); break; - case 0x5f: dis_show_op("sre",_abs_x); break; - - case 0x60: dis_show_op("rts",_imp); break; - case 0x61: dis_show_op("adc",_ind_x); break; - case 0x62: dis_show_op("jam",_imp); break; - case 0x63: dis_show_op("rra",_ind_x); break; - case 0x64: dis_show_op("nop",_zero); break; - case 0x65: dis_show_op("adc",_zero); break; - case 0x66: dis_show_op("ror",_zero); break; - case 0x67: dis_show_op("rra",_zero); break; - case 0x68: dis_show_op("pla",_imp); break; - case 0x69: dis_show_op("adc",_imm); break; - case 0x6a: dis_show_op("ror",_acc); break; - case 0x6b: dis_show_op("arr",_imm); break; - case 0x6c: dis_show_op("jmp",_ind); break; - case 0x6d: dis_show_op("adc",_abs); break; - case 0x6e: dis_show_op("ror",_abs); break; - case 0x6f: dis_show_op("rra",_abs); break; - - case 0x70: dis_show_op("bvs",_rel); break; - case 0x71: dis_show_op("adc",_ind_y); break; - case 0x72: dis_show_op("jam",_imp); break; - case 0x73: dis_show_op("rra",_ind_y); break; - case 0x74: dis_show_op("nop",_zero_x); break; - case 0x75: dis_show_op("adc",_zero_x); break; - case 0x76: dis_show_op("ror",_zero_x); break; - case 0x77: dis_show_op("rra",_zero_x); break; - case 0x78: dis_show_op("sei",_imp); break; - case 0x79: dis_show_op("adc",_abs_y); break; - case 0x7a: dis_show_op("nop",_imp); break; - case 0x7b: dis_show_op("rra",_abs_y); break; - case 0x7c: dis_show_op("nop",_abs_x); break; - case 0x7d: dis_show_op("adc",_abs_x); break; - case 0x7e: dis_show_op("ror",_abs_x); break; - case 0x7f: dis_show_op("rra",_abs_x); break; - - case 0x80: dis_show_op("nop",_imm); break; - case 0x81: dis_show_op("sta",_ind_x); break; - case 0x82: dis_show_op("nop",_imm); break; - case 0x83: dis_show_op("sax",_ind_x); break; - case 0x84: dis_show_op("sty",_zero); break; - case 0x85: dis_show_op("sta",_zero); break; - case 0x86: dis_show_op("stx",_zero); break; - case 0x87: dis_show_op("sax",_zero); break; - case 0x88: dis_show_op("dey",_imp); break; - case 0x89: dis_show_op("nop",_imm); break; - case 0x8a: dis_show_op("txa",_imp); break; - case 0x8b: dis_show_op("ane",_imm); break; - case 0x8c: dis_show_op("sty",_abs); break; - case 0x8d: dis_show_op("sta",_abs); break; - case 0x8e: dis_show_op("stx",_abs); break; - case 0x8f: dis_show_op("sax",_abs); break; - - case 0x90: dis_show_op("bcc",_rel); break; - case 0x91: dis_show_op("sta",_ind_y); break; - case 0x92: dis_show_op("jam",_imp); break; - case 0x93: dis_show_op("sha",_ind_y); break; - case 0x94: dis_show_op("sty",_zero_x); break; - case 0x95: dis_show_op("sta",_zero_x); break; - case 0x96: dis_show_op("stx",_zero_y); break; - case 0x97: dis_show_op("sax",_zero_y); break; - case 0x98: dis_show_op("tya",_imp); break; - case 0x99: dis_show_op("sta",_abs_y); break; - case 0x9a: dis_show_op("txs",_imp); break; - case 0x9b: dis_show_op("shs",_abs_y); break; - case 0x9c: dis_show_op("shy",_abs_x); break; - case 0x9d: dis_show_op("sta",_abs_x); break; - case 0x9e: dis_show_op("shx",_abs_y); break; - case 0x9f: dis_show_op("sha",_abs_y); break; - - case 0xa0: dis_show_op("ldy",_imm); break; - case 0xa1: dis_show_op("lda",_ind_x); break; - case 0xa2: dis_show_op("ldx",_imm); break; - case 0xa3: dis_show_op("lax",_ind_x); break; - case 0xa4: dis_show_op("ldy",_zero); break; - case 0xa5: dis_show_op("lda",_zero); break; - case 0xa6: dis_show_op("ldx",_zero); break; - case 0xa7: dis_show_op("lax",_zero); break; - case 0xa8: dis_show_op("tay",_imp); break; - case 0xa9: dis_show_op("lda",_imm); break; - case 0xaa: dis_show_op("tax",_imp); break; - case 0xab: dis_show_op("lxa",_imm); break; - case 0xac: dis_show_op("ldy",_abs); break; - case 0xad: dis_show_op("lda",_abs); break; - case 0xae: dis_show_op("ldx",_abs); break; - case 0xaf: dis_show_op("lax",_abs); break; - - case 0xb0: dis_show_op("bcs",_rel); break; - case 0xb1: dis_show_op("lda",_ind_y); break; - case 0xb2: dis_show_op("jam",_imp); break; - case 0xb3: dis_show_op("lax",_ind_y); break; - case 0xb4: dis_show_op("ldy",_zero_x); break; - case 0xb5: dis_show_op("lda",_zero_x); break; - case 0xb6: dis_show_op("ldx",_zero_y); break; - case 0xb7: dis_show_op("lax",_zero_y); break; - case 0xb8: dis_show_op("clv",_imp); break; - case 0xb9: dis_show_op("lda",_abs_y); break; - case 0xba: dis_show_op("tsx",_imp); break; - case 0xbb: dis_show_op("las",_abs_y); break; - case 0xbc: dis_show_op("ldy",_abs_x); break; - case 0xbd: dis_show_op("lda",_abs_x); break; - case 0xbe: dis_show_op("ldx",_abs_y); break; - case 0xbf: dis_show_op("lax",_abs_y); break; - - case 0xc0: dis_show_op("cpy",_imm); break; - case 0xc1: dis_show_op("cmp",_ind_x); break; - case 0xc2: dis_show_op("nop",_imm); break; - case 0xc3: dis_show_op("dcp",_ind_x); break; - case 0xc4: dis_show_op("cpy",_zero); break; - case 0xc5: dis_show_op("cmp",_zero); break; - case 0xc6: dis_show_op("dec",_zero); break; - case 0xc7: dis_show_op("dcp",_zero); break; - case 0xc8: dis_show_op("iny",_imp); break; - case 0xc9: dis_show_op("cmp",_imm); break; - case 0xca: dis_show_op("dex",_imp); break; - case 0xcb: dis_show_op("sbx",_imm); break; - case 0xcc: dis_show_op("cpy",_abs); break; - case 0xcd: dis_show_op("cmp",_abs); break; - case 0xce: dis_show_op("dec",_abs); break; - case 0xcf: dis_show_op("dcp",_abs); break; - - case 0xd0: dis_show_op("bne",_rel); break; - case 0xd1: dis_show_op("cmp",_ind_y); break; - case 0xd2: dis_show_op("jam",_imp); break; - case 0xd3: dis_show_op("dcp",_ind_y); break; - case 0xd4: dis_show_op("nop",_zero_x); break; - case 0xd5: dis_show_op("cmp",_zero_x); break; - case 0xd6: dis_show_op("dec",_zero_x); break; - case 0xd7: dis_show_op("dcp",_zero_x); break; - case 0xd8: dis_show_op("cld",_imp); break; - case 0xd9: dis_show_op("cmp",_abs_y); break; - case 0xda: dis_show_op("nop",_imp); break; - case 0xdb: dis_show_op("dcp",_abs_y); break; - case 0xdc: dis_show_op("nop",_abs_x); break; - case 0xdd: dis_show_op("cmp",_abs_x); break; - case 0xde: dis_show_op("dec",_abs_x); break; - case 0xdf: dis_show_op("dcp",_abs_x); break; - - case 0xe0: dis_show_op("cpx",_imm); break; - case 0xe1: dis_show_op("sbc",_ind_x); break; - case 0xe2: dis_show_op("nop",_imm); break; - case 0xe3: dis_show_op("isb",_ind_x); break; - case 0xe4: dis_show_op("cpx",_zero); break; - case 0xe5: dis_show_op("sbc",_zero); break; - case 0xe6: dis_show_op("inc",_zero); break; - case 0xe7: dis_show_op("isb",_zero); break; - case 0xe8: dis_show_op("inx",_imp); break; - case 0xe9: dis_show_op("sbc",_imm); break; - case 0xea: dis_show_op("nop",_imp); break; - case 0xeb: dis_show_op("sbc",_imm); break; - case 0xec: dis_show_op("cpx",_abs); break; - case 0xed: dis_show_op("sbc",_abs); break; - case 0xee: dis_show_op("inc",_abs); break; - case 0xef: dis_show_op("isb",_abs); break; - - case 0xf0: dis_show_op("beq",_rel); break; - case 0xf1: dis_show_op("sbc",_ind_y); break; - case 0xf2: dis_show_op("jam",_imp); break; - case 0xf3: dis_show_op("isb",_ind_y); break; - case 0xf4: dis_show_op("nop",_zero_x); break; - case 0xf5: dis_show_op("sbc",_zero_x); break; - case 0xf6: dis_show_op("inc",_zero_x); break; - case 0xf7: dis_show_op("isb",_zero_x); break; - case 0xf8: dis_show_op("sed",_imp); break; - case 0xf9: dis_show_op("sbc",_abs_y); break; - case 0xfa: dis_show_op("nop",_imp); break; - case 0xfb: dis_show_op("isb",_abs_y); break; - case 0xfc: dis_show_op("nop",_abs_x); break; - case 0xfd: dis_show_op("sbc",_abs_x); break; - case 0xfe: dis_show_op("inc",_abs_x); break; - case 0xff: dis_show_op("isb",_abs_x); break; - } - - log_printf("%c%c1%c%c%c%c%c %02X %02X %02X %02X\n", - (P & N_FLAG) ? 'N' : 'n', - (P & V_FLAG) ? 'V' : 'v', - (P & V_FLAG) ? 'B' : 'b', - (P & V_FLAG) ? 'D' : 'd', - (P & V_FLAG) ? 'I' : 'i', - (P & V_FLAG) ? 'Z' : 'z', - (P & V_FLAG) ? 'C' : 'c', - A, X, Y, S); -} - -#endif /* NES6502_DEBUG */ - -/* -** $Log: dis6502.c,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources -** -** Revision 1.4 2000/06/09 15:12:25 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/dis6502.h b/src/libxineadec/nosefart/dis6502.h deleted file mode 100644 index a02fd73ae..000000000 --- a/src/libxineadec/nosefart/dis6502.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** dis6502.h -** -** 6502 disassembler header -** $Id: dis6502.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ -*/ - -#ifndef _DIS6502_H_ -#define _DIS6502_H_ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -extern void nes6502_disasm(uint32 PC, uint8 P, uint8 A, uint8 X, uint8 Y, uint8 S); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* !_DIS6502_H_ */ - -/* -** $Log: dis6502.h,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources -** -** Revision 1.4 2000/06/09 15:12:25 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/fds_snd.c b/src/libxineadec/nosefart/fds_snd.c deleted file mode 100644 index fe2e4d624..000000000 --- a/src/libxineadec/nosefart/fds_snd.c +++ /dev/null @@ -1,94 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** fds_snd.c -** -** Famicom Disk System sound emulation -** $Id: fds_snd.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ -*/ - -#include "types.h" -#include "nes_apu.h" -#include "fds_snd.h" - -static int32 fds_incsize = 0; - -/* mix sound channels together */ -static int32 fds_process(void) -{ - int32 output; - output = 0; - - return output; -} - -/* write to registers */ -static void fds_write(uint32 address, uint8 value) -{ -} - -/* reset state of vrcvi sound channels */ -static void fds_reset(void) -{ - fds_incsize = apu_getcyclerate(); -} - -static void fds_init(void) -{ -} - -/* TODO: bleh */ -static void fds_shutdown(void) -{ -} - -static apu_memwrite fds_memwrite[] = -{ - { 0x4040, 0x4092, fds_write }, - { -1, -1, NULL } -}; - -apuext_t fds_ext = -{ - fds_init, - fds_shutdown, - fds_reset, - fds_process, - NULL, /* no reads */ - fds_memwrite -}; - -/* -** $Log: fds_snd.c,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources -** -** Revision 1.3 2000/07/03 02:18:53 matt -** much better external module exporting -** -** Revision 1.2 2000/06/20 04:06:16 matt -** migrated external sound definition to apu module -** -** Revision 1.1 2000/06/20 00:06:47 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/fds_snd.h b/src/libxineadec/nosefart/fds_snd.h deleted file mode 100644 index 9d20b5b2a..000000000 --- a/src/libxineadec/nosefart/fds_snd.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** fds_snd.h -** -** Famicom Disk System sound emulation -** $Id: fds_snd.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ -*/ - -#ifndef _FDS_SND_H_ -#define _FDS_SND_H_ - -#include "nes_apu.h" - -extern apuext_t fds_ext; - - -#endif /* _VRCVISND_H_ */ - -/* -** $Log: fds_snd.h,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources -** -** Revision 1.2 2000/06/20 04:06:16 matt -** migrated external sound definition to apu module -** -** Revision 1.1 2000/06/20 00:06:47 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/fmopl.c b/src/libxineadec/nosefart/fmopl.c deleted file mode 100644 index 29c884096..000000000 --- a/src/libxineadec/nosefart/fmopl.c +++ /dev/null @@ -1,1323 +0,0 @@ -/* -** -** File: fmopl.c -- software implementation of FM sound generator -** -** Copyright (C) 1999 Tatsuyuki Satoh , MultiArcadeMachineEmurator development -** -** Version 0.36f -** -*/ - -/* - preliminary : - Problem : - note: -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <math.h> -//#include "driver.h" /* use M.A.M.E. */ -#include "fmopl.h" - -/* MPC - hacks */ -#include "types.h" -#include "log.h" - -#ifndef PI -#define PI 3.14159265358979323846 -#endif - -/* -------------------- preliminary define section --------------------- */ -/* attack/decay rate time rate */ -#define OPL_ARRATE 141280 /* RATE 4 = 2826.24ms @ 3.6MHz */ -#define OPL_DRRATE 1956000 /* RATE 4 = 39280.64ms @ 3.6MHz */ - -#define DELTAT_MIXING_LEVEL (1) /* DELTA-T ADPCM MIXING LEVEL */ - -#define FREQ_BITS 24 /* frequency turn */ - -/* counter bits = 20 , octerve 7 */ -#define FREQ_RATE (1<<(FREQ_BITS-20)) -#define TL_BITS (FREQ_BITS+2) - -/* final output shift , limit minimum and maximum */ -#define OPL_OUTSB (TL_BITS+3-16) /* OPL output final shift 16bit */ -#define OPL_MAXOUT (0x7fff<<OPL_OUTSB) -#define OPL_MINOUT (-0x8000<<OPL_OUTSB) - -/* -------------------- quality selection --------------------- */ - -/* sinwave entries */ -/* used static memory = SIN_ENT * 4 (byte) */ -#define SIN_ENT 2048 - -/* output level entries (envelope,sinwave) */ -/* envelope counter lower bits */ -#define ENV_BITS 16 -/* envelope output entries */ -#define EG_ENT 4096 -/* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */ -/* used static memory = EG_ENT*4 (byte) */ - -#define EG_OFF ((2*EG_ENT)<<ENV_BITS) /* OFF */ -#define EG_DED EG_OFF -#define EG_DST (EG_ENT<<ENV_BITS) /* DECAY START */ -#define EG_AED EG_DST -#define EG_AST 0 /* ATTACK START */ - -#define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step */ - -/* LFO table entries */ -#define VIB_ENT 512 -#define VIB_SHIFT (32-9) -#define AMS_ENT 512 -#define AMS_SHIFT (32-9) - -#define VIB_RATE 256 - -/* -------------------- local defines , macros --------------------- */ - -/* register number to channel number , slot offset */ -#define SLOT1 0 -#define SLOT2 1 - -/* envelope phase */ -#define ENV_MOD_RR 0x00 -#define ENV_MOD_DR 0x01 -#define ENV_MOD_AR 0x02 - -/* -------------------- tables --------------------- */ -static const int slot_array[32]= -{ - 0, 2, 4, 1, 3, 5,-1,-1, - 6, 8,10, 7, 9,11,-1,-1, - 12,14,16,13,15,17,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1 -}; - -/* key scale level */ -#define ML(x) ((UINT32)((x)*0.1875*2/EG_STEP)) -static const UINT32 KSL_TABLE[8*16]= -{ - /* OCT 0 */ - ML(0.000), ML(0.000), ML(0.000), ML(0.000), - ML(0.000), ML(0.000), ML(0.000), ML(0.000), - ML(0.000), ML(0.000), ML(0.000), ML(0.000), - ML(0.000), ML(0.000), ML(0.000), ML(0.000), - /* OCT 1 */ - ML(0.000), ML(0.000), ML(0.000), ML(0.000), - ML(0.000), ML(0.000), ML(0.000), ML(0.000), - ML(0.000), ML(0.750), ML(1.125), ML(1.500), - ML(1.875), ML(2.250), ML(2.625), ML(3.000), - /* OCT 2 */ - ML(0.000), ML(0.000), ML(0.000), ML(0.000), - ML(0.000), ML(1.125), ML(1.875), ML(2.625), - ML(3.000), ML(3.750), ML(4.125), ML(4.500), - ML(4.875), ML(5.250), ML(5.625), ML(6.000), - /* OCT 3 */ - ML(0.000), ML(0.000), ML(0.000), ML(1.875), - ML(3.000), ML(4.125), ML(4.875), ML(5.625), - ML(6.000), ML(6.750), ML(7.125), ML(7.500), - ML(7.875), ML(8.250), ML(8.625), ML(9.000), - /* OCT 4 */ - ML(0.000), ML(0.000), ML(3.000), ML(4.875), - ML(6.000), ML(7.125), ML(7.875), ML(8.625), - ML(9.000), ML(9.750),ML(10.125),ML(10.500), - ML(10.875),ML(11.250),ML(11.625),ML(12.000), - /* OCT 5 */ - ML(0.000), ML(3.000), ML(6.000), ML(7.875), - ML(9.000),ML(10.125),ML(10.875),ML(11.625), - ML(12.000),ML(12.750),ML(13.125),ML(13.500), - ML(13.875),ML(14.250),ML(14.625),ML(15.000), - /* OCT 6 */ - ML(0.000), ML(6.000), ML(9.000),ML(10.875), - ML(12.000),ML(13.125),ML(13.875),ML(14.625), - ML(15.000),ML(15.750),ML(16.125),ML(16.500), - ML(16.875),ML(17.250),ML(17.625),ML(18.000), - /* OCT 7 */ - ML(0.000), ML(9.000),ML(12.000),ML(13.875), - ML(15.000),ML(16.125),ML(16.875),ML(17.625), - ML(18.000),ML(18.750),ML(19.125),ML(19.500), - ML(19.875),ML(20.250),ML(20.625),ML(21.000) -}; -#undef ML - -/* sustain lebel table (3db per step) */ -/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ -#define SC(db) ((INT32) (db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST) -static const INT32 SL_TABLE[16]={ - SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7), - SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31) -}; -#undef SC - -#define TL_MAX (EG_ENT*2) /* limit(tl + ksr + envelope) + sinwave */ -/* TotalLevel : 48 24 12 6 3 1.5 0.75 (dB) */ -/* TL_TABLE[ 0 to TL_MAX ] : plus section */ -/* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */ -static INT32 *TL_TABLE; - -/* pointers to TL_TABLE with sinwave output offset */ -static INT32 **SIN_TABLE; - -/* LFO table */ -static INT32 *AMS_TABLE; -static INT32 *VIB_TABLE; - -/* envelope output curve table */ -/* attack + decay + OFF */ -static INT32 ENV_CURVE[2*EG_ENT+1]; - -/* multiple table */ -#define ML(x) ((UINT32) (2*(x))) -static const UINT32 MUL_TABLE[16]= { -/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */ - ML(0.50), ML(1.00), ML(2.00), ML(3.00), ML(4.00), ML(5.00), ML(6.00), ML(7.00), - ML(8.00), ML(9.00),ML(10.00),ML(10.00),ML(12.00),ML(12.00),ML(15.00),ML(15.00) -}; -#undef ML - -/* dummy attack / decay rate ( when rate == 0 ) */ -static INT32 RATE_0[16]= -{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - -/* -------------------- static state --------------------- */ - -/* lock level of common table */ -static int num_lock = 0; - -/* work table */ -static void *cur_chip = NULL; /* current chip point */ -/* currenct chip state */ -/* static FMSAMPLE *bufL,*bufR; */ -static OPL_CH *S_CH; -static OPL_CH *E_CH; -OPL_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2; - -static INT32 outd[1]; -static INT32 ams; -static INT32 vib; -INT32 *ams_table; -INT32 *vib_table; -static INT32 amsIncr; -static INT32 vibIncr; -static INT32 feedback2; /* connect for SLOT 2 */ - -/* log output level */ -#define LOG_ERR 3 /* ERROR */ -#define LOG_WAR 2 /* WARNING */ -#define LOG_INF 1 /* INFORMATION */ - -#define LOG_LEVEL LOG_INF - -//#define LOG(n,x) if( (n)>=LOG_LEVEL ) logerror x -#define LOG(n,x) if( (n)>=LOG_LEVEL ) log_printf x - -/* --------------------- subroutines --------------------- */ - -INLINE int Limit( int val, int max, int min ) { - if ( val > max ) - val = max; - else if ( val < min ) - val = min; - - return val; -} - -/* status set and IRQ handling */ -INLINE void OPL_STATUS_SET(FM_OPL *OPL,int flag) -{ - /* set status flag */ - OPL->status |= flag; - if(!(OPL->status & 0x80)) - { - if(OPL->status & OPL->statusmask) - { /* IRQ on */ - OPL->status |= 0x80; - /* callback user interrupt handler (IRQ is OFF to ON) */ - if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1); - } - } -} - -/* status reset and IRQ handling */ -INLINE void OPL_STATUS_RESET(FM_OPL *OPL,int flag) -{ - /* reset status flag */ - OPL->status &=~flag; - if((OPL->status & 0x80)) - { - if (!(OPL->status & OPL->statusmask) ) - { - OPL->status &= 0x7f; - /* callback user interrupt handler (IRQ is ON to OFF) */ - if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0); - } - } -} - -/* IRQ mask set */ -INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag) -{ - OPL->statusmask = flag; - /* IRQ handling check */ - OPL_STATUS_SET(OPL,0); - OPL_STATUS_RESET(OPL,0); -} - -/* ----- key on ----- */ -INLINE void OPL_KEYON(OPL_SLOT *SLOT) -{ - /* sin wave restart */ - SLOT->Cnt = 0; - /* set attack */ - SLOT->evm = ENV_MOD_AR; - SLOT->evs = SLOT->evsa; - SLOT->evc = EG_AST; - SLOT->eve = EG_AED; -} -/* ----- key off ----- */ -INLINE void OPL_KEYOFF(OPL_SLOT *SLOT) -{ - if( SLOT->evm > ENV_MOD_RR) - { - /* set envelope counter from envleope output */ - SLOT->evm = ENV_MOD_RR; - if( !(SLOT->evc&EG_DST) ) - //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST; - SLOT->evc = EG_DST; - SLOT->eve = EG_DED; - SLOT->evs = SLOT->evsr; - } -} - -/* ---------- calcrate Envelope Generator & Phase Generator ---------- */ -/* return : envelope output */ -INLINE UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT ) -{ - /* calcrate envelope generator */ - if( (SLOT->evc+=SLOT->evs) >= SLOT->eve ) - { - switch( SLOT->evm ){ - case ENV_MOD_AR: /* ATTACK -> DECAY1 */ - /* next DR */ - SLOT->evm = ENV_MOD_DR; - SLOT->evc = EG_DST; - SLOT->eve = SLOT->SL; - SLOT->evs = SLOT->evsd; - break; - case ENV_MOD_DR: /* DECAY -> SL or RR */ - SLOT->evc = SLOT->SL; - SLOT->eve = EG_DED; - if(SLOT->eg_typ) - { - SLOT->evs = 0; - } - else - { - SLOT->evm = ENV_MOD_RR; - SLOT->evs = SLOT->evsr; - } - break; - case ENV_MOD_RR: /* RR -> OFF */ - SLOT->evc = EG_OFF; - SLOT->eve = EG_OFF+1; - SLOT->evs = 0; - break; - } - } - /* calcrate envelope */ - return SLOT->TLL+ENV_CURVE[SLOT->evc>>ENV_BITS]+(SLOT->ams ? ams : 0); -} - -/* set algorythm connection */ -static void set_algorythm( OPL_CH *CH) -{ - INT32 *carrier = &outd[0]; - CH->connect1 = CH->CON ? carrier : &feedback2; - CH->connect2 = carrier; -} - -/* ---------- frequency counter for operater update ---------- */ -INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT) -{ - int ksr; - - /* frequency step counter */ - SLOT->Incr = CH->fc * SLOT->mul; - ksr = CH->kcode >> SLOT->KSR; - - if( SLOT->ksr != ksr ) - { - SLOT->ksr = ksr; - /* attack , decay rate recalcration */ - SLOT->evsa = SLOT->AR[ksr]; - SLOT->evsd = SLOT->DR[ksr]; - SLOT->evsr = SLOT->RR[ksr]; - } - SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); -} - -/* set multi,am,vib,EG-TYP,KSR,mul */ -INLINE void set_mul(FM_OPL *OPL,int slot,int v) -{ - OPL_CH *CH = &OPL->P_CH[slot/2]; - OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - - SLOT->mul = MUL_TABLE[v&0x0f]; - SLOT->KSR = (v&0x10) ? 0 : 2; - SLOT->eg_typ = (v&0x20)>>5; - SLOT->vib = (v&0x40); - SLOT->ams = (v&0x80); - CALC_FCSLOT(CH,SLOT); -} - -/* set ksl & tl */ -INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v) -{ - OPL_CH *CH = &OPL->P_CH[slot/2]; - OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - int ksl = v>>6; /* 0 / 1.5 / 3 / 6 db/OCT */ - - SLOT->ksl = ksl ? 3-ksl : 31; - SLOT->TL = (INT32) (((v&0x3f)*(0.75/EG_STEP))); /* 0.75db step */ - - if( !(OPL->mode&0x80) ) - { /* not CSM latch total level */ - SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); - } -} - -/* set attack rate & decay rate */ -INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v) -{ - OPL_CH *CH = &OPL->P_CH[slot/2]; - OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - int ar = v>>4; - int dr = v&0x0f; - - SLOT->AR = ar ? &OPL->AR_TABLE[ar<<2] : RATE_0; - SLOT->evsa = SLOT->AR[SLOT->ksr]; - if( SLOT->evm == ENV_MOD_AR ) SLOT->evs = SLOT->evsa; - - SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0; - SLOT->evsd = SLOT->DR[SLOT->ksr]; - if( SLOT->evm == ENV_MOD_DR ) SLOT->evs = SLOT->evsd; -} - -/* set sustain level & release rate */ -INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v) -{ - OPL_CH *CH = &OPL->P_CH[slot/2]; - OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - int sl = v>>4; - int rr = v & 0x0f; - - SLOT->SL = SL_TABLE[sl]; - if( SLOT->evm == ENV_MOD_DR ) SLOT->eve = SLOT->SL; - SLOT->RR = &OPL->DR_TABLE[rr<<2]; - SLOT->evsr = SLOT->RR[SLOT->ksr]; - if( SLOT->evm == ENV_MOD_RR ) SLOT->evs = SLOT->evsr; -} - -/* operator output calcrator */ -#define OP_OUT(slot,env,con) slot->wavetable[((slot->Cnt+con)/(0x1000000/SIN_ENT))&(SIN_ENT-1)][env] -/* ---------- calcrate one of channel ---------- */ -INLINE void OPL_CALC_CH( OPL_CH *CH ) -{ - UINT32 env_out; - OPL_SLOT *SLOT; - - feedback2 = 0; - /* SLOT 1 */ - SLOT = &CH->SLOT[SLOT1]; - env_out=OPL_CALC_SLOT(SLOT); - if( env_out < EG_ENT-1 ) - { - /* PG */ - if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); - else SLOT->Cnt += SLOT->Incr; - /* connectoion */ - if(CH->FB) - { - int feedback1 = (CH->op1_out[0]+CH->op1_out[1])>>CH->FB; - CH->op1_out[1] = CH->op1_out[0]; - *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT,env_out,feedback1); - } - else - { - *CH->connect1 += OP_OUT(SLOT,env_out,0); - } - }else - { - CH->op1_out[1] = CH->op1_out[0]; - CH->op1_out[0] = 0; - } - /* SLOT 2 */ - SLOT = &CH->SLOT[SLOT2]; - env_out=OPL_CALC_SLOT(SLOT); - if( env_out < EG_ENT-1 ) - { - /* PG */ - if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); - else SLOT->Cnt += SLOT->Incr; - /* connectoion */ - outd[0] += OP_OUT(SLOT,env_out, feedback2); - } -} - -/* ---------- calcrate rythm block ---------- */ -#define WHITE_NOISE_db 6.0 -INLINE void OPL_CALC_RH( OPL_CH *CH ) -{ - UINT32 env_tam,env_sd,env_top,env_hh; - int whitenoise = (rand()&1)*((int)(WHITE_NOISE_db/EG_STEP)); - INT32 tone8; - - OPL_SLOT *SLOT; - int env_out; - - /* BD : same as FM serial mode and output level is large */ - feedback2 = 0; - /* SLOT 1 */ - SLOT = &CH[6].SLOT[SLOT1]; - env_out=OPL_CALC_SLOT(SLOT); - if( env_out < EG_ENT-1 ) - { - /* PG */ - if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); - else SLOT->Cnt += SLOT->Incr; - /* connectoion */ - if(CH[6].FB) - { - int feedback1 = (CH[6].op1_out[0]+CH[6].op1_out[1])>>CH[6].FB; - CH[6].op1_out[1] = CH[6].op1_out[0]; - feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT,env_out,feedback1); - } - else - { - feedback2 = OP_OUT(SLOT,env_out,0); - } - }else - { - feedback2 = 0; - CH[6].op1_out[1] = CH[6].op1_out[0]; - CH[6].op1_out[0] = 0; - } - /* SLOT 2 */ - SLOT = &CH[6].SLOT[SLOT2]; - env_out=OPL_CALC_SLOT(SLOT); - if( env_out < EG_ENT-1 ) - { - /* PG */ - if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); - else SLOT->Cnt += SLOT->Incr; - /* connectoion */ - outd[0] += OP_OUT(SLOT,env_out, feedback2)*2; - } - - // SD (17) = mul14[fnum7] + white noise - // TAM (15) = mul15[fnum8] - // TOP (18) = fnum6(mul18[fnum8]+whitenoise) - // HH (14) = fnum7(mul18[fnum8]+whitenoise) + white noise - env_sd =OPL_CALC_SLOT(SLOT7_2) + whitenoise; - env_tam=OPL_CALC_SLOT(SLOT8_1); - env_top=OPL_CALC_SLOT(SLOT8_2); - env_hh =OPL_CALC_SLOT(SLOT7_1) + whitenoise; - - /* PG */ - if(SLOT7_1->vib) SLOT7_1->Cnt += (2*SLOT7_1->Incr*vib/VIB_RATE); - else SLOT7_1->Cnt += 2*SLOT7_1->Incr; - if(SLOT7_2->vib) SLOT7_2->Cnt += ((CH[7].fc*8)*vib/VIB_RATE); - else SLOT7_2->Cnt += (CH[7].fc*8); - if(SLOT8_1->vib) SLOT8_1->Cnt += (SLOT8_1->Incr*vib/VIB_RATE); - else SLOT8_1->Cnt += SLOT8_1->Incr; - if(SLOT8_2->vib) SLOT8_2->Cnt += ((CH[8].fc*48)*vib/VIB_RATE); - else SLOT8_2->Cnt += (CH[8].fc*48); - - tone8 = OP_OUT(SLOT8_2,whitenoise,0 ); - - /* SD */ - if( env_sd < EG_ENT-1 ) - outd[0] += OP_OUT(SLOT7_1,env_sd, 0)*8; - /* TAM */ - if( env_tam < EG_ENT-1 ) - outd[0] += OP_OUT(SLOT8_1,env_tam, 0)*2; - /* TOP-CY */ - if( env_top < EG_ENT-1 ) - outd[0] += OP_OUT(SLOT7_2,env_top,tone8)*2; - /* HH */ - if( env_hh < EG_ENT-1 ) - outd[0] += OP_OUT(SLOT7_2,env_hh,tone8)*2; -} - -/* ----------- initialize time tabls ----------- */ -static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE ) -{ - int i; - double rate; - - /* make attack rate & decay rate tables */ - for (i = 0;i < 4;i++) OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0; - for (i = 4;i <= 60;i++){ - rate = OPL->freqbase; /* frequency rate */ - if( i < 60 ) rate *= 1.0+(i&3)*0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */ - rate *= 1<<((i>>2)-1); /* b2-5 : shift bit */ - rate *= (double)(EG_ENT<<ENV_BITS); - OPL->AR_TABLE[i] = (INT32) (rate / ARRATE); - OPL->DR_TABLE[i] = (INT32) (rate / DRRATE); - } - for (i = 60;i < 76;i++) - { - OPL->AR_TABLE[i] = EG_AED-1; - OPL->DR_TABLE[i] = OPL->DR_TABLE[60]; - } -#if 0 - for (i = 0;i < 64 ;i++){ /* make for overflow area */ - LOG(LOG_WAR,("rate %2d , ar %f ms , dr %f ms \n",i, - ((double)(EG_ENT<<ENV_BITS) / OPL->AR_TABLE[i]) * (1000.0 / OPL->rate), - ((double)(EG_ENT<<ENV_BITS) / OPL->DR_TABLE[i]) * (1000.0 / OPL->rate) )); - } -#endif -} - -/* ---------- generic table initialize ---------- */ -static int OPLOpenTable( void ) -{ - int s,t; - double rate; - int i,j; - double pom; - - /* allocate dynamic tables */ - if( (TL_TABLE = malloc(TL_MAX*2*sizeof(INT32))) == NULL) - return 0; - if( (SIN_TABLE = malloc(SIN_ENT*4 *sizeof(INT32 *))) == NULL) - { - free(TL_TABLE); - return 0; - } - if( (AMS_TABLE = malloc(AMS_ENT*2 *sizeof(INT32))) == NULL) - { - free(TL_TABLE); - free(SIN_TABLE); - return 0; - } - if( (VIB_TABLE = malloc(VIB_ENT*2 *sizeof(INT32))) == NULL) - { - free(TL_TABLE); - free(SIN_TABLE); - free(AMS_TABLE); - return 0; - } - /* make total level table */ - for (t = 0;t < EG_ENT-1 ;t++){ - rate = ((1<<TL_BITS)-1)/pow(10,EG_STEP*t/20); /* dB -> voltage */ - TL_TABLE[ t] = (int)rate; - TL_TABLE[TL_MAX+t] = -TL_TABLE[t]; -/* LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/ - } - /* fill volume off area */ - for ( t = EG_ENT-1; t < TL_MAX ;t++){ - TL_TABLE[t] = TL_TABLE[TL_MAX+t] = 0; - } - - /* make sinwave table (total level offet) */ - /* degree 0 = degree 180 = off */ - SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2] = &TL_TABLE[EG_ENT-1]; - for (s = 1;s <= SIN_ENT/4;s++){ - pom = sin(2*PI*s/SIN_ENT); /* sin */ - pom = 20*log10(1/pom); /* decibel */ - j = (int) (pom / EG_STEP); /* TL_TABLE steps */ - - /* degree 0 - 90 , degree 180 - 90 : plus section */ - SIN_TABLE[ s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j]; - /* degree 180 - 270 , degree 360 - 270 : minus section */ - SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT -s] = &TL_TABLE[TL_MAX+j]; -/* LOG(LOG_INF,("sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP));*/ - } - for (s = 0;s < SIN_ENT;s++) - { - SIN_TABLE[SIN_ENT*1+s] = s<(SIN_ENT/2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT]; - SIN_TABLE[SIN_ENT*2+s] = SIN_TABLE[s % (SIN_ENT/2)]; - SIN_TABLE[SIN_ENT*3+s] = (s/(SIN_ENT/4))&1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT*2+s]; - } - - /* envelope counter -> envelope output table */ - for (i=0; i<EG_ENT; i++) - { - /* ATTACK curve */ - pom = pow( ((double)(EG_ENT-1-i)/EG_ENT) , 8 ) * EG_ENT; - /* if( pom >= EG_ENT ) pom = EG_ENT-1; */ - ENV_CURVE[i] = (int)pom; - /* DECAY ,RELEASE curve */ - ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i; - } - /* off */ - ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1; - /* make LFO ams table */ - for (i=0; i<AMS_ENT; i++) - { - pom = (1.0+sin(2*PI*i/AMS_ENT))/2; /* sin */ - AMS_TABLE[i] = (INT32) ((1.0/EG_STEP)*pom); /* 1dB */ - AMS_TABLE[AMS_ENT+i] = (INT32) ((4.8/EG_STEP)*pom); /* 4.8dB */ - } - /* make LFO vibrate table */ - for (i=0; i<VIB_ENT; i++) - { - /* 100cent = 1seminote = 6% ?? */ - pom = (double)VIB_RATE*0.06*sin(2*PI*i/VIB_ENT); /* +-100sect step */ - VIB_TABLE[i] = VIB_RATE + (INT32) (pom*0.07); /* +- 7cent */ - VIB_TABLE[VIB_ENT+i] = VIB_RATE + (INT32) (pom*0.14); /* +-14cent */ - /* LOG(LOG_INF,("vib %d=%d\n",i,VIB_TABLE[VIB_ENT+i])); */ - } - return 1; -} - - -static void OPLCloseTable( void ) -{ - free(TL_TABLE); - free(SIN_TABLE); - free(AMS_TABLE); - free(VIB_TABLE); -} - -/* CSM Key Controll */ -INLINE void CSMKeyControll(OPL_CH *CH) -{ - OPL_SLOT *slot1 = &CH->SLOT[SLOT1]; - OPL_SLOT *slot2 = &CH->SLOT[SLOT2]; - /* all key off */ - OPL_KEYOFF(slot1); - OPL_KEYOFF(slot2); - /* total level latch */ - slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl); - slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl); - /* key on */ - CH->op1_out[0] = CH->op1_out[1] = 0; - OPL_KEYON(slot1); - OPL_KEYON(slot2); -} - -/* ---------- opl initialize ---------- */ -static void OPL_initalize(FM_OPL *OPL) -{ - int fn; - - /* frequency base */ - OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72 : 0; - /* Timer base time */ - OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 ); - /* make time tables */ - init_timetables( OPL , OPL_ARRATE , OPL_DRRATE ); - /* make fnumber -> increment counter table */ - for( fn=0 ; fn < 1024 ; fn++ ) - { - OPL->FN_TABLE[fn] = (UINT32) (OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2); - } - /* LFO freq.table */ - OPL->amsIncr = (INT32) (OPL->rate ? (double)AMS_ENT*(1<<AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0); - OPL->vibIncr = (INT32) (OPL->rate ? (double)VIB_ENT*(1<<VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0); -} - -/* ---------- write a OPL registers ---------- */ -static void OPLWriteReg(FM_OPL *OPL, int r, int v) -{ - OPL_CH *CH; - int slot; - unsigned int block_fnum; - - switch(r&0xe0) - { - case 0x00: /* 00-1f:controll */ - switch(r&0x1f) - { - case 0x01: - /* wave selector enable */ - if(OPL->type&OPL_TYPE_WAVESEL) - { - OPL->wavesel = v&0x20; - if(!OPL->wavesel) - { - /* preset compatible mode */ - int c; - for(c=0;c<OPL->max_ch;c++) - { - OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0]; - OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0]; - } - } - } - return; - case 0x02: /* Timer 1 */ - OPL->T[0] = (256-v)*4; - break; - case 0x03: /* Timer 2 */ - OPL->T[1] = (256-v)*16; - return; - case 0x04: /* IRQ clear / mask and Timer enable */ - if(v&0x80) - { /* IRQ flag clear */ - OPL_STATUS_RESET(OPL,0x7f); - } - else - { /* set IRQ mask ,timer enable*/ - UINT8 st1 = v&1; - UINT8 st2 = (v>>1)&1; - /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */ - OPL_STATUS_RESET(OPL,v&0x78); - OPL_STATUSMASK_SET(OPL,((~v)&0x78)|0x01); - /* timer 2 */ - if(OPL->st[1] != st2) - { - double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0; - OPL->st[1] = st2; - if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval); - } - /* timer 1 */ - if(OPL->st[0] != st1) - { - double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0; - OPL->st[0] = st1; - if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval); - } - } - return; -#if BUILD_Y8950 - case 0x06: /* Key Board OUT */ - if(OPL->type&OPL_TYPE_KEYBOARD) - { - if(OPL->keyboardhandler_w) - OPL->keyboardhandler_w(OPL->keyboard_param,v); - else - LOG(LOG_WAR,("OPL:write unmapped KEYBOARD port\n")); - } - return; - case 0x07: /* DELTA-T controll : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */ - if(OPL->type&OPL_TYPE_ADPCM) - YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); - return; - case 0x08: /* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */ - OPL->mode = v; - v&=0x1f; /* for DELTA-T unit */ - case 0x09: /* START ADD */ - case 0x0a: - case 0x0b: /* STOP ADD */ - case 0x0c: - case 0x0d: /* PRESCALE */ - case 0x0e: - case 0x0f: /* ADPCM data */ - case 0x10: /* DELTA-N */ - case 0x11: /* DELTA-N */ - case 0x12: /* EG-CTRL */ - if(OPL->type&OPL_TYPE_ADPCM) - YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); - return; -#if 0 - case 0x15: /* DAC data */ - case 0x16: - case 0x17: /* SHIFT */ - return; - case 0x18: /* I/O CTRL (Direction) */ - if(OPL->type&OPL_TYPE_IO) - OPL->portDirection = v&0x0f; - return; - case 0x19: /* I/O DATA */ - if(OPL->type&OPL_TYPE_IO) - { - OPL->portLatch = v; - if(OPL->porthandler_w) - OPL->porthandler_w(OPL->port_param,v&OPL->portDirection); - } - return; - case 0x1a: /* PCM data */ - return; -#endif -#endif - } - break; - case 0x20: /* am,vib,ksr,eg type,mul */ - slot = slot_array[r&0x1f]; - if(slot == -1) return; - set_mul(OPL,slot,v); - return; - case 0x40: - slot = slot_array[r&0x1f]; - if(slot == -1) return; - set_ksl_tl(OPL,slot,v); - return; - case 0x60: - slot = slot_array[r&0x1f]; - if(slot == -1) return; - set_ar_dr(OPL,slot,v); - return; - case 0x80: - slot = slot_array[r&0x1f]; - if(slot == -1) return; - set_sl_rr(OPL,slot,v); - return; - case 0xa0: - switch(r) - { - case 0xbd: - /* amsep,vibdep,r,bd,sd,tom,tc,hh */ - { - UINT8 rkey = OPL->rythm^v; - OPL->ams_table = &AMS_TABLE[v&0x80 ? AMS_ENT : 0]; - OPL->vib_table = &VIB_TABLE[v&0x40 ? VIB_ENT : 0]; - OPL->rythm = v&0x3f; - if(OPL->rythm&0x20) - { -#if 0 - usrintf_showmessage("OPL Rythm mode select"); -#endif - /* BD key on/off */ - if(rkey&0x10) - { - if(v&0x10) - { - OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0; - OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]); - OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]); - } - else - { - OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]); - OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]); - } - } - /* SD key on/off */ - if(rkey&0x08) - { - if(v&0x08) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]); - else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]); - }/* TAM key on/off */ - if(rkey&0x04) - { - if(v&0x04) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]); - else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]); - } - /* TOP-CY key on/off */ - if(rkey&0x02) - { - if(v&0x02) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]); - else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]); - } - /* HH key on/off */ - if(rkey&0x01) - { - if(v&0x01) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]); - else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]); - } - } - } - return; - } - /* keyon,block,fnum */ - if( (r&0x0f) > 8) return; - CH = &OPL->P_CH[r&0x0f]; - if(!(r&0x10)) - { /* a0-a8 */ - block_fnum = (CH->block_fnum&0x1f00) | v; - } - else - { /* b0-b8 */ - int keyon = (v>>5)&1; - block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff); - if(CH->keyon != keyon) - { - if( (CH->keyon=keyon) ) - { - CH->op1_out[0] = CH->op1_out[1] = 0; - OPL_KEYON(&CH->SLOT[SLOT1]); - OPL_KEYON(&CH->SLOT[SLOT2]); - } - else - { - OPL_KEYOFF(&CH->SLOT[SLOT1]); - OPL_KEYOFF(&CH->SLOT[SLOT2]); - } - } - } - /* update */ - if(CH->block_fnum != block_fnum) - { - int blockRv = 7-(block_fnum>>10); - int fnum = block_fnum&0x3ff; - CH->block_fnum = block_fnum; - - CH->ksl_base = KSL_TABLE[block_fnum>>6]; - CH->fc = OPL->FN_TABLE[fnum]>>blockRv; - CH->kcode = CH->block_fnum>>9; - if( (OPL->mode&0x40) && CH->block_fnum&0x100) CH->kcode |=1; - CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); - CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); - } - return; - case 0xc0: - /* FB,C */ - if( (r&0x0f) > 8) return; - CH = &OPL->P_CH[r&0x0f]; - { - int feedback = (v>>1)&7; - CH->FB = feedback ? (8+1) - feedback : 0; - CH->CON = v&1; - set_algorythm(CH); - } - return; - case 0xe0: /* wave type */ - slot = slot_array[r&0x1f]; - if(slot == -1) return; - CH = &OPL->P_CH[slot/2]; - if(OPL->wavesel) - { - /* LOG(LOG_INF,("OPL SLOT %d wave select %d\n",slot,v&3)); */ - CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v&0x03)*SIN_ENT]; - } - return; - } -} - -/* lock/unlock for common table */ -static int OPL_LockTable(void) -{ - num_lock++; - if(num_lock>1) return 0; - /* first time */ - cur_chip = NULL; - /* allocate total level table (128kb space) */ - if( !OPLOpenTable() ) - { - num_lock--; - return -1; - } - return 0; -} - -static void OPL_UnLockTable(void) -{ - if(num_lock) num_lock--; - if(num_lock) return; - /* last time */ - cur_chip = NULL; - OPLCloseTable(); -} - -#if (BUILD_YM3812 || BUILD_YM3526) -/*******************************************************************************/ -/* YM3812 local section */ -/*******************************************************************************/ - -/* ---------- update one of chip ----------- */ -void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length) -{ - int i; - int data; - FMSAMPLE *buf = buffer; - UINT32 amsCnt = OPL->amsCnt; - UINT32 vibCnt = OPL->vibCnt; - UINT8 rythm = OPL->rythm&0x20; - OPL_CH *CH,*R_CH; - - if( (void *)OPL != cur_chip ){ - cur_chip = (void *)OPL; - /* channel pointers */ - S_CH = OPL->P_CH; - E_CH = &S_CH[9]; - /* rythm slot */ - SLOT7_1 = &S_CH[7].SLOT[SLOT1]; - SLOT7_2 = &S_CH[7].SLOT[SLOT2]; - SLOT8_1 = &S_CH[8].SLOT[SLOT1]; - SLOT8_2 = &S_CH[8].SLOT[SLOT2]; - /* LFO state */ - amsIncr = OPL->amsIncr; - vibIncr = OPL->vibIncr; - ams_table = OPL->ams_table; - vib_table = OPL->vib_table; - } - R_CH = rythm ? &S_CH[6] : E_CH; - for( i=0; i < length ; i++ ) - { - /* channel A channel B channel C */ - /* LFO */ - ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT]; - vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT]; - outd[0] = 0; - /* FM part */ - for(CH=S_CH ; CH < R_CH ; CH++) - OPL_CALC_CH(CH); - /* Rythn part */ - if(rythm) - OPL_CALC_RH(S_CH); - /* limit check */ - data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT ); - /* store to sound buffer */ - buf[i] = data >> OPL_OUTSB; - } - - OPL->amsCnt = amsCnt; - OPL->vibCnt = vibCnt; -} -#endif /* (BUILD_YM3812 || BUILD_YM3526) */ - -#if BUILD_Y8950 - -void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length) -{ - int i; - int data; - FMSAMPLE *buf = buffer; - UINT32 amsCnt = OPL->amsCnt; - UINT32 vibCnt = OPL->vibCnt; - UINT8 rythm = OPL->rythm&0x20; - OPL_CH *CH,*R_CH; - YM_DELTAT *DELTAT = OPL->deltat; - - /* setup DELTA-T unit */ - YM_DELTAT_DECODE_PRESET(DELTAT); - - if( (void *)OPL != cur_chip ){ - cur_chip = (void *)OPL; - /* channel pointers */ - S_CH = OPL->P_CH; - E_CH = &S_CH[9]; - /* rythm slot */ - SLOT7_1 = &S_CH[7].SLOT[SLOT1]; - SLOT7_2 = &S_CH[7].SLOT[SLOT2]; - SLOT8_1 = &S_CH[8].SLOT[SLOT1]; - SLOT8_2 = &S_CH[8].SLOT[SLOT2]; - /* LFO state */ - amsIncr = OPL->amsIncr; - vibIncr = OPL->vibIncr; - ams_table = OPL->ams_table; - vib_table = OPL->vib_table; - } - R_CH = rythm ? &S_CH[6] : E_CH; - for( i=0; i < length ; i++ ) - { - /* channel A channel B channel C */ - /* LFO */ - ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT]; - vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT]; - outd[0] = 0; - /* deltaT ADPCM */ - if( DELTAT->flag ) - YM_DELTAT_ADPCM_CALC(DELTAT); - /* FM part */ - for(CH=S_CH ; CH < R_CH ; CH++) - OPL_CALC_CH(CH); - /* Rythn part */ - if(rythm) - OPL_CALC_RH(S_CH); - /* limit check */ - data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT ); - /* store to sound buffer */ - buf[i] = data >> OPL_OUTSB; - } - OPL->amsCnt = amsCnt; - OPL->vibCnt = vibCnt; - /* deltaT START flag */ - if( !DELTAT->flag ) - OPL->status &= 0xfe; -} -#endif - -/* ---------- reset one of chip ---------- */ -void OPLResetChip(FM_OPL *OPL) -{ - int c,s; - int i; - - /* reset chip */ - OPL->mode = 0; /* normal mode */ - OPL_STATUS_RESET(OPL,0x7f); - /* reset with register write */ - OPLWriteReg(OPL,0x01,0); /* wabesel disable */ - OPLWriteReg(OPL,0x02,0); /* Timer1 */ - OPLWriteReg(OPL,0x03,0); /* Timer2 */ - OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */ - for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0); - /* reset OPerator paramater */ - for( c = 0 ; c < OPL->max_ch ; c++ ) - { - OPL_CH *CH = &OPL->P_CH[c]; - /* OPL->P_CH[c].PAN = OPN_CENTER; */ - for(s = 0 ; s < 2 ; s++ ) - { - /* wave table */ - CH->SLOT[s].wavetable = &SIN_TABLE[0]; - /* CH->SLOT[s].evm = ENV_MOD_RR; */ - CH->SLOT[s].evc = EG_OFF; - CH->SLOT[s].eve = EG_OFF+1; - CH->SLOT[s].evs = 0; - } - } -#if BUILD_Y8950 - if(OPL->type&OPL_TYPE_ADPCM) - { - YM_DELTAT *DELTAT = OPL->deltat; - - DELTAT->freqbase = OPL->freqbase; - DELTAT->output_pointer = outd; - DELTAT->portshift = 5; - DELTAT->output_range = DELTAT_MIXING_LEVEL<<TL_BITS; - YM_DELTAT_ADPCM_Reset(DELTAT,0); - } -#endif -} - -/* ---------- Create one of vietual YM3812 ---------- */ -/* 'rate' is sampling rate and 'bufsiz' is the size of the */ -FM_OPL *OPLCreate(int type, int clock, int rate) -{ - char *ptr; - FM_OPL *OPL; - int state_size; - int max_ch = 9; /* normaly 9 channels */ - - if( OPL_LockTable() ==-1) return NULL; - /* allocate OPL state space */ - state_size = sizeof(FM_OPL); - state_size += sizeof(OPL_CH)*max_ch; -#if BUILD_Y8950 - if(type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT); -#endif - /* allocate memory block */ - ptr = malloc(state_size); - if(ptr==NULL) return NULL; - /* clear */ - memset(ptr,0,state_size); - OPL = (FM_OPL *)ptr; ptr+=sizeof(FM_OPL); - OPL->P_CH = (OPL_CH *)ptr; ptr+=sizeof(OPL_CH)*max_ch; -#if BUILD_Y8950 - if(type&OPL_TYPE_ADPCM) OPL->deltat = (YM_DELTAT *)ptr; ptr+=sizeof(YM_DELTAT); -#endif - /* set channel state pointer */ - OPL->type = type; - OPL->clock = clock; - OPL->rate = rate; - OPL->max_ch = max_ch; - /* init grobal tables */ - OPL_initalize(OPL); - /* reset chip */ - OPLResetChip(OPL); - return OPL; -} - -/* ---------- Destroy one of vietual YM3812 ---------- */ -void OPLDestroy(FM_OPL *OPL) -{ - OPL_UnLockTable(); - free(OPL); -} - -/* ---------- Option handlers ---------- */ - -void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset) -{ - OPL->TimerHandler = TimerHandler; - OPL->TimerParam = channelOffset; -} -void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param) -{ - OPL->IRQHandler = IRQHandler; - OPL->IRQParam = param; -} -void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param) -{ - OPL->UpdateHandler = UpdateHandler; - OPL->UpdateParam = param; -} -#if BUILD_Y8950 -void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param) -{ - OPL->porthandler_w = PortHandler_w; - OPL->porthandler_r = PortHandler_r; - OPL->port_param = param; -} - -void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param) -{ - OPL->keyboardhandler_w = KeyboardHandler_w; - OPL->keyboardhandler_r = KeyboardHandler_r; - OPL->keyboard_param = param; -} -#endif -/* ---------- YM3812 I/O interface ---------- */ -int OPLWrite(FM_OPL *OPL,int a,int v) -{ - if( !(a&1) ) - { /* address port */ - OPL->address = v & 0xff; - } - else - { /* data port */ - if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); - OPLWriteReg(OPL,OPL->address,v); - } - return OPL->status>>7; -} - -unsigned char OPLRead(FM_OPL *OPL,int a) -{ - if( !(a&1) ) - { /* status port */ - return OPL->status & (OPL->statusmask|0x80); - } - /* data port */ - switch(OPL->address) - { - case 0x05: /* KeyBoard IN */ - if(OPL->type&OPL_TYPE_KEYBOARD) - { - if(OPL->keyboardhandler_r) - return OPL->keyboardhandler_r(OPL->keyboard_param); - else - LOG(LOG_WAR,("OPL:read unmapped KEYBOARD port\n")); - } - return 0; -#if 0 - case 0x0f: /* ADPCM-DATA */ - return 0; -#endif - case 0x19: /* I/O DATA */ - if(OPL->type&OPL_TYPE_IO) - { - if(OPL->porthandler_r) - return OPL->porthandler_r(OPL->port_param); - else - LOG(LOG_WAR,("OPL:read unmapped I/O port\n")); - } - return 0; - case 0x1a: /* PCM-DATA */ - return 0; - } - return 0; -} - -int OPLTimerOver(FM_OPL *OPL,int c) -{ - if( c ) - { /* Timer B */ - OPL_STATUS_SET(OPL,0x20); - } - else - { /* Timer A */ - OPL_STATUS_SET(OPL,0x40); - /* CSM mode key,TL controll */ - if( OPL->mode & 0x80 ) - { /* CSM mode total level latch and auto key on */ - int ch; - if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); - for(ch=0;ch<9;ch++) - CSMKeyControll( &OPL->P_CH[ch] ); - } - } - /* reload timer */ - if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); - return OPL->status>>7; -} diff --git a/src/libxineadec/nosefart/fmopl.h b/src/libxineadec/nosefart/fmopl.h deleted file mode 100644 index 92a2859d7..000000000 --- a/src/libxineadec/nosefart/fmopl.h +++ /dev/null @@ -1,164 +0,0 @@ -#ifndef __FMOPL_H_ -#define __FMOPL_H_ - -#define HAS_YM3812 1 -typedef signed short int FMSAMPLE; - - -#define BUILD_YM3812 (HAS_YM3812) -#define BUILD_YM3526 (HAS_YM3526) -#define BUILD_Y8950 (HAS_Y8950) - -/* compiler dependence */ -#ifndef OSD_CPU_H -#define OSD_CPU_H -typedef unsigned char UINT8; /* unsigned 8bit */ -typedef unsigned short UINT16; /* unsigned 16bit */ -typedef unsigned int UINT32; /* unsigned 32bit */ -typedef signed char INT8; /* signed 8bit */ -typedef signed short INT16; /* signed 16bit */ -typedef signed int INT32; /* signed 32bit */ -#endif - -#if BUILD_Y8950 -#include "ymdeltat.h" -#endif - -typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec); -typedef void (*OPL_IRQHANDLER)(int param,int irq); -typedef void (*OPL_UPDATEHANDLER)(int param,int min_interval_us); -typedef void (*OPL_PORTHANDLER_W)(int param,unsigned char data); -typedef unsigned char (*OPL_PORTHANDLER_R)(int param); - -/* !!!!! here is private section , do not access there member direct !!!!! */ - -#define OPL_TYPE_WAVESEL 0x01 /* waveform select */ -#define OPL_TYPE_ADPCM 0x02 /* DELTA-T ADPCM unit */ -#define OPL_TYPE_KEYBOARD 0x04 /* keyboard interface */ -#define OPL_TYPE_IO 0x08 /* I/O port */ - -/* ---------- OPL one of slot ---------- */ -typedef struct fm_opl_slot { - INT32 TL; /* total level :TL << 8 */ - INT32 TLL; /* adjusted now TL */ - UINT8 KSR; /* key scale rate :(shift down bit) */ - INT32 *AR; /* attack rate :&AR_TABLE[AR<<2] */ - INT32 *DR; /* decay rate :&DR_TALBE[DR<<2] */ - INT32 SL; /* sustin level :SL_TALBE[SL] */ - INT32 *RR; /* release rate :&DR_TABLE[RR<<2] */ - UINT8 ksl; /* keyscale level :(shift down bits) */ - UINT8 ksr; /* key scale rate :kcode>>KSR */ - UINT32 mul; /* multiple :ML_TABLE[ML] */ - UINT32 Cnt; /* frequency count : */ - UINT32 Incr; /* frequency step : */ - /* envelope generator state */ - UINT8 eg_typ; /* envelope type flag */ - UINT8 evm; /* envelope phase */ - INT32 evc; /* envelope counter */ - INT32 eve; /* envelope counter end point */ - INT32 evs; /* envelope counter step */ - INT32 evsa; /* envelope step for AR :AR[ksr] */ - INT32 evsd; /* envelope step for DR :DR[ksr] */ - INT32 evsr; /* envelope step for RR :RR[ksr] */ - /* LFO */ - UINT8 ams; /* ams flag */ - UINT8 vib; /* vibrate flag */ - /* wave selector */ - INT32 **wavetable; -}OPL_SLOT; - -/* ---------- OPL one of channel ---------- */ -typedef struct fm_opl_channel { - OPL_SLOT SLOT[2]; - UINT8 CON; /* connection type */ - UINT8 FB; /* feed back :(shift down bit) */ - INT32 *connect1; /* slot1 output pointer */ - INT32 *connect2; /* slot2 output pointer */ - INT32 op1_out[2]; /* slot1 output for selfeedback */ - /* phase generator state */ - UINT32 block_fnum; /* block+fnum : */ - UINT8 kcode; /* key code : KeyScaleCode */ - UINT32 fc; /* Freq. Increment base */ - UINT32 ksl_base; /* KeyScaleLevel Base step */ - UINT8 keyon; /* key on/off flag */ -} OPL_CH; - -/* OPL state */ -typedef struct fm_opl_f { - UINT8 type; /* chip type */ - int clock; /* master clock (Hz) */ - int rate; /* sampling rate (Hz) */ - double freqbase; /* frequency base */ - double TimerBase; /* Timer base time (==sampling time) */ - UINT8 address; /* address register */ - UINT8 status; /* status flag */ - UINT8 statusmask; /* status mask */ - UINT32 mode; /* Reg.08 : CSM , notesel,etc. */ - /* Timer */ - int T[2]; /* timer counter */ - UINT8 st[2]; /* timer enable */ - /* FM channel slots */ - OPL_CH *P_CH; /* pointer of CH */ - int max_ch; /* maximum channel */ - /* Rythm sention */ - UINT8 rythm; /* Rythm mode , key flag */ -#if BUILD_Y8950 - /* Delta-T ADPCM unit (Y8950) */ - YM_DELTAT *deltat; /* DELTA-T ADPCM */ -#endif - /* Keyboard / I/O interface unit (Y8950) */ - UINT8 portDirection; - UINT8 portLatch; - OPL_PORTHANDLER_R porthandler_r; - OPL_PORTHANDLER_W porthandler_w; - int port_param; - OPL_PORTHANDLER_R keyboardhandler_r; - OPL_PORTHANDLER_W keyboardhandler_w; - int keyboard_param; - /* time tables */ - INT32 AR_TABLE[75]; /* atttack rate tables */ - INT32 DR_TABLE[75]; /* decay rate tables */ - UINT32 FN_TABLE[1024]; /* fnumber -> increment counter */ - /* LFO */ - INT32 *ams_table; - INT32 *vib_table; - INT32 amsCnt; - INT32 amsIncr; - INT32 vibCnt; - INT32 vibIncr; - /* wave selector enable flag */ - UINT8 wavesel; - /* external event callback handler */ - OPL_TIMERHANDLER TimerHandler; /* TIMER handler */ - int TimerParam; /* TIMER parameter */ - OPL_IRQHANDLER IRQHandler; /* IRQ handler */ - int IRQParam; /* IRQ parameter */ - OPL_UPDATEHANDLER UpdateHandler; /* stream update handler */ - int UpdateParam; /* stream update parameter */ -} FM_OPL; - -/* ---------- Generic interface section ---------- */ -#define OPL_TYPE_YM3526 (0) -#define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL) -#define OPL_TYPE_Y8950 (OPL_TYPE_ADPCM|OPL_TYPE_KEYBOARD|OPL_TYPE_IO) - -FM_OPL *OPLCreate(int type, int clock, int rate); -void OPLDestroy(FM_OPL *OPL); -void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset); -void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param); -void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param); -/* Y8950 port handlers */ -void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param); -void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param); - -void OPLResetChip(FM_OPL *OPL); -int OPLWrite(FM_OPL *OPL,int a,int v); -unsigned char OPLRead(FM_OPL *OPL,int a); -int OPLTimerOver(FM_OPL *OPL,int c); - -/* YM3626/YM3812 local section */ -void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length); - -void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length); - -#endif diff --git a/src/libxineadec/nosefart/log.c b/src/libxineadec/nosefart/log.c deleted file mode 100644 index 8935a596e..000000000 --- a/src/libxineadec/nosefart/log.c +++ /dev/null @@ -1,118 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** log.c -** -** Error logging functions -** $Id: log.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ -*/ - -#include <stdio.h> -#include <stdarg.h> -#include "types.h" -#include "log.h" - - -#ifdef OSD_LOG -#include "osd.h" -#endif - -#if defined(OSD_LOG) && !defined(NOFRENDO_DEBUG) -#error NOFRENDO_DEBUG must be defined as well as OSD_LOG -#endif - -/* Note that all of these functions will be empty if -** debugging is not enabled. -*/ -#ifdef NOFRENDO_DEBUG -static FILE *errorlog; -#endif - -int log_init(void) -{ -#ifdef NOFRENDO_DEBUG -#ifdef OSD_LOG - /* Initialize an OSD logging system */ - osd_loginit(); -#endif /* OSD_LOG */ - errorlog = fopen("errorlog.txt", "wt"); - if (NULL == errorlog) - return (-1); -#endif /* NOFRENDO_DEBUG */ - return 0; -} - -void log_shutdown(void) -{ -#ifdef NOFRENDO_DEBUG - /* Snoop around for unallocated blocks */ - mem_checkblocks(); - mem_checkleaks(); -#ifdef OSD_LOG - osd_logshutdown(); -#endif /* OSD_LOG */ - fclose(errorlog); -#endif /* NOFRENDO_DEBUG */ -} - -void log_print(const char *string) -{ -#ifdef NOFRENDO_DEBUG -#ifdef OSD_LOG - osd_logprint(string); -#endif /* OSD_LOG */ - /* Log it to disk, as well */ - fputs(string, errorlog); -#endif /* NOFRENDO_DEBUG */ -} - -void log_printf(const char *format, ... ) -{ -#ifdef NOFRENDO_DEBUG -#ifdef OSD_LOG - char buffer[1024 + 1]; -#endif /* OSD_LOG */ - va_list arg; - - va_start(arg, format); - -#ifdef OSD_LOG - vsprintf(buffer, format, arg); - osd_logprint(buffer); -#endif /* OSD_LOG */ - vfprintf(errorlog, format, arg); - va_end(arg); -#endif /* NOFRENDO_DEBUG */ -} - -/* -** $Log: log.c,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources -** -** Revision 1.5 2000/06/26 04:55:33 matt -** minor change -** -** Revision 1.4 2000/06/09 15:12:25 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/log.h b/src/libxineadec/nosefart/log.h deleted file mode 100644 index a12deff0a..000000000 --- a/src/libxineadec/nosefart/log.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** log.h -** -** Error logging header file -** $Id: log.h,v 1.3 2006/04/21 23:15:45 dsalt Exp $ -*/ - -#ifndef _LOG_H_ -#define _LOG_H_ - -#include <stdio.h> -#include "attributes.h" - -extern int log_init(void); -extern void log_shutdown(void); -extern void log_print(const char *string); -extern void log_printf(const char *format, ...) XINE_FORMAT_PRINTF(1, 2); - -#endif /* _LOG_H_ */ - -/* -** $Log: log.h,v $ -** Revision 1.3 2006/04/21 23:15:45 dsalt -** Add printf format attributes. -** -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources -** -** Revision 1.4 2000/06/09 15:12:25 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/memguard.c b/src/libxineadec/nosefart/memguard.c deleted file mode 100644 index 35b3ef6ba..000000000 --- a/src/libxineadec/nosefart/memguard.c +++ /dev/null @@ -1,417 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** memguard.c -** -** memory allocation wrapper routines -** -** NOTE: based on code (c) 1998 the Retrocade group -** $Id: memguard.c,v 1.4 2004/02/20 19:53:39 komadori Exp $ -*/ - -#include "types.h" - -/* undefine macro definitions, so we get real calls */ -#undef malloc -#undef free - -#include <string.h> -#include <stdlib.h> - -#if HAVE_INTTYPES_H -# include <inttypes.h> -#else -# if HAVE_STDINT_H -# include <stdint.h> -# endif -#endif - -#include "memguard.h" -#include "log.h" - - -/* Maximum number of allocated blocks at any one time */ -#define MAX_BLOCKS 16384 - -/* Memory block structure */ -typedef struct memblock_s -{ - void *block_addr; - int block_size; - char *file_name; - int line_num; -} memblock_t; - -boolean mem_debug = TRUE; /* debugging flag */ - - -#ifdef NOFRENDO_DEBUG - -static int mem_blockcount = 0; /* allocated block count */ -static memblock_t *mem_record = NULL; - -#define GUARD_STRING "GgUuAaRrDdSsTtRrIiNnGgBbLlOoCcKk" -#define GUARD_LENGTH 64 /* before and after allocated block */ - - -/* -** Check the memory guard to make sure out of bounds writes have not -** occurred. -*/ -static boolean mem_checkguardblock(void *data, int guard_size) -{ - uint8 *orig, *chk, *blk; - int i, alloc_size; - - /* get the original pointer */ - orig = (((uint8 *) data) - guard_size); - - /* get the size */ - alloc_size = *((uint32 *) orig); - - /* now skip past the size */ - blk = orig + sizeof(uint32); - - /* check leading guard string */ - chk = GUARD_STRING; - for (i = sizeof(uint32); i < guard_size; i++) - { - if (0 == *chk) - chk = GUARD_STRING; - if (*blk != *chk) - return FALSE; - chk++; - blk++; - } - - /* check end of block */ - chk = GUARD_STRING; - blk = ((uint8 *) data) + alloc_size; - for (i = 0; i < guard_size; i++) - { - if (0 == *chk) - chk = GUARD_STRING; - if (*blk != *chk) - return FALSE; - chk++; - blk++; - } - - /* we're okay! */ - return TRUE; -} - -/* free a guard block */ -static void mem_freeguardblock(void *data, int guard_size) -{ - uint8 *orig = (((uint8 *) data) - guard_size); - - free(orig); -} - -/* fill in the memory guard, advance the pointer to the 'real' memory */ -static void *mem_guardblock(int alloc_size, int guard_size) -{ - void *orig; - uint8 *blk, *chk; - int i; - - /* allocate memory */ - orig = calloc(alloc_size + (guard_size * 2), 1); - if (NULL == orig) - return NULL; - - blk = ((uint8 *) orig); - - /* store the size of the newly allocated block*/ - *((uint32 *) blk) = alloc_size; - - /* skip past the size */ - blk += sizeof(uint32); - - /* put guard string at beginning of block */ - chk = GUARD_STRING; - for (i = sizeof(uint32); i < guard_size; i++) - { - if (0 == *chk) - chk = GUARD_STRING; - *blk++ = *chk++; - } - - /* check end of block */ - chk = GUARD_STRING; - blk = guard_size + (uint8 *) orig + alloc_size; - for (i = 0; i < guard_size; i++) - { - if (0 == *chk) - chk = GUARD_STRING; - *blk++ = *chk++; - } - - return (void *) (guard_size + (uint8 *) orig); -} - - -/* Allocate a bunch of memory to keep track of all memory blocks */ -static void mem_init(void) -{ - if (mem_record) - { - free(mem_record); - mem_record = NULL; - } - - mem_record = calloc(MAX_BLOCKS * sizeof(memblock_t), 1); - ASSERT(mem_record); -} - -/* add a block of memory to the master record */ -static void mem_addblock(void *data, int block_size, char *file, int line) -{ - int i; - - for (i = 0; i < MAX_BLOCKS; i++) - { - if (NULL == mem_record[i].block_addr) - { - mem_record[i].block_addr = data; - mem_record[i].block_size = block_size; - mem_record[i].file_name = file; - mem_record[i].line_num = line; - return; - } - } - - ASSERT_MSG("out of memory blocks."); -} - -/* find an entry in the block record and delete it */ -static void mem_deleteblock(void *data, char *file, int line) -{ - int i; - char fail[256]; - - for (i = 0; i < MAX_BLOCKS; i++) - { - if (data == mem_record[i].block_addr) - { - if (FALSE == mem_checkguardblock(mem_record[i].block_addr, GUARD_LENGTH)) - { - sprintf(fail, "mem_deleteblock 0x%08X at line %d of %s -- block corrupt", - (uint32) data, line, file); - ASSERT_MSG(fail); - } - - memset(&mem_record[i], 0, sizeof(memblock_t)); - return; - } - } - - sprintf(fail, "mem_deleteblock 0x%08X at line %d of %s -- block not found", - (uint32) data, line, file); - ASSERT_MSG(fail); -} -#endif /* NOFRENDO_DEBUG */ - -/* allocates memory and clears it */ -#ifdef NOFRENDO_DEBUG -void *_my_malloc(int size, char *file, int line) -#else -void *_my_malloc(int size) -#endif -{ - void *temp; - char fail[256]; - -#ifdef NOFRENDO_DEBUG - if (NULL == mem_record && FALSE != mem_debug) - mem_init(); - - if (FALSE != mem_debug) - temp = mem_guardblock(size, GUARD_LENGTH); - else -#endif /* NOFRENDO_DEBUG */ - temp = calloc(sizeof(uint8), size); - - if (NULL == temp) - { -#ifdef NOFRENDO_DEBUG - sprintf(fail, "malloc: out of memory at line %d of %s. block size: %d\n", - line, file, size); -#else - sprintf(fail, "malloc: out of memory. block size: %d\n", size); -#endif - ASSERT_MSG(fail); - } - -#ifdef NOFRENDO_DEBUG - if (FALSE != mem_debug) - mem_addblock(temp, size, file, line); - - mem_blockcount++; -#endif - - return temp; -} - -/* free a pointer allocated with my_malloc */ -#ifdef NOFRENDO_DEBUG -void _my_free(void **data, char *file, int line) -#else -void _my_free(void **data) -#endif -{ - char fail[256]; - - if (NULL == data || NULL == *data - || ((uintptr_t)-1) == (uintptr_t) *data || ((uintptr_t)-1) == (uintptr_t) data) - { -#ifdef NOFRENDO_DEBUG - sprintf(fail, "free: attempted to free NULL pointer at line %d of %s\n", - line, file); -#else - sprintf(fail, "free: attempted to free NULL pointer.\n"); -#endif - ASSERT_MSG(fail); - } - -#ifdef NOFRENDO_DEBUG - /* if this is true, we are in REAL trouble */ - if (0 == mem_blockcount) - { - ASSERT_MSG("free: attempted to free memory when no blocks available"); - } - - if (FALSE != mem_debug) - mem_deleteblock(*data, file, line); - - mem_blockcount--; /* dec our block count */ - - if (FALSE != mem_debug) - mem_freeguardblock(*data, GUARD_LENGTH); - else -#endif /* NOFRENDO_DEBUG */ - free(*data); - - *data = NULL; /* NULL our source */ -} - -/* check for orphaned memory handles */ -void mem_checkleaks(void) -{ -#ifdef NOFRENDO_DEBUG - int i; - - if (FALSE == mem_debug) - return; - - if (mem_blockcount) - { - log_printf("memory leak - %d unfreed block%s\n\n", mem_blockcount, - mem_blockcount == 1 ? "" : "s"); - - for (i = 0; i < MAX_BLOCKS; i++) - { - if (mem_record[i].block_addr) - { - log_printf("addr: 0x%08X, size: %d, line %d of %s%s\n", - (uint32) mem_record[i].block_addr, - mem_record[i].block_size, - mem_record[i].line_num, - mem_record[i].file_name, - (FALSE == mem_checkguardblock(mem_record[i].block_addr, GUARD_LENGTH)) - ? " -- block corrupt" : ""); - } - } - } - else - log_printf("no memory leaks\n"); -#endif -} - -void mem_checkblocks(void) -{ -#ifdef NOFRENDO_DEBUG - int i; - - if (FALSE == mem_debug) - return; - - for (i = 0; i < MAX_BLOCKS; i++) - { - if (mem_record[i].block_addr) - { - if (FALSE == mem_checkguardblock(mem_record[i].block_addr, GUARD_LENGTH)) - { - log_printf("addr: 0x%08X, size: %d, line %d of %s -- block corrupt\n", - (uint32) mem_record[i].block_addr, - mem_record[i].block_size, - mem_record[i].line_num, - mem_record[i].file_name); - } - } - } -#endif /* NOFRENDO_DEBUG */ -} - -/* -** $Log: memguard.c,v $ -** Revision 1.4 2004/02/20 19:53:39 komadori -** Fixed detection of linux framebuffer support. Included xineutils.h in dsputil_mlib.c and added to diff_to_ffmpeg_cvs.txt. Fixed function prototype in dsputil_mlib.c (should be sent back to ffmpeg-dev at some point). Fixed includes in nosefart. Fixed nested comments and includes in goom. -** -** Revision 1.3 2004/02/19 02:50:25 rockyb -** Mandrake patches from -** http://cvs.mandrakesoft.com/cgi-bin/cvsweb.cgi/SPECS/xine-lib/ -** via Goetz Waschk who reports: -** -** The amd64 patch (xine-lib-1-rc0a-amd64.patch) sets some conservative -** CFLAGS for amd64, -** -** the lib64 patch (xine-lib-1-rc0a-lib64.patch) replaces hardcoded -** /lib to support the lib64 library dir on amd64, -** -** the directfb patch (xine-lib-1-rc2-no-directfb.patch) adds a -** configure option to disable directfb, -** -** the linuxfb patch (xine-lib-1-rc3a-no-linuxfb.patch) does the same -** for linux framebuffer and -** -** the 64bit fixes patch (xine-lib-1-rc3-64bit-fixes.patch) doesn't -** apply at the moment against the CVS -- demux_ogg.c was not applied. -** it includes some 64 bit pointer and other fixes for 64bit architectures. -** from Gwenole Beauchesne -** -** I haven't tested other than apply and compile. -** -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources -** -** Revision 1.8 2000/06/26 04:54:48 matt -** simplified and made more robust -** -** Revision 1.7 2000/06/12 01:11:41 matt -** cleaned up some error output for win32 -** -** Revision 1.6 2000/06/09 15:12:25 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/memguard.h b/src/libxineadec/nosefart/memguard.h deleted file mode 100644 index d80d6fb7c..000000000 --- a/src/libxineadec/nosefart/memguard.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** memguard.h -** -** memory allocation wrapper routines -** $Id: memguard.h,v 1.2 2003/03/01 02:23:01 storri Exp $ -*/ - -#ifndef _MEMGUARD_H_ -#define _MEMGUARD_H_ - -#ifdef NOFRENDO_DEBUG - -#define malloc(s) _my_malloc((s), __FILE__, __LINE__) -#define free(d) _my_free((void **) &(d), __FILE__, __LINE__) - -extern void *_my_malloc(int size, char *file, int line); -extern void _my_free(void **data, char *file, int line); - -#else /* Non-debugging versions of calls */ - -#define malloc(s) _my_malloc((s)) -#define free(d) _my_free((void **) &(d)) - -extern void *_my_malloc(int size); -extern void _my_free(void **data); - -#endif /* NOFRENDO_DEBUG */ - - -extern void mem_checkblocks(void); -extern void mem_checkleaks(void); - -extern boolean mem_debug; - -#endif /* _MEMGUARD_H_ */ - -/* -** $Log: memguard.h,v $ -** Revision 1.2 2003/03/01 02:23:01 storri -** Added new line at end of file to remove compiler warning. -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources -** -** Revision 1.5 2000/06/26 04:54:48 matt -** simplified and made more robust -** -** Revision 1.4 2000/06/09 15:12:25 matt -** initial revision -** -*/ - diff --git a/src/libxineadec/nosefart/mmc5_snd.c b/src/libxineadec/nosefart/mmc5_snd.c deleted file mode 100644 index 7269fa967..000000000 --- a/src/libxineadec/nosefart/mmc5_snd.c +++ /dev/null @@ -1,360 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** mmc5_snd.c -** -** Nintendo MMC5 sound emulation -** $Id: mmc5_snd.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ -*/ - -#include <string.h> -#include "types.h" -#include "mmc5_snd.h" -#include "nes_apu.h" - -/* TODO: encapsulate apu/mmc5 rectangle */ - -#define APU_OVERSAMPLE -#define APU_VOLUME_DECAY(x) ((x) -= ((x) >> 7)) - - -typedef struct mmc5dac_s -{ - int32 output; - boolean enabled; -} mmc5dac_t; - - -/* look up table madness */ -static int32 decay_lut[16]; -static int vbl_lut[32]; - -/* various sound constants for sound emulation */ -/* vblank length table used for rectangles, triangle, noise */ -static const uint8 vbl_length[32] = -{ - 5, 127, 10, 1, 19, 2, 40, 3, 80, 4, 30, 5, 7, 6, 13, 7, - 6, 8, 12, 9, 24, 10, 48, 11, 96, 12, 36, 13, 8, 14, 16, 15 -}; - -/* ratios of pos/neg pulse for rectangle waves -** 2/16 = 12.5%, 4/16 = 25%, 8/16 = 50%, 12/16 = 75% -** (4-bit adder in rectangles, hence the 16) -*/ -static const int duty_lut[4] = -{ - 2, 4, 8, 12 -}; - - -static int32 mmc5_incsize; -static uint8 mul[2]; -static mmc5rectangle_t mmc5rect[2]; -static mmc5dac_t mmc5dac; - -#define MMC5_RECTANGLE_OUTPUT chan->output_vol -static int32 mmc5_rectangle(mmc5rectangle_t *chan) -{ - int32 output; - -#ifdef APU_OVERSAMPLE - int num_times; - int32 total; -#endif /* APU_OVERSAMPLE */ - - /* reg0: 0-3=volume, 4=envelope, 5=hold, 6-7=duty cycle - ** reg1: 0-2=sweep shifts, 3=sweep inc/dec, 4-6=sweep length, 7=sweep on - ** reg2: 8 bits of freq - ** reg3: 0-2=high freq, 7-4=vbl length counter - */ - - APU_VOLUME_DECAY(chan->output_vol); - - if (FALSE == chan->enabled || 0 == chan->vbl_length) - return MMC5_RECTANGLE_OUTPUT; - - /* vbl length counter */ - if (FALSE == chan->holdnote) - chan->vbl_length--; - - /* envelope decay at a rate of (env_delay + 1) / 240 secs */ - chan->env_phase -= 4; /* 240/60 */ - while (chan->env_phase < 0) - { - chan->env_phase += chan->env_delay; - - if (chan->holdnote) - chan->env_vol = (chan->env_vol + 1) & 0x0F; - else if (chan->env_vol < 0x0F) - chan->env_vol++; - } - - if (chan->freq < APU_TO_FIXED(4)) - return MMC5_RECTANGLE_OUTPUT; - - chan->phaseacc -= mmc5_incsize; /* # of cycles per sample */ - if (chan->phaseacc >= 0) - return MMC5_RECTANGLE_OUTPUT; - -#ifdef APU_OVERSAMPLE - num_times = total = 0; - - if (chan->fixed_envelope) - output = chan->volume << 8; /* fixed volume */ - else - output = (chan->env_vol ^ 0x0F) << 8; -#endif - - while (chan->phaseacc < 0) - { - chan->phaseacc += chan->freq; - chan->adder = (chan->adder + 1) & 0x0F; - -#ifdef APU_OVERSAMPLE - if (chan->adder < chan->duty_flip) - total += output; - else - total -= output; - - num_times++; -#endif - } - -#ifdef APU_OVERSAMPLE - chan->output_vol = total / num_times; -#else - if (chan->fixed_envelope) - output = chan->volume << 8; /* fixed volume */ - else - output = (chan->env_vol ^ 0x0F) << 8; - - if (0 == chan->adder) - chan->output_vol = output; - else if (chan->adder == chan->duty_flip) - chan->output_vol = -output; -#endif - - return MMC5_RECTANGLE_OUTPUT; -} - -static uint8 mmc5_read(uint32 address) -{ - uint32 retval; - - retval = (uint32) (mul[0] * mul[1]); - - switch (address) - { - case 0x5205: - return (uint8) retval; - - case 0x5206: - return (uint8) (retval >> 8); - - default: - return 0xFF; - } -} - -/* mix vrcvi sound channels together */ -static int32 mmc5_process(void) -{ - int32 accum; - - accum = mmc5_rectangle(&mmc5rect[0]); - accum += mmc5_rectangle(&mmc5rect[1]); - if (mmc5dac.enabled) - accum += mmc5dac.output; - - return accum; -} - -/* write to registers */ -static void mmc5_write(uint32 address, uint8 value) -{ - int chan; - - switch (address) - { - /* rectangles */ - case MMC5_WRA0: - case MMC5_WRB0: - chan = (address & 4) ? 1 : 0; - mmc5rect[chan].regs[0] = value; - - mmc5rect[chan].volume = value & 0x0F; - mmc5rect[chan].env_delay = decay_lut[value & 0x0F]; - mmc5rect[chan].holdnote = (value & 0x20) ? TRUE : FALSE; - mmc5rect[chan].fixed_envelope = (value & 0x10) ? TRUE : FALSE; - mmc5rect[chan].duty_flip = duty_lut[value >> 6]; - break; - - case MMC5_WRA1: - case MMC5_WRB1: - break; - - case MMC5_WRA2: - case MMC5_WRB2: - chan = (address & 4) ? 1 : 0; - mmc5rect[chan].regs[2] = value; - if (mmc5rect[chan].enabled) - mmc5rect[chan].freq = APU_TO_FIXED((((mmc5rect[chan].regs[3] & 7) << 8) + value) + 1); - break; - - case MMC5_WRA3: - case MMC5_WRB3: - chan = (address & 4) ? 1 : 0; - mmc5rect[chan].regs[3] = value; - - if (mmc5rect[chan].enabled) - { - mmc5rect[chan].vbl_length = vbl_lut[value >> 3]; - mmc5rect[chan].env_vol = 0; - mmc5rect[chan].freq = APU_TO_FIXED((((value & 7) << 8) + mmc5rect[chan].regs[2]) + 1); - mmc5rect[chan].adder = 0; - } - break; - - case MMC5_SMASK: - if (value & 0x01) - mmc5rect[0].enabled = TRUE; - else - { - mmc5rect[0].enabled = FALSE; - mmc5rect[0].vbl_length = 0; - } - - if (value & 0x02) - mmc5rect[1].enabled = TRUE; - else - { - mmc5rect[1].enabled = FALSE; - mmc5rect[1].vbl_length = 0; - } - - break; - - case 0x5010: - if (value & 0x01) - mmc5dac.enabled = TRUE; - else - mmc5dac.enabled = FALSE; - break; - - case 0x5011: - mmc5dac.output = (value ^ 0x80) << 8; - break; - - case 0x5205: - mul[0] = value; - break; - - case 0x5206: - mul[1] = value; - break; - - default: - break; - } -} - -/* reset state of vrcvi sound channels */ -static void mmc5_reset(void) -{ - int i; - - /* get the phase period from the apu */ - mmc5_incsize = apu_getcyclerate(); - - for (i = 0x5000; i < 0x5008; i++) - mmc5_write(i, 0); - - mmc5_write(0x5010, 0); - mmc5_write(0x5011, 0); -} - -static void mmc5_init(void) -{ - int i; - int num_samples = apu_getcontext()->num_samples; - - /* lut used for enveloping and frequency sweeps */ - for (i = 0; i < 16; i++) - decay_lut[i] = num_samples * (i + 1); - - /* used for note length, based on vblanks and size of audio buffer */ - for (i = 0; i < 32; i++) - vbl_lut[i] = vbl_length[i] * num_samples; -} - -/* TODO: bleh */ -static void mmc5_shutdown(void) -{ -} - -static apu_memread mmc5_memread[] = -{ - { 0x5205, 0x5206, mmc5_read }, - { -1, -1, NULL } -}; - -static apu_memwrite mmc5_memwrite[] = -{ - { 0x5000, 0x5015, mmc5_write }, - { 0x5205, 0x5206, mmc5_write }, - { -1, -1, NULL } -}; - -apuext_t mmc5_ext = -{ - mmc5_init, - mmc5_shutdown, - mmc5_reset, - mmc5_process, - mmc5_memread, - mmc5_memwrite -}; - -/* -** $Log: mmc5_snd.c,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources -** -** Revision 1.6 2000/07/04 04:51:41 matt -** cleanups -** -** Revision 1.5 2000/07/03 02:18:53 matt -** much better external module exporting -** -** Revision 1.4 2000/06/28 22:03:51 matt -** fixed stupid oversight -** -** Revision 1.3 2000/06/20 20:46:58 matt -** minor cleanups -** -** Revision 1.2 2000/06/20 04:06:16 matt -** migrated external sound definition to apu module -** -** Revision 1.1 2000/06/20 00:06:47 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/mmc5_snd.h b/src/libxineadec/nosefart/mmc5_snd.h deleted file mode 100644 index 256cc2285..000000000 --- a/src/libxineadec/nosefart/mmc5_snd.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** mmc5_snd.h -** -** Nintendo MMC5 sound emulation header -** $Id: mmc5_snd.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ -*/ - -#ifndef _MMC5_SND_H_ -#define _MMC5_SND_H_ - -#define MMC5_WRA0 0x5000 -#define MMC5_WRA1 0x5001 -#define MMC5_WRA2 0x5002 -#define MMC5_WRA3 0x5003 -#define MMC5_WRB0 0x5004 -#define MMC5_WRB1 0x5005 -#define MMC5_WRB2 0x5006 -#define MMC5_WRB3 0x5007 -#define MMC5_SMASK 0x5015 - -typedef struct mmc5rectangle_s -{ - uint8 regs[4]; - - boolean enabled; - - int32 phaseacc; - int32 freq; - int32 output_vol; - boolean fixed_envelope; - boolean holdnote; - uint8 volume; - - int32 env_phase; - int32 env_delay; - uint8 env_vol; - - int vbl_length; - uint8 adder; - int duty_flip; -} mmc5rectangle_t; - - -#include "nes_apu.h" - -extern apuext_t mmc5_ext; - -#endif /* !_MMC5_SND_H_ */ - -/* -** $Log: mmc5_snd.h,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources -** -** Revision 1.2 2000/06/20 04:06:16 matt -** migrated external sound definition to apu module -** -** Revision 1.1 2000/06/20 00:06:47 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/nes6502.c b/src/libxineadec/nosefart/nes6502.c deleted file mode 100644 index d84bae912..000000000 --- a/src/libxineadec/nosefart/nes6502.c +++ /dev/null @@ -1,2564 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** nes6502.c -** -** NES custom 6502 (2A03) CPU implementation -** $Id: nes6502.c,v 1.2 2003/01/09 19:50:03 jkeil Exp $ -*/ - - -#include "types.h" -#include "nes6502.h" -#include "dis6502.h" -#include <stdio.h> - - -#define ADD_CYCLES(x) instruction_cycles += (x) -#define INC_CYCLES() instruction_cycles++ -//#define ADD_CYCLES(x) remaining_cycles -= (x) -//#define INC_CYCLES() remaining_cycles-- - -/* -** Check to see if an index reg addition overflowed to next page -*/ -#define CHECK_INDEX_OVERFLOW(addr, reg) \ -{ \ - if ((uint8) (addr) < (reg)) \ - INC_CYCLES(); \ -} - -/* -** Addressing mode macros -*/ - -#define NO_READ(value) /* empty */ - -#define IMMEDIATE_BYTE(value) \ -{ \ - value = bank_readbyte(PC++); \ -} - - -#define ABSOLUTE_ADDR(address) \ -{ \ - address = bank_readaddress(PC); \ - PC += 2; \ -} - -#define ABSOLUTE(address, value) \ -{ \ - ABSOLUTE_ADDR(address); \ - value = mem_read(address); \ -} - -#define ABSOLUTE_BYTE(value) \ -{ \ - ABSOLUTE(temp, value); \ -} - -#define ABS_IND_X_ADDR(address) \ -{ \ - address = (bank_readaddress(PC) + X) & 0xFFFF; \ - PC += 2; \ - CHECK_INDEX_OVERFLOW(address, X); \ -} - -#define ABS_IND_X(address, value) \ -{ \ - ABS_IND_X_ADDR(address); \ - value = mem_read(address); \ -} - -#define ABS_IND_X_BYTE(value) \ -{ \ - ABS_IND_X(temp, value); \ -} - -#define ABS_IND_Y_ADDR(address) \ -{ \ - address = (bank_readaddress(PC) + Y) & 0xFFFF; \ - PC += 2; \ - CHECK_INDEX_OVERFLOW(address, Y); \ -} - -#define ABS_IND_Y(address, value) \ -{ \ - ABS_IND_Y_ADDR(address); \ - value = mem_read(address); \ -} - -#define ABS_IND_Y_BYTE(value) \ -{ \ - ABS_IND_Y(temp, value); \ -} - -#define ZERO_PAGE_ADDR(address) \ -{ \ - IMMEDIATE_BYTE(address); \ -} - -#define ZERO_PAGE(address, value) \ -{ \ - ZERO_PAGE_ADDR(address); \ - value = ZP_READ(address); \ -} - -#define ZERO_PAGE_BYTE(value) \ -{ \ - ZERO_PAGE(btemp, value); \ -} - -/* Zero-page indexed Y doesn't really exist, just for LDX / STX */ -#define ZP_IND_X_ADDR(address) \ -{ \ - address = bank_readbyte(PC++) + X; \ -} - -#define ZP_IND_X(bAddr, value) \ -{ \ - ZP_IND_X_ADDR(bAddr); \ - value = ZP_READ(bAddr); \ -} - -#define ZP_IND_X_BYTE(value) \ -{ \ - ZP_IND_X(btemp, value); \ -} - -#define ZP_IND_Y_ADDR(address) \ -{ \ - address = bank_readbyte(PC++) + Y; \ -} - -#define ZP_IND_Y(address, value) \ -{ \ - ZP_IND_Y_ADDR(address); \ - value = ZP_READ(address); \ -} - -#define ZP_IND_Y_BYTE(value) \ -{ \ - ZP_IND_Y(btemp, value); \ -} - -/* -** For conditional jump relative instructions -** (BCC, BCS, BEQ, BMI, BNE, BPL, BVC, BVS) -*/ -#define RELATIVE_JUMP(cond) \ -{ \ - if (cond) \ - { \ - IMMEDIATE_BYTE(btemp); \ - if (((int8) btemp + (uint8) PC) & 0xFF00) \ - ADD_CYCLES(4); \ - else \ - ADD_CYCLES(3); \ - PC += ((int8) btemp); \ - } \ - else \ - { \ - PC++; \ - ADD_CYCLES(2); \ - } \ -} - -/* -** This is actually indexed indirect, but I call it -** indirect X to avoid confusion -*/ -#define INDIR_X_ADDR(address) \ -{ \ - btemp = bank_readbyte(PC++) + X; \ - address = zp_address(btemp); \ -} - -#define INDIR_X(address, value) \ -{ \ - INDIR_X_ADDR(address); \ - value = mem_read(address); \ -} - -#define INDIR_X_BYTE(value) \ -{ \ - INDIR_X(temp, value); \ -} - -/* -** This is actually indirect indexed, but I call it -** indirect y to avoid confusion -*/ -#define INDIR_Y_ADDR(address) \ -{ \ - IMMEDIATE_BYTE(btemp); \ - address = (zp_address(btemp) + Y) & 0xFFFF; \ - /* ???? */ \ - CHECK_INDEX_OVERFLOW(address, Y); \ -} - -#define INDIR_Y(address, value) \ -{ \ - INDIR_Y_ADDR(address); \ - value = mem_read(address); \ -} - -#define INDIR_Y_BYTE(value) \ -{ \ - /*IMMEDIATE_BYTE(btemp); \ - temp = zp_address(btemp) + Y; \ - CHECK_INDEX_OVERFLOW(temp, Y); \ - value = mem_read(temp);*/ \ - INDIR_Y(temp, value); \ -} - - -#define JUMP(address) PC = bank_readaddress((address)) - -/* -** Interrupt macros -*/ -#define NMI() \ -{ \ - PUSH(PC >> 8); \ - PUSH(PC & 0xFF); \ - CLEAR_FLAG(B_FLAG); \ - PUSH(P); \ - SET_FLAG(I_FLAG); \ - JUMP(NMI_VECTOR); \ - int_pending &= ~NMI_MASK; \ - ADD_CYCLES(INT_CYCLES); \ -} - -#define IRQ() \ -{ \ - PUSH(PC >> 8); \ - PUSH(PC & 0xFF); \ - CLEAR_FLAG(B_FLAG); \ - PUSH(P); \ - SET_FLAG(I_FLAG); \ - JUMP(IRQ_VECTOR); \ - int_pending &= ~IRQ_MASK; \ - ADD_CYCLES(INT_CYCLES); \ -} - -/* -** Instruction macros -*/ - -/* Warning! NES CPU has no decimal mode, so by default this does no BCD! */ -#ifdef NES6502_DECIMAL -#define ADC(cycles, read_func) \ -{ \ - read_func(data); \ - if (P & D_FLAG) \ - { \ - temp = (A & 0x0F) + (data & 0x0F) + (P & C_FLAG); \ - if (temp >= 10) \ - temp = (temp - 10) | 0x10; \ - temp += (A & 0xF0) + (data & 0xF0); \ - TEST_AND_FLAG(0 == ((A + data + (P & C_FLAG)) & 0xFF), Z_FLAG); \ - TEST_AND_FLAG(temp & 0x80, N_FLAG); \ - TEST_AND_FLAG(((~(A ^ data)) & (A ^ temp) & 0x80), V_FLAG); \ - if (temp > 0x9F) \ - temp += 0x60; \ - TEST_AND_FLAG(temp > 0xFF, C_FLAG); \ - A = (uint8) temp; \ - } \ - else \ - { \ - temp = A + data + (P & C_FLAG); \ - /* Set C on carry */ \ - TEST_AND_FLAG(temp > 0xFF, C_FLAG); \ - /* Set V on overflow */ \ - TEST_AND_FLAG(((~(A ^ data)) & (A ^ temp) & 0x80), V_FLAG); \ - A = (uint8) temp; \ - SET_NZ_FLAGS(A); \ - }\ - ADD_CYCLES(cycles); \ -} -#else -#define ADC(cycles, read_func) \ -{ \ - read_func(data); \ - temp = A + data + (P & C_FLAG); \ - /* Set C on carry */ \ - TEST_AND_FLAG(temp > 0xFF, C_FLAG); \ - /* Set V on overflow */ \ - TEST_AND_FLAG(((~(A ^ data)) & (A ^ temp) & 0x80), V_FLAG); \ - A = (uint8) temp; \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(cycles); \ -} -#endif /* NES6502_DECIMAL */ - -/* undocumented */ -#define ANC(cycles, read_func) \ -{ \ - read_func(data); \ - A &= data; \ - SET_NZ_FLAGS(A); \ - TEST_AND_FLAG(P & N_FLAG, C_FLAG); \ - ADD_CYCLES(cycles); \ -} - -#define AND(cycles, read_func) \ -{ \ - read_func(data); \ - A &= data; \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(cycles); \ -} - -/* undocumented */ -#define ANE(cycles, read_func) \ -{ \ - read_func(data); \ - A = (A | 0xEE) & X & data; \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(cycles); \ -} - -/* undocumented */ -#ifdef NES6502_DECIMAL -#define ARR(cycles, read_func) \ -{ \ - read_func(data); \ - data &= A; \ - if (P & D_FLAG) \ - { \ - temp = (data >> 1) | ((P & C_FLAG) << 7); \ - SET_NZ_FLAGS(temp); \ - TEST_AND_FLAG((temp ^ data) & 0x40, V_FLAG); \ - if (((data & 0x0F) + (data & 0x01)) > 5) \ - temp = (temp & 0xF0) | ((temp + 0x6) & 0x0F); \ - if (((data & 0xF0) + (data & 0x10)) > 0x50) \ - { \ - temp = (temp & 0x0F) | ((temp + 0x60) & 0xF0); \ - SET_FLAG(C_FLAG); \ - } \ - else \ - CLEAR_FLAG(C_FLAG); \ - A = (uint8) temp; \ - } \ - else \ - { \ - A = (data >> 1) | ((P & C_FLAG) << 7); \ - SET_NZ_FLAGS(A); \ - TEST_AND_FLAG(A & 0x40, C_FLAG); \ - TEST_AND_FLAG(((A >> 6) ^ (A >> 5)) & 1, V_FLAG); \ - }\ - ADD_CYCLES(cycles); \ -} -#else -#define ARR(cycles, read_func) \ -{ \ - read_func(data); \ - data &= A; \ - A = (data >> 1) | ((P & C_FLAG) << 7); \ - SET_NZ_FLAGS(A); \ - TEST_AND_FLAG(A & 0x40, C_FLAG); \ - TEST_AND_FLAG((A >> 6) ^ (A >> 5), V_FLAG); \ - ADD_CYCLES(cycles); \ -} -#endif /* NES6502_DECIMAL */ - -#define ASL(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr, data); \ - TEST_AND_FLAG(data & 0x80, C_FLAG); \ - data <<= 1; \ - write_func(addr, data); \ - SET_NZ_FLAGS(data); \ - ADD_CYCLES(cycles); \ -} - -#define ASL_A() \ -{ \ - TEST_AND_FLAG(A & 0x80, C_FLAG); \ - A <<= 1; \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(2); \ -} - -/* undocumented */ -#define ASR(cycles, read_func) \ -{ \ - read_func(data); \ - data &= A; \ - TEST_AND_FLAG(data & 0x01, C_FLAG); \ - A = data >> 1; \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(cycles); \ -} - -#define BCC() \ -{ \ - RELATIVE_JUMP((IS_FLAG_CLEAR(C_FLAG))); \ -} - -#define BCS() \ -{ \ - RELATIVE_JUMP((IS_FLAG_SET(C_FLAG))); \ -} - -#define BEQ() \ -{ \ - RELATIVE_JUMP((IS_FLAG_SET(Z_FLAG))); \ -} - -#define BIT(cycles, read_func) \ -{ \ - read_func(data); \ - TEST_AND_FLAG(0 == (data & A), Z_FLAG);\ - CLEAR_FLAG(N_FLAG | V_FLAG); \ - /* move bit 7/6 of data into N/V flags */ \ - SET_FLAG(data & (N_FLAG | V_FLAG)); \ - ADD_CYCLES(cycles); \ -} - -#define BMI() \ -{ \ - RELATIVE_JUMP((IS_FLAG_SET(N_FLAG))); \ -} - -#define BNE() \ -{ \ - RELATIVE_JUMP((IS_FLAG_CLEAR(Z_FLAG))); \ -} - -#define BPL() \ -{ \ - RELATIVE_JUMP((IS_FLAG_CLEAR(N_FLAG))); \ -} - -/* Software interrupt type thang */ -#define BRK() \ -{ \ - PC++; \ - PUSH(PC >> 8); \ - PUSH(PC & 0xFF); \ - SET_FLAG(B_FLAG); \ - PUSH(P); \ - SET_FLAG(I_FLAG); \ - JUMP(IRQ_VECTOR); \ - ADD_CYCLES(7); \ -} - -#define BVC() \ -{ \ - RELATIVE_JUMP((IS_FLAG_CLEAR(V_FLAG))); \ -} - -#define BVS() \ -{ \ - RELATIVE_JUMP((IS_FLAG_SET(V_FLAG))); \ -} - -#define CLC() \ -{ \ - CLEAR_FLAG(C_FLAG); \ - ADD_CYCLES(2); \ -} - -#define CLD() \ -{ \ - CLEAR_FLAG(D_FLAG); \ - ADD_CYCLES(2); \ -} - -#define CLI() \ -{ \ - CLEAR_FLAG(I_FLAG); \ - ADD_CYCLES(2); \ -} - -#define CLV() \ -{ \ - CLEAR_FLAG(V_FLAG); \ - ADD_CYCLES(2); \ -} - -/* TODO: ick! */ -#define _COMPARE(reg, value) \ -{ \ - temp = (reg) - (value); \ - /* C is clear when data > A */ \ - TEST_AND_FLAG(0 == (temp & 0x8000), C_FLAG); \ - SET_NZ_FLAGS((uint8) temp); /* handles Z flag */ \ -} - -#define CMP(cycles, read_func) \ -{ \ - read_func(data); \ - _COMPARE(A, data); \ - ADD_CYCLES(cycles); \ -} - -#define CPX(cycles, read_func) \ -{ \ - read_func(data); \ - _COMPARE(X, data); \ - ADD_CYCLES(cycles); \ -} - -#define CPY(cycles, read_func) \ -{ \ - read_func(data); \ - _COMPARE(Y, data); \ - ADD_CYCLES(cycles); \ -} - -/* undocumented */ -#define DCP(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr, data); \ - data--; \ - write_func(addr, data); \ - CMP(cycles, NO_READ); \ -} - -#define DEC(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr, data); \ - data--; \ - write_func(addr, data); \ - SET_NZ_FLAGS(data); \ - ADD_CYCLES(cycles); \ -} - -#define DEX() \ -{ \ - X--; \ - SET_NZ_FLAGS(X); \ - ADD_CYCLES(2); \ -} - -#define DEY() \ -{ \ - Y--; \ - SET_NZ_FLAGS(Y); \ - ADD_CYCLES(2); \ -} - -/* undocumented (double-NOP) */ -#define DOP(cycles) \ -{ \ - PC++; \ - ADD_CYCLES(cycles); \ -} - -#define EOR(cycles, read_func) \ -{ \ - read_func(data); \ - A ^= data; \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(cycles); \ -} - -#define INC(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr, data); \ - data++; \ - write_func(addr, data); \ - SET_NZ_FLAGS(data); \ - ADD_CYCLES(cycles); \ -} - -#define INX() \ -{ \ - X++; \ - SET_NZ_FLAGS(X); \ - ADD_CYCLES(2); \ -} - -#define INY() \ -{ \ - Y++; \ - SET_NZ_FLAGS(Y); \ - ADD_CYCLES(2); \ -} - -/* undocumented */ -#define ISB(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr, data); \ - data++; \ - write_func(addr, data); \ - SBC(cycles, NO_READ); \ -} - -#ifdef NES6502_TESTOPS -#define JAM() \ -{ \ - cpu_Jam(); \ -} -#elif defined(NSF_PLAYER) -#define JAM() \ -{ \ -} -#else -#define JAM() \ -{ \ - char jambuf[20]; \ - sprintf(jambuf, "JAM: PC=$%04X", PC); \ - ASSERT_MSG(jambuf); \ - ADD_CYCLES(2); \ -} -#endif /* NES6502_TESTOPS */ - -#define JMP_INDIRECT() \ -{ \ - temp = bank_readaddress(PC); \ - /* bug in crossing page boundaries */ \ - if (0xFF == (uint8) temp) \ - PC = (bank_readbyte(temp & ~0xFF) << 8) | bank_readbyte(temp); \ - else \ - JUMP(temp); \ - ADD_CYCLES(5); \ -} - -#define JMP_ABSOLUTE() \ -{ \ - JUMP(PC); \ - ADD_CYCLES(3); \ -} - -#define JSR() \ -{ \ - PC++; \ - PUSH(PC >> 8); \ - PUSH(PC & 0xFF); \ - JUMP(PC - 1); \ - ADD_CYCLES(6); \ -} - -/* undocumented */ -#define LAS(cycles, read_func) \ -{ \ - read_func(data); \ - A = X = S = (S & data); \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(cycles); \ -} - -/* undocumented */ -#define LAX(cycles, read_func) \ -{ \ - read_func(A); \ - X = A; \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(cycles); \ -} - -#define LDA(cycles, read_func) \ -{ \ - read_func(A); \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(cycles); \ -} - -#define LDX(cycles, read_func) \ -{ \ - read_func(X); \ - SET_NZ_FLAGS(X);\ - ADD_CYCLES(cycles); \ -} - -#define LDY(cycles, read_func) \ -{ \ - read_func(Y); \ - SET_NZ_FLAGS(Y);\ - ADD_CYCLES(cycles); \ -} - -#define LSR(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr, data); \ - TEST_AND_FLAG(data & 0x01, C_FLAG); \ - data >>= 1; \ - write_func(addr, data); \ - SET_NZ_FLAGS(data); \ - ADD_CYCLES(cycles); \ -} - -#define LSR_A() \ -{ \ - TEST_AND_FLAG(A & 0x01, C_FLAG); \ - A >>= 1; \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(2); \ -} - -/* undocumented */ -#define LXA(cycles, read_func) \ -{ \ - read_func(data); \ - A = X = ((A | 0xEE) & data); \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(cycles); \ -} - -#define NOP() \ -{ \ - ADD_CYCLES(2); \ -} - -#define ORA(cycles, read_func) \ -{ \ - read_func(data); \ - A |= data; \ - SET_NZ_FLAGS(A);\ - ADD_CYCLES(cycles); \ -} - -#define PHA() \ -{ \ - PUSH(A); \ - ADD_CYCLES(3); \ -} - -#define PHP() \ -{ \ - /* B flag is pushed on stack as well */ \ - PUSH((P | B_FLAG)); \ - ADD_CYCLES(3); \ -} - -#define PLA() \ -{ \ - A = PULL(); \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(4); \ -} - -#define PLP() \ -{ \ - P = PULL(); \ - SET_FLAG(R_FLAG); /* ensure reserved flag is set */ \ - ADD_CYCLES(4); \ -} - -/* undocumented */ -#define RLA(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr, data); \ - if (P & C_FLAG) \ - { \ - TEST_AND_FLAG(data & 0x80, C_FLAG); \ - data = (data << 1) | 1; \ - } \ - else \ - { \ - TEST_AND_FLAG(data & 0x80, C_FLAG); \ - data <<= 1; \ - } \ - write_func(addr, data); \ - A &= data; \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(cycles); \ -} - -/* 9-bit rotation (carry flag used for rollover) */ -#define ROL(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr, data); \ - if (P & C_FLAG) \ - { \ - TEST_AND_FLAG(data & 0x80, C_FLAG); \ - data = (data << 1) | 1; \ - } \ - else \ - { \ - TEST_AND_FLAG(data & 0x80, C_FLAG); \ - data <<= 1; \ - } \ - write_func(addr, data); \ - SET_NZ_FLAGS(data); \ - ADD_CYCLES(cycles); \ -} - -#define ROL_A() \ -{ \ - if (P & C_FLAG) \ - { \ - TEST_AND_FLAG(A & 0x80, C_FLAG); \ - A = (A << 1) | 1; \ - } \ - else \ - { \ - TEST_AND_FLAG(A & 0x80, C_FLAG); \ - A <<= 1; \ - } \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(2); \ -} - -#define ROR(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr, data); \ - if (P & C_FLAG) \ - { \ - TEST_AND_FLAG(data & 1, C_FLAG); \ - data = (data >> 1) | 0x80; \ - } \ - else \ - { \ - TEST_AND_FLAG(data & 1, C_FLAG); \ - data >>= 1; \ - } \ - write_func(addr, data); \ - SET_NZ_FLAGS(data); \ - ADD_CYCLES(cycles); \ -} - -#define ROR_A() \ -{ \ - if (P & C_FLAG) \ - { \ - TEST_AND_FLAG(A & 1, C_FLAG); \ - A = (A >> 1) | 0x80; \ - } \ - else \ - { \ - TEST_AND_FLAG(A & 1, C_FLAG); \ - A >>= 1; \ - } \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(2); \ -} - -/* undocumented */ -#define RRA(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr, data); \ - if (P & C_FLAG) \ - { \ - TEST_AND_FLAG(data & 1, C_FLAG); \ - data = (data >> 1) | 0x80; \ - } \ - else \ - { \ - TEST_AND_FLAG(data & 1, C_FLAG); \ - data >>= 1; \ - } \ - write_func(addr, data); \ - ADC(cycles, NO_READ); \ -} - -#define RTI() \ -{ \ - P = PULL(); \ - SET_FLAG(R_FLAG); /* ensure reserved flag is set */ \ - PC = PULL(); \ - PC |= PULL() << 8; \ - ADD_CYCLES(6); \ -} - -#define RTS() \ -{ \ - PC = PULL(); \ - PC = (PC | (PULL() << 8)) + 1; \ - ADD_CYCLES(6); \ -} - -/* undocumented */ -#define SAX(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr); \ - data = A & X; \ - write_func(addr, data); \ - ADD_CYCLES(cycles); \ -} - -/* Warning! NES CPU has no decimal mode, so by default this does no BCD! */ -#ifdef NES6502_DECIMAL -#define SBC(cycles, read_func) \ -{ \ - read_func(data); \ - /* NOT(C) is considered borrow */ \ - temp = A - data - ((P & C_FLAG) ^ C_FLAG); \ - if (P & D_FLAG) \ - { \ - uint8 al, ah; \ - al = (A & 0x0F) - (data & 0x0F) - ((P & C_FLAG) ^ C_FLAG); \ - ah = (A >> 4) - (data >> 4); \ - if (al & 0x10) \ - { \ - al -= 6; \ - ah--; \ - } \ - if (ah & 0x10) \ - ah -= 6; \ - TEST_AND_FLAG(temp < 0x100, C_FLAG); \ - TEST_AND_FLAG(((A ^ temp) & 0x80) && ((A ^ data) & 0x80), V_FLAG); \ - SET_NZ_FLAGS(temp & 0xFF); \ - A = (ah << 4) | (al & 0x0F); \ - } \ - else \ - { \ - TEST_AND_FLAG(((A ^ temp) & 0x80) && ((A ^ data) & 0x80), V_FLAG); \ - TEST_AND_FLAG(temp < 0x100, C_FLAG); \ - A = (uint8) temp; \ - SET_NZ_FLAGS(A & 0xFF); \ - } \ - ADD_CYCLES(cycles); \ -} -#else -#define SBC(cycles, read_func) \ -{ \ - read_func(data); \ - temp = A - data - ((P & C_FLAG) ^ C_FLAG); \ - TEST_AND_FLAG(((A ^ data) & (A ^ temp) & 0x80), V_FLAG); \ - TEST_AND_FLAG(temp < 0x100, C_FLAG); \ - A = (uint8) temp; \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(cycles); \ -} -#endif /* NES6502_DECIMAL */ - -/* undocumented */ -#define SBX(cycles, read_func) \ -{ \ - read_func(data); \ - temp = (A & X) - data; \ - TEST_AND_FLAG(temp < 0x100, C_FLAG); \ - X = temp & 0xFF; \ - SET_NZ_FLAGS(X); \ - ADD_CYCLES(cycles); \ -} - -#define SEC() \ -{ \ - SET_FLAG(C_FLAG); \ - ADD_CYCLES(2); \ -} - -#define SED() \ -{ \ - SET_FLAG(D_FLAG); \ - ADD_CYCLES(2); \ -} - -#define SEI() \ -{ \ - SET_FLAG(I_FLAG); \ - ADD_CYCLES(2); \ -} - -/* undocumented */ -#define SHA(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr); \ - data = A & X & ((uint8) ((addr >> 8) + 1)); \ - write_func(addr, data); \ - ADD_CYCLES(cycles); \ -} - -/* undocumented */ -#define SHS(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr); \ - S = A & X; \ - data = S & ((uint8) ((addr >> 8) + 1)); \ - write_func(addr, data); \ - ADD_CYCLES(cycles); \ -} - -/* undocumented */ -#define SHX(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr); \ - data = X & ((uint8) ((addr >> 8) + 1)); \ - write_func(addr, data); \ - ADD_CYCLES(cycles); \ -} - -/* undocumented */ -#define SHY(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr); \ - data = Y & ((uint8) ((addr >> 8 ) + 1)); \ - write_func(addr, data); \ - ADD_CYCLES(cycles); \ -} - -/* undocumented */ -#define SLO(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr, data); \ - TEST_AND_FLAG(data & 0x80, C_FLAG); \ - data <<= 1; \ - write_func(addr, data); \ - A |= data; \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(cycles); \ -} - -/* unoffical */ -#define SRE(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr, data); \ - TEST_AND_FLAG(data & 1, C_FLAG); \ - data >>= 1; \ - write_func(addr, data); \ - A ^= data; \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(cycles); \ -} - -#define STA(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr); \ - write_func(addr, A); \ - ADD_CYCLES(cycles); \ -} - -#define STX(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr); \ - write_func(addr, X); \ - ADD_CYCLES(cycles); \ -} - -#define STY(cycles, read_func, write_func, addr) \ -{ \ - read_func(addr); \ - write_func(addr, Y); \ - ADD_CYCLES(cycles); \ -} - -#define TAX() \ -{ \ - X = A; \ - SET_NZ_FLAGS(X);\ - ADD_CYCLES(2); \ -} - -#define TAY() \ -{ \ - Y = A; \ - SET_NZ_FLAGS(Y);\ - ADD_CYCLES(2); \ -} - -/* undocumented (triple-NOP) */ -#define TOP() \ -{ \ - PC += 2; \ - ADD_CYCLES(4); \ -} - -#define TSX() \ -{ \ - X = S; \ - SET_NZ_FLAGS(X);\ - ADD_CYCLES(2); \ -} - -#define TXA() \ -{ \ - A = X; \ - SET_NZ_FLAGS(A);\ - ADD_CYCLES(2); \ -} - -#define TXS() \ -{ \ - S = X; \ - ADD_CYCLES(2); \ -} - -#define TYA() \ -{ \ - A = Y; \ - SET_NZ_FLAGS(A); \ - ADD_CYCLES(2); \ -} - - -/* -** Stack and data fetching macros -*/ - -/* Set/clear/test bits in the flags register */ -#define SET_FLAG(mask) P |= (mask) -#define CLEAR_FLAG(mask) P &= ~(mask) -#define IS_FLAG_SET(mask) (P & (mask)) -#define IS_FLAG_CLEAR(mask) (0 == IS_FLAG_SET((mask))) - -#define TEST_AND_FLAG(test, mask) \ -{ \ - if ((test)) \ - SET_FLAG((mask)); \ - else \ - CLEAR_FLAG((mask)); \ -} - - -/* -** flag register helper macros -*/ - -/* register push/pull */ -#ifdef NES6502_MEM_ACCESS_CTRL - -# define PUSH(value) stack_push((S--),(value)) -# define PULL() stack_pull((++S)) - -#else - -# define PUSH(value) stack_page[S--] = (uint8) (value) -# define PULL() stack_page[++S] - -#endif /* #ifdef NES6502_MEM_ACCESS_CTRL */ - -/* Sets the Z and N flags based on given data, taken from precomputed table */ -#define SET_NZ_FLAGS(value) P &= ~(N_FLAG | Z_FLAG); \ - P |= flag_table[(value)] - -#define GET_GLOBAL_REGS() \ -{ \ - PC = reg_PC; \ - A = reg_A; \ - X = reg_X; \ - Y = reg_Y; \ - P = reg_P; \ - S = reg_S; \ -} - -#define SET_LOCAL_REGS() \ -{ \ - reg_PC = PC; \ - reg_A = A; \ - reg_X = X; \ - reg_Y = Y; \ - reg_P = P; \ - reg_S = S; \ -} - - -/* static data */ -static nes6502_memread *pmem_read, *pmr; -static nes6502_memwrite *pmem_write, *pmw; - -/* lookup table for N/Z flags */ -static uint8 flag_table[256]; - -/* internal critical CPU vars */ -static uint32 reg_PC; -static uint8 reg_A, reg_P, reg_X, reg_Y, reg_S; -static uint8 int_pending; -static int dma_cycles; - -/* execution cycle count (can be reset by user) */ -static uint32 total_cycles = 0; - -/* memory region pointers */ -static uint8 *nes6502_banks[NES6502_NUMBANKS]; -static uint8 *ram = NULL; -static uint8 *stack_page = NULL; - -/* access flag for memory - * $$$ ben : I add this for the playing time calculation. - * Only if compiled with NES6502_MEM_ACCESS. - */ -#ifdef NES6502_MEM_ACCESS_CTRL - -uint8 *acc_nes6502_banks[NES6502_NUMBANKS]; -static uint8 *acc_ram = NULL; -static uint8 *acc_stack_page = NULL; -uint8 nes6502_mem_access = 0; - -/* $$$ ben : - * Set memory access check flags, and store ORed frame global check - * for music time calculation. - */ -static void chk_mem_access(uint8 * access, int flags) -{ - uint8 oldchk = * access; - if ((oldchk&flags) != flags) { - nes6502_mem_access |= flags; - *access = oldchk|flags; - } -} - -INLINE void stack_push(uint8 s, uint8 v) -{ - chk_mem_access(acc_stack_page+s, NES6502_WRITE_ACCESS); - stack_page[s] = v; -} - -INLINE uint8 stack_pull(uint8 s) -{ - chk_mem_access(acc_stack_page+s, NES6502_READ_ACCESS); - return stack_page[s]; -} - -INLINE uint8 zp_read(register uint32 addr) -{ - chk_mem_access(acc_ram+addr, NES6502_READ_ACCESS); - return ram[addr]; -} - -INLINE void zp_write(register uint32 addr, uint8 v) -{ - chk_mem_access(acc_ram+addr, NES6502_WRITE_ACCESS); - ram[addr] = v; -} - -#define ZP_READ(addr) zp_read((addr)) -#define ZP_WRITE(addr, value) zp_write((addr),(value)) - -#define bank_readbyte(address) _bank_readbyte((address), NES6502_READ_ACCESS) -#define bank_readbyte_pc(address) _bank_readbyte((address), NES6502_EXE_ACCESS) - -#else -# define chk_mem_access(access, flags) - -/* -** Zero-page helper macros -*/ -#define ZP_READ(addr) ram[(addr)] -#define ZP_WRITE(addr, value) ram[(addr)] = (uint8) (value) - -#define bank_readbyte(address) _bank_readbyte((address)) -#define bank_readbyte_pc(address) _bank_readbyte((address)) - -#endif /* #ifdef NES6502_MEM_ACCESS_CTRL */ - -#ifdef NES6502_MEM_ACCESS_CTRL -int max_access[NES6502_NUMBANKS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - -INLINE uint8 _bank_readbyte(register uint32 address, const uint8 flags) -#else -INLINE uint8 _bank_readbyte(register uint32 address) -#endif -{ - ASSERT(nes6502_banks[address >> NES6502_BANKSHIFT]); - -#ifdef NES6502_MEM_ACCESS_CTRL - //printf("chk_mem_access(acc_nes6502_banks[%d] + %d, %d)\n", address>>NES6502_BANKSHIFT, address & NES6502_BANKMASK, flags); - - if((address & NES6502_BANKMASK) > max_access[address>>NES6502_BANKSHIFT]) - { - max_access[address>>NES6502_BANKSHIFT] = address & NES6502_BANKMASK; - //printf("max_access[%d] increased to %d\n", address>>NES6502_BANKSHIFT, max_access[address>>NES6502_BANKSHIFT]); - } -#endif - chk_mem_access(acc_nes6502_banks[address>>NES6502_BANKSHIFT] - + (address & NES6502_BANKMASK), - flags); - - return nes6502_banks[address >> NES6502_BANKSHIFT][address & NES6502_BANKMASK]; -} - - -INLINE void bank_writebyte(register uint32 address, register uint8 value) -{ - ASSERT(nes6502_banks[address >> NES6502_BANKSHIFT]); - -#ifdef NES6502_MEM_ACCESS_CTRL - //printf("chk_mem_access(acc_nes6502_banks[%d] + %d, %d)\n", address>>NES6502_BANKSHIFT, address & NES6502_BANKMASK, NES6502_WRITE_ACCESS); - - if((address & NES6502_BANKMASK) > max_access[address>>NES6502_BANKSHIFT]) - { - max_access[address>>NES6502_BANKSHIFT] = address & NES6502_BANKMASK; - //printf("max_access[%d] increased to %d\n", address>>NES6502_BANKSHIFT, max_access[address>>NES6502_BANKSHIFT]); - } -#endif - - chk_mem_access(acc_nes6502_banks[address>>NES6502_BANKSHIFT] - + (address & NES6502_BANKMASK), - NES6502_WRITE_ACCESS); - - nes6502_banks[address >> NES6502_BANKSHIFT][address & NES6502_BANKMASK] = value; -} - -/* Read a 16bit word */ -#define READ_SNES_16(bank,offset) \ -(\ - (offset) [ (uint8 *) (bank) ] |\ - ((unsigned int)( ((offset)+1) [ (uint8 *) (bank) ] ) << 8)\ -) - -INLINE uint32 zp_address(register uint8 address) -{ - chk_mem_access(acc_ram+address, NES6502_READ_ACCESS); - chk_mem_access(acc_ram+address+1, NES6502_READ_ACCESS); - -#if defined (HOST_LITTLE_ENDIAN) && defined(HOST_UNALIGN_WORD) - /* TODO: this fails if src address is $xFFF */ - /* TODO: this fails if host architecture doesn't support byte alignment */ - /* $$$ ben : DONE */ - return (uint32) (*(uint16 *)(ram + address)); -#elif defined(TARGET_CPU_PPC) - return __lhbrx(ram, address); -#else - return READ_SNES_16(ram,address); -/* uint32 x = (uint32) *(uint16 *)(ram + address); */ -/* return (x << 8) | (x >> 8); */ -//#endif /* TARGET_CPU_PPC */ -#endif /* HOST_LITTLE_ENDIAN */ -} - -INLINE uint32 bank_readaddress(register uint32 address) -{ - -#ifdef NES6502_MEM_ACCESS_CTRL - { - const unsigned int offset = address & NES6502_BANKMASK; - uint8 * addr = acc_nes6502_banks[address >> NES6502_BANKSHIFT]; - chk_mem_access(addr+offset+0, NES6502_READ_ACCESS); - chk_mem_access(addr+offset+1, NES6502_READ_ACCESS); - } -#endif - -#if defined (HOST_LITTLE_ENDIAN) && defined(HOST_UNALIGN_WORD) - /* TODO: this fails if src address is $xFFF */ - /* TODO: this fails if host architecture doesn't support byte alignment */ - /* $$$ ben : DONE */ - return (uint32) (*(uint16 *)(nes6502_banks[address >> NES6502_BANKSHIFT] + (address & NES6502_BANKMASK))); -#elif defined(TARGET_CPU_PPC) - return __lhbrx(nes6502_banks[address >> NES6502_BANKSHIFT], address & NES6502_BANKMASK); -#else - { - const unsigned int offset = address & NES6502_BANKMASK; - return READ_SNES_16(nes6502_banks[address >> NES6502_BANKSHIFT], offset); - } -/* uint32 x = (uint32) *(uint16 *)(nes6502_banks[address >> NES6502_BANKSHIFT] + (address & NES6502_BANKMASK)); */ -/* return (x << 8) | (x >> 8); */ -//#endif /* TARGET_CPU_PPC */ -#endif /* HOST_LITTLE_ENDIAN */ -} - - -/* read a byte of 6502 memory */ -static uint8 mem_read(uint32 address) -{ - /* TODO: following cases are N2A03-specific */ - /* RAM */ - if (address < 0x800) { - chk_mem_access(acc_ram + address, NES6502_READ_ACCESS); - return ram[address]; - } - /* always paged memory */ -// else if (address >= 0x6000) - else if (address >= 0x8000) { - return bank_readbyte(address); - } - /* check memory range handlers */ - else - { - for (pmr = pmem_read; pmr->min_range != 0xFFFFFFFF; pmr++) - { - if ((address >= pmr->min_range) && (address <= pmr->max_range)) - return pmr->read_func(address); - } - } - - /* return paged memory */ - return bank_readbyte(address); -} - -/* write a byte of data to 6502 memory */ -static void mem_write(uint32 address, uint8 value) -{ - /* RAM */ - if (address < 0x800) - { - chk_mem_access(acc_ram + address, NES6502_WRITE_ACCESS); - ram[address] = value; - return; - } - /* check memory range handlers */ - else - { - for (pmw = pmem_write; pmw->min_range != 0xFFFFFFFF; pmw++) - { - if ((address >= pmw->min_range) && (address <= pmw->max_range)) - { - pmw->write_func(address, value); - return; - } - } - } - - /* write to paged memory */ - bank_writebyte(address, value); -} - -/* set the current context */ -void nes6502_setcontext(nes6502_context *cpu) -{ - int loop; - - ASSERT(cpu); - - /* Set the page pointers */ - for (loop = 0; loop < NES6502_NUMBANKS; loop++) { - nes6502_banks[loop] = cpu->mem_page[loop]; -#ifdef NES6502_MEM_ACCESS_CTRL - acc_nes6502_banks[loop] = cpu->acc_mem_page[loop]; -#endif - } - - ram = nes6502_banks[0]; /* quicker zero-page/RAM references */ - stack_page = ram + STACK_OFFSET; -#ifdef NES6502_MEM_ACCESS_CTRL - acc_ram = acc_nes6502_banks[0]; /* quicker zero-page/RAM references */ - acc_stack_page = acc_ram + STACK_OFFSET; -#endif - - pmem_read = cpu->read_handler; - pmem_write = cpu->write_handler; - - reg_PC = cpu->pc_reg; - reg_A = cpu->a_reg; - reg_P = cpu->p_reg; - reg_X = cpu->x_reg; - reg_Y = cpu->y_reg; - reg_S = cpu->s_reg; - int_pending = cpu->int_pending; - dma_cycles = cpu->dma_cycles; -} - -/* get the current context */ -void nes6502_getcontext(nes6502_context *cpu) -{ - int loop; - - /* Set the page pointers */ - for (loop = 0; loop < NES6502_NUMBANKS; loop++) { - cpu->mem_page[loop] = nes6502_banks[loop]; -#ifdef NES6502_MEM_ACCESS_CTRL - cpu->acc_mem_page[loop] = acc_nes6502_banks[loop]; -#endif - } - - cpu->read_handler = pmem_read; - cpu->write_handler = pmem_write; - - cpu->pc_reg = reg_PC; - cpu->a_reg = reg_A; - cpu->p_reg = reg_P; - cpu->x_reg = reg_X; - cpu->y_reg = reg_Y; - cpu->s_reg = reg_S; - cpu->int_pending = int_pending; - cpu->dma_cycles = dma_cycles; -} - -/* DMA a byte of data from ROM */ -uint8 nes6502_getbyte(uint32 address) -{ - return bank_readbyte(address); -} - -/* get number of elapsed cycles */ -uint32 nes6502_getcycles(boolean reset_flag) -{ - uint32 cycles = total_cycles; - - if (reset_flag) - total_cycles = 0; - - return cycles; -} - - -/* Execute instructions until count expires -** -** Returns the number of cycles *actually* executed -** (note that this can be from 0-6 cycles more than you wanted) -*/ -int nes6502_execute(int remaining_cycles) -{ - int instruction_cycles, old_cycles = total_cycles; - uint32 temp, addr; /* for macros */ - uint32 PC; - uint8 A, X, Y, P, S; - uint8 opcode, data; - uint8 btemp, baddr; /* for macros */ - - GET_GLOBAL_REGS(); - -#ifdef NES6502_MEM_ACCESS_CTRL - /* reset global memory access for this execute loop. */ - nes6502_mem_access = 0; -#endif - - /* Continue until we run out of cycles */ - - - while (remaining_cycles > 0) - { - instruction_cycles = 0; - - /* check for DMA cycle burning */ - if (dma_cycles) - { - if (remaining_cycles <= dma_cycles) - { - dma_cycles -= remaining_cycles; - total_cycles += remaining_cycles; - goto _execute_done; - } - else - { - remaining_cycles -= dma_cycles; - total_cycles += dma_cycles; - dma_cycles = 0; - } - } - - if (int_pending) - { - /* NMI has highest priority */ - if (int_pending & NMI_MASK) - { - NMI(); - } - /* IRQ has lowest priority */ - else /* if (int_pending & IRQ_MASK) */ - { - if (IS_FLAG_CLEAR(I_FLAG)) - IRQ(); - } - } - - /* Fetch instruction */ - //nes6502_disasm(PC, P, A, X, Y, S); - - opcode = bank_readbyte_pc(PC++); - - /* Execute instruction */ - - switch (opcode) - { - case 0x00: /* BRK */ - BRK(); - break; - - case 0x01: /* ORA ($nn,X) */ - ORA(6, INDIR_X_BYTE); - break; - - /* JAM */ - case 0x02: /* JAM */ - case 0x12: /* JAM */ - case 0x22: /* JAM */ - case 0x32: /* JAM */ - case 0x42: /* JAM */ - case 0x52: /* JAM */ - case 0x62: /* JAM */ - case 0x72: /* JAM */ - case 0x92: /* JAM */ - case 0xB2: /* JAM */ - case 0xD2: /* JAM */ - case 0xF2: /* JAM */ - JAM(); - /* kill switch for CPU emulation */ - goto _execute_done; - - case 0x03: /* SLO ($nn,X) */ - SLO(8, INDIR_X, mem_write, addr); - break; - - case 0x04: /* NOP $nn */ - case 0x44: /* NOP $nn */ - case 0x64: /* NOP $nn */ - DOP(3); - break; - - case 0x05: /* ORA $nn */ - ORA(3, ZERO_PAGE_BYTE); - break; - - case 0x06: /* ASL $nn */ - ASL(5, ZERO_PAGE, ZP_WRITE, baddr); - break; - - case 0x07: /* SLO $nn */ - SLO(5, ZERO_PAGE, ZP_WRITE, baddr); - break; - - case 0x08: /* PHP */ - PHP(); - break; - - case 0x09: /* ORA #$nn */ - ORA(2, IMMEDIATE_BYTE); - break; - - case 0x0A: /* ASL A */ - ASL_A(); - break; - - case 0x0B: /* ANC #$nn */ - ANC(2, IMMEDIATE_BYTE); - break; - - case 0x0C: /* NOP $nnnn */ - TOP(); - break; - - case 0x0D: /* ORA $nnnn */ - ORA(4, ABSOLUTE_BYTE); - break; - - case 0x0E: /* ASL $nnnn */ - ASL(6, ABSOLUTE, mem_write, addr); - break; - - case 0x0F: /* SLO $nnnn */ - SLO(6, ABSOLUTE, mem_write, addr); - break; - - case 0x10: /* BPL $nnnn */ - BPL(); - break; - - case 0x11: /* ORA ($nn),Y */ - ORA(5, INDIR_Y_BYTE); - break; - - case 0x13: /* SLO ($nn),Y */ - SLO(8, INDIR_Y, mem_write, addr); - break; - - case 0x14: /* NOP $nn,X */ - case 0x34: /* NOP */ - case 0x54: /* NOP $nn,X */ - case 0x74: /* NOP $nn,X */ - case 0xD4: /* NOP $nn,X */ - case 0xF4: /* NOP ($nn,X) */ - DOP(4); - break; - - case 0x15: /* ORA $nn,X */ - ORA(4, ZP_IND_X_BYTE); - break; - - case 0x16: /* ASL $nn,X */ - ASL(6, ZP_IND_X, ZP_WRITE, baddr); - break; - - case 0x17: /* SLO $nn,X */ - SLO(6, ZP_IND_X, ZP_WRITE, baddr); - break; - - case 0x18: /* CLC */ - CLC(); - break; - - case 0x19: /* ORA $nnnn,Y */ - ORA(4, ABS_IND_Y_BYTE); - break; - - case 0x1A: /* NOP */ - case 0x3A: /* NOP */ - case 0x5A: /* NOP */ - case 0x7A: /* NOP */ - case 0xDA: /* NOP */ - case 0xFA: /* NOP */ - NOP(); - break; - - case 0x1B: /* SLO $nnnn,Y */ - SLO(7, ABS_IND_Y, mem_write, addr); - break; - - case 0x1C: /* NOP $nnnn,X */ - case 0x3C: /* NOP $nnnn,X */ - case 0x5C: /* NOP $nnnn,X */ - case 0x7C: /* NOP $nnnn,X */ - case 0xDC: /* NOP $nnnn,X */ - case 0xFC: /* NOP $nnnn,X */ - TOP(); - break; - - case 0x1D: /* ORA $nnnn,X */ - ORA(4, ABS_IND_X_BYTE); - break; - - case 0x1E: /* ASL $nnnn,X */ - ASL(7, ABS_IND_X, mem_write, addr); - break; - - case 0x1F: /* SLO $nnnn,X */ - SLO(7, ABS_IND_X, mem_write, addr); - break; - - case 0x20: /* JSR $nnnn */ - JSR(); - break; - - case 0x21: /* AND ($nn,X) */ - AND(6, INDIR_X_BYTE); - break; - - case 0x23: /* RLA ($nn,X) */ - RLA(8, INDIR_X, mem_write, addr); - break; - - case 0x24: /* BIT $nn */ - BIT(3, ZERO_PAGE_BYTE); - break; - - case 0x25: /* AND $nn */ - AND(3, ZERO_PAGE_BYTE); - break; - - case 0x26: /* ROL $nn */ - ROL(5, ZERO_PAGE, ZP_WRITE, baddr); - break; - - case 0x27: /* RLA $nn */ - RLA(5, ZERO_PAGE, ZP_WRITE, baddr); - break; - - case 0x28: /* PLP */ - PLP(); - break; - - case 0x29: /* AND #$nn */ - AND(2, IMMEDIATE_BYTE); - break; - - case 0x2A: /* ROL A */ - ROL_A(); - break; - - case 0x2B: /* ANC #$nn */ - ANC(2, IMMEDIATE_BYTE); - break; - - case 0x2C: /* BIT $nnnn */ - BIT(4, ABSOLUTE_BYTE); - break; - - case 0x2D: /* AND $nnnn */ - AND(4, ABSOLUTE_BYTE); - break; - - case 0x2E: /* ROL $nnnn */ - ROL(6, ABSOLUTE, mem_write, addr); - break; - - case 0x2F: /* RLA $nnnn */ - RLA(6, ABSOLUTE, mem_write, addr); - break; - - case 0x30: /* BMI $nnnn */ - BMI(); - break; - - case 0x31: /* AND ($nn),Y */ - AND(5, INDIR_Y_BYTE); - break; - - case 0x33: /* RLA ($nn),Y */ - RLA(8, INDIR_Y, mem_write, addr); - break; - - case 0x35: /* AND $nn,X */ - AND(4, ZP_IND_X_BYTE); - break; - - case 0x36: /* ROL $nn,X */ - ROL(6, ZP_IND_X, ZP_WRITE, baddr); - break; - - case 0x37: /* RLA $nn,X */ - RLA(6, ZP_IND_X, ZP_WRITE, baddr); - break; - - case 0x38: /* SEC */ - SEC(); - break; - - case 0x39: /* AND $nnnn,Y */ - AND(4, ABS_IND_Y_BYTE); - break; - - case 0x3B: /* RLA $nnnn,Y */ - RLA(7, ABS_IND_Y, mem_write, addr); - break; - - case 0x3D: /* AND $nnnn,X */ - AND(4, ABS_IND_X_BYTE); - break; - - case 0x3E: /* ROL $nnnn,X */ - ROL(7, ABS_IND_X, mem_write, addr); - break; - - case 0x3F: /* RLA $nnnn,X */ - RLA(7, ABS_IND_X, mem_write, addr); - break; - - case 0x40: /* RTI */ - RTI(); - break; - - case 0x41: /* EOR ($nn,X) */ - EOR(6, INDIR_X_BYTE); - break; - - case 0x43: /* SRE ($nn,X) */ - SRE(8, INDIR_X, mem_write, addr); - break; - - case 0x45: /* EOR $nn */ - EOR(3, ZERO_PAGE_BYTE); - break; - - case 0x46: /* LSR $nn */ - LSR(5, ZERO_PAGE, ZP_WRITE, baddr); - break; - - case 0x47: /* SRE $nn */ - SRE(5, ZERO_PAGE, ZP_WRITE, baddr); - break; - - case 0x48: /* PHA */ - PHA(); - break; - - case 0x49: /* EOR #$nn */ - EOR(2, IMMEDIATE_BYTE); - break; - - case 0x4A: /* LSR A */ - LSR_A(); - break; - - case 0x4B: /* ASR #$nn */ - ASR(2, IMMEDIATE_BYTE); - break; - - case 0x4C: /* JMP $nnnn */ - JMP_ABSOLUTE(); - break; - - case 0x4D: /* EOR $nnnn */ - EOR(4, ABSOLUTE_BYTE); - break; - - case 0x4E: /* LSR $nnnn */ - LSR(6, ABSOLUTE, mem_write, addr); - break; - - case 0x4F: /* SRE $nnnn */ - SRE(6, ABSOLUTE, mem_write, addr); - break; - - case 0x50: /* BVC $nnnn */ - BVC(); - break; - - case 0x51: /* EOR ($nn),Y */ - EOR(5, INDIR_Y_BYTE); - break; - - case 0x53: /* SRE ($nn),Y */ - SRE(8, INDIR_Y, mem_write, addr); - break; - - case 0x55: /* EOR $nn,X */ - EOR(4, ZP_IND_X_BYTE); - break; - - case 0x56: /* LSR $nn,X */ - LSR(6, ZP_IND_X, ZP_WRITE, baddr); - break; - - case 0x57: /* SRE $nn,X */ - SRE(6, ZP_IND_X, ZP_WRITE, baddr); - break; - - case 0x58: /* CLI */ - CLI(); - break; - - case 0x59: /* EOR $nnnn,Y */ - EOR(4, ABS_IND_Y_BYTE); - break; - - case 0x5B: /* SRE $nnnn,Y */ - SRE(7, ABS_IND_Y, mem_write, addr); - break; - - case 0x5D: /* EOR $nnnn,X */ - EOR(4, ABS_IND_X_BYTE); - break; - - case 0x5E: /* LSR $nnnn,X */ - LSR(7, ABS_IND_X, mem_write, addr); - break; - - case 0x5F: /* SRE $nnnn,X */ - SRE(7, ABS_IND_X, mem_write, addr); - break; - - case 0x60: /* RTS */ - RTS(); - break; - - case 0x61: /* ADC ($nn,X) */ - ADC(6, INDIR_X_BYTE); - break; - - case 0x63: /* RRA ($nn,X) */ - RRA(8, INDIR_X, mem_write, addr); - break; - - case 0x65: /* ADC $nn */ - ADC(3, ZERO_PAGE_BYTE); - break; - - case 0x66: /* ROR $nn */ - ROR(5, ZERO_PAGE, ZP_WRITE, baddr); - break; - - case 0x67: /* RRA $nn */ - RRA(5, ZERO_PAGE, ZP_WRITE, baddr); - break; - - case 0x68: /* PLA */ - PLA(); - break; - - case 0x69: /* ADC #$nn */ - ADC(2, IMMEDIATE_BYTE); - break; - - case 0x6A: /* ROR A */ - ROR_A(); - break; - - case 0x6B: /* ARR #$nn */ - ARR(2, IMMEDIATE_BYTE); - break; - - case 0x6C: /* JMP ($nnnn) */ - JMP_INDIRECT(); - break; - - case 0x6D: /* ADC $nnnn */ - ADC(4, ABSOLUTE_BYTE); - break; - - case 0x6E: /* ROR $nnnn */ - ROR(6, ABSOLUTE, mem_write, addr); - break; - - case 0x6F: /* RRA $nnnn */ - RRA(6, ABSOLUTE, mem_write, addr); - break; - - case 0x70: /* BVS $nnnn */ - BVS(); - break; - - case 0x71: /* ADC ($nn),Y */ - ADC(5, INDIR_Y_BYTE); - break; - - case 0x73: /* RRA ($nn),Y */ - RRA(8, INDIR_Y, mem_write, addr); - break; - - case 0x75: /* ADC $nn,X */ - ADC(4, ZP_IND_X_BYTE); - break; - - case 0x76: /* ROR $nn,X */ - ROR(6, ZP_IND_X, ZP_WRITE, baddr); - break; - - case 0x77: /* RRA $nn,X */ - RRA(6, ZP_IND_X, ZP_WRITE, baddr); - break; - - case 0x78: /* SEI */ - SEI(); - break; - - case 0x79: /* ADC $nnnn,Y */ - ADC(4, ABS_IND_Y_BYTE); - break; - - case 0x7B: /* RRA $nnnn,Y */ - RRA(7, ABS_IND_Y, mem_write, addr); - break; - - case 0x7D: /* ADC $nnnn,X */ - ADC(4, ABS_IND_X_BYTE); - break; - - case 0x7E: /* ROR $nnnn,X */ - ROR(7, ABS_IND_X, mem_write, addr); - break; - - case 0x7F: /* RRA $nnnn,X */ - RRA(7, ABS_IND_X, mem_write, addr); - break; - - case 0x80: /* NOP #$nn */ - case 0x82: /* NOP #$nn */ - case 0x89: /* NOP #$nn */ - case 0xC2: /* NOP #$nn */ - case 0xE2: /* NOP #$nn */ - DOP(2); - break; - - case 0x81: /* STA ($nn,X) */ - STA(6, INDIR_X_ADDR, mem_write, addr); - break; - - case 0x83: /* SAX ($nn,X) */ - SAX(6, INDIR_X_ADDR, mem_write, addr); - break; - - case 0x84: /* STY $nn */ - STY(3, ZERO_PAGE_ADDR, ZP_WRITE, baddr); - break; - - case 0x85: /* STA $nn */ - STA(3, ZERO_PAGE_ADDR, ZP_WRITE, baddr); - break; - - case 0x86: /* STX $nn */ - STX(3, ZERO_PAGE_ADDR, ZP_WRITE, baddr); - break; - - case 0x87: /* SAX $nn */ - SAX(3, ZERO_PAGE_ADDR, ZP_WRITE, baddr); - break; - - case 0x88: /* DEY */ - DEY(); - break; - - case 0x8A: /* TXA */ - TXA(); - break; - - case 0x8B: /* ANE #$nn */ - ANE(2, IMMEDIATE_BYTE); - break; - - case 0x8C: /* STY $nnnn */ - STY(4, ABSOLUTE_ADDR, mem_write, addr); - break; - - case 0x8D: /* STA $nnnn */ - STA(4, ABSOLUTE_ADDR, mem_write, addr); - break; - - case 0x8E: /* STX $nnnn */ - STX(4, ABSOLUTE_ADDR, mem_write, addr); - break; - - case 0x8F: /* SAX $nnnn */ - SAX(4, ABSOLUTE_ADDR, mem_write, addr); - break; - - case 0x90: /* BCC $nnnn */ - BCC(); - break; - - case 0x91: /* STA ($nn),Y */ - STA(6, INDIR_Y_ADDR, mem_write, addr); - break; - - case 0x93: /* SHA ($nn),Y */ - SHA(6, INDIR_Y_ADDR, mem_write, addr); - break; - - case 0x94: /* STY $nn,X */ - STY(4, ZP_IND_X_ADDR, ZP_WRITE, baddr); - break; - - case 0x95: /* STA $nn,X */ - STA(4, ZP_IND_X_ADDR, ZP_WRITE, baddr); - break; - - case 0x96: /* STX $nn,Y */ - STX(4, ZP_IND_Y_ADDR, ZP_WRITE, baddr); - break; - - case 0x97: /* SAX $nn,Y */ - SAX(4, ZP_IND_Y_ADDR, ZP_WRITE, baddr); - break; - - case 0x98: /* TYA */ - TYA(); - break; - - case 0x99: /* STA $nnnn,Y */ - STA(5, ABS_IND_Y_ADDR, mem_write, addr); - break; - - case 0x9A: /* TXS */ - TXS(); - break; - - case 0x9B: /* SHS $nnnn,Y */ - SHS(5, ABS_IND_Y_ADDR, mem_write, addr); - break; - - case 0x9C: /* SHY $nnnn,X */ - SHY(5, ABS_IND_X_ADDR, mem_write, addr); - break; - - case 0x9D: /* STA $nnnn,X */ - STA(5, ABS_IND_X_ADDR, mem_write, addr); - break; - - case 0x9E: /* SHX $nnnn,Y */ - SHX(5, ABS_IND_Y_ADDR, mem_write, addr); - break; - - case 0x9F: /* SHA $nnnn,Y */ - SHA(5, ABS_IND_Y_ADDR, mem_write, addr); - break; - - case 0xA0: /* LDY #$nn */ - LDY(2, IMMEDIATE_BYTE); - break; - - case 0xA1: /* LDA ($nn,X) */ - LDA(6, INDIR_X_BYTE); - break; - - case 0xA2: /* LDX #$nn */ - LDX(2, IMMEDIATE_BYTE); - break; - - case 0xA3: /* LAX ($nn,X) */ - LAX(6, INDIR_X_BYTE); - break; - - case 0xA4: /* LDY $nn */ - LDY(3, ZERO_PAGE_BYTE); - break; - - case 0xA5: /* LDA $nn */ - LDA(3, ZERO_PAGE_BYTE); - break; - - case 0xA6: /* LDX $nn */ - LDX(3, ZERO_PAGE_BYTE); - break; - - case 0xA7: /* LAX $nn */ - LAX(3, ZERO_PAGE_BYTE); - break; - - case 0xA8: /* TAY */ - TAY(); - break; - - case 0xA9: /* LDA #$nn */ - LDA(2, IMMEDIATE_BYTE); - break; - - case 0xAA: /* TAX */ - TAX(); - break; - - case 0xAB: /* LXA #$nn */ - LXA(2, IMMEDIATE_BYTE); - break; - - case 0xAC: /* LDY $nnnn */ - LDY(4, ABSOLUTE_BYTE); - break; - - case 0xAD: /* LDA $nnnn */ - LDA(4, ABSOLUTE_BYTE); - break; - - case 0xAE: /* LDX $nnnn */ - LDX(4, ABSOLUTE_BYTE); - break; - - case 0xAF: /* LAX $nnnn */ - LAX(4, ABSOLUTE_BYTE); - break; - - case 0xB0: /* BCS $nnnn */ - BCS(); - break; - - case 0xB1: /* LDA ($nn),Y */ - LDA(5, INDIR_Y_BYTE); - break; - - case 0xB3: /* LAX ($nn),Y */ - LAX(5, INDIR_Y_BYTE); - break; - - case 0xB4: /* LDY $nn,X */ - LDY(4, ZP_IND_X_BYTE); - break; - - case 0xB5: /* LDA $nn,X */ - LDA(4, ZP_IND_X_BYTE); - break; - - case 0xB6: /* LDX $nn,Y */ - LDX(4, ZP_IND_Y_BYTE); - break; - - case 0xB7: /* LAX $nn,Y */ - LAX(4, ZP_IND_Y_BYTE); - break; - - case 0xB8: /* CLV */ - CLV(); - break; - - case 0xB9: /* LDA $nnnn,Y */ - LDA(4, ABS_IND_Y_BYTE); - break; - - case 0xBA: /* TSX */ - TSX(); - break; - - case 0xBB: /* LAS $nnnn,Y */ - LAS(4, ABS_IND_Y_BYTE); - break; - - case 0xBC: /* LDY $nnnn,X */ - LDY(4, ABS_IND_X_BYTE); - break; - - case 0xBD: /* LDA $nnnn,X */ - LDA(4, ABS_IND_X_BYTE); - break; - - case 0xBE: /* LDX $nnnn,Y */ - LDX(4, ABS_IND_Y_BYTE); - break; - - case 0xBF: /* LAX $nnnn,Y */ - LAX(4, ABS_IND_Y_BYTE); - break; - - case 0xC0: /* CPY #$nn */ - CPY(2, IMMEDIATE_BYTE); - break; - - case 0xC1: /* CMP ($nn,X) */ - CMP(6, INDIR_X_BYTE); - break; - - case 0xC3: /* DCP ($nn,X) */ - DCP(8, INDIR_X, mem_write, addr); - break; - - case 0xC4: /* CPY $nn */ - CPY(3, ZERO_PAGE_BYTE); - break; - - case 0xC5: /* CMP $nn */ - CMP(3, ZERO_PAGE_BYTE); - break; - - case 0xC6: /* DEC $nn */ - DEC(5, ZERO_PAGE, ZP_WRITE, baddr); - break; - - case 0xC7: /* DCP $nn */ - DCP(5, ZERO_PAGE, ZP_WRITE, baddr); - break; - - case 0xC8: /* INY */ - INY(); - break; - - case 0xC9: /* CMP #$nn */ - CMP(2, IMMEDIATE_BYTE); - break; - - case 0xCA: /* DEX */ - DEX(); - break; - - case 0xCB: /* SBX #$nn */ - SBX(2, IMMEDIATE_BYTE); - break; - - case 0xCC: /* CPY $nnnn */ - CPY(4, ABSOLUTE_BYTE); - break; - - case 0xCD: /* CMP $nnnn */ - CMP(4, ABSOLUTE_BYTE); - break; - - case 0xCE: /* DEC $nnnn */ - DEC(6, ABSOLUTE, mem_write, addr); - break; - - case 0xCF: /* DCP $nnnn */ - DCP(6, ABSOLUTE, mem_write, addr); - break; - - case 0xD0: /* BNE $nnnn */ - BNE(); - break; - - case 0xD1: /* CMP ($nn),Y */ - CMP(5, INDIR_Y_BYTE); - break; - - case 0xD3: /* DCP ($nn),Y */ - DCP(8, INDIR_Y, mem_write, addr); - break; - - case 0xD5: /* CMP $nn,X */ - CMP(4, ZP_IND_X_BYTE); - break; - - case 0xD6: /* DEC $nn,X */ - DEC(6, ZP_IND_X, ZP_WRITE, baddr); - break; - - case 0xD7: /* DCP $nn,X */ - DCP(6, ZP_IND_X, ZP_WRITE, baddr); - break; - - case 0xD8: /* CLD */ - CLD(); - break; - - case 0xD9: /* CMP $nnnn,Y */ - CMP(4, ABS_IND_Y_BYTE); - break; - - case 0xDB: /* DCP $nnnn,Y */ - DCP(7, ABS_IND_Y, mem_write, addr); - break; - - case 0xDD: /* CMP $nnnn,X */ - CMP(4, ABS_IND_X_BYTE); - break; - - case 0xDE: /* DEC $nnnn,X */ - DEC(7, ABS_IND_X, mem_write, addr); - break; - - case 0xDF: /* DCP $nnnn,X */ - DCP(7, ABS_IND_X, mem_write, addr); - break; - - case 0xE0: /* CPX #$nn */ - CPX(2, IMMEDIATE_BYTE); - break; - - case 0xE1: /* SBC ($nn,X) */ - SBC(6, INDIR_X_BYTE); - break; - - case 0xE3: /* ISB ($nn,X) */ - ISB(8, INDIR_X, mem_write, addr); - break; - - case 0xE4: /* CPX $nn */ - CPX(3, ZERO_PAGE_BYTE); - break; - - case 0xE5: /* SBC $nn */ - SBC(3, ZERO_PAGE_BYTE); - break; - - case 0xE6: /* INC $nn */ - INC(5, ZERO_PAGE, ZP_WRITE, baddr); - break; - - case 0xE7: /* ISB $nn */ - ISB(5, ZERO_PAGE, ZP_WRITE, baddr); - break; - - case 0xE8: /* INX */ - INX(); - break; - - case 0xE9: /* SBC #$nn */ - case 0xEB: /* USBC #$nn */ - SBC(2, IMMEDIATE_BYTE); - break; - - case 0xEA: /* NOP */ - NOP(); - break; - - case 0xEC: /* CPX $nnnn */ - CPX(4, ABSOLUTE_BYTE); - break; - - case 0xED: /* SBC $nnnn */ - SBC(4, ABSOLUTE_BYTE); - break; - - case 0xEE: /* INC $nnnn */ - INC(6, ABSOLUTE, mem_write, addr); - break; - - case 0xEF: /* ISB $nnnn */ - ISB(6, ABSOLUTE, mem_write, addr); - break; - - case 0xF0: /* BEQ $nnnn */ - BEQ(); - break; - - case 0xF1: /* SBC ($nn),Y */ - SBC(5, INDIR_Y_BYTE); - break; - - case 0xF3: /* ISB ($nn),Y */ - ISB(8, INDIR_Y, mem_write, addr); - break; - - case 0xF5: /* SBC $nn,X */ - SBC(4, ZP_IND_X_BYTE); - break; - - case 0xF6: /* INC $nn,X */ - INC(6, ZP_IND_X, ZP_WRITE, baddr); - break; - - case 0xF7: /* ISB $nn,X */ - ISB(6, ZP_IND_X, ZP_WRITE, baddr); - break; - - case 0xF8: /* SED */ - SED(); - break; - - case 0xF9: /* SBC $nnnn,Y */ - SBC(4, ABS_IND_Y_BYTE); - break; - - case 0xFB: /* ISB $nnnn,Y */ - ISB(7, ABS_IND_Y, mem_write, addr); - break; - - case 0xFD: /* SBC $nnnn,X */ - SBC(4, ABS_IND_X_BYTE); - break; - - case 0xFE: /* INC $nnnn,X */ - INC(7, ABS_IND_X, mem_write, addr); - break; - - case 0xFF: /* ISB $nnnn,X */ - ISB(7, ABS_IND_X, mem_write, addr); - break; - } - - /* Calculate remaining/elapsed clock cycles */ - remaining_cycles -= instruction_cycles; - total_cycles += instruction_cycles; - } - -_execute_done: - - /* restore local copy of regs */ - SET_LOCAL_REGS(); - - /* Return our actual amount of executed cycles */ - return (total_cycles - old_cycles); -} - -/* Initialize tables, etc. */ -void nes6502_init(void) -{ - int index; - - /* Build the N / Z flag lookup table */ - flag_table[0] = Z_FLAG; - - for (index = 1; index < 256; index++) - flag_table[index] = (index & 0x80) ? N_FLAG : 0; - - reg_A = reg_X = reg_Y = 0; - reg_S = 0xFF; /* Stack grows down */ -} - - -/* Issue a CPU Reset */ -void nes6502_reset(void) -{ - reg_P = Z_FLAG | R_FLAG | I_FLAG; /* Reserved bit always 1 */ - int_pending = dma_cycles = 0; /* No pending interrupts */ - reg_PC = bank_readaddress(RESET_VECTOR); /* Fetch reset vector */ - /* TODO: 6 cycles for RESET? */ -} - -/* Non-maskable interrupt */ -void nes6502_nmi(void) -{ - int_pending |= NMI_MASK; -} - -/* Interrupt request */ -void nes6502_irq(void) -{ - int_pending |= IRQ_MASK; -} - -/* Set dma period (in cycles) */ -void nes6502_setdma(int cycles) -{ - dma_cycles += cycles; -} - -#ifdef NES6502_MEM_ACCESS_CTRL -void nes6502_chk_mem_access(uint8 * access, int flags) -{ - chk_mem_access(access, flags); -} -#endif - -/* -** $Log: nes6502.c,v $ -** Revision 1.2 2003/05/01 22:34:19 benjihan -** New NSF plugin -** -** Revision 1.1 2003/04/08 20:53:00 ben -** Adding more files... -** -** Revision 1.6 2000/07/04 04:50:07 matt -** minor change to includes -** -** Revision 1.5 2000/07/03 02:18:16 matt -** added a few notes about potential failure cases -** -** Revision 1.4 2000/06/09 15:12:25 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/nes6502.h b/src/libxineadec/nosefart/nes6502.h deleted file mode 100644 index 8713304ec..000000000 --- a/src/libxineadec/nosefart/nes6502.h +++ /dev/null @@ -1,157 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** nes6502.h -** -** NES custom 6502 CPU definitions / prototypes -** $Id: nes6502.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ -*/ - -/* straitm */ -#include "types.h" - -/* NOTE: 16-bit addresses avoided like the plague: use 32-bit values -** wherever humanly possible -*/ -#ifndef _NES6502_H_ -#define _NES6502_H_ - -/* Define this to enable decimal mode in ADC / SBC (not needed in NES) */ -/*#define NES6502_DECIMAL*/ - -/* number of bank pointers the CPU emulation core handles */ -#ifdef NSF_PLAYER -#define NES6502_4KBANKS -#endif - -#ifdef NES6502_4KBANKS -#define NES6502_NUMBANKS 16 -#define NES6502_BANKSHIFT 12 -#else -#define NES6502_NUMBANKS 8 -#define NES6502_BANKSHIFT 13 -#endif - -#define NES6502_BANKMASK ((0x10000 / NES6502_NUMBANKS) - 1) - -/* Add memory access control flags. This is a ram shadow memory that holds - * for each memory bytes access flags for read, write and execute access. - * The nes6502_mem_access holds all new access (all mode all location). It is - * used to determine if the player has loop in playing time calculation. - */ -#ifdef NES6502_MEM_ACCESS_CTRL -extern uint8 nes6502_mem_access; -# define NES6502_READ_ACCESS 1 -# define NES6502_WRITE_ACCESS 2 -# define NES6502_EXE_ACCESS 4 -#endif /* #ifdef NES6502_MEM_ACCESS_CTRL */ - -/* P (flag) register bitmasks */ -#define N_FLAG 0x80 -#define V_FLAG 0x40 -#define R_FLAG 0x20 /* Reserved, always 1 */ -#define B_FLAG 0x10 -#define D_FLAG 0x08 -#define I_FLAG 0x04 -#define Z_FLAG 0x02 -#define C_FLAG 0x01 - -/* Vector addresses */ -#define NMI_VECTOR 0xFFFA -#define RESET_VECTOR 0xFFFC -#define IRQ_VECTOR 0xFFFE - -/* cycle counts for interrupts */ -#define INT_CYCLES 7 -#define RESET_CYCLES 6 - -#define NMI_MASK 0x01 -#define IRQ_MASK 0x02 - -/* Stack is located on 6502 page 1 */ -#define STACK_OFFSET 0x0100 - -typedef struct -{ - uint32 min_range, max_range; - uint8 (*read_func)(uint32 address); -} nes6502_memread; - -typedef struct -{ - uint32 min_range, max_range; - void (*write_func)(uint32 address, uint8 value); -} nes6502_memwrite; - -typedef struct -{ - uint8 * mem_page[NES6502_NUMBANKS]; /* memory page pointers */ -#ifdef NES6502_MEM_ACCESS_CTRL - uint8 * acc_mem_page[NES6502_NUMBANKS]; /* memory access page pointer */ -#endif - nes6502_memread *read_handler; - nes6502_memwrite *write_handler; - int dma_cycles; - uint32 pc_reg; - uint8 a_reg, p_reg, x_reg, y_reg, s_reg; - uint8 int_pending; -} nes6502_context; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Functions which govern the 6502's execution */ -extern void nes6502_init(void); -extern void nes6502_reset(void); -extern int nes6502_execute(int total_cycles); -extern void nes6502_nmi(void); -extern void nes6502_irq(void); -extern uint8 nes6502_getbyte(uint32 address); -extern uint32 nes6502_getcycles(boolean reset_flag); -extern void nes6502_setdma(int cycles); - -#ifdef NES6502_MEM_ACCESS_CTRL -extern void nes6502_chk_mem_access(uint8 * access, int flags); -#else -#define nes6502_chk_mem_access(access,flags) -#endif - -/* Context get/set */ -extern void nes6502_setcontext(nes6502_context *cpu); -extern void nes6502_getcontext(nes6502_context *cpu); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _NES6502_H_ */ - -/* -** $Log: nes6502.h,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources -** -** Revision 1.4 2000/06/09 15:12:25 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/nes_apu.c b/src/libxineadec/nosefart/nes_apu.c deleted file mode 100644 index 474e2ca1a..000000000 --- a/src/libxineadec/nosefart/nes_apu.c +++ /dev/null @@ -1,1256 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** nes_apu.c -** -** NES APU emulation -** $Id: nes_apu.c,v 1.4 2005/05/07 09:11:39 valtri Exp $ -*/ - -#include <string.h> -#include "types.h" -#include "log.h" -#include "nes_apu.h" -#include "nes6502.h" - -#ifdef NSF_PLAYER -#include "nsf.h" -#else -#include "nes.h" -#include "nes_ppu.h" -#include "nes_mmc.h" -#include "nesinput.h" -#endif /* !NSF_PLAYER */ - - -#define APU_OVERSAMPLE -#define APU_VOLUME_DECAY(x) ((x) -= ((x) >> 7)) - - -/* pointer to active APU */ -static apu_t *apu; - -/* look up table madness */ -static int32 decay_lut[16]; -static int vbl_lut[32]; -static int trilength_lut[128]; - -/* noise lookups for both modes */ -#ifndef REALTIME_NOISE -static int8 noise_long_lut[APU_NOISE_32K]; -static int8 noise_short_lut[APU_NOISE_93]; -#endif /* !REALTIME_NOISE */ - -/* $$$ ben : last error */ -#define SET_APU_ERROR(APU,X) \ -if (APU) (APU)->errstr = "apu: " X; else - -#define APU_MIX_ENABLE(BIT) (apu->mix_enable&(1<<(BIT))) - -/* vblank length table used for rectangles, triangle, noise */ -static const uint8 vbl_length[32] = -{ - 5, 127, - 10, 1, - 19, 2, - 40, 3, - 80, 4, - 30, 5, - 7, 6, - 13, 7, - 6, 8, - 12, 9, - 24, 10, - 48, 11, - 96, 12, - 36, 13, - 8, 14, - 16, 15 -}; - -/* frequency limit of rectangle channels */ -static const int freq_limit[8] = -{ - 0x3FF, 0x555, 0x666, 0x71C, 0x787, 0x7C1, 0x7E0, 0x7F0 -}; - -/* noise frequency lookup table */ -static const int noise_freq[16] = -{ - 4, 8, 16, 32, 64, 96, 128, 160, - 202, 254, 380, 508, 762, 1016, 2034, 4068 -}; - -/* DMC transfer freqs */ -const int dmc_clocks[16] = -{ - 428, 380, 340, 320, 286, 254, 226, 214, - 190, 160, 142, 128, 106, 85, 72, 54 -}; - -/* ratios of pos/neg pulse for rectangle waves */ -static const int duty_lut[4] = { 2, 4, 8, 12 }; - - -void apu_setcontext(apu_t *src_apu) -{ - apu = src_apu; - /* $$$ ben reset eoor string here. */ - SET_APU_ERROR(apu,"no error"); -} - -/* -** Simple queue routines -*/ -#define APU_QEMPTY() (apu->q_head == apu->q_tail) - -static int apu_enqueue(apudata_t *d) -{ - ASSERT(apu); - apu->queue[apu->q_head] = *d; - - apu->q_head = (apu->q_head + 1) & APUQUEUE_MASK; - - if (APU_QEMPTY()) { - log_printf("apu: queue overflow\n"); - SET_APU_ERROR(apu,"queue overflow"); - return -1; - } - return 0; -} - -static apudata_t *apu_dequeue(void) -{ - int loc; - - ASSERT(apu); - - if (APU_QEMPTY()) { - log_printf("apu: queue empty\n"); - SET_APU_ERROR(apu,"queue empty"); - /* $$$ ben : should return 0 ??? */ - } - loc = apu->q_tail; - apu->q_tail = (apu->q_tail + 1) & APUQUEUE_MASK; - - return &apu->queue[loc]; -} - -int apu_setchan(int chan, boolean enabled) -{ - const unsigned int max = 6; - int old; - - ASSERT(apu); - if ((unsigned int)chan >= max) { - SET_APU_ERROR(apu,"channel out of range"); - return -1; - } - old = (apu->mix_enable>>chan) & 1; - if (enabled != (boolean)-1) { - apu->mix_enable = (apu->mix_enable & ~(1<<chan)) | ((!!enabled)<<chan); - } - return old; -} - -/* emulation of the 15-bit shift register the -** NES uses to generate pseudo-random series -** for the white noise channel -*/ -#ifdef REALTIME_NOISE -INLINE int8 shift_register15(uint8 xor_tap) -{ - static int sreg = 0x4000; - int bit0, tap, bit14; - - bit0 = sreg & 1; - tap = (sreg & xor_tap) ? 1 : 0; - bit14 = (bit0 ^ tap); - sreg >>= 1; - sreg |= (bit14 << 14); - return (bit0 ^ 1); -} -#else -static void shift_register15(int8 *buf, int count) -{ - static int sreg = 0x4000; - int bit0, bit1, bit6, bit14; - - if (count == APU_NOISE_93) - { - while (count--) - { - bit0 = sreg & 1; - bit6 = (sreg & 0x40) >> 6; - bit14 = (bit0 ^ bit6); - sreg >>= 1; - sreg |= (bit14 << 14); - *buf++ = bit0 ^ 1; - } - } - else /* 32K noise */ - { - while (count--) - { - bit0 = sreg & 1; - bit1 = (sreg & 2) >> 1; - bit14 = (bit0 ^ bit1); - sreg >>= 1; - sreg |= (bit14 << 14); - *buf++ = bit0 ^ 1; - } - } -} -#endif - -/* RECTANGLE WAVE -** ============== -** reg0: 0-3=volume, 4=envelope, 5=hold, 6-7=duty cycle -** reg1: 0-2=sweep shifts, 3=sweep inc/dec, 4-6=sweep length, 7=sweep on -** reg2: 8 bits of freq -** reg3: 0-2=high freq, 7-4=vbl length counter -*/ -#define APU_RECTANGLE_OUTPUT chan->output_vol -static int32 apu_rectangle(rectangle_t *chan) -{ - int32 output; - -#ifdef APU_OVERSAMPLE - int num_times; - int32 total; -#endif - - APU_VOLUME_DECAY(chan->output_vol); - - if (FALSE == chan->enabled || 0 == chan->vbl_length) - return APU_RECTANGLE_OUTPUT; - - /* vbl length counter */ - if (FALSE == chan->holdnote) - chan->vbl_length--; - - /* envelope decay at a rate of (env_delay + 1) / 240 secs */ - chan->env_phase -= 4; /* 240/60 */ - while (chan->env_phase < 0) - { - chan->env_phase += chan->env_delay; - - if (chan->holdnote) - chan->env_vol = (chan->env_vol + 1) & 0x0F; - else if (chan->env_vol < 0x0F) - chan->env_vol++; - } - - if ((FALSE == chan->sweep_inc && chan->freq > chan->freq_limit) - || chan->freq < APU_TO_FIXED(4)) - return APU_RECTANGLE_OUTPUT; - - /* frequency sweeping at a rate of (sweep_delay + 1) / 120 secs */ - if (chan->sweep_on && chan->sweep_shifts) - { - chan->sweep_phase -= 2; /* 120/60 */ - while (chan->sweep_phase < 0) - { - chan->sweep_phase += chan->sweep_delay; - if (chan->sweep_inc) /* ramp up */ - chan->freq -= chan->freq >> (chan->sweep_shifts); - else /* ramp down */ - chan->freq += chan->freq >> (chan->sweep_shifts); - } - } - - chan->phaseacc -= apu->cycle_rate; /* # of cycles per sample */ - if (chan->phaseacc >= 0) - return APU_RECTANGLE_OUTPUT; - -#ifdef APU_OVERSAMPLE - num_times = total = 0; - - if (chan->fixed_envelope) - output = chan->volume << 8; /* fixed volume */ - else - output = (chan->env_vol ^ 0x0F) << 8; -#endif - - while (chan->phaseacc < 0) - { - chan->phaseacc += chan->freq; - chan->adder = (chan->adder + 1) & 0x0F; - -#ifdef APU_OVERSAMPLE - if (chan->adder < chan->duty_flip) - total += output; - else - total -= output; - - num_times++; -#endif - } - -#ifdef APU_OVERSAMPLE - chan->output_vol = total / num_times; -#else - if (chan->fixed_envelope) - output = chan->volume << 8; /* fixed volume */ - else - output = (chan->env_vol ^ 0x0F) << 8; - - if (0 == chan->adder) - chan->output_vol = output; - else if (chan->adder == chan->duty_flip) - chan->output_vol = -output; -#endif - - return APU_RECTANGLE_OUTPUT; -} - -/* TRIANGLE WAVE -** ============= -** reg0: 7=holdnote, 6-0=linear length counter -** reg2: low 8 bits of frequency -** reg3: 7-3=length counter, 2-0=high 3 bits of frequency -*/ -#define APU_TRIANGLE_OUTPUT (chan->output_vol + (chan->output_vol >> 2)) -static int32 apu_triangle(triangle_t *chan) -{ - APU_VOLUME_DECAY(chan->output_vol); - - if (FALSE == chan->enabled || 0 == chan->vbl_length) - return APU_TRIANGLE_OUTPUT; - - if (chan->counter_started) - { - if (chan->linear_length > 0) - chan->linear_length--; - if (chan->vbl_length && FALSE == chan->holdnote) - chan->vbl_length--; - } - else if (FALSE == chan->holdnote && chan->write_latency) - { - if (--chan->write_latency == 0) - chan->counter_started = TRUE; - } -/* - if (chan->countmode == COUNTMODE_COUNT) - { - if (chan->linear_length > 0) - chan->linear_length--; - if (chan->vbl_length) - chan->vbl_length--; - } -*/ - if (0 == chan->linear_length || chan->freq < APU_TO_FIXED(4)) /* inaudible */ - return APU_TRIANGLE_OUTPUT; - - chan->phaseacc -= apu->cycle_rate; /* # of cycles per sample */ - while (chan->phaseacc < 0) - { - chan->phaseacc += chan->freq; - chan->adder = (chan->adder + 1) & 0x1F; - - if (chan->adder & 0x10) - chan->output_vol -= (2 << 8); - else - chan->output_vol += (2 << 8); - } - - return APU_TRIANGLE_OUTPUT; -} - - -/* WHITE NOISE CHANNEL -** =================== -** reg0: 0-3=volume, 4=envelope, 5=hold -** reg2: 7=small(93 byte) sample,3-0=freq lookup -** reg3: 7-4=vbl length counter -*/ -#define APU_NOISE_OUTPUT ((chan->output_vol + chan->output_vol + chan->output_vol) >> 2) - -static int32 apu_noise(noise_t *chan) -{ - int32 outvol; - -#if defined(APU_OVERSAMPLE) && defined(REALTIME_NOISE) -#else - int32 noise_bit; -#endif -#ifdef APU_OVERSAMPLE - int num_times; - int32 total; -#endif - - APU_VOLUME_DECAY(chan->output_vol); - - if (FALSE == chan->enabled || 0 == chan->vbl_length) - return APU_NOISE_OUTPUT; - - /* vbl length counter */ - if (FALSE == chan->holdnote) - chan->vbl_length--; - - /* envelope decay at a rate of (env_delay + 1) / 240 secs */ - chan->env_phase -= 4; /* 240/60 */ - while (chan->env_phase < 0) - { - chan->env_phase += chan->env_delay; - - if (chan->holdnote) - chan->env_vol = (chan->env_vol + 1) & 0x0F; - else if (chan->env_vol < 0x0F) - chan->env_vol++; - } - - chan->phaseacc -= apu->cycle_rate; /* # of cycles per sample */ - if (chan->phaseacc >= 0) - return APU_NOISE_OUTPUT; - -#ifdef APU_OVERSAMPLE - num_times = total = 0; - - if (chan->fixed_envelope) - outvol = chan->volume << 8; /* fixed volume */ - else - outvol = (chan->env_vol ^ 0x0F) << 8; -#endif - - while (chan->phaseacc < 0) - { - chan->phaseacc += chan->freq; - -#ifdef REALTIME_NOISE - -#ifdef APU_OVERSAMPLE - if (shift_register15(chan->xor_tap)) - total += outvol; - else - total -= outvol; - - num_times++; -#else - noise_bit = shift_register15(chan->xor_tap); -#endif - -#else - chan->cur_pos++; - - if (chan->short_sample) - { - if (APU_NOISE_93 == chan->cur_pos) - chan->cur_pos = 0; - } - else - { - if (APU_NOISE_32K == chan->cur_pos) - chan->cur_pos = 0; - } - -#ifdef APU_OVERSAMPLE - if (chan->short_sample) - noise_bit = noise_short_lut[chan->cur_pos]; - else - noise_bit = noise_long_lut[chan->cur_pos]; - - if (noise_bit) - total += outvol; - else - total -= outvol; - - num_times++; -#endif -#endif /* REALTIME_NOISE */ - } - -#ifdef APU_OVERSAMPLE - chan->output_vol = total / num_times; -#else - if (chan->fixed_envelope) - outvol = chan->volume << 8; /* fixed volume */ - else - outvol = (chan->env_vol ^ 0x0F) << 8; - -#ifndef REALTIME_NOISE - if (chan->short_sample) - noise_bit = noise_short_lut[chan->cur_pos]; - else - noise_bit = noise_long_lut[chan->cur_pos]; -#endif /* !REALTIME_NOISE */ - - if (noise_bit) - chan->output_vol = outvol; - else - chan->output_vol = -outvol; -#endif - - return APU_NOISE_OUTPUT; -} - - -INLINE void apu_dmcreload(dmc_t *chan) -{ - chan->address = chan->cached_addr; - chan->dma_length = chan->cached_dmalength; - chan->irq_occurred = FALSE; -} - -/* DELTA MODULATION CHANNEL -** ========================= -** reg0: 7=irq gen, 6=looping, 3-0=pointer to clock table -** reg1: output dc level, 6 bits unsigned -** reg2: 8 bits of 64-byte aligned address offset : $C000 + (value * 64) -** reg3: length, (value * 16) + 1 -*/ -#define APU_DMC_OUTPUT ((chan->output_vol + chan->output_vol + chan->output_vol) >> 2) -static int32 apu_dmc(dmc_t *chan) -{ - int delta_bit; - - APU_VOLUME_DECAY(chan->output_vol); - - /* only process when channel is alive */ - if (chan->dma_length) - { - chan->phaseacc -= apu->cycle_rate; /* # of cycles per sample */ - - while (chan->phaseacc < 0) - { - chan->phaseacc += chan->freq; - - delta_bit = (chan->dma_length & 7) ^ 7; - - if (7 == delta_bit) - { - chan->cur_byte = nes6502_getbyte(chan->address); - - /* steal a cycle from CPU*/ - nes6502_setdma(1); - - if (0xFFFF == chan->address) - chan->address = 0x8000; - else - chan->address++; - } - - if (--chan->dma_length == 0) - { - /* if loop bit set, we're cool to retrigger sample */ - if (chan->looping) - apu_dmcreload(chan); - else - { - /* check to see if we should generate an irq */ - if (chan->irq_gen) - { - chan->irq_occurred = TRUE; - nes6502_irq(); - } - - /* bodge for timestamp queue */ - chan->enabled = FALSE; - break; - } - } - - /* positive delta */ - if (chan->cur_byte & (1 << delta_bit)) - { - if (chan->regs[1] < 0x7D) - { - chan->regs[1] += 2; - chan->output_vol += (2 << 8); - } -/* - if (chan->regs[1] < 0x3F) - chan->regs[1]++; - - chan->output_vol &= ~(0x7E << 8); - chan->output_vol |= ((chan->regs[1] << 1) << 8); -*/ - } - /* negative delta */ - else - { - if (chan->regs[1] > 1) - { - chan->regs[1] -= 2; - chan->output_vol -= (2 << 8); - } - -/* - if (chan->regs[1] > 0) - chan->regs[1]--; - - chan->output_vol &= ~(0x7E << 8); - chan->output_vol |= ((chan->regs[1] << 1) << 8); -*/ - } - } - } - - return APU_DMC_OUTPUT; -} - - -static void apu_regwrite(uint32 address, uint8 value) -{ - int chan; - - ASSERT(apu); - switch (address) - { - /* rectangles */ - case APU_WRA0: - case APU_WRB0: - chan = (address & 4) ? 1 : 0; - apu->rectangle[chan].regs[0] = value; - - apu->rectangle[chan].volume = value & 0x0F; - apu->rectangle[chan].env_delay = decay_lut[value & 0x0F]; - apu->rectangle[chan].holdnote = (value & 0x20) ? TRUE : FALSE; - apu->rectangle[chan].fixed_envelope = (value & 0x10) ? TRUE : FALSE; - apu->rectangle[chan].duty_flip = duty_lut[value >> 6]; - break; - - case APU_WRA1: - case APU_WRB1: - chan = (address & 4) ? 1 : 0; - apu->rectangle[chan].regs[1] = value; - apu->rectangle[chan].sweep_on = (value & 0x80) ? TRUE : FALSE; - apu->rectangle[chan].sweep_shifts = value & 7; - apu->rectangle[chan].sweep_delay = decay_lut[(value >> 4) & 7]; - - apu->rectangle[chan].sweep_inc = (value & 0x08) ? TRUE : FALSE; - apu->rectangle[chan].freq_limit = APU_TO_FIXED(freq_limit[value & 7]); - break; - - case APU_WRA2: - case APU_WRB2: - chan = (address & 4) ? 1 : 0; - apu->rectangle[chan].regs[2] = value; -// if (apu->rectangle[chan].enabled) - apu->rectangle[chan].freq = APU_TO_FIXED((((apu->rectangle[chan].regs[3] & 7) << 8) + value) + 1); - break; - - case APU_WRA3: - case APU_WRB3: - chan = (address & 4) ? 1 : 0; - apu->rectangle[chan].regs[3] = value; - -// if (apu->rectangle[chan].enabled) - { - apu->rectangle[chan].vbl_length = vbl_lut[value >> 3]; - apu->rectangle[chan].env_vol = 0; - apu->rectangle[chan].freq = APU_TO_FIXED((((value & 7) << 8) + apu->rectangle[chan].regs[2]) + 1); - apu->rectangle[chan].adder = 0; - } - break; - - /* triangle */ - case APU_WRC0: -/* - if (0 == (apu->triangle.regs[0] & 0x80)) - apu->triangle.countmode = COUNTMODE_COUNT; - else - { - if (apu->triangle.countmode == COUNTMODE_LOAD && apu->triangle.vbl_length) - apu->triangle.linear_length = trilength_lut[value & 0x7F]; - - if (0 == (value & 0x80)) - apu->triangle.countmode = COUNTMODE_COUNT; - } -*/ - apu->triangle.regs[0] = value; - - apu->triangle.holdnote = (value & 0x80) ? TRUE : FALSE; - - -// if (apu->triangle.enabled) - { - if (FALSE == apu->triangle.counter_started && apu->triangle.vbl_length) - apu->triangle.linear_length = trilength_lut[value & 0x7F]; - } - - break; - - case APU_WRC2: - - apu->triangle.regs[1] = value; - -// if (apu->triangle.enabled) - apu->triangle.freq = APU_TO_FIXED((((apu->triangle.regs[2] & 7) << 8) + value) + 1); - break; - - case APU_WRC3: - - apu->triangle.regs[2] = value; - - /* this is somewhat of a hack. there appears to be some latency on - ** the Real Thing between when trireg0 is written to and when the - ** linear length counter actually begins its countdown. we want to - ** prevent the case where the program writes to the freq regs first, - ** then to reg 0, and the counter accidentally starts running because - ** of the sound queue's timestamp processing. - ** - ** set latency to a couple scanlines -- should be plenty of time for - ** the 6502 code to do a couple of table dereferences and load up the - ** other triregs - */ - - /* 06/13/00 MPC -- seems to work OK */ - apu->triangle.write_latency = (int) (2 * NES_SCANLINE_CYCLES / APU_FROM_FIXED(apu->cycle_rate)); -/* - apu->triangle.linear_length = trilength_lut[apu->triangle.regs[0] & 0x7F]; - if (0 == (apu->triangle.regs[0] & 0x80)) - apu->triangle.countmode = COUNTMODE_COUNT; - else - apu->triangle.countmode = COUNTMODE_LOAD; -*/ -// if (apu->triangle.enabled) - { - apu->triangle.freq = APU_TO_FIXED((((value & 7) << 8) + apu->triangle.regs[1]) + 1); - apu->triangle.vbl_length = vbl_lut[value >> 3]; - apu->triangle.counter_started = FALSE; - apu->triangle.linear_length = trilength_lut[apu->triangle.regs[0] & 0x7F]; - } - - break; - - /* noise */ - case APU_WRD0: - apu->noise.regs[0] = value; - apu->noise.env_delay = decay_lut[value & 0x0F]; - apu->noise.holdnote = (value & 0x20) ? TRUE : FALSE; - apu->noise.fixed_envelope = (value & 0x10) ? TRUE : FALSE; - apu->noise.volume = value & 0x0F; - break; - - case APU_WRD2: - apu->noise.regs[1] = value; - apu->noise.freq = APU_TO_FIXED(noise_freq[value & 0x0F]); - -#ifdef REALTIME_NOISE - apu->noise.xor_tap = (value & 0x80) ? 0x40: 0x02; -#else - /* detect transition from long->short sample */ - if ((value & 0x80) && FALSE == apu->noise.short_sample) - { - /* recalculate short noise buffer */ - shift_register15(noise_short_lut, APU_NOISE_93); - apu->noise.cur_pos = 0; - } - apu->noise.short_sample = (value & 0x80) ? TRUE : FALSE; -#endif - break; - - case APU_WRD3: - apu->noise.regs[2] = value; - -// if (apu->noise.enabled) - { - apu->noise.vbl_length = vbl_lut[value >> 3]; - apu->noise.env_vol = 0; /* reset envelope */ - } - break; - - /* DMC */ - case APU_WRE0: - apu->dmc.regs[0] = value; - - apu->dmc.freq = APU_TO_FIXED(dmc_clocks[value & 0x0F]); - apu->dmc.looping = (value & 0x40) ? TRUE : FALSE; - - if (value & 0x80) - apu->dmc.irq_gen = TRUE; - else - { - apu->dmc.irq_gen = FALSE; - apu->dmc.irq_occurred = FALSE; - } - break; - - case APU_WRE1: /* 7-bit DAC */ - /* add the _delta_ between written value and - ** current output level of the volume reg - */ - value &= 0x7F; /* bit 7 ignored */ - apu->dmc.output_vol += ((value - apu->dmc.regs[1]) << 8); - apu->dmc.regs[1] = value; -/* - apu->dmc.output_vol = (value & 0x7F) << 8; - apu->dmc.regs[1] = (value & 0x7E) >> 1; -*/ - break; - - case APU_WRE2: - apu->dmc.regs[2] = value; - apu->dmc.cached_addr = 0xC000 + (uint16) (value << 6); - break; - - case APU_WRE3: - apu->dmc.regs[3] = value; - apu->dmc.cached_dmalength = ((value << 4) + 1) << 3; - break; - - case APU_SMASK: - /* bodge for timestamp queue */ - apu->dmc.enabled = (value & 0x10) ? TRUE : FALSE; - - apu->enable_reg = value; - - for (chan = 0; chan < 2; chan++) - { - if (value & (1 << chan)) - apu->rectangle[chan].enabled = TRUE; - else - { - apu->rectangle[chan].enabled = FALSE; - apu->rectangle[chan].vbl_length = 0; - } - } - - if (value & 0x04) - apu->triangle.enabled = TRUE; - else - { - apu->triangle.enabled = FALSE; - apu->triangle.vbl_length = 0; - apu->triangle.linear_length = 0; - apu->triangle.counter_started = FALSE; - apu->triangle.write_latency = 0; - } - - if (value & 0x08) - apu->noise.enabled = TRUE; - else - { - apu->noise.enabled = FALSE; - apu->noise.vbl_length = 0; - } - - if (value & 0x10) - { - if (0 == apu->dmc.dma_length) - apu_dmcreload(&apu->dmc); - } - else - apu->dmc.dma_length = 0; - - apu->dmc.irq_occurred = FALSE; - break; - - /* unused, but they get hit in some mem-clear loops */ - case 0x4009: - case 0x400D: - break; - - default: - break; - } -} - -/* Read from $4000-$4017 */ -uint8 apu_read(uint32 address) -{ - uint8 value; - - ASSERT(apu); - - switch (address) - { - case APU_SMASK: - /* seems that bit 6 denotes vblank -- return 1 for now */ - value = 0x40; - - /* Return 1 in 0-5 bit pos if a channel is playing */ - if (apu->rectangle[0].enabled && apu->rectangle[0].vbl_length) - value |= 0x01; - if (apu->rectangle[1].enabled && apu->rectangle[1].vbl_length) - value |= 0x02; - if (apu->triangle.enabled && apu->triangle.vbl_length) - value |= 0x04; - if (apu->noise.enabled && apu->noise.vbl_length) - value |= 0x08; - - //if (apu->dmc.dma_length) - /* bodge for timestamp queue */ - if (apu->dmc.enabled) - value |= 0x10; - - if (apu->dmc.irq_occurred) - value |= 0x80; - - break; - -#ifndef NSF_PLAYER - case APU_JOY0: - value = input_get(INP_JOYPAD0); - break; - - case APU_JOY1: - value = input_get(INP_ZAPPER | INP_JOYPAD1 /*| INP_ARKANOID*/ /*| INP_POWERPAD*/); - break; -#endif /* !NSF_PLAYER */ - - default: - value = (address >> 8); /* heavy capacitance on data bus */ - break; - } - - return value; -} - - -void apu_write(uint32 address, uint8 value) -{ -#ifndef NSF_PLAYER - static uint8 last_write; -#endif /* !NSF_PLAYER */ - apudata_t d; - - switch (address) - { - case 0x4015: - /* bodge for timestamp queue */ - apu->dmc.enabled = (value & 0x10) ? TRUE : FALSE; - - case 0x4000: case 0x4001: case 0x4002: case 0x4003: - case 0x4004: case 0x4005: case 0x4006: case 0x4007: - case 0x4008: case 0x4009: case 0x400A: case 0x400B: - case 0x400C: case 0x400D: case 0x400E: case 0x400F: - case 0x4010: case 0x4011: case 0x4012: case 0x4013: - d.timestamp = nes6502_getcycles(FALSE); - d.address = address; - d.value = value; - apu_enqueue(&d); - break; - -#ifndef NSF_PLAYER - case APU_OAMDMA: - ppu_oamdma(address, value); - break; - - case APU_JOY0: - /* VS system VROM switching */ - mmc_vsvrom(value & 4); - - /* see if we need to strobe them joypads */ - value &= 1; - if ((0 == value) && last_write) - input_strobe(); - last_write = value; - break; - - case APU_JOY1: /* Some kind of IRQ control business */ - break; - -#endif /* !NSF_PLAYER */ - - default: - break; - } -} - -void apu_getpcmdata(void **data, int *num_samples, int *sample_bits) -{ - ASSERT(apu); - *data = apu->buffer; - *num_samples = apu->num_samples; - *sample_bits = apu->sample_bits; -} - - -void apu_process(void *buffer, int num_samples) -{ - apudata_t *d; - uint32 elapsed_cycles; - static int32 prev_sample = 0; - int32 next_sample, accum; - - ASSERT(apu); - - /* grab it, keep it local for speed */ - elapsed_cycles = (uint32) apu->elapsed_cycles; - - /* BLEH */ - apu->buffer = buffer; - - while (num_samples--) - { - while ((FALSE == APU_QEMPTY()) && (apu->queue[apu->q_tail].timestamp <= elapsed_cycles)) - { - d = apu_dequeue(); - apu_regwrite(d->address, d->value); - } - - elapsed_cycles += APU_FROM_FIXED(apu->cycle_rate); - - accum = 0; - if (APU_MIX_ENABLE(0)) accum += apu_rectangle(&apu->rectangle[0]); - if (APU_MIX_ENABLE(1)) accum += apu_rectangle(&apu->rectangle[1]); - if (APU_MIX_ENABLE(2)) accum += apu_triangle(&apu->triangle); - if (APU_MIX_ENABLE(3)) accum += apu_noise(&apu->noise); - if (APU_MIX_ENABLE(4)) accum += apu_dmc(&apu->dmc); - - if (apu->ext && APU_MIX_ENABLE(5)) accum += apu->ext->process(); - - /* do any filtering */ - if (APU_FILTER_NONE != apu->filter_type) - { - next_sample = accum; - - if (APU_FILTER_LOWPASS == apu->filter_type) - { - accum += prev_sample; - accum >>= 1; - } - else - accum = (accum + accum + accum + prev_sample) >> 2; - - prev_sample = next_sample; - } - - /* little extra kick for the kids */ - accum <<= 1; - - /* prevent clipping */ - if (accum > 0x7FFF) - accum = 0x7FFF; - else if (accum < -0x8000) - accum = -0x8000; - - /* signed 16-bit output, unsigned 8-bit */ - if (16 == apu->sample_bits) { - *(int16 *)(buffer) = (int16) accum; - buffer += sizeof(int16); - } - else { - *(uint8 *)(buffer) = (accum >> 8) ^ 0x80; - buffer += sizeof(uint8); - } - } - - /* resync cycle counter */ - apu->elapsed_cycles = nes6502_getcycles(FALSE); -} - -/* set the filter type */ -/* $$$ ben : - * Add a get feature (filter_type == -1) and returns old filter type - */ -int apu_setfilter(int filter_type) -{ - int old; - ASSERT(apu); - old = apu->filter_type; - if (filter_type != -1) { - apu->filter_type = filter_type; - } - return old; -} - -void apu_reset(void) -{ - uint32 address; - - ASSERT(apu); - - apu->elapsed_cycles = 0; - memset(&apu->queue, 0, APUQUEUE_SIZE * sizeof(apudata_t)); - apu->q_head = 0; - apu->q_tail = 0; - - /* use to avoid bugs =) */ - for (address = 0x4000; address <= 0x4013; address++) - apu_regwrite(address, 0); - -#ifdef NSF_PLAYER - apu_regwrite(0x400C, 0x10); /* silence noise channel on NSF start */ - apu_regwrite(0x4015, 0x0F); -#else - apu_regwrite(0x4015, 0); -#endif /* NSF_PLAYER */ - - if (apu->ext) - apu->ext->reset(); -} - -void apu_build_luts(int num_samples) -{ - int i; - - /* lut used for enveloping and frequency sweeps */ - for (i = 0; i < 16; i++) - decay_lut[i] = num_samples * (i + 1); - - /* used for note length, based on vblanks and size of audio buffer */ - for (i = 0; i < 32; i++) - vbl_lut[i] = vbl_length[i] * num_samples; - - /* triangle wave channel's linear length table */ - for (i = 0; i < 128; i++) - trilength_lut[i] = (i * num_samples) / 4; - -#ifndef REALTIME_NOISE - /* generate noise samples */ - shift_register15(noise_long_lut, APU_NOISE_32K); - shift_register15(noise_short_lut, APU_NOISE_93); -#endif /* !REALTIME_NOISE */ -} - -static void apu_setactive(apu_t *active) -{ - ASSERT(active); - apu = active; -} - -/* Initializes emulated sound hardware, creates waveforms/voices */ -apu_t *apu_create(int sample_rate, int refresh_rate, int sample_bits, boolean stereo) -{ - apu_t *temp_apu; -/* int channel; */ - - temp_apu = malloc(sizeof(apu_t)); - if (NULL == temp_apu) - return NULL; - /* $$$ ben : safety net, in case we forgot to init something */ - memset(temp_apu,0,sizeof(apu_t)); - - SET_APU_ERROR(temp_apu,"no error"); - temp_apu->sample_rate = sample_rate; - temp_apu->refresh_rate = refresh_rate; - temp_apu->sample_bits = sample_bits; - - temp_apu->num_samples = sample_rate / refresh_rate; - /* turn into fixed point! */ - temp_apu->cycle_rate = (int32) (APU_BASEFREQ * 65536.0 / (float) sample_rate); - - /* build various lookup tables for apu */ - apu_build_luts(temp_apu->num_samples); - - /* set the update routine */ - temp_apu->process = apu_process; - temp_apu->ext = NULL; - - apu_setactive(temp_apu); - apu_reset(); - - temp_apu->mix_enable = 0x3F; -/* for (channel = 0; channel < 6; channel++) */ -/* apu_setchan(channel, TRUE); */ - - apu_setfilter(APU_FILTER_LOWPASS); - - return temp_apu; -} - -apu_t *apu_getcontext(void) -{ - return apu; -} - -void apu_destroy(apu_t *src_apu) -{ - if (src_apu) - { - if (src_apu->ext) - src_apu->ext->shutdown(); - free(src_apu); - } -} - -int apu_setext(apu_t *src_apu, apuext_t *ext) -{ - ASSERT(src_apu); - - /* $$$ ben : seem cleaner like this */ - if (src_apu->ext) { - src_apu->ext->shutdown(); - } - - src_apu->ext = ext; - - /* initialize it */ - if (src_apu->ext) - src_apu->ext->init(); - - /* $$$ ben : May be one day extension int () will return error code */ - return 0; -} - -/* this exists for external mixing routines */ -int32 apu_getcyclerate(void) -{ - ASSERT(apu); - return apu->cycle_rate; -} - -/* -** $Log: nes_apu.c,v $ -** Revision 1.4 2005/05/07 09:11:39 valtri -** *BUGFIX* -** gcc4 patches from Dams Nadé (livna.org) and Keenan Pepper. -** -** Revision 1.3 2004/12/12 06:55:59 athp -** Code cleanups and elimination of some compiler warnings; patch courtesy of AL13N -** -** Revision 1.2 2003/08/25 21:51:43 f1rmb -** Reduce GCC verbosity (various prototype declaration fixes). ffmpeg, wine and fft*post are untouched (fft: for now). -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources -** -** Revision 1.19 2000/07/04 04:53:26 matt -** minor changes, sound amplification -** -** Revision 1.18 2000/07/03 02:18:53 matt -** much better external module exporting -** -** Revision 1.17 2000/06/26 11:01:55 matt -** made triangle a tad quieter -** -** Revision 1.16 2000/06/26 05:10:33 matt -** fixed cycle rate generation accuracy -** -** Revision 1.15 2000/06/26 05:00:37 matt -** cleanups -** -** Revision 1.14 2000/06/23 11:06:24 matt -** more faithful mixing of channels -** -** Revision 1.13 2000/06/23 03:29:27 matt -** cleaned up external sound inteface -** -** Revision 1.12 2000/06/20 00:08:39 matt -** bugfix to rectangle wave -** -** Revision 1.11 2000/06/13 13:48:58 matt -** fixed triangle write latency for fixed point apu cycle rate -** -** Revision 1.10 2000/06/12 01:14:36 matt -** minor change to clipping extents -** -** Revision 1.9 2000/06/09 20:00:56 matt -** fixed noise hiccup in NSF player mode -** -** Revision 1.8 2000/06/09 16:49:02 matt -** removed all floating point from sound generation -** -** Revision 1.7 2000/06/09 15:12:28 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/nes_apu.h b/src/libxineadec/nosefart/nes_apu.h deleted file mode 100644 index 9efbb560e..000000000 --- a/src/libxineadec/nosefart/nes_apu.h +++ /dev/null @@ -1,335 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** nes_apu.h -** -** NES APU emulation header file -** $Id: nes_apu.h,v 1.2 2003/01/09 19:50:03 jkeil Exp $ -*/ - -#ifndef _NES_APU_H_ -#define _NES_APU_H_ - -#ifdef __GNUC__ -#define INLINE static inline -#elif defined(WIN32) -#define INLINE static __inline -#else -#define INLINE static -#endif - -/* define this for realtime generated noise */ -#define REALTIME_NOISE - -#define APU_WRA0 0x4000 -#define APU_WRA1 0x4001 -#define APU_WRA2 0x4002 -#define APU_WRA3 0x4003 -#define APU_WRB0 0x4004 -#define APU_WRB1 0x4005 -#define APU_WRB2 0x4006 -#define APU_WRB3 0x4007 -#define APU_WRC0 0x4008 -#define APU_WRC2 0x400A -#define APU_WRC3 0x400B -#define APU_WRD0 0x400C -#define APU_WRD2 0x400E -#define APU_WRD3 0x400F -#define APU_WRE0 0x4010 -#define APU_WRE1 0x4011 -#define APU_WRE2 0x4012 -#define APU_WRE3 0x4013 - -#define APU_OAMDMA 0x4014 -#define APU_SMASK 0x4015 -#define APU_JOY0 0x4016 -#define APU_JOY1 0x4017 - -/* length of generated noise */ -#define APU_NOISE_32K 0x7FFF -#define APU_NOISE_93 93 - -#define APU_BASEFREQ (NES_MASTER_CLOCK / 12) - -/* to/from 16.16 fixed point */ -#define APU_TO_FIXED(x) ((x) << 16) -#define APU_FROM_FIXED(x) ((x) >> 16) - - -/* channel structures */ -/* As much data as possible is precalculated, -** to keep the sample processing as lean as possible -*/ - -typedef struct rectangle_s -{ - uint8 regs[4]; - - boolean enabled; - - int32 phaseacc; - int32 freq; - int32 output_vol; - boolean fixed_envelope; - boolean holdnote; - uint8 volume; - - int32 sweep_phase; - int32 sweep_delay; - boolean sweep_on; - uint8 sweep_shifts; - uint8 sweep_length; - boolean sweep_inc; - int32 freq_limit; - - int32 env_phase; - int32 env_delay; - uint8 env_vol; - - int vbl_length; - uint8 adder; - int duty_flip; -} rectangle_t; - -/* -enum -{ - COUNTMODE_LOAD, - COUNTMODE_COUNT -}; -*/ - -typedef struct triangle_s -{ - uint8 regs[3]; - - boolean enabled; - - int32 freq; - int32 phaseacc; - int32 output_vol; - - uint8 adder; - - boolean holdnote; - boolean counter_started; - /* quasi-hack */ - int write_latency; - -// boolean countmode; - - int vbl_length; - int linear_length; - -} triangle_t; - - -typedef struct noise_s -{ - uint8 regs[3]; - - boolean enabled; - - int32 freq; - int32 phaseacc; - int32 output_vol; - - int32 env_phase; - int32 env_delay; - uint8 env_vol; - boolean fixed_envelope; - boolean holdnote; - - uint8 volume; - - int vbl_length; - -#ifdef REALTIME_NOISE - uint8 xor_tap; -#else - boolean short_sample; - int cur_pos; -#endif /* REALTIME_NOISE */ -} noise_t; - -typedef struct dmc_s -{ - uint8 regs[4]; - - /* bodge for timestamp queue */ - boolean enabled; - - int32 freq; - int32 phaseacc; - int32 output_vol; - - uint32 address; - uint32 cached_addr; - int dma_length; - int cached_dmalength; - uint8 cur_byte; - - boolean looping; - boolean irq_gen; - boolean irq_occurred; - -} dmc_t; - -enum -{ - APU_FILTER_NONE, - APU_FILTER_LOWPASS, - APU_FILTER_WEIGHTED -}; - -typedef struct -{ - uint32 min_range, max_range; - uint8 (*read_func)(uint32 address); -} apu_memread; - -typedef struct -{ - uint32 min_range, max_range; - void (*write_func)(uint32 address, uint8 value); -} apu_memwrite; - -/* external sound chip stuff */ -typedef struct apuext_s -{ - void (*init)(void); - void (*shutdown)(void); - void (*reset)(void); - int32 (*process)(void); - apu_memread *mem_read; - apu_memwrite *mem_write; -} apuext_t; - - -/* APU queue structure */ -#define APUQUEUE_SIZE 4096 -#define APUQUEUE_MASK (APUQUEUE_SIZE - 1) - -/* apu ring buffer member */ -typedef struct apudata_s -{ - uint32 timestamp, address; - uint8 value; -} apudata_t; - - -typedef struct apu_s -{ - rectangle_t rectangle[2]; - triangle_t triangle; - noise_t noise; - dmc_t dmc; - uint8 enable_reg; - - apudata_t queue[APUQUEUE_SIZE]; - int q_head, q_tail; - uint32 elapsed_cycles; - - void *buffer; /* pointer to output buffer */ - int num_samples; - - int mix_enable; /* $$$ben : should improve emulation */ - int filter_type; - - int32 cycle_rate; - - int sample_rate; - int sample_bits; - int refresh_rate; - - void (*process)(void *buffer, int num_samples); - - /* $$$ ben : last error string */ - const char * errstr; - - /* external sound chip */ - apuext_t *ext; -} apu_t; - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Function prototypes */ -extern apu_t *apu_create(int sample_rate, int refresh_rate, int sample_bits, boolean stereo); -extern void apu_destroy(apu_t *apu); -extern int apu_setext(apu_t *apu, apuext_t *ext); -extern int apu_setfilter(int filter_type); -extern void apu_process(void *buffer, int num_samples); -extern void apu_reset(void); -extern int apu_setchan(int chan, boolean enabled); -extern int32 apu_getcyclerate(void); -extern apu_t *apu_getcontext(void); - -extern uint8 apu_read(uint32 address); -extern void apu_write(uint32 address, uint8 value); - -/* for visualization */ -extern void apu_getpcmdata(void **data, int *num_samples, int *sample_bits); - -extern void apu_setcontext(apu_t *src_apu); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _NES_APU_H_ */ - -/* -** $Log: nes_apu.h,v $ -** Revision 1.2 2003/01/09 19:50:03 jkeil -** NSF audio files were crashing on SPARC. -** -** - Define the correct HOST_ENDIAN for SPARC -** - remove unaligned memory accesses -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources -** -** Revision 1.12 2000/07/04 04:54:48 matt -** minor changes that helped with MAME -** -** Revision 1.11 2000/07/03 02:18:53 matt -** much better external module exporting -** -** Revision 1.10 2000/06/26 05:00:37 matt -** cleanups -** -** Revision 1.9 2000/06/23 03:29:28 matt -** cleaned up external sound inteface -** -** Revision 1.8 2000/06/20 04:06:16 matt -** migrated external sound definition to apu module -** -** Revision 1.7 2000/06/20 00:07:35 matt -** added convenience members to apu_t struct -** -** Revision 1.6 2000/06/09 16:49:02 matt -** removed all floating point from sound generation -** -** Revision 1.5 2000/06/09 15:12:28 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/nsf.c b/src/libxineadec/nosefart/nsf.c deleted file mode 100644 index 69f77546b..000000000 --- a/src/libxineadec/nosefart/nsf.c +++ /dev/null @@ -1,1055 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** nsf.c -** -** NSF loading/saving related functions -** $Id: nsf.c,v 1.4 2006/09/26 00:52:17 dgp85 Exp $ -*/ - - -#include <stdio.h> -#include <string.h> -#include "types.h" -#include "nsf.h" -#include "log.h" -#include "nes6502.h" -#include "nes_apu.h" -#include "vrcvisnd.h" -#include "vrc7_snd.h" -#include "mmc5_snd.h" -#include "fds_snd.h" - -/* TODO: bleh! should encapsulate in NSF */ -#define MAX_ADDRESS_HANDLERS 32 -static nes6502_memread nsf_readhandler[MAX_ADDRESS_HANDLERS]; -static nes6502_memwrite nsf_writehandler[MAX_ADDRESS_HANDLERS]; - -static nsf_t *cur_nsf = NULL; - -static void nsf_setcontext(nsf_t *nsf) -{ - ASSERT(nsf); - cur_nsf = nsf; -} - -static uint8 read_mirrored_ram(uint32 address) -{ - nes6502_chk_mem_access(&cur_nsf->cpu->acc_mem_page[0][address & 0x7FF], - NES6502_READ_ACCESS); - return cur_nsf->cpu->mem_page[0][address & 0x7FF]; -} - -static void write_mirrored_ram(uint32 address, uint8 value) -{ - nes6502_chk_mem_access(&cur_nsf->cpu->acc_mem_page[0][address & 0x7FF], - NES6502_WRITE_ACCESS); - cur_nsf->cpu->mem_page[0][address & 0x7FF] = value; -} - -/* can be used for both banked and non-bankswitched NSFs */ -static void nsf_bankswitch(uint32 address, uint8 value) -{ - int cpu_page; - int roffset; - uint8 *offset; - - cpu_page = address & 0x0F; - roffset = -(cur_nsf->load_addr & 0x0FFF) + ((int)value << 12); - offset = cur_nsf->data + roffset; - - nes6502_getcontext(cur_nsf->cpu); - cur_nsf->cpu->mem_page[cpu_page] = offset; -#ifdef NES6502_MEM_ACCESS_CTRL - cur_nsf->cpu->acc_mem_page[cpu_page] = offset + cur_nsf->length; -#endif - nes6502_setcontext(cur_nsf->cpu); -} - -static nes6502_memread default_readhandler[] = -{ - { 0x0800, 0x1FFF, read_mirrored_ram }, - { 0x4000, 0x4017, apu_read }, - { -1, -1, NULL } -}; - -static nes6502_memwrite default_writehandler[] = -{ - { 0x0800, 0x1FFF, write_mirrored_ram }, - { 0x4000, 0x4017, apu_write }, - { 0x5FF6, 0x5FFF, nsf_bankswitch }, - { -1, -1, NULL} -}; - -static uint8 invalid_read(uint32 address) -{ -#ifdef NOFRENDO_DEBUG - log_printf("filthy NSF read from $%04X\n", address); -#endif /* NOFRENDO_DEBUG */ - - return 0xFF; -} - -static void invalid_write(uint32 address, uint8 value) -{ -#ifdef NOFRENDO_DEBUG - log_printf("filthy NSF tried to write $%02X to $%04X\n", value, address); -#endif /* NOFRENDO_DEBUG */ -} - -/* set up the address handlers that the CPU uses */ -static void build_address_handlers(nsf_t *nsf) -{ - int count, num_handlers; - - memset(nsf_readhandler, 0, sizeof(nsf_readhandler)); - memset(nsf_writehandler, 0, sizeof(nsf_writehandler)); - - num_handlers = 0; - for (count = 0; num_handlers < MAX_ADDRESS_HANDLERS; count++, num_handlers++) - { - if (NULL == default_readhandler[count].read_func) - break; - - memcpy(&nsf_readhandler[num_handlers], &default_readhandler[count], - sizeof(nes6502_memread)); - } - - if (nsf->apu->ext) - { - if (NULL != nsf->apu->ext->mem_read) - { - for (count = 0; num_handlers < MAX_ADDRESS_HANDLERS; count++, num_handlers++) - { - if (NULL == nsf->apu->ext->mem_read[count].read_func) - break; - - memcpy(&nsf_readhandler[num_handlers], &nsf->apu->ext->mem_read[count], - sizeof(nes6502_memread)); - } - } - } - - /* catch-all for bad reads */ - nsf_readhandler[num_handlers].min_range = 0x2000; /* min address */ - nsf_readhandler[num_handlers].max_range = 0x5BFF; /* max address */ - nsf_readhandler[num_handlers].read_func = invalid_read; /* handler */ - num_handlers++; - nsf_readhandler[num_handlers].min_range = -1; - nsf_readhandler[num_handlers].max_range = -1; - nsf_readhandler[num_handlers].read_func = NULL; - num_handlers++; - ASSERT(num_handlers <= MAX_ADDRESS_HANDLERS); - - num_handlers = 0; - for (count = 0; num_handlers < MAX_ADDRESS_HANDLERS; count++, num_handlers++) - { - if (NULL == default_writehandler[count].write_func) - break; - - memcpy(&nsf_writehandler[num_handlers], &default_writehandler[count], - sizeof(nes6502_memwrite)); - } - - if (nsf->apu->ext) - { - if (NULL != nsf->apu->ext->mem_write) - { - for (count = 0; num_handlers < MAX_ADDRESS_HANDLERS; count++, num_handlers++) - { - if (NULL == nsf->apu->ext->mem_write[count].write_func) - break; - - memcpy(&nsf_writehandler[num_handlers], &nsf->apu->ext->mem_write[count], - sizeof(nes6502_memwrite)); - } - } - } - - /* catch-all for bad writes */ - nsf_writehandler[num_handlers].min_range = 0x2000; /* min address */ - nsf_writehandler[num_handlers].max_range = 0x5BFF; /* max address */ - nsf_writehandler[num_handlers].write_func = invalid_write; /* handler */ - num_handlers++; - /* protect region at $8000-$FFFF */ - nsf_writehandler[num_handlers].min_range = 0x8000; /* min address */ - nsf_writehandler[num_handlers].max_range = 0xFFFF; /* max address */ - nsf_writehandler[num_handlers].write_func = invalid_write; /* handler */ - num_handlers++; - nsf_writehandler[num_handlers].min_range = -1; - nsf_writehandler[num_handlers].max_range = -1; - nsf_writehandler[num_handlers].write_func = NULL; - num_handlers++; - ASSERT(num_handlers <= MAX_ADDRESS_HANDLERS); -} - -#define NSF_ROUTINE_LOC 0x5000 - -/* sets up a simple loop that calls the desired routine and spins */ -static void nsf_setup_routine(uint32 address, uint8 a_reg, uint8 x_reg) -{ - uint8 *mem; - - nes6502_getcontext(cur_nsf->cpu); - mem = cur_nsf->cpu->mem_page[NSF_ROUTINE_LOC >> 12] + (NSF_ROUTINE_LOC & 0x0FFF); - - /* our lovely 4-byte 6502 NSF player */ - mem[0] = 0x20; /* JSR address */ - mem[1] = address & 0xFF; - mem[2] = address >> 8; - mem[3] = 0xF2; /* JAM (cpu kill op) */ - - cur_nsf->cpu->pc_reg = NSF_ROUTINE_LOC; - cur_nsf->cpu->a_reg = a_reg; - cur_nsf->cpu->x_reg = x_reg; - cur_nsf->cpu->y_reg = 0; - cur_nsf->cpu->s_reg = 0xFF; - - nes6502_setcontext(cur_nsf->cpu); -} - -/* retrieve any external soundchip driver */ -static apuext_t *nsf_getext(nsf_t *nsf) -{ - switch (nsf->ext_sound_type) - { - case EXT_SOUND_VRCVI: - return &vrcvi_ext; - - case EXT_SOUND_VRCVII: - return &vrc7_ext; - - case EXT_SOUND_FDS: - return &fds_ext; - - case EXT_SOUND_MMC5: - return &mmc5_ext; - - case EXT_SOUND_NAMCO106: - case EXT_SOUND_SUNSOFT_FME07: - case EXT_SOUND_NONE: - default: - return NULL; - } -} - -static void nsf_inittune(nsf_t *nsf) -{ - uint8 bank, x_reg; - uint8 start_bank, num_banks; - - memset(nsf->cpu->mem_page[0], 0, 0x800); - memset(nsf->cpu->mem_page[6], 0, 0x1000); - memset(nsf->cpu->mem_page[7], 0, 0x1000); - -#ifdef NES6502_MEM_ACCESS_CTRL - memset(nsf->cpu->acc_mem_page[0], 0, 0x800); - memset(nsf->cpu->acc_mem_page[6], 0, 0x1000); - memset(nsf->cpu->acc_mem_page[7], 0, 0x1000); - memset(nsf->data+nsf->length, 0, nsf->length); -#endif - nsf->cur_frame = 0; -/* nsf->last_access_frame = 0; */ - nsf->cur_frame_end = !nsf->song_frames - ? 0 - : nsf->song_frames[nsf->current_song]; - - if (nsf->bankswitched) - { - /* the first hack of the NSF spec! */ - if (EXT_SOUND_FDS == nsf->ext_sound_type) - { - nsf_bankswitch(0x5FF6, nsf->bankswitch_info[6]); - nsf_bankswitch(0x5FF7, nsf->bankswitch_info[7]); - } - - for (bank = 0; bank < 8; bank++) - nsf_bankswitch(0x5FF8 + bank, nsf->bankswitch_info[bank]); - } - else - { - /* not bankswitched, just page in our standard stuff */ - ASSERT(nsf->load_addr + nsf->length <= 0x10000); - - /* avoid ripper filth */ - for (bank = 0; bank < 8; bank++) - nsf_bankswitch(0x5FF8 + bank, bank); - - start_bank = nsf->load_addr >> 12; - num_banks = ((nsf->load_addr + nsf->length - 1) >> 12) - start_bank + 1; - - for (bank = 0; bank < num_banks; bank++) - nsf_bankswitch(0x5FF0 + start_bank + bank, bank); - } - - /* determine PAL/NTSC compatibility shite */ - if (nsf->pal_ntsc_bits & NSF_DEDICATED_PAL) - x_reg = 1; - else - x_reg = 0; - - /* execute 1 frame or so; let init routine run free */ - nsf_setup_routine(nsf->init_addr, (uint8) (nsf->current_song - 1), x_reg); - nes6502_execute((int) NES_FRAME_CYCLES); -} - -void nsf_frame(nsf_t *nsf) -{ - // This is how Matthew Conte left it - //nsf_setcontext(nsf); /* future expansion =) */ - - // This was suggested by Arne Morten Kvarving, who says: -/* Also, I fixed a bug that prevented Nosefart to play multiple tunes at - one time (actually it was just a few missing setcontext calls in the - playback routine, it had a nice TODO commented beside it. You had to set - the cpu and apu contexts not just the nsf context). - - it will affect any player that tries to use nosefart to play more than one - tune at a time. -*/ - nsf_setcontext(nsf); - apu_setcontext(nsf->apu); - nes6502_setcontext(nsf->cpu); - - /* one frame of NES processing */ - nsf_setup_routine(nsf->play_addr, 0, 0); - nes6502_execute((int) NES_FRAME_CYCLES); - - ++nsf->cur_frame; -#if defined(NES6502_MEM_ACCESS_CTRL) && 0 - if (nes6502_mem_access) { - uint32 sec = - (nsf->last_access_frame + nsf->playback_rate - 1) / nsf->playback_rate; - nsf->last_access_frame = nsf->cur_frame; - fprintf(stderr,"nsf : memory access [%x] at frame #%u [%u:%02u]\n", - nes6502_mem_access, - nsf->last_access_frame, - sec/60, sec%60); - } -#endif - -} - -/* Deallocate memory */ -void nes_shutdown(nsf_t *nsf) -{ - int i; - - ASSERT(nsf); - - if (nsf->cpu) - { - if (nsf->cpu->mem_page[0]) - { - free(nsf->cpu->mem_page[0]);/*tracks 1 and 2 of lifeforce hang here.*/ - } - for (i = 5; i <= 7; i++) { - if (nsf->cpu->mem_page[i]) - { - free(nsf->cpu->mem_page[i]); - } - } - -#ifdef NES6502_MEM_ACCESS_CTRL - if (nsf->cpu->acc_mem_page[0]) - { - free(nsf->cpu->acc_mem_page[0]); - } - for (i = 5; i <= 7; i++) { - if (nsf->cpu->acc_mem_page[i]) - { - free(nsf->cpu->acc_mem_page[i]); - } - } -#endif - free(nsf->cpu); - } -} - -int nsf_init(void) -{ - nes6502_init(); - return 0; -} - -/* Initialize NES CPU, hardware, etc. */ -static int nsf_cpuinit(nsf_t *nsf) -{ - int i; - - nsf->cpu = malloc(sizeof(nes6502_context)); - if (NULL == nsf->cpu) - return -1; - - memset(nsf->cpu, 0, sizeof(nes6502_context)); - - nsf->cpu->mem_page[0] = malloc(0x800); - if (NULL == nsf->cpu->mem_page[0]) - return -1; - - /* allocate some space for the NSF "player" MMC5 EXRAM, and WRAM */ - for (i = 5; i <= 7; i++) - { - nsf->cpu->mem_page[i] = malloc(0x1000); - if (NULL == nsf->cpu->mem_page[i]) - return -1; - } - -#ifdef NES6502_MEM_ACCESS_CTRL - nsf->cpu->acc_mem_page[0] = malloc(0x800); - if (NULL == nsf->cpu->acc_mem_page[0]) - return -1; - /* allocate some space for the NSF "player" MMC5 EXRAM, and WRAM */ - for (i = 5; i <= 7; i++) - { - nsf->cpu->acc_mem_page[i] = malloc(0x1000); - if (NULL == nsf->cpu->acc_mem_page[i]) - return -1; - } -#endif - - nsf->cpu->read_handler = nsf_readhandler; - nsf->cpu->write_handler = nsf_writehandler; - - return 0; -} - -static unsigned int nsf_playback_rate(nsf_t *nsf) -{ - if (nsf->pal_ntsc_bits & NSF_DEDICATED_PAL) - { - if (nsf->pal_speed) - nsf->playback_rate = 1000000 / nsf->pal_speed; - else - nsf->playback_rate = 50; /* 50 Hz */ - } - else - { - if (nsf->ntsc_speed) - nsf->playback_rate = 1000000 / nsf->ntsc_speed; - else - nsf->playback_rate = 60; /* 60 Hz */ - } - return 0; -} - -static void nsf_setup(nsf_t *nsf) -{ - int i; - - nsf->current_song = nsf->start_song; - nsf_playback_rate(nsf); - - nsf->bankswitched = FALSE; - for (i = 0; i < 8; i++) - { - if (nsf->bankswitch_info[i]) - { - nsf->bankswitched = TRUE; - break; - } - } -} - -#ifdef HOST_LITTLE_ENDIAN -#define SWAP_16(x) (x) -#else /* !HOST_LITTLE_ENDIAN */ -#define SWAP_16(x) (((uint16) x >> 8) | (((uint16) x & 0xFF) << 8)) -#endif /* !HOST_LITTLE_ENDIAN */ - -/* $$$ ben : find extension. Should be OK with DOS, but not with some - * OS like RiscOS ... */ -static char * find_ext(char *fn) -{ - char * a, * b, * c; - a = strrchr(fn,'.'); - b = strrchr(fn,'/'); - c = strrchr(fn,'\\'); - if (a <= b || a <= c) { - a = 0; - } - return a; -} - -/* $$$ ben : FILE loader */ -struct nsf_file_loader_t { - struct nsf_loader_t loader; - FILE *fp; - char * fname; - int name_allocated; -}; - -static int nfs_open_file(struct nsf_loader_t *loader) -{ - struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; - - floader->name_allocated = 0; - floader->fp = 0; - if (!floader->fname) { - return -1; - } - floader->fp = fopen(floader->fname,"rb"); - if (!floader->fp) { - char * fname, * ext; - ext = find_ext(floader->fname); - if (ext) { - /* There was an extension, so we do not change it */ - return -1; - } - fname = malloc(strlen(floader->fname) + 5); - if (!fname) { - return -1; - } - /* try with .nsf extension. */ - strcpy(fname, floader->fname); - strcat(fname, ".nsf"); - floader->fp = fopen(fname,"rb"); - if (!floader->fp) { - free(fname); - return -1; - } - floader->fname = fname; - floader->name_allocated = 1; - } - return 0; -} - -static void nfs_close_file(struct nsf_loader_t *loader) -{ - struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; - if (floader->fp) { - fclose(floader->fp); - floader->fp = 0; - } - if (floader->fname && floader->name_allocated) { - free(floader->fname); - floader->fname = 0; - floader->name_allocated = 0; - } -} - -static int nfs_read_file(struct nsf_loader_t *loader, void *data, int n) -{ - struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; - int r = fread(data, 1, n, floader->fp); - if (r >= 0) { - r = n-r; - } - return r; -} - -static int nfs_length_file(struct nsf_loader_t *loader) -{ - struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; - long save, pos; - save = ftell(floader->fp); - fseek(floader->fp, 0, SEEK_END); - pos = ftell(floader->fp); - fseek(floader->fp, save, SEEK_SET); - return pos; -} - -static int nfs_skip_file(struct nsf_loader_t *loader, int n) -{ - struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; - int r; - r = fseek(floader->fp, n, SEEK_CUR); - return r; -} - -static const char * nfs_fname_file(struct nsf_loader_t *loader) -{ - struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; - return floader->fname ? floader->fname : "<null>"; -} - -static struct nsf_file_loader_t nsf_file_loader = { - { - nfs_open_file, - nfs_close_file, - nfs_read_file, - nfs_length_file, - nfs_skip_file, - nfs_fname_file - }, - 0,0,0 -}; - -struct nsf_mem_loader_t { - struct nsf_loader_t loader; - uint8 *data; - unsigned long cur; - unsigned long len; - char fname[32]; -}; - -static int nfs_open_mem(struct nsf_loader_t *loader) -{ - struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; - if (!mloader->data) { - return -1; - } - mloader->cur = 0; - sprintf(mloader->fname,"<mem(%p,%u)>", - mloader->data, (unsigned int)mloader->len); - return 0; -} - -static void nfs_close_mem(struct nsf_loader_t *loader) -{ - struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; - mloader->data = 0; - mloader->cur = 0; - mloader->len = 0; -} - -static int nfs_read_mem(struct nsf_loader_t *loader, void *data, int n) -{ - struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; - int rem; - if (n <= 0) { - return n; - } - if (!mloader->data) { - return -1; - } - rem = mloader->len - mloader->cur; - if (rem > n) { - rem = n; - } - memcpy(data, mloader->data + mloader->cur, rem); - mloader->cur += rem; - return n - rem; -} - -static int nfs_length_mem(struct nsf_loader_t *loader) -{ - struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; - return mloader->len; -} - -static int nfs_skip_mem(struct nsf_loader_t *loader, int n) -{ - struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; - unsigned long goal = mloader->cur + n; - mloader->cur = (goal > mloader->len) ? mloader->len : goal; - return goal - mloader->cur; -} - -static const char * nfs_fname_mem(struct nsf_loader_t *loader) -{ - struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; - return mloader->fname; -} - -static struct nsf_mem_loader_t nsf_mem_loader = { - { nfs_open_mem, nfs_close_mem, nfs_read_mem, nfs_length_mem, nfs_skip_mem }, - 0,0,0 -}; - -nsf_t * nsf_load_extended(struct nsf_loader_t * loader) -{ - nsf_t *temp_nsf = 0; - int length; - char id[6]; - - struct { - uint8 magic[4]; /* always "NESM" */ - uint8 type[4]; /* defines extension type */ - uint8 size[4]; /* extension data size (this struct include) */ - } nsf_file_ext; - - /* no loader ! */ - if (!loader) { - return NULL; - } - - /* Open the "file" */ - if (loader->open(loader) < 0) { - return NULL; - } - - /* Get file size, and exit if there is not enough data for NSF header - * and more since it does not make sens to have header without data. - */ - length = loader->length(loader); - /* For version 2, we do not need file length. just check error later. */ -#if 0 - if (length <= NSF_HEADER_SIZE) { - log_printf("nsf : [%s] not an NSF format file\n", - loader->fname); - goto error; - } -#endif - - /* Read magic */ - if (loader->read(loader, id, 5)) { - log_printf("nsf : [%s] error reading magic number\n", - loader->fname); - goto error; - } - - /* Check magic */ - if (memcmp(id, NSF_MAGIC, 5)) { - log_printf("nsf : [%s] is not an NSF format file\n", - loader->fname); - goto error; - } - - /* $$$ ben : Now the file should be an NSF, we can start allocating. - * first : the nsf struct - */ - temp_nsf = malloc(sizeof(nsf_t)); - - if (NULL == temp_nsf) { - log_printf("nsf : [%s] error allocating nsf header\n", - loader->fname); - goto error; - } - /* $$$ ben : safety net */ - memset(temp_nsf,0,sizeof(nsf_t)); - /* Copy magic ID */ - memcpy(temp_nsf,id,5); - - /* Read header (without MAGIC) */ - if (loader->read(loader, (int8 *)temp_nsf+5, NSF_HEADER_SIZE - 5)) { - log_printf("nsf : [%s] error reading nsf header\n", - loader->fname); - goto error; - } - - /* fixup endianness */ - temp_nsf->load_addr = SWAP_16(temp_nsf->load_addr); - temp_nsf->init_addr = SWAP_16(temp_nsf->init_addr); - temp_nsf->play_addr = SWAP_16(temp_nsf->play_addr); - temp_nsf->ntsc_speed = SWAP_16(temp_nsf->ntsc_speed); - temp_nsf->pal_speed = SWAP_16(temp_nsf->pal_speed); - - /* we're now at position 80h */ - - - /* Here comes the specific codes for spec version 2 */ - - temp_nsf->length = 0; - - if (temp_nsf->version > 1) { - /* Get specified data size in reserved field (3 bytes). */ - temp_nsf->length = 0 - + temp_nsf->reserved[0] - + (temp_nsf->reserved[1]<<8) - + (temp_nsf->reserved[2]<<16); - - } - /* no specified size : try to guess with file length. */ - if (!temp_nsf->length) { - temp_nsf->length = length - NSF_HEADER_SIZE; - } - - if (temp_nsf->length <= 0) { - log_printf("nsf : [%s] not an NSF format file (missing data)\n", - loader->fname); - goto error; - } - - /* Allocate NSF space, and load it up! */ - { - int len = temp_nsf->length; -#ifdef NES6502_MEM_ACCESS_CTRL - /* $$$ twice memory for access control shadow mem. */ - len <<= 1; -#endif - temp_nsf->data = malloc(len); - } - if (NULL == temp_nsf->data) { - log_printf("nsf : [%s] error allocating nsf data\n", - loader->fname); - goto error; - } - - /* Read data */ - if (loader->read(loader, temp_nsf->data, temp_nsf->length)) { - log_printf("nsf : [%s] error reading NSF data\n", - loader->fname); - goto error; - } - - /* Here comes the second part of spec > 1 : get extension */ - while (!loader->read(loader, &nsf_file_ext, sizeof(nsf_file_ext)) - && !memcmp(nsf_file_ext.magic,id,4)) { - /* Got a NESM extension here. Checks for known extension type : - * right now, the only extension is "TIME" which give songs length. - * in frames. - */ - int size; - size = 0 - + nsf_file_ext.size[0] - + (nsf_file_ext.size[1] << 8) - + (nsf_file_ext.size[2] << 16) - + (nsf_file_ext.size[3] << 24); - - if (size < sizeof(nsf_file_ext)) { - log_printf("nsf : [%s] corrupt extension size (%d)\n", - loader->fname, size); - /* Not a fatal error here. Just skip extension loading. */ - break; - } - size -= sizeof(nsf_file_ext); - - if (!temp_nsf->song_frames - && !memcmp(nsf_file_ext.type,"TIME", 4) - && !(size & 3) - && (size >= 2*4) - && (size <= 256*4)) { - - uint8 tmp_time[256][4]; - int tsongs = size >> 2; - int i; - int songs = temp_nsf->num_songs; - - /* Add 1 for 0 which contains total time for all songs. */ - ++songs; - - if (loader->read(loader, tmp_time, size)) { - log_printf("nsf : [%s] missing extension data\n", - loader->fname); - /* Not a fatal error here. Just skip extension loading. */ - break; - } - /* Alloc song_frames for songs (not tsongs). */ - temp_nsf->song_frames = malloc(sizeof(*temp_nsf->song_frames) * songs); - if (!temp_nsf->song_frames) { - log_printf("nsf : [%s] extension alloc failed\n", - loader->fname); - /* Not a fatal error here. Just skip extension loading. */ - break; - } - - if (tsongs > songs) { - tsongs = songs; - } - - /* Copy time info. */ - for (i=0; i<tsongs; ++i) { - temp_nsf->song_frames[i] = 0 - | tmp_time[i][0] - | (tmp_time[i][1] << 8) - | (tmp_time[i][2] << 16) - | (tmp_time[i][2] << 24); - } - /* Clear missing (safety net). */ - for (; i<songs; ++i) { - temp_nsf->song_frames[i] = 0; - } - } else if (loader->skip(loader, size)) { - log_printf("nsf : [%s] extension skip failed\n", - loader->fname); - /* Not a fatal error here. Just skip extension loading. */ - break; - } - } - - - /* Close "file" */ - loader->close(loader); - loader = 0; - - /* Set up some variables */ - nsf_setup(temp_nsf); - temp_nsf->apu = NULL; /* just make sure */ - - if (nsf_cpuinit(temp_nsf)) { - log_printf("nsf : error cpu init\n"); - goto error; - } - return temp_nsf; - - /* $$$ ben : some people tell that goto are not clean. I am not agree with - * them. In most case, it allow to avoid code duplications, which are as - * most people know a source of error... Here we are sure of being clean - */ - error: - if (loader) { - loader->close(loader); - } - if (temp_nsf) { - nsf_free(&temp_nsf); - } - return 0; -} - -/* Load a ROM image into memory */ -nsf_t *nsf_load(const char *filename, void *source, int length) -{ - struct nsf_loader_t * loader = 0; - - /* $$$ ben : new loader */ - if (filename) { - nsf_file_loader.fname = (char *)filename; - loader = &nsf_file_loader.loader; - } else { - nsf_mem_loader.data = source; - nsf_mem_loader.len = length; - nsf_mem_loader.fname[0] = 0; - loader = &nsf_mem_loader.loader; - } - return nsf_load_extended(loader); -} - -/* Free an NSF */ -void nsf_free(nsf_t **pnsf) -{ - nsf_t *nsf; - - if (!pnsf) { - return; - } - - nsf = *pnsf; - /* $$$ ben : Don't see why passing a pointer to pointer - * is not to clear it :) */ - *pnsf = 0; - - if (nsf) { - if (nsf->apu) - apu_destroy(nsf->apu); - - nes_shutdown(nsf); - - if (nsf->data) - free(nsf->data); - - if (nsf->song_frames) - free (nsf->song_frames); - - free(nsf); - } -} - -int nsf_setchan(nsf_t *nsf, int chan, boolean enabled) -{ - if (!nsf) - return -1; - - nsf_setcontext(nsf); - return apu_setchan(chan, enabled); -} - -int nsf_playtrack(nsf_t *nsf, int track, int sample_rate, int sample_bits, - boolean stereo) -{ - if (!nsf) { - return -1; - } - - /* make this NSF the current context */ - nsf_setcontext(nsf); - - /* create the APU */ - if (nsf->apu) { - apu_destroy(nsf->apu); - } - - nsf->apu = apu_create(sample_rate, nsf->playback_rate, sample_bits, stereo); - if (NULL == nsf->apu) - { - /* $$$ ben : from my point of view this is not clean. Function should - * never destroy object it has not created... - */ - /* nsf_free(&nsf); */ - return -1; - } - - apu_setext(nsf->apu, nsf_getext(nsf)); - - /* go ahead and init all the read/write handlers */ - build_address_handlers(nsf); - - /* convenience? */ - nsf->process = nsf->apu->process; - - nes6502_setcontext(nsf->cpu); - - if (track > nsf->num_songs) - track = nsf->num_songs; - else if (track < 1) - track = 1; - - nsf->current_song = track; - - apu_reset(); - - nsf_inittune(nsf); - - return nsf->current_song; -} - -int nsf_setfilter(nsf_t *nsf, int filter_type) -{ - if (!nsf) { - return -1; - } - nsf_setcontext(nsf); - return apu_setfilter(filter_type); -} - -/* -** $Log: nsf.c,v $ -** Revision 1.3 2003/05/01 22:34:20 benjihan -** New NSF plugin -** -** Revision 1.2 2003/04/09 14:50:32 ben -** Clean NSF api. -** -** Revision 1.1 2003/04/08 20:53:00 ben -** Adding more files... -** -** Revision 1.14 2000/07/05 14:54:45 matt -** fix for naughty Crystalis rip -** -** Revision 1.13 2000/07/04 04:59:38 matt -** removed DOS-specific stuff, fixed bug in address handlers -** -** Revision 1.12 2000/07/03 02:19:36 matt -** dynamic address range handlers, cleaner and faster -** -** Revision 1.11 2000/06/23 03:27:58 matt -** cleaned up external sound inteface -** -** Revision 1.10 2000/06/20 20:42:47 matt -** accuracy changes -** -** Revision 1.9 2000/06/20 00:05:58 matt -** changed to driver-based external sound generation -** -** Revision 1.8 2000/06/13 03:51:54 matt -** update API to take freq/sample data on nsf_playtrack -** -** Revision 1.7 2000/06/12 03:57:14 matt -** more robust checking for winamp plugin -** -** Revision 1.6 2000/06/12 01:13:00 matt -** added CPU/APU as members of the nsf struct -** -** Revision 1.5 2000/06/11 16:09:21 matt -** nsf_free is more robust -** -** Revision 1.4 2000/06/09 15:12:26 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/nsf.h b/src/libxineadec/nosefart/nsf.h deleted file mode 100644 index 356c187a3..000000000 --- a/src/libxineadec/nosefart/nsf.h +++ /dev/null @@ -1,184 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** nsf.h -** -** NSF loading/saving related defines / prototypes -** $Id: nsf.h,v 1.3 2007/01/18 21:34:10 dgp85 Exp $ -*/ - -#ifndef _NSF_H_ -#define _NSF_H_ - -#include "osd.h" -#include "nes6502.h" -#include "nes_apu.h" - -#define NSF_MAGIC "NESM\x1A" - -#define NSF_DEDICATED_PAL 0x01 -#define NSF_DUAL_PAL_NTSC 0x02 - -#define EXT_SOUND_NONE 0x00 -#define EXT_SOUND_VRCVI 0x01 -#define EXT_SOUND_VRCVII 0x02 -#define EXT_SOUND_FDS 0x04 -#define EXT_SOUND_MMC5 0x08 -#define EXT_SOUND_NAMCO106 0x10 -#define EXT_SOUND_SUNSOFT_FME07 0x20 -/* bits 6,7: future expansion */ - -#define NSF_HEADER_SIZE 0x80 - -/* 60 Hertz refresh (NTSC) */ -#define NES_MASTER_CLOCK 21477272.7272 -#define NTSC_REFRESH 60 -#define NTSC_SUBCARRIER_DIV 12 -#define NTSC_SCANLINES 262 - -#define NES_FRAME_CYCLES ((NES_MASTER_CLOCK / NTSC_SUBCARRIER_DIV) / NTSC_REFRESH) -#define NES_SCANLINE_CYCLES (NES_FRAME_CYCLES / NTSC_SCANLINES) - -/* filter levels */ -enum -{ - NSF_FILTER_NONE, - NSF_FILTER_LOWPASS, - NSF_FILTER_WEIGHTED, - NSF_FILTER_MAX, /* $$$ ben : add this one for range chacking */ -}; - -typedef struct nsf_s -{ - /* NESM header */ - uint8 id[5]; /* NESM\x1A */ - uint8 version; /* spec version */ - uint8 num_songs; /* total num songs */ - uint8 start_song; /* first song */ - uint16 load_addr; /* loc to load code */ - uint16 init_addr; /* init call address */ - uint16 play_addr; /* play call address */ - uint8 song_name[32]; /* name of song */ - uint8 artist_name[32]; /* artist name */ - uint8 copyright[32]; /* copyright info */ - uint16 ntsc_speed; /* playback speed (if NTSC) */ - uint8 bankswitch_info[8]; /* initial code banking */ - uint16 pal_speed; /* playback speed (if PAL) */ - uint8 pal_ntsc_bits; /* NTSC/PAL determination bits */ - uint8 ext_sound_type; /* type of external sound gen. */ - uint8 reserved[4]; /* reserved */ - - /* things that the NSF player needs */ - uint8 *data; /* actual NSF data */ - uint32 length; /* length of data */ - uint32 playback_rate; /* current playback rate */ - uint8 current_song; /* current song */ - boolean bankswitched; /* is bankswitched? */ - - /* $$$ ben : Playing time ... */ - uint32 cur_frame; - uint32 cur_frame_end; - uint32 * song_frames; - - /* $$$ ben : Last error string */ - const char * errstr; - - /* CPU and APU contexts */ - nes6502_context *cpu; - apu_t *apu; - - /* our main processing routine, calls all external mixing routines */ - void (*process)(void *buffer, int num_samples); -} __PACKED__ nsf_t; - -/* $$$ ben : Generic loader struct */ -struct nsf_loader_t { - /* Init and open. */ - int (*open)(struct nsf_loader_t * loader); - - /* Close and shutdown. */ - void (*close) (struct nsf_loader_t * loader); - - /* This function should return <0 on error, else the number of byte NOT read. - * that way a simple 0 test tell us if read was complete. - */ - int (*read) (struct nsf_loader_t * loader, void *data, int n); - - /* Get file length. */ - int (*length) (struct nsf_loader_t * loader); - - /* Skip n bytes. */ - int (*skip) (struct nsf_loader_t * loader,int n); - - /* Get filename (for debug). */ - const char * (*fname) (struct nsf_loader_t * loader); - -}; - -/* Function prototypes */ -extern int nsf_init(void); - -extern nsf_t * nsf_load_extended(struct nsf_loader_t * loader); -extern nsf_t *nsf_load(const char *filename, void *source, int length); -extern void nsf_free(nsf_t **nsf_info); - -extern int nsf_playtrack(nsf_t *nsf, int track, int sample_rate, - int sample_bits, boolean stereo); -extern void nsf_frame(nsf_t *nsf); -extern int nsf_setchan(nsf_t *nsf, int chan, boolean enabled); -extern int nsf_setfilter(nsf_t *nsf, int filter_type); - -#endif /* _NSF_H_ */ - -/* -** $Log: nsf.h,v $ -** Revision 1.3 2003/05/01 22:34:20 benjihan -** New NSF plugin -** -** Revision 1.2 2003/04/09 14:50:32 ben -** Clean NSF api. -** -** Revision 1.1 2003/04/08 20:53:00 ben -** Adding more files... -** -** Revision 1.11 2000/07/04 04:59:24 matt -** removed DOS-specific stuff -** -** Revision 1.10 2000/07/03 02:19:36 matt -** dynamic address range handlers, cleaner and faster -** -** Revision 1.9 2000/06/23 03:27:58 matt -** cleaned up external sound inteface -** -** Revision 1.8 2000/06/20 04:04:37 matt -** moved external soundchip struct to apu module -** -** Revision 1.7 2000/06/20 00:05:45 matt -** changed to driver-based external sound generation -** -** Revision 1.6 2000/06/13 03:51:54 matt -** update API to take freq/sample data on nsf_playtrack -** -** Revision 1.5 2000/06/12 01:13:00 matt -** added CPU/APU as members of the nsf struct -** -** Revision 1.4 2000/06/09 15:12:26 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/osd.h b/src/libxineadec/nosefart/osd.h deleted file mode 100644 index ee90aa972..000000000 --- a/src/libxineadec/nosefart/osd.h +++ /dev/null @@ -1,98 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** osd.h -** -** O/S dependent routine defintions (must be customized) -** $Id: osd.h,v 1.2 2003/07/12 12:31:14 mroi Exp $ -*/ - -#ifndef _OSD_H_ -#define _OSD_H_ - - -#if defined(__GNUC__) || defined(__ICC) -#define __PACKED__ __attribute__ ((packed)) -#define PATH_SEP '/' -#ifdef __DJGPP__ -#include <dpmi.h> -#include "dos_ints.h" -#endif -#elif defined(WIN32) -#define __PACKED__ -#define PATH_SEP '\\' -#else /* crapintosh? */ -#define __PACKED__ -#define PATH_SEP ':' -#endif - -extern void osd_loginit(void); -extern void osd_logshutdown(void); -extern void osd_logprint(const char *string); - -extern int osd_startsound(void (*playfunc)(void *buffer, int size)); -extern int osd_getsoundbps(void); -extern int osd_getsamplerate(void); - - -#ifndef NSF_PLAYER -#include "rgb.h" -#include "bitmap.h" - -extern bitmap_t *osd_getvidbuf(void); -typedef void (*blitproc_t)(bitmap_t *bmp, int x_pos, int y_pos, int width, int height); -extern blitproc_t osd_blit; -extern void osd_copytoscreen(void); - -extern void osd_showusage(char *filename); -extern void osd_fullname(char *fullname, const char *shortname); -extern char *osd_newextension(char *string, char *ext); - -extern void osd_setpalette(rgb_t *pal); -extern void osd_restorepalette(void); - -extern void osd_getinput(void); -extern int osd_gethostinput(void); -extern void osd_getmouse(int *x, int *y, int *button); - -extern int osd_init(void); -extern void osd_shutdown(void); -#endif /* !NSF_PLAYER */ - -#endif /* _OSD_H_ */ - -/* -** $Log: osd.h,v $ -** Revision 1.2 2003/07/12 12:31:14 mroi -** - adding support for the Intel compiler icc -** - general multipass compilation make targets -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources -** -** Revision 1.7 2000/07/04 04:45:33 matt -** moved INLINE define into types.h -** -** Revision 1.6 2000/06/29 16:06:18 neil -** Wrapped DOS-specific headers in an ifdef -** -** Revision 1.5 2000/06/09 15:12:25 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/types.h b/src/libxineadec/nosefart/types.h deleted file mode 100644 index c0293066c..000000000 --- a/src/libxineadec/nosefart/types.h +++ /dev/null @@ -1,147 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** types.h -** -** Data type definitions -** $Id: types.h,v 1.4 2004/08/27 19:33:37 valtri Exp $ -*/ - -#ifndef _NOSEFART_TYPES_H_ -#define _NOSEFART_TYPES_H_ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* Define this if running on little-endian (x86) systems */ - -#ifndef DCPLAYA -# define HOST_LITTLE_ENDIAN -#endif - -#ifdef __GNUC__ -#define INLINE static inline -#elif defined(WIN32) -#define INLINE static __inline -#else /* crapintosh? */ -#define INLINE static -#endif - -/* These should be changed depending on the platform */ - - - -#ifdef __BEOS__ /* added by Eli Dayan (for compiling under BeOS) */ - - /* use types in the BeOS Support Kit instead */ - #include <be/support/SupportDefs.h> -#elif defined (DCPLAYA) /* $$$ added by ben (for compiling with dcplaya) */ -# include <arch/types.h> -#else - typedef char int8; - typedef short int16; - typedef int int32; - - typedef unsigned char uint8; - typedef unsigned short uint16; - typedef unsigned int uint32; - -#endif - -typedef uint8 boolean; - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef NULL -#define NULL ((void *) 0) -#endif - -#ifdef NOFRENDO_DEBUG -#include <stdlib.h> -#include "memguard.h" -#include "log.h" -#define ASSERT(expr) if (FALSE == (expr))\ - {\ - log_printf("ASSERT: line %d of %s\n", __LINE__, __FILE__);\ - log_shutdown();\ - exit(1);\ - } -#define ASSERT_MSG(msg) {\ - log_printf("ASSERT: %s\n", msg);\ - log_shutdown();\ - exit(1);\ - } -#else /* Not debugging */ -#include "memguard.h" -#define ASSERT(expr) -#define ASSERT_MSG(msg) -#endif - -#endif /* _NOSEFART_TYPES_H_ */ - -/* -** $Log: types.h,v $ -** Revision 1.4 2004/08/27 19:33:37 valtri -** MINGW32 port. Engine library and most of plugins compiles now. -** -** List of some changes: -** - replaced some _MSC_VER by more common WIN32 -** - define INTLDIR, remove -static flag for included intl -** - shared more common CFLAGS with DEBUG_CFLAGS -** - use WIN32_CFLAGS for all building -** - separate some flags into THREAD_CFLAGS_CONFIG, -** THREAD_CFLAGS_CONFIG and ZLIB_LIB_CONFIG for public xine-config, -** automatically use internal libs if necessary -** - don't warn about missing X for mingw and cygwin -** - libw32dll disabled for WIN32 (making native loader would be -** interesting, or porting wine code to Windows? :->) -** - DVB and RTP disabled for WIN32, not ported yet -** - fix build and fix a warning in cdda -** - fix build for nosefart and libfaad -** - implement configure option --disable-freetype -** - sync libxine.pc and xine-config.in -** - add -liberty to goom under WIN32 -** - move original build files from included phread and zlib into archives -** and replace them by autotools -** -** Revision 1.3 2003/01/11 15:53:53 tmmm -** make the Nosefart engine aware of the config's WORDS_BIGENDIAN #define -** -** Revision 1.2 2003/01/09 19:50:04 jkeil -** NSF audio files were crashing on SPARC. -** -** - Define the correct HOST_ENDIAN for SPARC -** - remove unaligned memory accesses -** -** Revision 1.1 2003/01/08 07:04:36 tmmm -** initial import of Nosefart sources -** -** Revision 1.7 2000/07/04 04:46:44 matt -** moved INLINE define from osd.h -** -** Revision 1.6 2000/06/09 15:12:25 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/version.h b/src/libxineadec/nosefart/version.h deleted file mode 100644 index 38d69c61c..000000000 --- a/src/libxineadec/nosefart/version.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** version.h -** -** Program name / version definitions -** $Id: version.h,v 1.1 2003/04/08 20:46:46 ben Exp $ -*/ - -#ifndef _VERSION_H_ -#define _VERSION_H_ - -#ifdef NSF_PLAYER -#define APP_STRING "Nosefart" -#else -#define APP_STRING "Nofrendo" -#endif /* NSF_PLAYER */ - -#define APP_VERSION "2.3-mls" - -#endif /* _VERSION_H_ */ - -/* -** $Log: version.h,v $ -** Revision 1.1 2003/04/08 20:46:46 ben -** add new input for NES music file. -** -** Revision 1.7 2000/07/04 04:46:55 matt -** updated version number -** -** Revision 1.6 2000/06/20 00:03:39 matt -** updated for 1.91 -** -** Revision 1.5 2000/06/09 17:01:56 matt -** changed version to 1.90 -** -** Revision 1.4 2000/06/09 15:12:25 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/vrc7_snd.c b/src/libxineadec/nosefart/vrc7_snd.c deleted file mode 100644 index 42cff0103..000000000 --- a/src/libxineadec/nosefart/vrc7_snd.c +++ /dev/null @@ -1,347 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** vrc7_snd.c -** -** VRCVII sound hardware emulation -** Thanks to Charles MacDonald (cgfm2@hooked.net) for donating code. -** $Id: vrc7_snd.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ -*/ - -#include <stdio.h> -#include "types.h" -#include "vrc7_snd.h" -#include "fmopl.h" - - -static int buflen; -static int16 *buffer; - -#define OPL_WRITE(opl, r, d) \ -{ \ - OPLWrite((opl)->ym3812, 0, (r)); \ - OPLWrite((opl)->ym3812, 1, (d)); \ -} - -static vrc7_t vrc7; - -/* Fixed instrument settings, from MAME's YM2413 emulation */ -/* This might need some tweaking... */ -unsigned char table[16][11] = -{ - /* 20 23 40 43 60 63 80 83 E0 E3 C0 */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - - /* MAME */ - { 0x01, 0x22, 0x23, 0x07, 0xF0, 0xF0, 0x07, 0x18, 0x00, 0x00, 0x00 }, /* Violin */ - { 0x23, 0x01, 0x68, 0x05, 0xF2, 0x74, 0x6C, 0x89, 0x00, 0x00, 0x00 }, /* Acoustic Guitar(steel) */ - { 0x13, 0x11, 0x25, 0x00, 0xD2, 0xB2, 0xF4, 0xF4, 0x00, 0x00, 0x00 }, /* Acoustic Grand */ - { 0x22, 0x21, 0x1B, 0x05, 0xC0, 0xA1, 0x18, 0x08, 0x00, 0x00, 0x00 }, /* Flute */ - { 0x22, 0x21, 0x2C, 0x03, 0xD2, 0xA1, 0x18, 0x57, 0x00, 0x00, 0x00 }, /* Clarinet */ - { 0x01, 0x22, 0xBA, 0x01, 0xF1, 0xF1, 0x1E, 0x04, 0x00, 0x00, 0x00 }, /* Oboe */ - { 0x21, 0x21, 0x28, 0x06, 0xF1, 0xF1, 0x6B, 0x3E, 0x00, 0x00, 0x00 }, /* Trumpet */ - { 0x27, 0x21, 0x60, 0x00, 0xF0, 0xF0, 0x0D, 0x0F, 0x00, 0x00, 0x00 }, /* Church Organ */ - { 0x20, 0x21, 0x2B, 0x06, 0x85, 0xF1, 0x6D, 0x89, 0x00, 0x00, 0x00 }, /* French Horn */ - { 0x01, 0x21, 0xBF, 0x02, 0x53, 0x62, 0x5F, 0xAE, 0x01, 0x00, 0x00 }, /* Synth Voice */ - { 0x23, 0x21, 0x70, 0x07, 0xD4, 0xA3, 0x4E, 0x64, 0x01, 0x00, 0x00 }, /* Harpsichord */ - { 0x2B, 0x21, 0xA4, 0x07, 0xF6, 0x93, 0x5C, 0x4D, 0x00, 0x00, 0x00 }, /* Vibraphone */ - { 0x21, 0x23, 0xAD, 0x07, 0x77, 0xF1, 0x18, 0x37, 0x00, 0x00, 0x00 }, /* Synth Bass 1 */ - { 0x21, 0x21, 0x2A, 0x03, 0xF3, 0xE2, 0x29, 0x46, 0x00, 0x00, 0x00 }, /* Acoustic Bass */ - { 0x21, 0x23, 0x37, 0x03, 0xF3, 0xE2, 0x29, 0x46, 0x00, 0x00, 0x00 }, /* Electric Guitar(clean) */ - - -#if 0 - /* Horton, try 1 */ - { 0x05, 0x03, 0x10, 0x06, 0x74, 0xA1, 0x13, 0xF4, 0x00, 0x00, 0x00 }, - { 0x05, 0x01, 0x16, 0x00, 0xF9, 0xA2, 0x15, 0xF5, 0x00, 0x00, 0x00 }, - { 0x01, 0x41, 0x11, 0x00, 0xA0, 0xA0, 0x83, 0x95, 0x00, 0x00, 0x00 }, - { 0x01, 0x41, 0x17, 0x00, 0x60, 0xF0, 0x83, 0x95, 0x00, 0x00, 0x00 }, - { 0x24, 0x41, 0x1F, 0x00, 0x50, 0xB0, 0x94, 0x94, 0x00, 0x00, 0x00 }, - { 0x05, 0x01, 0x0B, 0x04, 0x65, 0xA0, 0x54, 0x95, 0x00, 0x00, 0x00 }, - { 0x11, 0x41, 0x0E, 0x04, 0x70, 0xC7, 0x13, 0x10, 0x00, 0x00, 0x00 }, - { 0x02, 0x44, 0x16, 0x06, 0xE0, 0xE0, 0x31, 0x35, 0x00, 0x00, 0x00 }, - { 0x48, 0x22, 0x22, 0x07, 0x50, 0xA1, 0xA5, 0xF4, 0x00, 0x00, 0x00 }, - { 0x05, 0xA1, 0x18, 0x00, 0xA2, 0xA2, 0xF5, 0xF5, 0x00, 0x00, 0x00 }, - { 0x07, 0x81, 0x2B, 0x05, 0xA5, 0xA5, 0x03, 0x03, 0x00, 0x00, 0x00 }, - { 0x01, 0x41, 0x08, 0x08, 0xA0, 0xA0, 0x83, 0x95, 0x00, 0x00, 0x00 }, - { 0x21, 0x61, 0x12, 0x00, 0x93, 0x92, 0x74, 0x75, 0x00, 0x00, 0x00 }, - { 0x21, 0x62, 0x21, 0x00, 0x84, 0x85, 0x34, 0x15, 0x00, 0x00, 0x00 }, - { 0x21, 0x62, 0x0E, 0x00, 0xA1, 0xA0, 0x34, 0x15, 0x00, 0x00, 0x00 }, -#endif - -#if 0 - /* Horton try 2 */ - { 0x31, 0x22, 0x23, 0x07, 0xF0, 0xF0, 0xE8, 0xF7, 0x00, 0x00, 0x00 }, - { 0x03, 0x31, 0x68, 0x05, 0xF2, 0x74, 0x79, 0x9C, 0x00, 0x00, 0x00 }, - { 0x01, 0x51, 0x72, 0x04, 0xF1, 0xD3, 0x9D, 0x8B, 0x00, 0x00, 0x00 }, - { 0x22, 0x61, 0x1B, 0x05, 0xC0, 0xA1, 0xF8, 0xE8, 0x00, 0x00, 0x00 }, - { 0x22, 0x61, 0x2C, 0x03, 0xD2, 0xA1, 0xA7, 0xE8, 0x00, 0x00, 0x00 }, - { 0x31, 0x22, 0xFA, 0x01, 0xF1, 0xF1, 0xF4, 0xEE, 0x00, 0x00, 0x00 }, - { 0x21, 0x61, 0x28, 0x06, 0xF1, 0xF1, 0xCE, 0x9B, 0x00, 0x00, 0x00 }, - { 0x27, 0x61, 0x60, 0x00, 0xF0, 0xF0, 0xFF, 0xFD, 0x00, 0x00, 0x00 }, - { 0x60, 0x21, 0x2B, 0x06, 0x85, 0xF1, 0x79, 0x9D, 0x00, 0x00, 0x00 }, - { 0x31, 0xA1, 0xFF, 0x0A, 0x53, 0x62, 0x5E, 0xAF, 0x00, 0x00, 0x00 }, - { 0x03, 0xA1, 0x70, 0x0F, 0xD4, 0xA3, 0x94, 0xBE, 0x00, 0x00, 0x00 }, - { 0x2B, 0x61, 0xE4, 0x07, 0xF6, 0x93, 0xBD, 0xAC, 0x00, 0x00, 0x00 }, - { 0x21, 0x63, 0xED, 0x07, 0x77, 0xF1, 0xC7, 0xE8, 0x00, 0x00, 0x00 }, - { 0x21, 0x61, 0x2A, 0x03, 0xF3, 0xE2, 0xB6, 0xD9, 0x00, 0x00, 0x00 }, - { 0x21, 0x63, 0x37, 0x03, 0xF3, 0xE2, 0xB6, 0xD9, 0x00, 0x00, 0x00 }, -#endif -}; - -static void vrc7_reset(void) -{ - int n; - - /* Point to current VRC7 context */ - vrc7_t *opll = &vrc7; - - /* Clear all YM3812 registers */ - for (n = 0; n < 0x100; n++) - OPL_WRITE(opll, n, 0x00); - - /* Turn off rhythm mode and key-on bits */ - OPL_WRITE(opll, 0xBD, 0xC0); - - /* Enable waveform select */ - OPL_WRITE(opll, 0x01, 0x20); -} - -static void vrc7_init(void) -{ - vrc7.ym3812 = OPLCreate(OPL_TYPE_YM3812, 3579545, apu_getcontext()->sample_rate); - ASSERT(vrc7.ym3812); - buflen = apu_getcontext()->num_samples; - buffer = malloc(buflen * 2); - ASSERT(buffer); - vrc7_reset(); -} - -static void vrc7_shutdown(void) -{ - vrc7_reset(); - OPLDestroy(vrc7.ym3812); - free(buffer); -} - -/* channel (0-9), instrument (0-F), volume (0-3F, YM3812 format) */ -static void load_instrument(uint8 ch, uint8 inst, uint8 vol) -{ - /* Point to current VRC7 context */ - vrc7_t *opll = &vrc7; - - /* Point to fixed instrument or user table */ - uint8 *param = (inst == 0) ? &opll->user[0] : &table[inst][0]; - - /* Maps channels to operator registers */ - uint8 ch2op[] = {0, 1, 2, 8, 9, 10, 16, 17, 18}; - - /* Make operator offset from requested channel */ - uint8 op = ch2op[ch]; - - /* Store volume level */ - opll->channel[ch].volume = (vol & 0x3F); - - /* Store instrument number */ - opll->channel[ch].instrument = (inst & 0x0F); - - /* Update instrument settings, except frequency registers */ - OPL_WRITE(opll, 0x20 + op, param[0]); - OPL_WRITE(opll, 0x23 + op, param[1]); - OPL_WRITE(opll, 0x40 + op, param[2]); - OPL_WRITE(opll, 0x43 + op, (param[3] & 0xC0) | opll->channel[ch].volume); - OPL_WRITE(opll, 0x60 + op, param[4]); - OPL_WRITE(opll, 0x63 + op, param[5]); - OPL_WRITE(opll, 0x80 + op, param[6]); - OPL_WRITE(opll, 0x83 + op, param[7]); - OPL_WRITE(opll, 0xE0 + op, param[8]); - OPL_WRITE(opll, 0xE3 + op, param[9]); - OPL_WRITE(opll, 0xC0 + ch, param[10]); -} - -static void vrc7_write(uint32 address, uint8 data) -{ - /* Point to current VRC7 context */ - vrc7_t *opll = &vrc7; - - if (address & 0x0020) /* data port */ - { - /* Store register data */ - opll->reg[opll->latch] = data; - - switch (opll->latch & 0x30) - { - case 0x00: /* User instrument registers */ - switch (opll->latch & 0x0F) - { - case 0x00: /* Misc. ctrl. (modulator) */ - case 0x01: /* Misc. ctrl. (carrier) */ - case 0x02: /* Key scale level and total level (modulator) */ - case 0x04: /* Attack / Decay (modulator) */ - case 0x05: /* Attack / Decay (carrier) */ - case 0x06: /* Sustain / Release (modulator) */ - case 0x07: /* Sustain / Release (carrier) */ - opll->user[(opll->latch & 0x07)] = data; - break; - - case 0x03: /* Key scale level, carrier/modulator waveform, feedback */ - - /* Key scale level (carrier) */ - /* Don't touch the total level (channel volume) */ - opll->user[3] = (opll->user[3] & 0x3F) | (data & 0xC0); - - /* Waveform select for the modulator */ - opll->user[8] = (data >> 3) & 1; - - /* Waveform select for the carrier */ - opll->user[9] = (data >> 4) & 1; - - /* Store feedback level in YM3812 format */ - opll->user[10] = ((data & 0x07) << 1) & 0x0E; - break; - } - - /* If the user instrument registers were accessed, then - go through each channel and update the ones that were - currently using the user instrument. We can skip the - last three channels in rhythm mode since they can - only use percussion sounds anyways. */ - if (opll->latch <= 0x05) - { - uint8 x; - - for (x = 0; x < 6; x++) - if (opll->channel[x].instrument == 0x00) - load_instrument(x, 0x00, opll->channel[x].volume); - } - break; - - case 0x10: /* Channel Frequency (LSB) */ - case 0x20: /* Channel Frequency (MSB) + key-on and sustain control */ - { - uint8 block; - uint16 frequency; - uint8 ch = (opll->latch & 0x0F); - - /* Ensure proper channel range */ - if (ch > 0x05) - break; - - /* Get VRC7 channel frequency */ - frequency = ((opll->reg[0x10 + ch] & 0xFF) | ((opll->reg[0x20 + ch] & 0x01) << 8)); - - /* Scale 9 bit frequency to 10 bits */ - frequency = (frequency << 1) & 0x1FFF; - - /* Get VRC7 block */ - block = (opll->reg[0x20 + ch] >> 1) & 7; - - /* Add in block */ - frequency |= (block << 10); - - /* Add key-on flag */ - if (opll->reg[0x20 + ch] & 0x10) - frequency |= 0x2000; - - /* Save current frequency/block/key-on setting */ - opll->channel[ch].frequency = (frequency & 0x3FFF); - - /* Write changes to YM3812 */ - OPL_WRITE(opll, 0xA0 + ch, (opll->channel[ch].frequency >> 0) & 0xFF); - OPL_WRITE(opll, 0xB0 + ch, (opll->channel[ch].frequency >> 8) & 0xFF); - } - break; - - case 0x30: /* Channel Volume Level and Instrument Select */ - - /* Ensure proper channel range */ - if (opll->latch > 0x35) - break; - - { - uint8 ch = (opll->latch & 0x0F); - uint8 inst = (data >> 4) & 0x0F; - uint8 vol = (data & 0x0F) << 2; - load_instrument(ch, inst, vol); - } - - break; - } - } - else /* Register latch */ - { - opll->latch = (data & 0x3F); - } -} - -static int32 vrc7_process(void) -{ - static int sample = 0; - - /* update a large chunk at once */ - if (sample >= buflen) - { - sample -= buflen; - YM3812UpdateOne(vrc7.ym3812, buffer, buflen); - } - - return (int32) ((int16 *) buffer)[sample++]; -} - -static apu_memwrite vrc7_memwrite[] = -{ - { 0x9010, 0x9010, vrc7_write }, - { 0x9030, 0x9030, vrc7_write }, - { -1, -1, NULL } -}; - -apuext_t vrc7_ext = -{ - vrc7_init, - vrc7_shutdown, - vrc7_reset, - vrc7_process, - NULL, /* no reads */ - vrc7_memwrite -}; - -/* -** $Log: vrc7_snd.c,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:36 tmmm -** initial import of Nosefart sources -** -** Revision 1.5 2000/07/04 04:51:02 matt -** made data types stricter -** -** Revision 1.4 2000/07/03 02:18:53 matt -** much better external module exporting -** -** Revision 1.3 2000/06/20 20:45:09 matt -** minor cleanups -** -** Revision 1.2 2000/06/20 04:06:16 matt -** migrated external sound definition to apu module -** -** Revision 1.1 2000/06/20 00:06:47 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/vrc7_snd.h b/src/libxineadec/nosefart/vrc7_snd.h deleted file mode 100644 index fd3880b63..000000000 --- a/src/libxineadec/nosefart/vrc7_snd.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** vrc7_snd.h -** -** VRCVII (Konami MMC) sound hardware emulation header -** Thanks to Charles MacDonald (cgfm2@hooked.net) for donating code. -** -** $Id: vrc7_snd.h,v 1.1 2003/01/08 07:04:36 tmmm Exp $ -*/ - -#ifndef _VRC7_SND_H_ -#define _VRC7_SND_H_ - -#include "fmopl.h" - -/* VRC7 context */ -typedef struct vrc7_s -{ - uint8 reg[0x40]; /* 64 registers */ - uint8 latch; /* Register latch */ - uint8 user[0x10]; /* User instrument settings */ - struct - { - uint16 frequency; /* Channel frequency */ - uint8 volume; /* Channel volume */ - uint8 instrument; /* Channel instrument */ - } channel[9]; - - FM_OPL *ym3812; -} vrc7_t; - - -#include "nes_apu.h" - -extern apuext_t vrc7_ext; - -#endif /* !_VRC7_SND_H_ */ - -/* -** $Log: vrc7_snd.h,v $ -** Revision 1.1 2003/01/08 07:04:36 tmmm -** initial import of Nosefart sources -** -** Revision 1.3 2000/07/04 04:51:02 matt -** made data types stricter -** -** Revision 1.2 2000/06/20 04:06:16 matt -** migrated external sound definition to apu module -** -** Revision 1.1 2000/06/20 00:06:47 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/vrcvisnd.c b/src/libxineadec/nosefart/vrcvisnd.c deleted file mode 100644 index b1f26fe52..000000000 --- a/src/libxineadec/nosefart/vrcvisnd.c +++ /dev/null @@ -1,210 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** vrcvisnd.c -** -** VRCVI sound hardware emulation -** $Id: vrcvisnd.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ -*/ - -#include "types.h" -#include "vrcvisnd.h" -#include "nes_apu.h" - - -static vrcvisnd_t vrcvi; -static int32 vrcvi_incsize; - -/* VRCVI rectangle wave generation */ -static int32 vrcvi_rectangle(vrcvirectangle_t *chan) -{ - /* reg0: 0-3=volume, 4-6=duty cycle - ** reg1: 8 bits of freq - ** reg2: 0-3=high freq, 7=enable - */ - - chan->phaseacc -= vrcvi_incsize; /* # of clocks per wave cycle */ - while (chan->phaseacc < 0) - { - chan->phaseacc += chan->freq; - chan->adder = (chan->adder + 1) & 0x0F; - } - - /* return if not enabled */ - if (FALSE == chan->enabled) - return 0; - - if (chan->adder < chan->duty_flip) - return -(chan->volume); - else - return chan->volume; -} - -/* VRCVI sawtooth wave generation */ -static int32 vrcvi_sawtooth(vrcvisawtooth_t *chan) -{ - /* reg0: 0-5=phase accumulator bits - ** reg1: 8 bits of freq - ** reg2: 0-3=high freq, 7=enable - */ - - chan->phaseacc -= vrcvi_incsize; /* # of clocks per wav cycle */ - while (chan->phaseacc < 0) - { - chan->phaseacc += chan->freq; - chan->output_acc += chan->volume; - - if (7 == ++chan->adder) - { - chan->adder = 0; - chan->output_acc = 0; - } - } - - /* return if not enabled */ - if (FALSE == chan->enabled) - return 0; - else - return (chan->output_acc >> 3) << 9; -} - -/* mix vrcvi sound channels together */ -static int32 vrcvi_process(void) -{ - int32 output; - - output = vrcvi_rectangle(&vrcvi.rectangle[0]); - output += vrcvi_rectangle(&vrcvi.rectangle[1]); - output += vrcvi_sawtooth(&vrcvi.saw); - - return output; -} - -/* write to registers */ -static void vrcvi_write(uint32 address, uint8 value) -{ - int chan; - - switch (address & 0xB003) - { - case 0x9000: - case 0xA000: - chan = (address >> 12) - 9; - vrcvi.rectangle[chan].reg[0] = value; - vrcvi.rectangle[chan].volume = (value & 0x0F) << 8; - vrcvi.rectangle[chan].duty_flip = (value >> 4) + 1; - break; - case 0x9001: - case 0xA001: - chan = (address >> 12) - 9; - vrcvi.rectangle[chan].reg[1] = value; - vrcvi.rectangle[chan].freq = APU_TO_FIXED(((vrcvi.rectangle[chan].reg[2] & 0x0F) << 8) + value + 1); - break; - case 0x9002: - case 0xA002: - chan = (address >> 12) - 9; - vrcvi.rectangle[chan].reg[2] = value; - vrcvi.rectangle[chan].freq = APU_TO_FIXED(((value & 0x0F) << 8) + vrcvi.rectangle[chan].reg[1] + 1); - vrcvi.rectangle[chan].enabled = (value & 0x80) ? TRUE : FALSE; - break; - case 0xB000: - vrcvi.saw.reg[0] = value; - vrcvi.saw.volume = value & 0x3F; - break; - case 0xB001: - vrcvi.saw.reg[1] = value; - vrcvi.saw.freq = APU_TO_FIXED((((vrcvi.saw.reg[2] & 0x0F) << 8) + value + 1) << 1); - break; - case 0xB002: - vrcvi.saw.reg[2] = value; - vrcvi.saw.freq = APU_TO_FIXED((((value & 0x0F) << 8) + vrcvi.saw.reg[1] + 1) << 1); - vrcvi.saw.enabled = (value & 0x80) ? TRUE : FALSE; - break; - default: - break; - } -} - -/* reset state of vrcvi sound channels */ -static void vrcvi_reset(void) -{ - int i; - - /* preload regs */ - for (i = 0; i < 3; i++) - { - vrcvi_write(0x9000 + i, 0); - vrcvi_write(0xA000 + i, 0); - vrcvi_write(0xB000 + i, 0); - } - - /* get the phase period from the apu */ - vrcvi_incsize = apu_getcyclerate(); -} - -static void vrcvi_dummy(void) -{ -} - -static apu_memwrite vrcvi_memwrite[] = -{ -// { 0x4040, 0x4092, ext_write }, /* FDS sound regs */ - { 0x9000, 0x9002, vrcvi_write }, /* vrc6 */ - { 0xA000, 0xA002, vrcvi_write }, - { 0xB000, 0xB002, vrcvi_write }, - { -1, -1, NULL } -}; - -apuext_t vrcvi_ext = -{ - vrcvi_dummy, /* no init */ - vrcvi_dummy, /* no shutdown */ - vrcvi_reset, - vrcvi_process, - NULL, /* no reads */ - vrcvi_memwrite -}; - -/* -** $Log: vrcvisnd.c,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:36 tmmm -** initial import of Nosefart sources -** -** Revision 1.9 2000/07/04 04:51:41 matt -** cleanups -** -** Revision 1.8 2000/07/03 02:18:53 matt -** much better external module exporting -** -** Revision 1.7 2000/06/20 04:06:16 matt -** migrated external sound definition to apu module -** -** Revision 1.6 2000/06/20 00:08:58 matt -** changed to driver based API -** -** Revision 1.5 2000/06/09 16:49:02 matt -** removed all floating point from sound generation -** -** Revision 1.4 2000/06/09 15:12:28 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nosefart/vrcvisnd.h b/src/libxineadec/nosefart/vrcvisnd.h deleted file mode 100644 index 7666fec0c..000000000 --- a/src/libxineadec/nosefart/vrcvisnd.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) -** -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of version 2 of the GNU Library General -** Public License as published by the Free Software Foundation. -** -** 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 -** Library General Public License for more details. To obtain a -** copy of the GNU Library General Public License, write to the Free -** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Any permitted reproduction of these routines, in whole or in part, -** must bear this legend. -** -** -** vrcvisnd.h -** -** VRCVI (Konami MMC) sound hardware emulation header -** $Id: vrcvisnd.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ -*/ - -#ifndef _VRCVISND_H_ -#define _VRCVISND_H_ - -typedef struct vrcvirectangle_s -{ - uint8 reg[3]; - int32 phaseacc; - uint8 adder; - - int32 freq; - int32 volume; - uint8 duty_flip; - boolean enabled; -} vrcvirectangle_t; - -typedef struct vrcvisawtooth_s -{ - uint8 reg[3]; - int32 phaseacc; - uint8 adder; - uint8 output_acc; - - int32 freq; - uint8 volume; - boolean enabled; -} vrcvisawtooth_t; - -typedef struct vrcvisnd_s -{ - vrcvirectangle_t rectangle[2]; - vrcvisawtooth_t saw; -} vrcvisnd_t; - -#include "nes_apu.h" - -extern apuext_t vrcvi_ext; - -#endif /* _VRCVISND_H_ */ - -/* -** $Log: vrcvisnd.h,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:36 tmmm -** initial import of Nosefart sources -** -** Revision 1.7 2000/06/20 04:06:16 matt -** migrated external sound definition to apu module -** -** Revision 1.6 2000/06/20 00:08:58 matt -** changed to driver based API -** -** Revision 1.5 2000/06/09 16:49:02 matt -** removed all floating point from sound generation -** -** Revision 1.4 2000/06/09 15:12:28 matt -** initial revision -** -*/ diff --git a/src/libxineadec/nsf.c b/src/libxineadec/nsf.c deleted file mode 100644 index 643d431a2..000000000 --- a/src/libxineadec/nsf.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * NSF Audio "Decoder" using the Nosefart NSF engine by Matt Conte - * http://www.baisoku.org/ - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#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 "nosefart/types.h" -#include "nosefart/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 = _X_BE_32(&buf->content[0]); - this->nsf_file = calloc(1, 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 *) calloc(1, 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. */ -static void *init_plugin (xine_t *xine, void *data) { - - nsf_class_t *this ; - - this = (nsf_class_t *) calloc(1, 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; -} - -/* This is a list of all of the internal xine audio buffer types that - * this decoder is able to handle. Check src/xine-engine/buffer.h for a - * list of valid buffer types (and add a new one if the one you need does - * not exist). Terminate the list with a 0. */ -static uint32_t audio_types[] = { - BUF_AUDIO_NSF, - 0 -}; - -/* This data structure combines the list of supported xine buffer types and - * the priority that the plugin should be given with respect to other - * plugins that handle the same buffer type. A plugin with priority (n+1) - * will be used instead of a plugin with priority (n). */ -static const decoder_info_t dec_info_audio = { - audio_types, /* supported types */ - 5 /* priority */ -}; - -/* The plugin catalog entry. This is the only information that this plugin - * will export to the public. */ -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* { type, API version, "name", version, special_info, init_function }, */ - { PLUGIN_AUDIO_DECODER, 15, "nsf", XINE_VERSION_CODE, &dec_info_audio, &init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; - diff --git a/src/libxineadec/xine_lpcm_decoder.c b/src/libxineadec/xine_lpcm_decoder.c deleted file mode 100644 index 100fcee9a..000000000 --- a/src/libxineadec/xine_lpcm_decoder.c +++ /dev/null @@ -1,417 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * 31-8-2001 Added LPCM rate sensing. - * (c) 2001 James Courtier-Dutton James@superbug.demon.co.uk - */ - -#ifndef __sun -#define _XOPEN_SOURCE 500 -#endif -/* avoid compiler warnings */ -#define _BSD_SOURCE 1 - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <netinet/in.h> /* ntohs */ - -#include "xine_internal.h" -#include "audio_out.h" -#include "buffer.h" - -#ifdef WIN32 -#include <winsock.h> -/*#include <Winsock2.h>*/ /* htons */ -#endif - -typedef struct { - audio_decoder_class_t decoder_class; -} lpcm_class_t; - -typedef struct lpcm_decoder_s { - audio_decoder_t audio_decoder; - - xine_stream_t *stream; - - uint32_t rate; - uint32_t bits_per_sample; - uint32_t number_of_channels; - uint32_t ao_cap_mode; - - int output_open; - int cpu_be; /* TRUE, if we're a Big endian CPU */ - - int64_t pts; - - uint8_t *buf; - size_t buffered_bytes; - size_t buf_size; - -} lpcm_decoder_t; - -static void lpcm_reset (audio_decoder_t *this_gen) { - - lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen; - - free (this->buf); - this->buf = NULL; -} - -static void lpcm_discontinuity (audio_decoder_t *this_gen) { - - lpcm_reset(this_gen); -} - -static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { - - lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen; - int16_t *sample_buffer=(int16_t *)buf->content; - int buf_size = buf->size; - int stream_be; - audio_buffer_t *audio_buffer; - int format_changed = 0; - int special_dvd_audio = 0; - - /* Drop preview data */ - if (buf->decoder_flags & BUF_FLAG_PREVIEW) - return; - - /* get config byte from mpeg2 stream */ - if ( (buf->decoder_flags & BUF_FLAG_SPECIAL) && - buf->decoder_info[1] == BUF_SPECIAL_LPCM_CONFIG ) { - unsigned int bits_per_sample = 16; - unsigned int sample_rate = 0; - unsigned int num_channels; - - lprintf("lpcm_decoder: config data 0x%x\n", buf->decoder_info[2]); - - /* BluRay PCM header is 4 bytes */ - if (buf->decoder_info[2] & 0xffffff00) { - static const uint8_t channels[16] = {0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8, 0, 0, 0, 0}; - - num_channels = channels[(buf->decoder_info[2] >> (16+4)) & 0x0f]; - switch ((buf->decoder_info[2] >> (24+6)) & 0x03) { - case 1: bits_per_sample = 16; break; - case 2: /*bits_per_sample = 20; break;*/ - /* fall thru. Samples are 0-padded to 24 bits, and - * converted later to 16 bits by dropping 8 lowest bits. - * this needs to be changed if audio out some day accepts 24bit samples. - */ - case 3: bits_per_sample = 24; break; - default: bits_per_sample = 0; break; - } - switch ((buf->decoder_info[2] >> 16) & 0x0f) { - case 1: sample_rate = 48000; break; - case 4: sample_rate = 96000; break; - case 5: sample_rate = 192000; break; - default: sample_rate = 0; break; - } - - if (!num_channels || !sample_rate || !bits_per_sample) - xine_log (this->stream->xine, XINE_LOG_MSG, - "lpcm_decoder: unsupported BluRay PCM format: 0x%08x\n", buf->decoder_info[2]); - - if (this->buffered_bytes) - xine_log (this->stream->xine, XINE_LOG_MSG, "lpcm_decoder: %zd bytes lost !\n", this->buffered_bytes); - - if (!this->buf) { - this->buffered_bytes = 0; - this->buf_size = 8128; - this->buf = malloc(this->buf_size); - } - - } else { - - /* MPEG2/DVD PCM header is one byte */ - num_channels = (buf->decoder_info[2] & 0x7) + 1; - switch ((buf->decoder_info[2]>>4) & 3) { - case 0: sample_rate = 48000; break; - case 1: sample_rate = 96000; break; - case 2: sample_rate = 44100; break; - case 3: sample_rate = 32000; break; - } - switch ((buf->decoder_info[2]>>6) & 3) { - case 0: bits_per_sample = 16; break; - case 1: bits_per_sample = 20; break; - case 2: bits_per_sample = 24; special_dvd_audio = 1; break; - } - } - - if( this->bits_per_sample != bits_per_sample || - this->number_of_channels != num_channels || - this->rate != sample_rate || - !this->output_open ) { - this->bits_per_sample = bits_per_sample; - this->number_of_channels = num_channels; - this->rate = sample_rate; - format_changed++; - - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "lpcm_decoder: format changed to %d channels, %d bits per sample, %d Hz, %d kbit/s\n", - num_channels, bits_per_sample, sample_rate, (num_channels * sample_rate * bits_per_sample)/1024); - } - } - - if( buf->decoder_flags & BUF_FLAG_STDHEADER ) { - this->rate=buf->decoder_info[1]; - this->bits_per_sample=buf->decoder_info[2]; - this->number_of_channels=buf->decoder_info[3]; - format_changed++; - } - - /* - * (re-)open output device - */ - if ( format_changed ) { - if (this->output_open) - this->stream->audio_out->close (this->stream->audio_out, this->stream); - - this->ao_cap_mode=_x_ao_channels2mode(this->number_of_channels); - - /* force 24-bit samples into 16 bits for now */ - if (this->bits_per_sample == 24) - this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, - 16, - this->rate, - this->ao_cap_mode) ; - else - this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, - this->bits_per_sample, - this->rate, - this->ao_cap_mode) ; - - /* stream/meta info */ - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Linear PCM"); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, - this->bits_per_sample * this->rate * this->number_of_channels); - } - - if (!this->output_open || (buf->decoder_flags & BUF_FLAG_HEADER) ) - return; - - if (buf->pts && !this->pts) - this->pts = buf->pts; - - /* data accumulation */ - if (this->buf) { - int frame_end = buf->decoder_flags & BUF_FLAG_FRAME_END; - if (this->buffered_bytes || !frame_end) { - if (this->buf_size < this->buffered_bytes + buf->size) { - this->buf_size *= 2; - this->buf = realloc(this->buf, this->buf_size); - } - - memcpy(this->buf + this->buffered_bytes, buf->content, buf->size); - this->buffered_bytes += buf->size; - - if (!frame_end) - return; - - sample_buffer = (int16_t*)this->buf; - buf_size = this->buffered_bytes; - this->buffered_bytes = 0; - } - } - - audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); - - /* Swap LPCM samples into native byte order, if necessary */ - buf->type &= 0xffff0000; - stream_be = ( buf->type == BUF_AUDIO_LPCM_BE ); - - if( this->bits_per_sample == 16 ){ - if (stream_be != this->cpu_be) - swab (sample_buffer, audio_buffer->mem, buf_size); - else - memcpy (audio_buffer->mem, sample_buffer, buf_size); - } - else if( this->bits_per_sample == 20 ) { - uint8_t *s = (uint8_t *)sample_buffer; - uint8_t *d = (uint8_t *)audio_buffer->mem; - int n = buf_size; - - if (stream_be != this->cpu_be) { - while( n >= 0 ) { - swab( s, d, 8 ); - s += 10; - d += 8; - n -= 10; - } - } else { - while( n >= 0 ) { - memcpy( d, s, 8 ); - s += 10; - d += 8; - n -= 10; - } - } - } else if( this->bits_per_sample == 24 ) { - uint8_t *s = (uint8_t *)sample_buffer; - uint8_t *d = (uint8_t *)audio_buffer->mem; - int n = buf_size; - - if ( stream_be ) { - if (special_dvd_audio) - while (n >= 12) { - if ( stream_be == this->cpu_be ) { - *d++ = s[0]; - *d++ = s[1]; - *d++ = s[2]; - *d++ = s[3]; - *d++ = s[4]; - *d++ = s[5]; - *d++ = s[6]; - *d++ = s[7]; - } else { - *d++ = s[1]; - *d++ = s[0]; - *d++ = s[3]; - *d++ = s[2]; - *d++ = s[5]; - *d++ = s[4]; - *d++ = s[7]; - *d++ = s[6]; - } - s += 12; - n -= 12; - } - else - while (n >= 3) { - if ( stream_be == this->cpu_be ) { - *d++ = s[0]; - *d++ = s[1]; - } else { - *d++ = s[1]; - *d++ = s[0]; - } - s += 3; - n -= 3; - } - } else { - while (n >= 3) { - if ( stream_be == this->cpu_be ) { - *d++ = s[1]; - *d++ = s[2]; - } else { - *d++ = s[2]; - *d++ = s[1]; - } - s += 3; - n -= 3; - } - } - - if ( (d - (uint8_t*)audio_buffer->mem)/2*3 < buf_size ) - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "lpcm_decoder: lost %i bytes of %i in the buffer\n", (int)(buf_size - (d - (uint8_t*)audio_buffer->mem)/2*3), buf_size); - - } else { - memcpy (audio_buffer->mem, sample_buffer, buf_size); - } - - audio_buffer->vpts = this->pts; - audio_buffer->num_frames = (((buf_size*8)/this->number_of_channels)/this->bits_per_sample); - - this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); - - this->pts = 0; -} - -static void lpcm_dispose (audio_decoder_t *this_gen) { - lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen; - - if (this->output_open) - this->stream->audio_out->close (this->stream->audio_out, this->stream); - this->output_open = 0; - - free (this->buf); - - free (this_gen); -} - -static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { - - lpcm_decoder_t *this ; - - this = (lpcm_decoder_t *) calloc(1, sizeof(lpcm_decoder_t)); - - this->audio_decoder.decode_data = lpcm_decode_data; - this->audio_decoder.reset = lpcm_reset; - this->audio_decoder.discontinuity = lpcm_discontinuity; - this->audio_decoder.dispose = lpcm_dispose; - - this->output_open = 0; - this->rate = 0; - this->bits_per_sample=0; - this->number_of_channels=0; - this->ao_cap_mode=0; - this->stream = stream; - - this->cpu_be = ( htons(1) == 1 ); - - return &this->audio_decoder; -} - -static char *get_identifier (audio_decoder_class_t *this) { - return "Linear PCM"; -} - -static char *get_description (audio_decoder_class_t *this) { - return "Linear PCM audio decoder plugin"; -} - -static void dispose_class (audio_decoder_class_t *this) { - free (this); -} - -static void *init_plugin (xine_t *xine, void *data) { - - lpcm_class_t *this ; - - this = (lpcm_class_t *) calloc(1, sizeof(lpcm_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; -} - -static uint32_t audio_types[] = { - BUF_AUDIO_LPCM_BE, BUF_AUDIO_LPCM_LE, 0 -}; - -static const decoder_info_t dec_info_audio = { - audio_types, /* supported types */ - 1 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_AUDIO_DECODER, 15, "pcm", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxineadec/xine_speex_decoder.c b/src/libxineadec/xine_speex_decoder.c deleted file mode 100644 index 9ae2e9718..000000000 --- a/src/libxineadec/xine_speex_decoder.c +++ /dev/null @@ -1,422 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * (ogg/)speex audio decoder plugin (libspeex wrapper) for xine - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <string.h> - -#define LOG_MODULE "speex_decoder" -#define LOG_VERBOSE -/* -#define LOG -*/ -#define LOG_BUFFERS 0 - -#include "xine_internal.h" -#include "audio_out.h" -#include "buffer.h" - -#include <ogg/ogg.h> - -#include <speex/speex.h> -#include <speex/speex_header.h> -#include <speex/speex_callbacks.h> -#include <speex/speex_stereo.h> - -#define MAX_FRAME_SIZE 2000 - -typedef struct { - audio_decoder_class_t decoder_class; -} speex_class_t; - -typedef struct speex_decoder_s { - audio_decoder_t audio_decoder; - - int64_t pts; - - int output_sampling_rate; - int output_open; - int output_mode; - - /* speex stuff */ - void *st; - int frame_size; - int rate; - int nframes; - int channels; - SpeexBits bits; - SpeexStereoState stereo; - int expect_metadata; - - int header_count; - - xine_stream_t *stream; - -} speex_decoder_t; - - -static void speex_reset (audio_decoder_t *this_gen) { - - speex_decoder_t *this = (speex_decoder_t *) this_gen; - - speex_bits_init (&this->bits); -} - -static void speex_discontinuity (audio_decoder_t *this_gen) { - - speex_decoder_t *this = (speex_decoder_t *) this_gen; - - this->pts=0; -} - -/* Known speex comment keys from ogg123 sources*/ -static struct { - char *key; /* includes the '=' for programming convenience */ - int xine_metainfo_index; -} speex_comment_keys[] = { - {"ARTIST=", XINE_META_INFO_ARTIST}, - {"ALBUM=", XINE_META_INFO_ALBUM}, - {"TITLE=", XINE_META_INFO_TITLE}, - {"GENRE=", XINE_META_INFO_GENRE}, - {"DESCRIPTION=", XINE_META_INFO_COMMENT}, - {"DATE=", XINE_META_INFO_YEAR}, - {NULL, 0} -}; - -#define readint(buf, base) (((buf[base+3]<<24)&0xff000000)| \ - ((buf[base+2]<<16)&0xff0000)| \ - ((buf[base+1]<<8)&0xff00)| \ - (buf[base]&0xff)) - -static -void read_metadata (speex_decoder_t *this, char * comments, int length) -{ - char * c = comments; - int len, i, nb_fields; - char * end; - - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "speex"); - - if (length < 8) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: invalid/corrupted comments\n"); - return; - } - - end = c+length; - len = readint (c, 0); - c += 4; - - if (c+len > end) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: invalid/corrupted comments\n"); - return; - } - -#ifdef LOG - /* Encoder */ - printf ("libspeex: "); - fwrite (c, 1, len, stdout); - printf ("\n"); -#endif - - c += len; - - if (c+4 > end) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: invalid/corrupted comments\n"); - return; - } - - nb_fields = readint (c, 0); - c += 4; - - for (i = 0; i < nb_fields; i++) { - if (c+4 > end) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: invalid/corrupted comments\n"); - return; - } - - len = readint (c, 0); - c += 4; - if (c+len > end) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: invalid/corrupted comments\n"); - return; - } - -#ifdef LOG - printf ("libspeex: "); - fwrite (c, 1, len, stdout); - printf ("\n"); -#endif - - for (i = 0; speex_comment_keys[i].key != NULL; i++) { - size_t keylen = strlen(speex_comment_keys[i].key); - - if ( !strncasecmp (speex_comment_keys[i].key, c, - keylen) ) { - char meta_info[(len - keylen) + 1]; - - lprintf ("known metadata %d %d\n", - i, speex_comment_keys[i].xine_metainfo_index); - - strncpy(meta_info, &c[keylen], len-keylen); - _x_meta_info_set_utf8(this->stream, speex_comment_keys[i].xine_metainfo_index, meta_info); - } - } - - c += len; - } -} - -static void speex_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { - - speex_decoder_t *this = (speex_decoder_t *) this_gen; - - llprintf (LOG_BUFFERS, "decode buf=%8p content=%8p flags=%08x\n", - buf, buf->content, buf->decoder_flags); - - if ( (buf->decoder_flags & BUF_FLAG_HEADER) && - !(buf->decoder_flags & BUF_FLAG_STDHEADER) ) { - lprintf ("preview buffer, %d headers to go\n", this->header_count); - - if (this->header_count) { - - if (!this->st) { - SpeexMode * spx_mode; - SpeexHeader * spx_header; - unsigned int modeID; - int bitrate; - - speex_bits_init (&this->bits); - - spx_header = speex_packet_to_header (buf->content, buf->size); - - if (!spx_header) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: could not read Speex header\n"); - return; - } - - modeID = (unsigned int)spx_header->mode; - if (modeID >= SPEEX_NB_MODES) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": invalid mode ID %u\n", modeID); - return; - } - - spx_mode = (SpeexMode *) speex_mode_list[modeID]; - - if (spx_mode->bitstream_version != spx_header->mode_bitstream_version) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: incompatible Speex mode bitstream version\n"); - return; - } - - this->st = speex_decoder_init (spx_mode); - if (!this->st) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: decoder initialization failed\n"); - return; - } - - this->rate = spx_header->rate; - speex_decoder_ctl (this->st, SPEEX_SET_SAMPLING_RATE, &this->rate); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, - this->rate); - - this->channels = spx_header->nb_channels; - if (this->channels == 2) { - SpeexCallback callback; - - callback.callback_id = SPEEX_INBAND_STEREO; - callback.func = speex_std_stereo_request_handler; - callback.data = &this->stereo; - speex_decoder_ctl (this->st, SPEEX_SET_HANDLER, &callback); - } - - this->nframes = spx_header->frames_per_packet; - if (!this->nframes) this->nframes = 1; - - speex_decoder_ctl (this->st, SPEEX_GET_FRAME_SIZE, &this->frame_size); - - speex_decoder_ctl (this->st, SPEEX_GET_BITRATE, &bitrate); - if (bitrate <= 1) bitrate = 16000; /* assume 16 kbit */ - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, bitrate); - - this->header_count += spx_header->extra_headers; - this->expect_metadata = 1; - - free (spx_header); - } else if (this->expect_metadata) { - read_metadata (this, buf->content, buf->size); - } - - this->header_count--; - - if (!this->header_count) { - int mode = _x_ao_channels2mode(this->channels); - - if (!this->output_open) { - this->output_open = - (this->stream->audio_out->open) (this->stream->audio_out, - this->stream, - 16, - this->rate, - mode); - lprintf ("this->output_open after attempt is %d\n", this->output_open); - } - } - } - - } else if (this->output_open) { - int j; - - audio_buffer_t *audio_buffer; - - audio_buffer = - this->stream->audio_out->get_buffer (this->stream->audio_out); - - speex_bits_read_from (&this->bits, buf->content, buf->size); - - for (j = 0; j < this->nframes; j++) { - int ret; - int bitrate; - - ret = speex_decode_int (this->st, &this->bits, audio_buffer->mem); - - if (ret==-1) - break; - if (ret==-2) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: Decoding error, corrupted stream?\n"); - break; - } - if (speex_bits_remaining(&this->bits)<0) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: Decoding overflow, corrupted stream?\n"); - break; - } - - if (this->channels == 2) { - speex_decode_stereo_int (audio_buffer->mem, this->frame_size, &this->stereo); - } - - speex_decoder_ctl (this->st, SPEEX_GET_BITRATE, &bitrate); - if (bitrate <= 1) bitrate = 16000; /* assume 16 kbit */ - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, bitrate); - - audio_buffer->vpts = this->pts; - this->pts=0; - audio_buffer->num_frames = this->frame_size; - - this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); - - buf->pts=0; - - } - } - else { - llprintf (LOG_BUFFERS, "output not open\n"); - } -} - -static void speex_dispose (audio_decoder_t *this_gen) { - - speex_decoder_t *this = (speex_decoder_t *) this_gen; - - if (this->st) { - speex_decoder_destroy (this->st); - } - speex_bits_destroy (&this->bits); - - if (this->output_open) - this->stream->audio_out->close (this->stream->audio_out, this->stream); - - free (this_gen); -} - -static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, - xine_stream_t *stream) { - - speex_decoder_t *this ; - static SpeexStereoState init_stereo = SPEEX_STEREO_STATE_INIT; - - this = (speex_decoder_t *) calloc(1, sizeof(speex_decoder_t)); - - this->audio_decoder.decode_data = speex_decode_data; - this->audio_decoder.reset = speex_reset; - this->audio_decoder.discontinuity = speex_discontinuity; - this->audio_decoder.dispose = speex_dispose; - this->stream = stream; - - this->output_open = 0; - this->header_count = 1; - this->expect_metadata = 0; - - this->st = NULL; - - this->channels = 1; - - memcpy (&this->stereo, &init_stereo, sizeof (SpeexStereoState)); - - return (audio_decoder_t *) this; -} - -/* - * speex plugin class - */ - -static char *get_identifier (audio_decoder_class_t *this) { - return "speex"; -} - -static char *get_description (audio_decoder_class_t *this) { - return "Speex audio decoder plugin"; -} - -static void dispose_class (audio_decoder_class_t *this) { - free (this); -} - -static void *init_plugin (xine_t *xine, void *data) { - - speex_class_t *this; - - this = (speex_class_t *) calloc(1, sizeof(speex_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; -} - -static uint32_t audio_types[] = { - BUF_AUDIO_SPEEX, 0 - }; - -static const decoder_info_t dec_info_audio = { - audio_types, /* supported types */ - 5 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_AUDIO_DECODER, 15, "speex", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxineadec/xine_vorbis_decoder.c b/src/libxineadec/xine_vorbis_decoder.c deleted file mode 100644 index 99012c40d..000000000 --- a/src/libxineadec/xine_vorbis_decoder.c +++ /dev/null @@ -1,385 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * (ogg/)vorbis audio decoder plugin (libvorbis wrapper) for xine - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <string.h> - -#define LOG_MODULE "vorbis_decoder" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include "xine_internal.h" -#include "audio_out.h" -#include "buffer.h" - -#include <ogg/ogg.h> -#include <vorbis/codec.h> - -#define MAX_NUM_SAMPLES 4096 -#define INIT_BUFSIZE 8192 - -typedef struct { - audio_decoder_class_t decoder_class; -} vorbis_class_t; - -typedef struct vorbis_decoder_s { - audio_decoder_t audio_decoder; - - int64_t pts; - - int output_sampling_rate; - int output_open; - int output_mode; - - ogg_packet op; /* we must use this struct to sent data to libvorbis */ - - /* vorbis stuff */ - vorbis_info vi; /* stores static vorbis bitstream settings */ - vorbis_comment vc; - vorbis_dsp_state vd; /* central working state for packet->PCM decoder */ - vorbis_block vb; /* local working state for packet->PCM decoder */ - - int16_t convbuffer[MAX_NUM_SAMPLES]; - int convsize; - - int header_count; - - xine_stream_t *stream; - - /* data accumulation stuff */ - unsigned char *buf; - int bufsize; - int size; - -} vorbis_decoder_t; - - -static void vorbis_reset (audio_decoder_t *this_gen) { - - vorbis_decoder_t *this = (vorbis_decoder_t *) this_gen; - - if( this->header_count ) return; - this->size = 0; - - /* clear block first, as it might contain allocated data */ - vorbis_block_clear(&this->vb); - vorbis_block_init(&this->vd,&this->vb); -} - -static void vorbis_discontinuity (audio_decoder_t *this_gen) { - - vorbis_decoder_t *this = (vorbis_decoder_t *) this_gen; - - this->pts=0; -} - -/* Known vorbis comment keys from ogg123 sources*/ -static struct { - char *key; /* includes the '=' for programming convenience */ - int xine_metainfo_index; -} vorbis_comment_keys[] = { - {"ARTIST=", XINE_META_INFO_ARTIST}, - {"ALBUM=", XINE_META_INFO_ALBUM}, - {"TITLE=", XINE_META_INFO_TITLE}, - {"GENRE=", XINE_META_INFO_GENRE}, - {"DESCRIPTION=", XINE_META_INFO_COMMENT}, - {"COMMENT=", XINE_META_INFO_COMMENT}, - {"DATE=", XINE_META_INFO_YEAR}, - {"TRACKNUMBER=", XINE_META_INFO_TRACK_NUMBER}, - {NULL, 0} -}; - -static void get_metadata (vorbis_decoder_t *this) { - - char **ptr=this->vc.user_comments; - while(*ptr){ - - char *comment = *ptr; - int i; - - lprintf("%s\n", comment); - - for (i = 0; vorbis_comment_keys[i].key != NULL; i++) { - - if ( !strncasecmp (vorbis_comment_keys[i].key, comment, - strlen(vorbis_comment_keys[i].key)) ) { - - lprintf ("known metadata %d %d\n", - i, vorbis_comment_keys[i].xine_metainfo_index); - - _x_meta_info_set_utf8(this->stream, vorbis_comment_keys[i].xine_metainfo_index, - comment + strlen(vorbis_comment_keys[i].key)); - - } - } - ++ptr; - } - - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "vorbis"); -} - -static void vorbis_check_bufsize (vorbis_decoder_t *this, int size) { - if (size > this->bufsize) { - this->bufsize = size + size / 2; - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - _("vorbis: increasing buffer to %d to avoid overflow.\n"), - this->bufsize); - this->buf = realloc(this->buf, this->bufsize); - } -} - -static void vorbis_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { - - vorbis_decoder_t *this = (vorbis_decoder_t *) this_gen; - - memset( &this->op, 0, sizeof(this->op) ); - - /* data accumulation */ - vorbis_check_bufsize(this, this->size + buf->size); - xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); - this->size += buf->size; - - if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - this->op.packet = this->buf; - this->op.bytes = this->size; - - /* reset accumultaion buffer */ - this->size = 0; - - if ( (buf->decoder_flags & BUF_FLAG_HEADER) && - !(buf->decoder_flags & BUF_FLAG_STDHEADER) ) { - - lprintf ("%d headers to go\n", this->header_count); - - if (this->header_count) { - int res = 0; - - if (this->header_count == 3) - this->op.b_o_s = 1; - - if ( (res = vorbis_synthesis_headerin(&this->vi,&this->vc,&this->op)) < 0 ) { - /* error case; not a vorbis header */ - xine_log(this->stream->xine, XINE_LOG_MSG, "libvorbis: this bitstream does not contain vorbis audio data. Following first 64 bytes (return: %d).\n", res); - xine_hexdump((char *)this->op.packet, this->op.bytes < 64 ? this->op.bytes : 64); - return; - } - - this->header_count--; - - if (!this->header_count) { - - int mode = AO_CAP_MODE_MONO; - - get_metadata (this); - - mode = _x_ao_channels2mode(this->vi.channels); - - this->convsize=MAX_NUM_SAMPLES/this->vi.channels; - - if (!this->output_open) { - this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, - this->stream, - 16, - this->vi.rate, - mode) ; - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, - this->vi.bitrate_nominal); - - } - - /* OK, got and parsed all three headers. Initialize the Vorbis - * packet->PCM decoder. */ - lprintf("all three headers parsed. initializing decoder.\n"); - /* initialize central decode state */ - vorbis_synthesis_init(&this->vd,&this->vi); - /* initialize local state for most of the decode so multiple - * block decodes can proceed in parallel. We could init - * multiple vorbis_block structures for vd here */ - vorbis_block_init(&this->vd,&this->vb); - } - } - - } else if (this->output_open) { - - float **pcm; - int samples; - - if(vorbis_synthesis(&this->vb,&this->op)==0) - vorbis_synthesis_blockin(&this->vd,&this->vb); - - if (buf->pts!=0) - this->pts=buf->pts; - - while ((samples=vorbis_synthesis_pcmout(&this->vd,&pcm))>0){ - - /* **pcm is a multichannel float vector. In stereo, for - * example, pcm[0][...] is left, and pcm[1][...] is right. - * samples is the size of each channel. Convert the float - * values (-1.<=range<=1.) to whatever PCM format and write - * it out - */ - - int i,j; - int bout=(samples<this->convsize?samples:this->convsize); - audio_buffer_t *audio_buffer; - - audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); - - /* convert floats to 16 bit signed ints (host order) and - interleave */ - for(i=0;i<this->vi.channels;i++){ - ogg_int16_t *ptr=audio_buffer->mem+i; - float *mono=pcm[i]; - for(j=0;j<bout;j++){ - int val=(mono[j] + 1.0f) * 32768.f; - val -= 32768; - /* might as well guard against clipping */ - if(val>32767){ - val=32767; - } else if(val<-32768){ - val=-32768; - } - *ptr=val; - ptr+=this->vi.channels; - } - } - - audio_buffer->vpts = this->pts; - this->pts=0; - audio_buffer->num_frames = bout; - - this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); - - buf->pts=0; - - /* tell libvorbis how many samples we actually consumed */ - vorbis_synthesis_read(&this->vd,bout); - } - } else { - lprintf("output not open\n"); - } - } -} - -static void vorbis_dispose (audio_decoder_t *this_gen) { - - vorbis_decoder_t *this = (vorbis_decoder_t *) this_gen; - - if( !this->header_count ) { - lprintf("deinitializing decoder\n"); - - vorbis_block_clear(&this->vb); - vorbis_dsp_clear(&this->vd); - } - - vorbis_comment_clear(&this->vc); - - vorbis_info_clear(&this->vi); /* must be called last */ - - if (this->output_open) - this->stream->audio_out->close (this->stream->audio_out, this->stream); - - lprintf("libvorbis instance destroyed\n"); - - free (this_gen); -} - -static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, - xine_stream_t *stream) { - - vorbis_decoder_t *this ; - - this = (vorbis_decoder_t *) calloc(1, sizeof(vorbis_decoder_t)); - - this->audio_decoder.decode_data = vorbis_decode_data; - this->audio_decoder.reset = vorbis_reset; - this->audio_decoder.discontinuity = vorbis_discontinuity; - this->audio_decoder.dispose = vorbis_dispose; - this->stream = stream; - - this->output_open = 0; - this->header_count = 3; - this->convsize = 0; - - this->bufsize = INIT_BUFSIZE; - this->buf = calloc(1, INIT_BUFSIZE); - this->size = 0; - - vorbis_info_init(&this->vi); - vorbis_comment_init(&this->vc); - - lprintf("libvorbis decoder instance created\n"); - - return (audio_decoder_t *) this; -} - -/* - * vorbis plugin class - */ - -static char *get_identifier (audio_decoder_class_t *this) { - return "vorbis"; -} - -static char *get_description (audio_decoder_class_t *this) { - return "vorbis audio decoder plugin"; -} - -static void dispose_class (audio_decoder_class_t *this) { - free (this); -} - -static void *init_plugin (xine_t *xine, void *data) { - - vorbis_class_t *this; - - this = (vorbis_class_t *) calloc(1, sizeof(vorbis_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; -} - -static uint32_t audio_types[] = { - BUF_AUDIO_VORBIS, 0 - }; - -static const decoder_info_t dec_info_audio = { - audio_types, /* supported types */ - 5 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_AUDIO_DECODER, 15, "vorbis", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; |