fix sound freq drifting

This commit is contained in:
jean-marcharvengt 2020-10-29 23:13:01 +01:00
parent d0a8583460
commit 43bcf15b37
3 changed files with 129 additions and 62 deletions

View file

@ -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)

View file

@ -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

View file

@ -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;
} }
@ -506,12 +612,10 @@ int init_sound (void)
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;
} }