Tuesday, June 30, 2015

pd9. vline object in Pure Data

The vline object is used to create ramps from one value to another value. Like a previous example, we will use the writesf object to write to external file.


A trigger bang bang bang bang is used to (1) open a file for writing, (2) starting a delay of 50 millisecond to end writing, (3) starting a 50-ms ramp from -1 to +1and (4) start writing.


The audio signal is a ramp from -1 to +1. This is not meant to be listened to, instead it is used to control an audio signal, such as attack and release of a note.



The output is a mono signal of 0.05 second duration:


pd8. Metro object in Pure Data

A metro object, once banged, sends bangs at the period of either argument, or second inlet, as in the example here.


Similar to the counter example, a float (f) stores a number and increments whenever it receives a bang, due to it's two connections with + 1 object, in a feedback loop.


The vertical slider changes the period (in millisecond). The height was changed in properties and the range was changed from 250 to 1000.


We also calculate the Frequency. Anytime, we can reset the count by clicking on the 0 message.


pd7. Toggle, Slider and Radio in Pure Data

There are 4 independent sections here. The toggle switch (at upper left) either outputs a 0 or 1. The value is held and acts like a checkbutton.


A horizontal slider is placed on the lower left side. The default range is from 0 to 127, which can be changed by changing its properties.


A vertical radio is also placed on the upper right side. We can also change the number of boxes, etc, by changing the properties.


A bang message is identical to bang object.


pd6. Moses and Select in Pure Data

Both moses and select (sel) are important for signal flow and control. Both have two inlets, as well as two outlets. If the second inlet was connected, it would override the control value, which is 5 in the objects below.


Moses will sent the input number to left outlet if that number is less than the control value. Otherwise, it will send it to the right outlet.


Select will send a bang to left outlet if the number is equal to the control value. If not, it will send a number to the right outlet.


pd5. Evaluating Expressions in Pure Data

To understand how to use Pure Data for electronic music, we have to understand signal flow. The best way to understand is with mathematical expressions.


We use the expr object to find the average of two numbers. expr knows we want two inlets since the expression has $f1 and $f2. If we had more variables, there will be more inlets.


On the right side, we evaluate using + and / objects. Both sides are equivalent; however expr is more compact, especially with more complicated expressions.


Changing the first number will sent a bang as well and the result will be updated in the Number atoms in last row. However changing the second number will not send a bang, and we have to click on the bang to recalculate.


Monday, June 29, 2015

pd4. Saving a wav file in Pure Data

We can use the writesf object to write a file.


A trigger bang bang bang is used to (1) open a file for writing, (2) starting a delay of 50 millisecond to end writing, and (3) start writing.


The audio signal is from a 440-Hz sinusoid oscillator, which is also sent to the writesf object..



The output is a mono signal of 0.05 second duration:


pd3. Counter in Pure Data

A float object, or f, can store a number. Here it holds the current Counter value.


A Message with value 0, resets the counter whenever clicked in Execute Mode. There is a comment of Reset, next to the Message. The bang object will increment the Counter when clicked in Execute mode.


A Number is used to display the output of Counter, that is the f object. A + object is used to feed the output of f to the right input of f. The comment of Counter indicates the number displays the Counter.


pd2. Trigger object in Pure Data

A trigger object can also use t as abbreviation, as we have used below. b stands for bang, and f for float, and so on. You do not have to use the abbreviated symbols on the object. The number of arguments in the trigger will determine the number of outlets.


The input is either bang object (Ctrl-Shift-B) (on the top left of patch below), or a Number (on the top right of patch below). Whenever either is changed, three different values are printed to console on three different lines.


For example if Number is changed (in Execute mode) to 11 it will add 3 prints (v3: 11, v2: bang, v1: bang). If the bang is clicked (in Execute mode), it prints ( v3: 0, v2: bang, v1: bang). Note the order is from right to left.


pd1. Print object in Pure Data


A Number and a print object are placed on the canvas. In the execute mode (Ctrl E), you can use mouse on the Number to change value.


The value is printed, on the terminal, after the hello world symbol and : separator, so it will be hello world: 1, at the moment when the number is 1. The print is triggered whenever the value in Number changes.


There are also two comments about the shortcuts.


Monday, June 15, 2015

tk6. Scale in Tkinter

A scale can be used to select a number within a range. Here the range is from 1 to 10.


The number selected is printed in the label just underneath it, using the command function of the Scale.


