Monday, December 28, 2009

Compiling ZynAddSubFX on Ubuntu 9.04

ZynAddSubFX does not compile from source by default and there is no configure file. Add the following packages and the build will succeed.

apt-get install fluid libmxml-dev libfftw3-3 mffm-fftw-dev libasound2-dev

I've never been happy with the appearance of ZynAddSubFX on linux. It seemed the fonts were all too big, crowding the screen and buttons. I was going to look into fixing this, which was the reason I downloaded the source version in the first place. But to my surprise, the version I compiled myself looked great. I'm guessing that fluid makes geometric decisions based on the video display it is used on and that the package maintainer uses a lower screen resolution than I do, thus the crappy display.

Thursday, December 24, 2009

M-Audio / Freebob and Ubuntu 9.10

In setting up a new Ubuntu 9.10 install with ubuntustudio, I had to do a few manual things. There is an UbuntuStudio distribution, but I typically opt to install what I need later, which is generally just the awesome audio stuff. If you go this route and want to use jack, be sure to also install the real time kernel.

sudo apt-get install ubuntustudio-audio
sudo apt-get install linux-rt

I use a M-Audio FiewWire Solo audio card and have used the freebob driver with success in the past. I was happy to see that it is installed by default now with qjackctl. But when I started jack initially I got errors suggesting the driver was not loaded. I had to install the driver and change permissions before I jack would start up.

sudo modprobe raw1397
sudo chmod a+rw /dev/raw1394

Chmod was transient however, and after rebooting /dev/raw1394 didn't have the correct permissions. I added a file called 40-permissions.rules and gave the audio group permission to access the device. I failed to mention earlier that I also had to add my personal user to the "audio" group before getting jack to start up.

sudo vim /etc/udev/rules.d/40-permissions.rules
# EEE1394 (firewire) devices
KERNEL=="raw1394", GROUP="audio"

So I was done right? No. After reboot I still didn't have permission to access the firewire device. ls told me why.

ls -altr /dev/raw1394
crw-rw---- 1 root video 171, 0 2009-12-24 19:55 /dev/raw1394

I guess by default /dev/raw1394 belongs to the video group. Well my user doesn't, and I'm not using firewire for video, so I switched it to belong to audio.

dextron@dextron:~$ sudo chgrp audio /dev/raw1394
ls -altr /dev/raw1394
crw-rw---- 1 root audio 171, 0 2009-12-24 19:55 /dev/raw1394

After another reboot, all is well. I'm wondering if I should have just left the group as "video" and added my user to the video group plus changing my udev rule (to use video instead of audio). I suspect there is no single right answer, but if you have any insights, please leave a comment. Thanks!

Monday, December 07, 2009

Creating digital synth sounds using Python

I used to really be into electronic music. I had a bunch of keyboards, synths and digital samplers and I would use them, along with a computer, to compose techno compositions. In fact, I took up c++ programming in the 90's with the intention of building a drum sequencer for Windows. Well that project didn't get finished and I got sidetracked writing code for corporations; after all you have to pay the bills first and find time to play around later.

Now seems like a good time to resume play.

Since Python is my language of choice these days, I thought I'd see what's out there by way of using the language to generate digital sounds. I found a wave generation library and a few sample snippets on the web, including code which can be used to produce a simple sine wave. I've been sampling since the 80's using Roland, Ensoniq and EMU samplers, and I have a pretty good understanding of the basics. But it turns out I had more to learn at the lowest level. Consider the following snippet of code, which can be used to generate a 90 Hz tone.

import wave, random, math, numpy

noise_output ='tone.wav', 'w')
noise_output.setparams((2, 2, 44100, 0, 'NONE', 'not compressed'))

# num of seconds
duration = 4

# Hz per second
samplerate = 44100

# total number of samples
samples = duration * samplerate

# pulse per second
frequency = 90 # Hz

The time of one sample is the inverse of the sample rate, and the period is the inverse of the frequency, so the number of samples is also the sample rate divided by the frequency.
period = samplerate / float(frequency) # in sample points

This is the phase increment.
omega = numpy.pi * .2 / period

Creates the x-axis set with 'period' number of items. numpy.arange(int(period), dtype = numpy.float) produces {0..146}, but since each value is a factor of omega, the transformed set is in the range {0..0.627}.
xaxis = numpy.arange(int(period), dtype = numpy.float) * omega

This snippet calculates the sin for each value in xaxis and multiplies that value with 16384. Here we're creating the y-axis data.
ydata = 16384 * numpy.sin(xaxis)

If we were to graph the sets now, we would see an inclining sin wave. Resize creates an extended array which repeats the ydata chunk, the result being something that looks a bit more like a saw wave than a sin wave due to the omega calculation.
signal = numpy.resize(ydata, (samples,))

for i in signal:
packed_value = wave.struct.pack('h', i)


Friday, December 04, 2009

Find all non-binary files in a directory

You've got to love that there are so many different ways to accomplish this. Here's one:

find . -type f | xargs file | grep -v ELF

1. Recursively finds all files in current directory
2. Pipes to file, which displays information about each file type
3. Pipes to grep, which checks to see that ELF is NOT in result text

file is a handy command. On Linux, binary files with show something like the following.

dvenable@dvenable:~/src$ file bin.exe
bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped

Thursday, December 03, 2009

Save with CTRL-S using VIM and copy/paste with CTRL-C, CTRL-V

Oh now this has got to be the best VIM find in years. I love VIM but get sick of copying from a web browser and having to visual paste in strange ways. It's my one holdover from Windows, the desire to use CTRL-C to copy and CTRL-V to paste. It turns out that this is easily remedied by modifying your .vimrc file and adding VIM mappings.

nmap <C-V> "+gP
imap <C-V> <ESC><C-V>i
vmap <C-C> "+y

That's it. Now enjoy the most standard shortcuts in your favorite VIM editor. The mappings looked so easy that I thought I'd try one of my own. Another thing that causes my fingers to grow weary is saving. The typical sequence is: press escape, then :w enter. I save all the time because I'm paranoid and I miss CTRL-S which is so much easier on the hands.

map <C-S> <ESC>:w<CR>
imap <C-S> <ESC>:w<CR>

Oh yes it is a sweet discovery!