ZX-Ревю 1992 №11-12 1991 г.

Профессиональный подход - продолжение разговора о некоторых приемах, позволяющих придать "профессионализм" вашим программам.


ПРОФЕССИОНАЛЬНЫЙ ПОДХОД

Сегодня - продолжение разговора о некоторых приемах, позволяющих придать "профессионализм" вашим программам. Мы поговорим о небольших кодовых блоках, позволяющих воспроизводить различные звуковые эффекты в ваших программах, такие, какие невозножно создать, непосредственно используя оператор "ВЕЕР". Это, например, стрельба из лазерного пистолета, пуск ракеты, торпеды, получение приза и т.д. Также разговор будет о программе "SOUND", позволяющей создавать и редактировать такие звуки. Попутно, в качестве лирического отступления, остановимся еще на одной теме: о том, как усовершенствовать введение числовых параметров при помощи оператора "INPUT". Кроме того, рассматривая готовую программу, мы еще раз проследим все моменты, изложенные в предыдущие статьях: применение блока "ON ERROR GO ТО", структура программы, управление программой при помощи меню и т.д.

За основу разработки взята программа "SPECSOUND" фирмы OZ SOFTWARE. Возможно, читателям известен еще один, более ранний прообраз этой программы "DZWIEKI". Взяв за основу принцип формирования кодовых блоков, воспроизводящих звуки, вся программа была изменена настолько, что стала возможна эффективная работа по созданию и редактированию звуков. Кроме того, устранены многие программные ошибки, и сделан перевод на русский язык. В общем, это стала практически другая программа, однако идея осталась той же. Структура самих кодовых блоков, получаемых в результате работы программы, изменена незначительно, лишь настолько, насколько это не повредило совместимости с прототипом программы.

В основе кодового блока одного звука лежит использование подпрограммы из ПЗУ "BEEPER", расположенной по адресу #03В5. При входе в эту подпрограмму, в регистре DE должно быть задано произведение частоты на время звучания звука, (то есть число периодов колебаний), а в регистре HL - величина, эквивалентная значению периода колебаний. Подробнее о работе подпрограммы "BEEPER" было рассказано на страницах ZX-РЕВЮ в разделе "СЕКРЕТЫ ПЗУ" см. N2 за 1991г. СТР. 28.

В общих словах, принцип формирования звука таков. Организуется цикл из последовательного обращения к подпрограмме "BEEPER", но при каждом следующем обращении период колебаний изменяется на определенную величину по сравнению с начальным тоном (может увеличиваться или уменьшаться). При этом, если величина смещения или ступеньки тона, незначительная, а число обращения к подпрограмме "BEEPER" (число ступенек тона) в цикле - большое, то на слух получится плавно изменяющийся звук - "скольжение" тона. Кроме того, получившееся "скольжение" входит в еще один цикл повторений, то есть большое число таких "скольжений" формируют результирующий звук. Изменяя исходные параметры в широких пределах и комбинируя их в различных взаимных сочетаниях, можно получать интересные звуковые эффекты. Имеется также возможность объединения двух или нескольких результирующих звуков в один (последовательное выполнение двух или более звуков), что открывает дополнительные возможности по созданию звуковых эффектов.

Для тех, кто интересуется машинными кодами, рассмотрим подробно блок кодов, воспроизводящий один звук. Если коды Вас не интересуют, то пропустите этот раздел и переходите непосредственно к Бейсик-программе "SOUND".

Блок кодов, воспроизводящий звук.

Длина блока - 32 байта. Его можно загружать в любое место памяти. Стартовый адрес блока равен адресу загрузки. Для примера, расположим его с адреса #АВ00, звездочкой справа отмечены параметры, которые могут меняться.

АВ00 0Е00 LD C,#00 (1)

АВ02 0605 LD B,#05 (2) *

АВ04 21F401 LD HL,#01F4 (3) *

АВ07 С5 PUSH ВС (4)

АВ08 114600 LD DE,#0046 (5) *

АВ0В Е5 PUSH HL (6)

АВ0С CDB503 CALL #03В5 (7)

AB0F E1 POP HL (8)

AB10 112800 LD DE,#0028 (9) *

AB13 ED52 SBC HL,DE (10) *

AB15 C1 POP ВС (11)

AB16 10EF DJNZ #AВ07 (12)

AB18 3E02 LD A,#05 (13) *

AB1A 0С INC C (14)

AB1B B9 CP C (15)

AB1C 20E4 JR NZ,#AB02 (16)

AB1D 00 NOP (17)

AB1F C9 RET (18)

