Skip to content

Instantly share code, notes, and snippets.

@GlaireDaggers
Last active August 27, 2021 22:52
Show Gist options
  • Save GlaireDaggers/2fba4847b00ce53abfbb321801efc507 to your computer and use it in GitHub Desktop.
Save GlaireDaggers/2fba4847b00ce53abfbb321801efc507 to your computer and use it in GitHub Desktop.
Psuedo code for a tracker-style synth engine in C#
using System;
class Voice
{
public void Mix(float[] target, int offset, int length)
{
// TODO: mix channel into target
Array.Clear(target, offset, length);
}
}
class MySynth
{
Voice[] _channels;
float[] _tmpBuffer;
int _tickLen;
int _tickRem;
public MySynth()
{
_channels = new Voice[8];
for (int i = 0; i < _channels.Length; i++)
{
_channels[i] = new Voice();
}
// just an example
_tickLen = 100;
}
private void Tick()
{
// TODO: do playback engine tick here
}
// NOTE: assuming a stereo buffer of interleaved LRLRLR... samples
public void Mix(float[] target, int offset, int length)
{
// clear portion of target array
Array.Clear(target, offset, length);
// allocate tmp buffer as needed
if (_tmpBuffer == null || _tmpBuffer.Length < length)
{
_tmpBuffer = new float[length];
}
// did we have leftover samples from last mix?
if (_tickRem > 0)
{
for (int i = 0; i < _channels.Length; i++)
{
_channels[i].Mix(_tmpBuffer, offset, _tickRem * 2);
}
}
// for each _tickLen samples, do a tick then mix channels into target
for (int i = _tickRem * 2; i < length; i += _tickLen * 2)
{
Tick();
int rem = length - i;
if (rem > _tickLen * 2)
{
rem = _tickLen * 2;
}
for (int c = 0; c < _channels.Length; c++)
{
_channels[c].Mix(_tmpBuffer, 0, rem);
for (int j = 0; j < rem; j++)
{
target[offset + i + j] += _tmpBuffer[j];
}
}
_tickRem = _tickLen - (rem / 2);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment