Websites, Propellers, and Sweet Music!

Well, I’m sure that you’ve noticed the new layout and domain name for my blog. Over winter break, I decided it was silly to have both a blog site and a school website. So, I purchased this domain (www.samkerr.com was taken) and am now going to host both sites here. My web host, A Small Orange, has a really good deal on a years worth of hosting for only $25, so Idecided to go with that. So far, it’s performing much better than my old site. If you’re in the market for a new web host, I’d appreciate you signing up through the previous link, since I get a referral bonus.

Parallax Propeller Logo

Propeller Time!

Anyways, at Christmas, I got a starter set for the Parallax Propeller microcontroller, an 8 core, 32-bit microcontroller. I really like to work with hardware and embedded type stuff, so I was really excited about this. I’ve played with AVR chips before, but this chip has a lot more power built-in, but it won’t require as much work as using an FPGA either.

Due to the nature of the Propeller, it can perform some really complex tasks. Since it’s 32 bits, it can easily handle some tasks, such as floating point division, that would be more difficult on other architectures. Not only that, but it has 8 ‘cores’! Each core, or ’cog,’ can run up to 80 MHz, has its own ALU (Arithmetic Logic Unit), counters, frequency, and video generators. In addition, each one can control every I/O pin. There is clearly a lot of power available here, but what would be a good starting point? Music of course!

I read an article a few weeks ago about music notes and their frequencies, and since each cog can generate a unique frequency, I thought it would be fun to make some music. I have a small speaker, so this would be a doable project. Since I’m just starting out, I decided to keep the design relatively simple. Here are a few things I decided I wanted to do:

  • Be able to generate any note.
  • Be able to use any I/O pin.
  • Be able to play a chromatic scale (all notes, sharps, and flats on the scale).
  • Be able to play a note for a specified time.
  • Be able to play across multiple octaves.

I also decided to make some concessions, at least for now:

  • No chord support initially.
  • All multi-cog management must be handled by the user.
  • Only quarter notes, eighth notes, sixteenth notes, thirty-second notes, and integer quantities of quarter notes can be played.
  • A BPM (Beats Per Minute) of 120 (or some other constant) will have to be used.

The Propeller chip has to be programmed in its own language, called Spin, so I had to learn that before I could get started. I found it kind of strange, as its syntax is very different from C or Java. It took me a while, but I eventually managed to figure it out a little bit.

The first step was to be able to synthesize a tone. To do this, I would need to generate a specific frequency. To achieve this, I need to calculate how long of a delay to impose between osciallting the output of the I/O pin, i.e. the period. I then need to divide the clock frequency by the period to give me the proper delay. The code for this ends up looking like:

PUB generateFrequency(Pin, Frequency)
{{
  Given a frequency, specified in Hz,
  output that frequency on the I/O pin Pin.
}}
  DIRA[Pin]~~ ' Set it to output
  repeat      ' Endless loop
    !OUTA[Pin] ' Oscillate the I/O pin
    waitcnt(cnt + CLKFREQ / Frequency) ' Wait for the specified time
Propeller Starter Kit

Who needs a piano? I have a half-watt speaker and a microcontroller!

If you have used the Propeller before, you probably know this section could be re-written to improve performance, using the built-in counters, but I didn’t really figure those out yet. Maybe I’ll optimize this later, but it works, so for now it’s fine.

Now that I can generate an arbitrary frequency, I can play any note I want. However, the code above simply loops endlessly, playing the same note. The next step is to be able to play a note for a specified period of time. This is where the fun will start, since I can use one cog to play the notes and another master cog to manage all the timings.

To achieve this, I need to calculate how long to play the note, get an available cog to start playing the note, wait for the note to play, then stop that cog. Creating a new cog was a little confusing, since I had to provide stack space to the cog, but there are a few examples of how to do this, so I managed to figure it out. Here is what I came up with:

PUB playNote(Note, Pin, Length) | WaitLength
  {{ playNote:
        Plays a given note for a specified number
        of beats.

        Note: Length must be given in fraction form,
        not decimal form

        Note: This method assumes Length is given
        in terms of beats, not measures, where a
        beat is a quarter note.
  }}
  Cog := cognew(generateFrequency(Pin, Note), @StackSpace) ' Remember which cog was being used
  WaitLength := calculateWait(Length) ' How long do we wait?
  waitcnt(cnt + WaitLength) ' Wait for the note to end
  cogstop(Cog)  ' Stop playing the note

A problem I see that might arise is if it takes longer to calculate the wait length than the note is supposed to be playing for. I don’t think this will be a big problem though since the cog is pretty quick and the notes aren’t really that fast, so for now I think it will be OK.

The biggest difficulty I had was figuring out exactly how long to play the note for. After working on it for a while, I did a little unit elimination to figure it out. Namely, CLK pulses/second * 60 seconds/1 minute * 1 minute / 120 beats * 1 beat = CLK/2 pulses / beat. That will give the length of time for a quarter note. After that, multiply that number by the number of beats to play.

PUB calculateWait(Length) | BaseLength
  ' A quarter note is one beat long
  if Length == 1/8              ' Thirty-Second Note
    return CLKFREQ * 60 / BPM / 8
  elseif Length == 1/4          ' Sixteenth Note
    return CLKFREQ * 60 / BPM / 4
  elseif Length == 1/2          ' Eight Note
    return CLKFREQ * 60 / BPM / 2
  elseif Length == 1            ' Quarter Note
    return CLKFREQ * 60 / BPM
  elseif Length > 1             ' Multiple Quarter Notes
    return CLKFREQ * 60 / BPM * Length

I ran into some problems with division, so I put anything shorter than a quarter note into an if statement. Anything longer than a quarter note can be handled normally since its length is greater than one.

Putting those three sections of code together, I can now play a chromatic scale like so:

CON
  ' Define constants for each note
  ANote = 220
  AShNote = 233
  BNote = 247
  CNote= 261
  CShNote = 277
  DNote = 293
  DshNote = 311
  ENote = 329
  FNote = 349
  FShNote = 367
  GNote = 392
  GShNote = 415
PUB main
  DIRA~~ ' Configure the I/O as output
  ' Play the chromatic scales as eighth notes, finishing with quarter note
  playNote(CNote, 0, 1/2)
  playNote(CShNote, 0, 1/2)
  playNote(DNote, 0, 1/2)
  playNote(DShNote, 0, 1/2)
  playNote(ENote, 0, 1/2)
  playNote(FShNote, 0, 1/2)
  playNote(GNote, 0, 1/2)
  playNote(GShNote, 0, 1/2)
  playNote(ANote * 2, 0, 1/2) ' Multiply the note by 2 to go up an octave
  playNote(AShNote * 2, 0, 1/2)
  playNote(BNote * 2, 0, 1/2)
  playNote(CNote * 2, 0, 1

This code defines the proper frequencies for each musical note on the scale as constants. Then to switch octaves, I can just multiply or divide the note by a constant to change the octave. Pretty cool huh?

Doing this music program was a lot of fun. I think it has a lot of potential to be improved too. I played around trying to play chords to no avail, but I think that might be because my speaker is so crappy. Ideally, I could write a program to automatically do chords and all the cog management for me. I think the next step will be to program some common songs into the Propeller. I always have been a fan of “Twinkle, Twinkle,” so maybe that’s where I’ll start…

Happy new year everyone!

About samkerr

I'm an eclectic person. I like to dabble in a multitude of things. I'm sure you'll find my blog reflects that.
This entry was posted in Code, microcontroller, Science and tagged , , . Bookmark the permalink.

3 Responses to Websites, Propellers, and Sweet Music!

  1. Pingback: Homemade MIDI Controller! | Rants, Rambles, and Rhinos

  2. venkatesh says:

    please tell me about the speaker. i have done all coding ,but speaker pins how to connect them to FPGA pins where can i get it? reply me with a email as soon as possible please….

  3. samkerr says:

    Speakers create a sound by oscillating at a specific frequency, which defines the sound you hear. In terms of a circuit, you can do this by oscillating an I/O line at whatever frequency you want. Try oscillating at 220Hz for a C note. You can do this by turning the I/O pin on, sleeping for a bit, turning it off, sleeping again, and repat.

    Hope that helps!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>