Files
player/Project/Src/NES/nes_apu.h
andy 045cff4cc6 整理代码
1.解决一些编译警告
2.发现png因为文件api不支持而不能使用
2025-10-18 13:58:40 +08:00

275 lines
5.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef __NES_APU_H
#define __NES_APU_H
//////////////////////////////////////////////////////////////////////////////////
//本程序移植自网友ye781205的NES模拟器工程
//ALIENTEK STM32F407开发板
//NES APU 驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2014/7/1
//版本V1.0
//////////////////////////////////////////////////////////////////////////////////
#define APU_SAMPLE_RATE 22050 //APU音频输出为22.050Khz
#define APU_PCMBUF_SIZE APU_SAMPLE_RATE/60 //44100/60=735 22050/60=367
#undef NULL
#define NULL 0
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#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_SMASK 0x4015
/* length of generated noise */
#define APU_NOISE_32K 0x7FFF
#define APU_NOISE_93 93
#define APU_BASEFREQ 1789772.7272727272727272
/* 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_t regs[4];
uint8_t enabled;
int phaseacc;
int freq;
int output_vol;
uint8_t fixed_envelope;
uint8_t holdnote;
uint8_t volume;
int sweep_phase;
int sweep_delay;
uint8_t sweep_on;
uint8_t sweep_shifts;
uint8_t sweep_length;
uint8_t sweep_inc;
/* this may not be necessary in the future */
int freq_limit;
/* rectangle 0 uses a complement addition for sweep
** increases, while rectangle 1 uses subtraction
*/
uint8_t sweep_complement;
int env_phase;
int env_delay;
uint8_t env_vol;
int vbl_length;
uint8_t adder;
int duty_flip;
} rectangle_t;
typedef struct triangle_s
{
uint8_t regs[3];
uint8_t enabled;
int freq;
int phaseacc;
int output_vol;
uint8_t adder;
uint8_t holdnote;
uint8_t counter_started;
/* quasi-hack */
int write_latency;
int vbl_length;
int linear_length;
} triangle_t;
typedef struct noise_s
{
uint8_t regs[3];
uint8_t enabled;
int freq;
int phaseacc;
int output_vol;
int env_phase;
int env_delay;
uint8_t env_vol;
uint8_t fixed_envelope;
uint8_t holdnote;
uint8_t volume;
int vbl_length;
#ifdef REALTIME_NOISE
uint8_t xor_tap;
#else
uint8_t short_sample;
int cur_pos;
#endif /* REALTIME_NOISE */
} noise_t;
typedef struct dmc_s
{
uint8_t regs[4];
/* bodge for timestamp queue */
uint8_t enabled;
int freq;
int phaseacc;
int output_vol;
uint32_t address;
uint32_t cached_addr;
int dma_length;
int cached_dmalength;
uint8_t cur_byte;
uint8_t looping;
uint8_t irq_gen;
uint8_t irq_occurred;
} dmc_t;
enum //定义枚举变量
{
APU_FILTER_NONE,
APU_FILTER_LOWPASS,
APU_FILTER_WEIGHTED
};
typedef struct
{
//uint32_t min_range, max_range;
signed long int min_range, max_range;
uint8_t (*read_func)(uint32_t address);
} apu_memread;
typedef struct
{
//uint32_t min_range, max_range;
signed long int min_range, max_range;
void (*write_func)(uint32_t address, uint8_t value);
} apu_memwrite;
/* external sound chip stuff */
typedef struct apuext_s
{
void (*init)(void);
void (*shutdown)(void);
void (*reset)(void);
//DCR
void (*paramschanged)(void);
int (*process)(void);
apu_memread *mem_read;
apu_memwrite *mem_write;
} apuext_t;
/* APU queue structure */
#define APUQUEUE_SIZE 256 //4096
#define APUQUEUE_MASK (APUQUEUE_SIZE - 1)
/* apu ring buffer member */
typedef struct apudata_s
{
uint32_t timestamp, address;
uint8_t value;
} apudata_t;
typedef struct apu_s
{
rectangle_t rectangle[2];
triangle_t triangle;
noise_t noise;
dmc_t dmc;
uint8_t enable_reg;
apudata_t queue[APUQUEUE_SIZE];//APUQUEUE_SIZE
int q_head, q_tail;
uint32_t elapsed_cycles;
void *buffer; /* pointer to output buffer输出缓冲区指针 */
int num_samples;
uint8_t mix_enable[6];
int filter_type;
int cycle_rate;
int sample_rate;
int sample_bits;
int refresh_rate;
int decay_lut[16];
int vbl_lut[32];
int trilength_lut[128];
/* external sound chip 外部声音芯片*/
apuext_t *ext;
} apu_t;
extern apu_t *apu;
extern uint16_t *wave_buffers;
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
extern void apu_init(void);
extern void apu_setparams(int sample_rate, int refresh_rate, int frag_size,int sample_bits);
extern void apu_process(uint16_t *buffer, int num_samples);
extern void apu_reset(void);
extern uint8_t Apu_Read4015(uint32_t address);
extern void Apu_Write(uint8_t value,uint32_t address);
void apu_soundoutput(void);
void apu_write4017(uint32_t address, uint8_t value);
#ifdef __cplusplus
}
#endif
#endif