Table of Contents

Class Sounds

Namespace
Sigil.Sound
Assembly
Sigil.Sound.dll

Sources: the starting points of a sound. Designed for using static Sigil.Sound.Sounds;.

public static class Sounds

Inheritance

Inherited Members

Properties

Silence

Silence.

public static Sound Silence { get; }

Property Value

Sound

Methods

Constant(double)

A constant signal (DC). Mostly useful as a building block.

public static Sound Constant(double value)

Parameters

value double

The level to output.

Returns

Sound

Fn(Func<double, double>)

A sound whose value is a function of time in seconds, such as Fn(t => 200 + 100 * t). Use it wherever a Sigil.Sound.Param is expected; C# cannot convert a bare lambda to Sigil.Sound.Param. The function runs on the audio thread once per frame, so it must not allocate.

public static Sound Fn(Func<double, double> function)

Parameters

function Func<double, double>

Maps time in seconds since the sound started to a value in [-1, 1] when played, or to any number when used as a parameter. When the render context has a Sigil.Sound.HostClock, time is the host's instead, so a replacement sound carries on from where the old one was. Inside a note voice it is always the time since the note began.

Returns

Sound

Examples

Sine(Fn(t => 200 + 100 * t))   // a rising pitch

Fn(Func<double, double>, FunctionRate)

Like Sigil.Sound.Sounds.Fn(System.Func{System.Double,System.Double}), but evaluated at the chosen rate. Sigil.Sound.FunctionRate.PerMillisecond calls the function about once a millisecond and draws a straight line between the answers: far cheaper for slow movement such as a stepped melody, filter sweep or envelope, and the same at any block size.

public static Sound Fn(Func<double, double> function, FunctionRate rate)

Parameters

function Func<double, double>

Maps time in seconds to a value; see Sigil.Sound.Sounds.Fn(System.Func{System.Double,System.Double}).

rate FunctionRate

How often the function runs.

Returns

Sound

Examples

// A cutoff that is recomputed once per millisecond instead of once per sample: cheaper, and smooth enough for a sweep.
Saw(110).LowPass(Fn(t => 200 + 4000 * Math.Abs(Math.Sin(t)), FunctionRate.PerMillisecond)) * 0.3

Noise(int)

White noise, independent per channel. The same seed renders the same noise.

public static Sound Noise(int seed = 1)

Parameters

seed int

Starting value of the generator; change it for different noise. Defaults to 1.

Returns

Sound

Examples

Noise().LowPass(1000) * 0.2

Sample(AudioBuffer, Param?, PlaybackMode, double, double?)

Plays a recorded or rendered sample, such as a drum hit or a loop. Speed sets the pitch: 2 is an octave up and 0.5 an octave down. A negative speed plays backward: a one-shot starts at its last frame and runs back to its first. Blending between frames keeps fractional speeds smooth.

public static Sound Sample(AudioBuffer buffer, Param? speed = null, PlaybackMode mode = PlaybackMode.OneShot, double loopStart = 0, double? loopEnd = null)

Parameters

buffer AudioBuffer

The audio to play, usually from Sigil.Sound.AudioBuffer.FromWav(System.IO.Stream) or a rendered sound.

speed Param?

Playback rate: 1 is the original pitch and speed. A number, or a sound or Fn(t => ...) to bend or vibrato it. Defaults to 1.

mode PlaybackMode

How the sample plays: once, looped, or ping-ponged. Defaults to Sigil.Sound.PlaybackMode.OneShot.

loopStart double

Where the loop begins, in seconds from the start of the sample. Used only by Sigil.Sound.PlaybackMode.Loop and Sigil.Sound.PlaybackMode.PingPong. Defaults to 0.

loopEnd double?

Where the loop ends, in seconds from the start of the sample. Defaults to null, the end of the sample. Must be after loopStart.

Returns

Sound

Examples

// One hit at the recorded pitch.
Sample(Samples.Load("pluck.wav"))
// A loop an octave down.
Sample(Samples.Load("pluck.wav"), speed: 0.5, mode: PlaybackMode.Loop) * 0.5
// Ping-pong between two points of the sample: forward from 0.05 s to 0.4 s, then backward, and so on.
Sample(Samples.Load("pluck.wav"), mode: PlaybackMode.PingPong, loopStart: 0.05, loopEnd: 0.4) * 0.5

Remarks

The sample is held in memory and read without allocating, so a single Sigil.Sound.AudioBuffer can back many voices. Its own sample rate is converted to the render rate, so a 44.1 kHz file plays at the right pitch in a 48 kHz render. For a sampler instrument, pitch each note by its frequency over the sample's root: Sample(kick, speed: v.Frequency / 261.63) plays a sample recorded at C4 at the pitch of each played note.

Exceptions

ArgumentException

The buffer has no frames.

ArgumentOutOfRangeException

The loop markers are outside the sample, or in the wrong order.

Sample(AudioBuffer, Param, double, PlaybackMode, double, double?)

Plays a sample at a pitch: the sample sounds at rootFrequency when played at that frequency, and every other frequency transposes it by the ratio. Use it to play a sample as an instrument, one note at a time.

public static Sound Sample(AudioBuffer buffer, Param frequency, double rootFrequency, PlaybackMode mode = PlaybackMode.OneShot, double loopStart = 0, double? loopEnd = null)

Parameters

buffer AudioBuffer

The audio to play, usually from Sigil.Sound.AudioBuffer.FromWav(System.String).

frequency Param

The pitch to play, in Hz: a number, or a sound such as a voice's v.Frequency.

rootFrequency double

The pitch the sample was recorded at, in Hz; for example 261.63 for a sample recorded at middle C.

mode PlaybackMode

How the sample plays: once, looped, or ping-ponged. Defaults to Sigil.Sound.PlaybackMode.OneShot.

loopStart double

Where the loop begins, in seconds from the start of the sample. Defaults to 0.

loopEnd double?

Where the loop ends, in seconds from the start of the sample. Defaults to null, the end of the sample.

Returns

Sound

Examples

// Plays the pluck at the pitch of each note; the pluck was recorded at 261.63 Hz (C4).
Notes.Parse("C4 E4 G4 C5").Every(Beats.Quarter).Loop()
    .Play(v => Sample(Samples.Load("pluck.wav"), v.Frequency, 261.63), bpm: 120) * 0.5

Remarks

This is Sample(buffer, speed: frequency / rootFrequency), written out for the common case. The root frequency is required so that a call with a single number cannot be mistaken for a speed.

Exceptions

ArgumentOutOfRangeException

rootFrequency is not positive, or the loop markers are invalid.

Saw(Param?)

An anti-aliased (PolyBLEP) sawtooth wave. frequency is in Hz.

public static Sound Saw(Param? frequency = null)

Parameters

frequency Param?

Pitch in Hz: a number, or a sound or Fn(t => ...) to modulate it. Defaults to 440 (A4).

Returns

Sound

Examples

Saw(110).LowPass(800)

Sine(Param?)

A sine wave. frequency is in Hz.

public static Sound Sine(Param? frequency = null)

Parameters

frequency Param?

Pitch in Hz: a number, or a sound or Fn(t => ...) for vibrato and sweeps. Also used as an LFO below 20 Hz. Defaults to 440 (A4).

Returns

Sound

Examples

Sine(440)

Square(Param?, Param?)

An anti-aliased (PolyBLEP) pulse wave. width is the duty cycle in (0, 1); 0.5 is a square.

public static Sound Square(Param? frequency = null, Param? width = null)

Parameters

frequency Param?

Pitch in Hz: a number, or a sound or Fn(t => ...) to modulate it. Defaults to 440 (A4).

width Param?

Fraction of each cycle spent high, from 0.01 to 0.99. Modulate it for pulse-width movement. Defaults to 0.5.

Returns

Sound

Examples

Square(110, Sine(0.3).Range(0.1, 0.9))

Triangle(Param?, Param?)

A band-limited triangle wave: a straight ramp up and a straight ramp down, from -1 to 1. Its corners are rounded so high pitches stay clean. Use it as a source, or at low rates as a bipolar modulator for Range.

public static Sound Triangle(Param? frequency = null, Param? skew = null)

Parameters

frequency Param?

Pitch in Hz: a number, or a sound or Fn(t => ...) to modulate it. Defaults to 440 (A4).

skew Param?

Where the peak falls in the cycle, from 0 to 1. 0.5 is symmetric. Defaults to 0.5.

Returns

Sound

Examples

Triangle(220, skew: 0.5) * 0.3
Sine(440) * Triangle(4, skew: 0.8).Range(0.9, 1.0)   // a tremolo that ramps up and snaps back

Remarks

Skew sets where the peak falls in each cycle. Skew 0.5 is symmetric, and a skew of 0.8 gives a slow rise and a quick fall. Skew 0 and 1 are limited to 0.01 and 0.99. A true saw needs a jump, and a triangle has none, so the extreme skews are a very steep ramp rather than a saw.

Exceptions

ArgumentOutOfRangeException

The constant skew is outside 0 to 1.