This post brought to you as part of fulfilling the requirements for Massey University’s 143.363.
The brief was to write both an additive and subtractive synthesizer, in addition to an effects processor. I generalized this a little bit so that you can combine random parts together, so the additive/subtractive synthesizers aren’t really separate any more.
Basically my code allows you to write ‘scores’ like this:
square wave:square:
glassharp:adsr:square wave,0.1,0.2,0.6,0.6
glassharpDelay:delay:glassharp,0.4
glassharpDelayed:gain:glassharpDelay,0.5
instrument:add:glassharp,glassharpDelayed
!instrument c e8 g c4 e8 g c’4 e’ g’ c e8 g c4 e8 g c’4 e’ g’
The first 5 lines are ‘instrument lines’ and the last one is a ‘score line’.
Instrument lines
The instrument lines are somewhat SSA-like in that you can only do one thing on one line. Each line has the structure [instrument name]:[source or filter]:[parameters]. The provided sources include sine, square, sawtooth, triangle, and additive (this latter has parameters which are the coefficients for additive synthesis).
An example of using additive synthesis (here used to approximate a square wave more and more closely):
sq1:additive:1
sq2:additive:1,0,0.333
sq3:additive:1,0,0.333,0,0.2
sq4:additive:1,0,0.333,0,0.2,0,0.14285714
!sq1 c d e f g r !sq2 c d e f g r !sq3 c d e f g r !sq4 c d e f g r
Filters include (parameters in brackets): delay (source instrument, seconds), gain (source instrument, amount), adsr (source instrument, attack time, decay time, sustain gain, release time), lowpass (instrument, frequency, order), highpass (instrument, frequency, order), add (instrument, instrument), subtract (instrument, instrument).
Score lines
Score lines specify the notes for the instruments to play. Notes are specified like this: [note name][optional sharp or flat][optional octave shift][optional length]. For example, to specify a C-major arpeggio using crotchets, over two octaves, you would use:
c4 e g c' e' g'
The note length ‘sticks’ for all following notes in the same line, and defaults to 4 (a crotchet) at the start of each line. Note length is specified as
, so c8 is half as long as c4.
Octave shift is indicated using commas or apostrophes:
c,,, c,, c, c c' c'' c'''
Sharps and flats are indicated using ‘s’ and ‘b’, respectively:
c cs d ds e f gb g ab a as b c'
To change instrument in the middle of the score line, use the syntax ‘!instrument_name’. (This operation takes no time in the score.)
Multiple score lines will be played simultaneously. An example:
g2 a g g
e2 f f e
c2 c b, c
Rests are specified using the ‘note name’ ‘r’.
Caveats
- The code isn’t written for widespread consumption (it is very get-the-job-done).
- It is possible to send the program into an infinite loop using a filter that refers to itself. (e.g.
infinite:delay:infinite,0.5) - Currently you cannot control filter parameters via the score lines; this means you cannot (e.g.) create sound from white noise using a series of filters, as you cannot change the pitch.
- Wavetables aren’t implemented, but should be easy to add.
- The tempo is currently fixed at 120 BPM.
- Gain for the whole audio file will be reduced automatically to prevent clipping.
- The file format itself is not very forgiving. It is best to stick closely to the examples shown above! (In particular, white space at the end of a score line will break things with obscure messages.)
Code & example
You can listen to an example rendered by my code here. The code can be downloaded (including the score for that example) here.
Comments on implementation
The various files with ‘handle’ in their name are there to support Matlab’s form of closures (this is what I got from the documentation); if you don’t do it this way then all the references to ‘synth_options{n}’ end up being to the wrong options as Matlab’s anonymous functions are in some ways call-by-name.
The file ‘lookup’ is used instead of interfacing directly to java.util.Hashtable because you can’t (AFAIK) marshal function_handles across to Java and back.
Comments 2
This is a pretty cool implementation George. I like how everyone’s done it quite differently.
Yours has a more robust music system than mine – mine’s based on semiquaver time divisions (though you can specify longer notes of course) and MIDI note numbers.
My code’s pretty ridiculous too: http://www.momentstudio.co.nz/other/MATLABSynth.zip
I did wavetable instead of additive and it sounds rather horrible, because the repeats are so obvious. My laptop also adds loud clicks between notes – I should have recorded the outputs at uni, where it sounds fine. http://www.momentstudio.co.nz/other/synthOutput.mp3
Posted 25 Oct 2008 at 1:14 pm ¶Hi,
Posted 15 Mar 2009 at 2:25 am ¶I am doing project of music analysis and synthesis.
I recorded the music and analysed it using Fourier Transform and calculated power spectrum and frequency spectrum using MATLAB.
I have to regenerate the music using MATLAB. I have calculated fundamental frequencies,multiples and their amplitude but i couldnt regenerate it clearly.
Could you help me?
Thanks in advance.
Post a Comment