Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/amari-calipso/synthscript

A basic software synthetizer programmable in Python and a dedicated language
https://github.com/amari-calipso/synthscript

audio audio-processing domain-specific-language dsl language-design language-engineering midi midi-files music python python3 sf2 sound sound-processing soundfont soundfont2 synthesizer

Last synced: about 1 month ago
JSON representation

A basic software synthetizer programmable in Python and a dedicated language

Awesome Lists containing this project

README

        

# SynthScript
A basic software synthetizer programmable in Python and a dedicated language.

To run, open or compile `SynthScript.opal`, and pass it a file to run as a command line argument.
# Command line arguments
- `--compile`
- Tells the program that the given file is written in SynthScript and needs to be compiled.
- **Usage**: --compile
- `--export-tracks`
- Generates a .wav file for each playback channel.
- **Usage**: --export-tracks
- `--realtime`
- Skips the rendering process and plays the source code directly. This option will produce a lower quality sound and more inaccuracies in playback.
- **Usage**: --realtime
- `--cupy`
- Uses the GPU to perform NumPy operations. Results in a significant performance improvement. Requires the `cupy` module installed.
- **Usage**: --cupy
# Synthetizer tools
## `Instrument`
An `Instrument` is a way to combine waveforms and `Process`es.
### Arguments
```
Instrument(**instruments, postProcess, preProcess, static)
```
- `**instruments`: a list of keyword arguments used to refer to other `Instrument`s or waveforms.
- `postProcess`: (Optional) used to refer to a `Process` object for post processing;
- `preProcess`: (Optional) used to refer to a `Process` object for pre processing;
- `static`: If set to `True`, the `Instrument` will not react to variable changes. Useful for performance reasons. `False` by default.
## `Process`
A `Process` is a way to combine effects.
### Arguments
```
Process(**effects, static)
```
- `**effects`: a list of keyword arguments used to refer to other `Process` objects or effects.
- `static`
## `Midi`
A `Midi` is a way to include and play midi files.
### Arguments
```
Midi(file, instruments)
```
- `file`: the midi file.
- `instruments`: a list of instruments mapped to midi channels. If not set, square waves will be used for every channel.
## `SoundFont`
A `SoundFont` is a way to include and use `.sf2` files.
### Arguments
```
SoundFont(file)
```
- `file`: the `.sf2` file.
This class contains a `getInstrument` method that will find an instrument given its name.
## `SoundFontInstrument`
A `SoundFontInstrument` lets you use a specific instrument from a `SoundFont`
### Arguments
```
SoundFontInstrument(soundFont, preset, bank)
```
- `soundFont`: the `SoundFont` you want to get the instruments from.
- `preset` and `bank` let you pick a specific instrument. Both arguments are optional.

It's not recommended to mix `SoundFontInstrument`s and waveforms in the same track when using midi files due to approximation errors.
## Waveforms
Waveforms all take two basic arguments when generated:
```
Wave(amplitude, static)
```
- `amplitude`: the waveform's amplitude;
- `static`

Available waveforms are:
- `Square(amplitude, duty, static)`
- `duty`: the square wave's duty cycle. Can be either a float or another waveform or `Instrument`. Default is 0.5.
- `Sawtooth(amplitude, width, static)`
- `width`: width of the rising ramp as a proportion of the total cycle of the sawtooth wave.
- `Noise(amplitude, static)`
## Effects
### Post processing effects
- `Envelope(attack, decay, sustain, release, static)`
- `attack`: sets the time it takes for the signal to rise from an amplitude of 0 to full amplitude. Default is 0.
- `decay`: sets the time it takes for the signal to fall from full amplitude to the sustain level.
- `sustain`: sets the amplitude of the wave for the time the key is held.
- `release`: sets the time it takes for the sound to decay from the sustain level to an amplitude of 0 when the key is released.
### Pre processing effects
- `Vibrato(osc, amount, static)`
- `osc`: sets the rate at which the frequency oscillates. Default is 0.25.
- `amount`: sets the amount of variation of frequency. Default is 1.
- `FreqSweep(toFreq, time)`
- `toFreq`: the destination frequency.
- `time`: the amount of time in which the wave's frequency should reach the destination frequency.
# The language and the Python API
NOTE: The compiler will ignore any tabs or newlines. Spaces however make a difference in syntax, unless they're inside brackets.
## Statements
Statements are not case sensitive.
### `CREATE AS `
- The `CREATE` statement is used to create instances of any class.
- Optionally, a `WITH` clause can be added to pass arguments to the class constructor. Example:
```
CREATE Instrument AS myInstrument WITH (
mySquare = Square(),
myNoise = Noise()
)
```
- The Python equivalent of the snippet above would be:
```
myInstrument = Instrument(
mySquare = Square(),
myNoise = Noise()
)
```
### `SET OF TO `
- Assigns values to variables or properties of objects.
- Example:
```
SET duty OF myInstrument.mySquare TO 0.3
```
- The Python equivalent of the snippet above would be:
```
myInstrument.mySquare.duty = 0.3
```
### `NOTE CHANNEL `
- Plays or stops frequencies on a given channel id.
- The frequency can be:
- A number, in which case it will be interpreted as a value in Hertz;
- A note (example: `NOTE c4 CHANNEL 1 ON`). Notes are not case sensitive.
- The channel id can be anywhere in the range 0-15;
- The status can assume any value that is considered `True`, including language specific values such as ON and OFF (case insensitive).
- An optional `USING` clause can be added, to specify which instrument to use. If not specified, the synthetizer will use the default instrument. Example:
```
NOTE C4 CHANNEL 3 ON USING myInstrument
```
- Optionally, a `WITH` clause can be added to pass arguments to the `note` method:
- `velocity`: relative volume of the note. Can be anywhere in the range 0-512. Default is 512.
- `delay`: amount of time (in seconds) to wait after the note started playing. Default is 0.
- Example:
```
NOTE C4 CHANNEL 2 ON USING myInstrument WITH (
velocity = 128,
delay = 1.5
)

NOTE C4 CHANNEL 2 OFF
```
- You can use SynthScript's Python API to do the same operation. The `note` method is composed like this:
```
synth.note(
frequency, channel, status,
, ,
)
```
Arguments in angular brackets are optional.
### `PITCHBEND CHANNEL BY `
- Varies the pitch of all notes in a given channel.
- The channel id can be anywhere in the range 0-15;
- The amount can be anywhere in the range -8192 to 8192;
- Optionally, a `WITH` clause can be added to pass arguments to the `pitchBend` method:
- `delay`: amount of time (in seconds) to wait after the pitch bending has been applied. Default is 0.
- Example:
```
PITCHBEND CHANNEL 2 BY -123 WITH (
delay = 0.25
)
PITCHBEND CHANNEL 2 BY -292
```
- You can use SynthScript's Python API to do the same operation. The `pitchBend` method is composed like this:
```
synth.pitchBend(amount, channel, )
```
Arguments in angular brackets are optional.
### `WAIT