______
/ | ________
/ |____ / \
/ | \/ _ \
\ ___ /_\ \
\ \_/ . \
\ /\_____/ /
\________/ | /
|______/
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