Merge branch 'audio' into 'master'

Audio

See merge request projectn/nexus-am!42
This commit is contained in:
Zihao Yu 2020-04-24 20:28:55 +08:00
commit ed7744a593
33 changed files with 6764 additions and 33 deletions

View File

@ -12,6 +12,7 @@ INCLUDES += $(addprefix -I, $(INC_DIR)) -I$(AM_HOME)/am/
INCLUDES += -I$(AM_HOME)/am/include
CFLAGS += -O2 -MMD -Wall -Werror -ggdb $(INCLUDES) \
-D__ISA__=\"$(ISA)\" -D__ISA_$(shell echo $(ISA) | tr a-z A-Z)__ \
-D__PLATFORM__=\"$(PLATFORM)\" -D__PLATFORM_$(shell echo $(PLATFORM) | tr a-z A-Z)__ \
-D__ARCH__=$(ARCH) -D__ARCH_$(shell echo $(ARCH) | tr a-z A-Z | tr - _) \
-DARCH_H=\"arch/$(ARCH).h\" \
-fno-asynchronous-unwind-tables -fno-builtin -fno-stack-protector \

View File

@ -15,6 +15,7 @@ extern "C" {
#define _DEV_VIDEO 0x0000ac04 // AM Virtual Video Controller
#define _DEV_SERIAL 0x0000ac05 // AM Virtual Serial
#define _DEV_STORAGE 0x0000ac06 // AM Virtual Persistent Storage
#define _DEV_AUDIO 0x0000ac07 // AM Virtual Audio Controller
#define _DEV_PCICONF 0x00000080 // PCI Configuration Space
#define _AM_DEVREG(dev, reg, id, ...) \
@ -36,6 +37,9 @@ _AM_DEVREG(SERIAL, CTRL, 4, uint8_t data);
_AM_DEVREG(STORAGE, INFO, 1, uint32_t blksz, blkcnt);
_AM_DEVREG(STORAGE, RDCTRL, 2, void *buf; uint32_t blkno, blkcnt);
_AM_DEVREG(STORAGE, WRCTRL, 3, void *buf; uint32_t blkno, blkcnt);
_AM_DEVREG(AUDIO, INIT, 1, uint32_t freq, channels, samples, bufsize);
_AM_DEVREG(AUDIO, SBCTRL, 2, uint8_t *stream; int len, wait);
_AM_DEVREG(AUDIO, SBSTAT, 3, int bufsize, count);
#define _DEVREG_PCICONF(bus, slot, func, offset) \
((uint32_t)( 1) << 31) | ((uint32_t)( bus) << 16) | \
((uint32_t)(slot) << 11) | ((uint32_t)(func) << 8) | (offset)

View File

@ -8,6 +8,7 @@ AM_SRCS := native/trm.c \
native/devices/input.c \
native/devices/timer.c \
native/devices/video.c \
native/devices/audio.c \
CFLAGS += -fpie
ASFLAGS += -fpie -pie

View File

@ -4,6 +4,7 @@ AM_SRCS += nemu/common/trm.c \
nemu/common/input.c \
nemu/common/timer.c \
nemu/common/video.c \
nemu/common/audio.c \
dummy/mpe.c \
CFLAGS += -I$(AM_HOME)/am/src/nemu/include

View File

@ -0,0 +1,94 @@
#include <am.h>
#include <amdev.h>
#include <SDL2/SDL.h>
#include <klib.h>
#define SBUF_SIZE_MAX 65536
static uint8_t sbuf [SBUF_SIZE_MAX] = {};
static int sbuf_size = 0;
static int head = 0, tail = 0;
static volatile int count = 0;
static void audio_play(void *userdata, uint8_t *stream, int len) {
int nread = len;
if (count < len) nread = count;
if (nread + tail < sbuf_size) {
memcpy(stream, sbuf + tail, nread);
tail += nread;
} else {
int first_cpy_len = sbuf_size - tail;
memcpy(stream, sbuf + tail, first_cpy_len);
memcpy(stream + first_cpy_len, sbuf, nread - first_cpy_len);
tail = nread - first_cpy_len;
}
count -= nread;
if (len > nread) memset(stream + nread, 0, len - nread);
}
static int audio_write(uint8_t *buf, int len) {
int free = sbuf_size - count;
int nwrite = len;
if (free < len) nwrite = free;
if (nwrite + head < sbuf_size) {
memcpy(sbuf + head, buf, nwrite);
head += nwrite;
} else {
int first_cpy_len = sbuf_size - head;
memcpy(sbuf + head, buf, first_cpy_len);
memcpy(sbuf, buf + first_cpy_len, nwrite - first_cpy_len);
head = nwrite - first_cpy_len;
}
count += nwrite;
return nwrite;
}
void __am_audio_init() {
}
size_t __am_audio_write(uintptr_t reg, void *buf, size_t size) {
switch (reg) {
case _DEVREG_AUDIO_INIT: {
_DEV_AUDIO_INIT_t *init = (_DEV_AUDIO_INIT_t *)buf;
SDL_AudioSpec s = {};
s.freq = init->freq;
s.format = AUDIO_S16SYS;
s.channels = init->channels;
s.samples = init->samples;
s.callback = audio_play;
s.userdata = NULL;
sbuf_size = init->bufsize;
assert(sbuf_size <= SBUF_SIZE_MAX);
head = tail = 0;
count = 0;
SDL_InitSubSystem(SDL_INIT_AUDIO);
SDL_OpenAudio(&s, NULL);
SDL_PauseAudio(0);
return size;
}
case _DEVREG_AUDIO_SBCTRL: {
_DEV_AUDIO_SBCTRL_t *ctl = (_DEV_AUDIO_SBCTRL_t *)buf;
if (ctl->wait) {
assert(ctl->len <= sbuf_size);
while (sbuf_size - count < ctl->len);
}
ctl->len = audio_write(ctl->stream, ctl->len);
return size;
}
}
return 0;
}
size_t __am_audio_read(uintptr_t reg, void *buf, size_t size) {
switch (reg) {
case _DEVREG_AUDIO_SBSTAT: {
_DEV_AUDIO_SBSTAT_t *stat = (_DEV_AUDIO_SBSTAT_t *)buf;
stat->count = count;
stat->bufsize = sbuf_size;
return size;
}
}
return 0;
}

View File

@ -3,12 +3,15 @@
void __am_timer_init();
void __am_video_init();
void __am_audio_init();
void __am_input_init();
size_t __am_input_read(uintptr_t reg, void *buf, size_t size);
size_t __am_timer_read(uintptr_t reg, void *buf, size_t size);
size_t __am_video_read(uintptr_t reg, void *buf, size_t size);
size_t __am_audio_read(uintptr_t reg, void *buf, size_t size);
size_t __am_video_write(uintptr_t reg, void *buf, size_t size);
size_t __am_audio_write(uintptr_t reg, void *buf, size_t size);
static int init_flag = 0;
@ -23,6 +26,7 @@ int _ioe_init() {
__am_timer_init();
__am_video_init();
__am_audio_init();
__am_input_init();
return 0;
}
@ -33,6 +37,7 @@ size_t _io_read(uint32_t dev, uintptr_t reg, void *buf, size_t size) {
case _DEV_INPUT: return __am_input_read(reg, buf, size);
case _DEV_TIMER: return __am_timer_read(reg, buf, size);
case _DEV_VIDEO: return __am_video_read(reg, buf, size);
case _DEV_AUDIO: return __am_audio_read(reg, buf, size);
}
return 0;
}
@ -41,6 +46,7 @@ size_t _io_write(uint32_t dev, uintptr_t reg, void *buf, size_t size) {
if (init_flag == 1) { _ioe_init(); }
switch (dev) {
case _DEV_VIDEO: return __am_video_write(reg, buf, size);
case _DEV_AUDIO: return __am_audio_write(reg, buf, size);
}
return 0;
}

View File

@ -0,0 +1,70 @@
#include <am.h>
#include <amdev.h>
#include <klib.h>
#include <nemu.h>
static uint8_t* const sbuf = (uint8_t *)AUDIO_SBUF_ADDR;
static int sbuf_size = 0;
static int head = 0;
void __am_audio_init() {
}
static int audio_write(uint8_t *buf, int len) {
uint32_t count = inl(AUDIO_COUNT_ADDR);
int free = sbuf_size - count;
int nwrite = len;
if (free < len) nwrite = free;
if (nwrite + head < sbuf_size) {
memcpy(sbuf + head, buf, nwrite);
head += nwrite;
} else {
int first_cpy_len = sbuf_size - head;
memcpy(sbuf + head, buf, first_cpy_len);
memcpy(sbuf, buf + first_cpy_len, nwrite - first_cpy_len);
head = nwrite - first_cpy_len;
}
count += nwrite;
outl(AUDIO_COUNT_ADDR, count);
return nwrite;
}
size_t __am_audio_write(uintptr_t reg, void *buf, size_t size) {
switch (reg) {
case _DEVREG_AUDIO_INIT: {
_DEV_AUDIO_INIT_t *init = (_DEV_AUDIO_INIT_t *)buf;
outl(AUDIO_FREQ_ADDR, init->freq);
outl(AUDIO_CHANNELS_ADDR, init->channels);
outl(AUDIO_SAMPLES_ADDR, init->samples);
outl(AUDIO_SBUF_SIZE_ADDR, init->bufsize);
outl(AUDIO_INIT_ADDR, 1);
sbuf_size = init->bufsize;
head = 0;
return size;
}
case _DEVREG_AUDIO_SBCTRL: {
_DEV_AUDIO_SBCTRL_t *ctl = (_DEV_AUDIO_SBCTRL_t *)buf;
if (ctl->wait) {
assert(ctl->len <= sbuf_size);
while (sbuf_size - inl(AUDIO_COUNT_ADDR) < ctl->len);
}
ctl->len = audio_write(ctl->stream, ctl->len);
return size;
}
}
return 0;
}
size_t __am_audio_read(uintptr_t reg, void *buf, size_t size) {
switch (reg) {
case _DEVREG_AUDIO_SBSTAT: {
_DEV_AUDIO_SBSTAT_t *stat = (_DEV_AUDIO_SBSTAT_t *)buf;
stat->count = inl(AUDIO_COUNT_ADDR);
stat->bufsize = sbuf_size;
return size;
}
}
return 0;
}

View File

