сгенерированная длина ноты midi - PullRequest
0 голосов
/ 09 ноября 2010

Я создал некоторый код javascript, который генерирует MIDI-файлы на основе переданной ноты и октавы.По большей части это работает довольно хорошо.Проблема в том, что нота C (note = 0) воспроизводится намного короче, чем любая другая нота (от 1 (C #) до 11 (B)).

Вот мой код:

function play(note, octave, program){
    var note = (octave*12 + note).toString(16);
    var velocity = 'ff';
    var MIDI_DATA =
      'MThd%00%00%00%06%00%01%00%01%00%C0' + // midi header
      'MTrk%00%00%00%0E' + // track header
        '%00%C0%'+program+
        '%00%90%'+note+'%'+velocity+
        '%70%30%00' + 
        '%00%FF%2F%00'; 

    MIDI_DATA = btoa(unescape(MIDI_DATA));
    var e = document.createElement('embed');
    e.src = "data:audio/mid;base64,"+MIDI_DATA;
    e.type = "video/quicktime";
    document.body.appendChild(e);
    return e;
}

Почему звук C-play (0, 4, '18') звучит намного короче, чем любой другой - play (1, 4, '18')?Кажется, что высота звука правильная, просто длина ноты.

Я думаю, что это может иметь какое-то отношение к тому, что C имеет значение 0, но я не знаю достаточно о том, что я делаю здесь с мидичтобы определить проблему.

ПРИМЕЧАНИЕ. Этот код не работает в IE (любая версия).

Ответы [ 2 ]

1 голос
/ 09 ноября 2010

Если я правильно помню, ноты MIDI воспроизводятся, задавая высоту и скорость (т. Е. Громкость) между 1 и 127, и останавливаются, давая одинаковую высоту со скоростью 0.

0 голосов
/ 09 ноября 2010

Если значение ноты меньше 16, вы получите недопустимую escape-последовательность, то есть %0 вместо %00.Функция unescape не превратит это в персонажа, но оставит его без изменений.Поскольку это два символа вместо одного, он перетекает в байт скорости, а остальная часть MIDI-кода выходит из синхронизации.

Вы можете использовать такой код для форматирования числа в две шестнадцатеричные цифры:

function toHex(n) {
  var code = '0' + n.toString(16);
  return code.substr(code.length - 2, 2);
}

Используйте это, чтобы сделать значение примечания двумя цифрами:

var note = toHex(octave*12 + note);
...