Справочник программиста на персональном компьютере фирмы IBM. Таймеры и звук - Создание звуковых эффектов

ОГЛАВЛЕНИЕ

     2.2.8 Создание звуковых эффектов.


   Звуковые  эффекты  обычно достигаются  непрерывным  изменением
частоты тона. Только PCjr  достаточно  хорошо оборудован для этой
цели (см. обсуждение в [2.2.1]).  На других машинах нельзя произ-
водить звуковые эффекты одновременно с другими операциями.

   Высокий уровень.


   Благодаря мощности своих операторов SOUND и PLAY Бейсик позво-
ляет достаточно легко создавать сложные звуковые эффекты.  Но все
должно быть сконструировано из  чистых  музыкальных  тонов, а это
значит,  что  эффект дисторции звука должен достигаться  за  счет
такого быстрого  изменения  тона,  что  ухо не успевает разделить
тона.  Например, душераздирающее "чириканье" может быть  получено
при быстром переключении между одним и тем же тоном, отстоящим на
несколько октав:

100 FOR N = 1 TO 100     'установка длительности
110 PLAY "L64 T255"      'самый быстрый темп
120 PLAY "O1A"           'выдаем низкое A
130 PLAY "O5A"           'выдаем высокое A
140 NEXT                 'повтор

При изменении частоты всего на несколько герц получаем вибрацию:

100 FOR N = 1 TO 100     'установка длительности
110 SOUND 440,1          'выдаем ноту A
120 SOUND 445,1          'немного меняем частоту
130 NEXT                 'повтор

Другая  техника  заключается во вложении плавно меняющихся  тонов
внутрь последовательности, которая  сама гуляет по частотам вверх
или вниз.  На рис.  2-6 показана движущаяся вверх  последователь-
ность. Многие игры с лабиринтами используют эту технику:

100 FOR I = 1 TO 10   'число повторений
110 FOR J = 1 TO 6    'число разных октав
120 PLAY "MBL64T255O=J;BA#AG#GF#FED#DC#CC#DD#EFF#GG#AA#B"
130 NEXT              'повтор в более высокой октаве
140 NEXT              'повтор всей последовательности

   PCjr значительно более мощный, чем остальные машины, благодаря
специальной  микросхеме генератора звука.  Оператор  NOISE  может
производить множество звуков, формат этого оператора такой:

   NOISE источник, громкость, длительность

Источник  -  это число от 0 до 7, значение которого  приведено  в
таблице:

   0       периодический шум в высоком диапазоне
   1       периодический шум в среднем диапазоне
   2       периодический шум в низком диапазоне
   3       периодический шум, диапазон меняется с каналом 3
   4       белый шум в высоком диапазоне
   5       белый шум в среднем диапазоне
   6       белый шум в низком диапазоне
   7       белый шум, диапазон меняется с каналом 3
Громкость задается числом от  0  до  15,  где 0 соответствует от-
сутствию звука. Длительность указывается числом импульсов счетчи-
ка времени суток, которые отсчитываются 18.2 раза в секунду.

   Низкий уровень.


   Любой из способов, показанных на Бейсике может быть реализован
на  ассемблере, хотя, как видно из предыдущих разделов, это  тре-
бует затрат на программирование.  Кроме того, ассемблер позволяет
генерировать  нечистые  тона, когда интервал, в течение  которого
динамик включен, не равен интервалу, в течение которого он выклю-
чен.  Такое нарушение симметрии может приводить к жужжащим и бря-
кающим звукам. Когда отношение этих интервалов составляет, скажем
50  к 1, то получаем жужжание.  Если увеличить отношение еще в 10
- 20 раз, то жужжание переходит  в  отдельные  брякающие звуки. В
любом  случае звук генерируется микросхемой интерфейса с  перифе-
рией 8255, с помощью  техники  показанной  в  [2.2.2]. Вот пример
жужжания:

NUMBER_CYCLES  EQU  300     ;число переключений динамика
FREQUENCY1     EQU  50      ;время, когда динамик включен
FREQUENCY2     EQU  3200    ;время, когда динамик выключен
PORT_B         EQU  61H     ;адрес порта B микросхемы 8255
            CLI                  ;запрет прерываний
            MOV  DX,NUMBER_CYCLES;DX считает длину тона
            IN   AL,PORT_B       ;получаем статус порта
            AND  AL,11111110B    ;отключаем динамик от таймера
NEXT_CYCLE: OR   AL,00000010B    ;включаем динамик
            OUT  PORT_B,AL       ;посылаем команду
            MOV  CX,FREQUENCY1   ;задержка для первой части
FIRST_HALF: LOOP FIRST_HALF      ;
            AND  AL,11111101B    ;выключаем динамик
            OUT  PORT_B,AL       ;посылаем команду
            MOV  CX,FREQUENCY2   ;задержка для второй части
SECND_HALF: LOOP SECND_HALF      ;
            DEC  DX              ;уменьшаем число циклов
            JNZ  NEXT_CYCLE      ;если 0, то пора кончать
            STI                  ;разрешаем прерывания

Для  создания брякающих звуков можно использовать этот же код, но
надо заменить значение FREQUENCY2 на величину около 40000.