15.4.5. Подача звуковых сигналов

Звуковые процедуры Sound ( Hz : Word ) и Nosound дают доступ к встроенному динамику ПЭВМ. Процедура Sound включает звук с заданной частотой тона в герцах. После включения звука программа выполняется дальше. Более того, если сама программа «забудет» выключить звук, то придется добавлять к ней в конец оператор NoSound под непрекращающийся аккомпанемент динамика. Набор звуковых команд всегда должна завершать процедура NoSound, выключающая динамик, хотя вызовов процедур Sound может быть сколько угодно. В таком случае звук не будет прекращаться, но будет менять свою частоту согласно заданным аргументам. Можно, например, в начало каждой процедуры поставить команду Sound с различными частотами. Тогда при работе программа будет издавать трели.

Очень часто процедуры Sound и NoSound используются вместе с процедурой задержки времени Delay(ms). Например, строка программы

Sound(300); Delay (1000); NoSound;

издает ровный звук на частоте 300 Гц продолжительностью 1 с. Но при этом во время звучания программа будет «стоять».

В качестве примера приведем несложную процедуру печати строк в звуковом сопровождении (рис. 15.15):

| USES CRT;

| {Процедура звуковой печати строк }

| PROCEDURE SoundType( X, Y: Byte; S; String; ms: Word );

| CONST

| Hz = 50; {частота тона }

| VAR i : Byte;{параметр цикла}

| BEGIN

| Dec(X);

| for i:=1 to Lengh(S) do begin

| Sound(Hz); Delay(ms); {первый сигнал }

| GotoXY(X+i, Y); Write(S[i]); {печать символа }

| Sound(2*Hz); Delay(ms); {второй сигнал }

| Nosound {снятие звука }

| end {for}

| END;

| BEGIN{--ПРИМЕР ВЫЗОВА--}

| ClrScr;

| SoundType(20, 10, '0123456789abcdeedcba9876543210', 40);

| Readln {пауза до нажатия клавиши ввода }

| END.

Рис. 15.15

- 340 -

Если разделять вызовы Sound с разными частотами небольшими задержками, то можно «синтезировать» довольно сложные звуки. Интересные примеры этого приводятся в учебной программе Turbo Pascal Tutor фирмы Borland International. Некоторые из них приведены на рис. 15.16.

| PROGRAM Sounds; { Демонстрация звуковых эффектов }

| USES CRT;

| { -- ПРОЦЕДУРЫ СИНТЕЗА ЗВУКОВ — }

| PROCEDURE Phone; { телефонный сигнал }

| VAR i : Word;

| BEGIN

| Repeat { Цикл: }

| for i:=1 to 100 do

| begin { собственно сигнал }

| Sound(1200); Delay(10); NoSound

| end;

| Delay(800) { задержка 0,8 с }

| until KeyPressed { выход - после нажатия клавиши }

| END;

| PROCEDURE Bell; { резкий звук }

| BEGIN

| Repeat { начало цикла показа }

| Sound(1800); Delay(2);

| Sound(2000); Delay(2);

| Sound(2200); Delay(2);

| Sound(2400); Delay(2)

| until KeyPressed; { выход - после нажатия клавиши }

| NoSound { отключение звучания }

| END;

| PROCEDURE Sirena; { имитация сигнала тревоги }

| VAR i : Word;

| BEGIN

| Repeat { основной цикл }

| for i := 400 to 800 do begin { восходящие тона }

| Sound( i ); Delay( 3 ) end;

| for i := 800 downto 400 do

| begin { нисходящие тона }

| Sound( i ); Delay( 3 )

| end;

| NoSound { отключение звучания }

| until KeyPressed { выход - после нажатия клавиши }

| END;

Рис. 15.16

- 341 -

| PROCEDURE Pause; { очистка буфера клавиатуры и пауза }

| VAR

| ch : Char;

| BEGIN

| While KeyPressed do ch:=ReadKey; { очистка буфера } Delay( 200 ) { задержка 0,2 с }

| END;

| BEGIN {=== основная часть ===}

| ClrScr;

| Write('Нажмите любую клавишу'#10#10#13);

| { Вызовы процедур - исполнителей: }

| Write('Звук телефона'#13);

| Phone;

| Pause;

| Write(' Звук зуммера '#13); Bell; Pause;

| Write(' Звук сирены '#13); Sirena;

| Pause;

| ClrScr

| END.

Рис. 15.16 (окончание)

Вообще говоря, встроенный в ПЭВМ «слабенький» одноголосый динамик можно «заставить» играть джаз и говорить на сносном русском языке. Но это делается с помощью специальных программ, а вручную вряд ли возможно. Зато ввести в программу нехитрые мотивы можно, зная ноты и их частотные эквиваленты в герцах.

Мы предоставляем заинтересованному читателю поупражняться в программировании и написать программу составления таблицы нот по рабочей формуле (в терминах Турбо Паскаля):

| VAR

Hz : Word;

OKT : Integer;

NOTA : Byte;

Hz:=Round( 440 * Exp( Ln(2) * (OKT - (10 - NOTA)/12 ) ) );

Здесь OKT — номер одной из восьми октав, покрывающих диапазон от 32 Гц до почти 8 кГц. Самая низкотональная октава в таком диапазоне имеет отрицательный номер (-3) и дальнейшая нумерация соответственно будет -2, -1, 0, 1, ..., +4. Параметр NOTA — это номер ноты в октаве: «До» --> 1, «До-диез» --> 2, «Ре» --> 3, .... «Си» --> 12.

- 342 -