mirror of
https://github.com/digital-jellyfish/Virtu.git
synced 2025-02-17 04:32:21 +00:00
Included missing changes from last checkin.
--HG-- extra : convert_revision : svn%3Affd33b8c-2492-42e0-bdc5-587b920b7d6d/trunk%4043069
This commit is contained in:
parent
ea2a892113
commit
0d1a883260
@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
namespace Jellyfish.Virtu.Services
|
||||
{
|
||||
@ -10,19 +10,26 @@ namespace Jellyfish.Virtu.Services
|
||||
{
|
||||
}
|
||||
|
||||
public void ToggleOutput() // machine thread
|
||||
public void Output(int data) // machine thread
|
||||
{
|
||||
lock (_lock)
|
||||
_buffer[_index] = (byte)data;
|
||||
_index = (_index + 1) % SampleSize;
|
||||
if (_index == 0)
|
||||
{
|
||||
long cycles = Machine.Cpu.Cycles;
|
||||
int toggleDelta = (int)(cycles - _toggleCycles);
|
||||
_toggleCycles = cycles;
|
||||
|
||||
_deltaBuffer[_writeIndex] = toggleDelta;
|
||||
_writeIndex = (_writeIndex + 1) % DeltaBufferSize;
|
||||
_readEvent.Set();
|
||||
if (Machine.Settings.Cpu.IsThrottled)
|
||||
{
|
||||
_writeEvent.WaitOne();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Stop() // main thread
|
||||
{
|
||||
_readEvent.Set(); // signal events; avoids deadlock
|
||||
_writeEvent.Set();
|
||||
}
|
||||
|
||||
protected void Update(int bufferSize, Action<byte[], int> updateBuffer) // audio thread
|
||||
{
|
||||
if (updateBuffer == null)
|
||||
@ -30,39 +37,12 @@ namespace Jellyfish.Virtu.Services
|
||||
throw new ArgumentNullException("updateBuffer");
|
||||
}
|
||||
|
||||
lock (_lock)
|
||||
if (Machine.State == MachineState.Running)
|
||||
{
|
||||
long cycles = Machine.Cpu.Cycles;
|
||||
int updateDelta = (int)(cycles - _updateCycles);
|
||||
_updateCycles = _toggleCycles = cycles; // reset audio frame
|
||||
|
||||
if (updateDelta > 0)
|
||||
{
|
||||
double bytesPerCycle = (double)bufferSize / (Machine.Settings.Cpu.IsThrottled ? CyclesPerSample : updateDelta);
|
||||
|
||||
while (_readIndex != _writeIndex)
|
||||
{
|
||||
int deltaSize = (int)(_deltaBuffer[_readIndex] * bytesPerCycle);
|
||||
if (deltaSize > bufferSize)
|
||||
{
|
||||
_deltaBuffer[_readIndex] -= (int)((double)bufferSize / bytesPerCycle);
|
||||
break;
|
||||
}
|
||||
|
||||
updateBuffer(_isOutputHigh ? SampleHigh : SampleZero, deltaSize);
|
||||
_isOutputHigh ^= true;
|
||||
|
||||
bufferSize -= deltaSize;
|
||||
_readIndex = (_readIndex + 1) % DeltaBufferSize;
|
||||
}
|
||||
|
||||
updateBuffer(_isOutputHigh ? SampleHigh : SampleZero, bufferSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
updateBuffer(SampleZero, bufferSize);
|
||||
}
|
||||
_readEvent.WaitOne();
|
||||
}
|
||||
updateBuffer(_buffer, bufferSize);
|
||||
_writeEvent.Set();
|
||||
}
|
||||
|
||||
public const int SampleRate = 44100; // hz
|
||||
@ -71,20 +51,10 @@ namespace Jellyfish.Virtu.Services
|
||||
public const int SampleLatency = 40; // ms
|
||||
public const int SampleSize = (int)(SampleRate * SampleLatency / 1000f) * SampleChannels * SampleBits / 8;
|
||||
|
||||
private const int CyclesPerSecond = 1022730;
|
||||
private const int CyclesPerSample = (int)(CyclesPerSecond * SampleLatency / 1000f);
|
||||
private byte[] _buffer = new byte[SampleSize];
|
||||
private int _index;
|
||||
|
||||
private static readonly byte[] SampleHigh = Enumerable.Repeat((byte)0xFF, SampleSize).ToArray();
|
||||
private static readonly byte[] SampleZero = new byte[SampleSize];
|
||||
|
||||
private const int DeltaBufferSize = 8192;
|
||||
|
||||
private int[] _deltaBuffer = new int[DeltaBufferSize];
|
||||
private uint _readIndex;
|
||||
private uint _writeIndex;
|
||||
private bool _isOutputHigh;
|
||||
private long _toggleCycles;
|
||||
private long _updateCycles;
|
||||
private object _lock = new object();
|
||||
private AutoResetEvent _readEvent = new AutoResetEvent(false);
|
||||
private AutoResetEvent _writeEvent = new AutoResetEvent(false);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user