Class SamplerEngine
The shared polyphonic sampler engine: a pool of NAudio.Sampler.SamplerVoices driven by MIDI, rendering 32-bit float stereo through the ISampleProvider pull model, with voice stealing, exclusive (choke) groups, sustain-pedal hold, per-channel controller state, and shared reverb/chorus send buses. Format-specific subclasses (SoundFontSampler, SfzSampler) only supply the regions a note should play; everything else lives here so both formats run through one engine.
public abstract class SamplerEngine : IMidiInstrument, ISampleProvider
- Inheritance
-
SamplerEngine
- Implements
- Derived
- Inherited Members
- Extension Methods
Remarks
The engine is single-threaded by design: Read(Span<float>) and every MIDI entry point (ProcessMidiEvent(MidiEvent), NoteOn(int, int, int), NoteOff(int, int), …) must be called from one thread — normally the audio thread. To drive it from asynchronous sources (a MIDI input callback, a UI), wrap it in LiveMidiInstrument, which queues events lock-free and applies them on the audio thread.
Subclassing is deliberately internal for v1: the abstract region supply is
private protected and the format-neutral region model is internal,
so new instrument formats are added inside NAudio.Sampler. Widening this
later is non-breaking; see the "Deliberate v1 constraints" section of
Docs/Architecture/SamplerDesign.md.
Constructors
SamplerEngine(int, int)
Creates the engine with a voice pool and the shared send buses.
protected SamplerEngine(int sampleRate, int maxVoices)
Parameters
Fields
MaxFramesPerBlock
Maximum frames rendered per internal block.
protected const int MaxFramesPerBlock = 1024
Field Value
Properties
ActiveVoiceCount
The number of voices currently sounding.
public int ActiveVoiceCount { get; }
Property Value
Chorus
The shared chorus effect voices feed through their chorus send.
public ChorusEffect Chorus { get; }
Property Value
MasterGain
Master output gain applied after mixing all voices. Default 1.
public float MasterGain { get; set; }
Property Value
Reverb
The shared reverb effect voices feed through their reverb send.
public ReverbEffect Reverb { get; }
Property Value
WaveFormat
The output format: 32-bit float stereo at the configured sample rate.
public WaveFormat WaveFormat { get; }
Property Value
Methods
AllNotesOff()
Releases all held notes on every channel, honouring each channel's sustain pedal: per the MIDI 1.0 spec, All Notes Off (CC123) behaves as if a note-off were received for each note, so notes on a channel whose damper pedal is down keep ringing (parked) until pedal-up — which then also fires their release triggers, like an ordinary pedalled note-off. One-shot and release-triggered voices ignore note-off and are unaffected; use AllSoundOff() to silence everything.
public void AllNotesOff()
AllSoundOff()
Stops every sounding voice immediately (with a short fade).
public void AllSoundOff()
GetActivePlaybackPositions(double[])
Copies each active voice's current source-sample read position into
destination (up to its length), returning the count
written. For UI playback indicators — allocation-free and cheap; safe to
call from the UI thread (a momentarily stale read is harmless).
public int GetActivePlaybackPositions(double[] destination)
Parameters
destinationdouble[]
Returns
NoteOff(int, int)
Releases a note on a channel. With the sustain pedal down the note is remembered and only released when the pedal rises.
public void NoteOff(int channel, int note)
Parameters
NoteOn(int, int, int)
Starts a note on a channel at a given velocity.
public void NoteOn(int channel, int note, int velocity)
Parameters
ProcessMidiEvent(MidiEvent)
Dispatches a MIDI event (note on/off, control change, pitch-bend, channel pressure, program change). Unsupported messages are ignored.
public void ProcessMidiEvent(MidiEvent midiEvent)
Parameters
midiEventMidiEvent
Read(Span<float>)
Fill the specified buffer with 32 bit floating point samples
public int Read(Span<float> buffer)
Parameters
Returns
- int
The number of samples written. Return 0 to signal end of stream.