Відтворення потоку подій MIDI

Тепер, коли MIDI вже лічені в память, а дельти перетворені в кількість відліків, здійснити програвання подій досить просто Метод GetSamples швидко переглядає потік подій для кожного дельта інтервалу, відповідно до його тривалістю, здійснюється програвання всіх каналів кожна подія направляється до відповідного канал

Лістинг 2221 Відтворення подій MIDI

size_t MidiRead::GetSamples(AudioSample *buffer, size_t numSamples) {

_currentEvent = _events / / Починаємо з першої події

_samplesRemaining = 0

}

for(size_t i=0 i&ltnumSamples i++)

buffer[i]=0

size_t samplesReturned = 0

while (_currentEvent &amp&amp (numSamples&gt0)) {

if (_samplesRemaining &gt 0) {

size_t samplesToPlay = numSamples

if (samplesToPlay &gt _samplesRemaining)

samplesToPlay = _samplesRemaining

for (int i=0i&lt16i++)

_channel[i]-&gtAddSamples(buffer,samplesToPlay)

buffer += samplesToPlay

samplesReturned += samplesToPlay

_samplesRemaining = samplesToPlay

numSamples = samplesToPlay

if (numSamples == 0)

return samplesReturned

}

_samplesRemaining += _currentEvent-&gtdelay

_currentEvent = _currentEvent-&gtnext

}

return samplesReturned

}

Більшість повідомлень каналів направляється в окремий канал

Лістинг 2222 Відтворення однієї події MIDI

int ch = _currentEvent-> status & 0xF switch (_currentEvent-> status & 0xF0) {case 0x80: / / Відключення ноти

_channel[ch]-&gtEndNote(_currentEvent-&gtdata[0],_currentEvent-

&gtdata[1] )

break

case 0x90: / / Включення ноти

if (_currentEvent-&gtdata[1] = = 0)

_channel[ch]-&gtEndNote(_currentEvent-&gtdata[0], 64)

else

_channel[ch]-&gtStartNote(_currentEvent-&gtdata[0],

_currentEvent-&gtdata[1])

break

case 0xA0: / / Ключ послекасания

_channel[ch]-&gtKeyAftertouch(_currentEvent-&gtdata[0],

_currentEvent-&gtdata[1] )

break

case 0xB0: / / Зміна режиму

_channel[ch]-&gtMode(_currentEvent-&gtdata[0],

_currentEvent-&gtdata[1])

break

case 0xC0: / / Програмуємо канал

_channel[ch]-&gtProgram(_currentEvent-&gtdata[0])

break

case 0xD0: / / Канал послекасания

_channel[ch]-&gtChannelAftertouch(_currentEvent-&gtdata[0])

break

case 0xE0: / / Зміна висоти тону (колесо висоти)

_channel[ch]-&gtPitchBend(_currentEvent-&gtdata[1]*12 8

+ _currentEvent-&gtdata[0])

break

case 0xF0: / / Особливі події

if (_currentEvent-> status == 0xFF) {/ / Метасобитіе

switch(_currentEvent-&gtdata[0]) {

case 0: break / / Порядковий номер доріжки

case 1: case 2: case 3: case 4: case 5:

case 6: case 7: case 8: case 9: case 10:

case 11: case 12: case 13: case 14: case 15:

break / / Текстовий коментар

case 47: break / / Кінець доріжки

case 81: break / / Темп

case 88: break / / Сигнатура часу

case 89: break / / Тональність

case 127: break / / Специфічне для секвенсора

/ / Доріжка .. (Мета ..)

default: fprintf(stderr,&quotTrack %2d: (Meta 0x%02x)\n&quot,

_currentEvent-&gttrack,

_currentEvent-&gtdata[0])

}

} else if(_currentEvent-&gtstatus == 0xF0) {

/ / Ексклюзивне подія

/ / Доріжка .. (ексклюзивне

/ / Подія)

fprintf(stderr,&quotTrack %2d: (Sysex Event)\n&quot,

_currentEvent-&gttrack)

} else if(_currentEvent-&gtstatus == 0xF7) {

/ / Спеціальний ексклюзивне

/ / Подія

/ / Доріжка .. (спеціальне

/ / Ексклюзивне подія)

fprintf(stderr,&quotTrack %2d: (Special Sysex Event)\n&quot,

_currentEvent-&gttrack)

} else {

/ / Доріжка ..: Статус:

fprintf(stderr,&quotTrack %2d: &quot,_currentEvent-&gttrack)

fprintf(stderr, &quotStatus: 0x%02x\n&quot, _currentEvent-&gtstatus)

}

break

default: / / Є події, які

/ / Не розглянуті вище

/ / Доріжка .. Помилковий статус ..

fprintf(stderr,&quotTrack %2d, Bad Status: 0x%x\n&quot,

_currentEvent-&gttrack,_currentEvent-&gtstatus)

break

}

Джерело: Кінтцель Т Керівництво програміста по роботі зі звуком = A Programmers Guide to Sound: Пер з англ М: ДМК Пресс, 2000 432 с, іл (Серія «Для програмістів»)

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*