Whenever the command is invoked by a scale change, a parameter is passed by Tkinter. It is referred to as e here, but it does not make any difference what we call it, as long as we are consistent.

# tk6.py
from tkinter import *
from tkinter.ttk import *
root = Tk()
root.geometry('400x300')
root.title('Scale')
root['bg']='blue'
scaleVal = StringVar()
scaleVal.set('5.000')
scale = Scale(root, from_=1, to=10,
              orient = HORIZONTAL,
              command = lambda e: scaleVal.set('%.3f' % float(e)))
scale.set(5)
scale.pack(fill = X)

label = Label(root, textvariable = scaleVal, pad = 100)
label.pack(expand = True)
root.mainloop()

Output:

tk5. Using lambda functions in Tkinter

For the last example, we will now use the lambda function so we do not need a separate function.


The function is now completely inline, within the checkbutton definition.

# tk5.py
from tkinter import *
from tkinter.ttk import *

root=Tk()
root.title('Checkbutton Status')
root.geometry('300x100')
frame = Frame(root)
frame.pack()
status = StringVar()
checkbutton = Checkbutton(frame, text='status\ncheckbutton', 
     command = lambda : display.set(status.get()),
            variable=status, onvalue='on', offvalue='off')
checkbutton.grid(row = 1, column= 0)
label = Label(frame, text = 'status', pad = 5)
label.grid(row = 0, column = 1)
display = StringVar()
display.set('off')
label1 = Label(frame, textvariable = display, pad = 5)
label1.grid(row = 1, column = 1)
root.mainloop()

tk4. Checkbutton in TKinter

Checkbuttons are similar to Buttons. Now the toggling action of checking or unchecking will be the status. Whenever the state changes, we invoke the function statusChanged. This function displays the current value of the checkbutton.


We again use a 2 by 2 grid, within a Frame, with the 3 widgets being a checkbutton, static label, and non-static Label (named display).


Now, we have 2 StringVar objects, one for the checkbutton and the other for the display Label.


There is no reason to have the statusChanged function be a separate function, since it is only 1-line. We can also put it, inline, as a lambda function.

# tk4.py
from tkinter import *
from tkinter.ttk import *

def statusChanged():
    display.set(status.get())
    
root=Tk()
root.title('Checkbutton Status')
root.geometry('300x100')
frame = Frame(root)
frame.pack()
status = StringVar()
checkbutton = Checkbutton(frame, text='status\ncheckbutton', 
     command=statusChanged, variable=status,
     onvalue='on', offvalue='off')
checkbutton.grid(row = 1, column= 0)
label = Label(frame, text = 'status', pad = 5)
label.grid(row = 0, column = 1)
display = StringVar()
display.set('off')
label1 = Label(frame, textvariable = display, pad = 5)
label1.grid(row = 1, column = 1)
root.mainloop()

Output:

Sunday, June 14, 2015

tk3. Button and StringVar in Tkinter

The themed widgets from Tkinter will be used from now on, so the additional import in the code below.


The function increment, defined in the code, adds 1 to value currently held in a label.


Here, there are 3 widgets in total, within the Frame widget.


The 3 widgets take 3 of the 4 positions in a 2 by 2 grid. The button widget has text '+' and pressing it will invoke the increment function.


There are 2 labels. The first has the name label and is static with text of 'Counter'. The second, label1, can have the text updated using a StringVar object. We initialize it as '0' and update via the increment function.

# tk3.py
from tkinter import *
from tkinter.ttk import *

def increment():
    a = int(counter.get())
    counter.set(a+1)
    
root=Tk()
root.title('Button Counter')
root.geometry('200x100')
frame = Frame(root)
frame.pack()
button = Button(frame, text='+',
                    command = increment, pad = 5)
button.grid(row = 1, column= 0)
label = Label(frame, text = 'Counter', pad = 5)
label.grid(row = 0, column = 1)
counter = StringVar()
counter.set(0)
label1 = Label(frame, textvariable = counter, pad = 5)
label1.grid(row = 1, column = 1)
root.mainloop()

Output:

tk2. Labels in TKinter

A red frame fills the window.


There is one label inside the frame. Both the frame and label use pack geometry manager, rather than grid or absolute positioning with place.


The label text is 'Hello World' in big letters. We use a red background to match the frame background.

