Хакатон/Пишем музыку в Scratch/Midi-CSV generator
Материал из Letopisi.Ru — «Время вернуться домой»
- Исходный проект https://scratch.mit.edu/projects/102685408
- дополнительная информация - https://music.stackexchange.com/questions/24893/how-to-decode-this-csv-from-a-midi-file - как читаются csv файлы, перекодированные из midi
- http://flashmusicgames.com/midi/index.html
Данные выглядят следующим образом:
2, 0, MIDI_port, 0 2, 0, Title_t, "Bass Synt" 2, 3072, Note_on_c, 1, 26, 96 2, 3072, Note_on_c, 1, 38, 86 2, 3220, Note_on_c, 1, 38, 0 2, 3220, Note_on_c, 1, 26, 0 2, 3648, Note_on_c, 1, 26, 97 2, 3648, Note_on_c, 1, 38, 96 2, 3788, Note_on_c, 1, 38, 0 2, 3788, Note_on_c, 1, 26, 0
Содержание |
Stage
когда щёлкнут по зелёному флагу задать [load v] значение [0] перейти в x: (0) y: (0) установить эффект [яркость v] в значение (0) задать [turbo mode v] значение [false] показаться повторять пока не <(turbo mode) = [true]> detect turbo :: custom end сменить костюм на [costume4 v] создать клон [себя самого v] перейти в x: (-60) y: (-30) повторить (2) следующий костюм создать клон [себя самого v] установить x в (162) end спрятаться определить detect turbo перезапустить таймер повторить (10) сменить костюм на (костюм #) end задать [turbo mode v] значение <(таймер) < [0.1]> когда я получу [delete screen clones v] удалить клон когда я получу [apple midi v] перейти в x: (0) y: (0) сменить костюм на [costume7 v] перейти назад на (999) слоев показаться создать клон [себя самого v] спрятаться когда я получу [play song v] спрятаться перейти в x: (0) y: (0) сменить костюм на [costume6 v] перейти назад на (999) слоев показаться создать клон [себя самого v] спрятаться когда щёлкнут по зелёному флагу сменить костюм на [costume1 v] ждать (0.5) секунд повторять пока не <(turbo mode) = [true]> сменить костюм на [costume2 v] ждать (1) секунд сменить костюм на [costume3 v] ждать (0.25) секунд сменить костюм на [costume1 v] ждать (1) секунд end когда я получу [load v] сменить костюм на [costume5 v] перейти в x: (0) y: (0) показаться когда я начинаю как клон установить эффект [яркость v] в значение (0) если <<(костюм #) = [5]> или <(костюм #) = [6]>> , то всегда если <касается [указатель мышки v] ?> , то установить эффект [яркость v] в значение (-30) если <мышка нажата?> , то установить эффект [яркость v] в значение (-70) если <(костюм #) = [5]> , то передать [import v] иначе если <(костюм #) = [6]> , то передать [examples v] end end передать [delete screen clones v] end иначе установить эффект [яркость v] в значение (0) end end иначе end
?
Midi Player
define Split (#) On Every (\/) to (list) set [i v] to [1] set [prox v] to [] repeat (length of (#)) if <(letter (i) of (#)) = (\/)> then add (prox) to (list) set [prox v] to [] else set [prox v] to (join (prox) (letter (i) of (#))) end change [i v] by (1) end define Render frame: (frame) pen up delete (all v) of [FrameData v] delete (all v) of [Frame v] Split (item (frame) of [Frames v] :: list) On Every [\]] to [Frame v] :: custom set [l v] to [1] repeat until <(l) > (length of [Frame v] :: list)> Split (item (l) of [Frame v] :: list) On Every [/] to [FrameData v] :: custom change [l v] by (1) end set [l v] to [1] repeat until <(l) > (length of [FrameData v] :: list)> if <(lines) = [false]> then pen up end go to x: (((item (l) of [FrameData v] :: list) * ((size) - ((size) * (0.7)))) + (x)) y: (((item ((l) + (1)) of [FrameData v] :: list) * ((size) - ((size) * (0.7)))) + (y)) set [lines v] to (item ((l) + (2)) of [FrameData v] :: list) pen down change [l v] by (3) end define Find letter (#) in chars set [i v] to [1] Get case of (letter (1) of (#)) :: custom if <(case) = [lower]> then repeat until <(item (i) of [chars v] :: list) = (join (letter (1) of (#)) [2])> change [i v] by (1) if <(i) > (length of [chars v] :: list)> then set [i v] to [97] stop [this script v] end end else repeat until <(item (i) of [chars v] :: list) = (letter (1) of (#))> change [i v] by (1) if <(i) > (length of [chars v] :: list)> then set [i v] to [97] stop [this script v] end end end if <(i) < [10]> then set [i v] to (join [0] (i)) end define Get case of (#) switch costume to [Case Checker v] switch costume to (letter (1) of (#)) if <not <(costume #) = [1]>> then set [case v] to [upper] else set [case v] to [lower] end define Type (Text) at x: (X) y: (Y) thickness: (thickness) size: (size) spacing: (spacing) Reset :: custom set [size v] to (size) set pen size to ((thickness) + (bold)) set pen color to (color) Encode (Text) :: custom set [x v] to (X) set [y v] to (Y) delete (all v) of [Imput v] set [c v] to [1] repeat ((length of (CodedText)) / (2)) add (join (letter (c) of (CodedText)) (letter ((c) + (1)) of (CodedText))) to [Imput v] change [c v] by (2) end set [c v] to [1] repeat until <(c) > (length of [Imput v] :: list)> pen up if <(item (c) of [Imput v] :: list) = [07]> then Custom imput: (item ((c) + (1)) of [Imput v] :: list) :: custom set pen size to ((thickness) + (bold)) change [c v] by (2) end Render frame: (item (c) of [Imput v] :: list) :: custom change [c v] by (1) change [x v] by ((((thickness) + (bold)) + ((size) * (12))) * (spacing)) if <<(x) > [237]> or <(item (c) of [Imput v] :: list) = [96]>> then set [x v] to [-230] change [y v] by (-25) if <(item (c) of [Imput v] :: list) = [96]> then delete (c) of [Imput v] end end if <(y) < [-180]> then wait (2.5) secs clear set [x v] to [-230] set [y v] to [120] end end change [x v] by ((((thickness) + (bold)) + ((size) * (12))) * (spacing)) pen up define Encode (text) set [CodedText v] to [] set [c v] to [1] repeat until <(c) > (length of (text))> Find letter (letter (c) of (text)) in chars :: custom set [CodedText v] to (join (CodedText) (i)) change [c v] by (1) end define Custom imput: (imput) if <(imput) = [77]> then if <(bold) = [0]> then Bold: <not <>> :: custom else Bold: <> :: custom end else if <(imput) = [21]> then set pen color to [#be0000] else if <(imput) = [68]> then set pen color to [#fa4534] else if <(imput) = [23]> then set pen color to [#d8a32f] else if <(imput) = [70]> then set pen color to [#fefe3e] else if <(imput) = [19]> then set pen color to [#00c000] else if <(imput) = [66]> then set pen color to [#42fd3e] else if <(imput) = [67]> then set pen color to [#4af9fc] else if <(imput) = [20]> then set pen color to [#00bfc1] else if <(imput) = [18]> then set pen color to [#0100be] else if <(imput) = [26]> then set pen color to [#3d41fa] else if <(imput) = [69]> then set pen color to [#fe40f8] else if <(imput) = [22]> then set pen color to [#be00be] else if <(imput) = [71]> then set pen color to [#fff] else if <(imput) = [24]> then set pen color to [#bebebe] else if <(imput) = [25]> then set pen color to [#3f3f3f] else if <(imput) = [17]> then set pen color to [#000] else end end end end end end end end end end end end end end end end end define Reset set pen color to [#000] Bold: <> :: custom define Bold: <bold?> if <bold?> then set [bold v] to [4] else set [bold v] to [0] end when I start as a clone set [brightness v] effect to (0) forever if <<touching [mouse-pointer v] ?> and <not <(costume #) = [41]>>> then set [brightness v] effect to (-30) if <mouse down?> then if <(costume #) = [40]> then set [brightness v] effect to (-70) wait until <not <mouse down?>> if <(timer) = [0]> then broadcast [play song v] set [pause v] to [0] else if <(pause) = [0]> then broadcast [play song v] else if <(pause) = [1]> then set [pause v] to [0] end end end else if <(costume #) = [41]> then set [brightness v] effect to (-70) wait until <not <mouse down?>> if <(action track) = (track)> then set [action track v] to [0] else set [action track v] to (track) end else if <(costume #) = [42]> then set [brightness v] effect to (-70) wait until <not <mouse down?>> if <(item (track) of [muted v] :: list) = [0]> then replace item (track) of [muted v] with [1] replace item (track) of [singles v] with [0] else replace item (track) of [muted v] with [0] end else if <(costume #) = [43]> then set [brightness v] effect to (-70) wait until <not <mouse down?>> if <(item (track) of [singles v] :: list) = [0]> then replace item (track) of [singles v] with [1] replace item (track) of [muted v] with [0] else replace item (track) of [singles v] with [0] end else if <(costume #) = [44]> then set [brightness v] effect to (-70) set [action track v] to (track) broadcast [stop settings v] and wait broadcast [channel settings v] and wait wait until <not <mouse down?>> else if <<(costume #) = [45]> or <(costume #) = [46]>> then set [brightness v] effect to (-70) wait until <not <mouse down?>> if <(costume #) = [45]> then set [pause v] to [1] switch costume to [costume6 v] else broadcast [reset timer v] switch costume to [costume8 v] end else end end end end end end end else if <<(costume #) = [42]> and <(item (track) of [muted v] :: list) = [1]>> then set [brightness v] effect to (-30) else if <<(costume #) = [43]> and <(item (track) of [singles v] :: list) = [1]>> then set [brightness v] effect to (-30) else if <<(costume #) = [46]> and <(pause) = [0]>> then switch costume to [costume8 v] set [brightness v] effect to (0) else set [brightness v] effect to (0) end end end end end when I receive [display v] set [playing? v] to [1] set [track v] to [1] set [text y v] to [162] broadcast [delete clones v] show clear set size to (100) % repeat (tracks) if <(item (track) of [drummed channels v] :: list) = [false]> then Type (join (join [&a] (item ((track) + ((tracks) * (2))) of [chnl var v] :: list)) (join [ (] (join (item ((track) + (tracks)) of [chnl var v] :: list) [)]))) at x: (-155) y: (text y) thickness: (2) size: (0.75) spacing: (0.8) :: custom else Type (join (join [&a] (item ((track) + ((tracks) * (2))) of [chnl var v] :: list)) [ (Percussion)]) at x: (-147) y: (text y) thickness: (2) size: (0.75) spacing: (0.8) :: custom end Type (join [&aTrack] (track)) at x: ((192) - (((length of (track)) - (1)) * ((202) - (194)))) y: (text y) thickness: (2) size: (0.75) spacing: (0.8) :: custom set pen color to [#fff] go to x: (-240) y: ((text y) - (4)) pen down go to x: (240) y: ((text y) - (4)) pen up go to x: (-235) y: (text y) switch costume to [costume2 v] create clone of [myself v] go to x: (-215) y: (text y) switch costume to [costume5 v] create clone of [myself v] go to x: (-195) y: (text y) switch costume to [costume3 v] create clone of [myself v] go to x: (-175) y: (text y) switch costume to [costume4 v] create clone of [myself v] change [track v] by (1) change [text y v] by (-20) end set size to (200) % go to x: (190) y: (-175) switch costume to [costume1 v] create clone of [myself v] go to x: (215) y: (-175) switch costume to [costume8 v] create clone of [myself v] hide when I receive [delete clones v] delete this clone
Tune generator
определить load notes добавить (элемент (((bar) * (2)) + ((bar) + (1))) из [notes v] :: list) к [this bar notes v] добавить (элемент (((bar) * (2)) + ((bar) + (2))) из [notes v] :: list) к [this bar notes v] добавить (элемент (((bar) * (2)) + ((bar) + (3))) из [notes v] :: list) к [this bar notes v] определить delete (string1) off \[this bar notes\] задать [i v] значение [0] повторять пока не <(i) > (длина списка [this bar notes v] :: list)> изменить [i v] на (1) Split (слить (элемент (i) из [this bar notes v] :: list) и [/]) On Every [/] to [high/low v] :: custom если <[high/low v] содержит (string1) ?> , то задать [l v] значение (i) задать [i v] значение [0] повторять пока не <(элемент (i) из [high/low v] :: list) = (string1)> изменить [i v] на (1) end удалить (i) из [high/low v] задать [i v] значение [1] задать [new string v] значение (элемент (i) из [high/low v] :: list) повторить ((длина списка [high/low v] :: list) - (1)) задать [new string v] значение (слить (new string) и (слить [/] и (элемент (i) из [high/low v] :: list))) изменить [i v] на (1) end заменить элемент (l) в [this bar notes v] на (new string) стоп [этот скрипт v] иначе изменить [i v] на (1) end end определить pick high/low note Split (слить (note) и [/]) On Every [/] to [high/low v] :: custom задать [note v] значение (элемент (random v) из [high/low v] :: list) определить Split (#) On Every (\/) to (list) задать [i v] значение [1] задать [prox v] значение [] удалить (все v) из (list) повторить (длина (#)) если <(буква (i) в (#)) = (\/)> , то добавить (prox) к (list) задать [prox v] значение [] иначе задать [prox v] значение (слить (prox) и (буква (i) в (#))) end изменить [i v] на (1) end когда я получу [generate tune v] generate tune (1) :: custom generate tune (2) :: custom generate tune (3) :: custom generate tune (4) :: custom generate tune (5) :: custom convert to midi csv :: custom определить convert to midi csv удалить (все v) из [midi csv v] удалить (все v) из [times v] задать [j v] значение [1] повторить (5) задать [l v] значение (элемент (j) из [Ls v] :: list) добавить ((элемент (l) из [waits v] :: list) * (1000)) к [times v] добавить (слить (l) и [, 0, Start_track]) к [midi csv v] добавить (слить (l) и (слить [, 0, Program_c, 0, ] и ((элемент (l) из [instrument ids v] :: list) - (1)))) к [midi csv v] добавить (слить (l) и (слить [, 0, Title_t, "] и (слить (элемент (l) из [titles v] :: list) и ["]))) к [midi csv v] задать [l v] значение (элемент (j) из [Ls v] :: list) повторить (элемент (l) из [repeats v] :: list) задать [k v] значение [1] повторить (длина списка (слить [tune] и (l)) :: list) Split (слить (элемент (k) из (слить [tune] и (l)) :: list) и [:]) On Every [:] to [high/low v] :: custom добавить (слить (l) и (слить [, ] и (слить (элемент (j) из [times v] :: list) и (слить [, Note_on_c, ] и (слить (l) и (слить [, ] и (слить (элемент (1 v) из [high/low v] :: list) и [, 100]))))))) к [midi csv v] добавить (слить (l) и (слить [, ] и (слить ((элемент (j) из [times v] :: list) + ((элемент (2 v) из [high/low v] :: list) * (1000))) и (слить [, Note_off_c, ] и (слить (l) и (слить [, ] и (слить (элемент (1 v) из [high/low v] :: list) и [, 0]))))))) к [midi csv v] заменить элемент (j) в [times v] на ((элемент (j) из [times v] :: list) + ((элемент (2 v) из [high/low v] :: list) * (1000))) изменить [k v] на (1) end end добавить (слить (l) и [, 0, End_track]) к [midi csv v] изменить [j v] на (1) end добавить (слить (l) и [, 0, End_file]) к [midi csv v] заменить элемент (1 v) в [midi csv v] на (элемент (1 v) из [midi csv v] :: list) определить generate tune (tune) если <(tune) = [5]> , то удалить (все v) из [tune5 v] добавить [36:1] к [tune5 v] добавить [41:1] к [tune5 v] добавить [36:1] к [tune5 v] добавить [31:1] к [tune5 v] иначе удалить (все v) из (слить [tune] и (tune)) задать [bar v] значение [0] задать [add v] значение [1] повторить (4) удалить (все v) из [this bar notes v] load notes :: custom задать [length v] значение (элемент (random v) из [lengths v] :: list) задать [note v] значение (элемент (random v) из [this bar notes v] :: list) pick high/low note :: custom добавить (слить (note) и (слить [:] и (length))) к (слить [tune] и (tune)) delete (note) off \[this bar notes\] :: custom если <не <(length) = [1]>> , то задать [note v] значение (элемент (random v) из [this bar notes v] :: list) pick high/low note :: custom добавить (слить (note) и (слить [:] и (length))) к (слить [tune] и (tune)) delete (note) off \[this bar notes\] :: custom если <(length) = [0.25]> , то задать [note v] значение (элемент (random v) из [this bar notes v] :: list) pick high/low note :: custom добавить (слить (note) и (слить [:] и (length))) к (слить [tune] и (tune)) delete (note) off \[this bar notes\] :: custom удалить (все v) из [this bar notes v] load notes :: custom задать [note v] значение (элемент (random v) из [this bar notes v] :: list) pick high/low note :: custom добавить (слить (note) и (слить [:] и (length))) к (слить [tune] и (tune)) delete (note) off \[this bar notes\] :: custom end end изменить [bar v] на (1) изменить [add v] на (1) end end