SN76489: Implemented periodic noise

This commit is contained in:
beirich 2011-01-16 21:06:14 +00:00
parent d1110de5de
commit 457819b331
6 changed files with 54 additions and 74 deletions

View File

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

View File

@ -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();
}

View File

@ -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);
}
}*/
}*/
}
}
}

View File

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

View File

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

View File

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