Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

sorrygle

Package Overview
Dependencies
Maintainers
1
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sorrygle

Text-based MIDI-writing language and its compiler

  • 1.3.1-e
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
3
decreased by-40%
Maintainers
1
Weekly downloads
 
Created
Source

Sorrygle

Text-based MIDI-writing language and its compiler

npm npm Discord Website

Introduction

I often chat with my friends via Discord. However, it becomes cumbersome when I want to share a bundle of melody. To do so I had to turn on a notation software (e.g., MuseScore) first, create a new sheet, write the melody, export it to a sound file, and then finally I could do share.

So as to alleviate this nasty time-consuming process, I thought that MML (i.e., Music Macro Language) can be a solution. But I felt disappointment when I realized that MML doesn't support so many sugars such as staccato, sforzando, crescendo, and graces.

Of course MML actually does support some of them (e.g., crescendo), but you know it's too long to write in comfort. For example in crescendo, you must change the volume for every note increasingly in MML.

// Crescendo in MML
L8 V1C V2D V3E V4F V5G V6A V7B V8G >V9C1
// Crescendo in Sorrygle
(q=8) (v=10)<+cdefgabg ^c~~~~~~~90>

The problem becomes bigger when it comes to graces. Assume that a grace note is a 64th note long. Then you must calculate the total length of graces and subtract the value from the length of the main note.

// Graces in MML
L64 G A B^32^16 L8 A G A
// Graces in Sorrygle
(q=8) [>ga]baga

In addition, even if crescendoes and graces can be exist in MML, I couldn't recognize such notations at a glance (this is important). That's why I've defined a new language that can be converted into MIDI files.

Now I'm happy 😊.

Demo

https://sorry.daldal.so/sorrygle

Getting Started

CLI

  1. npm -g install sorrygle
  2. sorrygle "cege[c^c]~~~"
  3. Open output.mid
  4. Cool and good.

Script

  1. npm install sorrygle
import { writeFileSync } from "fs";
import { Sorrygle } from "sorrygle";

console.log(Sorrygle.parse("cege[c^c]~~~")); // This prints the AST of the input.
console.log(Sorrygle.getTimeline("cege[c^c]~~~")); // This prints the timeline of the input.
writeFileSync("./output.mid", Sorrygle.compile("cege[c^c]~~~"));

or

const { writeFileSync } = require("fs");
const { Sorrygle } = require("sorrygle");

console.log(Sorrygle.parse("cege[c^c]~~~")); // This prints the AST of the input.
console.log(Sorrygle.getTimeline("cege[c^c]~~~")); // This prints the timeline of the input.
writeFileSync("./output.mid", Sorrygle.compile("cege[c^c]~~~"));
  1. Open output.mid
  2. Cool and good.

Grammar

  • Integer variable
  • Numeric variable
  • Duration
NotationNameMeaningDefault
((bpm=ⓘ))BPM configurationSet the current BPM to ⓘ.120
((fermata=ⓝ))Fermata configurationSet the length of fermatas to ⓝ. The duration of the note becomes ⓝ times.2
((time-sig=ⓘ/ⓘ))Time signature configurationSet the time signature to ⓘ/ⓘ.4/4
#ⓘChannel declaration(1≤ⓘ≤16) Set the current channel for following input.1
(o=ⓘ)Default octave(0≤ⓘ≤8) Set the default octave for following input.4
(p=ⓘ)Instrument(0≤ⓘ≤127) Set the instrument for following input. You can refer to GM 1 Sound Set for determining the value. Please note that PC# = ⓘ + 1 since ⓘ starts from zero.0
(q=ⓓ)QuantizationSet the default note/rest/tie length for following input.16
(s=ⓘ)Sustain pedal(0≤ⓘ≤127) Set the value of the sustain pedal. It's enabled only if ⓘ≥64.0
(t=ⓘ)TransposeTranspose following input.0
(v=ⓘ)Volume(1≤ⓘ≤100) Set the volume for following input.80
cdefgabNotePlay C, D, E, F, G, A, B in sequence. You can use 도레미파솔라시 instead.
CDFGASharp notePlay C#, D#, F#, G#, A# in sequence. You can use 돗렛팟솘랏 instead.
렢밒솚랖싶Flat notePlay Db, Eb, Gb, Ab, Bb in sequence.
_RestKeep silent. You can use instead.
+Semitone upIncrease the pitch of the preceding note by one semitone. (i.e., c+ = C)
-Semitone downDecrease the pitch of the preceding note by one semitone. (i.e., c- = vb)
~TieIncrease the length of the preceding note. You can use instead.
[ceg]ChordPlay C, E, G at once.
[|ceg]ArpeggioPlay C, E, G rapidly in sequence.
^cOctave upPlay C in one octave higher than the default.
vcOctave downPlay C in one octave lower than the default.
(^ceg)Ranged octave upPlay all notes in the bracket in one octave higher than the default.
(vceg)Ranged octave downPlay all notes in the bracket in one octave lower than the default.
(3ceg)TripletSet the length of each note to 2/3 of the current quantization.
(5cdefg)QuintupletSet the length of each note to 2/5 of the current quantization.
(7cdefgab)SeptupletSet the length of each note to 2/7 of the current quantization.
(scdef)Ranged sustain pedalSame as (s=127)cdef(s=0).
(:ceg)Ranged sublengthSame as (q=16)ceg(q=8) in (q=8). (quadruplet)
(|ceg)Ranged superlengthSame as (q=4)ceg(q=8) in (q=8). (uni-tuplet)
[>ga]bAppoggiaturaTreat all notes in the bracket as appoggiaturas.
[[c~~~|efga]]ParallelizationPlay all notes sequentially in each section at once.
<.c>StaccatoPlay the note shortly (precisely T8).
<~c>FermataPlay the note lengthy (as configured by Fermata configuration).
<!c>SforzandoPlay the note strongly (in the maximum volume).
<tc>TrillPlay the note as a trill (of interval T16).
<+cegⓘ>Crescendo(1≤ⓘ≤100) Play all notes in the bracket with the increasing volume from the current volume to ⓘ.
<-gecⓘ>Decrescendo(1≤ⓘ≤100) Play all notes in the bracket with the decreasing volume from the current volume to ⓘ.
<p(ⓝ)c~(ⓝ)~~(ⓝ)>Pitch bend(-1≤ⓝ≤1) Play all notes in the bracket with the plan modifying the pitch bend linearly.
|:Open repeatSet the start point of a repetition.
:|ⓘClose repeat(1≤ⓘ) Set the end point of a repetition. You can omit ⓘ if you want to repeat the closed interval just once.1
/1Prima voltaPlay the following notes only if it's the first time to be played.
/2Seconda voltaPlay the following notes after one repetition, skipping the notes of the corresponding prima volta. Since currently only prima and seconda voltas are supported, you can omit this.
{ⓘceg}Group declarationName the set of notes ⓘ.
{=ⓘ}Group referenceRefer the set ⓘ.
=/Head commentIgnore the text before this.
/=Tail commentIgnore the text after this.

