ZX Forum
#04
19 ноября 1997 |
|
Мир звуков Спектрума - глава 2: Оператор BEEP, Создание эффектов на BEEPе, Создание музыки на BEEPе.
2. Оператор BEEP Единственная возможность получения зву- ка, которую предоставляет Spectrum-бей- сик - это оператор BEEP. Его формат: BEEP t, f где t - длительность звука в секундах, а f - высота в полутонах. Чтобы ноту повы- сить или понизить на октаву, необходимо ее значение соответственно увеличить или уменьшить на 12. Так, BEEP 0.5, 0 воспроизведет ноту ДО первой октавы в течение полсекунды, а BEEP 0.5, 12 - ту же ноту ДО, но уже второй ок- тавы. Указанное нотоисчисление не очень точ- но, поэтому взгляните на рис.3. Там в верхней строчке приведены приблизительные, а в нижней - точные параметры оператора BEEP для первой октавы. Музыкальный диапазон BEEPа достаточно широк - от -60 до 69. Он охватывает 18,5 октав, но самые низкие и самые высокие из них не представляют практического интере- са для создания музыки, хотя вполне могут использоваться в звуковых эффектах. И в заключение можно добавить об удоб- стве, которое Spectrum-бейсик предостав- ляет нам в записи десятичных дробей. Если такая дробь меньше единицы, то ноль перед точкой можно не ставить. Таким образом, BEEP 0.125,11 можно записать как BEEP .125,11. Дальше по тексту книги я именно так и буду делать. 2.1. Создание эффектов на BEEPе Для того, чтобы сделать что-либо поин- тереснее простых гудков, оператор BEEP обычно включается в какой-нибудь цикл, где изменяются один или оба его параметра. Простейший пример может выглядеть так: 10 FOR A=0 TO 60 20 BEEP .01,A 30 NEXT A Эту маленькую программку можно долго и упорно изменять, получая все новые и новые эффекты. Попробуйте модифицировать преде- лы, шаг, направление цикла, длительность в операторе BEEP. Как это сделать, я думаю, понятно всем, поэтому примеров приводить не буду. Во время ваших экспериментов пом- ните, что при маленьких длительностях низ- кие ноты воспроизводиться не будут, и чем ниже нота, тем больше должна быть дли- тельность. Когда Вам надоест занятие, предложенное в предыдущем абзаце, можно переходить к следующему этапу - изменению "внутреннос- тей" цикла... Можно увеличить число операторов BEEP. Причем они могут быть настроены как на одинаковые частоты и длительности, так и на разные: 10 FOR A=0 TO 20 20 BEEP .007,A+7: BEEP .003,A 30 NEXT A Диапазон звучания дополнительных BEEPов можно ограничить: 10 FOR A=0 TO 69 20 BEEP .01,A 30 IF A>20 AND A<40 THEN BEEP .01,A+8 40 NEXT A или так: 10 FOR A=0 TO 69 20 BEEP .0003,A-6: BEEP .001,A-3: BEEP .01,A 30 NEXT A Последний эффект интересен тем, что в нем второй и третий BEEPы вступают постепенно (см. сноску на предыдущей странице). Эффект можно замедлить с помощью опера- тора PAUSE: 10 FOR A=10 TO 40 STEP 2 20 BEEP .01,A: PAUSE 2 30 NEXT A Можно в течение воспроизведения менять длительность: 10 LET T=.01 20 FOR A=10 TO 60: BEEP T,A 30 LET T=T-.0002: NEXT A 10 FOR A=0 TO 60 20 BEEP A/500,60-A 30 NEXT A В первом из этих примеров попробуйте поме- нять шаг или направление изменения дли- тельности, начальное ее значение. Следующий вариант - вложенные циклы, которых может быть сколько угодно. BEEPы могут встречаться в любом из них: 10 FOR A=2 TO 5: BEEP .01,A 20 FOR B=20 TO 30: BEEP .01,B 30 NEXT B: NEXT A 10 FOR A=1 TO 40 STEP 10 20 FOR B=A TO A+20 30 BEEP .03,B 40 NEXT B: NEXT A Попробуйте объединить несколько циклов. Например: 10 FOR A=12 TO 69: BEEP .001,A 20 NEXT A 30 FOR A=69 TO 12 STEP -1 40 BEEP .001,A: NEXT A И, наконец, во всю эту коллекцию можно добавить элемент случайности: 10 FOR A=1 TO 10: LET F=RND*50 20 BEEP .1,F: BEEP .1,F+7: BEEP .1,F+4 30 NEXT A 10 FOR A=1 TO 20 20 BEEP .1,RND*20+40 30 NEXT A 10 FOR A=1 TO 20 20 BEEP RND/6,RND*60 30 NEXT A Все перечисленные выше методы создания эффектов могут использоваться совместно, в любой комбинации. Ищите, пробуйте, и Вы найдете среди множества парочку подходящих для Вашей программы эффектов. 2.2. Создание музыки на BEEPе К сожалению, на операторе BEEP невоз- можно создать сложную музыку, но наиграть простенькую мелодию на нем можно. Первое, что приходит в голову при по- пытке создать мелодию - это составить це- почку из BEEPов, которая обещает быть ве- сьма неопределенных размеров. Этот способ примитивен, неудобен, занимает много мес- та и вообще не очень красив. Ему сущес- твует несколько достойных замен. Например, можно использовать такой цикл: 10 FOR A=1 TO 10 20 READ T,F: BEEP T,F 30 NEXT A И где-нибудь в программу вставить строку, начинающуюся с оператора DATA и содержа- щую длительности и высоты нот мелодии. В данном примере их должно быть по десять. В некоторых музыкальных произведениях бывают паузы. Чтобы исполнять такие мело- дии, приведенный выше цикл придется немно- го модифицировать: 10 FOR A=1 TO 10: READ T,F 20 IF T=0 THEN PAUSE F*50: NEXT A 30 BEEP T,F: NEXT A Теперь достаточно в данные вставить 0, а за ним длительность паузы в секундах. Вы, наверное, заметили, что значение паузы умножается на 50. Это делается пото- му, что параметр оператора PAUSE исчис- ляется в пятидесятых долях секунды. В таб- лице 1 приведено соответствие нот дли- тельностям операторов BEEP и PAUSE. В этой таблице даны стандартные значения нот и пауз, но в принципе можно использовать лю- бые числа. Вот, к примеру, программа, исполняющая куплет детской песенки "В лесу родилась елочка": 10 FOR A=1 TO 29: READ T,F 20 IF T=0 THEN PAUSE F*50: NEXT A 30 BEEP T,F: NEXT A 9000 DATA .25,7.02,.25,15.86,.25, 15.86,.25,14.039,.25,15.86 9010 DATA .25,12,.25,7.02,.25,7.02, .25,7.02,.25,15.86,.25,15.86 9020 DATA .25,14.039,.25,20.84,.5, 19.02,0,.5,.25,19.02,.25,8.84 9030 DATA .25,8.84,.25,16.98,.25, 16.98,.25,15.86,.25,14.039,.25, 12 9040 DATA .25,7.02,.25,15.86,.25, 15.86,.25,14.039,.25,15.86,.5, 12 В эту программу можно ввести возмож- ность изменения темпа. Для этого необходи- мо первые три строки заменить следующими: 5 LET N=.5 10 FOR A=1 TO 29: READ T,F 20 IF T=0 THEN PAUSE F*N*50: NEXT A 30 BEEP T*N,F: NEXT A Теперь Вы можете добиться желаемого темпа исполнения мелодии, подставляя раз- личные значения в пятую строку. Однако не советую Вам вставлять туда 0 и очень боль- шие числа. Можно еще усовершенствовать эту прог- раммку. Например, вставить контроль нажа- тия клавиши, сделать ее более гибкой в от- ношении длины мелодии, оформить как под- программу и т.д. Конечный вариант может выглядеть так: 9090 DATA 100 9100 LET N=.5: RESTORE 9000 9110 READ T,F 9120 IF T=100 OR INKEY$<>"" THEN RETURN 9130 IF T=0 THEN PAUSE F*N*50: GO TO 9110 9140 BEEP T*N,F: GO TO 9110 Удалите все строки с 5 по 30 предыдущей программы и введите эти. Теперь Вы можете вызывать мелодию на исполнение оператором GO SUB 9100. Кроме того, теперь не надо старательно вычислять количество нот в ме- лодии: достаточно в ее конец вставить чис- ло 100 (что, собственно, и сделано в стро- ке 9090). Также Вы можете в любой момент прервать исполнение, нажав любую клавишу. Если мелодия кончится - подпрограмма так- же закончит свою работу. При повторном за- пуске мелодия начнется сначала, но если убрать оператор RESTORE 9000, то она про- должится с того места, где была прервана (если, конечно, Вы не использовали опера- тор READ или RESTORE после ее вызова). Можно сделать проигрывание цикличес- ким. Для этого придется поменять еще пару строк: 9120 IF INKEY$<>"" THEN RETURN 9125 IF T=100 THEN GO TO 9100 Теперь вернуться из подпрограммы можно только по нажатию клавиши. Зато мелодия будет звучать, пока кому-нибудь совсем не надоест. Программы такого типа идеальны для простого исполнения, без замены и сохране- ния мелодии, но если Вы хотите записать свое произведение на магнитофон и загру- жать его прямо из работающей программы, то Вам подойдет следующий фрагмент: 10 FOR A=3 TO D(1)*2+2 STEP 2 20 IF D(A)=0 THEN PAUSE D(A+1)*D(2)*50: NEXT A 30 BEEP D(A)*D(2),D(A+1) 40 NEXT A Для того, чтобы он заработал, перед его запуском необходимо объявить и заполнить массив D, содержащий такую информацию о мелодии: D(1) - количество нот D(2) - темп исполнения D(3) - длительность 1 D(4) - нота 1 . . . D(N) - длительность N D(N+1) - нота N Его можно загрузить с кассеты, подав пря- мую команду LOAD "name" DATA D() или заполнить из строчек DATA следующей программкой: 10 DIM D(20): RESTORE 20 FOR A=1 TO 20: READ D(A) 30 NEXT A Обратите внимание, что первые две цифры данных должны быть количеством нот и тем- пом. Созданный таким образом массив можно сохранить на ленте командой SAVE "name" DATA D() Приведу еще один пример подобной прог- раммы, оформленный по последнему писку мо- ды: 9100 LET A=2 9110 IF D(A)=100 THEN GO TO 9100 9120 IF INKEY$<>"" THEN RETURN 9130 IF D(A)=0 THEN PAUSE D(A+1)*D(1)* 50: GO TO 9150 9140 BEEP D(A)*D(1),D(A+1) 9150 LET A=A+2: GO TO 9110 Массив для этой подпрограммы должен быть таким: D(1) - темп исполнения D(2) - длительность 1 D(3) - нота 1 . . . D(N) - длительность N D(N+1) - нота N D(N+2) - 100 Заметьте, что количество нот указывать не надо. На основе этого примера можно сделать даже музыкальный редактор. Теперь вернемся к составлению цепочек данных. Допустим, на нотном стане Вы увидели ноту точь-в-точь, как на рис.4. Это ЛЯ первой октавы. Из рисунка 1 видно, что ее частота запишется как 8.84. Это одна четвертая, и, взглянув на таб- лицу 1, можно определить, что ее длитель- ность будет .25. Таким образом, пара дан- ных для этой ноты будет .25,8.84. Для всех последующих нот вычисления будут такими же.
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября