ZX Forum
#04
19 ноября 1997 |
|
Мир звуков Спектрума - глава 4.4: Программирование звуковых эффектов - Программирование музыки.
4.4. Программирование музыки Программирование музыки в кодах - заня- тие неблагодарное. Лучше это делать с по- мощью какого-нибудь музыкального редакто- ра. Но редактор может не удовлетворить все Ваши потребности, так что освоить програм- мирование в кодах все же желательно. Принцип тот же - последовательно чи- таются данные и вызывается процедура вос- произведения. При этом необходимо предус- мотреть прерывание исполнения (чаще всего в этих целях контролируется нажатие ка- кой-нибудь клавиши). Например: 1415. 10 START LD HL,60000 ; HL=адрес данных 20 NEXT LD E,(HL) ; DE= 30 INC HL ; дли- 40 LD D,(HL) ; тель 50 INC HL ; ность 60 LD A,D ; DE 70 CP 255 ; = 80 JR NZ,CONT ; 65535 90 LD A,E ; ? 100 CP 255 ; если да, 110 JR Z,START ; то мелодия сначала 120 CONT LD A,D ; DE= 130 OR E ; 0 ? 140 JR NZ,BEEP ; если нет, то перейти на BEEP 150 LD E,(HL) ; DE= 160 INC HL ; длитель- 170 LD D,(HL) ; ность 180 INC HL ; паузы 190 PAUSE HALT ; ожидание прерывания 200 DEC DE ; DE=DE-1 210 LD A,D ; DE= 220 OR E ; 0 ? 230 JR NZ,PAUSE ; если нет, то цикл 240 JR NEXT ; переход на обработку след. данных 250 BEEP LD C,(HL) ; BC= 260 INC HL ; час- 270 LD B,(HL) ; то- 280 INC HL ; та 290 PUSH HL ; сохранение HL 300 PUSH BC ; поместить BC в стек 310 POP HL ; поместить значение из стека в HL 320 CALL 949 ; вызов подпрограммы воспроизведения 330 CALL 654 ; контроль клавиатуры 340 POP HL ; восстановление HL 350 LD A,E ; A=E 360 CP 255 ; если нажата клавиша, 370 RET NZ ; то возврат в бейсик 380 JR NEXT ; переход на обработку след. данных 2 При вызове этой подпрограммы из машин- ных кодов обратите внимание, что прерыва- ния должны быть разрешены! Иначе, если в данных первой будет стоять пауза, компью- тер "зависнет". Перед использованием этой довольно страшненькой подпрограммы необходимо соз- дать для нее массив данных (это и есть са- мое веселое). В данном случае он должен располагаться с адреса 60000 (#EA60), но Вы можете легко изменить его местонахожде- ние, поменяв число в первой строке этой подпрограммы. Данные для каждой ноты должны быть сле- дующими: сначала два байта длительности (первый - младший), затем два байта часто- ты. Если вместо длительности поместить два нуля, то следующая пара байт будет рас- сматриваться как длина паузы. Чтобы отме- тить конец мелодии, вставьте в данные вме- сто очередной длительности два байта 255. Длительность паузы измеряется в пятиде- сятых долях секунды, а в чем измеряется длительность ноты - не знает, наверное, никто, хотя рассчитать необходимое значе- ние все же можно (см. главу 4). Теперь о недостатках, которых, честно говоря, хоть отбавляй. Два из них уже бы- ли упомянуты выше: трудность составления мелодии и довольно странное измерение дли- тельности нот. Кроме того, длительность зависит от частоты. Например, если Вы вве- дете такие данные: 0,1,100,0,0,1,0,5,255, 255, то не услышите две разные ноты одина- ковой длины, как ожидали. Еще один недостаток - возможность прер- вать исполнение только в промежутке между нотами. Впрочем, это можно легко испра- вить: 1415. 10 START LD HL,60000 ; HL=адрес данных 20 NEXT LD E,(HL) ; DE= 30 INC HL ; дли- 40 LD D,(HL) ; тель 50 INC HL ; ность 60 LD A,D ; DE 70 CP 255 ; = 80 JR NZ,CONT ; 65535 90 LD A,E ; ? 100 CP 255 ; если да, 110 JR Z,START ; то мелодия сначала 120 CONT LD A,D ; DE= 130 OR E ; 0 ? 140 JR NZ,BEEP ; если нет, то перейти на BEEP 150 LD E,(HL) ; DE= 160 INC HL ; длитель- 170 LD D,(HL) ; ность 180 INC HL ; паузы 190 PAUSE XOR A ; A=0 (контроль всей клавиа- туры) 200 IN A,(254) ; опрос клавиш 210 CPL ; инвертирование A 220 AND 31 ; сброс лишних битов 230 RET NZ ; если нажата клавиша, то воз- врат 240 HALT ; ожидание прерывания 250 DEC DE ; DE=DE-1 260 LD A,D ; DE= 270 OR E ; 0 ? 280 JR NZ,PAUSE ; если нет, то цикл 290 JR NEXT ; переход на обработку след. данных 300 BEEP LD C,(HL) ; BC= 310 INC HL ; час- 320 LD B,(HL) ; то- 330 INC HL ; та 340 PUSH HL ; сохранение HL 350 PUSH BC ; поместить BC в стек 360 POP HL ; поместить значение из стека в HL 370 CALL PLAY ; вызов подпрограммы воспроизведения 380 POP HL ; восстановление HL 390 RET NZ ; то возврат в бейсик 400 JR NEXT ; переход на обработку след. данных 410 PLAY DI ; запрет прерываний 420 LD A,(23624) ; A= 430 SRL A ; цвет 440 SRL A ; бор- 450 SRL A ; дюра 460 LOOP1 XOR 16 ; инвертирование бита D4 470 OUT (254),A ; вывод A в порт 254 480 LD C,A ; сохранение A 490 PUSH HL ; сохранение HL 500 LOOP2 XOR A ; A=0 (контроль всей клавиа- туры) 510 IN A,(254) ; опрос клавиш 520 CPL ; инвертирование A 530 AND 31 ; сброс лишних битов 540 JR Z,CONT2 ; если клавиша не нажата, то продолжить 550 POP HL ; снять значение со стека 560 EI ; разрешение прерываний 570 RET ; возврат 580 CONT2 DEC HL ; HL=HL-1 590 LD A,H ; HL= 600 OR L ; 0 ? 610 JR NZ,LOOP2 ; если нет, то цикл 620 POP HL ; восстановление HL 630 DEC DE ; DE=DE-1 640 LD A,D ; DE= 650 OR E ; 0 ? 660 LD A,C ; восстановление A 670 JR NZ,LOOP1 ; если DE<>0, то цикл 680 EI ; разрешение прерываний 690 RET ; возврат 2 Обратите внимание на то, что одинаковые данные будут воспроизводиться по-разному этой и предыдущей подпрограммами. И, наконец, самый очевидный недоста- ток - музыка, которая получается с помощью этих подпрограмм, слишком примитивна. На ассемблере можно сделать что-нибудь и по- серьезнее. Надеюсь, что убедил Вас не пытаться программировать музыку напрямую в кодах, а вместо этого приобрести хороший музыкаль- ный редактор. Все подпрограммы, приведенные в этой главе, можно использовать и для создания эффектов. Для этого достаточно вместо нот закодировать отдельные ступени эффекта. Желательно, чтобы каждая ступень была как можно короче, тогда эффект будет звучать плавно.
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября