⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mzpokeysnd.c

📁 wince下著名的视频播放器源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * mzpokeysnd.c - POKEY sound chip emulation, v1.6 * * Copyright (C) 2002 Michael Borisov * Copyright (C) 2002-2005 Atari800 development team (see DOC/CREDITS) * * This file is part of the Atari800 emulator project which emulates * the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers. * * Atari800 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. * * Atari800 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 Atari800; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#include "config.h"#include <stdlib.h>#include <math.h>#ifdef ASAP /* external project, see http://asap.sf.net */#include "asap_internal.h"#else#include "atari.h"#endif#include "mzpokeysnd.h"#include "pokeysnd.h"#include "remez.h"#define SND_FILTER_SIZE  2048#define NPOKEYS 2/* Volume only emulations declarations */#ifdef VOL_ONLY_SOUND#define	SAMPBUF_MAX	2000extern int	sampbuf_val[SAMPBUF_MAX];	/* volume values */extern int	sampbuf_cnt[SAMPBUF_MAX];	/* relative start time */extern int	sampbuf_ptr;                    /* pointer to sampbuf */extern int	sampbuf_rptr;                   /* pointer to read from sampbuf */extern int	sampbuf_last;                   /* last absolute time */extern int	sampbuf_AUDV[4 * MAXPOKEYS];	/* prev. channel volume */extern int	sampbuf_lastval;		/* last volume */extern int	sampout;			/* last out volume */extern uint16	samp_freq;extern int	samp_consol_val;		/* actual value of console sound */#endif  /* VOL_ONLY_SOUND *//* M_PI was not defined in MSVC headers */#ifndef M_PI# define M_PI 3.141592653589793#endifstatic unsigned int num_cur_pokeys = 0;/* Filter */static unsigned sample_rate; /* Hz */static unsigned pokey_frq; /* Hz - for easier resampling */static int filter_size;static double filter_data[SND_FILTER_SIZE];static unsigned audible_frq;static const unsigned long pokey_frq_ideal =  1789790; /* Hz - True */#if 0static const int filter_size_44 = 1274;static const int filter_size_44_8 = 884;static const int filter_size_22 = 1239;static const int filter_size_22_8 = 893;static const int filter_size_11 = 1305;static const int filter_size_11_8 = 937;static const int filter_size_48 = 898;static const int filter_size_48_8 = 626;static const int filter_size_8  = 1322;static const int filter_size_8_8 = 1214;#endif/* Flags and quality */static int snd_flags = 0;static int snd_quality = 0;/* Poly tables */static unsigned char poly4tbl[15];static unsigned char poly5tbl[31];static unsigned char poly17tbl[131071];static unsigned char poly9tbl[511];struct stPokeyState;typedef unsigned char (*readout_t)(struct stPokeyState* ps);typedef void (*event_t)(struct stPokeyState* ps, char p5v, char p4v, char p917v);/* State variables for single Pokey Chip */typedef struct stPokeyState{    /* Poly positions */    unsigned int poly4pos;    unsigned int poly5pos;    unsigned int poly17pos;    unsigned int poly9pos;    /* Change queue */    unsigned char ovola;    int qet[1322]; /* maximal length of filter */    unsigned char qev[1322];    int qebeg;    int qeend;    /* Main divider (64khz/15khz) */    unsigned char mdivk;    /* 28 for 64khz, 114 for 15khz */    /* Main switches */    unsigned char selpoly9;    unsigned char c0_hf;    unsigned char c1_f0;    unsigned char c2_hf;    unsigned char c3_f2;    /* Main output state */    unsigned char outvol_all;    unsigned char forcero; /* Force readout */    /* channel 0 state */    readout_t readout_0;    event_t event_0;    unsigned long c0divpos;    unsigned long c0divstart;   /* AUDF0 recalculated */    unsigned long c0divstart_p; /* start value when c1_f0 */    unsigned short c0diva;      /* AUDF0 register */    unsigned char c0ctl;        /* AUDC0 register */    unsigned char c0t1;         /* D - 5bit, Q goes to sw3 */    unsigned char c0t2;         /* D - out sw2, Q goes to sw4 and t3 */    unsigned char c0t3;         /* D - out t2, q goes to xor */    unsigned char c0sw1;        /* in1 - 4bit, in2 - 17bit, out goes to sw2 */    unsigned char c0sw2;        /* in1 - /Q t2, in2 - out sw1, out goes to t2 */    unsigned char c0sw3;        /* in1 - +5, in2 - Q t1, out goes to C t2 */    unsigned char c0sw4;        /* hi-pass sw */    unsigned char c0vo;         /* volume only */    unsigned char c0stop;       /* channel counter stopped */    unsigned char vol0;    unsigned char outvol_0;    /* channel 1 state */    readout_t readout_1;    event_t event_1;    unsigned long c1divpos;    unsigned long c1divstart;    unsigned short c1diva;    unsigned char c1ctl;    unsigned char c1t1;    unsigned char c1t2;    unsigned char c1t3;    unsigned char c1sw1;    unsigned char c1sw2;    unsigned char c1sw3;    unsigned char c1sw4;    unsigned char c1vo;    unsigned char c1stop;      /* channel counter stopped */    unsigned char vol1;    unsigned char outvol_1;    /* channel 2 state */    readout_t readout_2;    event_t event_2;    unsigned long c2divpos;    unsigned long c2divstart;    unsigned long c2divstart_p;     /* start value when c1_f0 */    unsigned short c2diva;    unsigned char c2ctl;    unsigned char c2t1;    unsigned char c2t2;    unsigned char c2sw1;    unsigned char c2sw2;    unsigned char c2sw3;    unsigned char c2vo;    unsigned char c2stop;          /* channel counter stopped */    unsigned char vol2;    unsigned char outvol_2;    /* channel 3 state */    readout_t readout_3;    event_t event_3;    unsigned long c3divpos;    unsigned long c3divstart;    unsigned short c3diva;    unsigned char c3ctl;    unsigned char c3t1;    unsigned char c3t2;    unsigned char c3sw1;    unsigned char c3sw2;    unsigned char c3sw3;    unsigned char c3vo;    unsigned char c3stop;          /* channel counter stopped */    unsigned char vol3;    unsigned char outvol_3;} PokeyState;PokeyState pokey_states[NPOKEYS];/* Forward declarations for ResetPokeyState */static unsigned char readout0_normal(PokeyState* ps);static void event0_pure(PokeyState* ps, char p5v, char p4v, char p917v);static unsigned char readout1_normal(PokeyState* ps);static void event1_pure(PokeyState* ps, char p5v, char p4v, char p917v);static unsigned char readout2_normal(PokeyState* ps);static void event2_pure(PokeyState* ps, char p5v, char p4v, char p917v);static unsigned char readout3_normal(PokeyState* ps);static void event3_pure(PokeyState* ps, char p5v, char p4v, char p917v);void ResetPokeyState(PokeyState* ps){    /* Poly positions */    ps->poly4pos = 0;    ps->poly5pos = 0;    ps->poly9pos = 0;    ps->poly17pos = 0;    /* Change queue */    ps->ovola = 0;    ps->qebeg = 0;    ps->qeend = 0;    /* Global Pokey controls */    ps->mdivk = 28;    ps->selpoly9 = 0;    ps->c0_hf = 0;    ps->c1_f0 = 0;    ps->c2_hf = 0;    ps->c3_f2 = 0;    ps->outvol_all = 0;    ps->forcero = 0;    /* Channel 0 state */    ps->readout_0 = readout0_normal;    ps->event_0 = event0_pure;    ps->c0divpos = 1000;    ps->c0divstart = 1000;    ps->c0divstart_p = 1000;    ps->c0diva = 255;    ps->c0ctl = 0;    ps->c0t1 = 0;    ps->c0t2 = 0;    ps->c0t3 = 0;    ps->c0sw1 = 0;    ps->c0sw2 = 0;    ps->c0sw3 = 0;    ps->c0sw4 = 0;    ps->c0vo = 1;    ps->c0stop = 1;    ps->vol0 = 0;    ps->outvol_0 = 0;    /* Channel 1 state */    ps->readout_1 = readout1_normal;    ps->event_1 = event1_pure;    ps->c1divpos = 1000;    ps->c1divstart = 1000;    ps->c1diva = 255;    ps->c1ctl = 0;    ps->c1t1 = 0;    ps->c1t2 = 0;    ps->c1t3 = 0;    ps->c1sw1 = 0;    ps->c1sw2 = 0;    ps->c1sw3 = 0;    ps->c1sw4 = 0;    ps->c1vo = 1;    ps->c1stop = 1;    ps->vol1 = 0;    ps->outvol_1 = 0;    /* Channel 2 state */    ps->readout_2 = readout2_normal;    ps->event_2 = event2_pure;    ps->c2divpos = 1000;    ps->c2divstart = 1000;    ps->c2divstart_p = 1000;    ps->c2diva = 255;    ps->c2ctl = 0;    ps->c2t1 = 0;    ps->c2t2 = 0;    ps->c2sw1 = 0;    ps->c2sw2 = 0;    ps->c2sw3 = 0;    ps->c2vo = 0;    ps->c2stop = 0;    ps->vol2 = 0;    ps->outvol_2 = 0;    /* Channel 3 state */    ps->readout_3 = readout3_normal;    ps->event_3 = event3_pure;    ps->c3divpos = 1000;    ps->c3divstart = 1000;    ps->c3diva = 255;    ps->c3ctl = 0;    ps->c3t1 = 0;    ps->c3t2 = 0;    ps->c3sw1 = 0;    ps->c3sw2 = 0;    ps->c3sw3 = 0;    ps->c3stop = 1;    ps->vol3 = 0;    ps->outvol_3 = 0;}double read_resam_all(PokeyState* ps){    int i = ps->qebeg;    unsigned char avol,bvol;    double sum;    if(ps->qebeg == ps->qeend)    {        return ps->ovola * filter_data[0]; /* if no events in the queue */    }    avol = ps->ovola;    sum = 0;    /* Separate two loop cases, for wrap-around and without */    if(ps->qeend < ps->qebeg) /* With wrap */    {        while(i<filter_size)        {            bvol = ps->qev[i];            sum += (avol-bvol)*filter_data[ps->qet[i]];            avol = bvol;            ++i;        }        i=0;    }    /* without wrap */    while(i<ps->qeend)    {        bvol = ps->qev[i];        sum += (avol-bvol)*filter_data[ps->qet[i]];        avol = bvol;        ++i;    }    sum += avol*filter_data[0];    return sum;}static void add_change(PokeyState* ps, unsigned char a){    ps->qev[ps->qeend] = a;    ps->qet[ps->qeend] = 0;    ++ps->qeend;    if(ps->qeend >= filter_size)        ps->qeend = 0;}static void bump_qe_subticks(PokeyState* ps, int subticks){    /* Remove too old events from the queue while bumping */    int i = ps->qebeg;    if(ps->qeend < ps->qebeg) /* Loop with wrap */    {        while(i<filter_size)        {            ps->qet[i] += subticks;            if(ps->qet[i] >= filter_size - 1)            {                ps->ovola = ps->qev[i];                ++ps->qebeg;                if(ps->qebeg >= filter_size)                    ps->qebeg = 0;            }            ++i;        }        i=0;    }    /* loop without wrap */    while(i<ps->qeend)    {        ps->qet[i] += subticks;        if(ps->qet[i] >= filter_size - 1)        {            ps->ovola = ps->qev[i];            ++ps->qebeg;            if(ps->qebeg >= filter_size)                ps->qebeg = 0;        }        ++i;    }}static void build_poly4(void){    unsigned char c;    unsigned char i;    unsigned char poly4=1;    for(i=0; i<15; i++)    {        poly4tbl[i] = ~poly4;        c = ((poly4>>2)&1) ^ ((poly4>>3)&1);        poly4 = ((poly4<<1)&15) + c;    }}static void build_poly5(void){	unsigned char c;	unsigned char i;	unsigned char poly5 = 1;	for(i = 0; i < 31; i++) {		poly5tbl[i] = ~poly5; /* Inversion! Attention! */		c = ((poly5 >> 2) ^ (poly5 >> 4)) & 1;		poly5 = ((poly5 << 1) & 31) + c;	}}static void build_poly17(void){	unsigned int c;	unsigned int i;	unsigned int poly17 = 1;	for(i = 0; i < 131071; i++) {		poly17tbl[i] = (unsigned char) poly17;		c = ((poly17 >> 11) ^ (poly17 >> 16)) & 1;		poly17 = ((poly17 << 1) & 131071) + c;	}}static void build_poly9(void){	unsigned int c;	unsigned int i;	unsigned int poly9 = 1;	for(i = 0; i < 511; i++) {		poly9tbl[i] = (unsigned char) poly9;		c = ((poly9 >> 3) ^ (poly9 >> 8)) & 1;		poly9 = ((poly9 << 1) & 511) + c;	}}static void advance_polies(PokeyState* ps, unsigned long tacts){    ps->poly4pos = (tacts + ps->poly4pos) % 15;    ps->poly5pos = (tacts + ps->poly5pos) % 31;    ps->poly17pos = (tacts + ps->poly17pos) % 131071;    ps->poly9pos = (tacts + ps->poly9pos) % 511;}/***********************************   READ OUTPUT 0  ************************************/static unsigned char readout0_vo(PokeyState* ps){    return ps->vol0;}static unsigned char readout0_hipass(PokeyState* ps){    if(ps->c0t2 ^ ps->c0t3)        return ps->vol0;    else return 0;}static unsigned char readout0_normal(PokeyState* ps){    if(ps->c0t2)        return ps->vol0;    else return 0;}/***********************************   READ OUTPUT 1  ************************************/static unsigned char readout1_vo(PokeyState* ps){    return ps->vol1;}static unsigned char readout1_hipass(PokeyState* ps){    if(ps->c1t2 ^ ps->c1t3)        return ps->vol1;    else return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -