NAME

Peta::Synth - a software synthesizer in Perl

VERSION

version 0.2610180

SYNOPSIS

use Peta::Synth;

my $done = Peta::Synth->render_file('song.mid', 'song.flac',
    rate => 48000, partials => 64, engine => 'auto', workers => 2);
printf "%.1f s of sound in %.1f s\n", $done->{seconds}, $done->{took};

DESCRIPTION

Plays MIDI with instruments that are synthesized, not sampled: each voice sine partials, a plucked or struck string, FM operators and bands of noise under envelopes, a filter that moves and routes of modulation (see Peta::Synth::Voice), the 128 General MIDI programs and the drum kit described as such (Peta::Synth::Patch), a reverb and equalizers. It runs on perl5 and on pperl, where the JIT compiles its loops; PDL and a graphics card (pperl's WebGPU) are used where they are there.

The parts are listed at the top of the source; what they can do is told in the distribution's doc/ (midi.md, synthesis.md, rendering.md, backends.md). For a synthesizer of one's own to play into, see Peta::Synth::Synth.

METHODS

play_file

Peta::Synth->play_file('song.mid', latency => 0.15, stop => sub { $stop });

Plays a MIDI file on the sound server (PulseAudio, or PipeWire through its pipewire-pulse) as it renders: Peta::Synth::Output::Pulse. Options as for render_file (rate, partials, engine, bank, length, tail), and output (pipewire: libpipewire through pperl's Peta::FFI, Peta::Synth::Output::PipeWire; pulse: the PulseAudio protocol, which PipeWire also serves, Peta::Synth::Output::Pulse; auto: PipeWire where it can be), latency (seconds the server holds ahead, 0.15), auto (fewer partials for new notes when the machine cannot keep up, 1), stop (a sub that says when to stop at once), progress (called with the seconds played, the seconds in all and the synthesizer). The sound is not normalized; the limiter keeps it from clipping. Returns seconds, notes, peak_voices, engine, partials (at the end), output and stopped.

play_live

Peta::Synth->play_live(in => 'all', latency => 0.03, stop => sub { $stop });

Plays MIDI as it comes in (Peta::Synth::Input) on the sound server, until stop says so. in: all (every source of the ALSA sequencer, and those plugged in later), none (a port for others to connect), sources by address or name joined by commas, or the path of a raw MIDI device or pipe. quantum: the samples rendered at a time, a multiple of 64 (256); each quantum's MIDI is applied before it is rendered. rate, partials, engine, bank, latency (0.03), auto as for play_file; output as there, or an object that writes (write, stop); progress is called with the synthesizer and the input after each quantum. Returns seconds, notes, engine, partials, output and input (the port's address).

profile_file

Peta::Synth->profile_file($in, rate => ..., partials => ..., bank => ..., length => ..., tail => ...): what rendering a MIDI file will cost, before it is rendered: its Peta::Synth::Profile.

player

Peta::Synth::player($output, rate => ..., latency => ..., title => ...): the writer play_file plays through.

render_file

render_file($midi, $out, %opt): renders a MIDI file (a name or a Peta::Synth::MIDI) into $out, in the format its extension names (see Peta::Synth::Output). Options:

rate

The sample rate (48000).

partials

The most partials a voice has (48): the main measure of quality, and of the time a render takes.

fidelity

low, mid or high (high): what may be left out that is hardly heard, as Peta::Synth::Synth has it (voices end sooner as they fade, fewer sound at once). high renders sample for sample as ever; play_file and play_live take mid by default.

engine

perl, pdl, gpu or auto (Peta::Synth::Engine).

workers

The number of processes the notes are shared among (1). The reverb is linear, so each process runs its own and the parts are summed.

bits

16 (dithered), 24, or 32 (float, WAV only).

normalize

The peak, in dBFS, the result is scaled to (-1); undef leaves it as rendered.

tail

The most seconds rendered after the last event (30); rendering stops as soon as everything is silent.

bank

Changes to the instruments, as "edits" in Peta::Synth::Synth gives them (the web page saves them as a JSON file).

length

Only the first seconds of the file; notes still held there are let go.

quality

The encoder's quality: the compression level for FLAC (0-8, 5); for MP3 kbit/s (192, at 16-24 kHz 96) or V0 .. V9 (a variable bitrate, as LAME's -V); the Vorbis quality for Ogg (0-10, 6); kbit/s for Opus (160).

ffmpeg_gapless

An MP3's Info tag names the encoder LavfPeta, so that FFmpeg plays it gapless ("THE ENCODER'S NAME" in Peta::MP3::Encode).

progress

A sub called with the seconds rendered and the length of the file.

Returns a hash: seconds of sound, took (seconds), notes, peak_voices, engine, workers, peak, file.

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.