mirror of
https://github.com/digital-jellyfish/Virtu.git
synced 2024-06-12 01:29:27 +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;
|
||||||
using System.Linq;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
|
@ -10,19 +10,26 @@ public AudioService(Machine machine) :
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
_readEvent.Set();
|
||||||
int toggleDelta = (int)(cycles - _toggleCycles);
|
if (Machine.Settings.Cpu.IsThrottled)
|
||||||
_toggleCycles = cycles;
|
{
|
||||||
|
_writeEvent.WaitOne();
|
||||||
_deltaBuffer[_writeIndex] = toggleDelta;
|
}
|
||||||
_writeIndex = (_writeIndex + 1) % DeltaBufferSize;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
protected void Update(int bufferSize, Action<byte[], int> updateBuffer) // audio thread
|
||||||
{
|
{
|
||||||
if (updateBuffer == null)
|
if (updateBuffer == null)
|
||||||
|
@ -30,39 +37,12 @@ protected void Update(int bufferSize, Action<byte[], int> updateBuffer) // audio
|
||||||
throw new ArgumentNullException("updateBuffer");
|
throw new ArgumentNullException("updateBuffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (_lock)
|
if (Machine.State == MachineState.Running)
|
||||||
{
|
{
|
||||||
long cycles = Machine.Cpu.Cycles;
|
_readEvent.WaitOne();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
updateBuffer(_buffer, bufferSize);
|
||||||
|
_writeEvent.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
public const int SampleRate = 44100; // hz
|
public const int SampleRate = 44100; // hz
|
||||||
|
@ -71,20 +51,10 @@ protected void Update(int bufferSize, Action<byte[], int> updateBuffer) // audio
|
||||||
public const int SampleLatency = 40; // ms
|
public const int SampleLatency = 40; // ms
|
||||||
public const int SampleSize = (int)(SampleRate * SampleLatency / 1000f) * SampleChannels * SampleBits / 8;
|
public const int SampleSize = (int)(SampleRate * SampleLatency / 1000f) * SampleChannels * SampleBits / 8;
|
||||||
|
|
||||||
private const int CyclesPerSecond = 1022730;
|
private byte[] _buffer = new byte[SampleSize];
|
||||||
private const int CyclesPerSample = (int)(CyclesPerSecond * SampleLatency / 1000f);
|
private int _index;
|
||||||
|
|
||||||
private static readonly byte[] SampleHigh = Enumerable.Repeat((byte)0xFF, SampleSize).ToArray();
|
private AutoResetEvent _readEvent = new AutoResetEvent(false);
|
||||||
private static readonly byte[] SampleZero = new byte[SampleSize];
|
private AutoResetEvent _writeEvent = new AutoResetEvent(false);
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user