(Tone.js) Мы хотим синхронизировать наш генератор заметок с нашей игрой нот. как нам это сделать? - PullRequest
0 голосов
/ 26 октября 2019

//number of notes
timevar = 100
timetracker = -timevar
//button to init program
window.onload = function() {
  document.querySelector('button').addEventListener('click', () => initialise())
}
//main program
function initialise() {
  //add to timetracker till == timevar
  timetracker += timevar
  //init matrix with probabilities
  genmatrix = math.matrix([
    [0.21, 0.26, 0.16, 0.18, 0.19],
    [0.19, 0.24, 0.18, 0.18, 0.21],
    [0.25, 0.05, 0.50, 0.10, 0.10],
    [0.14, 0.10, 0.15, 0.50, 0.11],
    [0.50, 0.25, 0.12, 0.06, 0.07]
  ])
  //array to determine notes
  initvec = math.matrix([1., 0., 0., 0., 0.])
  //multiply matrices to get new probabilities
  prod = math.multiply(initvec, genmatrix)
  //assign value to array that plays note
  notevec = initvec
  //get timevar amount of notes
  for (var i = 0; i <= timevar; i++) {
    //new probabilities
    prod = math.multiply(notevec, genmatrix)
    //assign value to array that plays note
    notevec = getnote(prod)
    //function trigger notes
    notes(i)
  }
  var BPM = 80

  //function that triggers notes
  function notes(a) {
    //init synth tone

    var synth = new Tone.Synth().toMaster()
    Tone.Transport.bpm.value = 70;
    var drum = new Tone.MembraneSynth().toMaster()
    var loop = new Tone.Loop(function(time) {
      //triggered every eighth note.
      console.log(time);
    }, "8n").start(0);
    
    Tone.Transport.start();
    
    //log value of array
    console.log(notevec._data)
    
    //dict with notes
    var NoteDict = {
      0: "G3",
      1: "A#3",
      2: "C3",
      3: "D3",
      4: "F3",
      5: "G3",
      6: "A#3"
    }
    var NoteDict2 = {
      0: "G2",
      1: "A#2",
      2: "C2",
      3: "D2",
      4: "F2",
      5: "G2",
      6: "A#2"
    }
    //check which value is == 1
    var i
    for (i = 0; i <= 4; i++) {
      if (notevec._data[i] == 1) {
        break
      }
    }


    //trigger note
    Tone.Transport.scheduleRepeat(function(time) {

    }, '8n')
    synth.triggerAttackRelease(NoteDict[i], "8n", a / 4 + timetracker);
    drum.triggerAttackRelease(NoteDict2[i], "2n", a + timetracker + math.random(0, 0.02))


    //drum2.triggerAttackRelease("G5", "4n", a+timetracker)
  }


  function getnote(v) {

    randno = math.random()
    sel = 0
    sumfore = 0

    for (var i = 0; i <= v._size[0]; i++) {
      sumfore = sumfore + v._data[i]
      if (randno < sumfore) {
        sel = i
        break
      }
    }
    vret = math.zeros(v._size[0])
    vret._data[i] = 1


    return vret
  }
  //keydown eventlistener
  window.addEventListener("keydown", keysPressed, false);


  keys_pressed = [0, 0]
  keys_reset_counter = 0

  function keysPressed(e) {
    // store an entry for every key pressed
    keys_reset_counter++
    if (keys_reset_counter % 2 == 0) {
      keys_pressed = [e, 0]
    } else {
      keys_pressed[1] = e
    }
    //assign keypress number to rowswitch function
    if (keys_reset_counter % 2 != 0) {
      if (keys_pressed[0].keyCode >= 49 && keys_pressed[0].keyCode <= 53 && keys_pressed[1].keyCode >= 49 && keys_pressed[1].keyCode <= 53) {
        genmatrix = rowswitch(keys_pressed[0].keyCode - 49, keys_pressed[1].keyCode - 49, genmatrix)
        console.log(genmatrix)
        console.log(keys_pressed)
      }
    }
    if (keys_reset_counter % 2 != 0) {
      if (keys_pressed[0].keyCode >= 54 && keys_pressed[0].keyCode <= 57 && keys_pressed[1].keyCode >= 54 && keys_pressed[1].keyCode <= 57) {
        genmatrix = colswitch(keys_pressed[0].keyCode - 54, keys_pressed[1].keyCode - 54, genmatrix)
        console.log(genmatrix)
        console.log(keys_pressed)
      }
    }
  }

  //switching rows
  function rowswitch(i1, i2, mat) {
    //take mat, construct row switching mat.
    console.log(mat._size)
    rowswitcher = math.identity(mat._size)
    storage = rowswitcher[i2]
    rowswitcher[i2] = rowswitcher[i1]
    rowswitcher[i1] = storage
    return math.multiply(rowswitcher, mat)
  }

  //switching columns
  function colswitch(i1, i2, mat) {
    //take matrice, construct col seitching matrice
    colswitcher = math.identity(mat._size)
    storage = colswitcher[i2]
    colswitcher[i2] = colswitcher[i1]
    colswitcher[i1] = storage
    return math.multiply(mat, colswitcher)
  }

  function setup() {


  }
}

По сути, мы генерируем музыку из вероятностей в матрице. В процессе генерации заметок мы хотим изменить матрицу. Используя прослушиватели событий, мы переключаем строки и столбцы исходной матрицы

genmatrix

. Проблема в том, что музыка генерируется до того, как мы получим возможность изменить принятые композиционные решения. Как мы проигрываем музыкальные ноты, как только сгенерированы массивы

notevec._data

Вероятно, это как-то связано с Tone.schedule. Пожалуйста, помогите!

...