-- MGCInts library -- this imports most modules except those in util local MGCInts = require "mgcints" -- create a default engine with 2 channels local engine = MGCInts.Default.Engine(2, "key scale test") local macros = engine:getCommandTable() local builder = MGCInts.MML.CmdBuilder() -- i took 3-4 hours to make this (optional arguments not shown) local notelist = engine:importFeature "keyscale" -- build some dummy commands for k, v in notelist() do local cmd = builder:setHandler(function (ch) -- calling getNoteIndex is all it takes to handle accidentals local n = ch.key:getNoteIndex(k) ch:addChunk((" Note: %d (%s%s)\n"):format( 60 + n, k:upper(), (n > v and "#" or "b"):rep(math.abs(n - v)))) end):make() macros:addCommand(k, cmd) macros:addCommand(k:upper(), cmd) end -- channel header / footer engine.channel:beforeCallback(function (self) self:addChunk("Channel " .. self:getID() .. ": \n") end) engine.channel:afterCallback(function (self) self:addChunk "End of data\n\n" end) -- test inserter, we will use a text file engine:setInserter(function (rom, song, track) rom:write("MGCInts test\nTrack: " .. track .. "\n\n") song:doAll(function (ch) rom:write(ch:getStream():build()) end) end) -- compile an MML string local mmlstr = [[ !1 k-bea efgab k=a gab k+a a !2 _c+ c _c+ c | c _c+ c _c=- c ]] MGCInts.Music.Compiler.processFile(engine, mmlstr, io.stdout, 1) -- k: key signature, applies sharps/flats to list of notes -- _: accidental, applies sharps/flats on top of key signatures -- |: bar line, resets accidentals but keeps keys --[[ output: MGCInts test Track: 1 Channel 1: Note: 63 (Eb) Note: 65 (F) Note: 67 (G) Note: 68 (Ab) Note: 70 (Bb) Note: 67 (G) Note: 69 (A) Note: 70 (Bb) Note: 70 (A#) End of data Channel 2: Note: 61 (C#) Note: 62 (C##) Note: 60 (C) Note: 61 (C#) Note: 59 (Cb) End of data ]]