Package: gensound
GensoundThe Python way to audio processing & synthesis.An intuitive, flexible and lightweight library for:Experimenting with audio and signal processingCreating and manipulating soundsElectronic compositionCore features:Platform independentVery intuitive syntaxEasy to create new effects or experiments and combine them with existing featuresGreat for learning about audio and signalsMulti-channel audio for customizable placement of sound sourcesParametrizationAnd more to come!SetupInstall usingpip install gensound.
This will also ensure NumPy is installed.
For smoother playback, it is also recommended to have any one ofsimpleaudio,playsound,PyGameinstalled.
It is also recommended to haveFFMPEGinstalled,
which enables read/export of file formats other than Wave and AIFF.Run the examples below (or some of the example files in the repository).Gensound in less than a minuteAll audio is a mixture of signals (audio streams), to which we can apply transforms (effects).To apply a transform to a signal we use the syntax:Signal * Transform;To mix two signals together we use addition:Signal + Signal;And to concatenate two signals (play one after the other):Signal | Signal.Each of these operations results in a newSignalobject on which we can perform more of these operations.Now, let's run some basic examples!Show Me the CodeLoad a WAV into aSignalobject from a file:fromgensoundimportWAV,test_wavwav=WAV(test_wav)# load sample WAV, included with gensoundPlayback or file export:wav.play()wav.export("test.wav")Play file using different sample rate (results in pitch shift):wav.play(sample_rate=32000)# original sample rate 44.1 kHzPlay only the R channel:wav[1].play()# wav[0] is L channel, wav[1] is RTurn down the volume of L channel:wav[0]*=0.5# amplitude halved; wav[1] amplitude remains the samewav.play()Same thing, but usingdBs:fromgensoundimportGainwav[0]*=Gain(-3)# apply Gain transform to attenuate by 3 dBMix a Stereo signal (L-R channels) to mono (center channel only):wav=0.5*wav[0]+0.5*wav[1]# sums up L and R channels together, halving the amplitudesSwitch L/R channels:wav[0],wav[1]=wav[1],wav[0]Crop 5 seconds from the beginning (5e3is short for5000.0, meaning 5,000 milliseconds or 5 seconds):wav=wav[5e3:]# since 5e3 is float, gensound knows we are not talking about channelsIf we only care about the R channel:wav=wav[1,5e3:]# 5 seconds onwards, R channel onlyWe can decide to slice using sample numbers (ints) instead of absolute time (floats):wav=wav[:,:1000]# grabs first 1000 samples in both channels; samples are in intsRepeat a signal 5 times:wav=wav**5Mix a 440Hz (middle A) sine wave to the L channel, 4 seconds after the beginning:fromgensoundimportSinewav[0,4e3:]+=Sine(frequency=440,duration=2e3)*Gain(-9)Play a tune (see full syntaxhere):s=Sine('D5 C# A F# B G# E# C# F#',duration=0.5e3)s.play()Reverse the R channel:fromgensoundimportReversewav[1]*=Reverse()Haas effect- delaying the L channel by several samples makes the sound appear to be coming from the right:fromgensoundimportShiftwav[0]*=Shift(80)# try changing the number of samples# when listening, pay attention to the direction the audio appears to be coming fromStretch effect - slowing down or speeding up the signal by stretching or shrinking it. This affects pitch as well:fromgensound.effectsimportStretchwav*=Stretch(rate=1.5)# plays the Signal 1.5 times as fastwav*=Stretch(duration=30e3)# alternative syntax: fit the Signal into 30 secondsAdvanced: AutoPan both L/R channels with different frequency and depth:fromgensound.curveimportSineCurves=WAV(test_wav)[10e3:30e3]# pick 20 seconds of audiocurveL=SineCurve(frequency=0.2,depth=50,baseline=-50,duration=20e3)# L channel will move in a Sine pattern between -100 (Hard L) and 0 (C)curveR=SineCurve(frequency=0.12,depth=100,baseline=0,duration=20e3)# R channel will move in a Sine pattern (different frequency) between -100 and 100t=s[0]*Pan(curveL)+s[1]*Pan(curveR)Syntax CheatsheetMeet the two core classes:Signal- a stream of multi-channeled samples, either raw (e.g. loaded from WAV file) or mathematically computable (e.g. a Sawtooth wave). Behaves very much like anumpy.ndarray.Transform- any process that can be applied to a Signal (for example, reverb, filtering, gain, reverse, slicing).By combining Signals in various ways and applying Transforms to them, we can generate anything.Signals are envisioned as mathematical objects, and Gensound relies greatly on overloading of arithmetic operations on them, in conjunction with Transforms.
All of the following expressions return a new Signal object:amplitude*Signal: change Signal's amplitude (loudness) by a given factor (float)-Signal: inverts the SignalSignal + Signal: mix two Signals togetherSignal | Signal: concatenate two Signals one after the otherSignal**4: repeat the Signal 4 timesSignal*Transform: applyTransformtoSignalSignal[start_channel:end_channel,start_ms:end_ms]:Signalsliced 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].The slice notations may also be used for assignments:wav[4e3:4.5e3]=Sine(frequency=1e3,duration=0.5e3)# censor beep on seconds 4-4.5wav[0,6e3:]*=Vibrato(frequency=4,width=0.5)# add vibrato effect to L channel starting from second 6...and to increase the number of channels implicitly:wav=WAV("mono_audio.wav")# mono Signal objectwav[1]=-wav[0]# now a stereo Signal with R being a phase inverted version of LNote the convention that floats represent time as milliseconds, while integers represent number of samples.When performing playback or file export of a Signal,
Gensound resolves the Signal tree recursively, combining the various Signals and applying the transforms.MoreI would love to hear about your experience using Gensound - what worked well, what didn't, what do you think is missing.
Don't hesitate todrop me a line.The gradually evolvingWikiis both a tutorial and a reference,
and will also provide many fun examples to learn and play with.
If you are interested in contributing, check outContribution.