Sound cleanup. In case you're curious, the "SilenceLeaveRoomForFrameCount" part ended up not mattering (and may have been slightly counterproductive) once SoundOutputProvider had the ability to be notified of underruns. It doesn't matter for BufferedAsync either.
This commit is contained in:
parent
f2e9ca2ac9
commit
36daa01ad6
|
@ -129,11 +129,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
int cursorDelta = CircularDistance(_lastWriteCursor, writeCursor, BufferSizeBytes);
|
int cursorDelta = CircularDistance(_lastWriteCursor, writeCursor, BufferSizeBytes);
|
||||||
cursorDelta += BufferSizeBytes * (int)Math.Round((elapsedSeconds - (cursorDelta / (double)(Sound.SampleRate * Sound.BlockAlign))) / bufferSizeSeconds);
|
cursorDelta += BufferSizeBytes * (int)Math.Round((elapsedSeconds - (cursorDelta / (double)(Sound.SampleRate * Sound.BlockAlign))) / bufferSizeSeconds);
|
||||||
_filledBufferSizeBytes -= cursorDelta;
|
_filledBufferSizeBytes -= cursorDelta;
|
||||||
if (_filledBufferSizeBytes < 0)
|
detectedUnderrun = _filledBufferSizeBytes < 0;
|
||||||
{
|
|
||||||
_sound.OnUnderrun();
|
|
||||||
detectedUnderrun = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (isInitializing || detectedUnderrun)
|
if (isInitializing || detectedUnderrun)
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,7 +56,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
if (_remainingSamples < 0)
|
if (_remainingSamples < 0)
|
||||||
{
|
{
|
||||||
_remainingSamples = 0;
|
_remainingSamples = 0;
|
||||||
_sound.OnUnderrun();
|
|
||||||
detectedUnderrun = true;
|
detectedUnderrun = true;
|
||||||
}
|
}
|
||||||
_lastWriteTime = currentWriteTime;
|
_lastWriteTime = currentWriteTime;
|
||||||
|
|
|
@ -81,7 +81,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
bool detectedUnderrun = sourceState == ALSourceState.Stopped;
|
bool detectedUnderrun = sourceState == ALSourceState.Stopped;
|
||||||
if (detectedUnderrun)
|
if (detectedUnderrun)
|
||||||
{
|
{
|
||||||
_sound.OnUnderrun();
|
|
||||||
// SampleOffset should reset to 0 when stopped; update the queued sample count to match
|
// SampleOffset should reset to 0 when stopped; update the queued sample count to match
|
||||||
UnqueueProcessedBuffers();
|
UnqueueProcessedBuffers();
|
||||||
currentSamplesPlayed = 0;
|
currentSamplesPlayed = 0;
|
||||||
|
|
|
@ -102,10 +102,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
bool isInitializing = _runningSamplesQueued == 0;
|
bool isInitializing = _runningSamplesQueued == 0;
|
||||||
bool detectedUnderrun = !isInitializing && _sourceVoice.State.BuffersQueued == 0;
|
bool detectedUnderrun = !isInitializing && _sourceVoice.State.BuffersQueued == 0;
|
||||||
if (detectedUnderrun)
|
|
||||||
{
|
|
||||||
_sound.OnUnderrun();
|
|
||||||
}
|
|
||||||
long samplesAwaitingPlayback = _runningSamplesQueued - _sourceVoice.State.SamplesPlayed;
|
long samplesAwaitingPlayback = _runningSamplesQueued - _sourceVoice.State.SamplesPlayed;
|
||||||
int samplesNeeded = (int)Math.Max(BufferSizeSamples - samplesAwaitingPlayback, 0);
|
int samplesNeeded = (int)Math.Max(BufferSizeSamples - samplesAwaitingPlayback, 0);
|
||||||
if (isInitializing || detectedUnderrun)
|
if (isInitializing || detectedUnderrun)
|
||||||
|
|
|
@ -109,39 +109,20 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
public bool LogUnderruns { get; set; }
|
public bool LogUnderruns { get; set; }
|
||||||
|
|
||||||
private bool InitializeBufferWithSilence
|
|
||||||
{
|
|
||||||
get { return true; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool RecoverFromUnderrunsWithSilence
|
|
||||||
{
|
|
||||||
get { return true; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private int SilenceLeaveRoomForFrameCount
|
|
||||||
{
|
|
||||||
get { return Global.Config.SoundThrottle ? 1 : 2; } // Why 2? I don't know, but it seems to work well with the clock throttle's behavior.
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void HandleInitializationOrUnderrun(bool isUnderrun, ref int samplesNeeded)
|
internal void HandleInitializationOrUnderrun(bool isUnderrun, ref int samplesNeeded)
|
||||||
{
|
{
|
||||||
if ((!isUnderrun && InitializeBufferWithSilence) || (isUnderrun && RecoverFromUnderrunsWithSilence))
|
// Fill device buffer with silence but leave enough room for one frame
|
||||||
{
|
|
||||||
int samplesPerFrame = (int)Math.Round(SampleRate / Global.Emulator.CoreComm.VsyncRate);
|
int samplesPerFrame = (int)Math.Round(SampleRate / Global.Emulator.CoreComm.VsyncRate);
|
||||||
int silenceSamples = Math.Max(samplesNeeded - (SilenceLeaveRoomForFrameCount * samplesPerFrame), 0);
|
int silenceSamples = Math.Max(samplesNeeded - samplesPerFrame, 0);
|
||||||
_outputDevice.WriteSamples(new short[silenceSamples * 2], silenceSamples);
|
_outputDevice.WriteSamples(new short[silenceSamples * 2], silenceSamples);
|
||||||
samplesNeeded -= silenceSamples;
|
samplesNeeded -= silenceSamples;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void OnUnderrun()
|
if (isUnderrun)
|
||||||
{
|
{
|
||||||
if (!IsStarted) return;
|
|
||||||
|
|
||||||
if (LogUnderruns) Console.WriteLine("Sound underrun detected!");
|
if (LogUnderruns) Console.WriteLine("Sound underrun detected!");
|
||||||
_outputProvider.OnVolatility();
|
_outputProvider.OnVolatility();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateSound(float atten)
|
public void UpdateSound(float atten)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue