Syntax Reference - Quefumas/gensound GitHub Wiki
Here we cover core syntactical features that are not specific to any Signal or Transform.
Time Durations
Whenever time is involved, use float
to represent milliseconds, and int
to represent number of samples.
The following examples are very different:
Sine(frequency=440, duration=100) # first 100 samples of a 440Hz Sine wave - actual duration depends on sample rate
Sine(frequency=440, duration=100.0) # a 440Hz Sine wave lasting 0.1 seconds, regardless of sample rate
A convenient convention for specifying milliseconds is using Python's scientific notation, which always results in a float
, and thus can't be misinterpreted as a number of samples.
For example: 1e3
means 1*10**3 = 1000.0
, which Gensound interprets as one second (=1000 milliseconds). Similarly 5e3
is 5 seconds, and 0.5e3
half a second.
Operations
All of the following expressions return a new Signal object:
Signal + Signal
: mix two Signals togetherSignal + number
: adds DC to Signal (if you don't know what this means, you don't need it)-Signal
: phase inversionSignal | Signal
: concatenate two Signals (play one after the other)Signal | number
: concatenates silence (measured in samples or ms, depends on type ofnumber
)Signal**int
: repeat the Signalint
times (TODO: implement floats as well?)Signal*Transform
: applyTransform
toSignal
float*Signal
: change Signal's amplitude (loudness) by a given factorfloat
(private case ofTransform
application)Transform*Transform
: chaining Transforms so that they can be later applied to a Signal together- (Rare)
Signal | BiTransform | Signal
: this is for a specialized kind of Transform, that operates on two Signals. So far this is only used for Cross-Fades (TODO cover somewhere)
Slicing Channels and Time
Gensound uses syntax similar to the indexing system in NumPy.
For a given Signal we may choose a certain set of channels, and a certain time span.
Since time durations and time positions are interpreted differently according to whether they are int
or float
, some care needs to be taken.
Signal[start_channel:end_channel,start_ms:end_ms]
:Signal
sliced to a certain range of channels and time (in ms). The first slice expects integers; the second expects floats.Signal[start_channel:end_channel,start_sample:end_sample]
: When the second slice finds integers instead of floats, it is interpreted as a range over samples instead of milliseconds. Note that the duration of this Signal changes according to the sample rate.Signal[start_channel:end_channel]
: when a single slice of ints is given, it is taken to mean the channels.Signal[start_ms:end_ms]
: if the slice is made up of floats, it is interpreted as timestamps, i.e.:Signal[:,start_ms:end_ms]
.
In short, when indexing with floats, Gensound knows we are talking about time positions. When indexing with ints, we may mean either the channels or sample numbers (or both); sample numbers will always be preceded by the channels, as otherwise Gensound has no way to tell.