110 lines
3.0 KiB
C#
110 lines
3.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
namespace BizHawk.Emulation.Sound.Utilities
|
|
{
|
|
/// <summary>
|
|
/// provides pass-through sound for the dumping tool to use, while making a "best effort"
|
|
/// to have something available for audio output
|
|
/// </summary>
|
|
public class DualSound : ISoundProvider
|
|
{
|
|
/// <summary>
|
|
/// implementation of a "slave" ISoundProvider that recieves best effort audio
|
|
/// </summary>
|
|
class SecondPin : ISoundProvider
|
|
{
|
|
/// <summary>
|
|
/// the source to draw from
|
|
/// </summary>
|
|
DualSound master;
|
|
|
|
public SecondPin(DualSound master)
|
|
{
|
|
this.master = master;
|
|
}
|
|
|
|
public void GetSamples(short[] samples)
|
|
{
|
|
int i;
|
|
for (i = 0; i < Math.Min(samples.Length, master.ringbuffer.Count); i++)
|
|
samples[i] = master.ringbuffer.Dequeue();
|
|
for (; i < samples.Length; i++)
|
|
// underflow
|
|
samples[i] = 0;
|
|
}
|
|
|
|
public void DiscardSamples()
|
|
{
|
|
master.ringbuffer.Clear();
|
|
}
|
|
|
|
public int MaxVolume
|
|
{
|
|
// ignored
|
|
get;
|
|
set;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// original input source
|
|
/// </summary>
|
|
ISoundProvider input;
|
|
|
|
/// <summary>
|
|
/// threshold at which to discard samples
|
|
/// </summary>
|
|
int killsize;
|
|
|
|
/// <summary>
|
|
/// storage of samples waiting to go to second pin
|
|
/// </summary>
|
|
Queue<short> ringbuffer;
|
|
|
|
/// <summary>
|
|
/// get the slave pin
|
|
/// </summary>
|
|
public ISoundProvider secondpin
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
/// <summary>
|
|
/// default constructor
|
|
/// </summary>
|
|
/// <param name="input">the ISoundProvider to use as input</param>
|
|
/// <param name="buffsize">how many sample pairs to save for the second pin</param>
|
|
public DualSound(ISoundProvider input, int buffsize)
|
|
{
|
|
this.input = input;
|
|
killsize = buffsize * 2;
|
|
ringbuffer = new Queue<short>(killsize);
|
|
secondpin = new SecondPin(this);
|
|
}
|
|
|
|
public void GetSamples(short[] samples)
|
|
{
|
|
input.GetSamples(samples);
|
|
if (ringbuffer.Count >= killsize)
|
|
ringbuffer.Clear();
|
|
foreach (var sample in samples)
|
|
ringbuffer.Enqueue(sample);
|
|
}
|
|
|
|
public void DiscardSamples()
|
|
{
|
|
throw new Exception("Dumpers should never discard samples!");
|
|
}
|
|
|
|
public int MaxVolume
|
|
{
|
|
get { return input.MaxVolume; }
|
|
set { input.MaxVolume = value; }
|
|
}
|
|
}
|
|
}
|