Тестування нот

Наступна коротка програма тестує класи інструментів і нот, розроблені в цьому розділі Спочатку визначається простий клас AudioAbstract, який програє кілька нот Функція main створює обєкт інструменту і просить клас PlayInstrument програти одну або кілька нот Можна легко змінити цю програму і протестувати інші інструменти

Треба звернути увагу на те, як у класі PlayInstrument організована одночасна робота з декількома нотами Він обнуляє буфер перед тим, як попросити різні ноти додати в нього свої вибірки і також перевіряє повертається AddSamples значення, щоб визначити, чи закінчилася нота Коли це відбувається, клас видаляє нотний обєкт і, нарешті, повертає буферу максимальний обсяг, щоб показати, коли закінчаться всі ноти

Памятайте, що лише деякі інструменти припиняють своє звучання моментально інші мають невеликий період загасання, тому важливо не зупиняти відтворення кожної ноти навіть після виклику EndNote

Лістинг 2116 Програма playnotecpp

#include &quotaudioh&quot

#include &quotaplayerh&quot

/ / Пробуємо підібрати відповідний програвач для Win3 2,

/ / Macintosh або UNIX / NAS

#if defined(_WIN32)

#include &quotwinplayrh&quot typedef WinPlayer Player

#elif defined(macintosh)

#include &quotmacplayrh&quot typedef MacPlayer Player

#else

#include &quotnasplayrh&quot typedef NasPlayer Player

#endif

#include &quotinstrumth&quot

#include &quotsampledh&quot

#include &quotauh&quot

#include &quotpluckedh&quot

#include &ltcstdlib&gt

#include &ltfstream&gt

class PlayInstrument: public AudioAbstract {

private:

long _samplesRemaining AbstractInstrument *_instr AbstractNote *_notes[5] float _pitches[5]

float _volumes[5]

protected:

void MinMaxChannels(int *min, int *max, int *preferred) {

*min = *max = *preferred = 1

}

public :

void Init() {

_samplesRemaining = 44100 * 5 / / Відтворюємо

/ / Протягом 5 с

for(int i=0i&lt5i++) {

_notes[i] = 0

_pitches[i] = _volumes[i] = 0

}

}

PlayInstrument(AbstractInstrument *instr) { Init() _instr = instr

}

void AddNote(float pitch, float volume) {

int i = 0

while(_pitches[i] = 0)

i++

_pitches[i] = pitch

_volumes[i] = volume

}

~PlayInstrument() {

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

if (_notes[i]) delete _notes[i]

}

size_t GetSamples(AudioSample *buffer, size_t numSamples) {

for (size_t s = 0 s

buffer[s] = 0 size_t maxSamples = 0 int i

for (i = 0 i <5; i + +) {/ / При необхідності

/ / Створюємо ноти

if (_pitches [i] && _notes [i]) / / При необхідності

/ / Створюємо ноту

_notes[i] = _instr-&gtNewNote(_pitches[i],_volumes[i])

}

for (i = 0 i <5; i + +) {/ / Відтворюємо

/ / Кожну ноту в буфер

if (_notes [i]) {/ / Якщо ця нота існує,

/ / Відтворюємо її

size_t samplesRead = 0

/ / Якщо прийшов час почати

/ / Загасання ..

if((_samplesRemaining &gt= 0)

&amp&amp (static_cast&ltlong&gt(numSamples) &gt

_samplesRemaining)) {

_notes[i]-&gtAddSamples(buffer,_samplesRemaining)

_notes [i] -> EndNote (05) / / Почати загасання

/ / Ноти

samplesRead

= _samplesRemaining + _notes[i]-&gtAddSamples(

buffer+_samplesRemaining,numSamples-

_samplesRemaining)

} else {

samplesRead = _notes[i]-

&gtAddSamples(buffer,numSamples)

}

if (samplesRead

delete _notes [i] / / Видаляємо її

_notes[i] = 0

_pitches [i] = 0 / / He відновлювати її

_volumes [i] = 0 / / He відновлювати її

}

if (samplesRead &gt maxSamples)

maxSamples = samplesRead

}

}

_samplesRemaining -= numSamples

return maxSamples

}

void SamplingRate(long rate) { AudioAbstract::SamplingRate(rate)

_instr-&gtSamplingRate(rate)

}

}

int main(int argc, char **argv) { bool saveOutput = false AbstractInstrument *instr = 0

argv + + argc – / / Пропускаємо імя програми

/ / Обробка параметрів

/ / Командного рядка

while ((argc&gt0) &amp&amp (**argv == &quot-&quot)) {

char *p=*argv

switch(p[1]) {

case 0: / / Вибираємо інструмент 0

instr = new SineWaveInstrument

break

case 1: / / Вибираємо інструмент 1

instr = new PluckedStringInstrument

break

case p: / / Відтворюємо вихідні дані

saveOutput = false

break

case а: / / Записуємо дані у файлі формату AU

saveOutput = true

break

}

argv++ argc–

}

if(instr == 0) {instr = new SineWaveInstrument } PlayInstrument pi(instr)

if (argc == 0) {/ / За замовчуванням просто головна тріада

piAddNote(3300F, 03F) piAddNote(4400F, 03F) piAddNote(5500F, 03F)

} Else {/ / Прочитуємо ноти / гучність

/ / З командного рядка

while (argc&gt0) {

float volume = 10/((argc+1)/2)

if(argc&gt1) {

volume = atof(argv[l])

argc–

} piAddNote(atof(argv[0]),volume) argc–

argv+= 2

}

}

AbstractPlayer *player

if (saveOutput) {/ / Відтворюємо в файл AU

ofstream out(&quotplaynoteau&quot) player = new AuWrite(&amppi, out) player-&gtPlay()

delete player

} Else {/ / Відтворюємо на гучномовець

player = new Player(&amppi)

player-&gtPlay ()

delete player

}

delete instr

return 0

}

Джерело: Кінтцель Т Керівництво програміста по роботі зі звуком = 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>

*

*