2016-08-11 6 views
1

Каков наилучший способ воспроизведения одной заметки за другой? Вот самый функциональный бит кода, который у меня есть сейчас.Воспроизведение последовательности заметок MIDI в swift

let majorScale = [60, 62, 64, 65, 67, 69, 71, 72] 
    for i in majorScale { 
     sampler.startNote(UInt8(i), withVelocity: 127, onChannel: 1) 
     sleep(1) 
     sampler.stopNote(UInt8(i), onChannel: 1) 
    } 

Проблема этого метода состоит в том, что сон() принимает только Uint8 как параметры, так что я не могу сделать отметку последнего менее чем за 1 секунду таким образом.

Я музыкант в первую очередь. Я просто понял немного о программировании из колледжа, когда я взял пару классов java. Тем не менее, я не знаю, какие существуют другие варианты.

  • Есть ли встроенный MIDI-плеер, который можно использовать для обработки длительности ноты?

  • Есть ли способ «сон» менее чем за одну секунду, а затем вычисления длительности сам? Как и в 1/8 нот, играемый со скоростью 100 уд/мин, продлится ((60/100)/2) = 0,3 секунды.

  • Должен ли я вместо того, чтобы принимать информацию ноты и, по сути делаю MIDI-файл, который я могу тогда играть?

Как лучше всего решить эту проблему?

EDIT

Вот обновленный код:

for i in majorScale { 
     sampler.startNote(UInt8(i), withVelocity: 127, onChannel: 1) 
     let pause = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 1 * Int64(NSEC_PER_SEC)) 
     dispatch_after(pause, dispatch_get_main_queue()) { 
      self.sampler.stopNote(UInt8(i), onChannel: 1) 
     } 
     sampler.stopNote(UInt8(i), onChannel: 1) 
    } 

Так я понял, что-то об этом. Я сменил инструмент на орган (вместо фортепиано), и он останавливает заметки через 1 секунду, или 10, или все, что я там нахожу, но похоже, что это продолжается с циклом for, тем временем все ноты звучат одновременно, а не последовательно.

ответ

0

Я не могу помочь с миди аспектом этого, но для приостановки или спать, вы должны использовать dispatch_after. Поместите следующий код вместо спящего (1) и вызова stopNote. Это позволит вам выполнять задержки с точностью до секунды. Просто измените второй параметр вызова dispatch_time_t() в любое время.

let pause = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 1 * Int64(NSEC_PER_SEC)) 
dispatch_after(pause, dispatch_get_main_queue()) { 
     sampler.stopNote(UInt8(i), onChannel: 1) 
} 
+1

Только потому, что API принимает единицы наносекунд, это не означает, что фактическая реализация может прийти где угодно. См. Документацию по адресу dispatch_after. Это лучшее усилие и может быть значительно дольше, чем требуется. Для воспроизведения музыки точно есть, конечно, лучший способ через специализированный APi – BaseZen

+0

Хорошо, поэтому я вроде как понимаю, что здесь происходит ... но это не совсем работает. Если я копирую вышеприведенный код, он запускается, но воспроизводит всю шкалу в течение секунды. Кажется, он совсем не ждет. Я заменил 1000 вместо 1, и получил тот же результат. –

+0

Кроме того, BaseZen, я уверен, что вы правы ... вероятно, есть API, который может справиться с этим, но это был кошмар, который дошел до этого момента. Я бы предпочел использовать какой-то метод сна. а не вычислять другой набор запутанных API. Документация Apple по обработке звука настолько пятнистая, и на примере кода не так много. –

0

Не делайте этого.

Посмотрите на AudioToolbox. MusicPlayer запланирует MIDI-события в MusicSequence.

У меня есть около 1x10^примеры Gazillion на моем blog.

+2

Пожалуйста, укажите мне страница, которая мне нужна, или даже лучше, c & p код, демонстрирующий это. Как вы говорите, у вас есть много примеров в вашем блоге, и для такого новичка, как я, довольно сложно пытаться разобрать все, чтобы найти то, что мне нужно. –