Changed Qt sound underflow/overflow so that it better scales with changing running faster or slower than realtime.
This commit is contained in:
parent
301fb99a8a
commit
896af76167
|
@ -1005,120 +1005,122 @@ FCEUD_Update(uint8 *XBuf,
|
||||||
int blitDone = 0;
|
int blitDone = 0;
|
||||||
//extern int FCEUDnetplay;
|
//extern int FCEUDnetplay;
|
||||||
|
|
||||||
#ifdef CREATE_AVI
|
//#ifdef CREATE_AVI
|
||||||
if (LoggingEnabled == 2 || (eoptions&EO_NOTHROTTLE))
|
//if (LoggingEnabled == 2 || (eoptions&EO_NOTHROTTLE))
|
||||||
{
|
//{
|
||||||
if(LoggingEnabled == 2)
|
// if(LoggingEnabled == 2)
|
||||||
{
|
// {
|
||||||
int16* MonoBuf = new int16[Count];
|
// int16* MonoBuf = new int16[Count];
|
||||||
int n;
|
// int n;
|
||||||
for(n=0; n<Count; ++n)
|
// for(n=0; n<Count; ++n)
|
||||||
{
|
// {
|
||||||
MonoBuf[n] = Buffer[n] & 0xFFFF;
|
// MonoBuf[n] = Buffer[n] & 0xFFFF;
|
||||||
}
|
// }
|
||||||
NESVideoLoggingAudio
|
// NESVideoLoggingAudio
|
||||||
(
|
// (
|
||||||
MonoBuf,
|
// MonoBuf,
|
||||||
FSettings.SndRate, 16, 1,
|
// FSettings.SndRate, 16, 1,
|
||||||
Count
|
// Count
|
||||||
);
|
// );
|
||||||
delete [] MonoBuf;
|
// delete [] MonoBuf;
|
||||||
}
|
// }
|
||||||
Count /= 2;
|
// Count /= 2;
|
||||||
if (inited & 1)
|
// if (inited & 1)
|
||||||
{
|
// {
|
||||||
if (Count > GetWriteSound()) Count = GetWriteSound();
|
// if (Count > GetWriteSound()) Count = GetWriteSound();
|
||||||
|
|
||||||
if (!mutecapture)
|
// if (!mutecapture)
|
||||||
{
|
// {
|
||||||
if(Count > 0 && Buffer) WriteSound(Buffer,Count);
|
// if(Count > 0 && Buffer) WriteSound(Buffer,Count);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
//if (inited & 2)
|
// //if (inited & 2)
|
||||||
// FCEUD_UpdateInput();
|
// // FCEUD_UpdateInput();
|
||||||
if(XBuf && (inited & 4)) BlitScreen(XBuf);
|
// if(XBuf && (inited & 4)) BlitScreen(XBuf);
|
||||||
|
//
|
||||||
return;
|
// return;
|
||||||
}
|
//}
|
||||||
#endif
|
//#endif
|
||||||
aviRecordAddAudioFrame( Buffer, Count );
|
aviRecordAddAudioFrame( Buffer, Count );
|
||||||
|
|
||||||
int ocount = Count;
|
WriteSound(Buffer,Count);
|
||||||
|
|
||||||
|
//int ocount = Count;
|
||||||
// apply frame scaling to Count
|
// apply frame scaling to Count
|
||||||
Count = (int)(Count / g_fpsScale);
|
//Count = (int)(Count / g_fpsScale);
|
||||||
if (Count)
|
//if (Count)
|
||||||
{
|
//{
|
||||||
int32 can=GetWriteSound();
|
// int32 can=GetWriteSound();
|
||||||
static int uflow=0;
|
// static int uflow=0;
|
||||||
int32 tmpcan;
|
// int32 tmpcan;
|
||||||
|
|
||||||
// don't underflow when scaling fps
|
// // don't underflow when scaling fps
|
||||||
if(can >= GetMaxSound() && g_fpsScale==1.0) uflow=1; /* Go into massive underflow mode. */
|
// if(can >= GetMaxSound() && g_fpsScale==1.0) uflow=1; /* Go into massive underflow mode. */
|
||||||
|
|
||||||
if(can > Count) can=Count;
|
// if(can > Count) can=Count;
|
||||||
else uflow=0;
|
// else uflow=0;
|
||||||
|
|
||||||
#ifdef CREATE_AVI
|
// #ifdef CREATE_AVI
|
||||||
if (!mutecapture)
|
// if (!mutecapture)
|
||||||
#endif
|
// #endif
|
||||||
WriteSound(Buffer,can);
|
// WriteSound(Buffer,can);
|
||||||
|
|
||||||
//if(uflow) puts("Underflow");
|
// //if(uflow) puts("Underflow");
|
||||||
tmpcan = GetWriteSound();
|
// tmpcan = GetWriteSound();
|
||||||
// don't underflow when scaling fps
|
// // don't underflow when scaling fps
|
||||||
if (g_fpsScale>1.0 || ((tmpcan < Count*0.90) && !uflow))
|
// if (g_fpsScale>1.0 || ((tmpcan < Count*0.90) && !uflow))
|
||||||
{
|
// {
|
||||||
if (XBuf && (inited&4) && !(NoWaiting & 2))
|
// if (XBuf && (inited&4) && !(NoWaiting & 2))
|
||||||
{
|
// {
|
||||||
BlitScreen(XBuf); blitDone = 1;
|
// BlitScreen(XBuf); blitDone = 1;
|
||||||
}
|
// }
|
||||||
Buffer+=can;
|
// Buffer+=can;
|
||||||
Count-=can;
|
// Count-=can;
|
||||||
if(Count)
|
// if(Count)
|
||||||
{
|
// {
|
||||||
if(NoWaiting)
|
// if(NoWaiting)
|
||||||
{
|
// {
|
||||||
can=GetWriteSound();
|
// can=GetWriteSound();
|
||||||
if(Count>can) Count=can;
|
// if(Count>can) Count=can;
|
||||||
#ifdef CREATE_AVI
|
// #ifdef CREATE_AVI
|
||||||
if (!mutecapture)
|
// if (!mutecapture)
|
||||||
#endif
|
// #endif
|
||||||
WriteSound(Buffer,Count);
|
// WriteSound(Buffer,Count);
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
while(Count>0)
|
// while(Count>0)
|
||||||
{
|
// {
|
||||||
#ifdef CREATE_AVI
|
// #ifdef CREATE_AVI
|
||||||
if (!mutecapture)
|
// if (!mutecapture)
|
||||||
#endif
|
// #endif
|
||||||
WriteSound(Buffer,(Count<ocount) ? Count : ocount);
|
// WriteSound(Buffer,(Count<ocount) ? Count : ocount);
|
||||||
Count -= ocount;
|
// Count -= ocount;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
} //else puts("Skipped");
|
// } //else puts("Skipped");
|
||||||
//else if (!NoWaiting && FCEUDnetplay && (uflow || tmpcan >= (Count * 1.8)))
|
// //else if (!NoWaiting && FCEUDnetplay && (uflow || tmpcan >= (Count * 1.8)))
|
||||||
//{
|
// //{
|
||||||
// if (Count > tmpcan) Count=tmpcan;
|
// // if (Count > tmpcan) Count=tmpcan;
|
||||||
// while(tmpcan > 0)
|
// // while(tmpcan > 0)
|
||||||
// {
|
// // {
|
||||||
// // printf("Overwrite: %d\n", (Count <= tmpcan)?Count : tmpcan);
|
// // // printf("Overwrite: %d\n", (Count <= tmpcan)?Count : tmpcan);
|
||||||
// #ifdef CREATE_AVI
|
// // #ifdef CREATE_AVI
|
||||||
// if (!mutecapture)
|
// // if (!mutecapture)
|
||||||
// #endif
|
// // #endif
|
||||||
// WriteSound(Buffer, (Count <= tmpcan)?Count : tmpcan);
|
// // WriteSound(Buffer, (Count <= tmpcan)?Count : tmpcan);
|
||||||
// tmpcan -= Count;
|
// // tmpcan -= Count;
|
||||||
// }
|
// // }
|
||||||
//}
|
// //}
|
||||||
}
|
//}
|
||||||
else
|
//else
|
||||||
{
|
//{
|
||||||
if (XBuf && (inited&4))
|
// if (XBuf && (inited&4))
|
||||||
{
|
// {
|
||||||
BlitScreen(XBuf); blitDone = 1;
|
// BlitScreen(XBuf); blitDone = 1;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
if ( !blitDone )
|
if ( !blitDone )
|
||||||
{
|
{
|
||||||
if (XBuf && (inited&4))
|
if (XBuf && (inited&4))
|
||||||
|
|
|
@ -48,6 +48,7 @@ static int s_mute = 0;
|
||||||
|
|
||||||
extern int EmulationPaused;
|
extern int EmulationPaused;
|
||||||
extern double frmRateAdjRatio;
|
extern double frmRateAdjRatio;
|
||||||
|
extern double g_fpsScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback from the SDL to get and play audio data.
|
* Callback from the SDL to get and play audio data.
|
||||||
|
@ -261,33 +262,136 @@ void
|
||||||
WriteSound(int32 *buf,
|
WriteSound(int32 *buf,
|
||||||
int Count)
|
int Count)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
int uflowMode = 0;
|
||||||
|
int ovrFlowSkip = 1;
|
||||||
|
int udrFlowDup = 1;
|
||||||
|
static int skipCounter = 0;
|
||||||
|
|
||||||
|
if ( g_fpsScale >= 0.90 )
|
||||||
|
{
|
||||||
|
uflowMode = 0;
|
||||||
|
ovrFlowSkip = (int)(g_fpsScale);
|
||||||
|
|
||||||
|
if ( ovrFlowSkip < 1 )
|
||||||
|
{
|
||||||
|
ovrFlowSkip = 1;
|
||||||
|
}
|
||||||
|
if ( s_BufferIn >= (s_BufferSize/2) )
|
||||||
|
{
|
||||||
|
ovrFlowSkip++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
udrFlowDup = (int)(1.0 / g_fpsScale);
|
||||||
|
|
||||||
|
if ( udrFlowDup < 1 )
|
||||||
|
{
|
||||||
|
udrFlowDup = 1;
|
||||||
|
}
|
||||||
|
if ( s_BufferIn <= (s_BufferSize/2) )
|
||||||
|
{
|
||||||
|
udrFlowDup++;
|
||||||
|
}
|
||||||
|
uflowMode = (udrFlowDup > 1);
|
||||||
|
}
|
||||||
extern int EmulationPaused;
|
extern int EmulationPaused;
|
||||||
if (EmulationPaused == 0)
|
if (EmulationPaused == 0)
|
||||||
{
|
{
|
||||||
int waitCount = 0;
|
int waitCount = 0;
|
||||||
|
|
||||||
while(Count)
|
if ( uflowMode )
|
||||||
{
|
{ // Underflow mode
|
||||||
while(s_BufferIn == s_BufferSize)
|
while (Count)
|
||||||
{
|
{
|
||||||
SDL_Delay(1); waitCount++;
|
while (s_BufferIn == s_BufferSize)
|
||||||
|
|
||||||
if ( waitCount > 1000 )
|
|
||||||
{
|
{
|
||||||
printf("Error: Sound sink is not draining... Breaking out of audio loop to prevent lockup.\n");
|
SDL_Delay(1); waitCount++;
|
||||||
return;
|
|
||||||
|
if ( waitCount > 1000 )
|
||||||
|
{
|
||||||
|
printf("Error: Sound sink is not draining... Breaking out of audio loop to prevent lockup.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<udrFlowDup; i++)
|
||||||
|
{
|
||||||
|
s_Buffer[s_BufferWrite] = *buf;
|
||||||
|
s_BufferWrite = (s_BufferWrite + 1) % s_BufferSize;
|
||||||
|
|
||||||
|
SDL_LockAudio();
|
||||||
|
s_BufferIn++;
|
||||||
|
SDL_UnlockAudio();
|
||||||
|
}
|
||||||
|
|
||||||
|
Count--;
|
||||||
|
buf++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( ovrFlowSkip == 1 )
|
||||||
|
{ // Perfect one to one realtime
|
||||||
|
skipCounter = 0;
|
||||||
|
|
||||||
|
while (Count)
|
||||||
|
{
|
||||||
|
while (s_BufferIn == s_BufferSize)
|
||||||
|
{
|
||||||
|
SDL_Delay(1); waitCount++;
|
||||||
|
|
||||||
|
if ( waitCount > 1000 )
|
||||||
|
{
|
||||||
|
printf("Error: Sound sink is not draining... Breaking out of audio loop to prevent lockup.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s_Buffer[s_BufferWrite] = *buf;
|
||||||
|
Count--;
|
||||||
|
s_BufferWrite = (s_BufferWrite + 1) % s_BufferSize;
|
||||||
|
|
||||||
|
SDL_LockAudio();
|
||||||
|
s_BufferIn++;
|
||||||
|
SDL_UnlockAudio();
|
||||||
|
|
||||||
|
buf++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{ // Overflow mode
|
||||||
|
while (Count)
|
||||||
|
{
|
||||||
|
while (s_BufferIn == s_BufferSize)
|
||||||
|
{
|
||||||
|
SDL_Delay(1); waitCount++;
|
||||||
|
|
||||||
s_Buffer[s_BufferWrite] = *buf;
|
if ( waitCount > 1000 )
|
||||||
Count--;
|
{
|
||||||
s_BufferWrite = (s_BufferWrite + 1) % s_BufferSize;
|
printf("Error: Sound sink is not draining... Breaking out of audio loop to prevent lockup.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SDL_LockAudio();
|
if ( skipCounter == 0 )
|
||||||
s_BufferIn++;
|
{
|
||||||
SDL_UnlockAudio();
|
s_Buffer[s_BufferWrite] = *buf;
|
||||||
|
s_BufferWrite = (s_BufferWrite + 1) % s_BufferSize;
|
||||||
|
|
||||||
|
SDL_LockAudio();
|
||||||
|
s_BufferIn++;
|
||||||
|
SDL_UnlockAudio();
|
||||||
|
}
|
||||||
|
skipCounter = (skipCounter+1) % ovrFlowSkip;
|
||||||
|
|
||||||
|
Count--;
|
||||||
|
buf++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
buf++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue