Отредактировано: Первоначально я думал, что вы можете просто добавить счетчик в барах в конец существующей последовательности, а затем сбросить его до нужной длины, используя AKCallbackInstrument с событием в нулевом такте, но оказывается, что это несколько сложнее.
После любого вызова setLength()
, вы должны позвонить enableLooping()
, чтобы восстановить циклическое поведение. Под этим подразумевается вызов MusicTrackSetProperty
с kSequenceTrackProperty_LoopInfo
для каждого трека в базовом MusicSequence
. Вызов этого во время работы секвенсора имеет странный побочный эффект - перемещение точки воспроизведения в положение, расстояние от конца исходной последовательности которого равно новой длине последовательности. Так, например, если у вас есть последовательность из 20 ударов, и вы хотите динамически изменить ее на последовательность из 16 ударов, вызов enableLooping()
переместит точку воспроизведения на бит 4 (то есть, 20 - 16 = 4). Затем он будет проигрывать до 16, а затем зацикливаться, как и ожидалось. К счастью, этот прыжок не слишком сильно влияет на время.
Тогда решение состоит в том, чтобы удвоить длину последовательности и поставить счет в самом конце. Например, если у вас есть последовательность из 16 ударов, установите длину 32 ударов и начните отсчет в событиях в такте 28. Затем, в такте 0, вы можете вызвать setLength(AKDuration(beats: 16.0))
и enableLooping()
, и точка воспроизведения перейдет к ритм 16, который, в соответствии с новым циклическим поведением, фактически равен 0. Время не идеальное, но неплохое (задержка около 3 мс, но это, вероятно, не является преградой, если вы уже используете MusicSequence
основанный секвенсор.)
Это не очень хорошее решение, но я могу подтвердить, что оно работает.