Duration

  • 1: Whole note
  • 2: Half note
  • 4: Quarter note
  • 8: 8th note
  • 16: 16th note
  • 32: 32nd note
  • 64: 64th note
  • You can put t at the end of each number above for triplets.
  • You can put d or dd at the front of each number above for (double-)dotted notes.
  • Tⓘ: ⓘ-tick-long note. Note that ♩ = T128.

Bank Selection

You can use more than 128 instruments (if supported) by providing a bank number like (p=123/1) which refers the instrument of Patch No. 124 and Bank No. 1. The default value of the bank number is zero.

User-defined Range

You can define your own range like the example below.

{{octave-chord}}{
  [vxx]
}

#1 {{octave-chord}}(cdefg~~~) /= This is equivalent to
#1 [vcc][vdd][vee][vff][vgg]~~~

Channel Continuation

You can write notes through several channels alternately like below. This helps you transcript a long score without scrolling Sorrygle texts to the desired position.

#1  (♪)      cdefg~~~
#2  (♩)(o=3) c c c c
#~1          gfedc~~~   /= This continues the previous #1
#~2          vgvg[vcc]~ /= This continues the previous #2

Emoji Declaration

You can let a Unicode emoji perform as a local configuration which is like (...=...).

((🔊=(v=100)))
((🔈=(v=1)))

#1 (🔈)cdefgab(🔊)^c~~~~~~~ /= This is equivalent to
#1 (v=1)cdefgab(v=100)^c~~~~~~~

There are some default emoji declarations below. Of course you can overwrite.

EmojiSame as...
🎹(p=0)
🪗(p=21)
🎸(p=24)
🎻(p=40)
🎤(p=54)
🎺(p=56)
🎷(p=64)
🪕(p=105)
🥁(p=118)
𝅝(q=1)
𝅗𝅥(q=2)
𝅘𝅥 or ♩(q=4)
𝅘𝅥𝅮 or ♪(q=8)
𝅘𝅥𝅯 or ♬(q=16)
𝅘𝅥𝅰(q=32)

Example

🎵 Wolfgang Amadeus Mozart - Turkish March (first 27 bars)

((time-sig=2/4))
#1
0 =/       ____                            baGa (o=5)
2 =/ |:{10 c~__dcvbc                       e~__feDe
4 =/       baGabaGa                   }{12 <!^c~~~>a_^c_
6 =/       [>ga]b_[Fa]_[eg]_[Fa]_          [>ga]b_[Fa]_[eg]_[Fa]_
8 =/       [>ga]b_[Fa]_[eg]_[DF]_     } /1 e~~~(vbaGa) :|
10=/ /2    e~~~          |:{13 [ce]_[df]_  [eg]_[eg]_agfe
13=/       [[<!d~~~>|vb~vg~]][ce]_[df]_    [eg]_[eg]_agfe
15=/       [vbd]~~~[vac]_[vbd]_            [ce]_[ce]_fedc
17=/       (v[[<!b~~~>|G~e~]])[vac]_[vbd]_ [ce]_[ce]_fedc
19=/       (v[bG]~~~)(o=4)}baGa(o=5){=10}  {14 <!^c~~~>a_b_
24=/       ^c_b_a_G_                       a_e_f_d_
26=/       c~~~(q=32)(v<tb~~~~~>ab)(q=16)  va~~~} :|

#2(♪)
0 =/       __                              __
2 =/ |:{20 va[ce][ce][ce]                  va[ce][ce][ce]
4 =/       va[ce]va[ce]               }{22 va[ce][ce][ce]
6 =/       (ve[b^e][b^e][b^e]              e[b^e][b^e][b^e]
8 =/       e[b^e]vbb                  )}/1 ve~__    :|
10=/ /2    ve~            |:{23__          vccvee
13=/       g~__                            vccvee
15=/       g~__                            vvavavcc
17=/       e~__                            vvavavcc
19=/       e~}__{=20}                  {24 vf[vaD][vaD][vaD]
24=/       (ve[a^e]d[fb]                   c[ea]d[fb]
26=/       [ea][ea][eG][eG]                [vaa]~)} :|

License

MIT

Keywords

FAQs

Package last updated on 27 Mar 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc