{"id":18084861,"url":"https://github.com/coderofsalvation/asciistep16","last_synced_at":"2025-04-06T00:13:23.456Z","repository":{"id":192019098,"uuid":"685885448","full_name":"coderofsalvation/ASCIISTEP16","owner":"coderofsalvation","description":"ASCIISTEP16 specification which allows pckeyboards to act as 16-step music-sequencers","archived":false,"fork":false,"pushed_at":"2023-09-01T08:50:22.000Z","size":25,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-12T06:21:42.552Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Nix","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/coderofsalvation.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-09-01T08:28:44.000Z","updated_at":"2024-08-14T13:35:30.000Z","dependencies_parsed_at":"2023-09-02T04:31:24.144Z","dependency_job_id":null,"html_url":"https://github.com/coderofsalvation/ASCIISTEP16","commit_stats":null,"previous_names":["coderofsalvation/asciistep16"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coderofsalvation%2FASCIISTEP16","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coderofsalvation%2FASCIISTEP16/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coderofsalvation%2FASCIISTEP16/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coderofsalvation%2FASCIISTEP16/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/coderofsalvation","download_url":"https://codeload.github.com/coderofsalvation/ASCIISTEP16/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247415976,"owners_count":20935387,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-31T15:08:26.973Z","updated_at":"2025-04-06T00:13:23.431Z","avatar_url":"https://github.com/coderofsalvation.png","language":"Nix","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n  \n  \u003cmeta name=\"GENERATOR\" content=\"github.com/mmarkdown/mmark Mmark Markdown Processor - mmark.miek.nl\"\u003e\n  \u003cmeta charset=\"utf-8\"\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n\n\u003c!-- for annotated version see: https://raw.githubusercontent.com/ietf-tools/rfcxml-templates-and-schemas/main/draft-rfcxml-general-template-annotated-00.xml --\u003e\n\n\u003ch1 class=\"special\" id=\"abstract\"\u003eAbstract\u003c/h1\u003e\n\n\u003cp\u003eASCIISTEP16 is pckeyboard standard \u0026amp; translation of popular hardware 16-step drum/midisequencers (electribe MX, electribe SX, mc303, tr909,tr808, mc707, arturia beatstep).\nThe goal of ASCIISTEP16 is to offer a pckeyboard mode (usually for tracker software) which allows music software to use pckeyboard-keys as music-stepsequencer keys.\u003c/p\u003e\n\u003csection data-matter=\"main\"\u003e\n\u003ch1 id=\"what-is-asciistep16\"\u003eWhat is ASCIISTEP16\u003c/h1\u003e\n\n\u003cp\u003e\u003cimg src=\"https://i.imgur.com/mDsOXqt.png\" style=\"width:60%\"/\u003e\u003c/p\u003e\n\n\u003cp\u003eThe goal of ASCIISTEP16 is to offer a pckeyboard mode (usually for tracker software) which:\u003c/p\u003e\n\n\u003cul\u003e\n\u003cli\u003ecan act as a substitute for a hardware stepsequencer (on a pckeyboard)\u003c/li\u003e\n\u003cli\u003eallows \u0026lsquo;grid\u0026rsquo;-like liveperformance on pckeyboards\u003c/li\u003e\n\u003cli\u003eallows people coming from the hardware stepsequencer scene to easily use ASCIISTEP16 compatible music-software\u003c/li\u003e\n\u003cli\u003eallows any unix character-device, or implementation to send 16 stepsequencer-buttons over ascii\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003ch1 id=\"implementations\"\u003eImplementations\u003c/h1\u003e\n\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/coderofsalvation/MilkyTrackerX\"\u003eMilkyTracker X-build\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003eplease comment on this gist if your software implements ASCIISTEP16\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch1 id=\"translation-table\"\u003eTranslation table\u003c/h1\u003e\n\n\u003cp\u003eThe table below focuses on QWERTY keyboards, but other keyboard layouts can follow the exact same logic of using the first 2x8 (rows-x-cols) alphabet keys (see image above).\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003ethe uppercase character is preferred (\u0026lsquo;Q\u0026rsquo; instead of \u0026lsquo;q\u0026rsquo; e.g.) to not interfere with normal keymappings of the software.\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003estep\u003c/th\u003e\n\u003cth\u003echaracter\u003c/th\u003e\n\u003cth\u003ecomment\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e0\u003c/td\u003e\n\u003ctd\u003eQ\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e1\u003c/td\u003e\n\u003ctd\u003eW\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e2\u003c/td\u003e\n\u003ctd\u003eE\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e3\u003c/td\u003e\n\u003ctd\u003eR\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e4\u003c/td\u003e\n\u003ctd\u003eT\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e5\u003c/td\u003e\n\u003ctd\u003eY\u003c/td\u003e\n\u003ctd\u003einternational equivalent \u0026lsquo;Z\u0026rsquo; e.g.\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e6\u003c/td\u003e\n\u003ctd\u003eU\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e7\u003c/td\u003e\n\u003ctd\u003eI\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e8\u003c/td\u003e\n\u003ctd\u003eA\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e9\u003c/td\u003e\n\u003ctd\u003eS\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e10\u003c/td\u003e\n\u003ctd\u003eD\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e11\u003c/td\u003e\n\u003ctd\u003eF\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e12\u003c/td\u003e\n\u003ctd\u003eG\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e13\u003c/td\u003e\n\u003ctd\u003eH\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e14\u003c/td\u003e\n\u003ctd\u003eJ\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e15\u003c/td\u003e\n\u003ctd\u003eK\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003echannel/track\u003c/th\u003e\n\u003cth\u003eascii key for muting/selecting\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e1\u003c/td\u003e\n\u003ctd\u003e\u0026lsquo;1\u0026rsquo;\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e2\u003c/td\u003e\n\u003ctd\u003e\u0026lsquo;2\u0026rsquo;\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e3\u003c/td\u003e\n\u003ctd\u003e\u0026lsquo;3\u0026rsquo;\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e4\u003c/td\u003e\n\u003ctd\u003e\u0026lsquo;4\u0026rsquo;\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e5\u003c/td\u003e\n\u003ctd\u003e\u0026lsquo;5\u0026rsquo;\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e6\u003c/td\u003e\n\u003ctd\u003e\u0026lsquo;6\u0026rsquo;\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e7\u003c/td\u003e\n\u003ctd\u003e\u0026lsquo;7\u0026rsquo;\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e8\u003c/td\u003e\n\u003ctd\u003e\u0026lsquo;8\u0026rsquo;\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e9\u003c/td\u003e\n\u003ctd\u003e\u0026lsquo;9\u0026rsquo;\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e10\u003c/td\u003e\n\u003ctd\u003e\u0026lsquo;0\u0026rsquo;\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e11\u003c/td\u003e\n\u003ctd\u003e\u0026rsquo;-\u0026rsquo;\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e12\u003c/td\u003e\n\u003ctd\u003e\u0026rsquo;=\u0026rsquo;\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003ch2 id=\"example-implementation-in-c-c\"\u003eExample implementation in C/C++\u003c/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003e/* \n  example usage: \n\t  int stepsize = trackerGridSettings.getStepIncrement();                        // optional: allow variable stepsizes\n\t  int bar      = cursor.row / (16*stepsize);\n\t  int steprow  = ASCIISTEP16(character,bar) * stepsize;\n\t  int ch       = ASCIISTEP16_channel(character);                                // ctrl +1 jumps to ch 1 (cursor)\n\t  if( ch      != -1 ) muteOrSelectChannel( ch, CTRLpressed() );                 // shift+1 (un)mutes ch 1\n\t  if( steprow != -1 ) writeNote( 'c-4', steprow, getCurrentChannel() );         // write step\n\t  else writeNote( lowercaseKeyToNote(i), getCursorRow(), getCurrentChannel() ); // write keyjazz note\n*/\n\nint ASCIISTEP16(char ascii, unsigned int bar)\n{\n\tint number = -1;\n\tswitch (ascii)\n\t{\n\t\t// ASCIISTEP16 standard (https://gist.github.com/coderofsalvation/8d760b191f4bb5465c8772d5618e5c4b)\n\t\tcase 'Q': number = 0; break;\n\t\tcase 'W': number = 1; break;\n\t\tcase 'E': number = 2; break;\n\t\tcase 'R': number = 3; break;\n\t\tcase 'T': number = 4; break;\n\t\tcase 'Y': number = 5; break;\n\t\tcase 'U': number = 6; break;\n\t\tcase 'I': number = 7; break;\n\t\tcase 'A': number = 8; break;\n\t\tcase 'S': number = 9; break;\n\t\tcase 'D': number = 10; break;\n\t\tcase 'F': number = 11; break;\n\t\tcase 'G': number = 12; break;\n\t\tcase 'H': number = 13; break;\n\t\tcase 'J': number = 14; break;\n\t\tcase 'K': number = 15; break;\n\t}\n\treturn number == -1 ? -1 : number + (bar*16);\n}\n\nint ASCIISTEP16_channel(char ascii)\n{\n\tint number = -1;\n\tswitch (ascii)\n\t{\n\t\t// ASCIISTEP16 standard (https://gist.github.com/coderofsalvation/8d760b191f4bb5465c8772d5618e5c4b)\n\t\tcase '1': number = 0; break;\n\t\tcase '2': number = 1; break;\n\t\tcase '3': number = 2; break;\n\t\tcase '4': number = 3; break;\n\t\tcase '5': number = 4; break;\n\t\tcase '6': number = 5; break;\n\t\tcase '7': number = 6; break;\n\t\tcase '8': number = 7; break;\n\t\tcase '9': number = 8; break;\n\t\tcase '0': number = 9; break;\n\t\tcase '-': number = 10; break;\n\t\tcase '=': number = 11; break;\n\t}\n\treturn number;\n}\n\u003c/code\u003e\u003c/pre\u003e\n\n\u003ch1 id=\"quick-win-trackers-keyjazz-enabled-software\"\u003eQuick win: trackers \u0026amp; \u0026lsquo;keyjazz\u0026rsquo;-enabled software\u003c/h1\u003e\n\n\u003cp\u003eMost trackers already support octave-switching, transposing-selected note(s), and instrument-switching using keyboard shortcuts. This creates very interesting ASCIISTEP16 workflows by simply implementing ASCIISTEP16.\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003eASCIISTEP16 does not interfere with most trackers/keyjazz enabled daws, since the uppercase characters (\u0026lsquo;Q\u0026rsquo; not \u0026lsquo;q\u0026rsquo;) are usually unused (or simply translated to lowercase).\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003eHint: CAPS-LOCK \u0026amp; SHIFT act as an ASCIISTEP16 enable/disable-toggle for free!\u003c/p\u003e\n\n\u003ch1 id=\"bar-pages\"\u003eBar pages\u003c/h1\u003e\n\n\u003cp\u003eMost stepsequencer support multiple bars (for example: the electribes offer 4), which allow for editing longer patterns by repurposing the same 16 step-buttons.\u003c/p\u003e\n\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003ebar page\u003c/th\u003e\n\u003cth\u003estep value\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e0\u003c/td\u003e\n\u003ctd\u003e1,2,3,5,6,7,8,9,10,11,12,13,14,15,16\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e1\u003c/td\u003e\n\u003ctd\u003e17,18,19,20,21,22,23,24,25,26,27\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd\u003e..\u003c/td\u003e\n\u003ctd\u003eand so on\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003eBasically, each stepvalue is relative based on the current bar-page, and evaluated as \u003ccode\u003estepvalue * (page*16)\u003c/code\u003e (page starting at 0).\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch1 id=\"navigating-bar-pages\"\u003enavigating bar pages\u003c/h1\u003e\n\n\u003cp\u003eThe ASCIISTEP16 standard is to use increment/decrement shortcuts to navigate pages:\u003c/p\u003e\n\n\u003cp\u003e*\u003ccode\u003epage-up/down\u003c/code\u003e (to switch to next/previous page, which turns step 1-16 into 17-24 e.g. )\n* and/or \u003ccode\u003earrow up/down\u003c/code\u003e in  \u003ccode\u003epage-down\u003c/code\u003e \u003cstrong\u003ein combination\u003c/strong\u003e with shift/ctrl/alt etc.\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003eThis is easy to implement in 99% of trackers, which already support cursor-navigation.\nSo the implementation is deadsimple to determine \u0026amp; apply the current bar-page:\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cpre\u003e\u003ccode\u003ewhen entering a key ('E' which translates to asciistep16 value 2 e.g.):\n  row = getCurrentRow()\n  bar = row / 16\n  editrow = asciistep16('Q') + (bar*16) // replace 'Q' with user input\n  if( editrow \u0026gt; 0 ) writeNote( note, editrow) // step was entered\n\u003c/code\u003e\u003c/pre\u003e\n\n\u003ch1 id=\"scope-limits\"\u003eScope (limits)\u003c/h1\u003e\n\n\u003cp\u003eASCIISTEP16 v1 is very simple/limited (therefore an easy standard to implement):\u003c/p\u003e\n\n\u003cul\u003e\n\u003cli\u003eASCIISTEP16 focuses on laptop-friendly shortcuts (first 3 alphanumeric rows + CTRL and SHIFT)\u003c/li\u003e\n\u003cli\u003eASCIISTEP16 does not dictate how to change metadata of a step (note-value, volume-value) (see \u003ccode\u003eQuick win\u003c/code\u003e above)\u003c/li\u003e\n\u003cli\u003eASCIISTEP16 does not dictate how to control the transport / clock (start/stop/record) e.g.\u003c/li\u003e\n\u003cli\u003eASCIISTEP16 does not dictate how to change keyboard mappings\u003c/li\u003e\n\u003cli\u003eASCIISTEP16 does not dictate how to toggle/control userinterface elements\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003eMost trackers/daws already have a default way of doing these things, therefore ASCIISTEP16 stay simple to implement. Ideas for ASCIISTEP16-NOTE, ASCIISTEP16-VOLUME, ASCIISTEP16-TRANSPORT extensions are welcome though.\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch1 id=\"contact\"\u003eContact\u003c/h1\u003e\n\n\u003cul\u003e\n\u003cli\u003eleonvankammen|gmail.com\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003ch1 id=\"iana-considerations\"\u003eIANA Considerations\u003c/h1\u003e\n\n\u003cp\u003eThis document has no IANA actions.\u003c/p\u003e\n\n\u003ch1 id=\"acknowledgments\"\u003eAcknowledgments\u003c/h1\u003e\n\n\u003cp\u003eTODO acknowledge.\u003c/p\u003e\n\u003c/section\u003e\n\n\u003c/body\u003e\n\u003c/html\u003e\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoderofsalvation%2Fasciistep16","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoderofsalvation%2Fasciistep16","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoderofsalvation%2Fasciistep16/lists"}