PySynth
Fork me on GitHub

Downloads | Changes | Modules | Usage | License | Contact

PySynth is a simple music synthesizer written in Python. It’s based on a 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 into a WAV file without too much tinkering.

There are three variants: PySynth A is faster, only needs Python itself, and sounds more like a cross between a flute and organ. PySynth B is more complex in sound and needs NumPy. It's supposed to be a little closer to a piano. (No competition for Pianoteq of course, but a reasonable fit for keyboard music.) Finally, PySynth S is more comparable to a guitar, banjo, or harpsichord, depending on note length and pitch.

The current release of the synthesizer is monophonic, i.e. it can only play one note at a time. (Although successive notes can overlap in PySynth B and S, but not A.) However, two 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.

Examples

Here are some sample output files converted to MP4 format:

Downloads

Current tar.gz archive of all PySynth modules:

PySynth-1.0.1.tar.gz (2012-08-01)

You can also browse the current repository at GitHub and obtain the source code by using the git command git clone git://github.com/mdoege/PySynth.git

Individual modules can also be downloaded separately below.

Pranav Ravichandran currently has a fork at GitHub where he is implementing some cool new features.

Changes

V1.0.1 fixes a minor issue with Pyglet sound playback and corrects the import path for PyAudio. Thanks again, Pranav!

V1.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!

V0.9 introduced a Nokia ringtone synthesizer module, contributed by Pēteris Caune. (Run nokiacomposer2wav.py to generate some audio samples. He also provides an online version.) Thanks, Pete!

V0.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

Synthesizer modules

(These modules take a list of notes and note lengths and use it to create a WAV file.)

PySynth “A”

This synth is very simple and sounds vaguely like a flute or organ. Only Python v2.x (not 3.x!) itself is needed for PySynth A. It should run on all Python-supported platforms, like Windows, Unix, and the Mac.

PySynth “B”

This module 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 “S”

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.

Note that PySynth B and S require NumPy in addition to Python itself, but binary installation packages are available for Windows / Linux / OS X, so this should not be a problem.

PySynth beeper

This belongs to nokiacomposer2wav.py.

Controller scripts

(These scripts serve as more convenient ways to drive the actual synthesizers.)

ABC parser

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):

% python read_abc.py http://trillian.mit.edu/~jc/music/abc/Germany/LiliMarlen.abc

Lili Marleen.mp4

Detailed usage:

read_abc.py filename [num_song] [--syn_b/--syn_s]

* num_song selects the song in the file corresponding to the number given
* --syn_b and --syn_s can be added to use the PySynth B or PySynth S
    modules, respectively, 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.

Interactive command line environment

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.

Nokia ringtone synthesizer

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.


Usage

The script can be used as a module by other Python programs or the interactive Python shell:

% python
ActivePython 2.5.0.0 (ActiveState Software Inc.) based on
Python 2.5 (r25:51908, Mar  9 2007, 17:40:37) 
[GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 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:

python read_abc.py straw.abc

gives you this file.


License

This software is provided under the GPL.

Contact

Email: Martin C. Doege


Sample program output

% time python 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