Программирование LEGO NXT роботов на языке NXC - Создаём музыку

Материал из roboforum.ru Wiki
Перейти к: навигация, поиск

Автор: Daniele Benedettelli

Перевод: © Ботов Антон aka =DeaD=, 2009

Эксклюзивно для www.roboforum.ru
копирование на другие ресурсы и публикация перевода
без разрешения его автора запрещены

Создаём музыку

Модуль NXT имеет встроенный динамик и может воспроизводить музыку и даже звуковые файлы. Это может быть полезно в том случае, когда вы хотите чтобы NXT сказал вам, что что-то случилось. Но это также может быть просто более интересно, когда робот играет музыку или разговаривает в процессе выполнения заданий.

Проигрываем звуковые файлы

BricxCC содержит в себе встроенную утилиту для преобразования .wav-файлов в .rso-файлы, доступную через меню "Tools" / "Sound conversion".

Завершив преобразование, вы можете сохранить .rso-файлы со звуками во флеш-память NXT при помощи другой утилиты (меню "Tools" / "NXT explorer"), после чего их можно будет воспроизводить командой

PlayFileEx(filename, volume, loop?)

Аргументы команды - имя файла, громкость (число от 0 до 4), и необязательный флаг зацикливания "loop", выставьте его в 1 (или TRUE), если хотите, чтобы файл вопроизвёлся не один раз, выставление его в 0 (или FALSE) воспроизведёт файл один раз.

#define TIME 200
#define MAXVOL 7
#define MINVOL 1
#define MIDVOL 3
#define pause_4th Wait(TIME)
#define pause_8th Wait(TIME/2)
#define note_4th \
PlayFileEx("! Click.rso",MIDVOL,FALSE); pause_4th
#define note_8th \
PlayFileEx("! Click.rso",MAXVOL,FALSE); pause_8th
task main()
{
  PlayFileEx("! Startup.rso",MINVOL,FALSE);
  Wait(2000);
  note_4th;
  note_8th;
  note_8th;
  note_4th;
  note_4th;
  pause_4th;
  note_4th;
  note_4th;
  Wait(100);
}

Эта забавная программа сначала проигрывает звук начала работы, который вы возможно уже слышали, а затем использует стандартный звук "click" чтобы сыграть джингл “Shave and a haircut” который приводит в восторг кролика Роджера! Макрос действительно очень удобен в данном случае для упрощения записи команд в главное задаче: попробуйте модифицировать настройки громкости чтобы сделать мелодию наиболее приятной.

Играем музыку

Чтобы воспроизвести тоновый сигнал вы можете использовать команду PlayToneEx(frequency, duration, volume, loop?) Она имеет 4 параметра. Первый это частота тона в Герцах, второй - продолжительность в 1/1000 секунды (как в операторе "wait"), и последний - такой же флаг зацикливания, как и в предыдущей команде. Кроме того может быть использована команда PlayTone(frequency, duration), в этом случае громкость используется настроенная в меню вашего модуля NXT, а функция зацикливания недоступна.

Вот таблица с полезными частотами музыкальных нот по октавам:

Нота 3 4 5 6 7 8 9
B (Си) 247 494 988 1976 3951 7902
A# (Ля-диез) 233 466 932 1865 3729 7458
A (Ля) 220 440 880 1760 3520 7040 14080
G# (Соль-диез) 415 831 1661 3322 6644 13288
G (Соль) 392 784 1568 3136 6272 12544
F# (Фа-диез) 370 740 1480 2960 5920 11840
F (Фа) 349 698 1397 2794 5588 11176
E (Ми) 330 659 1319 2637 5274 10548
D# (Ре-диез) 311 622 1245 2489 4978 9956
D (Ре) 294 587 1175 2349 4699 9398
C# (До-диез) 277 554 1109 2217 4435 8870
C (До) 262 523 1047 2093 4186 8372

Как и в случае с PlayFileEx, модуль NXT не дожидается когда нота доиграет. Так что если вы хотите воспроизвести подряд несколько нот - вам придётся добавить между ними достаточно долгие команды "wait". Например вот так:

#define VOL 3
task main()
{
PlayToneEx(262,400,VOL,FALSE); Wait(500);
PlayToneEx(294,400,VOL,FALSE); Wait(500);
PlayToneEx(330,400,VOL,FALSE); Wait(500);
PlayToneEx(294,400,VOL,FALSE); Wait(500);
PlayToneEx(262,1600,VOL,FALSE); Wait(2000);
}

Вы можете с легкость создавать музыкальные фрагменты с использованием инструмента "Brick Piano", являющегося частью BricxCC.

Если вы хотите, чтобы NXT играл музыку, когда выполнял различные задачи - лучше используйте для этого отдельную задачу. Вот пример достаточно достаточно глупой программы, где NXT ездит взад-вперед и параллельно играет музыку.

task music()
{
  while (true)
  {
    PlayTone(262,400); Wait(500);
    PlayTone(294,400); Wait(500);
    PlayTone(330,400); Wait(500);
    PlayTone(294,400); Wait(500);
  }
}

task movement()
{
  while(true)
  {
    OnFwd(OUT_AC, 75); Wait(3000);
    OnRev(OUT_AC, 75); Wait(3000);
  }
}

task main()
{
  Precedes(music, movement);
}

Подводим итоги

В этой главе вы научились как с помощью NXT проигрывать звуки и музыку. Кроме того вы увидели, как использовать отдельную задачу для воспроизведения музыки.