Monday, April 21, 2014

6. Writing a Wav File - 3

The program csound is used to write an audio file.




csound was created in the 1980's at MIT. It is written in the C language. This is an audio library which simplifies sound synthesis. With this program, I will illustrate different aspects of audio programming.




To get csound, we should go to this web address, www.csounds.com. After clicking on download, we can find the link to the install files.




This is the install file for Windows.




During installation, you will check the option to install csound Python bindings.




After installation, you should have a list of programs such as this.




To use the Python bindings, we have to import csnd6.




Next we have to define an orchestra string. In Python, we can define a multi-line string with triple quotes. Here we define an instrument, instr 1, which is an oscil opcode. The out, opcode, sends the oscil output to the output device. Opcode is short for operation code.




Basically oscil reads values from a table, and repeats them as needed. The oscil opcode needs 3 arguments. The first one in this example is 32767. This happens to be the maximum for 16-bit wav files. The table will be repeated to create a 261.626 Hz signal. The table number is 1, and table 1 will be created in the next step.




This is the string to create our score. In the first line, we create the square wave as a sum of 3 sine frequencies. This line starts with a f-statement, which indicates this is a table. The table has 8192 values. The 4th parameter specifies a generation routine. This is known as GEN in csound documentation. GEN10 creates sine waves. GEN10 can accept any number of parameters after 10. These are the amplitude values for the different frequency terms. For the square wave, the only nonzero terms are the odd terms. Further they are of the form 1 divided by n, thus we can see we have one-third or .33 for 3rd frequency and one-fifth or .2 for the 5th frequency. In this case, the table is normalized. Usually for audio we want tables to be normalized. However we can force it to remain unscaled and retain their values. In the next statement beginning with the letter i, we define our first audio event. It will utilize instrument 1, start at time 0, and last for 5 seconds. These are the three basic parameters any i-statement must have. The parameters are referred to as p-fields, with the first parameter being p1, the second parameter being p2, and the third parameter being p3.




If we replace the f-statement with this line, we will have a simple sine wave, that is, only 1 frequency component is used.




If we replace the f-statement with this line, we will have a wave with 2 Fourier components.




This is our case to form the Fourier coefficients for the first 3 nonzero Fourier frequencies.




All the tables created using the previous values are normalized. However if the GEN number is negative, the table is as-is, that is, without rescaling.




The first nonzero Fourier component is 4 divided by pi. The second nonzero Fourier component is 4 divided by 3 pi. The third nonzero Fourier component is 4 divided by 5pi. These are calculated here in the IPython shell.




Now if we replaced the f-statement with this line, we will see some signal is clipped off. This might be important in a distortion effect.




Returning to the Python program, we create a csound instance.




Now we can create different options like saving it to a file, which is the o flag.




We have to compile the orchestra piece, which is the orc string.




Next we compile the score piece, which is the sco string.




Finally these three lines perform the score.




Instead of running in the IPython prompt, we could write a script with all the commands.


# SquareWave.py
import csnd6
orc = """
instr   1 
  aSW oscil 32767, 261.626, 1
  out aSW
endin
"""
sco ="""
f 1 0 8192 10 1 0 .33 0 .2
i 1 0 5
"""
c = csnd6.Csound()
c.SetOption("-o SqWav.wav") 
c.CompileOrc(orc)
c.ReadScore(sco) 
c.Start()
c.Perform() 
c.Stop()



We can run the the Python file with this code.




Now the wav file is created and we can open in an Audio program such as Audacity.




However we will not use the Python bindings. We will use Python to write a csd text file. The csd file, has the orchestra and score. It is easy to write with Python. The csd format is the standard file format understood by csound.


; SquareWave.csd

<CsoundSynthesizer>

<CsOptions>

</CsOptions>

<CsInstruments>

instr   1 

  aSW oscil 32767, 261.626, 1

  out aSW

endin

</CsInstruments>

<CsScore>

f 1 0 8192 10 1 0 .33 0 .2

i 1 0 5

</CsScore>

</CsoundSynthesizer>



After creating the text file, we can run csound command prompt line by using the system command from the os module. Basically os.system will execute any string in the command prompt. For example we can start any executable program such as csound or even, Audacity. In this example we use the o flag to save the audio file that was rendered by the score.




You may go to pythonaudio.blogspot.com to see the slides. To see a larger image of the slide, you can click on them at that page, which provides easy navigation controls. The text for the audio of the slides as well as any relevant source code is also on that page.




This is the video of Tutorial 6:


No comments:

Post a Comment

About Me

I have used Python for the last 10+ years. I have a PhD in Electrical Engineering. I have taught Assembly Language programming of Intel-compatible chips as well as PC hardware interfacing. In my research, I have used Python to automate my calculations in physics and chemistry. I also use C++ and Java, often with Python.