Mixer balancing and stereo output toggle

This commit is contained in:
Asnivor 2017-12-07 13:09:53 +00:00
parent f0cef1cf0d
commit 43ed79cd64
4 changed files with 80 additions and 70 deletions

View File

@ -265,7 +265,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
private byte envelopeClock = 0; private byte envelopeClock = 0;
private int selectedRegister; private int selectedRegister;
public ushort soundSampleCounter; public ushort soundSampleCounter;
private bool stereoSound = true; private bool stereoSound = false;
private bool sustaining; private bool sustaining;
private bool sustain; private bool sustain;
private bool alternate; private bool alternate;
@ -316,15 +316,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
} }
} }
/// <summary>
/// Set whether sound output is stereo or mono
/// </summary>
public bool StereoSound
{
get { return stereoSound; }
set { stereoSound = value; }
}
/// <summary> /// <summary>
/// Utility method to set all registers externally /// Utility method to set all registers externally
/// </summary> /// </summary>
@ -453,18 +444,9 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
private void EndSampleAY() private void EndSampleAY()
{ {
if (stereoSound) averagedChannelSamples[0] = (short)((averagedChannelSamples[ChannelLeft] + averagedChannelSamples[ChannelCenter]) / soundSampleCounter);
{ averagedChannelSamples[1] = (short)((averagedChannelSamples[ChannelRight] + averagedChannelSamples[ChannelCenter]) / soundSampleCounter);
averagedChannelSamples[0] = (short)((averagedChannelSamples[ChannelLeft] + averagedChannelSamples[ChannelCenter]) / soundSampleCounter);
averagedChannelSamples[1] = (short)((averagedChannelSamples[ChannelRight] + averagedChannelSamples[ChannelCenter]) / soundSampleCounter);
averagedChannelSamples[2] = 0;// beeperSound;
}
else
{
averagedChannelSamples[0] = (short)((averagedChannelSamples[ChannelLeft] + averagedChannelSamples[ChannelCenter] + averagedChannelSamples[ChannelRight]) / soundSampleCounter);
averagedChannelSamples[1] = (short)((averagedChannelSamples[ChannelLeft] + averagedChannelSamples[ChannelCenter] + averagedChannelSamples[ChannelRight]) / soundSampleCounter);
averagedChannelSamples[2] = 0;// (averagedChannelSamples[ChannelLeft] + averagedChannelSamples[ChannelCenter] + averagedChannelSamples[ChannelRight]) / soundSampleCounter + beeperSound;
}
soundSampleCounter = 0; soundSampleCounter = 0;
} }

View File

@ -206,12 +206,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
for (var i = firstSample; i < currentEnd + pulse.Length; i += TStatesPerSample) for (var i = firstSample; i < currentEnd + pulse.Length; i += TStatesPerSample)
{ {
samples[sampleIndex++] = pulse.State ? (short)(short.MaxValue / 2) : (short)0; if (_tapeMode)
samples[sampleIndex++] = pulse.State ? (short)(short.MaxValue / 6) : (short)0;
//resampler.EnqueueSample(samples[sampleIndex - 1], samples[sampleIndex - 1]); else
samples[sampleIndex++] = pulse.State ? (short)(short.MaxValue / 2) : (short)0;
} }
currentEnd += pulse.Length; currentEnd += pulse.Length;
} }

View File

@ -8,7 +8,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <summary> /// <summary>
/// My attempt at mixing multiple ISoundProvider sources together and outputting another ISoundProvider /// My attempt at mixing multiple ISoundProvider sources together and outputting another ISoundProvider
/// Currently only supports SyncSoundMode.Sync /// Currently only supports SyncSoundMode.Sync
/// Attached ISoundProvider sources must already be stereo 44.1khz /// Attached ISoundProvider sources must already be stereo 44.1khz and ideally sound buffers should be the same length
/// </summary> /// </summary>
internal sealed class SoundProviderMixer : ISoundProvider internal sealed class SoundProviderMixer : ISoundProvider
{ {
@ -20,11 +20,15 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
public int NSamp { get; set; } public int NSamp { get; set; }
} }
private bool _stereo = true;
public bool Stereo
{
get { return _stereo; }
set { _stereo = value; }
}
private readonly List<Provider> SoundProviders; private readonly List<Provider> SoundProviders;
private short[] _buffer;
private int _nSamp;
public SoundProviderMixer(params ISoundProvider[] soundProviders) public SoundProviderMixer(params ISoundProvider[] soundProviders)
{ {
SoundProviders = new List<Provider>(); SoundProviders = new List<Provider>();
@ -119,40 +123,51 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
var firstEntry = SoundProviders.First(); var firstEntry = SoundProviders.First();
bool sameCount = SoundProviders.All(s => s.NSamp == firstEntry.NSamp); bool sameCount = SoundProviders.All(s => s.NSamp == firstEntry.NSamp);
if (!sameCount)
if (sameCount)
{ {
// get the highest number of samples nsamp = firstEntry.NSamp;
int max = SoundProviders.Aggregate((i, j) => i.Buffer.Length > j.Buffer.Length ? i : j).Buffer.Length;
nsamp = max;
samples = new short[nsamp * 2]; samples = new short[nsamp * 2];
// take a pass at populating the samples array for each provider if (_stereo)
foreach (var sp in SoundProviders)
{ {
short sectorVal = 0; for (int i = 0; i < samples.Length; i++)
int pos = 0;
for (int i = 0; i < sp.Buffer.Length; i++)
{ {
if (sp.Buffer[i] > sp.MaxVolume) short sectorVal = 0;
sectorVal = (short)sp.MaxVolume; foreach (var sp in SoundProviders)
else
{ {
if (sp.SoundProvider is AY38912) if (sp.Buffer[i] > sp.MaxVolume)
{ sectorVal += (short)sp.MaxVolume;
// boost audio
sectorVal += (short)(sp.Buffer[i] * 2);
}
else else
{ {
sectorVal += sp.Buffer[i]; sectorVal += sp.Buffer[i];
} }
} }
samples[pos++] += sectorVal; samples[i] = sectorVal;
} }
} }
/* else
{
// convert to mono
for (int i = 0; i < samples.Length; i += 2)
{
short s = 0;
foreach (var sp in SoundProviders)
{
s += (short)((sp.Buffer[i] + sp.Buffer[i + 1]) / 2);
}
samples[i] = s;
samples[i + 1] = s;
}
}
}
else if (!sameCount)
{
// this is a pretty poor implementation that doesnt work very well
// ideally soundproviders should ensure that their number of samples is identical
int divisor = 1; int divisor = 1;
int highestCount = 0; int highestCount = 0;
@ -194,27 +209,30 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
sectorVal = (short)sp.MaxVolume; sectorVal = (short)sp.MaxVolume;
else else
sectorVal = sp.Buffer[i]; sectorVal = sp.Buffer[i];
for (int s = 0; s < divisor; s++) for (int s = 0; s < divisor; s++)
{ {
samples[pos++] += sectorVal; samples[pos++] += sectorVal;
} }
} }
} }
*/
} /*
else // get the highest number of samples
{ int max = SoundProviders.Aggregate((i, j) => i.Buffer.Length > j.Buffer.Length ? i : j).Buffer.Length;
nsamp = firstEntry.NSamp;
nsamp = max;
samples = new short[nsamp * 2]; samples = new short[nsamp * 2];
for (int i = 0; i < samples.Length; i++) // take a pass at populating the samples array for each provider
foreach (var sp in SoundProviders)
{ {
short sectorVal = 0; short sectorVal = 0;
foreach (var sp in SoundProviders) int pos = 0;
for (int i = 0; i < sp.Buffer.Length; i++)
{ {
if (sp.Buffer[i] > sp.MaxVolume) if (sp.Buffer[i] > sp.MaxVolume)
sectorVal += (short)sp.MaxVolume; sectorVal = (short)sp.MaxVolume;
else else
{ {
if (sp.SoundProvider is AY38912) if (sp.SoundProvider is AY38912)
@ -225,12 +243,14 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
else else
{ {
sectorVal += sp.Buffer[i]; sectorVal += sp.Buffer[i];
} }
} }
}
samples[i] = sectorVal; samples[pos++] += sectorVal;
}
} }
*/
} }
} }

View File

@ -24,7 +24,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
public bool PutSettings(ZXSpectrumSettings o) public bool PutSettings(ZXSpectrumSettings o)
{ {
if (SoundMixer != null)
SoundMixer.Stereo = o.StereoSound;
Settings = o; Settings = o;
return false; return false;
} }
@ -39,11 +43,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
public class ZXSpectrumSettings public class ZXSpectrumSettings
{ {
[DisplayName("Auto-load tape")] [DisplayName("Stereo Sound")]
[Description("Auto or manual tape operation")] [Description("Turn stereo sound on or off")]
[DefaultValue(true)] [DefaultValue(true)]
public bool AutoLoadTape { get; set; } public bool StereoSound { get; set; }
public ZXSpectrumSettings Clone() public ZXSpectrumSettings Clone()
{ {
@ -73,6 +77,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
[DefaultValue(TapeLoadSpeed.Accurate)] [DefaultValue(TapeLoadSpeed.Accurate)]
public TapeLoadSpeed TapeLoadSpeed { get; set; } public TapeLoadSpeed TapeLoadSpeed { get; set; }
[DisplayName("Auto-load tape")]
[Description("Auto or manual tape operation")]
[DefaultValue(true)]
public bool AutoLoadTape { get; set; }
public ZXSpectrumSyncSettings Clone() public ZXSpectrumSyncSettings Clone()
{ {
return (ZXSpectrumSyncSettings)MemberwiseClone(); return (ZXSpectrumSyncSettings)MemberwiseClone();