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:
J.D. Purcell 2016-12-18 20:45:38 -05:00
parent f2e9ca2ac9
commit 36daa01ad6
5 changed files with 10 additions and 39 deletions

View File

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

View File

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

View File

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

View File

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

View File

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