@ -3,10 +3,12 @@
void __am_vga_init();
void __am_timer_init();
void __am_audio_init();
int _ioe_init() {
__am_vga_init();
__am_timer_init();
__am_audio_init();
return 0;
}
@ -14,12 +16,15 @@ size_t __am_timer_read(uintptr_t reg, void *buf, size_t size);
size_t __am_video_read(uintptr_t reg, void *buf, size_t size);
size_t __am_video_write(uintptr_t reg, void *buf, size_t size);
size_t __am_input_read(uintptr_t reg, void *buf, size_t size);
size_t __am_audio_read(uintptr_t reg, void *buf, size_t size);
size_t __am_audio_write(uintptr_t reg, void *buf, size_t size);
size_t _io_read(uint32_t dev, uintptr_t reg, void *buf, size_t size) {
switch (dev) {
case _DEV_INPUT: return __am_input_read(reg, buf, size);
case _DEV_TIMER: return __am_timer_read(reg, buf, size);
case _DEV_VIDEO: return __am_video_read(reg, buf, size);
case _DEV_AUDIO: return __am_audio_read(reg, buf, size);
}
return 0;
}
@ -27,6 +32,7 @@ size_t _io_read(uint32_t dev, uintptr_t reg, void *buf, size_t size) {
size_t _io_write(uint32_t dev, uintptr_t reg, void *buf, size_t size) {
switch (dev) {
case _DEV_VIDEO: return __am_video_write(reg, buf, size);
case _DEV_AUDIO: return __am_audio_write(reg, buf, size);
}
return 0;
}

View File

@ -12,6 +12,13 @@
# define SCREEN_ADDR 0x100
# define SYNC_ADDR 0x104
# define FB_ADDR 0xa0000000
# define AUDIO_FREQ_ADDR 0x200
# define AUDIO_CHANNELS_ADDR 0x204
# define AUDIO_SAMPLES_ADDR 0x208
# define AUDIO_SBUF_SIZE_ADDR 0x20c
# define AUDIO_INIT_ADDR 0x210
# define AUDIO_COUNT_ADDR 0x214
# define AUDIO_SBUF_ADDR 0xa0800000
#elif defined(__ARCH_RISCV64_NOOP) || defined(__ARCH_RISCV32_NOOP)
# define KBD_ADDR 0x40900000
# define RTC_ADDR 0x4800bff8
@ -25,6 +32,13 @@
# define SCREEN_ADDR 0xa1000100
# define SYNC_ADDR 0xa1000104
# define FB_ADDR 0xa0000000
# define AUDIO_FREQ_ADDR 0xa1000200
# define AUDIO_CHANNELS_ADDR 0xa1000204
# define AUDIO_SAMPLES_ADDR 0xa1000208
# define AUDIO_SBUF_SIZE_ADDR 0xa100020c
# define AUDIO_INIT_ADDR 0xa1000210
# define AUDIO_COUNT_ADDR 0xa1000214
# define AUDIO_SBUF_ADDR 0xa0800000
#endif
#define MMIO_BASE 0xa0000000

19
apps/fceux/src/config.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef __CONFIG_H__
#define __CONFIG_H__
#define SOUND_NONE 0
#define SOUND_LQ 1
#define SOUND_HQ 2
#if defined(__PLATFORM_NEMU__)
# define NR_FRAMESKIP 1
# define SOUND_CONFIG SOUND_LQ
#elif defined(__PLATFORM_NOOP__)
# define NR_FRAMESKIP 2
# define SOUND_CONFIG SOUND_NONE
#else
# define NR_FRAMESKIP 0
# define SOUND_CONFIG SOUND_HQ
#endif
#endif

View File

@ -0,0 +1,165 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2002 Xodnizel
*
* This program 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.
*
* 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 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-1301 USA
*/
/// \file
/// \brief Handles sound emulation using the SDL.
#include "sdl.h"
#include <amdev.h>
#include "../../config.h"
// unit: 16-bit
static unsigned int s_BufferSize;
/**
* Initialize the audio subsystem.
*/
int
InitSound()
{
#if SOUND_CONFIG == SOUND_NONE
return 1;
#endif
#if SOUND_CONFIG == SOUND_HQ
const int soundrate = 44100;
const int soundq = 1;
#else
const int soundrate = 11025;
const int soundq = 0;
#endif
const int soundbufsize = 128;
const int soundvolume = 150;
const int soundtrianglevolume = 256;
const int soundsquare1volume = 256;
const int soundsquare2volume = 256;
const int soundnoisevolume = 256;
const int soundpcmvolume = 256;
_DEV_AUDIO_INIT_t init;
init.freq = soundrate;
init.channels = 1;
init.samples = 512;
init.bufsize = soundbufsize * soundrate / 1000;
if (init.bufsize < init.samples * 2) {
init.bufsize = init.samples * 2;
}
s_BufferSize = init.bufsize;
init.bufsize *= sizeof(int16_t);
_io_write(_DEV_AUDIO, _DEVREG_AUDIO_INIT, &init, sizeof(init));
FCEUI_SetSoundVolume(soundvolume);
FCEUI_SetSoundQuality(soundq);
FCEUI_Sound(soundrate);
FCEUI_SetTriangleVolume(soundtrianglevolume);
FCEUI_SetSquare1Volume(soundsquare1volume);
FCEUI_SetSquare2Volume(soundsquare2volume);
FCEUI_SetNoiseVolume(soundnoisevolume);
FCEUI_SetPCMVolume(soundpcmvolume);
return 1;
}
/**
* Returns the size of the audio buffer.
*/
uint32
GetMaxSound(void)
{
return(s_BufferSize);
}
/**
* Returns the amount of free space in the audio buffer.
*/
uint32
GetWriteSound(void)
{
_DEV_AUDIO_SBSTAT_t audio;
_io_read(_DEV_AUDIO, _DEVREG_AUDIO_SBSTAT, &audio, sizeof(audio));
audio.count /= sizeof(int16_t);
return s_BufferSize - audio.count;
}
/**
* Send a sound clip to the audio subsystem.
*/
void
WriteSound(int32 *buf,
int Count)
{
extern int EmulationPaused;
if (EmulationPaused == 0) {
// FECUX stores each PCM sample as 32-bit data,
// but it sets the audio type with AUDIO_S16SYS,
// so we should transform the `buf` into a 16-bit
// buffer before feeding it to the audio device
int16_t *buf16 = (int16_t *)malloc(sizeof(buf16[0]) * Count);
assert(buf16);
int i;
for (i = 0; i < Count; i ++) {
buf16[i] = buf[i];
}
_DEV_AUDIO_SBCTRL_t audio;
audio.stream = (uint8_t *)buf16;
audio.wait = 1;
audio.len = Count * sizeof(buf16[0]);
_io_write(_DEV_AUDIO, _DEVREG_AUDIO_SBCTRL, &audio, sizeof(audio));
free(buf16);
}
}
/**
* Pause (1) or unpause (0) the audio output.
*/
void
SilenceSound(int n)
{
//SDL_PauseAudio(n);
}
/**
* Shut down the audio subsystem.
*/
int
KillSound(void)
{
FCEUI_Sound(0);
return 0;
}
/**
* Adjust the volume either down (-1), up (1), or to the default (0).
* Unmutes if mute was active before.
*/
void
FCEUD_SoundVolumeAdjust(int n)
{
}
/**
* Toggles the sound on or off.
*/
void
FCEUD_SoundToggle(void)
{
}

View File

@ -11,12 +11,7 @@
#include "sdl-video.h"
#include "../../types.h"
#ifdef __ISA_NATIVE__
#define NR_FRAMESKIP 0
#else
#define NR_FRAMESKIP 2
#endif
#include "../../config.h"
int isloaded;
@ -34,6 +29,8 @@ int gametype = 0;
int pal_emulation;
int dendy;
bool swapDuty;
// global configuration object
//Config *g_config;
@ -123,6 +120,9 @@ DriverInitialize(FCEUGI *gi)
if(InitVideo(gi) < 0) return 0;
inited|=4;
if(InitSound())
inited|=1;
eoptions &= ~EO_FOURSCORE;
InitInputInterface();
@ -149,8 +149,53 @@ FCEUD_Update(uint8 *XBuf,
int32 *Buffer,
int Count)
{
// apply frame scaling to Count
int ocount = Count;
if(Count) {
int32 can=GetWriteSound();
static int uflow=0;
int32 tmpcan;
// don't underflow when scaling fps
if(can >= (int)GetMaxSound()) uflow=1; /* Go into massive underflow mode. */
if(can > Count) can=Count;
else uflow=0;
WriteSound(Buffer,can);
//if(uflow) puts("Underflow");
tmpcan = GetWriteSound();
// don't underflow when scaling fps
if((tmpcan < Count*9/10) && !uflow) {
if(XBuf && (inited&4) && !(NoWaiting & 2))
BlitScreen(XBuf);
Buffer+=can;
Count-=can;
if(Count) {
if(NoWaiting) {
can=GetWriteSound();
if(Count>can) Count=can;
WriteSound(Buffer,Count);
} else {
while(Count>0) {
WriteSound(Buffer,(Count<ocount) ? Count : ocount);
Count -= ocount;
}
}
}
} //else puts("Skipped");
// Fceux believes that audio buffer underflow only occurs with a network
// play, but NEMU runs too slow, which may also underflow the audio buffer.
// So we should add back the following code to handle such underflow.
// Note that we remove "&& FCEUDnetplay" in the condition.
else if(!NoWaiting && (uflow || tmpcan >= (Count * 9 / 5))) {
if(Count > tmpcan) Count=tmpcan;
while(tmpcan > 0) {
// printf("Overwrite: %d\n", (Count <= tmpcan)?Count : tmpcan);
WriteSound(Buffer, (Count <= tmpcan)?Count : tmpcan);
tmpcan -= Count;
}
}
} else {
if(!NoWaiting && (!(eoptions&EO_NOTHROTTLE) || FCEUI_EmulationPaused())) {
while (SpeedThrottle()) { FCEUD_UpdateInput(); }

View File

@ -400,6 +400,7 @@ void FCEUI_Kill(void) {
///Skip may be passed in, if FRAMESKIP is #defined, to cause this to emulate more than one frame
void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int skip) {
//skip initiates frame skip if 1, or frame skip and sound skip if 2
int ssize;
if (frameAdvanceRequested)
{
@ -421,6 +422,8 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski
// emulator is paused
memcpy(XBuf, XBackBuf, 256*256);
*pXBuf = XBuf;
*SoundBuf = WaveFinal;
*SoundBufSize = 0;
return;
}
}
@ -429,11 +432,20 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski
FCEUPPU_Loop(skip);
if (skip != 2) ssize = FlushEmulateSound(); //If skip = 2 we are skipping sound processing
timestampbase += timestamp;
timestamp = 0;
soundtimestamp = 0;
*pXBuf = skip ? 0 : XBuf;
if (skip == 2) { //If skip = 2, then bypass sound
*SoundBuf = 0;
*SoundBufSize = 0;
} else {
*SoundBuf = WaveFinal;
*SoundBufSize = ssize;
}
if ((EmulationPaused & EMULATIONPAUSED_FA) && (!frameAdvanceLagSkip))
//Lots of conditions here. EmulationPaused & EMULATIONPAUSED_FA must be true. In addition frameAdvanceLagSkip or lagFlag must be false
@ -450,7 +462,7 @@ void FCEUI_CloseGame(void) {
void ResetNES(void) {
if (!GameInfo) return;
GameInterface(GI_RESETM2);
//FCEUSND_Reset();
FCEUSND_Reset();
FCEUPPU_Reset();
X6502_Reset();
@ -488,7 +500,7 @@ void PowerNES(void) {
SetWriteHandler(0x800, 0x1FFF, BRAMH); //hack for a small speed boost.
InitializeInput();
//FCEUSND_Power();
FCEUSND_Power();
FCEUPPU_Power();
//Have the external game hardware "powered" after the internal NES stuff. Needed for the NSF code and VS System code.
@ -525,6 +537,7 @@ void FCEU_ResetVidSys(void) {
normalscanlines = (dendy ? 290 : 240)+newppu; // use flag as number!
totalscanlines = normalscanlines + (overclock_enabled ? postrenderscanlines : 0);
FCEUPPU_SetVideoSystem(w || dendy);
SetSoundVariables();
}
FCEUS FSettings;

1585
apps/fceux/src/fcoeffs.h Normal file

File diff suppressed because it is too large Load Diff

206
apps/fceux/src/filter.cpp Normal file
View File

@ -0,0 +1,206 @@
/// \file
/// \brief Sound filtering code
#include "types.h"
#include "sound.h"
#include "x6502.h"
#include "fceu.h"
#include "filter.h"
#include "fcoeffs.h"
static int32 sq2coeffs[SQ2NCOEFFS];
static int32 coeffs[NCOEFFS];
static uint32 mrindex;
static uint32 mrratio;
void SexyFilter2(int32 *in, int32 count)
{
#ifdef moo
static int64 acc=0;
double x,p;
int64 c;
x=2*M_PI*6000/FSettings.SndRate;
p=((double)2-cos(x)) - sqrt(pow((double)2-cos(x),2) -1 );
c=p*0x100000;
//printf("%f\n",(double)c/0x100000);
#endif
static int64 acc=0;
while(count--)
{
int64 dropcurrent;
dropcurrent=((*in<<16)-acc)>>3;
acc+=dropcurrent;
*in=acc>>16;
in++;
//acc=((int64)0x100000-c)* *in + ((c*acc)>>20);
//*in=acc>>20;
//in++;
}
}
void SexyFilter(int32 *in, int32 *out, int32 count)
{
static int64 acc1=0,acc2=0;
int32 mul1,mul2,vmul;
mul1=(94<<16)/FSettings.SndRate;
mul2=(24<<16)/FSettings.SndRate;
vmul=(FSettings.SoundVolume<<16)*3/4/100;
//FCEU_DispMessage("SoundVolume %d, vmul %d",0,FSettings.SoundVolume,vmul);
if(FSettings.soundq) vmul/=4;
else vmul*=2; /* TODO: Increase volume in low quality sound rendering code itself */
while(count)
{
int64 ino=(int64)*in*vmul;
acc1+=((ino-acc1)*mul1)>>16;
acc2+=((ino-acc1-acc2)*mul2)>>16;
//printf("%d ",*in);
*in=0;
{
int32 t=(acc1-ino+acc2)>>16;
//if(t>32767 || t<-32768) printf("Flow: %d\n",t);
if(t>32767) t=32767;
if(t<-32768) t=-32768;
*out=t;
}
in++;
out++;
count--;
}
}
/* Returns number of samples written to out. */
/* leftover is set to the number of samples that need to be copied
from the end of in to the beginning of in.
*/
//static uint32 mva=1000;
/* This filtering code assumes that almost all input values stay below 32767.
Do not adjust the volume in the wlookup tables and the expansion sound
code to be higher, or you *might* overflow the FIR code.
*/
int32 NeoFilterSound(int32 *in, int32 *out, uint32 inlen, int32 *leftover)
{
uint32 x;
uint32 max;
int32 *outsave=out;
int32 count=0;
// for(x=0;x<inlen;x++)
// {
// if(in[x]>mva){ mva=in[x]; printf("%ld\n",in[x]);}
// }
max=(inlen-1)<<16;
if(FSettings.soundq==2)
for(x=mrindex;x<max;x+=mrratio)
{
int32 acc=0,acc2=0;
unsigned int c;
int32 *S,*D;
for(c=SQ2NCOEFFS,S=&in[(x>>16)-SQ2NCOEFFS],D=sq2coeffs;c;c--,D++)
{
acc+=(S[c]**D)>>6;
acc2+=(S[1+c]**D)>>6;
}
acc=((int64)acc*(65536-(x&65535))+(int64)acc2*(x&65535))>>(16+11);
*out=acc;
out++;
count++;
}
else
for(x=mrindex;x<max;x+=mrratio)
{
int32 acc=0,acc2=0;
unsigned int c;
const int32 *S,*D;
for(c=NCOEFFS,S=&in[(x>>16)-NCOEFFS],D=coeffs;c;c--,D++)
{
acc+=(S[c]**D)>>6;
acc2+=(S[1+c]**D)>>6;
}
acc=((int64)acc*(65536-(x&65535))+(int64)acc2*(x&65535))>>(16+11);
*out=acc;
out++;
count++;
}
mrindex=x-max;
if(FSettings.soundq==2)
{
mrindex+=SQ2NCOEFFS*65536;
*leftover=SQ2NCOEFFS+1;
}
else
{
mrindex+=NCOEFFS*65536;
*leftover=NCOEFFS+1;
}
if(GameExpSound.NeoFill)
GameExpSound.NeoFill(outsave,count);
SexyFilter(outsave,outsave,count);
if(FSettings.lowpass)
SexyFilter2(outsave,count);
return(count);
}
void MakeFilters(int32 rate)
{
const int32 *tabs[6]={C44100NTSC,C44100PAL,C48000NTSC,C48000PAL,C96000NTSC,
C96000PAL};
const int32 *sq2tabs[6]={SQ2C44100NTSC,SQ2C44100PAL,SQ2C48000NTSC,SQ2C48000PAL,
SQ2C96000NTSC,SQ2C96000PAL};
const int32 *tmp;
int32 x;
uint32 nco;
if(FSettings.soundq==2)
nco=SQ2NCOEFFS;
else
nco=NCOEFFS;
mrindex=(nco+1)<<16;
mrratio=(PAL?(int64)(PAL_CPU*65536):(int64)(NTSC_CPU*65536))/rate;
if(FSettings.soundq==2)
tmp=sq2tabs[(PAL?1:0)|(rate==48000?2:0)|(rate==96000?4:0)];
else
tmp=tabs[(PAL?1:0)|(rate==48000?2:0)|(rate==96000?4:0)];
if(FSettings.soundq==2)
for(x=0;x<SQ2NCOEFFS>>1;x++)
sq2coeffs[x]=sq2coeffs[SQ2NCOEFFS-1-x]=tmp[x];
else
for(x=0;x<NCOEFFS>>1;x++)
coeffs[x]=coeffs[NCOEFFS-1-x]=tmp[x];
#ifdef MOO
/* Some tests involving precision and error. */
{
static int64 acc=0;
int x;
for(x=0;x<SQ2NCOEFFS;x++)
acc+=(int64)32767*sq2coeffs[x];
printf("Foo: %lld\n",acc);
}
#endif
}

3
apps/fceux/src/filter.h Normal file
View File

@ -0,0 +1,3 @@
int32 NeoFilterSound(int32 *in, int32 *out, uint32 inlen, int32 *leftover);
void MakeFilters(int32 rate);
void SexyFilter(int32 *in, int32 *out, int32 count);

View File

@ -0,0 +1 @@
appears to be related to http://gmeteor.sourceforge.net/index.html

View File

@ -0,0 +1,512 @@
116,
9,
9,
10,
10,
10,
10,
10,
10,
10,
10,
9,
9,
8,
8,
7,
6,
5,
4,
3,
2,
1,
0,
-1,
-2,
-4,
-5,
-7,
-9,
-10,
-12,
-14,
-16,
-18,
-20,
-22,
-24,
-25,
-27,
-29,
-31,
-33,
-34,
-36,
-37,
-39,
-40,
-41,
-42,
-43,
-44,
-44,
-44,
-45,
-45,
-44,
-44,
-43,
-42,
-41,
-40,
-39,
-37,
-35,
-33,
-30,
-28,
-25,
-22,
-18,
-15,
-11,
-7,
-3,
0,
4,
9,
13,
18,
22,
27,
32,
36,
41,
46,
50,
55,
59,
64,
68,
72,
76,
79,
82,
85,
88,
91,
93,
94,
96,
97,
97,
97,
97,
96,
95,
93,
91,
88,
85,
81,
77,
73,
68,
62,
56,
50,
43,
36,
28,
20,
12,
4,
-4,
-13,
-22,
-32,
-41,
-51,
-60,
-70,
-79,
-89,
-98,
-107,
-116,
-125,
-133,
-141,
-148,
-155,
-162,
-168,
-173,
-178,
-182,
-186,
-188,
-190,
-192,
-192,
-191,
-190,
-188,
-185,
-181,
-176,
-170,
-163,
-156,
-147,
-138,
-128,
-117,
-105,
-93,
-79,
-66,
-51,
-36,
-20,
-4,
11,
28,
45,
63,
80,
98,
115,
133,
150,
167,
183,
200,
215,
231,
245,
259,
272,
284,
295,
305,
314,
322,
328,
334,
338,
340,
341,
341,
339,
336,
331,
324,
316,
307,
296,
283,
269,
253,
236,
218,
198,
176,
154,
131,
106,
80,
54,
26,
-1,
-29,
-58,
-88,
-117,
-147,
-177,
-207,
-236,
-265,
-294,
-321,
-348,
-374,
-399,
-423,
-445,
-466,
-486,
-503,
-519,
-533,
-545,
-554,
-562,
-567,
-570,
-570,
-568,
-564,
-557,
-547,
-535,
-520,
-503,
-483,
-461,
-436,
-409,
-379,
-347,
-314,
-278,
-240,
-200,
-159,
-117,
-72,
-27,
18,
65,
113,
161,
210,
258,
306,
354,
402,
448,
494,
538,
581,
622,
661,
698,
733,
765,
795,
822,
846,
866,
883,
897,
907,
914,
916,
915,
910,
901,
887,
870,
848,
823,
793,
759,
722,
680,
635,
587,
534,
479,
420,
359,
295,
228,
159,
88,
15,
-58,
-134,
-210,
-287,
-364,
-441,
-518,
-593,
-668,
-741,
-813,
-882,
-949,
-1013,
-1074,
-1131,
-1185,
-1235,
-1280,
-1321,
-1357,
-1387,
-1412,
-1432,
-1446,
-1454,
-1456,
-1451,
-1440,
-1423,
-1400,
-1370,
-1333,
-1290,
-1241,
-1185,
-1123,
-1055,
-981,
-901,
-816,
-726,
-631,
-531,
-427,
-319,
-208,
-93,
24,
143,
265,
388,
511,
635,
759,
882,
1004,
1124,
1242,
1357,
1468,
1575,
1678,
1776,
1868,
1955,
2034,
2107,
2172,
2229,
2278,
2318,
2349,
2370,
2382,
2384,
2376,
2357,
2327,
2287,
2237,
2175,
2103,
2020,
1926,
1822,
1708,
1583,
1449,
1306,
1153,
992,
822,
645,
461,
270,
74,
-127,
-333,
-543,
-757,
-972,
-1189,
-1406,
-1623,
-1839,
-2052,
-2263,
-2469,
-2670,
-2866,
-3055,
-3235,
-3407,
-3569,
-3721,
-3861,
-3988,
-4102,
-4201,
-4286,
-4355,
-4407,
-4441,
-4458,
-4456,
-4434,
-4393,
-4331,
-4249,
-4145,
-4020,
-3873,
-3704,
-3512,
-3299,
-3063,
-2806,
-2526,
-2224,
-1900,
-1556,
-1190,
-804,
-398,
27,
471,
933,
1412,
1908,
2419,
2945,
3484,
4036,
4599,
5172,
5754,
6344,
6940,
7541,
8146,
8754,
9363,
9971,
10578,
11182,
11781,
12374,
12959,
13536,
14103,
14658,
15199,
15727,
16239,
16734,
17211,
17669,
18106,
18521,
18914,
19283,
19627,
19946,
20239,
20505,
20743,
20952,
21133,
21284,
21405,
21497,
21558,
21588,

View File

@ -0,0 +1,512 @@
-116,
-8,
-8,
-8,
-8,
-8,
-8,
-8,
-8,
-7,
-7,
-6,
-5,
-5,
-4,
-3,
-2,
-1,
0,
1,
2,
4,
5,
7,
9,
10,
12,
14,
16,
18,
19,
21,
23,
25,
27,
28,
30,
32,
33,
34,
36,
37,
38,
38,
39,
40,
40,
40,
40,
39,
39,
38,
37,
36,
34,
33,
31,
29,
26,
24,
21,
18,
14,
11,
7,
4,
0,
-3,
-8,
-12,
-16,
-21,
-25,
-29,
-34,
-38,
-43,
-47,
-51,
-55,
-59,
-62,
-66,
-69,
-72,
-75,
-77,
-79,
-80,
-81,
-82,
-83,
-83,
-82,
-81,
-80,
-78,
-75,
-72,
-69,
-65,
-61,
-56,
-51,
-45,
-39,
-33,
-26,
-19,
-11,
-4,
3,
12,
20,
29,
37,
46,
55,
64,
72,
81,
89,
97,
105,
112,
119,
126,
132,
138,
143,
147,
151,
154,
156,
158,
159,
159,
158,
157,
154,
151,
146,
141,
135,
128,
121,
112,
103,
93,
82,
70,
58,
45,
31,
17,
3,
-11,
-26,
-41,
-57,
-72,
-88,
-104,
-119,
-134,
-149,
-163,
-177,
-191,
-203,
-215,
-226,
-236,
-246,
-254,
-261,
-267,
-271,
-274,
-276,
-277,
-276,
-274,
-270,
-264,
-258,
-249,
-240,
-228,
-216,
-201,
-186,
-169,
-151,
-132,
-111,
-90,
-68,
-44,
-20,
3,
28,
54,
80,
106,
132,
158,
184,
209,
234,
258,
281,
304,
325,
345,
364,
381,
397,
411,
423,
433,
441,
447,
451,
453,
452,
449,
444,
436,
426,
413,
399,
381,
362,
340,
316,
289,
261,
231,
199,
165,
130,
93,
55,
16,
-23,
-63,
-104,
-145,
-187,
-228,
-269,
-310,
-349,
-388,
-425,
-461,
-495,
-528,
-558,
-586,
-612,
-635,
-655,
-673,
-687,
-698,
-705,
-709,
-710,
-707,
-700,
-690,
-675,
-657,
-636,
-610,
-581,
-549,
-513,
-473,
-431,
-385,
-336,
-285,
-232,
-176,
-118,
-59,
1,
64,
127,
190,
254,
318,
381,
444,
505,
566,
624,
680,
734,
786,
834,
879,
920,
957,
990,
1019,
1043,
1062,
1076,
1085,
1088,
1086,
1079,
1065,
1046,
1022,
991,
955,
913,
866,
814,
756,
693,
626,
554,
478,
398,
314,
228,
138,
46,
-47,
-143,
-240,
-337,
-435,
-532,
-628,
-723,
-817,
-907,
-995,
-1080,
-1161,
-1237,
-1309,
-1375,
-1436,
-1490,
-1538,
-1579,
-1612,
-1639,
-1657,
-1667,
-1669,
-1662,
-1647,
-1623,
-1590,
-1548,
-1498,
-1439,
-1372,
-1296,
-1212,
-1120,
-1020,
-913,
-800,
-680,
-553,
-422,
-286,
-145,
0,
146,
296,
447,
599,
752,
904,
1054,
1203,
1348,
1490,
1627,
1759,
1885,
2004,
2115,
2218,
2312,
2396,
2470,
2533,
2584,
2623,
2650,
2664,
2665,
2652,
2625,
2584,
2529,
2460,
2376,
2278,
2167,
2041,
1902,
1750,
1585,
1407,
1218,
1018,
808,
588,
359,
123,
-120,
-369,
-623,
-881,
-1142,
-1403,
-1665,
-1926,
-2184,
-2439,
-2688,
-2931,
-3166,
-3392,
-3607,
-3810,
-4000,
-4176,
-4335,
-4478,
-4602,
-4706,
-4790,
-4852,
-4891,
-4906,
-4897,
-4862,
-4801,
-4713,
-4598,
-4454,
-4283,
-4082,
-3853,
-3595,
-3308,
-2992,
-2647,
-2274,
-1873,
-1445,
-990,
-509,
-3,
527,
1081,
1657,
2254,
2870,
3505,
4156,
4823,
5504,
6196,
6898,
7609,
8326,
9048,
9773,
10498,
11222,
11943,
12658,
13366,
14065,
14753,
15427,
16086,
16728,
17351,
17953,
18533,
19088,
19616,
20118,
20590,
21032,
21441,
21818,
22160,
22467,
22738,
22971,
23167,
23324,
23443,
23522,
23561,

View File

@ -0,0 +1,512 @@
-115,
-12,
-13,
-14,
-14,
-14,
-15,
-15,
-15,
-15,
-15,
-15,
-15,
-15,
-14,
-14,
-13,
-12,
-11,
-10,
-9,
-8,
-7,
-5,
-3,
-2,
0,
1,
3,
5,
7,
10,
12,
14,
17,
19,
22,
24,
26,
29,
31,
33,
35,
37,
39,
41,
42,
44,
45,
46,
47,
48,
48,
48,
48,
48,
47,
47,
45,
44,
42,
40,
38,
35,
33,
30,
26,
23,
19,
15,
10,
6,
1,
-3,
-8,
-13,
-18,
-23,
-28,
-33,
-39,
-44,
-49,
-54,
-59,
-63,
-68,
-72,
-76,
-80,
-83,
-86,
-88,
-91,
-92,
-94,
-94,
-95,
-94,
-93,
-92,
-90,
-88,
-85,
-81,
-77,
-73,
-67,
-62,
-55,
-49,
-42,
-34,
-26,
-18,
-9,
0,
9,
18,
28,
38,
48,
57,
67,
77,
87,
96,
106,
114,
123,
131,
139,
146,
152,
158,
163,
168,
171,
174,
176,
177,
177,
177,
175,
172,
168,
164,
158,
151,
143,
135,
125,
115,
103,
91,
78,
65,
50,
35,
20,
3,
-12,
-29,
-46,
-63,
-80,
-98,
-115,
-132,
-148,
-165,
-180,
-196,
-210,
-224,
-237,
-248,
-259,
-269,
-277,
-285,
-290,
-295,
-298,
-299,
-299,
-297,
-294,
-289,
-282,
-274,
-264,
-252,
-239,
-224,
-208,
-190,
-171,
-151,
-129,
-106,
-82,
-57,
-31,
-5,
22,
49,
77,
105,
134,
162,
190,
217,
244,
270,
295,
320,
343,
365,
385,
404,
421,
436,
449,
460,
469,
475,
479,
481,
480,
477,
471,
462,
451,
437,
421,
402,
380,
357,
330,
302,
271,
238,
203,
167,
129,
89,
48,
6,
-35,
-79,
-123,
-167,
-211,
-255,
-298,
-341,
-383,
-423,
-462,
-500,
-535,
-569,
-600,
-628,
-654,
-677,
-697,
-713,
-726,
-735,
-741,
-743,
-741,
-735,
-725,
-711,
-693,
-671,
-645,
-616,
-582,
-545,
-504,
-459,
-412,
-361,
-307,
-251,
-192,
-132,
-69,
-5,
60,
126,
193,
260,
328,
394,
460,
525,
588,
650,
709,
765,
819,
869,
916,
958,
997,
1031,
1060,
1084,
1103,
1116,
1124,
1126,
1123,
1113,
1097,
1075,
1047,
1013,
973,
928,
876,
819,
756,
689,
616,
539,
457,
372,
283,
190,
95,
-1,
-100,
-201,
-302,
-404,
-506,
-607,
-706,
-804,
-900,
-993,
-1082,
-1167,
-1248,
-1324,
-1395,
-1459,
-1517,
-1569,
-1613,
-1649,
-1678,
-1698,
-1710,
-1713,
-1707,
-1692,
-1667,
-1634,
-1591,
-1539,
-1478,
-1408,
-1329,
-1242,
-1146,
-1043,
-931,
-813,
-688,
-556,
-419,
-277,
-131,
19,
172,
328,
485,
643,
801,
958,
1113,
1266,
1416,
1561,
1702,
1836,
1964,
2085,
2197,
2300,
2393,
2476,
2548,
2608,
2656,
2690,
2712,
2720,
2713,
2692,
2657,
2607,
2542,
2462,
2367,
2257,
2133,
1994,
1842,
1676,
1497,
1305,
1102,
888,
663,
430,
187,
-61,
-317,
-579,
-844,
-1113,
-1383,
-1653,
-1922,
-2189,
-2452,
-2709,
-2960,
-3203,
-3437,
-3659,
-3869,
-4065,
-4245,
-4409,
-4556,
-4682,
-4789,
-4873,
-4935,
-4973,
-4986,
-4972,
-4933,
-4865,
-4770,
-4646,
-4492,
-4309,
-4096,
-3853,
-3579,
-3276,
-2942,
-2578,
-2185,
-1763,
-1313,
-835,
-330,
200,
755,
1335,
1937,
2560,
3203,
3864,
4543,
5236,
5942,
6660,
7387,
8122,
8863,
9608,
10354,
11099,
11842,
12580,
13311,
14033,
14745,
15443,
16125,
16791,
17436,
18061,
18663,
19239,
19789,
20310,
20801,
21261,
21687,
22079,
22435,
22755,
23037,
23281,
23485,
23649,
23772,
23854,
23896,

View File

@ -0,0 +1,512 @@
113,
14,
15,
15,
16,
16,
17,
17,
18,
18,
18,
18,
18,
17,
17,
16,
16,
15,
14,
12,
11,
10,
8,
6,
4,
2,
0,
-1,
-3,
-6,
-8,
-11,
-13,
-16,
-18,
-21,
-24,
-26,
-29,
-31,
-33,
-35,
-37,
-39,
-41,
-42,
-44,
-45,
-46,
-46,
-47,
-47,
-46,
-46,
-45,
-44,
-42,
-40,
-38,
-36,
-33,
-30,
-26,
-23,
-19,
-15,
-10,
-6,
-1,
3,
8,
13,
19,
24,
29,
35,
40,
45,
50,
55,
60,
64,
68,
72,
75,
79,
81,
83,
85,
86,
87,
87,
87,
86,
84,
82,
79,
76,
72,
67,
62,
56,
50,
43,
36,
28,
20,
11,
2,
-6,
-15,
-25,
-34,
-44,
-54,
-63,
-73,
-82,
-91,
-100,
-109,
-117,
-124,
-131,
-137,
-142,
-147,
-151,
-154,
-156,
-158,
-158,
-157,
-156,
-153,
-149,
-145,
-139,
-132,
-124,
-115,
-105,
-95,
-83,
-71,
-58,
-44,
-29,
-14,
0,
16,
32,
48,
65,
81,
98,
114,
129,
145,
159,
174,
187,
199,
211,
221,
231,
239,
246,
251,
255,
257,
258,
257,
255,
251,
245,
237,
228,
217,
205,
191,
175,
158,
140,
120,
99,
77,
54,
30,
6,
-19,
-44,
-70,
-96,
-123,
-148,
-174,
-199,
-223,
-247,
-269,
-291,
-311,
-329,
-346,
-361,
-374,
-385,
-393,
-400,
-404,
-406,
-405,
-401,
-395,
-387,
-376,
-362,
-346,
-327,
-306,
-282,
-256,
-228,
-198,
-166,
-133,
-98,
-61,
-23,
14,
53,
93,
133,
173,
212,
251,
290,
327,
363,
397,
430,
461,
489,
515,
538,
558,
575,
589,
600,
607,
610,
609,
605,
597,
585,
569,
549,
526,
498,
467,
432,
395,
353,
309,
262,
213,
161,
107,
51,
-5,
-63,
-122,
-181,
-240,
-299,
-357,
-414,
-469,
-523,
-575,
-623,
-669,
-712,
-751,
-786,
-817,
-843,
-865,
-881,
-893,
-899,
-899,
-894,
-884,
-867,
-845,
-817,
-784,
-745,
-701,
-651,
-597,
-537,
-474,
-406,
-334,
-259,
-181,
-100,
-17,
67,
152,
239,
325,
412,
497,
581,
663,
742,
818,
890,
959,
1022,
1081,
1133,
1180,
1220,
1254,
1280,
1299,
1310,
1313,
1308,
1295,
1273,
1243,
1205,
1159,
1104,
1042,
972,
894,
809,
718,
621,
517,
409,
296,
179,
58,
-64,
-190,
-316,
-443,
-570,
-696,
-820,
-941,
-1059,
-1173,
-1281,
-1384,
-1480,
-1569,
-1649,
-1722,
-1785,
-1838,
-1881,
-1912,
-1933,
-1942,
-1939,
-1924,
-1897,
-1858,
-1806,
-1741,
-1665,
-1576,
-1476,
-1365,
-1243,
-1110,
-968,
-816,
-657,
-490,
-316,
-136,
47,
235,
426,
619,
811,
1003,
1193,
1380,
1563,
1740,
1910,
2072,
2225,
2368,
2499,
2618,
2723,
2814,
2889,
2949,
2991,
3016,
3022,
3010,
2979,
2929,
2859,
2769,
2660,
2531,
2384,
2217,
2032,
1830,
1611,
1376,
1126,
862,
585,
297,
0,
-307,
-621,
-940,
-1262,
-1586,
-1910,
-2232,
-2550,
-2862,
-3165,
-3459,
-3740,
-4007,
-4258,
-4491,
-4703,
-4893,
-5059,
-5200,
-5313,
-5396,
-5449,
-5470,
-5457,
-5409,
-5326,
-5206,
-5048,
-4853,
-4618,
-4345,
-4032,
-3681,
-3290,
-2861,
-2393,
-1888,
-1347,
-769,
-158,
486,
1162,
1868,
2602,
3362,
4146,
4952,
5777,
6619,
7475,
8342,
9219,
10102,
10988,
11874,
12757,
13635,
14504,
15361,
16204,
17029,
17833,
18615,
19370,
20096,
20790,
21451,
22075,
22660,
23205,
23707,
24164,
24574,
24937,
25250,
25513,
25725,
25884,
25991,
26044,

View File

@ -0,0 +1,512 @@
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,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
0,
0,
0,
0,
0,
0,
-1,
-1,
-2,
-2,
-2,
-3,
-3,
-3,
-3,
-3,
-3,
-3,
-3,
-3,
-2,
-2,
-1,
-1,
0,
0,
1,
2,
3,
4,
4,
5,
6,
6,
7,
7,
7,
7,
7,
7,
6,
6,
5,
4,
2,
1,
0,
-1,
-3,
-5,
-6,
-8,
-10,
-11,
-12,
-13,
-14,
-14,
-14,
-14,
-14,
-13,
-11,
-10,
-8,
-6,
-3,
0,
1,
4,
7,
10,
13,
16,
18,
21,
22,
24,
25,
25,
25,
24,
23,
21,
18,
15,
12,
8,
3,
-1,
-6,
-11,
-16,
-20,
-25,
-29,
-33,
-36,
-39,
-41,
-42,
-42,
-41,
-39,
-36,
-32,
-27,
-22,
-15,
-8,
-1,
6,
14,
22,
30,
37,
44,
51,
56,
60,
64,
65,
66,
65,
62,
58,
53,
46,
38,
28,
18,
6,
-4,
-17,
-29,
-41,
-53,
-64,
-74,
-83,
-90,
-95,
-99,
-100,
-100,
-97,
-91,
-84,
-74,
-62,
-49,
-33,
-17,
0,
18,
36,
55,
72,
89,
104,
118,
129,
138,
144,
148,
148,
144,
138,
128,
114,
98,
79,
58,
34,
9,
-16,
-42,
-69,
-95,
-120,
-143,
-163,
-181,
-195,
-205,
-211,
-212,
-209,
-201,
-188,
-171,
-149,
-124,
-94,
-62,
-27,
8,
46,
84,
121,
156,
189,
219,
245,
267,
283,
294,
298,
295,
287,
271,
249,
221,
187,
148,
104,
57,
7,
-44,
-96,
-148,
-198,
-245,
-288,
-326,
-358,
-382,
-400,
-408,
-408,
-399,
-381,
-354,
-318,
-274,
-223,
-165,
-102,
-35,
34,
105,
175,
244,
309,
370,
424,
470,
507,
533,
549,
553,
545,
524,
492,
447,
392,
326,
252,
169,
81,
-10,
-105,
-200,
-293,
-383,
-466,
-541,
-606,
-660,
-700,
-726,
-737,
-732,
-710,
-672,
-619,
-550,
-467,
-372,
-266,
-152,
-31,
93,
219,
344,
464,
577,
680,
771,
847,
907,
948,
970,
970,
949,
907,
843,
760,
657,
537,
403,
256,
99,
-62,
-228,
-392,
-552,
-704,
-845,
-970,
-1077,
-1164,
-1226,
-1264,
-1274,
-1257,
-1211,
-1138,
-1038,
-912,
-763,
-593,
-407,
-206,
3,
219,
435,
647,
851,
1040,
1212,
1361,
1484,
1578,
1639,
1666,
1656,
1610,
1528,
1409,
1257,
1073,
860,
623,
367,
95,
-184,
-468,
-749,
-1020,
-1277,
-1512,
-1719,
-1894,
-2033,
-2130,
-2182,
-2188,
-2146,
-2056,
-1918,
-1734,
-1507,
-1240,
-939,
-610,
-257,
109,
484,
859,
1225,
1574,
1898,
2190,
2441,
2646,
2798,
2893,
2926,
2897,
2802,
2643,
2421,
2140,
1803,
1416,
986,
522,
32,
-472,
-983,
-1487,
-1974,
-2433,
-2853,
-3223,
-3534,
-3777,
-3944,
-4030,
-4029,
-3940,
-3760,
-3492,
-3137,
-2701,
-2189,
-1611,
-977,
-298,
411,
1139,
1868,
2584,
3270,
3910,
4489,
4991,
5404,
5713,
5909,
5982,
5926,
5735,
5409,
4948,
4356,
3639,
2808,
1873,
851,
-241,
-1385,
-2559,
-3738,
-4899,
-6016,
-7064,
-8015,
-8845,
-9529,
-10043,
-10366,
-10479,
-10363,
-10006,
-9397,
-8529,
-7398,
-6005,
-4355,
-2456,
-320,
2033,
4587,
7316,
10193,
13188,
16268,
19400,
22548,
25673,
28740,
31710,
34547,
37216,
39683,
41916,
43887,
45570,
46943,
47990,
48695,
49050,

View File

@ -0,0 +1,512 @@
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,
-1,
-1,
-1,
-1,
-1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
1,
1,
1,
2,
2,
2,
2,
2,
2,
2,
2,
2,
1,
1,
0,
0,
0,
0,
-1,
-1,
-2,
-3,
-3,
-4,
-4,
-5,
-5,
-5,
-5,
-5,
-5,
-4,
-4,
-3,
-2,
-1,
0,
0,
1,
2,
4,
5,
6,
7,
8,
9,
10,
10,
10,
10,
10,
9,
8,
7,
6,
4,
2,
0,
-1,
-4,
-6,
-8,
-11,
-13,
-15,
-16,
-18,
-19,
-19,
-19,
-19,
-18,
-17,
-15,
-13,
-10,
-6,
-3,
0,
4,
8,
12,
17,
20,
24,
27,
30,
32,
33,
34,
34,
33,
31,
28,
25,
20,
15,
9,
3,
-3,
-10,
-17,
-24,
-31,
-37,
-43,
-48,
-52,
-55,
-57,
-57,
-56,
-54,
-50,
-45,
-38,
-30,
-21,
-11,
0,
10,
21,
33,
44,
55,
64,
73,
80,
86,
90,
92,
91,
88,
84,
76,
67,
56,
42,
27,
11,
-5,
-23,
-41,
-59,
-76,
-92,
-106,
-119,
-129,
-136,
-141,
-142,
-140,
-134,
-125,
-112,
-96,
-77,
-56,
-32,
-6,
19,
47,
74,
100,
125,
149,
169,
186,
199,
208,
213,
212,
206,
195,
179,
158,
132,
102,
68,
32,
-6,
-46,
-86,
-126,
-164,
-200,
-232,
-259,
-282,
-298,
-308,
-311,
-307,
-294,
-275,
-248,
-214,
-173,
-128,
-77,
-23,
33,
91,
149,
205,
258,
307,
350,
386,
415,
434,
443,
442,
431,
408,
375,
332,
280,
219,
151,
76,
-1,
-82,
-164,
-245,
-322,
-394,
-459,
-515,
-561,
-595,
-615,
-622,
-613,
-590,
-552,
-499,
-433,
-354,
-264,
-165,
-59,
51,
164,
277,
387,
490,
586,
670,
741,
797,
835,
854,
853,
832,
790,
729,
647,
548,
433,
304,
163,
15,
-138,
-293,
-445,
-592,
-729,
-852,
-959,
-1046,
-1111,
-1151,
-1165,
-1151,
-1110,
-1040,
-944,
-822,
-677,
-512,
-329,
-133,
71,
280,
489,
693,
886,
1063,
1220,
1353,
1458,
1530,
1569,
1571,
1535,
1462,
1352,
1206,
1027,
818,
584,
328,
57,
-222,
-505,
-785,
-1054,
-1306,
-1534,
-1733,
-1896,
-2019,
-2097,
-2128,
-2108,
-2038,
-1917,
-1747,
-1529,
-1269,
-970,
-639,
-283,
90,
474,
857,
1233,
1590,
1921,
2216,
2467,
2667,
2810,
2890,
2904,
2849,
2724,
2530,
2270,
1946,
1566,
1135,
664,
160,
-363,
-895,
-1425,
-1938,
-2423,
-2866,
-3256,
-3582,
-3834,
-4003,
-4082,
-4067,
-3953,
-3741,
-3431,
-3028,
-2537,
-1967,
-1328,
-632,
106,
871,
1646,
2413,
3154,
3849,
4482,
5034,
5489,
5833,
6051,
6134,
6074,
5864,
5504,
4994,
4339,
3546,
2628,
1599,
477,
-716,
-1958,
-3223,
-4482,
-5708,
-6869,
-7936,
-8878,
-9666,
-10273,
-10671,
-10839,
-10755,
-10402,
-9767,
-8843,
-7623,
-6110,
-4308,
-2228,
114,
2701,
5505,
8499,
11650,
14923,
18277,
21673,
25068,
28417,
31678,
34807,
37762,
40502,
42991,
45192,
47076,
48617,
49792,
50584,
50983,

1375
apps/fceux/src/sound.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,13 @@
#include "types.h"
#include "sound.h"
uint32 soundtsoffs = 0;
uint32 soundtsinc = 1;
bool DMC_7bit = 0;
EXPSOUND GameExpSound = {};
int32 WaveHi[40000] = {};
int32 Wave[2048+512] = {};
int32 nesincsize=0;
//uint32 soundtsoffs = 0;
//uint32 soundtsinc = 1;
//bool DMC_7bit = 0;
//EXPSOUND GameExpSound = {};
//int32 WaveHi[40000] = {};
//int32 Wave[2048+512] = {};
//int32 nesincsize=0;
uint8 *UNIFchrrama = 0;
void AddExState(void *v, uint32 s, int type, const char *desc) { }

View File

@ -484,15 +484,18 @@ extern int test; test++;
_tcount=0;
if(MapIRQHook) MapIRQHook(temp);
if (!overclocking)
FCEU_SoundCPUHook(temp);
uint32 lastPC = _PC;
_PC++;
switch(b1)
{
#include "ops.inc"
}
if (lastPC == _PC) {
if (lastPC == _PC && _count > 0) {
// spinning, just finish the run
_count = 0;
ADDCYC(_count / 48);
}
}
}

View File

@ -283,17 +283,19 @@ __umoddi3(du_int a, du_int b)
}
#include <klib.h>
// for more details, refer to
// https://gcc.gnu.org/onlinedocs/gccint/Integer-library-routines.html
// only use for linking
int __clzsi2 (unsigned int a) {
_halt(1);
if (a == 0) return 0;
int bit = 31;
while ((a & (1 << bit)) == 0) bit --;
return bit;
}
int __ctzsi2 (unsigned int a) {
_halt(1);
if (a == 0) return 0;
int bit = 0;
while ((a & (1 << bit)) == 0) bit ++;
return bit;
}

View File

@ -28,24 +28,30 @@ int atoi(const char* nptr) {
return x;
}
static struct {
void *ptr;
uintptr_t size;
} last = { .ptr = NULL, .size = 0 };
void *malloc(size_t size) {
static void *head = NULL;
if (head == NULL) {
head = _heap.start;
printf("heap start = %x\n", head);
if (last.ptr == NULL) {
last.ptr = _heap.start;
printf("heap start = %x\n", last.ptr);
}
// aligning
size = ROUNDUP(size, sizeof(uintptr_t));
if (head + size >= _heap.end) return NULL;
printf("malloc: size = %d\n", size);
void *ret = head;
head += size;
// skip the region allocated by the last call
last.ptr += last.size;
if (last.ptr + size >= _heap.end) return NULL;
void *ret = last.ptr;
last.size = size;
return ret;
}
void free(void *ptr) {
if (ptr == last.ptr) last.size = 0;
}
#endif

View File

@ -1,4 +1,4 @@
NAME := amtest
SRCS := $(shell find -L ./src/ -name "*.c")
SRCS := $(shell find -L ./src/ -name "*.[cS]")
include $(AM_HOME)/Makefile.app

View File

@ -11,6 +11,7 @@ static const char *tests[256] = {
['t'] = "real-time clock test",
['k'] = "readkey test",
['v'] = "display test",
['a'] = "audio test",
['p'] = "x86 virtual memory test",
};
@ -23,6 +24,7 @@ int main(const char *args) {
CASE('t', rtc_test, IOE);
CASE('k', keyboard_test, IOE);
CASE('v', video_test, IOE);
CASE('a', audio_test, IOE);
CASE('p', vm_test, CTE(vm_handler), VME(simple_pgalloc, simple_pgfree));
case 'H':
default:

View File

@ -0,0 +1,31 @@
#include <amtest.h>
#include <amdev.h>
void audio_test() {
_DEV_AUDIO_INIT_t init;
init.freq = 8000;
init.channels = 1;
init.samples = 1024;
init.bufsize = 8192;
_io_write(_DEV_AUDIO, _DEVREG_AUDIO_INIT, &init, sizeof(init));
extern uint8_t audio_payload, audio_payload_end;
uint32_t audio_len = &audio_payload_end - &audio_payload;
_DEV_AUDIO_SBCTRL_t ctl;
int nplay = 0;
ctl.stream = &audio_payload;
ctl.wait = 1;
while (nplay < audio_len) {
ctl.len = (audio_len - nplay > 4096 ? 4096 : audio_len - nplay);
_io_write(_DEV_AUDIO, _DEVREG_AUDIO_SBCTRL, &ctl, sizeof(ctl));
ctl.stream += ctl.len;
nplay += ctl.len;
printf("Already play %d/%d bytes of data\n", nplay, audio_len);
}
// wait until the audio finishes
_DEV_AUDIO_SBSTAT_t stat;
do {
_io_read(_DEV_AUDIO, _DEVREG_AUDIO_SBSTAT, &stat, sizeof(stat));
} while (stat.count > 0);
}

View File

@ -0,0 +1,6 @@
.section .data
.global audio_payload, audio_payload_end
.p2align 3
audio_payload:
.incbin "src/tests/audio/little-star.pcm"
audio_payload_end:

Binary file not shown.