Struct NoteEvent
- Namespace
- Sigil.Sound
- Assembly
- Sigil.Sound.Notes.dll
One thing that happens to a note in a Sigil.Sound.NoteStream: it starts, or it ends. Unlike a Sigil.Sound.Note in a pattern, which knows how long it lasts, a live note has no length: it lasts until its Sigil.Sound.NoteEventKind.Off arrives.
public readonly record struct NoteEvent : IEquatable<NoteEvent>Implements
Inherited Members
Remarks
Sigil.Sound.NoteEvent.Id is what pairs the two events. Every operator keeps the pairing: an Off always ends the notes that its
On produced, whatever the operator would compute for that note now. The pitch of a note is the nearest MIDI pitch and
Sigil.Sound.NoteEvent.Cents the distance from it, so notes from other tunings and bent notes keep their exact pitch through every operator.
Constructors
NoteEvent(NoteEventKind, long, int, float, float, int)
One thing that happens to a note in a Sigil.Sound.NoteStream: it starts, or it ends. Unlike a Sigil.Sound.Note in a pattern, which knows how long it lasts, a live note has no length: it lasts until its Sigil.Sound.NoteEventKind.Off arrives.
public NoteEvent(NoteEventKind Kind, long Id, int Pitch, float Velocity = 0.8, float Cents = 0, int Channel = 0)Parameters
KindNoteEventKind-
Starts or ends the note.
Idlong-
Identifies the note; the same on its
Onand itsOff. Unique among the notes sounding in one stream. Pitchint-
The nearest MIDI pitch, 0 to 127; 60 is middle C.
Velocityfloat-
How hard the note was played, from 0 to 1. Meaningful for an
On. Centsfloat-
Hundredths of a semitone above
Pitch(negative for below). Channelint-
A routing tag that operators leave alone; a function of yours may set or read it (
n with { Channel = 2 }).
Remarks
Sigil.Sound.NoteEvent.Id is what pairs the two events. Every operator keeps the pairing: an Off always ends the notes that its
On produced, whatever the operator would compute for that note now. The pitch of a note is the nearest MIDI pitch and
Sigil.Sound.NoteEvent.Cents the distance from it, so notes from other tunings and bent notes keep their exact pitch through every operator.
Properties
Cents
Hundredths of a semitone above Pitch (negative for below).
public float Cents { get; init; }Property Value
Channel
A routing tag that operators leave alone; a function of yours may set or read it (n with { Channel = 2 }).
public int Channel { get; init; }Property Value
Frequency
The note's frequency in Hz, in 12-tone equal temperament with A4 (MIDI 69) at 440 Hz, including Sigil.Sound.NoteEvent.Cents.
public double Frequency { get; }Property Value
Id
Identifies the note; the same on its On and its Off. Unique among the notes sounding in one stream.
public long Id { get; init; }Property Value
IsOn
True for the event that starts the note.
public bool IsOn { get; }Property Value
Kind
Starts or ends the note.
public NoteEventKind Kind { get; init; }Property Value
Pitch
The nearest MIDI pitch, 0 to 127; 60 is middle C.
public int Pitch { get; init; }Property Value
PitchWithCents
The pitch as a fraction of a MIDI note number: 60.5 is a quarter tone above middle C.
public double PitchWithCents { get; }Property Value
Velocity
How hard the note was played, from 0 to 1. Meaningful for an On.
public float Velocity { get; init; }Property Value
Methods
Chance(double, int)
True for a random share of notes: Where(n => n.Chance(0.3)) lets 3 in 10 through. Which ones depends only on the
seed and the note's Sigil.Sound.NoteEvent.Id, so the same performance is picked the same way every time.
public bool Chance(double probability, int seed = 0)Parameters
Returns
Examples
// Seven in ten of the notes get through, the same ones every time.
var keys = new NoteInput();
var sound = keys.Stream.Where(n => n.Chance(0.7, seed: 4))
.Play(v => Saw(v.Frequency).LowPass(1800).Adsr(0.005, 0.2, 0.5, 0.2), polyphony: 12);
keys.NoteOn("c3 d3 e3 f3 g3 a3 b3 c4");
sound * 0.2
Detune(double)
This note moved by cents hundredths of a semitone, carrying whole semitones into the pitch.
public NoteEvent Detune(double cents)Parameters
centsdouble-
How far to move, up (positive) or down.
Returns
Examples
// Every note 30 cents sharp, so against an untouched copy of the stream the pair beats slowly.
var keys = new NoteInput();
var sound = (keys.Stream + keys.Stream.Select(n => n.Detune(30)))
.Play(v => Saw(v.Frequency).LowPass(1800).Adsr(0.005, 0.2, 0.5, 0.25));
keys.NoteOn("c3 g3");
sound * 0.3
InScale(Scale)
True when the note is a tone of scale, in any octave. Where(n => n.InScale(scale)) keeps those.
public bool InScale(Scale scale)Parameters
scaleScale-
The scale, such as
Scale.Parse("d dorian").
Returns
Examples
// Only the keys that belong to D dorian get through: the C# and G# are left out.
var keys = new NoteInput();
var dorian = Scale.Parse("d dorian");
var sound = keys.Stream.Where(n => n.InScale(dorian))
.Play(v => Square(v.Frequency).LowPass(1500).Adsr(0.005, 0.2, 0.4, 0.2));
keys.NoteOn("d3 c#3 f3 g#3 a3");
sound * 0.2
Snap(Scale, QuantizeMode)
This note moved to a tone of scale, in any octave; a note already in the scale is returned as it is. The cents
of a moved note are cleared. Select(n => n.Snap(scale)) quantizes a stream.
public NoteEvent Snap(Scale scale, QuantizeMode mode = QuantizeMode.Nearest)Parameters
scaleScale-
The tones allowed.
modeQuantizeMode-
Which tone a note between two goes to. Defaults to the closest, and the lower one when two are equally close.
Returns
Examples
// Keys outside D dorian are moved to the nearest tone of it, so whatever is played stays in the scale.
var keys = new NoteInput();
var dorian = Scale.Parse("d dorian");
var sound = keys.Stream.Select(n => n.Snap(dorian))
.Play(v => Triangle(v.Frequency).LowPass(2000).Adsr(0.01, 0.2, 0.6, 0.3));
keys.NoteOn("d3 f#3 a3 c#4");
sound * 0.3
Start(long, int, float, float, int)
An event that starts a note.
public static NoteEvent Start(long id, int pitch, float velocity = 0.8, float cents = 0, int channel = 0)Parameters
Returns
Stop(long, int, float, int)
An event that ends a note.
public static NoteEvent Stop(long id, int pitch, float cents = 0, int channel = 0)Parameters
Returns
Transpose(int)
This note moved by semitones. A note moved out of the MIDI range is dropped by the stream that gets it.
public NoteEvent Transpose(int semitones)Parameters
semitonesint-
How far to move, up (positive) or down.
Returns
Examples
// A function of your own that moves a note: loud ones up an octave, soft ones down a fifth.
var keys = new NoteInput();
var sound = keys.Stream.Select(n => n.Velocity > 0.7f ? n.Transpose(12) : n.Transpose(-5))
.Play(v => Saw(v.Frequency).LowPass(1800).Adsr(0.005, 0.2, 0.5, 0.25));
keys.NoteOn("c3:0.9 e3:0.4");
sound * 0.3