mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 03:01:03 +00:00
ad302618b6
Original commit message from CVS: * gst/nsf/nes_apu.c: (apu_process): * gst/nsf/nes_apu.h: Don't do void pointer arithmetic - it's a gcc extension.
371 lines
7.7 KiB
C
371 lines
7.7 KiB
C
/*
|
|
** 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$
|
|
*/
|
|
|
|
#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)(uint8 *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(uint8 *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);
|
|
|
|
/* FIXME: added while importing for GStreamer */
|
|
void apu_setcontext(apu_t *src_apu);
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif /* __cplusplus */
|
|
|
|
#endif /* _NES_APU_H_ */
|
|
|
|
/*
|
|
** $Log$
|
|
** Revision 1.3 2008/04/09 13:43:51 thaytan
|
|
** * gst/nsf/nes_apu.c: (apu_process):
|
|
** * gst/nsf/nes_apu.h:
|
|
** Don't do void pointer arithmetic - it's a gcc extension.
|
|
**
|
|
** Revision 1.2 2008-03-25 15:56:12 slomo
|
|
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
|
** * gst/nsf/Makefile.am:
|
|
** * gst/nsf/dis6502.h:
|
|
** * gst/nsf/fds_snd.c:
|
|
** * gst/nsf/fds_snd.h:
|
|
** * gst/nsf/fmopl.c:
|
|
** * gst/nsf/fmopl.h:
|
|
** * gst/nsf/gstnsf.c:
|
|
** * gst/nsf/log.c:
|
|
** * gst/nsf/log.h:
|
|
** * gst/nsf/memguard.c:
|
|
** * gst/nsf/memguard.h:
|
|
** * gst/nsf/mmc5_snd.c:
|
|
** * gst/nsf/mmc5_snd.h:
|
|
** * gst/nsf/nes6502.c:
|
|
** * gst/nsf/nes6502.h:
|
|
** * gst/nsf/nes_apu.c:
|
|
** * gst/nsf/nes_apu.h:
|
|
** * gst/nsf/nsf.c:
|
|
** * gst/nsf/nsf.h:
|
|
** * gst/nsf/osd.h:
|
|
** * gst/nsf/types.h:
|
|
** * gst/nsf/vrc7_snd.c:
|
|
** * gst/nsf/vrc7_snd.h:
|
|
** * gst/nsf/vrcvisnd.c:
|
|
** * gst/nsf/vrcvisnd.h:
|
|
** Update our internal nosefart to nosefart-2.7-mls to fix segfaults
|
|
** on some files. Fixes bug #498237.
|
|
** Remove some // comments, fix some compiler warnings and use pow()
|
|
** instead of a slow, selfmade implementation.
|
|
**
|
|
** Revision 1.2 2003/04/09 14:50:32 ben
|
|
** Clean NSF api.
|
|
**
|
|
** Revision 1.1 2003/04/08 20:53:01 ben
|
|
** Adding more files...
|
|
**
|
|
** 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
|
|
**
|
|
*/
|