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
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.
Building My Shruthi1
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 8voice 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 Shruthi1. 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 Shruth1 4Pole Mission Kit, and decided to put it together from scratch.
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 

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 

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 

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 

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 

Recreating the Haskell List Part 1
This is part 1 of a 6 part tutorial
Data Structures as Containers
In a language like C, you can think of data structures as containers which hold one or more objects.
A Container
1 2 3 

The int_container_t
type is now something which holds one int. To make the same sort of data structure in Haskell you would
write:
Int container in Haskell
1


Ignoring for a moment the suffix deriving Show
, this looks a lot like a function declaration, because that is essentially
what it is. The identifier IntContainer
appears on both sides, but the two are actually in two different namespaces. It is
not necessary for these two identifiers to have the same name, but people will often do this by convention.
The left hand side of this declaration names a new type IntContainer
, and the right hand side is defining a data constructor
for this type, essentially a function named IntContainer
which takes one Int
as argument which it uses to create an instance of this type.
Using the data constructor in ghci
1 2 3 4 5 6 7 8 9 10 

If I pass the data constructor a 4
, it returns something which is of type IntContainer. The ghci command :t
can be used
to get type information about just about anything in Haskell. IntContainer :: Int > IntContainer
is read “IntContainer is
a function which accepts an Int and returns an IntContainer”. i :: IntContainer
is read “i is of type IntContainer”.