ПОСЛУШАЕМ
Вишев Алекс/MSD/20.12.99(c)
Благородной целью сего послания является просветить народ
о технологии работы с цифровым звуком. Приступим.
Немного науки.
Если вы не в ладах с физикой, то священный долг вашего по-
корного слуги напомнить вам о том, что из себя представляет
звук. Итак, звук - это механическое колебание распростроняе-
мое в упругой среде и воспринимаемое органами слуха. Музы-
кальные звуки характеризуются высотой тона, громкостью и
тембром. Высота тона соответствует его частоте: чем больше
частота, тем выше тон звука. Громкость звука обусловливается
силой звука, которая в свою очередь определяется амплитудой
колебания звуковой волны. Звук будет тем громче, чем больше
амплитуда колебания. Звуки исходящие от различных источников
неодинаковы по тембру, т.е. по окраске.
Для нас же частота - это периодичность выкидывания очеред-
ного байта в AY. При всем при этом, частота формируется уже
в процессе звучания сэмпла (таким образом является возможным
проигрывание однажды оцифрованого сэмпла на разных нотах и
октавах).
Начало.
Поговорим о работе с AY (ковоксы еще так редки...). Самое
простое, что можно придумать, - это вывод сэмпла в один
канал AY.
Кстати, сэмпл представляет из себя определенный набор бай-
тов, несущих информацию об амплитуде звука.
Продолжим. AY обладает лишь шестнадцатью уровнями громкос-
ти (4 бита, 16 уровней), а сэмплы, как правило, бывают
восьмибитными (256 уровней). Из этого следует, что их надо
конвертировать в четырехбитный формат. Но не все так просто,
так как у AY, при увеличении громкости на единицу, таковая
возрастает не на 1/16. Этот печальный факт подводит нас к
тому, что для конвертирования придется завести специальную
таблицу. Здесь она не приводится, а интересующихся отсылаю
в ZX FORMAT 8.
Вот простейшая процедурка для проигрывания одного сэмпла.
Здесь предполагается, что сэмпл конвертирован. Если нет, то
звук будет некачественным.
DI ;запретим прерывания
LD HL,sample ;начало звука в памяти
LD DE,lenght ;его длина
LD BC,#FFFD ;порт для записи номера регистра AY
LD A,8 ;регистр громкости АУ канал А
OUT (C),A ;установим
LD B,#BF ;BC=#BFFD - порт записи в регистры AY
LOOP LD A,(HL) ;возьмем байт
OUT (C),A ;кинем в порт
INC HL ;
DEFS 20 ;задержка, дла выставления частоты, чем
;больше - тем ниже тон
DEC DE
LD A,D
OR E ;DE=0 ?
JR NZ,LOOP ;продолжим цикл
EI ;разрешим прерывания
RET
Многоканальный звук.
Теперь переходим к самому интересному. Как вы могли наблю-
дать, частота звука по такому методу может устанавливаться
только для одного звукового канала. Как же нам быть, ведь в
АУ их три ? А быть нам очень просто. Правда для этого пона-
добится еще один регистр. Например вот так:
LD A,D ;регистр D используется как счетчик пере-
LOW ADD A,0 ;полнений. В HL адрес инструмента.
LD D,A ;Как только регистр D переполнится
LD A,L ;произойдет увеличение HL на единицу
HIGH ADC A,1 ;дополнительно к этому будет происходить
LD L,A ;увеличение HL на количество HIGH за
ADC A,H ;каждый проход плейера
SUB L
LD H,A
Таким образом, нам нужна специальная таблица, в которой
будут содержаться байты LOW и HIGH для каждой ноты каждой
октавы.
Плейер.
Вот теперь по-моему совсем все просто. Итак, мы имеем
где-то в памяти таблицу нот, таблицу адресов сэмплов и,
собственно говоря, список нот, на которых надо проигрывать
мелодию. Также мы имеем сам плейер, как основной модуль
программы, и процедурку на прерываниях, которая будет зани-
маться тем, что заменять параметры LOW и HIGH, а также
адреса сэмплов для каждого звукового канала.
Устанавливаем прерывания на адрес вашей процедурки, кото-
рая меняет пораметры LOW и HIGH. В HL - адрес инструмента.
Как промежуточный счетчик используется D. Сэмплы должны быть
конвертированными. К каждому байту сэмпла необходимо приба-
вить #А0, что связано с особенностями дешифрации, так как
звук выводить мы будем по младшей половинке порта AY. В кон-
це сэмпла должно быть определенное количество нулей, по ко-
торым определяется конец сэмпла. Это количество равняется
самому большому значению HIGH, используемому в вашем плейере
+1. Вот приблизительно как это будет выглядеть:
BEGIN
LD BC,#FFFD
A_CHAN LD A,8
OUT (C),A ;канал А
LD A,80 ;если под сэмплы используется 128-ая память
OUT (#FD),A ;переключим страницу памяти. Где 80 - нуле-
;вая страница, 81 - первая и т.д.
LD A,(HL) ;берем байт сэмпла
VOL SUB 1 ;этой командой мы ловим два зайца.
;Во-первых,
;мы определяем конец сэмпла, а во-вторых,
;здесь можно выставлять громкость звучания.
;Чем больше VOL - тем тише звук, но не > 15
JR C,NOT_SMP;обход, если сэмпл кончился
OUT (#FD),A};выводим звук
LD A,D };частота
LOW ADD A,0 }
LD D,A }
LD A,L }
HIGH ADC A,1 }
LD L,A }
ADC A,H }
SUB L }
LD H,A }
B_CHAN LD A,9 ;канал B
OUT (C),A ;
............;и т. д. для всех звуковых каналов.
............;
............;
JP BEGIN
NOT_SMP ;выставляем задержку равную выполнению }
;что необходимо для того, чтобы не сби-
;вать частоту звука в других каналах,
;если инструмент кончился.
;Аналогично для всех каналов
JP B_CHAN
Далее следует процедура, работающая на прерываниях и как я
уже говорил меняющая параметры в плейере. Темп, с которым
будет играть мелодия, выставляется тоже очень просто,
например так:
INT PUSH AF ;запомним AF
TEMP LD A,10 ;счетчик темпа. 50 прерываний в секунду/10
DEC A ;уменьшим
JR Z,OK ;если ноль, то запустить процедуру
LD (TEMP+1),A;иначе запомнить счетчик
POP AF
RETI ;выйти из прерывания в плейер
OK LD A,10
LD (TEMP+1),A
.............;пошла процедура
Вот вроде бы все тонкости я осветил. Далее дело техники. А
написать после этого свой цифровой радактор по-моему - раз
плюнуть. Единственное, что я еще имею вам сказать - необхо-
димо, чтобы плейер и прога на прерываниях работала макси-
мально быстро. Побольше экспериментируйте, и может быть
когда-нибудь вы напишите самый крутой digital редактор на
Спектруме. Ариведерчи.
Вишев Алекс/MSD/20.12.99 18:4
Other articles: