Main tab part 1/1:
--
-- Sample how to play a note by name
-- =================================
--
-- The central formula can calculate the StartFrequency
-- (between 0.0 and 1.0) for
-- the sound function from a half-tone stepping. Calculation
-- used from ABCplayer. Thanks @Fred and the others who found
-- that formula :-)
--
-- The magic calculation formula:
-- f = 440*2^((halfSteps-69)/12)
-- startFrequency = math.sqrt(f/44100*100/8-0.001)
--
-- halfSteps is the number of half steps which our note has
-- from the base. If it is 0, then it plays C0.
--
-- Now in the calcHalfStepsFromNote you can pass a string that
-- contains a note (CDEFGAH), an octave (0 to 8) and
-- an accidental (# or b) which changes the note by a halfstep
-- up or down. The function then uses a lookup table to
-- find the number of half steps for the note, multiplies the
-- octave by 12 and then sums all up. The result is
-- used as halfSteps input in the above formula.
--
-- Have fun,
-- Kilam Malik.
curNote = "C"
curOctave = "3"
curAccidental = ""
baseNr = -1
octaveNr = -1
accidentalNr = -1
frequency = -1
codeaFrequency = -1
buttonsNotes = {}
buttonsOctaves = {}
buttonsAccidentals = {}
buttonPlay = nil
-- cdefgah but sorted by alphabet for quick calc a-cdefgh:
baseNoteLookup = { 9, -1, 0, 2, 4, 5, 7, 11 }
displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)
function calcHalfStepsFromNote(note)
local base
local octave
local accidental
if string.len(note) == 2 then
base = string.lower(string.sub(note, 1, 1))
octave = string.sub(note, 2, 2)
accidental = ""
elseif string.len(note) == 3 then
base = string.lower(string.sub(note, 1, 1))
octave = string.sub(note, 2, 2)
accidental = string.lower(string.sub(note, 3, 3))
else
return 0
end
charNr = string.byte(base) - string.byte("a")
baseNr = baseNoteLookup[charNr + 1]
octaveNr = tonumber(octave) + 1
if accidental== "#" then
accidentalNr = 1
elseif accidental == "b" then
accidentalNr = -1
else
accidentalNr = 0
end
local halfTones = octaveNr * 12 + baseNr + accidentalNr
return halfTones
end
function buttonNoteClicked(note)
curNote = note
-- Deselect all other buttons in group... have to make a
-- button group class in the future to do this handling:
for i = 0, table.maxn(buttonsNotes) do
if buttonsNotes[i] == nil then
else
buttonsNotes[i].selected = false
end
end
end
function buttonOctaveClicked(octave)
curOctave = octave
-- Deselect all other buttons in group... have to make a
-- button group class in the future to do this handling:
for i = 0, table.maxn(buttonsOctaves) do
if buttonsOctaves[i] == nil then
else
buttonsOctaves[i].selected = false
end
end
end
function buttonAccidentalClicked(accidental)
curAccidental = accidental
-- Deselect all other buttons in group... have to make a
-- button group class in the future to do this handling:
for i = 0, table.maxn(buttonsAccidentals) do
if buttonsAccidentals[i] == nil then
else
buttonsAccidentals[i].selected = false
end
end
end
function buttonPlayClicked(id)
local halfSteps = calcHalfStepsFromNote(curNote .. curOctave .. curAccidental)
frequency = 440*2^((halfSteps-69)/12)
codeaFrequency = math.sqrt(frequency/44100*100/8-0.001)
instrument = {Waveform = Waveform, StartFrequency = codeaFrequency, AttackTime = AttackTime, SustainPunch = SustainPunch, DecayTime = DecayTime}
sound(instrument)
--encStr = sound( ENCODE, instrument )
--print(encStr)
--sound(DATA, encStr)
end
function createButton(name, x, y, w, h, btype, callback)
local btnImgPressed = image(70, 70)
setContext(btnImgPressed)
fill(200, 200, 200, 255)
rect(0,0,w,h)
fill(121, 225, 162, 255)
rect(5,5,w-10,h-10)
fill(0, 0, 0, 255)
textMode(CENTER)
text(name, w/2, h/2)
fill(255, 255, 255, 255)
text(name, w/2-1, h/2+1)
setContext()
local btnImgNormal = image(w, h)
setContext(btnImgNormal)
tint(255, 255, 255, 127)
sprite(btnImgPressed, w/2, h/2, w, h)
noTint()
setContext()
if btype == 0 then
b = Button(name, x, y, w, h, btnImgPressed, btnImgPressed, btype, callback)
else
b = Button(name, x, y, w, h, btnImgNormal, btnImgPressed, btype, callback)
end
return b
end
function setup()
local b
-- Create note buttons:
b = createButton("C", 50, HEIGHT-50, 70, 70, 1, buttonNoteClicked)
b.selected = true
table.insert(buttonsNotes, b)
b = createButton("D", 150, HEIGHT-50, 70, 70, 1, buttonNoteClicked)
table.insert(buttonsNotes, b)
b = createButton("E", 250, HEIGHT-50, 70, 70, 1, buttonNoteClicked)
table.insert(buttonsNotes, b)
b = createButton("F", 350, HEIGHT-50, 70, 70, 1, buttonNoteClicked)
table.insert(buttonsNotes, b)
b = createButton("G", 450, HEIGHT-50, 70, 70, 1, buttonNoteClicked)
table.insert(buttonsNotes, b)
b = createButton("A", 550, HEIGHT-50, 70, 70, 1, buttonNoteClicked)
table.insert(buttonsNotes, b)
b = createButton("H", 650, HEIGHT-50, 70, 70, 1, buttonNoteClicked)
table.insert(buttonsNotes, b)
-- Create octave buttons:
b = createButton("0", 50, HEIGHT-150, 70, 70, 1, buttonOctaveClicked)
table.insert(buttonsOctaves, b)
b = createButton("1", 150, HEIGHT-150, 70, 70, 1, buttonOctaveClicked)
table.insert(buttonsOctaves, b)
b = createButton("2", 250, HEIGHT-150, 70, 70, 1, buttonOctaveClicked)
table.insert(buttonsOctaves, b)
b = createButton("3", 350, HEIGHT-150, 70, 70, 1, buttonOctaveClicked)
b.selected = true
table.insert(buttonsOctaves, b)
b = createButton("4", 450, HEIGHT-150, 70, 70, 1, buttonOctaveClicked)
table.insert(buttonsOctaves, b)
b = createButton("5", 550, HEIGHT-150, 70, 70, 1, buttonOctaveClicked)
table.insert(buttonsOctaves, b)
b = createButton("6", 650, HEIGHT-150, 70, 70, 1, buttonOctaveClicked)
table.insert(buttonsOctaves, b)
b = createButton("7", 750, HEIGHT-150, 70, 70, 1, buttonOctaveClicked)
table.insert(buttonsOctaves, b)
-- Create accitental buttons:
b = createButton("", 50, HEIGHT-250, 70, 70, 1, buttonAccidentalClicked)
b.selected = true
table.insert(buttonsAccidentals, b)
b = createButton("#", 150, HEIGHT-250, 70, 70, 1, buttonAccidentalClicked)
table.insert(buttonsAccidentals, b)
b = createButton("b", 250, HEIGHT-250, 70, 70, 1, buttonAccidentalClicked)
table.insert(buttonsAccidentals, b)
-- Create play button:
buttonPlay = createButton("Play", 50, HEIGHT-350, 70, 70, 0, buttonPlayClicked)
end
function touched(touch)
for i = 0, table.maxn(buttonsNotes) do
if buttonsNotes[i] == nil then
else
buttonsNotes[i]:touched(touch)
end
end
for i = 0, table.maxn(buttonsOctaves) do
if buttonsOctaves[i] == nil then
else
buttonsOctaves[i]:touched(touch)
end
end
for i = 0, table.maxn(buttonsAccidentals) do
if buttonsAccidentals[i] == nil then
else
buttonsAccidentals[i]:touched(touch)
end
end
buttonPlay:touched(touch)
end