abcsound: an abc Front End for CSound


abcsound Tutorial

Maybe it will Just Work...

If all you want to do is use Csound to play an abc score, then simply running abcsound.py should spit out a playable Csound .csd file:

python abcsound.py someSong.abc > someSong.csd

The resulting score will have a tempo of 100 (unless overridden by an Q: statement in the abc score), and will use a simple plucked-string instrument to render the score.

A little more involved...

If you don't like the defaults, you can use your own orchestra and customize how it gets rendered by Csound. You need to have a basic understanding of Csound, so you may want to go read The Csound Book and/or check out the Csound reference manual.

Start with a .csd file containing the orchestra you want to use in the <CsInstruments> section. In the <CsScore> section, write all the GEN statements that you'll need to use, but don't write any i-statements; abcscore.py will add those.

You also need to add some code to the beginning of the abc score file to tell abcscore.py how to generate the i-statements in the resulting Csound score. These statements will tell abcsound.py what voice name to associate with each Csound instrument, and what the p-field values for those instruments should be in the generated score. For example, given the following initial .csd file:



<CsoundSynthesizer>

<CsOptions>
</CsOptions>

<CsInstruments>

sr 		= 		44100
kr 		= 		4410
ksmps 	= 		10
nchnls 	= 		1

		instr   1
; A  Karplus-Strong plucked string
a1 		pluck 	2000, p4, p5, 2, 1
		out 	a1
		endin

</CsInstruments>

<CsScore>
f 1  0 4096 10   1    
f 2  0 4096 10   1  .5 .333 .25 .2 .166 .142 .125 .111 .1 .09 .083 .076 .071 .066 .062

; abcsound's output will be inserted here.

</CsScore>

</CsoundSynthesizer>

we can add the following statements at the beginning of someSong.abc in order to link the abc data to Csound:


instr Guitar [p1=1:p4=pitch:p5=440]
voices Guitar

This means:
  • The voice named "Guitar" should be generated as i-statements with p1 (instrument number) equal to 1, the note pitch assigned to parameter p4, and the constant value 440 assigned to p5 (this is a bandpass filter frequency).
  • Use the "Guitar" voice to voice the single line of music present in the file.
Then, you run abcsound.py with the skeleton .csd file as the second argument, and once again, it spits the complete .csd file out to stdout:

python abcsound.py someSong.abc skeleton.csd > someSong.csd

Why, you may ask, should you have to specify what voice to use, when you just defined the voice? The reason is that abcsound.py supports multiple voices. This is an extension of the standard abc notation, and is covered in the next section.

Feel the POWERPoWeRpower...

Let's say that someSong.abc contains the following trivial bit of music:


instr Guitar [p1=1:p4=pitch:p5=440]
voices Guitar

|abcd|
|cdef|

|gfed|
|bagf|

With the voices defined above, we would hear four measures of four quarter notes. However, if, instead of


voices Guitar

we had written


voices Guitar Guitar

then abcsound.py would treat each group of two parallel lines of music as two parallel staves, and would render two measures of four quarter notes each, and during each quarter note we would hear the successive dyads "ac", "bd", "ce", "df", "gb", "fa", "eg", and "df".

You can write for as many parallel voices as you like. If we have multiple instruments defined in the .csd orchestra, we can define them as abc instruments using instr statements, and write parallel voices for different instruments. abcsound.py takes care of matching up successive sets of parallel staves so that everything works out. The only gotcha to be aware of is that each line of a group of parallel staves should have the same number of measures; otherwise you will probably get confused. abcsound.py will still render the score as written, but the timing will be off.

Total inSANity!!!

The final bit of Csound yumminess that abcsound.py provides, is that you can change a Csound instrument's p-field values on the fly using abc's decoration notation, {code}. The "code" inside the decorator is just a list of pfield values, just like we used when defining the abc instruments. For example, the following changes to the abc score above will cause the first voice's p5 filter value to ramp down from 660Hz to 220Hz over the course of the score (I added space to the second voice merely to keep corresponding notes aligned):


instr Guitar [p1=1:p4=pitch:p5=440]
voices Guitar Guitar

|{[p5=660]} a {[p5=>]} bcd|
|           c          def|

|gfe {[p5=220]} d|
|bag            f|

Note that a decorator takes effect on notes that occur after it appears, so there has to be at least one note after a decorator for that decorator to do anything. If you see messages from Csound about ramp values being undefined, you have probably violated this rule. This mechanism can be used to change any p-field to any arbitrary value at any point in the score (provided I haven't got any bugs in the code).

It's also possible to define the decorator text separately and assign it a short name. This minimizes spatial disruption in the score:



instr Guitar [p1=1:p4=pitch:p5=440]
voices Guitar Guitar

decorator X [p5=660]
decorator Y [p5=>]
decorator Z [p5=220]

|{X}a{Y}bcd|
|   c   def|

|gfe{Z}d|
|bag   f|

So... Have fun, y'all. I know I will!

-- JK


Last changed:
09-07-09 01:21:48


This page was rendered by LittleSite.
LittleSite is Copyright (c) 2005 by J.Knapka.
Questions and comments to JK