# tk2.py
from tkinter import *
root = Tk()
root.title('Welcome')
root.geometry('500x500')
frame = Frame(root)
frame['bg']='red'
frame.pack(expand = True, fill = BOTH)
label = Label(frame, text = 'Hello World!', bg = "red",
              font=("Helvetica", 64))
label.pack(side = RIGHT)
root.mainloop()

Output:

tk1. Frames in Tkinter

Tkinter is one of the GUI systems that we can use with Python, which is included in the default Python. In these examples, Python 3+ is used. For Python 2.7, you have to change the import names.


Almost any GUI application will use Frames, to embed other widgets such as Labels and Buttons. The only function of this program is to create 4 Frames in a grid arrangement.


After the import(s), we have to define an instance or the Tk class, as the root Widget. Two of its properties are then set.


For frame1 to frame4, we set three properties, width, height, and background color. We can use config function to set many properties at once.


Next, we layout the grid and start our loop.

# tk1.py
from tkinter import *
root = Tk()
root.title('The Frame')
root.geometry('500x500')
frame1 = Frame(root)
frame1['bg'] = 'red'
frame1['width'] = '240'
frame1['height'] = '240'
frame2 = Frame(root)
frame2.config(bg = 'blue', width = '240', height = '240')
frame3 = Frame(root)
frame3.config(bg = 'green', width = '240', height = '240')
frame4 = Frame(root)
frame4.config(bg = 'purple', width = '240', height = '240')
frame1.grid(row = 0, column = 0)
frame2.grid(row = 1, column = 0)
frame3.grid(row = 0, column = 1)
frame4.grid(row = 1, column = 1)
root.mainloop()

Output:

Wednesday, June 10, 2015

lmms7. Piano Roll in LMMS

A bassline is created in the Beat and Bassline editor (BB Editor).


We use bass01.ogg from My Samples sidebar, and drag it to the BB Editor.


We change the track name to Bass. Right now it will still have steps.


We can right-click on the steps and select Open in Piano Roll. We can create a pattern like this:



Note that in above, velocity (volume) of first note and the approximate middle note are reduced. Now the sample will be played at the indicated frequency in time.


The patterns for the Song Editor and BB Editor are shown here:


The resulting audio in Audacity shows how the bassline is rendered.



Tuesday, June 9, 2015

lmms6. Multi Beat and Bassline sections

It is possible to have more that one rhythmic section in Beat + Bassline editor (BB Editor).


Here, we will have three. Three instances of the Triple Oscillator have been moved, from Instrument plugins, to BB Editor and then renamed, to Square, Triangle and Sine, respectively.


This is the for the Square. Osc2 and Osc3 volumes are set to 0 so they do not contribute to the resulting audio, and Osc1 wave is set as Square. Also the CRS (coarse frequency) is set at -24 semitones. This is done so frequency is lower, and the time period is higher.



Likewise, we have changed settings on Triangle and Sine, so only OSC1 is active and is set at the correct waveform shape. The patterns in Song Editor and BB Editor are shown. The other sections of BB Editor have identical pattern, onset at beginning of measure.



We can see that the square is active for first two bars or measures, triangle for the next 2, and sine for the last 2 measures. This is shown here


The selected audio is zoomed in to see that it is indeed triangular:

Sunday, June 7, 2015

lmms5. Envelope Settings of the Triple Oscillator

One of the instruments in LMMS is the Triple Oscillator. It is composed of three audio sources such as 3 sine waves. In the default mode (MIX), the output is just the sum.


You can select the Triple Oscillator from the Instrument plugins, near the My Samples button. A list of instruments will appear and you can drag the Triple Oscillator to the Beat + Bassline Editor. You can remove the Kicker instrument from the Editor if you want.


This is the pattern selected:


By playing it, you will notice the master is clipping often as seen by the reddish colors. By exporting the wav file, you can verify the clipping in Audacity:


A solution is too decrease the time of each note. By clicking on Triple Oscillator in Beat + Bassline Editor, the Triple Oscillator setting dialog appears. Select the ENV/LFO tab, and set the hold to be zero, by changing the HOLD knob.


Now exporting the file, we see that the notes are not touching each other.

lmms4. Adding Steps to Beat + Bassline Editor

The Beat + Bassline Editor has a default of 16 steps


For 4/4 time signature, 16 steps correspond to 1 bar or 4 beats. If we add steps, by right-clicking on the pattern and by selecting the Add Steps option, we have 32 steps, or 2 bars.


With the tempo of 140 beats per minute, one beat is 0.42857 seconds (1/140). Thus, 1 bar is 1.7143 seconds.


This is the setting of the Song Editor and Beat + Bassline Editor:


Now each block in the Song Editor is 2 bars. We select 2 beginning bars, have silence for middle 2 bars, and then select another two bars. Thus the silence is 2*1.7143 seconds = 3.4286 seconds as verified by the audio opened in Audacity:

lmms3. Timing in LMMS

Change the tempo from 140 beats per minute to 60 beats per minute. This makes it easier to see the timing relations


For the usual time signature of 4/4, 1 beat is now 1 second in duration, and 1-bar is 4-seconds in duration.


Remove the Kicker instrument from Beat + Bassline editor, and add drum sample from My Samples.


Use this pattern for the Beat + Bassline editor and Song Editor. (If the image is too small, you can click to get the original size)


In the Song Editor we can see that bars 2 and 3 and not selected. That corresponds to 8-seconds, from 4 to 12, of silence.


Within the Beat + Bassline editor we can see that samples exist at 0-second, 1-second and 3-second. It should be noted that four position separation in this editor correspond to 1 second time-difference, for a 60 beats per minute tempo.


lmm2. Using My Samples in LMMS

The project My Samples is where you will place your samples. In addition, it also has some pre-built samples.


First, remove the Kicker instrument from Beat+Bassline editor.


Open up My Samples (icon on left-side panel), and choose the latin subfolder. Drag the first sample to Beat+Bassline editor. Do the same for the second sample. Now the Beat + Bassline editor should look like this:


After making the patterns in the two editors, exporting the file to wav, we can open in Audacity.


The first file is the result, while the 2nd and 3rd are the actual samples in the LMMS folder.

lmms1. Introduction to LMMS

We can use Python or another language to create any audio. However, it does not provide the interactive experience, such as making changes and listening to the result. This is where a DAW (Digital Audio Workstation) like LMMS is helpful. It is free and open-source.


It is best to use Python to create repetitive parts and for analysis.


Most of what Python will be used here is to extract features, so they may be used to create new samples, etc.


It is assumed that you have installed and setup LMMS. Here we will create a very simple audio.


When LMMS is opened, the default tempo is 140 and there is a Kicker instrument on Beats and Bass Editor. Click on two locations in the pattern so it looks like this:


We added two instances of the audio sample at positions 9 and 13. Also, position 1 in Song Editor has been switched. Next, we can use the File menu to export the file as a wav file.


The file is opened in Audacity, which is also free and open-source. We can see two replicas of the sample at two positions that were created in the Beats and Bass Editor. Also we note the frequency of the sample is changing from high to low (within a small range). Even though the amplitude is 1, the effective volume is low because of our inability to detect low-frequencies (fletcher-munson equal loudness curves).

Monday, June 1, 2015

nlp31. Reading text with PlaintextCorpusReader in Python NLTK

Rather than creating our corpus, it is instructive to read corpus in nltk_data/corpora.


In that module, they define the variable movie_reviews, which we can use if we import it.


We can use that corpus with 2000 reviews, 1000 positive and 1000 negative. They use pos and neg folders to store the two categories.

# nlp31.py

from __future__ import print_function, division
from nltk.corpus.reader import PlaintextCorpusReader
from nltk.data import path
path = path[0] + '/corpora/movie_reviews'

mov_rev = PlaintextCorpusReader(path,'.*.txt')
fils = mov_rev.fileids()
print('len(fils) =',len(fils))
print('First 10 files')
for fil in fils[:10]: print(fil)
nPos = len([fil for fil in fils if fil.startswith('pos')])
nNeg = len([fil for fil in fils if fil.startswith('neg')])
print("pos - %d, neg - %d" % (nPos,nNeg))
print("First 10 words of 1st review")
words = mov_rev.words(fils[0])
for word in words[:10]:
    print(word,end=' ')

#len(fils) = 2000
#First 10 files
#neg/cv000_29416.txt
#neg/cv001_19502.txt
#neg/cv002_17424.txt
#neg/cv003_12683.txt
#neg/cv004_12641.txt
#neg/cv005_29357.txt
#neg/cv006_17022.txt
#neg/cv007_4992.txt
#neg/cv008_29326.txt
#neg/cv009_29417.txt
#pos - 1000, neg - 1000
#First 10 words of 1st review
#plot : two teen couples go to a church party