Сначала (1) обнуляется счетчик числа повторений "скольжения" - (внешнего цикла) -регистр С. Затем (2) в регистр B заносится число ступенек тона (число повторений внутреннего цикла), а в регистр HL - период начального тона (3). Далее начинает выполняться внутренний цикл. На стеке запоминается (4) содержимое регистров B и C (так как оно будет изменено после отработки подпрограммы "BEEPER"). Потом (5) в регистр DE заносится число периодов колебаний, которые будут выработаны подпрограммой "BEEPER". Чем меньше это число, то есть чем меньшее число колебаний будет выполнено перед очередным изменением периода колебаний, тем более плавным на слух будет "скольжение" тона. Другими словами эту величину можно охарактеризовать как дискретность получающегося звука. Затем на стеке запоминается (6) содержимое регистра HL (по той же причине, что и ВС), выполняется подпрограмма "BEEPER" (7) и возвращается со стека (8) содержимое HL. теперь надо изменить величину тона перед следующим вызовом подпрограммы "BEEPER". Для этого величина смещения (или ступеньки тона) заносится (9) в регистр DE, после чего (10) отнимается от содержимого регистра HL. (Если вместо SBC задан код команды ADC, тогда DE складывается с HL. Таким образом можно задать повышение или понижение тона "скольжения".) Теперь в HL - новое значение периода колебаний. Далее возвращается со стека (11) значение BC и проверяется величина B - счетчика внутреннего цикла. Если заданное число повторений внутреннего цикла не выполнено, то происходит (12) очередное повторение внутреннего цикла (с адреса #АВ07) с измененным значением периода колебаний. А если счетчик внутреннего цикла обнулен, то продолжается выполнение программы. В регистр A заносится (13) число повторений "скольжений" (внешнего цикла). Так как один внешний цикл уже завершен, то происходит увеличение на единицу (14) счетчика внешних циклов - регистра C. Потом это значение сравнивается (15) с тем, что задано в А. Если число в А больше, чем в C (то есть разница не равна нулю), то происходит (16) возврат на повторение внешнего цикла с адреса #АВ02 (выполнение следующего "скольжения"). Если заданное число внешних циклов выполнено, то (17), (18) завершение работы - возврат в вызывающую программу. Необходимость команды NOP в конце программы объясняется желанием сохранить совместимость с прообразом программы "SOUND".

Это то, что касается кодового блока. Теперь рассмотрим Бейсик-программу для редактирования кодовых блоков звуков.

Программа "SOUND"

Сначала несколько слов о том, что же может эта программа. Во-первых, она может продемонстрировать 20 готовых звуков, созданных для примера с ее помощью. Прослушав их, Вы сможете примерно оценить "диапазон" возможностей программы. Вы также можете получить для записи на магнитофон любой (или любые несколько, по выбору) или все 20 примеров звуков для дальнейшего использования в своих программах.

Во-вторых, программа позволяет создавать новые звуки и эффективно заниматься редактированием любого из созданных звуков. При создании нового звука можно, взяв за основу один из имеющихся 20 примеров, подробно "рассмотреть" параметры звука и по мере необходимости изменять их, добиваясь требуемого звучания. Можно также объединить два и более готовых звука в один, чтобы получать комплексные звуковые эффекты. Готовые звуки можно записать на магнитную ленту. Можно также загружать с магнитной ленты для редактирования блоки кодов - звуки, полученные при помощи этой программы.

Область памяти для создания и редактирования звуков определена с адреса 43776 (#AВ00) (может быть изменена по Вашему желанию). Максимальное число создаваемых звуков ограничено областью до конца памяти и составляет 680 звуков. Наверное, это заведомо превышает возможности любого пользователя, поэтому в программе не предусмотрена проверка на достижение конца памяти. При необходимости, Вы можете сами организовать такую проверку, если захотите.

При работе, программа отличается "деликатностью", а именно, она предлагает возможные варианты ответа, предупреждает, если результат неудовлетворительный и рекомендует, что надо сделать, чтобы добиться положительного результата.

Рассматривая текст программы, вы увидите, что структура программы - такая же, как была описана в ZX-РЕВЮ N 9-10 за этот год, когда речь шла о дебюте программы "PROG". Поэтому, если вам непонятны некоторые моменты, то еще раз прочтите о дебюте "PROG".

Итак, текст программы "SOUND", затем комментарии.

0 REM КОДЫ

1 GO ТО 100

3 RANDOMIZE 3: GO SUB 10: GO SUB 7: GO SUB 8: BORDER 1: PAPER 0: INK 6: CLEAR 43775: PRINT

BRIGHT 1;AT 2,10: "ПРОГРАММА ДЛЯ"; AT 3,6; "РЕДАКТИРОВАНИЯ ЗВУКОВ"; PAPER 2; INK 7; DIVERSE 1;AT 8,8; " ";AT 9,8: " S O U N D "; AT 10,8; "

"; PAPER 0; INK 2; INVERSE 0;AT 15,3; "OZ SOFTWARE + АЛЕКСЕЕВ А. Г. "

4 PRINT INK 4; BRIGHT 1;AT 18,12; "01.08.92": BEEP.1,26: BEEP .1,20: GO SUB 20: GO TO 100

5 SAVE "SOUND" LINE 2

6 VERIFY "SOUND": GO TO 5

7 RANDOMIZE PEEK 23635+256*PEEK 23536+773: POKE 23675,PEEK 23670: POKE 23676, PEEK 23671:

RETURN : REM UDG

8 RANDOMIZE PEEK 23635+256*PEEK 23536-251: POKE 23606,РЕЕК 23570: POKE 23607,PEEK 23671:

RETURN: REM RUS

9 POKE 23606,0: POKE 23607,60: RETURN : REM LAT

10 POKE PEEK 23635+256*PEEK 23636+993, PEEK 23670: POKE PEEK 23535+256*PEEK 23636+994, PEEK

23671: RANDOMIZE USR (PEEK 23635+256*PEEK 23636+941): RETURN 20 INPUT ; : PRINT #0; PAPER 6; INK 2; BRIGHT 1; AT 1,5:" НАЖМИТЕ ЛЮБУЮ КЛАВИШУ " 22 RANDOMIZE 24: GO SUB 10: PAUSE 0 24 IF INKEY$="q" THEN GO TO 9999 26 RETURN

30 BORDER 1: PAPER 0: INK 6: CLS

31 FOR M=1 TO NN: READ M$: PRINT AT (Y0+(M-1)*DY), X0;N$: NEXT M: PRINT INK 4; AT Y1,3;

"SPACE,DOWN,UP,0,ENTER,BREAK"

32 IF MM<1 THEN LET MM=NN

33 IF MM>NN THEN LET MM=1

34 PRINT AT (Y0+(MM-1)*DY),X0-DX; PAPER 7; INK 2; BRIGHT 1; OVER 2;S$: BEEP .03,2*MM+10

35 PAUSE 0: LET I=(INKEY$=" " OR INKEY$="6" OR CODE INKEY$=10)+(INKEY$="7" OR CODE

INKEY$=11)*2+(INKEY$="0" OR CODE INKEY$=12 OR CODE INKEY$=13)*3+(INKEY$="q")*4: GO TO (35+I)

37 PRINT AT (Y0*(MM-1)*DY),X0-DX; OVER 1;S$: LET MM=MM-2*I+3:GO TO 32

38 BEEP .1,36: RETURN

39 GO TO 9999

40 RANDOMIZE 49: GO SUB 10: BORDER 1: PAPER 1: INK 7: CLS 42 PRINT AT 1,0;" ЭТА ПРОГРАММА ПРЕДНАЗНАЧЕНА

ДЛЯ СОЗДАНИЯ БЛОКОВ МАШИННЫХ КОДОВ, КОТОРЫЕ ВОСПРОИЗВЕДУТ РАЗЛИЧНЫЕ ЗВУКОВЫЕ ЭФФЕКТЫ В ВАШИХ ПРОГРАММАХ ( НАПРИМЕР, СТРЕЛЬБА ИЗ ЛАЗЕРНОГО ПИСТОЛЕТА, ПУСК РАКЕТЫ, ПОЛУЧЕН ИЕ ПРИЗА И ДР. ) " 44 PRINT '" БЛОКИ КОДОВ МОГУ Т БЫТЬ РАЗМЕЩЕНЫ ЗА RAMTOP ИЛИ ИХ МОЖНО РАС-

ПОЛОЖИТЬ В ПЕРВОЙ (ИЛИ НУЛЕВОЙ) СТРОКЕ BASIC ЗА ОПЕРАТОРОМ REM. " 46 PRINT '" БЛОК КОДОВ, ВОСПРОИЗВОДЯЩИЙ ОДИН ЗВУК, ИМЕЕТ ДЛИНУ 32 БАЙТА. ЕГО МОЖНО ПЕРЕМЕЩАТЬ В ПАМЯТИ. СТАРТОВЫЙ АДРЕС ДЛЯ ВОСПРОИЗВЕДЕНИЯ ЗВУКА БУДЕТ РАВЕН АДРЕСУ ЗАГРУЗКИ. " 48 ВЕЕР .1,20: GO SUB 20: RETURN

50 RANDOMIZE 59: GO SUB 10: PRINT PAPER 6; INK 2; AT 2,6:" ЧИСЛО ЗВУКОВ: "; FLASH 1;B: PAUSE 50

52 FOR J=1 TO B: PRINT PAPER 6; INK 2: AT 4,9;" ЗВУК НОМЕР ";J;" ": RANDOMIZE USR (U+32*(J-1)): PAUSE 60: NEXT J

59 RETURN

60 PRINT PAPER 2: INK 7; BRIGHT 1; FLASH 1;AT 2,6;" ВЫ УВЕРЕНЫ (Y/N)? ": PAUSE 0: RETURN 70 LET SEC=INT (H*C*(2*E+Z«(G-1)*F)*G/8E5): IF SEC<=10 THEN RETURH

72 LET Т=INT(SEC/60): LET S=SEC-60*T 74 CLS : РRINT AT 5,0: " ОБРАЩАЕМ ВАШЕ ВНИМАНИЕ НА ТО, ЧТО ВРЕМЯ ЗВУЧАНИЯ ЗВУКА БУДЕТ

СОСТАВЛЯТЬ ПРИМЕРНО:"; AT 9,9; Т: " МИН. ";S;" СЕК. "; AT 11,0; " ВЫ ГОТОВЫ К ПРОСЛУШИВАНИЮ ?"" " ЕСЛИ ДА, ТО НАЖМИТЕ [Y]; ЕСЛИ

ВОЗВРАТ В МЕНЮ ТО ЛЮБУЮ КЛАВИШУ."" " ПОСЛЕ ВОЗВРАТА В МЕНЮ НАДО УМЕНЬШИТЬ ДИСКРЕТНОСТЬ ЗВУКА. ЧИСЛО СТУПЕНЕК ТОНА ИЛИ ПЕРИОД НАЧАЛЬНОГО ТОНА." 76 ВЕЕР .5,0: PAUSE 0: RETURN 100 LET P=0

110 LET B=20: LET U=PEEK 23635+256*РЕЕК 23636+1014 190 LET MM=1

200 RANDOMIZE 190: GO SUB 10: RESTORE 200: LET NN=4: LET Y0=6:LET X0=3: LET DY=2: LET DX=1:

LET S$=" ":': LET Y1=18: GO SUB 30: GO TO 200+10*MM

210 LET U=43776: LET E=P: GO TO 300 220 GO SUB 50: GO TO 200 230 GO SUB 6000: LET MM=1: GO TO 200 240 GO SUB 40: LET MM=1: GO TO 200

299 DATA "РАБОТА С РЕДАКТОРОМ ЗВУКОВ","ДЕМОНСТРАЦИЯ ПРИМЕРОВ 3ВУКOB","ЗАПИСЬ ПРИМЕРОВ

ЗВУКОВ","ИНФОРМАЦИЯ О ПРОГРАММЕ"

300 RANDOMIZE 390: GO SUB 10: RESTORE 300: LET NN=9: LET Y0=6: LET X0=4: LET DY=1: LET DX=1:

LET S$=" ": LET Y1=18: GO SUB 30

302 IF B=0 AND MM<>1 AND MM<>7 AND MM<>9 THEN PRINT PAPER 6;INK 2;AT 2,2:" СНАЧАЛА НАДО

СОЗДАТЬ ЗВУК ": ВЕЕР .5,0: PAUSE 50: LET MM=1: GO ТО 300 304 GO ТО 300+10*MM 310 GO TO 1000 320 GO то 2000 330 GO TO 4000

340 IF B<2 THEN PRINT PAPER 6; INK 2: AT 2,1;" СНАЧАЛА НАДО СОЗДАТЬ 2 ЗВУКА ": ВЕЕР .5,0:

PAUSE 50: LET MM=1: GO TO 300 345 GO TO 5000 350 GO SUB 50: GO TO 300 360 GO SUB 6000: LET MM=1: GO ТО 300 370 GO TO 7000 380 LET ММ = 1: GO TO 500 390 LET P=B: GO TO 190

399 DATA "СОЗДАНИЕ НОВОГО ЗВУКА","РЕДАКТИРОВАНИЕ ЗВУКА","ИЗМЕНЕНИЕ ЧИСЛА

ПОВТОРЕНИЙ","СОЕДИНЕНИЕ ДВУХ ЗВУКОВ"," ДЕМОНСТРАЦИЯ ЗВУКОВ", "ЗАПИСЬ ЗВУКОВ", "ЗАГРУЗКА 3BУKOB", "УДАЛЕНИЕ ЗВУКОВ", "ВОЗВРАТ В ГЛАВНОЕ МЕНЮ"

400 RANDOMIZE 402: GO SUB 10: RESTORE 400: LET NN = 2: LET Y0=9:LET X0=8: LET DY = 2: LET DX

= 2: LET S$=" ": LET Y1=18: GO SUB 30

402 GO TO 400+10*ММ 410 LET Z=-1: POKE A+20,82: RETURN 420 LET Z=1: POKE A+20,90: RETURN 499 DATA "ПОВЫШЕНИЕ ТОНА","ПОНИЖЕНИЕ ТОНА"

500 RANDOMIZE 504: GO SUB 10: RESTORE 500: LET NN=2: LET Y0=9: LET X0=3: LET DY=2: LET DX=1:

LET S$=" ": LET Y1=18: GO SUB 30

502 GO SUB 60: IF INKEY$="y" OR INKEY$="Y" THEN GO TO 500+10*MM 504 LET MM=1: GO TO 300 510 LET B=B-1: GO TO 504 520 RUN 3 599 DATA "УДАЛЕНИЕ ПОСЛЕДНЕГО ЗВУКА"," ПЕРЕЗАПУСК ПРОГРАММЫ" 1000 PAPER 1: INK 7: CLS 1010 PRINT AT 4,0;

" ЕСЛИ ВЫ ХОТИТЕ ЗА ОСНОВУ ЗВУКА ВЗЯТЬ ПРИМЕР, ИЗ ИМЕЮЩИХСЯ В ПРОГРАММЕ, ВВЕДИТЕ НОМЕР ЭТОГО

ПРИМЕРА....... ЕСЛИ НЕТ, ТО НАЖМИТЕ (ENTER)."

1020 LET B=B+1: LET P=B: LET N=B-INT(В/20)*20

1030 RANDOMIZE 1030: GO SUB 10:INPUT ("НОМЕР ПРИМЕРА (1-20): ";N;" : "): LINE F$: IF F$<>""

THEN LET N=VAL F$ 1040 IF N<1 OR N>20 THEN GO TO 1030 1050 PRINT AT 13,0;" ВАМ В ДИАЛОГЕ БУДУТ ПРЕДЛОЖЕНЫ ЧИСЛОВЫЕ ПАРАМЕТРЫ. ЕСЛИ ХОТИТЕ ИЗМЕНИТЬ ИХ, ВВЕДИТЕ СВОИ ЗНАЧЕНИЯ." ' '

" ЕСЛИ НЕТ, НАЖИМАЙТЕ [ENTER]. 1060 RANDOMIZE 1060: GO SUB 10:LET A=U+32*(B-1): LET Y=PEEK 23635+256*PEEK 23636+1014+32*(N-1)

1070 FOR R = 0 TO 31: POKE (A+R),(PEEK (Y+R)): NEXT R 1060 GO SUB 20: GO TO 3000 2000 PAPER 1: INK 7: CLS

2010 RANDOMIZE 2010: GO SUB 10:PRINT AT 21,0: "НОМЕР РЕДАКТИРУЕМОГО ЗВУКА": INPUT ("(1-

";B;"):";P;" : "); LINE F$: IF F$<>" THEN LET P=VAL F$ 2020 IF P<1 OR P>B THEN GO TO 2010 2030 LET A=U+32*(P-1) 2040 GO TO 3000 2500 CLS : PRINT AT 7,0;" ИЗМЕНЕНИЕ ТОНА ОЧЕНЬ ВЕЛИКО, ПОЭТОМУ В РЕЗУЛЬТАТЕ ТОН СТАНЕТ НИЖЕ МИНИНАЛЬНОЙ ВЕЛИЧИНЫ. " 2510 IF Z=-l THEN PRINT AT 9,0;"ВЫШЕ МАКС"; 2520 PRINT ''" НАДО ИЗМЕНИТЬ НАЧАЛЬНЫЙ ТОН, УМЕНЬШИТЬ ВЕЛИЧИНУ СТУПЕНЬКИ ТОНА ИЛИ ЧИСЛО СТУПЕНЕК ТОНА." 2530 ВЕЕР .5,0: GO SUB 20 3000 PAPER 1: INK 7: CLS

3010 LET C=PEEK (A+9)+256*PEEK (A+10): LET E=PEEK (A+5)+256*PEEK (A+6): LET F=PEEK

(A+17)+256*PEEK(A+18): LET G=PEEK (A+3) 3020 RANDOMIZE 3020: GO SUB 10:CLS : PRINT AT 21,0; "ДИСКРЕТНОСТЬ ТОНА": INPUT ("(1-2000) :

";C; " : "); LINE F$: IF F$<>" THEN LET C=VAL F$ 3030 IF C<1 OR C>2000 THEN GO TO 3020

3040 POKE A+10, INT (C/256): POKE A+9, INT(C-(PEEK (A+10)*256))

3050 RANDOMIZE 3050: GO SUB 10:CLS : PRINT AT 21,0:"ПЕРИОД НАЧАЛЬНОГО ТОНА": INPUT ("(120000): ";E;" : "); LINE F$: IF F$<>"" THEN LET E=VAL F$ 3060 IF E<1 OR E>20000 THEN GO TO 3050

3070 POKE A+6, INT (E/256): POKE A+5,INT(E-(PEEK (A+6)*256))

3080 IF PEEK (А+20)=82 THEN LET Z=-1: LET MM=1

3090 IF PEEK (A+20)=90 THEN LET Z=1: LET MM=2

3100 GO SUB 100

3110 PAPER 1: INK 7: CLS

3120 RANDOMIZE 3120: GO SUB 10:PRINT AT 21,0;"ВЕЛИЧИНА СТУПЕНЬКИ ТОНА": INPUT ("(1-2000) :

";F;" : "); LINE F$: IF F$<>"" THEN LET F=VAL F$ 3130 IF F<1 OR F>2000 THEN GO TO 3120 3140 POKE A+18,INT (F/256): POKE A+17,(F-(PEEK(A+18)*256))

3150 RANDOMIZE 3150: GO SUB 10:CLS : PRINT AT 19,0; "ЧИСЛО СТУПЕНЕК ТОНА......(ЕСЛИ 1 - ТО

ПОСТОЯННЫЙ ТОН)": INPUT ("(1-255) : ":G;" : "); LINE F$: IF F$<>"" THEN LET G=VAL F$ 3160 IF G<1 OR G>255 THEN GO TO 3150 3170 POKE A+3,G

3180 RANDOMIZE 3000: GO SUB 10: IF E+Z*F*(G-1)<1 OR E+Z*F*(G-1)>20000 THEN GO TO 2500 3190 LET H=1: GO SUB 70: IF SEC>10 AND INKEY$<>"y" AND INKEY$<>"Y" THEN LET MM=2: GO TO 300 3200 CLS : POKE A+24,201: PRINT AT 11,2; "СЛУШАЙТЕ: ТАК ЗВУЧИТ ВАШ ЗВУК": PAUSE 50: RANDOMIZE USR A 3210 PRINT AT 19,0:" НАЖМИТЕ ВREAK ДЛЯ ПОВТОРЕНИЯ РЕДАКТИРОВАНИЯ ИЛИ ЛЮБУЮ КЛАВИШУ ДЛЯ ПРОДОЛЖЕНИЯ...": PAUSE 0 4000 PAPER 1: INK 7: CLS 4010 LET Н=РЕЕК (А+25)-РЕЕК (А+1)

4020 RANDOMIZE 4020: GO SUB 10:PRINT AT 21,0: "ЧИСЛО ПОВТОРЕНИЙ": INPUT ("(1-255) : ";H;" :

"); LINE F$: IF F$<>"" THEN LET H=VAL F$ 4030 IF H<1 OR H>255 THEN GO TO 4020 4040 POKE A+1,0: POKE A+24,62: POKE a+25,Н

4050 RANDOMIZE 4000: GO SUB 10: GO SUB 70: IF SEC>10 AND INKEY$<>"y" AND INKEY$<>"Y" THEN LET MM=3: GO TO 300

4060 RANDOMIZE 4000: GO SUB 10: CLS : PRINT AT 8,11; INVERSE 1; "СЛУШАЙТЕ "; INVERSE 0; AT 10,7;"ЗВУК НОМЕР ";P;" ГОТОВ": PRINT AT 12,2:"ЗАПУСК - RANDOMIZE USR ";A: PAUSE 50: RANDOMIZE USR A 4070 PRINT AT 19,0:" НАЖМИТЕ BREAK ДЛЯ ИЗМЕНЕНИЯ ЧИСЛА ПОВТОРЕНИЙ ИЛИ ЛЮБУЮ КЛАВИШУ ДЛЯ ПРОДОЛЖЕНИЯ...": PAUSE 0 4080 LET MM=2: GO ТО 300 5000 PAPER 1: INK 7: CLS : LET D=1: IF B=2 THEN GO TO 5100 5010 PRINT AT 10,0;" СОЕДИНИТЬ МОЖНО ДВА СОСЕДНИХ ЗВУКА. ДЛЯ ЭТОГО ВВЕДИТЕ НОМЕР ПЕРВОГО ИЗ ДВУХ СМЕЖНЫХ ЗВУКОВ, КОТОРЫЕ НАДО СОЕДИНИТЬ." 5020 RANDOMIZE 5020: GO SUB 10: INPUT ("НОМЕР ЗВУКА (1-";В-1;") : ";D;" : "); LINE F$: IF

F$<>"" THEN LET D=VAL F$ 5030 IF D<1 OR D>B-1 THEN GO TO 5020 5100 LET A=U+32*(D-1): POKE A+31,0

5110 RANDOMIZE 300: GO SUB 10: CLS : PRINT INVERSE 1;AT 7,10;"СЛУШАЙТЕ "; INVERSE 0"" ЗВУК НОМЕР ";D;" + ЗВУК НОМЕР "^+1""ЗАПУСК - RANDOMIZE USR ";A; PAUSE 50: RANDOMIZE USR A

5120 RANDOMIZE 5200: GO SUB 10:PRINT AT 19,0;" НАЖМИТЕ BREAK ДЛЯ РАЗДЕЛЕНИЯ ЗВУКОВ ИЛИ ЛЮБУЮ КЛАВИШУ ДЛЯ ПРОДОЛЖЕНИЯ...":PAUSE 0 5130 LET MM=2: GO TO 300 5200 POKE A+31,201: LET MM=4: GO ТО 300

6000 PAPER 1: INK 7: CLS 6010 LET O=1: IF B=1 THEN LET I= 32: GO TO 6100 6020 PRINT AT 8,0;" СНАЧАЛА ВВЕДИТЕ НОМЕР ЗВУКА, С КОТОРОГО ХОТИТЕ НАЧАТЬ ЗАПИСЬ, ЗАТЕМ НОМЕР ЗВУКА, КОТОРЫМ ХОТИТЕ ЗАВЕРШИТЬ ЗАПИСЬ. "

6030 RANDOMIZE 6030: GO SUB 10: INPUT ("НАЧАЛЬНЫЙ ЗВУК (1-";В;" ) : ";O; " : "); LINE F$: IF

F$<> "" THEN LET O=VAL F$ 6040 IF O<1 OR O>B THEN GO TO 6030 6050 LET V=B: IF O=B THEN LET I=32: GO TO 6100

6060 RANDOMIZE 6060: GO SUB 10: INPUT ("КОНЕЧНЫЙ ЗВУК nO;"-"^;") : ";V;" : "); LINE F$:

IF F$<>"" THEN LET V=VAL F$ 6070 IF V<O OR V>B THEN GO TO 6060 6080 LET I=(V-O+1)*32

6090 IF PEEK (U+(O-I)*32+(I-1))=0 THEN LET I = I+32: GO TO 6090

6100. RANDOMIZE 6200: GO SUB 10: CLS : PRINT AT 21,0; "ИМЯ ФАЙЛА : ": GO SUB 9: INPUT F$ 6110 CLS : SAVE F$CODE U+32*(O-I),I

6120 GO SUB 8: CLS : PRINT AT 1,0; " КОГДА ВЫ БУДЕТЕ ЗАПИСАННЫЙ БЛОК КОДОВ ВСТРАИВАТЬ В ПРОГРАММУ, ПОМНИТЕ, ЧТО ЕСЛИ ВЫ РАСПОЛАГАЕТЕ ЕГО В ПЕРВОЙ ^УЛЕ-ВОЙ) СТРОКЕ BASIC, TO ВЫ ДОЛЖНЫ В ЭТОЙ СТРОКЕ ПОСЛЕ 0ПЕРАТ0PA REM НАБРАТЬ "; FLASH 1;I; FLASH 0; " ПРОБЕЛОВ. " 6130 PRINT '" ЗАГРУЗИТЕ ЗАПИСАННЫИ БЛОК КОДОВ: LOAD ""ИМЯ"" MDE 23760..... АДРЕСА ЗАПУСКА ЗВУКОВ БУДУТ

РАВНЫ: 23760+32* (N-1 ), ГДЕ N -НОМЕР ЗВУКА ИЗ ЗАПИСАННОГО БЛОКА

ЗВУКОВ....... ЕСЛИ ВЫ РАСПОЛАГАЕТЕ КОДЫ ЗА

RAMTOP, Т О: LOAD "ИМЯ" CODE ADR ГДЕ ADR >=RAMTOP+1. СТАРТОВЫЕ АДРЕСА ЗВУКОВ БУДУТ ADR+32*(N-1)." 6140 ВЕЕР .1,20: GO SUB 20

6200 GO SUB 6: RETURN

7000 RANDOMIZE 7100: GO SUB 10: GO SUB 9: PAPER 1: INK 7: CLS 7010 LOAD ""CODE (U+B*32)

7020 LET LEN = PEEK (PEEK 23649+256*PEEK 23650+28)+256*PEEK (PEEK 23649+256*PEEK 23650+29) 7030 LET P=B+1: LET B=B+INT (LEN/32)

7040 GO SUB 8: PRINT.....ЧИСЛО ЗАГРУЖЕННЫХ ЗВУКОВ: "; INT (LEN/32)

7050 BEEP .1,20: GO SUB 20 7060 LET MM=2: GO TO 300

7100 GO SUB 8: PRINT ' ' 'TAB 4; FLASH 1; " ОШИБКА МАГНИТОФОНА " 'FLASH 0.....

ПОВТОРИТЬ ЧТЕНИЕ- [Y],...... ВОЗВРАТ В МЕНЮ - ЛЮБАЯ КЛАВИША"

7110 ВЕЕР .5.0: GO SUB 20

7120 IF INKEY$="Y" THEN GO TO 7000

7130 LET MM=7: GO TO 300

9999 PAPER 1: INK 7

Переменные, используемые в программе. P - текущий номер звука. В - суммарное число звуков в блоке кодов. U - начальный адрес массива кодов, отведенного под звуки.

N - номер звука из примеров, который берется за основу при создании новых звуков. F$ - стринг для оператора INPUT, значение которого присваивается переменным. А - начальный адрес звука, являвшегося текущим.

Y - начальный адрес выбранного примера звука.

R - счетчик перебрасываемых байтов при создании основы звука.

С - дискретность тона.

Е - период начального тона.

F - величина ступеньки тона.

Z - признак увеличения или уменьшения тона.

G - число ступенек тона.

J - номер демонстрируемого звука.

H - число повторений "скольжений" тона.

SEC - примерное время звучания звука в секундах.

T, S - то же, но соответственно в минутах и секундах.

D - номер первого из двух смежных звуков, которые надо соединить.

0 - начальный звук для записи.

V - конечный звук для записи.

1 - длина блока кодов для записи на магнитную ленту. LEN - длина блока кодов при загрузке звуков с ленты.

О нулевой строке и о кодах, размещенных там - чуть позже. А сейчас об остальных строках программы.

Автостарт программы - со строки 2. Так как для работы программы не нужны никакие кодовые блоки, кроме расположенных в нулевой строке, то строка 2 в программе отсутствует. Строка 3 - вывод на экран заставки. (При этом я считаю "делом чести" для себя указывать в заставке фирму, создавшую прототип этой программы.) После вывода заставки, строка 4 адресует на непосредственное начало программы - строку 100.

В строках 100, 110 устанавливаются начальные параметры. Обнуляется счетчик текущего номера звука (Р), максимальное число звуков в блоке кодов (В) устанавливается равным 20 - именно столько готовых примеров находится в программе. Определяется начальный адрес (U) области кодов примеров звуков (он может измениться в случае работы с дисковой операционной системой TR-DOS или при подключении ИНТЕРФЕЙСА-1).

Строка 190 определяет начальное положение указателя главного меню на первый пункт. Затем со строки 200 запускается главное меню. В главном меню 4 пункта:

[ РАБОТА С РЕДАКТОРОМ ЗВУКОВ ] ДЕМОНСТРАЦИЯ ПРИМЕРОВ ЗВУКОВ ЗАПИСЬ ПРИМЕРОВ ЗВУКОВ ИНФОРМАЦИЯ О ПРОГРАММЕ

Первый пункт - выделен, так как он наиболее вероятен для выбора. Работа меню подробно была изложена в ZX-РЕВЮ N 9-10 за этот год см. стр. 197. Там же подробно описаны переменные, касающиеся работы меню, поэтому эту часть - пропускаем. Отмечу только, что несколько изменена логика работы блока "ON ERROR GO TO", касающаяся переходов из одного меню в другое, но на этом мы еще остановимся. А также добавлен опрос клавиши "Q" и переход, в случае ее нажатия, на строку 9999, аналогично тому, как это делается в строке 24 для остановки программы.

При выборе первого пункта, строка 210 запускает второе меню. При этом принимает заданное значение начальный адрес области памяти, определенной под создаваемые звуки (U), а максимальное число созданных звуков (В) становится равным P, то есть пока что -нулю.

При выборе второго пункта выполняется (строка 220) подпрограмма GO SUB 50 - это демонстрация готовых звуков, затем опять переход в главное меню. Перед демонстрацией Вам показывается, сколько созданных звуков находится в памяти. Если в этот момент нажать "BREAK", то произойдет завершение подпрограммы путем перехода на строку 59. При помощи "BREAK" можно прервать подпрограмму демонстрации звуков в любом ее месте, но только если клавиша удерживается нажатой до завершения очередного звука, то есть до окончания программы в машинных кодах и возврата в Бейсик, когда возобновит свое действие блок "ON ERROR GO TO".

При выборе третьего пункта выполняется большая подпрограмма GO SUB 6000 - это запись звуков на магнитную ленту, после чего происходит возврат в главвое меню с выделением первого пункта.

При выборе четвертого пункта на экран выводится некоторая вступительная информация о программе (при помощи GO SUB 40).

Вернемся к действиям, происходящим в результате выбора первого пункта главного меню. Строка 210 адресует программу на строку 300 - это запуск второго меню с выделенным первым пунктом. (При этом нет необходимости задавать, как положено, LET MM=1: GO ТО 300, так как MM и так равно 1.)

Второе меню выглядит следующим образом:

[ СОЗДАНИЕ НОВОГО ЗВУКА ] РЕДАКТИРОВАНИЕ ЗВУКА ИЗМЕНЕНИЕ ЧИСЛА ПОВТОРЕНИЙ СОЕДИНЕНИЕ ДВУХ ЗВУКОВ ДЕМОНСТРАЦИЯ ЗВУКОВ ЗАПИСЬ ЗВУКОВ ЗАГРУЗКА ЗВУКОВ УДАЛЕНИЕ ЗВУКОВ ВОЗВРАТ В ГЛАВНОЕ МЕНЮ

При работе второго меню после выполнения подпрограммы меню GO SUB 30 идет строка 302, в которой проверяется допустимость тех или иных действии. Так, если еще не создано ни одного звука, то не может идти речи о редактировании или демонстрации звуков или записи звуков и т.п. В этом случае на экран выводится табличка "СНАЧАЛА НАДО СОЗДАТЬ ЗВУК", затем предупредительный звуковой сигнал, после чего возобновляется работа второго меню.

А теперь небольшое лирическое отступление, необходимое для пояснения дальнейших строк программы. Кстати Вы можете использовать изложенный прием и в других своих программах.




СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Ufo #3 - Миражи замка Франко-Кастелло.
Pain - Slip "Я не пытаюсь вые..ться! Просто делаю игры. Делаю их, одну за другой"...
Deja vu - слово в защиту известного Барнаульского журнала.
Лаборатория - Схема расширения памяти Таганрог 128.
Запуск - 8-ой отдел II.

В этот день...   19 апреля