Downloads | Changes | Synthesizer modules | Support scripts | Usage | License | Contact
PySynth is a suite of simple music synthesizers and helper scripts written in Python 3. It is based on a synth script I found on the Web and then modified for my purposes. The goal is not to produce many different sounds, but to have scripts that can turn ABC notation or MIDI files into a WAV file without too much tinkering.
There are nine PySynth variants now: PySynth A, the oldest variant, only needs Python itself, and sounds somewhat like a cross between a flute and organ. PySynth B is more complex in sound and needs NumPy. It is supposed to be a little closer to a piano. No competition for Pianoteq of course, but a reasonable fit for keyboard music. PySynth E is similar, but an FM-synthesized e-piano so it sounds much brighter than B (slightly DX7 e-piano-like; I used the DX7 presets in hexter as a basis). PySynth S is more comparable to a guitar, banjo, or harpsichord, depending on note length and pitch. PySynth C, D, and P are subtractive synths, reminiscent of 1970s analog synthesizer voices.
The synthesizers are all monophonic, i.e. they can only play one note at a time. (Although successive notes can overlap in PySynth B and S, but not A.) However, two or more output files can be mixed together as in the case of the stereo files below.
If you need more powerful Python sound synthesis than PySynth offers, you might want to check out the Pyo toolkit. To convert complex ABC files to MIDI you might want to try abcmidi. Some good Open Source synthesizers are Yoshimi, amsynth, Surge, and Dexed.
Here are some WAV output files converted to MP3 or MP4 format:
Here are tar.gz archives of all PySynth modules:
PySynth-2.4.tar.gz (2020-01-28; for Python 2 or 3) |
|
PySynth-1.1.tar.gz (2015-01-03; final version for Python 2) |
You can browse the repository at GitHub or obtain the source code with git like this:
git clone git://github.com/mdoege/PySynth.git
ZIP file of the latest git version of PySynth
V2.4 restores Python 2 compatibility.
V2.3 fixes a timing bug in the MIDI file reader.
V2.2 adds a sample-based synth, PySynth “samp”, based on the Salamander piano samples.
V2.1 adds three subtractive synths: “C” (sawtooth wave), “D” (square wave), and “P” (white noise). Also, readmidi.py was improved to better deal with overlapping notes and notes that are switched off by setting their velocity to zero. MIDI rendering seems to work quite well now, as evidenced by the new Popcorn demo song.
V2.0 switches to Python 3, adds the MIDI reader readmidi.py, and incorporates several pull requests with bug fixes and improvements.
2015V1.1 adds the “E” FM synth module and mixfiles.py.
V1.0.1 fixes a minor issue with Pyglet sound playback and corrects the import path for PyAudio. Thanks again, Pranav!
2012V1.0 added interactive song creation and playback via menv.py. This CLI allows you to enter notes and hear them played back as synthesized by PySynth. Thanks, Pranav!
2011V0.9 introduced a Nokia ringtone synthesizer module, contributed by Pēteris Caune. (Run nokiacomposer2wav.py to generate some audio samples.) Thanks, Pete!
2009V0.8: Improved support for ABC notation features such as tuplets and song tempo; better performance and sound of PySynth “S”.
V0.7: Added the ABC parser and the “B” and “S” synths.
V0.6: Initial public release
These modules take a list of notes and note lengths and use it to create a WAV file. The B, E, and S synths also require NumPy.
This additive monophonic synth is very simple and sounds vaguely like a flute or organ, combined with piano-like note volume decay. Only Python itself is needed for PySynth A. It should run on all Python-supported platforms, like Windows, Unix, and the Mac.
An additive synth module which attempts to create a more piano-like sound with more harmonics. This version is polyphonic in the sense that it doesn’t cut off previous notes when the next note sounds.
PySynth C is a simple bowed string sound based on subtractive synthesis. It uses a sawtooth oscillator and a low-pass filter, similar to a 1970s analog synth (or a string sound in amsynth, or a sound from a MOS Technology SID). Like PySynth A, it only requires Python itself to run.
PySynth D uses subtractive synthesis like PySynth C, but is based on a square wave instead. This synth lead-type sound is reminiscent of a woodwind. Square waves were also used in 1970s/1980s computer sound chips such as the General Instrument AY-3-8910 or the Atari POKEY. Only Python itself is required.
Based on PySynth B, this module creates a simple e-piano sound based on phase modulation, the usual method of doing FM synthesis e.g. on 1980s Yamaha synthesizers. This sound is of course inspired by the Rhodes piano on a Yamaha DX7.
PySynth P uses subtractive synthesis like PySynth C and D, but is based on white noise with an exponential volume envelope. It creates an untuned percussion sound. This type of sound was commonly used in the 1980s for percussive and game sound effects. Only Python itself is required.
This module simulates a single plucked string with the Karplus-Strong algorithm (think guitar or harpsichord). Due to the nature of this kind of synthesis, higher frequency-notes in particular can be slightly out of tune with PySynth S, as opposed to the other variants where the harmonics are exact. This could be remedied with a higher sampling rate, but that would also make it a little slow for Python.
This contributed synth belongs to nokiacomposer2wav.py and is supposed to recreate ringtones of vintage Nokia feature phones.
This synth uses the 48 kHz, 24-bit Salamander piano samples. Please set the path to the Salamander WAVs (including the trailing slash) on line 50.
These scripts serve as more convenient ways to drive the actual synthesizers.
PySynth has some basic support for music in the ABC notation language. The script needs the location of the ABC song file (either local or via http), optionally followed by the song number (defaults to 1):
python3 read_abc.py http://mdoege.github.io/PySynth/LiliMarlen.abc.txt
Detailed usage:
read_abc.py filename [num_song] [--syn_b/--syn_c/--syn_d/--syn_e/--syn_p/--syn_s/--syn_samp] * num_song selects the song in the file corresponding to the number given * --syn_b, --syn_e, --syn_s, etc. can be added to use other PySynth modules instead of the default PySynth A
If you need a quick way to edit, visualize, and—in supported browsers—play an ABC music file, take a look at ABCPig.
Synthesize one track from a MIDI file with PySynth (defaults to MIDI track 1):
python3 readmidi.py file.mid [tracknum] [file.wav] [--syn_b/--syn_c/--syn_d/--syn_e/--syn_p/--syn_s/--syn_samp]
mixfiles.py mixes two mono audio files to create a stereo file, e.g.: python3 mixfiles.py right.wav left.wav both.wav
Please note that mixfiles.py inputs and outputs 44.1 kHz WAV files, so do not use this with Pysynth “samp” output (which is 48 kHz) or you will get wrong results.
This feature, contributed by Pranav Ravichandran, is used by running menv.py. It is really self-explaining, you enter your desired notes and any optional parameters like bpm on the command line and after you hit return PySynth synthesizes the sound and plays it back via the speakers. Depending on the speed of your computer and the length of the sound, there might be a slight pause between your input and sound playback.
PyAudio is recommended for playback functionality, but Pyglet, tkSnack, or a command line audio player of your choice are also supported.
Pēteris Caune has implemented nokiacomposer2wav.py, which as the name suggests takes a Nokia ringtone and synthesizes it using pysynth_beeper.py. nokiacomposer2wav.py also produces some test files when invoked directly.
The script can be used as a module by other Python programs or the interactive Python shell:
% python3 >>> import pysynth >>> test = ( ('c', 4), ('e', 4), ('g', 4), ('c5', 1) ) >>> pysynth.make_wav(test, fn = "test.wav") Writing to file test.wav [1/4] >>>
…which will give you this timeless masterpiece. That’s the C major chord over the middle C followed by the high C. Three quarters, followed by a whole note (which PySynth assumes to equal 4 quarters).
First comes the note name (a to g), then optionally a '#' or 'b' for sharp or flat, then optionally the octave (defaults to 4). An asterisk at the end means to play the note a little louder.
The note duration comes next, with dotted notes represented by negative numbers (e.g. -2 is a dotted half note). 'r' is a rest. So e.g. “The Blue Danube” starts with:
song = ( ('c', 4), ('c*', 4), ('e', 4), ('g', 4), ('g*', 2), ('g5', 4), ('g5*', 4), ('r', 4), ('e5', 4), ('e5*', 4) ) >>> from pysynth_b import * *** EXPERIMENTAL PIANO VERSION WITH NOTE CACHING *** >>> make_wav(song, fn = "danube.wav", leg_stac = .7, bpm = 180) ← Beats per minute is really quarters per minute here. [1/10] [5/10] [9/10] Writing to file danube.wav >>>
For more convenient note entry, you can e.g. use the ABC notation importer:
This is an example from the ABC documentation:
X: 1 T: Balance the Straw R: jig N: This tune goes with one of the best-known Morris dances. It is also a good jig N: for other dances, usually in AABB form. The B phrase bears a strong resemblance N: to a certain Christmas carol, and at Morris dances you will hear words like: N: __ Hark! the herald angels sing, __ N: __ Glory to the Morris Ring. __ N: Sometimes assorted other things are praised by the angels. N: M: 6/8 L: 1/8 K: G D \ |: "G"G2B B>AB | "C"c2A A>ce | "D7"d>ed cAc | "G"G2B B2D \ | "G"G2B B>AB | "C"c2A A>ce | "D7"d>ed cEF | "G"G4 z2 :| B/c/ \ |: "G"dz d dz G | "(D7)"c2B "D7"B2A | "G"dz d dz G | "D7"B2A A2D \ | "G"G2B B>AB | "C"c2A A>ce | "D7"d>ed cEF | "G"G4 z2 :|
Creating the audio with:
python3 read_abc.py straw.abc
gives you this file.
This software is provided under the GPL.
% time python3 pysynth.py Piano key frequencies (for equal temperament): Key number Scientific name Frequency (Hz) 1 A0 27.50 2 A#0 29.14 3 B0 30.87 4 C1 32.70 5 C#1 34.65 6 D1 36.71 7 D#1 38.89 8 E1 41.20 9 F1 43.65 10 F#1 46.25 11 G1 49.00 12 G#1 51.91 13 A1 55.00 14 A#1 58.27 15 B1 61.74 16 C2 65.41 17 C#2 69.30 18 D2 73.42 19 D#2 77.78 20 E2 82.41 21 F2 87.31 22 F#2 92.50 23 G2 98.00 24 G#2 103.83 25 A2 110.00 26 A#2 116.54 27 B2 123.47 28 C3 130.81 29 C#3 138.59 30 D3 146.83 31 D#3 155.56 32 E3 164.81 33 F3 174.61 34 F#3 185.00 35 G3 196.00 36 G#3 207.65 37 A3 220.00 38 A#3 233.08 39 B3 246.94 40 C4 261.63 41 C#4 277.18 42 D4 293.66 43 D#4 311.13 44 E4 329.63 45 F4 349.23 46 F#4 369.99 47 G4 392.00 48 G#4 415.30 49 A4 440.00 50 A#4 466.16 51 B4 493.88 52 C5 523.25 53 C#5 554.37 54 D5 587.33 55 D#5 622.25 56 E5 659.26 57 F5 698.46 58 F#5 739.99 59 G5 783.99 60 G#5 830.61 61 A5 880.00 62 A#5 932.33 63 B5 987.77 64 C6 1046.50 65 C#6 1108.73 66 D6 1174.66 67 D#6 1244.51 68 E6 1318.51 69 F6 1396.91 70 F#6 1479.98 71 G6 1567.98 72 G#6 1661.22 73 A6 1760.00 74 A#6 1864.66 75 B6 1975.53 76 C7 2093.00 77 C#7 2217.46 78 D7 2349.32 79 D#7 2489.02 80 E7 2637.02 81 F7 2793.83 82 F#7 2959.96 83 G7 3135.96 84 G#7 3322.44 85 A7 3520.00 86 A#7 3729.31 87 B7 3951.07 88 C8 4186.01 Creating Demo Songs... (this might take about a minute) Writing to file pysynth_scale.wav [1/26] [5/26] [9/26] [13/26] [17/26] [21/26] [25/26] Writing to file pysynth_anthem.wav [1/25] [5/25] [9/25] [13/25] [17/25] [21/25] [25/25] Writing to file pysynth_chopin.wav [1/29] [5/29] [9/29] [13/29] [17/29] [21/29] [25/29] [29/29] Writing to file pysynth_bach_rh.wav [1/52] [5/52] [9/52] [13/52] [17/52] [21/52] [25/52] [29/52] [33/52] [37/52] [41/52] [45/52] [49/52] [1/52] [5/52] [9/52] [13/52] [17/52] [21/52] [25/52] [29/52] [33/52] [37/52] [41/52] [45/52] [49/52] Writing to file pysynth_bach_lh.wav [1/33] [5/33] [9/33] [13/33] [17/33] [21/33] [25/33] [29/33] [33/33] [1/33] [5/33] [9/33] [13/33] [17/33] [21/33] [25/33] [29/33] [33/33] Mixing files, total length 29.54 s... 0 s 5 s 10 s 15 s 20 s 25 s 63.615u 0.498s 1:06.09 96.9% 0+0k 0+45io 0pf+0w