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>
@ -452,19 +443,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
} }
private void EndSampleAY() private void EndSampleAY()
{
if (stereoSound)
{ {
averagedChannelSamples[0] = (short)((averagedChannelSamples[ChannelLeft] + averagedChannelSamples[ChannelCenter]) / soundSampleCounter); averagedChannelSamples[0] = (short)((averagedChannelSamples[ChannelLeft] + averagedChannelSamples[ChannelCenter]) / soundSampleCounter);
averagedChannelSamples[1] = (short)((averagedChannelSamples[ChannelRight] + 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,13 +206,12 @@ 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)
{ {
if (_tapeMode)
samples[sampleIndex++] = pulse.State ? (short)(short.MaxValue / 6) : (short)0;
else
samples[sampleIndex++] = pulse.State ? (short)(short.MaxValue / 2) : (short)0; samples[sampleIndex++] = pulse.State ? (short)(short.MaxValue / 2) : (short)0;
//resampler.EnqueueSample(samples[sampleIndex - 1], samples[sampleIndex - 1]);
} }
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,10 +20,14 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
public int NSamp { get; set; } public int NSamp { get; set; }
} }
private readonly List<Provider> SoundProviders; private bool _stereo = true;
public bool Stereo
{
get { return _stereo; }
set { _stereo = value; }
}
private short[] _buffer; private readonly List<Provider> SoundProviders;
private int _nSamp;
public SoundProviderMixer(params ISoundProvider[] soundProviders) public SoundProviderMixer(params ISoundProvider[] soundProviders)
{ {
@ -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)
{
// get the highest number of samples
int max = SoundProviders.Aggregate((i, j) => i.Buffer.Length > j.Buffer.Length ? i : j).Buffer.Length;
nsamp = max; if (sameCount)
{
nsamp = firstEntry.NSamp;
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) {
for (int i = 0; i < samples.Length; i++)
{ {
short sectorVal = 0; short sectorVal = 0;
int pos = 0; foreach (var sp in SoundProviders)
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
{
if (sp.SoundProvider is AY38912)
{
// 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;
@ -201,20 +216,23 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
} }
} }
} }
*/
} /*
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
{
short sectorVal = 0;
foreach (var sp in SoundProviders) foreach (var sp in SoundProviders)
{
short sectorVal = 0;
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)
@ -227,11 +245,13 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
sectorVal += sp.Buffer[i]; sectorVal += sp.Buffer[i];
} }
} }
}
samples[i] = sectorVal; samples[pos++] += sectorVal;
} }
} }
*/
}
} }
#endregion #endregion

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,10 +43,10 @@ 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();