2010-11-09 4 views
0

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

Вот мой код:

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; 
} 

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

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

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

+0

А что происходит, когда вы звоните миди файл непосредственно в браузере/quicktime без использования встроенного тега? Играет ли он правильное время? – epascarello

+1

Я не могу воспроизвести это поведение - все ноты играют за такое же количество времени. Обновите версию QT? – LesterDove

+0

Кажется, это проблема с моей звуковой картой. Я тестировал несколько комбинаций OS/браузера, но не несколько компьютеров. Спасибо, что привлек это к моему вниманию. Я должен был проверить это раньше. – marshallpenguin

ответ

1

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

+0

Вы правы, коды выше 127 - это управляющие коды, а не данные. Скорость должна быть '7f', а не' ff'. – Guffa

+0

Изменение его с ff на 7f не повлияло. Но спасибо. – marshallpenguin

0

Когда примечание значение меньше 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); 
+0

Спасибо, Guffa, но ваш предоставленный код ничего не меняет. Я забыл упомянуть, что обрезание происходит только на 4-й октаве. – marshallpenguin

+0

Когда примечание имеет шестнадцатеричное значение «30», примечание отключается. – marshallpenguin