Welcome to SMCore documentation
by Sylvain MachefertTable of contents
- What is SMCore?
- About the documentation
- How to use SMCore in your scripts?
- Quick start
- Version history
- About the author
What is SMCore?
SMCore is a set of functions and classes written in Lua 4.0 / MyrScript, the scripting language embedded in Harmony Assistant, music software created by Myriad Software,
Current version is: 20250501.
Update announcements are published in
this topic on Myriad forum.
Use this topic for bug report, suggestions, questions.
Special thanks go to Danièl Frouvelle
who published a lot of scripts, helped me to start in MyrScript dev, and whose source code is old-school hard-coded but efficient.
This gives me idea of "industrialize" button creation in dialog interface,
an then I could go further into more complex componants
such as Slider, Spinner and Grid.
SM are my initials, and Core means that these libraries are usable in all my scripts, and shared here for others scripts creators.
Here is the list of .mys files that will be installed into Scripts/Includes directory.
You don't have to modify them, unless you are crazy developper and want to help me fix a bug.
- SMUtils.mys:
Probably the first and only one you need to include. It includes: MSDefine, SMJavaCollections, SMLogger, SMStrings, SMTables and SMTheory.
It contains unsorted but essential functions for manipulating MyrScript objects such as Target or Dynamic, start play from a bar...
Also essential, all assertions functions to protect your scripts, see Assertions section.
And more! - SMCore.mys: run once after SMCore update, performs unit tests (ensure that new version won't break old results). Tests can print a lot in console.
- SMCore-Updater.mys: check and update SMCore.
- SMCSV.mys: read and write CSV files, use table, Collection and Map.
- SMDialog.mys:- create user interface like Danièl, but easier, and add complex components. Assist you in translating the user interface.
- SMGraph.mys: simplify picture and text drawings and polygon creation for Graph, Surface operations...
- SMInstruments.mys:
instrument or sound picker (selector), instrument properties.
Visit the online instrument database to explore informations you can obtain in this file.
Note that it's still under development. - SMJavaCollections.mys:
a rewrite of Java's Collection and Map, with essential features.
- Collection is a table that can perform sort, search, insert and delete, unique. They are browsable in ascending or descending order.
- Map is an association between key and value. Key is guaranteed to be unique, and is backed by a Collection. One key has one value, they can't be nil.
- SMLexicon.mys:
extends
Dialog.Translate
. - SMLogger.mys:
allow you to print debug, info, warning or error message into Console or into a log file.
By default, debug is only printed when writing your script, info, warn and error are always.
Don't worry anymore of leftprint("debugging message")
when your scripts are published! - SMMenu.mys: create menus in your script, for a multiple or single choice, or fully customized multi-level menu with switches and functio calls.
- SMStrings.mys: useful string manipulation functions.
- SMStructureReader.mys: read (a bit in a wild manner) some textual .cfg files of Harmony, e.g. keyboards (.kbd files)
- SMTheory.mys: Chord and Interval objects that understand chords, calculate notes of an interval... All about solfege goes here.
- other files are:
- interfaces (.myc) used by some functions,
- Translations (*lex*.txt)
- Internal use for new version download, unit tests.
About the documentation
This documentation is generated from the source code by a home made program, inspired by luadoc syntax. Even for me, it's easier to read and navigate this HTML version than open all my files and read the comments! 😊
Types
Lua native types are nil, string, number, table and function.
In the documentation, I added int when a number is expected to be an integer.
This is not Lua standard, but may help you in reading. Integer are often used by constants, such as FACE_BOLD
,
ALIGN_RIGHT
, INSTR_VIOLIN
, or can refer to a table index,
a char in a string (e.g. strsub("my string", a, b)
, a MIDI note pitch...
number reflects a possible decimal value like a frequency (in Hz), a percentile...
Lua has no real boolean, true
= 1 and false
= 0, they are numbers, but when an argument
is expected to be a boolean, his type is: boolean.
MyrScript objects have a small Harmony Assistant icon, e.g.: Dialog, Score, Staff.
SMCore Objects have a "C" icon, for Class: CSV, Interval, SMDialog, Collection.
SMCore table structures have their own icon too: Dialog.UserTable, Component, Grid.
Navigate the documentation
Left navigation pane
- Files show the content of each file: constants, classes, global functions.
- Classes and Tables show their fields and functions.
- Sections are convenient indexes that group together functions related to the same item, MyrScript object, or feature,
e.g. Staves, Play, Strings, Tables..., even if they are not in the same file.
A function can be present in more than one section
How to use SMCore in your scripts?
Copy/past this code at the beginning of your script, or in the function Init(dialog)
of floatting window or interface composer file
-- download/update SMCore Include "SMCore-Updater" SMCoreRequireVersion(20250501)
SMCoreRequireVersion(20250501)
download all SMCore files if needed (never downloaded or outdated)
and then performs unit tests that may print a lot in Console.
It's done only once per version released. If you see error message in the Console, please report the issue in this forum topic.
When I'll submit updates and bugfix, the version number 20250501
to write as argument will change, you'll see it on top of this page and in the forum topic.
Other scripts that require an older version of SMCore don't need this light change, I'll do my best to keep compatibility.
After this, your script continues.
Include files you need. You can include first SMUtils add an IncludeOnce(...)
function
that optimize including of file, avoid double inclusion that may consume CPU if included file perform heavy tasks..
Example:
Include "SMUtils" IncludeOnce("SMDialog")
Notes:
- the parenthesis required for
IncludeOnce(...)
and not forInclude "SMUtils"
. - When you
Include "SMUtils"
, MSDefine, SMJavaCollection, SMLogger, SMLexicon, SMStrings and SMTheory are also included. These are quite light, and massively used everywhere in the library. - SMMenu, SMDialog and the heavy SMInstruments are not included, as most of your scripts won't require them.
- SMInstruments is so heavy that it takes 40 seconds in debug mode to load, displaying a progress bar, plus 20 secondes to build a cache.
Next loads in debug mode take 10 seconds. Cache is rebuild if you change language settings and at SMCore updates.
In Run mode, first load is about 1 second, and cache load is around 50 milliseconds.
Quick start
Collection
Unsorted collection
-- create an unsorted Collection. -- Elements are stored in the insertion order local fruits = Collection:new() fruits:add("banana") fruits:add("apple") print(fruits:contains("apricot")) --> nil or false print(fruits:indexOf("apple")) --> 2 fruits:insert("banana") -- allow multiple bananas print(fruits:lastIndexOf("banana")) --> 3 print(fruits:remove("cherry")) --> 0, there were no cherry in Collection -- Browse fruits:iterator() while fruits:hasNext() do print(fruits:next()) end --> banana, apple, banana
Set: a collection of unique elements
local set = Collection:new("string", true)
Sorted set: unique elements are sorted
local sortedSet = Collection:new("string", true, SORT_ASCENDING)
Elements are typed
Like in Java, I appreciate to have typed element,
i.e. if I expect strings, it throws an error when inserting something else,
else it's a nightmare to debug.
A special value "mixed"
is available, but here it's intentional and you have to check the type
of each item before performing string functions, number for arithmetics...
Here is a sorted set of numbers:
local numbers = Collection:new("number", true, SORT_ASCENDING) --numbers:add(3.14); numbers:add(1); numbers:add(-1.234) numbers:add(3.14, 1, -1.234) -- equivalent to above commented line numbers:debug() --> print a nice structure showing that the collection is sorted
Map
A Map of number keys associated with string values
local numbers = Map:new("number", "string", SORT_ASCENDING) numbers:put(3.14, "pi") numbers:put(1.41, "sqrt(2)") numbers:put(-3.14, "-pi") numbers:put(12, "carbone") numbers:put(14, "carbone") print(numbers:containsKey(1.41)) --> true print(numbers:containsKey(13) --> nil or false numbers:containsValue("pi") --> true print(numbers:get(12)) --> "carbone" print(numbers:firstKey()) --> -3.14, the lowest number -- iterate over the keys local ks = numbers:keySet() ks:iterator() while ks:hasNext() do print(ks:next()) end --> -3.14, 1,41, 3.14, 12, 14 -- iterate over values, in the same order of the keys local v = numbers:values() v:iterator() while v:hasNext() do print(v:next()) end --> -pi, sqrt(2), pi, carbone, carbone -- iterate over entries (key,value) numbers:iterator() while numbers:hasNext() local k,v = numbers:next() -- print or whatever you want end numbers:remove(12)
CSV file read and write
Only write and read strings. Number can be converted using tonumber(...)
if needed.
local csv = CSV:new("file.csv", "w") csv:writeHeader("ID"); csv:writeHeader("Name") -- write using a standard table csv:writeLine({"42","Sylvain"}) -- write using a Collection local data = Collection:new("string") data:add("123"); data:add("Didier") csv:writeLine(data) -- write using a Map data = Map:new("string", "string") data:put("ID", "456"); data:put("Name", "Olivier") csv:writeLine(data) csv:close() -- important! -- And now, read! local csv2 = CSV:new("file.csv", "r") -- Reading row by row data = csv2:readLine() while data~=nil do data:print() local id,name = data:get("ID"), data:get("Name") data = csv2:readLine() end csv2:close()
SMDialog
See SMDialog for minimal code to copy/past in your floatting window or interface composer
Version history
2025-05-01 (HA v9.9.9e):
- Functions for Targets (rehearsal marks).
- CopyOrnaments: portamento wasn't copied.
- MidiGetEventFiltered function optimization for
Midi.GetEvent
- SMDialog: Midi navigation and value change using pitch bend and controllers from hardware
- SMDialog and menu: minor accessibility fixes.
- Stopwatch class
TableToElements(table)
replacement for bogus MSLibraryPushAllTableElts(table)
,
and its counterpartElementsToTable(...)
- Reflection functions.
BinNot(...)
bitwise NOT operation, and conversions to/from hexadecimal and binary numbers greater than 32-bit.- INI file read and write
- Bars utility functions for global bar settings, splitting, bar numberings
2025-01-24 (HA v9.9.9):
- SMCore is now included at Harmony Assistant v9.9.9 install.
- Collection and Map:
- code optimizations and more precise type-protection,
- plain text search and regexp search
- Map:removeAll(...)
- 540+ instruments in database
- SMDialog components:
OnInit(...)
andOnExit(...)
events to open and close resources.- new Switchable component: checkbox, radio or switch
- new Knob component: resizable and accessible knobs
Lexicon:addEntries(...)
for simple script with few entries that won't require small lex_*.txt files.- Free objets functions:
CopyFreeObjects(...)
,InsertReservedPages(...)
,DeleteReservedPages(...)
- Serialization/Deserialization (kind of JSON for Lua) and class introspection,
- Batch processing mechanism
2024-09-14
- Menu: a switch change can be stopped (e.g. by a confirmation rejected).
- Ternary
IF(expr, a, b)
andtable_insert_multi(myArray, data1, data2)
function. - Function for StavesGroup:
GetStavesGroup(score[, staff])
,ChooseStavesGroup(...)
. - JumpAndSelectBar: a better replacement to
score.JumpToBar(...)
. - Lexicon: a default language can be forced to French e.g. if a script is not translated in Spanish when HA interface is in Spanish, when French is more understood than English.
- Score appearance (display setup): load and save settings
GetFilesInfolder(...)
: a fixed and simplified version ofBrowseFolder(...)
.- XYSlider: improved value rounding, fixed axis position and keyboard interactions.
- XYSlider: added a mask to display values with unit or other words instead of raw x, y values.
2024-08-25
- SMInstruments: bug fix when Gold Base II is not the current sound base.
- SMInstruments: database improvement, string courses, ranges, and more instruments.
- SMGraph:
CropSurface(...)
. - SMDialog: XYSlider, 'buttons' renamed to 'components' in docs and function names.
- SMMenu.
- Various Inputs:
ChooseFont(...)
,ChooseStaves(...)
... - SMUtils: boolean operations, flags.
2023-11-30: major release
IncludeOnce(...)
avoid CPU comsuptions whenInclude(...)
multiple time a heavy script.- Durations conversions: 256th of quarter to milliseconds, milliseconds to % of a note, etc...
- GetDynamicsThatApplyToStaff: dynamics may apply to merged staves, group, or whole score. So which ones apply to a specified staff?
- Collection now accept sorting function for table, but still can't guarantee unicity.
- SMGraph:
DrawPicture(...)
(demo script) - SMGraph:
DrawText(...)
- SMDialog: Grid is now functionnal (demo script)
- SMDialog: Spinner, a component that act like a menu or a list, but use less space, display 2 arrows for previous/next value, and accept mouse scroll
- SMInstruments: Beta version of a database about instruments, classifications (orchestra, midi, alphabetic...) and their related sound
- SMInstruments: Beta version of a picker to choose an instrument or a sound
- SMTheory: music theory (solfege), Chord and Interval objects
- SMUtils: assertion functions: easily protect argument and throw understable standadirzed error messages
- SMLogger: old logs (more than 30 days) are removed from log files
2022-11-10
- Documentation has been moved here and improved.
- SMDialog: keyboard navigation
- SMDialog: added Slider and preview of Grid
2022-06-16
- First version of SMDialog
- Added switch case functions, more for educational purpose than real use
- Collection and Map simultaneous (concurrent) iterators
2022-05-26
- First documentation
- argument checks
- Removed debugs in Collection:retainsAll(...)