using System;
using NAudio.Utils;
using NAudio.Wave;
using LibPDBinding.Managed;
using LibPDBinding.Managed.Events;
namespace LibPdBindingNaudio
{
class NewApiPdProvider : IWaveProvider, IDisposable
{
static readonly int Ticks = 8;
static readonly int SampleRate = 44100;
static readonly int Channels = 2;
CircularBuffer _circularBuffer;
int _minBuffer;
Pd _pd;
Patch _patch;
float[] _pdBuffer;
public NewApiPdProvider ()
{
SetUpPd ();
SetUpBuffer ();
RefillBuffer ();
}
~NewApiPdProvider ()
{
Dispose (false);
}
void SetUpBuffer ()
{
int blocksize = _pd.BlockSize;
_circularBuffer = new CircularBuffer (blocksize * Ticks * Channels * 4); _pdBuffer = new float[Ticks * Channels * blocksize];
_minBuffer = blocksize * Ticks * Channels * 2;
}
void SetUpPd ()
{
_pd = new Pd (0, 2, SampleRate);
_patch = _pd.LoadPatch ("../../../pd/test.pd");
_pd.Messaging.Float += Pd_Float;
_pd.Messaging.Bind (CursorReceiver);
_pd.Start ();
}
void Pd_Float (object sender, FloatEventArgs e)
{
Console.WriteLine ("{0}, {1}", e.Receiver, e.Float.Value);
}
void RefillBuffer ()
{
while (_circularBuffer.Count < _minBuffer) {
_pd.Process (Ticks, new float[0], _pdBuffer);
_circularBuffer.Write (PcmFromFloat (_pdBuffer), 0, _pdBuffer.Length * 4);
}
}
byte[] PcmFromFloat (float[] pdOutput)
{
WaveBuffer wavebuffer = new WaveBuffer (pdOutput.Length * 4);
for (var i = 0; i < pdOutput.Length; i++) {
wavebuffer.FloatBuffer [i] = pdOutput [i];
}
return wavebuffer.ByteBuffer;
}
public int Read (byte[] buffer, int offset, int count)
{
int read = _circularBuffer.Read (buffer, offset, count);
RefillBuffer ();
return read;
}
public WaveFormat WaveFormat {
get {
return WaveFormat.CreateIeeeFloatWaveFormat (SampleRate, Channels);
}
}
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
void Dispose (bool isDisposing)
{
_pd.Messaging.Unbind (CursorReceiver);
_pd.Messaging.Float -= Pd_Float;
_pd.Stop ();
_patch.Dispose ();
_pd.Dispose ();
}
public static string CursorReceiver = "cursor";
}
}