Хакатон/Пишем музыку в 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








Персональные инструменты
Инструменты