NAME
Peta::Synth::Synth - the synthesizer: channels, voices, engine, reverb
VERSION
version 0.2610180
SYNOPSIS
my $synth = Peta::Synth::Synth->new(rate => 48000, partials => 48);
$synth->play({ type => 'note_on', channel => 0, key => 60, velocity => 100 });
my ($left, $right) = $synth->render(4800); # 0.1 s, packed floats
$synth->schedule(Peta::Synth::MIDI->read('song.mid')->timeline);
while ($synth->busy) {
my ($l, $r) = $synth->render(1024);
...
}
DESCRIPTION
A running synthesizer of sixteen MIDI channels. It takes events now ("play") or at a time ("schedule"), and renders quanta of samples. Notes of channel 10, and of a channel with bank 120 or 127, are drums. What MIDI it understands (controllers, RPN and NRPN, system exclusive, mono mode) is listed with the channel's fields above _channel in the source and in doc/midi.md.
METHODS
new
new(rate => 48000, partials => 48, voices => 256, fidelity => 'high', gain => 0.3, limiter => 1, engine => $engine, reverb => {...}, waves => 1). partials is the most partials a voice has, voices the most voices at once (the quietest ending ones are stolen first). fidelity (low, mid, high) is what may be left out that is hardly heard, for playing on a machine that cannot keep up: a voice that has fallen 60 dB (mid) or 45 dB (low) under its full level fades out in 5 ms and ends, not at 80 dB, and low plays at most 48 voices at once. High leaves nothing out. The engine defaults to the fastest there is (Peta::Synth::Engine). waves: harmonic partials are read from wave sequences (Peta::Synth::Wavetable), made as notes need them and kept; a store of them can be given (made ahead, shared); 0 turns every partial one by one. By default as the engine fares better (its reads_waves: the GPU engine turns partials, the others read tables).
waves
The store of wave sequences (Peta::Synth::Wavetable), or undef.
play
An event (as Peta::Synth::MIDI has them) now.
by_hand, held, let_go, forget_held
by_hand($event): an event played by hand (the page, MIDI played live), now; what it sets is held against the other MIDI (a file's): the instrument (bank select and program change), the mixer's controllers (volume, pan, the sends, portamento time, the sound controllers), the arpeggiator's settings (also as an event: { type => 'arp', channel, name, value }). What is played (notes, the wheels, expression, pedals) is not held. While a setting is held, the file's events for it are kept aside, the last of each, and a reset from the file keeps it; a reset played by hand lets go of everything. held($channel): what the channel holds, by name (program, cc 7, arp mode). let_go($channel, $name): a setting let go (without a name, all the channel's), as the file has it by then. forget_held: nothing held, the settings left as they are.
schedule
schedule(\@events, $offset, $from): events with a time in seconds, from now plus $offset, in any order (those at the same time in the order given). With $from, from that many seconds into them: the events before it but the notes (programs, controllers, bends, system exclusive) are applied at once, in their order, so that the channels are as the file has them there. Before that, reset_channels (below).
render, render_arrays
render($n): the next $n samples (a multiple of 64) as left and right strings of packed floats; render_arrays gives them as array references.
render_frames
render_frames($frames, $quantum = 512): a whole sound, the next $frames samples as array references, rendered in quanta of $quantum (the rest of the last one is dropped).
foresee
What the scheduled events will sound, without sounding them: every voice they start, with the second it starts, the second it will be silent (inf: never) and its channel's program (undef on the drums); the queue is used up. For planning: Peta::Synth::Profile.
pending, active
Events still scheduled, and voices sounding.
busy
Whether anything is left to render: events, voices, or the reverb's tail.
stop, panic, reset, reset_channels
stop: drop what is scheduled and release every voice. panic: the same, and silence within milliseconds. reset: every channel to its defaults, every voice gone at once, nothing held. reset_channels: every channel and the master to their defaults as a MIDI reset sets them, the voices that sound let go (as their channels then have them); the mutes stay, and what is held by hand (see by_hand).
channel
channel($number): the state of a channel, 0 .. 15 (a hash; its mute may be set).
program_patch, drum_patch, restore_patch
program_patch($program, $bank), drum_patch($key, $kit): the synth's own patch of a program (or of its variation, by GS bank) or of a drum key (in a kit; a key the kit does not have as its own is the standard kit's); its fields can be changed while the synth runs. restore_patch('program' or 'drum', $n, $bank) goes back to the default.
A program change picks the variation of the bank selected before it ("variation" in Peta::Synth::Patch), and on a drum channel the kit ("kit" in Peta::Synth::Patch); the channel keeps them as variation and kit.
edits, apply_edits
edits: what has been changed from the default patches, as a bank ({ programs => { 0 => { cutoff => 3000 }, '8:4' => {...} }, drums => { 38 => {...}, '40:38' => {...} } }: a variation or a kit's own key as bank:number), which apply_edits($bank) applies to a synth.
set
set($name, $value): partials, voices, fidelity, gain or limiter.
account, load, adapt
For playing as it renders: account($seconds, $samples) after each render, what it took; load the smoothed share of real time the rendering takes; adapt($most) gives new notes fewer partials when the load is high, more (up to $most) when it is low.
arpeggiator, set_arpeggiator
arpeggiator($channel): a channel's arpeggiator (Peta::Synth::Arpeggiator). While it is on, the channel's keys go to it and it plays them, its notes queued a quantum ahead (its first at once). set_arpeggiator($channel, on => 1, mode => 'updown', ...) changes its own settings (the page's, a bank's); turned off, what it plays is let go. What MIDI sets (a file's NRPN, CC 80 and 81, tempo) lasts until a reset or a file played from a point (reset_channels): then it is its own settings again. The own settings are saved with the bank.
channel_eq, set_channel_eq
channel_eq($channel): a channel's equalizer (Peta::Synth::EQ, its response used as gains on the partials of the channel's voices). set_channel_eq($channel, band => { freq, gain, q }, ...) changes it, for the voices that sound too. Saved with the bank; a reset leaves it.
rate, now, engine, reverb, eq, stats
The sample rate, the sample the next quantum starts at, the engine, the reverb, the master equalizer (Peta::Synth::EQ), and counts of what has been rendered.
AUTHOR
PetaMem s.r.o. <info@petamem.com>
COPYRIGHT
Copyright (c) 2026 PetaMem s.r.o.
LICENSE
This package is free software, dual-licensed under the Artistic License 2.0 and the BSD 2-Clause License. See the LICENSE file of the distribution.