音频处理指针化
This commit is contained in:
parent
bf0acee294
commit
2303b0c5f6
@ -6,10 +6,13 @@ namespace Essgee.Emulation.Audio
|
|||||||
{
|
{
|
||||||
public CGBAudio()
|
public CGBAudio()
|
||||||
{
|
{
|
||||||
channelSampleBuffer = new List<short>[numChannels];
|
//channelSampleBuffer = new List<short>[numChannels];
|
||||||
for (int i = 0; i < numChannels; i++) channelSampleBuffer[i] = new List<short>();
|
//for (int i = 0; i < numChannels; i++) channelSampleBuffer[i] = new List<short>();
|
||||||
|
//mixedSampleBuffer = new List<short>();
|
||||||
|
|
||||||
mixedSampleBuffer = new List<short>();
|
//改为二维数组
|
||||||
|
channelSampleBuffer_Init(numChannels, 1470);
|
||||||
|
mixedSampleBuffer_set = new short[1470];
|
||||||
|
|
||||||
channel1 = new Square(true);
|
channel1 = new Square(true);
|
||||||
channel2 = new Square(false);
|
channel2 = new Square(false);
|
||||||
|
@ -4,10 +4,11 @@ using Essgee.Utilities;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Essgee.Emulation.Audio
|
namespace Essgee.Emulation.Audio
|
||||||
{
|
{
|
||||||
public partial class DMGAudio : IAudio
|
public unsafe partial class DMGAudio : IAudio
|
||||||
{
|
{
|
||||||
// https://gbdev.gg8.se/wiki/articles/Gameboy_sound_hardware
|
// https://gbdev.gg8.se/wiki/articles/Gameboy_sound_hardware
|
||||||
// http://emudev.de/gameboy-emulator/bleeding-ears-time-to-add-audio/
|
// http://emudev.de/gameboy-emulator/bleeding-ears-time-to-add-audio/
|
||||||
@ -34,8 +35,55 @@ namespace Essgee.Emulation.Audio
|
|||||||
|
|
||||||
protected int frameSequencerReload, frameSequencerCounter, frameSequencer;
|
protected int frameSequencerReload, frameSequencerCounter, frameSequencer;
|
||||||
|
|
||||||
protected List<short>[] channelSampleBuffer;
|
//protected List<short>[] channelSampleBuffer;
|
||||||
protected List<short> mixedSampleBuffer;
|
#region //指针化 channelSampleBuffer
|
||||||
|
static short[][] channelSampleBuffer_src;
|
||||||
|
static GCHandle[] channelSampleBuffer_handle;
|
||||||
|
public static short*[] channelSampleBuffer;
|
||||||
|
public static int[] channelSampleBufferLength;
|
||||||
|
public static int channelSampleBuffer_writePos;
|
||||||
|
public static bool channelSampleBuffer_IsNull => channelSampleBuffer == null;
|
||||||
|
public static void channelSampleBuffer_Init(int length1, int Lenght2)
|
||||||
|
{
|
||||||
|
if (channelSampleBuffer_src != null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < channelSampleBuffer_src.Length; i++)
|
||||||
|
channelSampleBuffer_handle[i].ReleaseGCHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
channelSampleBuffer_src = new short[length1][];
|
||||||
|
channelSampleBuffer_handle = new GCHandle[length1];
|
||||||
|
channelSampleBuffer = new short*[length1];
|
||||||
|
channelSampleBuffer_writePos = 0;
|
||||||
|
for (int i = 0; i < channelSampleBuffer_src.Length; i++)
|
||||||
|
{
|
||||||
|
channelSampleBuffer_src[i] = new short[Lenght2];
|
||||||
|
channelSampleBuffer_src[i].GetObjectPtr(ref channelSampleBuffer_handle[i], ref channelSampleBuffer[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
//protected List<short> mixedSampleBuffer;
|
||||||
|
|
||||||
|
#region //指针化 mixedSampleBuffer
|
||||||
|
short[] mixedSampleBuffer_src;
|
||||||
|
GCHandle mixedSampleBuffer_handle;
|
||||||
|
public short* mixedSampleBuffer;
|
||||||
|
public int mixedSampleBufferLength;
|
||||||
|
public int mixedSampleBuffer_writePos;
|
||||||
|
public bool mixedSampleBuffer_IsNull => mixedSampleBuffer == null;
|
||||||
|
public short[] mixedSampleBuffer_set
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
mixedSampleBuffer_handle.ReleaseGCHandle();
|
||||||
|
mixedSampleBuffer_src = value;
|
||||||
|
mixedSampleBufferLength = value.Length;
|
||||||
|
mixedSampleBuffer_writePos = 0;
|
||||||
|
mixedSampleBuffer_src.GetObjectPtr(ref mixedSampleBuffer_handle, ref mixedSampleBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
public virtual event EventHandler<EnqueueSamplesEventArgs> EnqueueSamples;
|
public virtual event EventHandler<EnqueueSamplesEventArgs> EnqueueSamples;
|
||||||
public virtual void OnEnqueueSamples(EnqueueSamplesEventArgs e) { EnqueueSamples?.Invoke(this, e); }
|
public virtual void OnEnqueueSamples(EnqueueSamplesEventArgs e) { EnqueueSamples?.Invoke(this, e); }
|
||||||
|
|
||||||
@ -60,10 +108,14 @@ namespace Essgee.Emulation.Audio
|
|||||||
|
|
||||||
public DMGAudio()
|
public DMGAudio()
|
||||||
{
|
{
|
||||||
channelSampleBuffer = new List<short>[numChannels];
|
//channelSampleBuffer = new List<short>[numChannels];
|
||||||
for (int i = 0; i < numChannels; i++) channelSampleBuffer[i] = new List<short>();
|
//for (int i = 0; i < numChannels; i++) channelSampleBuffer[i] = new List<short>();
|
||||||
|
//mixedSampleBuffer = new List<short>();
|
||||||
|
|
||||||
|
//改为二维数组
|
||||||
|
channelSampleBuffer_Init(numChannels, 1470);
|
||||||
|
mixedSampleBuffer_set = new short[1470];
|
||||||
|
|
||||||
mixedSampleBuffer = new List<short>();
|
|
||||||
|
|
||||||
channel1 = new Square(true);
|
channel1 = new Square(true);
|
||||||
channel2 = new Square(false);
|
channel2 = new Square(false);
|
||||||
@ -263,13 +315,22 @@ namespace Essgee.Emulation.Audio
|
|||||||
sampleCycleCount -= cyclesPerSample;
|
sampleCycleCount -= cyclesPerSample;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mixedSampleBuffer.Count >= (samplesPerFrame * numOutputChannels))
|
//if (mixedSampleBuffer.Count >= (samplesPerFrame * numOutputChannels))
|
||||||
|
if (mixedSampleBuffer_writePos >= (samplesPerFrame * numOutputChannels))
|
||||||
{
|
{
|
||||||
|
//EnqueueSamplesEventArgs eventArgs = EnqueueSamplesEventArgs.Create(
|
||||||
|
// numChannels,
|
||||||
|
// channelSampleBuffer.Select(x => x.ToArray()).ToArray(),
|
||||||
|
// new bool[] { !channel1ForceEnable, !channel2ForceEnable, !channel3ForceEnable, !channel4ForceEnable },
|
||||||
|
// mixedSampleBuffer.ToArray());
|
||||||
|
|
||||||
EnqueueSamplesEventArgs eventArgs = EnqueueSamplesEventArgs.Create(
|
EnqueueSamplesEventArgs eventArgs = EnqueueSamplesEventArgs.Create(
|
||||||
numChannels,
|
numChannels,
|
||||||
channelSampleBuffer.Select(x => x.ToArray()).ToArray(),
|
channelSampleBuffer,
|
||||||
new bool[] { !channel1ForceEnable, !channel2ForceEnable, !channel3ForceEnable, !channel4ForceEnable },
|
new bool[] { !channel1ForceEnable, !channel2ForceEnable, !channel3ForceEnable, !channel4ForceEnable },
|
||||||
mixedSampleBuffer.ToArray());
|
mixedSampleBuffer,
|
||||||
|
mixedSampleBuffer_writePos);
|
||||||
|
|
||||||
OnEnqueueSamples(eventArgs);
|
OnEnqueueSamples(eventArgs);
|
||||||
|
|
||||||
FlushSamples();
|
FlushSamples();
|
||||||
@ -295,10 +356,18 @@ namespace Essgee.Emulation.Audio
|
|||||||
var ch3 = (short)(((channel3Enable[i] ? channel3.OutputVolume : 0) * (volumeRightLeft[i] + 1)) << 8);
|
var ch3 = (short)(((channel3Enable[i] ? channel3.OutputVolume : 0) * (volumeRightLeft[i] + 1)) << 8);
|
||||||
var ch4 = (short)(((channel4Enable[i] ? channel4.OutputVolume : 0) * (volumeRightLeft[i] + 1)) << 8);
|
var ch4 = (short)(((channel4Enable[i] ? channel4.OutputVolume : 0) * (volumeRightLeft[i] + 1)) << 8);
|
||||||
|
|
||||||
channelSampleBuffer[0].Add(ch1);
|
//废弃旧的数组方式
|
||||||
channelSampleBuffer[1].Add(ch2);
|
//channelSampleBuffer[0].Add(ch1);
|
||||||
channelSampleBuffer[2].Add(ch3);
|
//channelSampleBuffer[1].Add(ch2);
|
||||||
channelSampleBuffer[3].Add(ch4);
|
//channelSampleBuffer[2].Add(ch3);
|
||||||
|
//channelSampleBuffer[3].Add(ch4);
|
||||||
|
|
||||||
|
//二维指针下标
|
||||||
|
channelSampleBuffer_writePos++;
|
||||||
|
channelSampleBuffer[0][channelSampleBuffer_writePos] = ch1;
|
||||||
|
channelSampleBuffer[1][channelSampleBuffer_writePos] = ch2;
|
||||||
|
channelSampleBuffer[2][channelSampleBuffer_writePos] = ch3;
|
||||||
|
channelSampleBuffer[3][channelSampleBuffer_writePos] = ch4;
|
||||||
|
|
||||||
/* Mix samples */
|
/* Mix samples */
|
||||||
var mixed = 0;
|
var mixed = 0;
|
||||||
@ -308,16 +377,22 @@ namespace Essgee.Emulation.Audio
|
|||||||
if (channel4ForceEnable) mixed += ch4;
|
if (channel4ForceEnable) mixed += ch4;
|
||||||
mixed /= numChannels;
|
mixed /= numChannels;
|
||||||
|
|
||||||
mixedSampleBuffer.Add((short)mixed);
|
//废弃旧的方式
|
||||||
|
//mixedSampleBuffer.Add((short)mixed);
|
||||||
|
//指针下标
|
||||||
|
mixedSampleBuffer_writePos++;
|
||||||
|
mixedSampleBuffer[mixedSampleBuffer_writePos] = (short)mixed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FlushSamples()
|
public void FlushSamples()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numChannels; i++)
|
//for (int i = 0; i < numChannels; i++)
|
||||||
channelSampleBuffer[i].Clear();
|
// channelSampleBuffer[i].Clear();
|
||||||
|
channelSampleBuffer_writePos = 0;
|
||||||
|
|
||||||
mixedSampleBuffer.Clear();
|
//mixedSampleBuffer.Clear();
|
||||||
|
mixedSampleBuffer_writePos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual byte ReadPort(byte port)
|
public virtual byte ReadPort(byte port)
|
||||||
|
@ -4,11 +4,12 @@ using Essgee.Utilities;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using static Essgee.Emulation.Utilities;
|
using static Essgee.Emulation.Utilities;
|
||||||
|
|
||||||
namespace Essgee.Emulation.Audio
|
namespace Essgee.Emulation.Audio
|
||||||
{
|
{
|
||||||
public class SN76489 : IAudio
|
public unsafe class SN76489 : IAudio
|
||||||
{
|
{
|
||||||
/* http://www.smspower.org/Development/SN76489 */
|
/* http://www.smspower.org/Development/SN76489 */
|
||||||
/* Differences in various system's PSGs: http://forums.nesdev.com/viewtopic.php?p=190216#p190216 */
|
/* Differences in various system's PSGs: http://forums.nesdev.com/viewtopic.php?p=190216#p190216 */
|
||||||
@ -26,8 +27,60 @@ namespace Essgee.Emulation.Audio
|
|||||||
protected virtual int noiseBitShift => 14;
|
protected virtual int noiseBitShift => 14;
|
||||||
|
|
||||||
/* Sample generation & event handling */
|
/* Sample generation & event handling */
|
||||||
protected List<short>[] channelSampleBuffer;
|
//protected List<short>[] channelSampleBuffer;
|
||||||
protected List<short> mixedSampleBuffer;
|
|
||||||
|
|
||||||
|
#region //指针化 channelSampleBuffer
|
||||||
|
static short[][] channelSampleBuffer_src;
|
||||||
|
static GCHandle[] channelSampleBuffer_handle;
|
||||||
|
public static short*[] channelSampleBuffer;
|
||||||
|
public static int[] channelSampleBufferLength;
|
||||||
|
public static int channelSampleBuffer_writePos;
|
||||||
|
public static bool channelSampleBuffer_IsNull => channelSampleBuffer == null;
|
||||||
|
public static void channelSampleBuffer_Init(int length1, int Lenght2)
|
||||||
|
{
|
||||||
|
if (channelSampleBuffer_src != null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < channelSampleBuffer_src.Length; i++)
|
||||||
|
channelSampleBuffer_handle[i].ReleaseGCHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
channelSampleBuffer_src = new short[length1][];
|
||||||
|
channelSampleBuffer_handle = new GCHandle[length1];
|
||||||
|
channelSampleBuffer = new short*[length1];
|
||||||
|
channelSampleBuffer_writePos = 0;
|
||||||
|
for (int i = 0; i < channelSampleBuffer_src.Length; i++)
|
||||||
|
{
|
||||||
|
channelSampleBuffer_src[i] = new short[Lenght2];
|
||||||
|
channelSampleBuffer_src[i].GetObjectPtr(ref channelSampleBuffer_handle[i], ref channelSampleBuffer[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
//protected List<short> mixedSampleBuffer;
|
||||||
|
|
||||||
|
#region //指针化 mixedSampleBuffer
|
||||||
|
short[] mixedSampleBuffer_src;
|
||||||
|
GCHandle mixedSampleBuffer_handle;
|
||||||
|
public short* mixedSampleBuffer;
|
||||||
|
public int mixedSampleBufferLength;
|
||||||
|
public int mixedSampleBuffer_writePos;
|
||||||
|
public bool mixedSampleBuffer_IsNull => mixedSampleBuffer == null;
|
||||||
|
public short[] mixedSampleBuffer_set
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
mixedSampleBuffer_handle.ReleaseGCHandle();
|
||||||
|
mixedSampleBuffer_src = value;
|
||||||
|
mixedSampleBufferLength = value.Length;
|
||||||
|
mixedSampleBuffer_writePos = 0;
|
||||||
|
mixedSampleBuffer_src.GetObjectPtr(ref mixedSampleBuffer_handle, ref mixedSampleBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
public virtual event EventHandler<EnqueueSamplesEventArgs> EnqueueSamples;
|
public virtual event EventHandler<EnqueueSamplesEventArgs> EnqueueSamples;
|
||||||
public virtual void OnEnqueueSamples(EnqueueSamplesEventArgs e) { EnqueueSamples?.Invoke(this, e); }
|
public virtual void OnEnqueueSamples(EnqueueSamplesEventArgs e) { EnqueueSamples?.Invoke(this, e); }
|
||||||
|
|
||||||
@ -76,10 +129,14 @@ namespace Essgee.Emulation.Audio
|
|||||||
|
|
||||||
public SN76489()
|
public SN76489()
|
||||||
{
|
{
|
||||||
channelSampleBuffer = new List<short>[numChannels];
|
//channelSampleBuffer = new List<short>[numChannels];
|
||||||
for (int i = 0; i < numChannels; i++) channelSampleBuffer[i] = new List<short>();
|
//for (int i = 0; i < numChannels; i++) channelSampleBuffer[i] = new List<short>();
|
||||||
|
//mixedSampleBuffer = new List<short>();
|
||||||
|
|
||||||
|
//改为二维数组
|
||||||
|
channelSampleBuffer_Init(numChannels, 1470);
|
||||||
|
mixedSampleBuffer_set = new short[1470];
|
||||||
|
|
||||||
mixedSampleBuffer = new List<short>();
|
|
||||||
|
|
||||||
volumeRegisters = new ushort[numChannels];
|
volumeRegisters = new ushort[numChannels];
|
||||||
toneRegisters = new ushort[numChannels];
|
toneRegisters = new ushort[numChannels];
|
||||||
@ -211,13 +268,21 @@ namespace Essgee.Emulation.Audio
|
|||||||
sampleCycleCount -= cyclesPerSample;
|
sampleCycleCount -= cyclesPerSample;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mixedSampleBuffer.Count >= (samplesPerFrame * numOutputChannels))
|
//if (mixedSampleBuffer.Count >= (samplesPerFrame * numOutputChannels))
|
||||||
|
if (mixedSampleBuffer_writePos >= (samplesPerFrame * numOutputChannels))
|
||||||
{
|
{
|
||||||
|
//EnqueueSamplesEventArgs eventArgs = EnqueueSamplesEventArgs.Create(
|
||||||
|
// numChannels,
|
||||||
|
// channelSampleBuffer.Select(x => x.ToArray()).ToArray(),
|
||||||
|
// new bool[] { !channel1ForceEnable, !channel2ForceEnable, !channel3ForceEnable, !channel4ForceEnable },
|
||||||
|
// mixedSampleBuffer.ToArray());
|
||||||
|
|
||||||
EnqueueSamplesEventArgs eventArgs = EnqueueSamplesEventArgs.Create(
|
EnqueueSamplesEventArgs eventArgs = EnqueueSamplesEventArgs.Create(
|
||||||
numChannels,
|
numChannels,
|
||||||
channelSampleBuffer.Select(x => x.ToArray()).ToArray(),
|
channelSampleBuffer,
|
||||||
new bool[] { !channel1ForceEnable, !channel2ForceEnable, !channel3ForceEnable, !channel4ForceEnable },
|
new bool[] { !channel1ForceEnable, !channel2ForceEnable, !channel3ForceEnable, !channel4ForceEnable },
|
||||||
mixedSampleBuffer.ToArray());
|
mixedSampleBuffer,
|
||||||
|
mixedSampleBufferLength);
|
||||||
|
|
||||||
OnEnqueueSamples(eventArgs);
|
OnEnqueueSamples(eventArgs);
|
||||||
|
|
||||||
@ -291,10 +356,19 @@ namespace Essgee.Emulation.Audio
|
|||||||
var ch3 = (short)(volumeTable[volumeRegisters[2]] * ((toneRegisters[2] < 2 ? true : channelOutput[2]) ? 1.0 : 0.0));
|
var ch3 = (short)(volumeTable[volumeRegisters[2]] * ((toneRegisters[2] < 2 ? true : channelOutput[2]) ? 1.0 : 0.0));
|
||||||
var ch4 = (short)(volumeTable[volumeRegisters[3]] * (noiseLfsr & 0x1));
|
var ch4 = (short)(volumeTable[volumeRegisters[3]] * (noiseLfsr & 0x1));
|
||||||
|
|
||||||
channelSampleBuffer[0].Add(ch1);
|
//废弃旧的数组方式
|
||||||
channelSampleBuffer[1].Add(ch2);
|
//channelSampleBuffer[0].Add(ch1);
|
||||||
channelSampleBuffer[2].Add(ch3);
|
//channelSampleBuffer[1].Add(ch2);
|
||||||
channelSampleBuffer[3].Add(ch4);
|
//channelSampleBuffer[2].Add(ch3);
|
||||||
|
//channelSampleBuffer[3].Add(ch4);
|
||||||
|
|
||||||
|
//二维指针下标
|
||||||
|
channelSampleBuffer_writePos++;
|
||||||
|
channelSampleBuffer[0][channelSampleBuffer_writePos] = ch1;
|
||||||
|
channelSampleBuffer[1][channelSampleBuffer_writePos] = ch2;
|
||||||
|
channelSampleBuffer[2][channelSampleBuffer_writePos] = ch3;
|
||||||
|
channelSampleBuffer[3][channelSampleBuffer_writePos] = ch4;
|
||||||
|
|
||||||
|
|
||||||
/* Mix samples */
|
/* Mix samples */
|
||||||
var mixed = 0;
|
var mixed = 0;
|
||||||
@ -304,16 +378,22 @@ namespace Essgee.Emulation.Audio
|
|||||||
if (channel4ForceEnable) mixed += ch4;
|
if (channel4ForceEnable) mixed += ch4;
|
||||||
mixed /= numChannels;
|
mixed /= numChannels;
|
||||||
|
|
||||||
mixedSampleBuffer.Add((short)mixed);
|
//废弃旧的方式
|
||||||
|
//mixedSampleBuffer.Add((short)mixed);
|
||||||
|
//指针下标
|
||||||
|
mixedSampleBuffer_writePos++;
|
||||||
|
mixedSampleBuffer[mixedSampleBuffer_writePos] = (short)mixed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FlushSamples()
|
public void FlushSamples()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numChannels; i++)
|
//for (int i = 0; i < numChannels; i++)
|
||||||
channelSampleBuffer[i].Clear();
|
// channelSampleBuffer[i].Clear();
|
||||||
|
channelSampleBuffer_writePos = 0;
|
||||||
|
|
||||||
mixedSampleBuffer.Clear();
|
//mixedSampleBuffer.Clear();
|
||||||
|
mixedSampleBuffer_writePos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ushort CheckParity(ushort val)
|
private ushort CheckParity(ushort val)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Essgee.Emulation.Audio
|
namespace Essgee.Emulation.Audio
|
||||||
{
|
{
|
||||||
public class SegaGGPSG : SegaSMSPSG
|
public unsafe class SegaGGPSG : SegaSMSPSG
|
||||||
{
|
{
|
||||||
public const int PortStereoControl = 0x06;
|
public const int PortStereoControl = 0x06;
|
||||||
|
|
||||||
@ -34,10 +34,19 @@ namespace Essgee.Emulation.Audio
|
|||||||
var ch3 = (channel2Enable[i] ? (short)(volumeTable[volumeRegisters[2]] * ((toneRegisters[2] < 2 ? true : channelOutput[2]) ? 1.0 : 0.0)) : (short)0);
|
var ch3 = (channel2Enable[i] ? (short)(volumeTable[volumeRegisters[2]] * ((toneRegisters[2] < 2 ? true : channelOutput[2]) ? 1.0 : 0.0)) : (short)0);
|
||||||
var ch4 = (channel3Enable[i] ? (short)(volumeTable[volumeRegisters[3]] * (noiseLfsr & 0x1)) : (short)0);
|
var ch4 = (channel3Enable[i] ? (short)(volumeTable[volumeRegisters[3]] * (noiseLfsr & 0x1)) : (short)0);
|
||||||
|
|
||||||
channelSampleBuffer[0].Add(ch1);
|
|
||||||
channelSampleBuffer[1].Add(ch2);
|
//废弃旧的数组方式
|
||||||
channelSampleBuffer[2].Add(ch3);
|
//channelSampleBuffer[0].Add(ch1);
|
||||||
channelSampleBuffer[3].Add(ch4);
|
//channelSampleBuffer[1].Add(ch2);
|
||||||
|
//channelSampleBuffer[2].Add(ch3);
|
||||||
|
//channelSampleBuffer[3].Add(ch4);
|
||||||
|
|
||||||
|
//二维指针下标
|
||||||
|
channelSampleBuffer_writePos++;
|
||||||
|
channelSampleBuffer[0][channelSampleBuffer_writePos] = ch1;
|
||||||
|
channelSampleBuffer[1][channelSampleBuffer_writePos] = ch2;
|
||||||
|
channelSampleBuffer[2][channelSampleBuffer_writePos] = ch3;
|
||||||
|
channelSampleBuffer[3][channelSampleBuffer_writePos] = ch4;
|
||||||
|
|
||||||
/* Mix samples */
|
/* Mix samples */
|
||||||
var mixed = 0;
|
var mixed = 0;
|
||||||
@ -47,7 +56,11 @@ namespace Essgee.Emulation.Audio
|
|||||||
if (channel4ForceEnable) mixed += ch4;
|
if (channel4ForceEnable) mixed += ch4;
|
||||||
mixed /= numChannels;
|
mixed /= numChannels;
|
||||||
|
|
||||||
mixedSampleBuffer.Add((short)mixed);
|
//废弃旧的方式
|
||||||
|
//mixedSampleBuffer.Add((short)mixed);
|
||||||
|
//指针下标
|
||||||
|
mixedSampleBuffer_writePos++;
|
||||||
|
mixedSampleBuffer[mixedSampleBuffer_writePos] = (short)mixed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,12 +2,14 @@
|
|||||||
|
|
||||||
namespace Essgee.EventArguments
|
namespace Essgee.EventArguments
|
||||||
{
|
{
|
||||||
public class EnqueueSamplesEventArgs : EventArgs
|
public unsafe class EnqueueSamplesEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public int NumChannels { get; set; }
|
public int NumChannels { get; set; }
|
||||||
public short[][] ChannelSamples { get; set; }
|
//public short[][] ChannelSamples { get; set; }
|
||||||
|
public short*[] ChannelSamples { get; set; }
|
||||||
public bool[] IsChannelMuted { get; set; }
|
public bool[] IsChannelMuted { get; set; }
|
||||||
public short[] MixedSamples { get; set; }
|
public short* MixedSamples { get; set; }
|
||||||
|
public int MixedSamplesLength { get; set; }
|
||||||
|
|
||||||
//public EnqueueSamplesEventArgs(int numChannels, short[][] channelSamples, bool[] isMuted, short[] mixedSamples)
|
//public EnqueueSamplesEventArgs(int numChannels, short[][] channelSamples, bool[] isMuted, short[] mixedSamples)
|
||||||
//{
|
//{
|
||||||
@ -17,17 +19,19 @@ namespace Essgee.EventArguments
|
|||||||
// MixedSamples = mixedSamples;
|
// MixedSamples = mixedSamples;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
public static EnqueueSamplesEventArgs Create(int numChannels, short[][] channelSamples, bool[] isMuted, short[] mixedSamples)
|
//public static EnqueueSamplesEventArgs Create(int numChannels, short[][] channelSamples, bool[] isMuted, short[] mixedSamples)
|
||||||
|
public static EnqueueSamplesEventArgs Create(int numChannels, short*[] channelSamples, bool[] isMuted, short* mixedSamples,int mixedSamplesLength)
|
||||||
{
|
{
|
||||||
var eventArgs = ObjectPoolAuto.Acquire<EnqueueSamplesEventArgs>();
|
var eventArgs = ObjectPoolAuto.Acquire<EnqueueSamplesEventArgs>();
|
||||||
eventArgs.NumChannels = numChannels;
|
eventArgs.NumChannels = numChannels;
|
||||||
eventArgs.ChannelSamples = channelSamples;
|
eventArgs.ChannelSamples = channelSamples;
|
||||||
eventArgs.IsChannelMuted = isMuted;
|
eventArgs.IsChannelMuted = isMuted;
|
||||||
eventArgs.MixedSamples = mixedSamples;
|
eventArgs.MixedSamples = mixedSamples;
|
||||||
|
eventArgs.MixedSamplesLength = mixedSamplesLength;
|
||||||
return eventArgs;
|
return eventArgs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static class EnqueueSamplesEventArgsEx
|
public unsafe static class EnqueueSamplesEventArgsEx
|
||||||
{
|
{
|
||||||
public static void Release(this EnqueueSamplesEventArgs eventArgs)
|
public static void Release(this EnqueueSamplesEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
|
@ -346,7 +346,7 @@ public class Essgeeinit : MonoBehaviour
|
|||||||
|
|
||||||
private void LoadAndRunCartridge(string fileName)
|
private void LoadAndRunCartridge(string fileName)
|
||||||
{
|
{
|
||||||
//Application.targetFrameRate = 60;
|
Application.targetFrameRate = 60;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var (machineType, romData) = CartridgeLoader.Load(fileName, "ROM image");
|
var (machineType, romData) = CartridgeLoader.Load(fileName, "ROM image");
|
||||||
@ -698,7 +698,7 @@ public class Essgeeinit : MonoBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EnqueueSoundSamples(object sender, EnqueueSamplesEventArgs e)
|
public unsafe void EnqueueSoundSamples(object sender, EnqueueSamplesEventArgs e)
|
||||||
{
|
{
|
||||||
//if (sampleQueue.Count > MaxQueueLength)
|
//if (sampleQueue.Count > MaxQueueLength)
|
||||||
//{
|
//{
|
||||||
@ -718,7 +718,8 @@ public class Essgeeinit : MonoBehaviour
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
//TODO 音频处理
|
//TODO 音频处理
|
||||||
soundHandler.SubmitSamples(e.MixedSamples, e.ChannelSamples, e.MixedSamples.Length);
|
//soundHandler.SubmitSamples(e.MixedSamples, e.ChannelSamples, e.MixedSamples.Length);
|
||||||
|
soundHandler.SubmitSamples(e.MixedSamples, e.ChannelSamples, e.MixedSamplesLength);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ public class UEGSoundPlayer : MonoBehaviour//, ISoundPlayer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SubmitSamples(short[] buffer, short[][] ChannelSamples, int samples_a)
|
public unsafe void SubmitSamples(short* buffer, short*[] ChannelSamples, int samples_a)
|
||||||
{
|
{
|
||||||
var current = Essgeeinit.sw.Elapsed;
|
var current = Essgeeinit.sw.Elapsed;
|
||||||
var delta = current - lastElapsed;
|
var delta = current - lastElapsed;
|
||||||
@ -74,9 +74,7 @@ public class UEGSoundPlayer : MonoBehaviour//, ISoundPlayer
|
|||||||
|
|
||||||
for (int i = 0; i < samples_a; i += 2)
|
for (int i = 0; i < samples_a; i += 2)
|
||||||
{
|
{
|
||||||
//_buffer.Write(buffer[i] / 32767.0f);
|
_buffer.Write(buffer[i] / 32767.0f);
|
||||||
float data = (uint)(buffer[i] + 32767);
|
|
||||||
_buffer.Write(data / ushort.MaxValue);
|
|
||||||
//_buffer.Write(buffer[i] / 32767.0f);
|
//_buffer.Write(buffer[i] / 32767.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user