Friday, June 27, 2008

Audio Experiments!

This program is a little interactive demo of 3 "audio experiments" I came up with. (An example of its sounds). My goal here was to create interesting sounds, experiment with FFTs, and test my digital audio code - but more on that later.

First, there is the "Vibrato Lab". A quick overview: Wav files store a sound as a long list of numbers, representing air pressure vs. time. If the computer plays through this list of samples at a faster rate, we hear a higher pitch. For example, playing every other sample results in something sounding an octave higher and twice as fast. If the samples are played back at a varying rate, the pitch of the output varies, making a comical wavy sound. This is how I wrote a vibrato effect.

When testing the vibrato effect, I found that it could sound interesting if the vibrato effect were applied twice - something like vibrato(vibrato(sound)). So, this is what the vibrato lab does. Use the sliders to change the width (how widely the pitch varies) and the frequency of oscillation. Use the checkboxes to enable another vibrato effect. Play with it!

Next, the "CrFeedback". Have you ever played with video feedback, where when you tilt the camera the picture spirals and twists? When experimenting with audio code, I invented an effect that I like to think of this as the audio analog of those spirals. In this case, the song spirals out of control and degenerates into interesting noise. What you hear is like the sum of the song and many slower versions of itself. Play with the parameters - the "right" settings seem to be dependent on the clip you choose.



Finally, "Frequency Sketch". Last semester I took a course in Signals and Systems. Fourier transforms and the like are very cool, and the math was interesting. Most of the course dealt with signals in the context of voltage and current, but I wanted to apply what I had learned to audio. I wrote fourier transform code, and played around with discrete fourier transforms of audio significantly. As the name implies, the FFT is a faster algorithm for this, and so I replaced my fourier code with some FFT code by Don Cross, originally in C. Anyways, in this experiment, you can draw in the frequency domain, and hear the result! I've wanted something like this for a while, and there is still much left to study.

Microsoft Paint is the user interface for Frequency Sketch :). If you draw red pixels or lines on "input.png", you can hear the results. For example, drawing one red dot creates one sine wave, and so you will hear one pitch. The axes in blue show Hz. Note that the highest red pixel is chosen for a given frequency if there are more than one red pixels in a column. So far I've created ambient, flute-like, and eerie siren effects, but this is just the beginning.



All of this was accomplished in a few days - using a library of digital audio code I've been working on for the past few weeks. I created a project in C# called CsWaveAudio; features include saving and opening wave files, synthesizing sounds, FFT, and certain effects. One interesting part of the library is that it stores samples as doubles, between -1.0 and 1.0. This makes it much easier to do calculations - and when writing effects you don't need to consider whether you are in 8-bit or 16-bit. The library also includes code for some "instruments" made from adding sine waves.

Downloads


Windows binary

Examples of sounds

CsWaveAudio, a C# digital audio library, GPL

And, get all of the code: Downpoured at Github

More notes: in the vibrato lab, the "tremolo" option creates oscillation in amplitude, not in pitch. Also, try clicking numbers to see what happens. The code for the CrFeedback effect is in the readme file - check out the svn source to modify it. There is a "randomize phases" checkbox in frequency sketch and I'm still not sure why this makes such a difference. Beat frequencies can be created because of the spacing between pixels in the input image. Maybe I should look into interpolation.

Monday, June 23, 2008

LaTeXinWord

When I have time, I type up notes from school in LaTeX, so that they will be archived and legible for the future. This works ok, but I use many quick illustrations and diagrams, which are a pain to add to a LaTeX document (or at least are in any editor I've used). Also, even when the picture is saved, and in the right format, you can't really control positioning. By design, LaTeX has its own ideas about where it thinks your figure should go. This is good for actual "figures" as you would find in a paper, but I want my little diagrams to be inline with the text and not on the next page. In Word, by contrast, I can select an image and Ctrl C, Ctrl V it right into the document, but LaTeX's formatting of formulas is so much better.

As it turns out, I can have a combination of the two. There is a good open source project, LatexInWord which I recently discovered. Now I can keep the formulas I was using but have more control over layout of pictures. The interface is good - all one needs to do is press Alt-L to insert Latex. Also, I can have this open side-by-side with Lyx in view source mode, or another editor, and copy and paste. (There appear to be similar macros for OpenOffice, like this.)

Of course, I'll still write my actual papers in standard LaTeX, but for my personal notes, this should work well.

Tonight I wrote a quick macro to be used with LatexInWord. It prints out the LaTeX source for all of the formulas in the document. I thought this would be useful to have for archival purposes (in the future I might not have LatexInWord or Word so a plain text copy is good). This is basically my first Word vba script, but it worked when I tested it.
Sub ExportLatexAsText()
    Dim strRes As String
    Dim i As Integer
    Dim newline As String
    newline = Chr(13) & Chr(10)
    i = 1
    For Each currentShape In ActiveDocument.InlineShapes
        If currentShape.AlternativeText <> "" Then
            strRes = strRes & newline & newline & "Formula " & i & newline
            strRes = strRes & currentShape.AlternativeText
            i = i + 1
        End If
    Next
    Selection.Text = strRes

End Sub


You can add this to the document under Macros. Just start editing an existing macro, and when you're looking at the source, put this subroutine in.

Friday, June 20, 2008

Googlecalc

This has been done before several times, but usually in Perl. After reading a version by Matt Sparks, I quickly wrote a C# version. I think this is something that will be useful. You type in an expression, which is sent to Google, and the result is printed back.

Bin (Windows exe) Source, project file is Vs2008 but the source should work in 2005.

On another note, while I have enjoyed reading entries in the Obfuscated C Code Contest for a while, there is another interesting contest that sounds just as fun. The Underhanded C Contest is a "programming contest to turn out code that is malicious, but passes a rigorous inspection, and looks like an honest mistake."

Another clever contest is the Obfuscated V contest in 2004, where contestants wrote short programs that appear to simply count votes, but actually influence the results.

Thursday, June 19, 2008

Summer

I have been writing code, but that will have to wait. I just needed to post something since it's been a while.

In Java, Math.abs can return a negative number (!). I heard about it from here.

Python 2.6 is in beta. In Python, last fall Guido talked about the GIL. Now I am interested to see a "multiprocessing" module which "supports the spawning of processes using a similar API of the threading module". This is pretty cool - it will allow programs to take advantage of multiple processors, while maintaining the GIL.

A Python 3k hack from here. At least on the Python 3k I'm using , __signature__ isn't available yet, so this doesn't work yet. Annotations can be useful though.
#posted by Nick Coghlan
#on Python-3000 list,
#http://mail.python.org/pipermail/python-3000/2006-May/002033.html

#Apparently __signature__ hasn't been added yet. This won't work yet.

class Annotate(object):
     def __init__(*args, **kwds):
         self, args = args[0], args[1:]
         self.arg_notes = args
         self.kwd_notes = kwds
         self.return_note = None
         self.strict = False

     @classmethod
     def strict(*args, **kwds):
         cls, args = args[0], args[1:]
         self = cls(*args, **kwds)
         self.strict = True
         return self

     def returns(self, note):
         self.return_note = note
         return self

     def __call__(self, func):
         func.__signature__.update_annotations(self)
         return func

@Annotate(str, str, int).returns(int)
def f(a, b, c=0):
     # some operation producing an int. . .

@Annotate.strict(str, str, int).returns(int)
def f(a, b, c=0):
     # some operation producing an int. . .


I am currently working for Avid in Tewksbury, MA, as a "Media Engine Infrastructure Software Engineer Intern". It's going well so far as I dig deeper and deeper into c++.