Инструмент один и канал — тоже один, что бы это ни значило.
В самом начале одновременно должно звучать по три ноты(клавиши). Может быть небольшое наложение вначале из-за тормозов и загрузки.
Алгоритм виден в первой реализации. Он, упрощенно, такой:
1 время = 0; задаем координату времени
2 нота = номерНоты; номер ноты, начинающий играть в момент «время» (0)
3 начатьИгратьНоту(нота, время);
4 закончитьИгратьНоту(нота, время + длительностьНоты) звукоизвлечение происходит «в отдельном потоке», то есть не влияет на возможность обрабатывать алгоритм далее.
5 если есть другие непроигранные ноты, начинающие звучать в момент «время» — вернуться к шагу 2 с одной из этой нот.
6 время = время + расстояние до начала ближайшей по времени следующей ноты
7 перейти к шагу 2
// линия времени
var delay = 0;
...
// длительность ноты
var gap = 0.6;
MIDI.setVolume(0, 80);
// первый такт
// начинаем играть ноту 49 в момент времени 0
MIDI.noteOn(0, 49, velocity, delay);
// перестаем играть ноту 49 в момент времени (0 + 4 длительности ноты)
MIDI.noteOff(0, 49, delay + 4 * gap);
// так как процесс происходит в "отдельном потоке", сразу пишем другую ноту
// начинаем играть ноту 37 так же в момент времени 0
MIDI.noteOn(0, 37, velocity, delay);
// перестаем играть ноту 37 в момент времени (0 + 4 длительности ноты)
MIDI.noteOff(0, 37, delay + 4 * gap);
// опять же, т.к. поток другой, запускаем уже третью ноту №56 в момент времени 0
MIDI.noteOn(0, 56, velocity, delay);
// перестаем играть ее в момент времени (0 + 1 длительность ноты)
MIDI.noteOff(0, 56, delay +gap);
// сдвигаем координату времени до начала звучания следующей по времени ноты
// время = 0 + 1 длительность ноты
delay += gap;
// нота 56 перестала звучать, ноты 37 и 49 продолжают играть
// начинаем играть ноту 61 в момент времени (1 длительность ноты)
MIDI.noteOn(0, 61, velocity, delay);
// престаем играть ноту в момент времени (1 длительность ноты + 1 длительность ноты)
MIDI.noteOff(0, 61, delay + duration);
// сдвигаем координату времени до начала звучания следующей по времени ноты
// время = 1 длительность ноты + 1 длительность ноты
delay += gap;
// нота 61 тоже перестала звучать, а ноты 37 и 49 будут играть еще два такта
// first bar
// тоже самое, только время является полем player'а
//начинаем играть C2 в время=0 и прекращаем в время=1
player.play('C2', 1);
// начинаем играть C1 в время=0 и прекращаем время=1
player.play('C1', 1);
// начинаем играть G3 в время=0 и прекращаем время=1/12
// true здесь приведет к время = время + 1/12
player.play('G3', 1/12, true);
// начинаем играть C4 в время=1/12 и прекращаем время=2/12
// true здесь тоже подвинет временную координату внутри player'а
player.play('C4', 1/12, true);
Благодарю за подробное и понятное объяснение.
Поправил про нотацию, октавы и длительности.
С размерностями и длительностями было непросто, так как нот 12, и каждая — 1/8. Но на самом деле размер — не 12/8, а 2/2. Кроме того, в пятом и шестом тактах после двенадцати восьмых нот (четырех триолей) еще идет 1/16, «не влезающая» в такт. Что несколько затрудняло стройную математическую модель, выстроившуюся у меня в голове. В итоге и вылетело совершенно из головы про сложные размеры, где такт != целая нота.
Если кому интересно, то собственно абсолютная длина x определяется по указанию темпа (Adagio Sostenuto), метрической доле (половина), принятым соглашениям, ну и собственно личному вкусу и настроению исполнителя.
В интернете мнения об абсолютной длительности расходятся от «нельзя определить, но стоит ориентироваться на темп» до «считается через BPM/метроном по Мальтеру». И хотя я понимаю, что на заре развития нотной грамоты сложно было задать метроном ровно на m ударов в минуту и сыграть ноту длительностью n/m, сегодня в музыкальном ПО совсем не хочется ссылаться на «вкус и настроение исполнителя».
Тот же guitar pro ориентируется на BPM, насколько помню.
В самом начале одновременно должно звучать по три ноты(клавиши). Может быть небольшое наложение вначале из-за тормозов и загрузки.
Алгоритм виден в первой реализации. Он, упрощенно, такой:
1 время = 0; задаем координату времени
2 нота = номерНоты; номер ноты, начинающий играть в момент «время» (0)
3 начатьИгратьНоту(нота, время);
4 закончитьИгратьНоту(нота, время + длительностьНоты) звукоизвлечение происходит «в отдельном потоке», то есть не влияет на возможность обрабатывать алгоритм далее.
5 если есть другие непроигранные ноты, начинающие звучать в момент «время» — вернуться к шагу 2 с одной из этой нот.
6 время = время + расстояние до начала ближайшей по времени следующей ноты
7 перейти к шагу 2
Попробуйте стабильные версии браузера FF/Chrome.
Поправил про нотацию, октавы и длительности.
С размерностями и длительностями было непросто, так как нот 12, и каждая — 1/8. Но на самом деле размер — не 12/8, а 2/2. Кроме того, в пятом и шестом тактах после двенадцати восьмых нот (четырех триолей) еще идет 1/16, «не влезающая» в такт. Что несколько затрудняло стройную математическую модель, выстроившуюся у меня в голове. В итоге и вылетело совершенно из головы про сложные размеры, где такт != целая нота.
В интернете мнения об абсолютной длительности расходятся от «нельзя определить, но стоит ориентироваться на темп» до «считается через BPM/метроном по Мальтеру». И хотя я понимаю, что на заре развития нотной грамоты сложно было задать метроном ровно на m ударов в минуту и сыграть ноту длительностью n/m, сегодня в музыкальном ПО совсем не хочется ссылаться на «вкус и настроение исполнителя».
Тот же guitar pro ориентируется на BPM, насколько помню.