______ / | ________ / |____ / \ / | \/ _ \ \ ___ /_\ \ \ \_/ . \ \ /\_____/ / \________/ | / |______/
Lullaby_in.c Part 3
Edit: replaced int(reg) with int(round(reg)). Not that it should have any noticeable sound differences, but it’s a bit more accurate.
Resuming.
In order to play a scale, I needed notes. But the GBA sound chip has no clue what a note is, it just want to be fed with the right register value to control the frequency of a specific channel. The register value can be calculated with 2048 – 4194304 / (32 * frequency), then converted to hexadecimal. So far I calculated this manually to get a few octaves of C and G notes.
In order to play several scales, I need now much more notes and I’m not going to calculate them all by hand, nor make the poor GBA CPU do that in real-time every time a note needs to be played.
So it’s time for some high-level laziness:
#!/usr/bin/env python notes = [["C",65.406],["CH",69.296],["D",73.416],["DH",77.782], ["E",82.407],["F",87.307],["FH",92.499],["G",97.999], ["GH",103.826],["A",110],["AH",116.541],["B",123.471]] def makeHex(freq): reg = 2048-(4194304/(32*freq)) regHex = "{0:#0{1}x}".format(int(round(reg)),6) return regHex def makeArray(note,freq): i = 0 array = "int "+note+" [6] = {" while i < 6: array += makeHex(freq*pow(2,i))+"," i += 1 return array[:-1]+"};" for note in notes: print makeArray(note[0],note[1])
This thing will produce the following that I can then nicely paste in my C code, Ô pythonesque joy and wonders:
int C [6] = {0x002c,0x0416,0x060b,0x0706,0x0783,0x07c1}; int CH [6] = {0x009d,0x044e,0x0627,0x0714,0x078a,0x07c5}; int D [6] = {0x0107,0x0483,0x0642,0x0721,0x0790,0x07c8}; int DH [6] = {0x016b,0x04b5,0x065b,0x072d,0x0797,0x07cb}; int E [6] = {0x01c9,0x04e5,0x0672,0x0739,0x079d,0x07ce}; int F [6] = {0x0223,0x0511,0x0689,0x0744,0x07a2,0x07d1}; int FH [6] = {0x0277,0x053b,0x069e,0x074f,0x07a7,0x07d4}; int G [6] = {0x02c7,0x0563,0x06b2,0x0759,0x07ac,0x07d6}; int GH [6] = {0x0312,0x0589,0x06c4,0x0762,0x07b1,0x07d9}; int A [6] = {0x0359,0x05ad,0x06d7,0x076c,0x07b6,0x07db}; int AH [6] = {0x039b,0x05ce,0x06e7,0x0773,0x07ba,0x07dd}; int B [6] = {0x03da,0x05ed,0x06f7,0x077b,0x07be,0x07df};
Then I guess I can find a way to assign the tonic and dominant notes on the fly depending on the selected scale… Mmmm… we’ll see about that in the next part I suppose.
Leave a Reply