SN76489: Implemented periodic noise
This commit is contained in:
parent
d1110de5de
commit
457819b331
|
@ -41,6 +41,7 @@ namespace BizHawk.Emulation.Sound
|
|||
|
||||
public HuC6280PSG()
|
||||
{
|
||||
Waves.InitWaves();
|
||||
for (int i=0; i<8; i++)
|
||||
Channels[i] = new PSGChannel();
|
||||
}
|
||||
|
@ -164,11 +165,9 @@ namespace BizHawk.Emulation.Sound
|
|||
{
|
||||
wave = Waves.NoiseWave;
|
||||
freq = channel.NoiseFreq;
|
||||
leftVol /= 2;
|
||||
rightVol /= 2;
|
||||
}
|
||||
|
||||
float adjustedWaveLengthInSamples = SampleRate / (channel.NoiseChannel ? freq/512f : freq);
|
||||
float adjustedWaveLengthInSamples = SampleRate / (channel.NoiseChannel ? freq/(float)channel.Wave.Length : freq);
|
||||
float moveThroughWaveRate = wave.Length / adjustedWaveLengthInSamples;
|
||||
|
||||
int end = start + len;
|
||||
|
@ -177,10 +176,7 @@ namespace BizHawk.Emulation.Sound
|
|||
channel.SampleOffset %= wave.Length;
|
||||
short value = channel.DDA ? channel.DDAValue : wave[(int) channel.SampleOffset];
|
||||
|
||||
float left = ((value * LogScale[channel.Volume] / 255f / 6f) * (leftVol / 15f));
|
||||
|
||||
if (left>32768f || left <-32768f) Console.WriteLine("HEY BAD THINGS");
|
||||
samples[i++] += (short) left;
|
||||
samples[i++] += (short)((value * LogScale[channel.Volume] / 255f / 6f) * (leftVol / 15f));
|
||||
samples[i++] += (short)((value * LogScale[channel.Volume] / 255f / 6f) * (rightVol / 15f));
|
||||
|
||||
channel.SampleOffset += moveThroughWaveRate;
|
||||
|
|
|
@ -3,14 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Globalization;
|
||||
using System.IO;
|
||||
|
||||
// Emulates a Texas Instruments SN76489. This is found in:
|
||||
// + Sega 8-bit consoles (SMS/MarkIII/Game Gear/SG-1000/SC-3000/etc)
|
||||
// + In the Genesis/MegaDrive as a 2ndary sound source
|
||||
// + Some arcade hardware
|
||||
|
||||
// The Game Gear version is enhanced to support stereo output.
|
||||
// TODO at this time, I dont know if some arcades need a different PsgBase value or if it is constant.
|
||||
// TODO the noise channel emulation is not perfect.
|
||||
// Emulates a Texas Instruments SN76489
|
||||
// TODO the freq->note translation should be moved to a separate utility class.
|
||||
|
||||
namespace BizHawk.Emulation.Sound
|
||||
|
@ -35,7 +28,7 @@ namespace BizHawk.Emulation.Sound
|
|||
{
|
||||
if (Volume == 0) return;
|
||||
|
||||
float adjustedWaveLengthInSamples = SampleRate / (Noise ? (Frequency / 512f) : Frequency);
|
||||
float adjustedWaveLengthInSamples = SampleRate / (Noise ? (Frequency / (float)Wave.Length) : Frequency);
|
||||
float moveThroughWaveRate = Wave.Length / adjustedWaveLengthInSamples;
|
||||
|
||||
int end = start + len;
|
||||
|
@ -62,6 +55,7 @@ namespace BizHawk.Emulation.Sound
|
|||
|
||||
public SN76489()
|
||||
{
|
||||
Waves.InitWaves();
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
Channels[i] = new Channel();
|
||||
|
@ -112,7 +106,25 @@ namespace BizHawk.Emulation.Sound
|
|||
commands.Enqueue(new QueuedCommand {Value = value, Time = cycles-frameStartTime});
|
||||
}
|
||||
|
||||
public void WritePsgDataImmediate(byte value)
|
||||
private void UpdateNoiseType(int value)
|
||||
{
|
||||
Channels[3].NoiseType = (byte)(value & 0x07);
|
||||
switch (Channels[3].NoiseType & 3)
|
||||
{
|
||||
case 0: Channels[3].Frequency = PsgBase / 16; break;
|
||||
case 1: Channels[3].Frequency = PsgBase / 32; break;
|
||||
case 2: Channels[3].Frequency = PsgBase / 64; break;
|
||||
case 3: Channels[3].Frequency = Channels[2].Frequency; break;
|
||||
}
|
||||
var newWave = (value & 4) == 0 ? Waves.PeriodicWave16 : Waves.NoiseWave;
|
||||
if (newWave != Channels[3].Wave)
|
||||
{
|
||||
Channels[3].Wave = newWave;
|
||||
Channels[3].WaveOffset = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
private void WritePsgDataImmediate(byte value)
|
||||
{
|
||||
switch (value & 0xF0)
|
||||
{
|
||||
|
@ -123,14 +135,7 @@ namespace BizHawk.Emulation.Sound
|
|||
break;
|
||||
case 0xE0:
|
||||
PsgLatch = value;
|
||||
Channels[3].NoiseType = (byte) (value & 0x03);
|
||||
switch (Channels[3].NoiseType)
|
||||
{
|
||||
case 0: Channels[3].Frequency = PsgBase/16; break;
|
||||
case 1: Channels[3].Frequency = PsgBase/32; break;
|
||||
case 2: Channels[3].Frequency = PsgBase/64; break;
|
||||
case 3: Channels[3].Frequency = Channels[2].Frequency; break;
|
||||
}
|
||||
UpdateNoiseType(value);
|
||||
break;
|
||||
case 0x90:
|
||||
Channels[0].Volume = (byte)(~value & 15);
|
||||
|
@ -156,7 +161,7 @@ namespace BizHawk.Emulation.Sound
|
|||
if (f > 15000)
|
||||
f = 0; // upper bound of playable frequency
|
||||
Channels[channel].Frequency = (ushort) f;
|
||||
if (Channels[3].NoiseType == 3 && channel == 2)
|
||||
if ((Channels[3].NoiseType & 3) == 3 && channel == 2)
|
||||
Channels[3].Frequency = (ushort) f;
|
||||
} else { // volume latched
|
||||
Channels[channel].Volume = (byte)(~value & 15);
|
||||
|
@ -244,6 +249,7 @@ namespace BizHawk.Emulation.Sound
|
|||
else
|
||||
Console.WriteLine("Skipping unrecognized identifier " + args[0]);
|
||||
}
|
||||
UpdateNoiseType(Channels[3].NoiseType);
|
||||
}
|
||||
|
||||
public void SaveStateBinary(BinaryWriter writer)
|
||||
|
@ -271,7 +277,7 @@ namespace BizHawk.Emulation.Sound
|
|||
Channels[1].Frequency = reader.ReadUInt16();
|
||||
Channels[2].Frequency = reader.ReadUInt16();
|
||||
Channels[3].Frequency = reader.ReadUInt16();
|
||||
Channels[3].NoiseType = reader.ReadByte();
|
||||
UpdateNoiseType(reader.ReadByte());
|
||||
PsgLatch = reader.ReadByte();
|
||||
StereoPanning = reader.ReadByte();
|
||||
}
|
||||
|
|
|
@ -2,61 +2,37 @@
|
|||
{
|
||||
public static class Waves
|
||||
{
|
||||
public static readonly short[] SquareWave =
|
||||
public static short[] SquareWave;
|
||||
public static short[] ImperfectSquareWave;
|
||||
public static short[] NoiseWave;
|
||||
public static short[] PeriodicWave16;
|
||||
|
||||
public static void InitWaves()
|
||||
{
|
||||
SquareWave = new short[]
|
||||
{
|
||||
-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
|
||||
32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767
|
||||
};
|
||||
|
||||
public static readonly short[] ImperfectSquareWave =
|
||||
ImperfectSquareWave = new short[]
|
||||
{
|
||||
-32768,-30145,-27852,-26213,-24902,-23592,-22282,-20971,-19988,-19005,-18350,-17694,-17366,-17039,-16711,-16711,
|
||||
32767, 30145, 27852, 26213, 24902, 23592, 22282, 20971, 19988, 19005, 18350, 17694, 17366, 17039, 16711, 16711
|
||||
};
|
||||
|
||||
public static readonly short[] NoiseWave =
|
||||
PeriodicWave16 = new short[] { 32767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
NoiseWave = new short[0x2000];
|
||||
var rnd = new System.Random(unchecked((int)0xDEADBEEF));
|
||||
for (int i = 0; i < NoiseWave.Length; i++)
|
||||
{
|
||||
32767, 32767, 32767,-32768,-32768,-32768, 32767,-32768, 32767, 32767, 32767, 32767,-32768,-32768,-32768,-32768, 32767, 32767,-32768,-32768, 32767, 32767,-32768,-32768, 32767, 32767,-32768,-32768, 32767, 32767,-32768,-32768, 32767,-32768,-32768,
|
||||
32767, 32767,-32768,-32768, 32767, 32767,-32768,-32768, 32767, 32767,-32768, 32767, 32767,-32768, 32767, 32767, 32767,-32768,-32768, 32767, 32767,-32768,-32768, 32767,-32768,-32768,-32768, 32767,-32768,-32768,-32768,-32768, 32767,-32768, 32767,
|
||||
32767, 32767,-32768,-32768,-32768,-32768,-32768, 32767,-32768,-32768, 32767,-32768, 32767,-32768, 32767,-32768, 32767, 32767,-32768,-32768,-32768, 32767,-32768, 32767,-32768,-32768, 32767, 32767,-32768, 32767,-32768,-32768,-32768, 32767,-32768,
|
||||
32767, 32767, 32767, 32767, 32767, 32767, 32767,-32768, 32767, 32767,-32768, 32767, 32767, 32767,-32768,-32768,-32768, 32767,-32768,-32768, 32767,-32768, 32767,-32768, 32767,-32768,-32768,-32768, 32767,-32768, 32767,-32768,-32768, 32767,-32768,
|
||||
-32768, 32767, 32767, 32767,-32768, 32767,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 32767,-32768, 32767,-32768, 32767,-32768,-32768, 32767, 32767, 32767,-32768, 32767, 32767,-32768,-32768, 32767, 32767, 32767,-32768, 32767, 32767, 32767,
|
||||
-32768,-32768, 32767, 32767, 32767,-32768,-32768,-32768,-32768,-32768, 32767, 32767,-32768,-32768,-32768, 32767,-32768,-32768, 32767, 32767, 32767,-32768,-32768,-32768,-32768,-32768, 32767, 32767, 32767,-32768,-32768,-32768, 32767,-32768, 32767,
|
||||
32767,-32768, 32767, 32767, 32767, 32767, 32767, 32767, 32767,-32768,-32768, 32767, 32767,-32768, 32767,-32768, 32767, 32767,-32768, 32767,-32768,-32768, 32767, 32767, 32767,-32768, 32767,-32768,-32768, 32767, 32767, 32767, 32767, 32767,-32768,
|
||||
32767, 32767,-32768, 32767,-32768,-32768,-32768, 32767,-32768, 32767, 32767, 32767, 32767,-32768, 32767,-32768, 32767, 32767, 32767,-32768, 32767, 32767, 32767,-32768,-32768, 32767,-32768,-32768, 32767, 32767, 32767,-32768, 32767, 32767, 32767,
|
||||
-32768,-32768,-32768, 32767, 32767, 32767,-32768, 32767,-32768,-32768, 32767, 32767,-32768,-32768, 32767,-32768,-32768,-32768, 32767, 32767,-32768,-32768,-32768, 32767, 32767, 32767, 32767,-32768, 32767, 32767, 32767, 32767, 32767,-32768, 32767,
|
||||
32767,-32768,-32768, 32767,-32768,-32768,-32768,-32768, 32767,-32768, 32767, 32767,-32768, 32767, 32767,-32768, 32767,-32768,-32768,-32768,-32768, 32767,-32768, 32767,-32768, 32767, 32767,-32768,-32768, 32767, 32767, 32767, 32767,-32768, 32767,
|
||||
-32768, 32767, 32767, 32767,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 32767, 32767, 32767, 32767,-32768, 32767, 32767,-32768,-32768, 32767, 32767, 32767,-32768, 32767, 32767, 32767,-32768,-32768,-32768, 32767, 32767,-32768,
|
||||
-32768,-32768,-32768,-32768, 32767, 32767,-32768,-32768, 32767,-32768,-32768, 32767, 32767,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 32767,-32768, 32767, 32767, 32767,-32768,-32768,-32768,-32768,-32768,-32768, 32767, 32767,-32768,-32768,
|
||||
32767,-32768, 32767,-32768, 32767, 32767,-32768,-32768, 32767,-32768,-32768,-32768, 32767,-32768, 32767,-32768, 32767, 32767,-32768,-32768,-32768,-32768, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,-32768,-32768,-32768, 32767, 32767,
|
||||
-32768, 32767,-32768, 32767, 32767,-32768,-32768, 32767,-32768,-32768,-32768,-32768, 32767,-32768,-32768, 32767,-32768,-32768,-32768,-32768, 32767,-32768,-32768,-32768,-32768, 32767, 32767,-32768, 32767, 32767,-32768,-32768,-32768, 32767, 32767,
|
||||
32767,-32768,-32768, 32767,-32768,-32768,-32768,-32768, 32767,-32768, 32767,-32768,-32768, 32767, 32767, 32767,-32768,-32768,-32768,-32768,-32768, 32767
|
||||
};
|
||||
int r = rnd.Next();
|
||||
if ((r & 1) > 0)
|
||||
NoiseWave[i] = short.MaxValue;
|
||||
}
|
||||
|
||||
public static readonly short[] TriangleWave =
|
||||
{
|
||||
-32768,-32513,-32257,-32001,-31745,-31489,-31233,-30977,-30721,-30465,-30209,-29953,-29697,-29441,-29185,-28929,-28673,-28417,-28161,-27905,-27649,-27393,-27137,-26881,-26625,-26369,-26113,-25857,-25601,-25345,-25089,-24833,-24577,-24321,-24065,
|
||||
-23809,-23553,-23297,-23041,-22785,-22529,-22273,-22017,-21761,-21505,-21249,-20993,-20737,-20481,-20225,-19969,-19713,-19457,-19201,-18945,-18689,-18433,-18177,-17921,-17665,-17409,-17153,-16897,-16641,-16385,-16129,-15873,-15617,-15361,-15105,
|
||||
-14849,-14593,-14337,-14081,-13825,-13569,-13313,-13057,-12801,-12545,-12289,-12033,-11777,-11521,-11265,-11009,-10753,-10497,-10241,-9985,-9729,-9473,-9217,-8961,-8705,-8449,-8193,-7937,-7681,-7425,-7169,-6913,-6657,-6401,-6145,-5889,-5633,-5377,
|
||||
-5121,-4865,-4609,-4353,-4097,-3841,-3585,-3329,-3073,-2817,-2561,-2305,-2049,-1793,-1537,-1281,-1025,-769,-513,-257,-1,255,511,767,1023,1279,1535,1791,2047,2303,2559,2815,3071,3327,3583,3839,4095,4351,4607,4863,5119,5375,5631,5887,6143,6399,
|
||||
6655,6911,7167,7423,7679,7935,8191,8447,8703,8959,9215,9471,9727,9983,10239,10495,10751,11007,11263,11519,11775,12031,12287,12543,12799,13055,13311,13567,13823,14079,14335,14591,14847,15103,15359,15615,15871,16127,16383,16639,16895,
|
||||
17151,17407,17663,17919,18175,18431,18687,18943,19199,19455,19711,19967,20223,20479,20735,20991,21247,21503,21759,22015,22271,22527,22783,23039,23295,23551,23807,24063,24319,24575,24831,25087,25343,25599,25855,26111,26367,26623,
|
||||
26879,27135,27391,27647,27903,28159,28415,28671,28927,29183,29439,29695,29951,30207,30463,30719,30975,31231,31487,31743,31999,32255,32511,32767,32511,32255,31999,31743,31487,31231,30975,30719,30463,30207,29951,29695,29439,29183,
|
||||
28927,28671,28415,28159,27903,27647,27391,27135,26879,26623,26367,26111,25855,25599,25343,25087,24831,24575,24319,24063,23807,23551,23295,23039,22783,22527,22271,22015,21759,21503,21247,20991,20735,20479,20223,19967,19711,19455,
|
||||
19199,18943,18687,18431,18175,17919,17663,17407,17151,16895,16639,16383,16127,15871,15615,15359,15103,14847,14591,14335,14079,13823,13567,13311,13055,12799,12543,12287,12031,11775,11519,11263,11007,10751,10495,10239,9983,9727,9471,
|
||||
9215,8959,8703,8447,8191,7935,7679,7423,7167,6911,6655,6399,6143,5887,5631,5375,5119,4863,4607,4351,4095,3839,3583,3327,3071,2815,2559,2303,2047,1791,1535,1279,1023,767,511,255,-1,-257,-513,-769,-1025,-1281,-1537,-1793,-2049,-2305,-2561,
|
||||
-2817,-3073,-3329,-3585,-3841,-4097,-4353,-4609,-4865,-5121,-5377,-5633,-5889,-6145,-6401,-6657,-6913,-7169,-7425,-7681,-7937,-8193,-8449,-8705,-8961,-9217,-9473,-9729,-9985,-10241,-10497,-10753,-11009,-11265,-11521,-11777,-12033,-12289,-12545,
|
||||
-12801,-13057,-13313,-13569,-13825,-14081,-14337,-14593,-14849,-15105,-15361,-15617,-15873,-16129,-16385,-16641,-16897,-17153,-17409,-17665,-17921,-18177,-18433,-18689,-18945,-19201,-19457,-19713,-19969,-20225,-20481,-20737,-20993,-21249,-21505,
|
||||
-21761,-22017,-22273,-22529,-22785,-23041,-23297,-23553,-23809,-24065,-24321,-24577,-24833,-25089,-25345,-25601,-25857,-26113,-26369,-26625,-26881,-27137,-27393,-27649,-27905,-28161,-28417,-28673,-28929,-29185,-29441,-29697,-29953,-30209,-30465,
|
||||
-30721,-30977,-31233,-31489,-31745,-32001,-32257,-32513
|
||||
};
|
||||
|
||||
/*public static short[] SineWave;
|
||||
public static short[] SawWave;
|
||||
|
||||
public static void InitWaves()
|
||||
{
|
||||
TriangleWave = new short[512];
|
||||
/*TriangleWave = new short[512];
|
||||
for (int i = 0; i < 256; i++)
|
||||
TriangleWave[i] = (short)((ushort.MaxValue*i/256)-short.MinValue);
|
||||
for (int i = 0; i < 256; i++)
|
||||
|
@ -71,7 +47,7 @@
|
|||
for (int i=0; i<1024; i++)
|
||||
{
|
||||
SineWave[i] = (short) (Math.Sin(i*Math.PI*2/1024d)*32767);
|
||||
}
|
||||
}*/
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
|
|
|
@ -254,6 +254,8 @@ namespace BizHawk.MultiClient
|
|||
{
|
||||
Global.ClientControls.UnpressButton("Emulator Pause");
|
||||
EmulatorPaused = !EmulatorPaused;
|
||||
if (EmulatorPaused) Global.Sound.StopSound();
|
||||
else Global.Sound.StartSound();
|
||||
}
|
||||
|
||||
if (EmulatorPaused == false || Global.ClientControls["Frame Advance"])
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
SoundEnabled True
|
||||
LastRomPath D:\TAS\adelikatTAS\Archive
|
||||
LastRomPath D:\lib\roms\Game Gear
|
||||
HardResetBinding LeftShift+Tab
|
||||
FastForwardBinding J1 B6
|
||||
RewindBinding J1 B5
|
||||
|
|
Loading…
Reference in New Issue