fix sound freq drifting
This commit is contained in:
parent
d0a8583460
commit
43bcf15b37
3 changed files with 129 additions and 62 deletions
|
|
@ -36,16 +36,6 @@ void init_sound_table16(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_sound_table8 (void)
|
|
||||||
{
|
|
||||||
#ifdef HAS_TABLE
|
|
||||||
int i,j;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
for (j = 0; j < 64; j++)
|
|
||||||
sound_table[i][j] = (j * (uae_s8)i) / 256;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void AUDxDAT(int nr, uae_u16 v)
|
void AUDxDAT(int nr, uae_u16 v)
|
||||||
{
|
{
|
||||||
|
|
@ -122,32 +112,7 @@ void sample16_handler(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void sample8_handler(void)
|
|
||||||
{
|
|
||||||
#ifndef DONT_WANT_SOUND
|
|
||||||
int nr, adk;
|
|
||||||
uae_u32 data = SOUND8_BASE_VAL;
|
|
||||||
|
|
||||||
eventtab[ev_sample].evtime = cycles + sample_evtime;
|
|
||||||
eventtab[ev_sample].oldcycles = cycles;
|
|
||||||
|
|
||||||
adk = adkcon;
|
|
||||||
|
|
||||||
#ifdef HAS_TABLE
|
|
||||||
if (!(adk & 0x11))
|
|
||||||
data += sound_table[audio_channel[0].current_sample][audio_channel[0].vol];
|
|
||||||
if (!(adk & 0x22))
|
|
||||||
data += sound_table[audio_channel[1].current_sample][audio_channel[1].vol];
|
|
||||||
if (!(adk & 0x44))
|
|
||||||
data += sound_table[audio_channel[2].current_sample][audio_channel[2].vol];
|
|
||||||
if (!(adk & 0x88))
|
|
||||||
data += sound_table[audio_channel[3].current_sample][audio_channel[3].vol];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PUT_SOUND_BYTE (data);
|
|
||||||
check_sound_buffers ();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAS_ULAW
|
#ifdef HAS_ULAW
|
||||||
static uae_u8 int2ulaw(int ch)
|
static uae_u8 int2ulaw(int ch)
|
||||||
|
|
|
||||||
|
|
@ -7,26 +7,24 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define sndbufsize 8192
|
#define sndbufsize 4096 //1024 //8192 //2048 //2048
|
||||||
|
|
||||||
extern int sound_fd;
|
extern int sound_fd;
|
||||||
extern uae_u16 sndbuffer[];
|
extern uae_u16 sndbuffer[];
|
||||||
extern uae_u16 *sndbufpt;
|
extern uae_u32 sndbufpt;
|
||||||
|
|
||||||
|
|
||||||
static __inline__ void check_sound_buffers (void)
|
static __inline__ void check_sound_buffers (void)
|
||||||
{
|
{
|
||||||
if (sndbufpt - sndbuffer >= sndbufsize) {
|
if (sndbufpt >= sndbufsize) {
|
||||||
//write (sound_fd, sndbuffer, sndbufsize);
|
//write (sound_fd, sndbuffer, sndbufsize);
|
||||||
sndbufpt = sndbuffer;
|
sndbufpt = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define PUT_SOUND_BYTE(b) do { *(uae_u8 *)sndbufpt = b; sndbufpt = (uae_u16 *)(((uae_u8 *)sndbufpt) + 1); } while (0)
|
#define PUT_SOUND_WORD(b) do { sndbuffer[sndbufpt] = b; sndbufpt +=1; } while (0)
|
||||||
#define PUT_SOUND_WORD(b) do { *(uae_u16 *)sndbufpt = b; sndbufpt = (uae_u16 *)(((uae_u8 *)sndbufpt) + 2); } while (0)
|
|
||||||
#define SOUND16_BASE_VAL 0
|
#define SOUND16_BASE_VAL 0
|
||||||
#define SOUND8_BASE_VAL 128
|
|
||||||
|
|
||||||
#define DEFAULT_SOUND_MAXB 8192
|
#define DEFAULT_SOUND_MAXB 8192
|
||||||
#define DEFAULT_SOUND_MINB 8192
|
#define DEFAULT_SOUND_MINB 8192
|
||||||
|
|
|
||||||
|
|
@ -300,7 +300,9 @@ void uae_Input(int bClick) {
|
||||||
if (bClick & MASK_KEY_USER2) {
|
if (bClick & MASK_KEY_USER2) {
|
||||||
if (isMouse) isMouse = false;
|
if (isMouse) isMouse = false;
|
||||||
else isMouse = true;
|
else isMouse = true;
|
||||||
|
#ifndef HAS_T4_VGA
|
||||||
emu_setKeymap(0);
|
emu_setKeymap(0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Diskswap in joystick mode
|
// Diskswap in joystick mode
|
||||||
|
|
@ -405,13 +407,6 @@ void emu_KeyboardOnUp(int keymodifer, int key) {
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
uae_u16 sndbuffer[sndbufsize];
|
|
||||||
uae_u16 * sndbufpt;
|
|
||||||
static uae_u32 *sndbuffer32=(uae_u32 *)sndbuffer;
|
|
||||||
static uae_u32 sndbufrdpt=sndbufsize/4;
|
|
||||||
static uae_u32 sndinc=0x100; // default read increment
|
|
||||||
#define sndbufrdmask ((sndbufsize/2-1)<<8)+0xff
|
|
||||||
|
|
||||||
void read_joystick(int nr, unsigned int *dir, int *button)
|
void read_joystick(int nr, unsigned int *dir, int *button)
|
||||||
{
|
{
|
||||||
int left = 0, right = 0, top = 0, bot = 0;
|
int left = 0, right = 0, top = 0, bot = 0;
|
||||||
|
|
@ -456,14 +451,124 @@ void flush_line(int y)
|
||||||
|
|
||||||
void flush_block(int ystart,int ystop){}
|
void flush_block(int ystart,int ystop){}
|
||||||
|
|
||||||
|
|
||||||
|
uae_u16 sndbuffer[sndbufsize];
|
||||||
|
uae_u32 sndbufpt;
|
||||||
|
static uae_u32 psndbufpt=0;
|
||||||
|
|
||||||
|
static uae_u32 *sndbuffer32=(uae_u32 *)sndbuffer;
|
||||||
|
static uae_u32 sndbufrdpt=(sndbufsize/2)<<8;
|
||||||
|
static uae_u32 psndbufrdpt=(sndbufsize/2)<<8;
|
||||||
|
static uae_u32 sndbufrdcnt=0;
|
||||||
|
|
||||||
|
static uae_u32 sndinc=0x100; // default read increment
|
||||||
|
#define sndbufrdmask ((sndbufsize/2-1)<<8)+0xff
|
||||||
|
|
||||||
|
|
||||||
|
#define AVG_COUNT 16
|
||||||
|
static int avgcounter = AVG_COUNT;
|
||||||
|
static uae_u32 avgr=0;
|
||||||
|
static uae_u32 avgw=0;
|
||||||
|
static uae_u32 inc = (0x378<<8)/(0x2E0); //(wdelta<<8)/(0x2E0);
|
||||||
|
|
||||||
|
// distance between read and write buffer
|
||||||
|
static long incdelta=0;
|
||||||
|
static long pdelta=0x1000;
|
||||||
|
static bool pdown=true;
|
||||||
|
|
||||||
|
|
||||||
void flush_screen(int ystart,int ystop)
|
void flush_screen(int ystart,int ystop)
|
||||||
{
|
{
|
||||||
uae_u32 loc = (sndbufpt-sndbuffer)/2;
|
|
||||||
int delta = (sndbufrdpt>>8)-loc;
|
|
||||||
if (delta < 0) delta = (sndbufrdpt>>8) + (sndbufsize/2)-loc;
|
|
||||||
sndinc=((sndbufsize/4)<<8)/delta;
|
|
||||||
|
|
||||||
emu_DrawVsync();
|
emu_DrawVsync();
|
||||||
|
|
||||||
|
// #sample written per frame
|
||||||
|
int wdelta = 0;
|
||||||
|
uae_u32 wdpt = sndbufpt;
|
||||||
|
if (wdpt > psndbufpt) {
|
||||||
|
wdelta = wdpt-psndbufpt;
|
||||||
|
}
|
||||||
|
else if (wdpt < psndbufpt) {
|
||||||
|
wdelta = wdpt + sndbufsize - psndbufpt;
|
||||||
|
}
|
||||||
|
psndbufpt = wdpt;
|
||||||
|
|
||||||
|
// #sample read per frame
|
||||||
|
int rdelta = sndbufrdcnt;
|
||||||
|
sndbufrdcnt = 0;
|
||||||
|
/*
|
||||||
|
int rdelta = 0;
|
||||||
|
uae_u32 rdpt = sndbufrdpt>>8;
|
||||||
|
if (rdpt > psndbufrdpt) {
|
||||||
|
rdelta = rdpt-psndbufrdpt;
|
||||||
|
}
|
||||||
|
else if (rdpt < psndbufrdpt) {
|
||||||
|
rdelta = rdpt + sndbufsize/2 - psndbufrdpt;
|
||||||
|
}
|
||||||
|
psndbufrdpt = rdpt;
|
||||||
|
*/
|
||||||
|
|
||||||
|
inc = (wdelta<<8)/(0x2E0);
|
||||||
|
|
||||||
|
// Compute average R/W over AVG_COUNT frame
|
||||||
|
avgcounter--;
|
||||||
|
avgw += wdelta;
|
||||||
|
avgr += rdelta;
|
||||||
|
if (avgcounter == 0) {
|
||||||
|
wdelta = avgw/AVG_COUNT;
|
||||||
|
rdelta = avgr/AVG_COUNT;
|
||||||
|
avgw = 0;
|
||||||
|
avgr = 0;
|
||||||
|
avgcounter = AVG_COUNT;
|
||||||
|
|
||||||
|
//emu_printi(wdelta);
|
||||||
|
//emu_printi(rdelta);
|
||||||
|
//inc = (wdelta<<8)/(rdelta);
|
||||||
|
|
||||||
|
uae_u32 xwrpt = sndbufpt;
|
||||||
|
uae_u32 xrdpt = (sndbufrdpt>>8)*2;
|
||||||
|
uae_u32 delta = 0;
|
||||||
|
if (xrdpt > xwrpt) {
|
||||||
|
delta = xrdpt-xwrpt;
|
||||||
|
}
|
||||||
|
else if (xrdpt < xwrpt) {
|
||||||
|
delta = xrdpt + sndbufsize - xwrpt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we try to be keep read and write buffer at half distance of each other
|
||||||
|
bool down;
|
||||||
|
if (delta < pdelta) {
|
||||||
|
down = true;
|
||||||
|
if (delta < (sndbufsize/2-0x100)) {
|
||||||
|
if ( (down) && (pdown) )
|
||||||
|
incdelta += 2;
|
||||||
|
else
|
||||||
|
incdelta = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (delta > pdelta) {
|
||||||
|
down = false;
|
||||||
|
if (delta > (sndbufsize/2+0x100)) {
|
||||||
|
if ( (!down) && (!pdown) )
|
||||||
|
incdelta -= 2;
|
||||||
|
else
|
||||||
|
incdelta = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Hard reset sound buffer?
|
||||||
|
if ( (delta < sndbufsize/4) || (delta > (sndbufsize-sndbufsize/4)) ) {
|
||||||
|
memset(sndbuffer,sizeof(sndbuffer),0);
|
||||||
|
sndbufpt = 0;
|
||||||
|
sndbufrdpt=(sndbufsize/2)<<8;
|
||||||
|
psndbufrdpt=(sndbufsize/2)<<8;
|
||||||
|
delta = sndbufsize/2;
|
||||||
|
}
|
||||||
|
pdelta = delta;
|
||||||
|
pdown = down;
|
||||||
|
//emu_printi(delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
sndinc=inc+incdelta;
|
||||||
|
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -494,6 +599,7 @@ void SND_Process(void *stream, int len) {
|
||||||
uae_u32 s = sndbuffer32[sndbufrdpt>>8];
|
uae_u32 s = sndbuffer32[sndbufrdpt>>8];
|
||||||
*data++ = (s >> 16);
|
*data++ = (s >> 16);
|
||||||
*data++ = (s & 0xffff);
|
*data++ = (s & 0xffff);
|
||||||
|
sndbufrdcnt += 2;
|
||||||
sndbufrdpt += sndinc;
|
sndbufrdpt += sndinc;
|
||||||
sndbufrdpt &= sndbufrdmask;
|
sndbufrdpt &= sndbufrdmask;
|
||||||
}
|
}
|
||||||
|
|
@ -504,14 +610,12 @@ int init_sound (void)
|
||||||
{
|
{
|
||||||
currprefs.sound_maxbsiz = sndbufsize;
|
currprefs.sound_maxbsiz = sndbufsize;
|
||||||
sample_evtime = (long)maxhpos * maxvpos * 50 / currprefs.sound_freq;
|
sample_evtime = (long)maxhpos * maxvpos * 50 / currprefs.sound_freq;
|
||||||
init_sound_table16 ();
|
init_sound_table16();
|
||||||
eventtab[ev_sample].handler = sample16_handler;
|
eventtab[ev_sample].handler = sample16_handler;
|
||||||
int i;
|
memset(sndbuffer,sizeof(sndbuffer),0);
|
||||||
for (i=0;i<sndbufsize;i++) {
|
sndbufpt = 0;
|
||||||
sndbuffer[i] = 0;
|
sndbufrdpt=(sndbufsize/2)<<8;
|
||||||
}
|
psndbufrdpt=(sndbufsize/2)<<8;
|
||||||
sndbufpt = sndbuffer;
|
|
||||||
sndbufrdpt=(sndbufsize/4)<<8;
|
|
||||||
sound_available = 1;
|
sound_available = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue