Irken Kitties

Creating Sound on the NES

I am into all types of synthesizers, old and new, and recently I’ve taken to the sound of older video game sound chips. I recently desoldered the NES’s 2A03 processor off its mainboard and have it in partial communication with an Arudino, but rewind, do I really know enough about composing music on that chip? Not yet. So there’s only one thing to do about that.

6502 Assembler

The NES was programmed in 6502 assembly language, and lucky for me, it actually has a really straight forward instruction set, but still, last month I was still not familiar with it enough to make anything. Now, usually when I don’t understand something, I write a program that somehow involves whatever topic I’m learning. You can’t write a program like an assembler without understanding how the processor for that assembler works, so I wrote my own assembler for the NES called n65.

This is the assembler I will be using in this article, and to help me compose music on the NES.

You can easily install n65 through RubyGems.org:

gem install n65

New Track: Mí Feabhra 12

I wrote a new track last month called Mí Febhra 12th. The influence behind it, is that I was playing some piano in what could be called the “Aphex Key”, which is a musical key often used by Richard D James. One of my favourite pieces of music ever, is a piano track by Aphex Twin called Avril 14th, so this was sort of the idea I was going for. Lately I have been really into the sound chips in video game consoles of the past. This track is almost completely piano, and the NES 2A03’s audio processing unit, plus some breakish style drums.

Read on for some more info on what I’ve been working on with regards to the NES’s processor.

Matrices as Linear Operators

Since they are my favourite, let’s learn something neat about matrices, something that can also serve as the first post on this new blog of mine about math, programming, and DSP.

Sonoluminescence

I wrote a new track called Sonoluminescence yesterday during one of my: “Make a song as fast as I can”, marathons. Took about 5 hours in total to write, plus maybe an hour mixing it. Writing music quickly works pretty well, and seems to bring out more creativity.

What is Sonoluminescence?

What is sonoluminescence anyway? Basically, they discovered it while working on sonar. Some researchers were trying to speed up the development of photographic film by shooting ultrasonic soundwaves at a flask of developer fluid (for some reason) and noticed the bubbles it was creating were emiting light.

Building My Shruthi-1

Last year I built a small MIDI controlled polyphonic synthesizer called KittySynth using a 72MHz LeafLabs Maple microcontroller board, an Audio Codec Shield from Open Music Labs, and some C++. I had originally had some ideas to try to build something like this by abusing the timers and PWM duty cycles on a 16MHz Arduino Mega I have, but quickly realized there was no way on earth I could build what I wanted to with the small amount of resources on an Arduino. The ARM based STM32 chip on the Maple had just enough resources available to create an 8-voice polyphonic wavetable synth, which I should write about sooner or later.

Anyway, while researching for that project I found out that someone actually has created a perfectly viable synthesizer based around a 20MHz ATMega chip (as in the Arduino) called the Shruthi-1. I thought this was a perfect opportunity to go through the steps of actually building a proper synth of the sort I would someday like to design, so I ordered the Shruth-1 4-Pole Mission Kit, and decided to put it together from scratch.

The Parts Arrived

Recreating the Haskell List Part 6: The IO Monad

This is part 6 of a 6 part tutorial

The IO Monad

In pure functional programming, all functions are supposed to be referentially transparent, and that means that each time you call a function with the same arguments, it should give you the exact same result. When functions are referentially transparent, you have a lot less worries about whether or not it will always work correctly.

A mathematical function is never going to give you a different answer no matter how many times you give it the same argument. The reason for that is pretty much that it cannot get any values from anywhere other than what you passed it, so it can never be any different.

Recreating the Haskell List Part 5: Monads

This is part 5 of a 6 part tutorial

Monads

The Haskell list type is also an instance of the Monad typeclass. There are four functions defined for a monad, but you only need to implement 2 of them: >>= (pronounced bind) and return.

The Monad Typeclass

1
2
3
4
5
class Monad m where
    (>>=) :: m a -> (a -> m b) -> m b
    (>>) :: m a -> m b -> m b
    return :: a -> m a
    fail :: String -> m a

The easiest function is return. It just wraps a value in the monad container, and it is exactly the same thing as pure from the Applicative class. The bind function takes a monad holding a value of type a, and a function which can change an a into the same type of monad holding something of type b.

Before making MyList an instance of Monad, it might be easier to see what happens if we make something simpler like Container from part 1 an instance first.

Making Container a Monad

1
2
3
4
5
6
instance Monad Container where
    (Container contents) >>= f = f contents
    return a = Container a
-- binding a container to a function
(Container 3) >>= (\x -> return $ x + 2)
=> Container 5

Recreating the Haskell List Part 4: Applicative Functors

This is part 4 of a 6 part tutorial

Applicative Functors

A Haskell list is also an Applicative Functor. If we want to make MyList one too, we can look at the interface for the Applicative class, and implement the right functions.

Interface for the Applicative Typeclass

1
2
3
4
:info Applicative
=> class (Functor f) => Applicative f where
    pure :: a -> f a
    (<*>) :: f (a -> b) -> f a -> f b

So, it looks as though we need to implement the functions pure and <*> in order to be an instance of Applicative. This also says that whatever is Applictaive has the prerequisite of also being a Functor. The function pure must take any type a and wrap it in the container MyList. This is also called lifting a into the Functor. Implementing pure is easy enough, because it is the same thing as our data constructor, Cons.

Recreating the Haskell List Part 3: Monoids

This is part 3 of a 6 part tutorial

Monoids

It turns out that cons lists can be more than just a Functor, it can be a Monoid. A Monoid is a object with a single associative binary operation, and an identity element. This means that things like addition and multiplication form a monoid.

The identity element for addition is the number $0$, because $x + 0 = x$. An identity element and any other element, when operated on by the single associative binary operation, is one that does not change the other element. Basically you can add $0$ to any number and you just get the same number. The identity element for multiplication is $1$, because $x \cdot 1 = x$ for every number.

The binary operation should be one which can combine two of the objects, and for a list that happens to be appending them using the function ++.

[1, 2, 3] ++ [4, 5, 6] == [1, 2, 3, 4, 5, 6] Easy enough, so that means the identity element, the element you can combine with a list that will return the same list is: [], the empty list. [1, 2] ++ [] == [1, 2]

The ghci command :info shows that to be an instance of a monoid you must implement the functions mempty which returns the identity element, and either mappend or mconcat. Typeclasses can sometimes have default implementations for some functions, and it’s often the case that two functions are actually defined by default in terms of one another, meaning you only have to implement one of them and the other will automatically work. Here mappend and mconcat are defined in terms of each other so we just decide to implement the easier of the two, mappend

Looking at the type signatures below we can see mappend :: a -> a -> a, where in our case a will be the type MyList. This means mappend receives two lists and returns a third in which they are combined. For addition this would have been receiving two numbers that need to be combined, but for a list it just means to stick them together end to end.

Recreating the Haskell List Part 2: Functors

This is part 2 of a 6 part tutorial

Functors

How can we modify or transform a value or values that are contained in a data structure such as Container? Let’s say we have a Container holding the integer 4, and we want to add 1 to it. The problem is that a Container doesn’t have addition defined for it, and really, it shouldn’t considering that any possible type could be stored inside it, any number of which have no meaningful way to respond to addition.

Let’s look at a similar situation in C++:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template <class T>
class Container {
   T _value;
   public:
   Container(T value) : _value(value) { }
   T get_value() {
       return _value;
   }
   void set_value(T value){
       _value = value;
   }
};
Container<int> container = Container<int>(4);
//  Of course, you can't do this to transform the value inside
container = container + 1
//  You must remove it, apply the transformation and put it back
int x = container.get_value();
x = x + 1
container.set_value(x);

The extreme generality of this C++ class means that it would be a mistake to define operator+ on it, as any number of types T also cannot meaningfully respond to addition. Now we find ourselves in a similar situation in Haskell:

1
2
3
4
5
6
7
8
9
let container = Container 4
let container' = container + 1
<interactive>:3:28:
    No instance for (Num (Container Integer))
        arising from a use of `+'
    Possible fix:
        add an instance declaration for (Num (Container Integer))
    In the expression: container + 1
    In an equation for container': container' = container + 1