Синтезирование речи
Синтезировать речь можно просто записывая и воспроизводя её как любой другой звук с помощью подпрограмм, но обычно действуют иначе. Сначала в компьютер вводятся все фонемы определенного языка, затем у пользователя запрашивается фраза, и, наконец, компьютер последовательно воспроизводит входящие в нее фонемы. Этот способ позволяет значительно экономить память и воспроизводить абсолютно любые фразы.
Программа, позволяющая Spectrum разговаривать
Бейсик ZX:
10 CLEAR 25343: LET L=3
20 PRINT "Wait please…"
30 FOR A=25344 TO 25433: READ D: POKE A,D: NEXT A
40 FOR A=0 TO 25: POKE 25437,A*L+100
50 CLS: PRINT "Press any key, then say '";CHR$ (A+65);"'": PAUSE 0
60 RANDOMIZE USR 25344: NEXT A
70 CLS: INPUT "Enter phrase:"; LINE A$: PRINT A$
80 FOR A=1 TO LEN A$
90 IF A$(A)=" " THEN POKE 25433+A,32:NEXT A
100 IF A$(A)>="a" THEN LET A$(A)=CHR$(CODE A$(A)-32)
110 POKE 25433+A,(CODE A$(A)-65)*L+100: NEXT A: POKE 25433+A, 0
120 RANDOMIZE USR 25406: GOTO 70
130 DATA 243, 33, 0, 0, 17, 0, L, 6, 8, 203, 38, 219, 254, 203, 119, 40, 2, 203, 198, 16, 244, 35, 27, 122, 179, 32, 236, 251, 201
140 DATA 243, 33, 0, 0, 17, 0, L, 62, 7, 6, 8, 230, 239, 203, 6, 48, 2, 246, 16, 211, 254, 16, 244, 35, 27, 79, 122, 179, 121, 32, 234, 251, 201
150 DATA 33, 90, 99, 126, 183, 200, 254, 32, 32, 7, 6, 5, 116, 16, 253, 24, 8, 50, 32, 99, 229, 205, 29, 99, 225, 35, 24, 231
- 30 — считываются в память программы в кодах
- 40…60 — записываются фонемы с микрофона
- 70 — ввод фразы
- 80…110 — фраза заносится в память в специальном формате
- 120 — вызывается подпрограмма воспроизведения
- 130…150 — подпрограммы в кодах
- Попросит немного подождать, считывая кодовую часть
- Затем Вы должны будете последовательно произнести в микрофон 26 фонем
- После этого Вы можете вводить любые фразы и наслаждаться их звучанием
Бейсик ZX:
SAVE "name" CODE 25600,6656*L
Бейсик ZX:
35 LOAD "name" CODE 25600: GOTO 70
Бейсик ZX:
SAVE "SPEAKER" LINE 10
- Подключить русский шрифт (подробнее см. в [1])
- Увеличить число фонем
- Сменить все сообщения, выводимые на экран
- Не использовать мягкие согласные (в компьютерном исполнении их мягкость практически не слышна)
- Гласные «Е», «Ё», «Ю» и «Я» заменять на «Й» и, соответственно, «Э», «О», «У» и «А»
- Твердый знак также заменять буквой «Й»
- Sinclair → sinkler
- компьютер → кампйутер
Звук на прерываниях
Проблема и её решение
Напоминание о прерываниях
Режим 1 (стандартный):
Режим 0:
Режим 2:
Как работает режим 2 прерываний
- Микропроцессор считывает с шины данных байт, называемый вектором прерывания
- Он передается в младший байт шины адреса
- В старший байт записывается содержимое регистра I
- По полученному таким образом адресу процессор считывает из памяти два байта
- Эти два байта интерпретируются как адрес подпрограммы обработки прерывания
Установка собственного обработчика прерываний
Последовательность действий:
- Запретить прерывания
- Записать в память адрес обработчика прерываний
- Задать в регистре I старший байт адреса указателя на обработчик
- Установить второй режим прерываний
- Разрешить прерывания
Возврат к стандартному режиму:
- Запретить прерывания
- Записать в регистр I число 63
- Установить первый режим прерываний
- Разрешить прерывания
Таблица векторов прерываний
Правила составления обработчиков прерываний
1. Скорость выполнения
2. Сохранение регистров
3. Осторожность с ПЗУ
4. Запрет вложенных прерываний
Совместимость со стандартным обработчиком
Применение прерываний для звука
Формат данных для звуковых эффектов
Для каждой ноты в блоке данных должно быть по два байта:
- Первый байт - частота (1…253)
- Второй байт - длительность (0…255)
Контрольные коды:
- 0 - переключение тон/шум
- 254 - начало цикла
- 255 - конец блока
Полный пакет программ для работы со звуком на прерываниях
Assembler Z80:
10 ORG 60000
20 JP SINIT ; подключение прерываний
30 JP SSTOP ; отключение прерываний
40 JP NEWFX ; инициализация эффекта
50 MUTE LD (COUNT),A ; "заглушка"
60 RET
70 SINIT XOR A
80 LD (COUNT),A
90 LD A,24 ; код команды JR
100 LD (65535),A
110 LD A,195 ; код команды JP
120 LD (65524),A
130 LD HL,INTR ; HL=адрес обработчика
140 LD (65525),HL
150 LD HL,65024
160 LD DE,65025
170 LD BC,256
180 LD (HL),255 ; адрес прерывания - 65535
190 LD A,H
200 LDIR ; заполнение таблицы
210 DI
220 LD I,A
230 IM 2
240 EI
250 RET
260 SSTOP DI ; отключение прерываний
270 LD A,63
280 LD I,A
290 IM 1
300 EI
310 RET
320 NEWFX DI ; инициализация эффекта
330 LD (COUNT),A
340 XOR A
350 LD (FLAG),A
360 LD (ADDR),HL
370 LD (CURADD),HL
380 EI
390 RET
400 ADDR DEFW 0 ; начальный адрес блока данных
410 CURADD DEFW 0 ; текущий адрес в блоке данных
420 COUNT DEFB 0 ; количество повторений
430 FLAG DEFB 0 ; флаг тон/шум
440 INTR PUSH AF ; обработчик прерывания
450 PUSH BC ; сохранение регистров
460 PUSH DE
470 PUSH HL
480 TEST LD A,(COUNT) ; A=счетчик повторений
490 OR A ; есть что играть?
500 JR Z,EXIT
510 LD HL,(CURADD) ; HL=текущий адрес
520 NEXT LD A,(HL)
530 INC HL
540 CP 254 ; A=254? (начало цикла)
550 JR NZ,CONT1
560 LD (ADDR),HL ; изменение начального адреса
570 JR NEXT
580 CONT1 CP 255 ; A=255? (конец)
590 JR NZ,CONT2
600 LD HL,(ADDR) ; восстановление начального
610 LD (CURADD),HL ; адреса блока данных
620 LD HL,COUNT
630 DEC (HL) ; уменьшение счётчика повторений
640 JR TEST
650 CONT2 OR A ; A=0? (переключатель)
660 JR NZ,CONT3
670 LD A,(FLAG)
680 CPL ; инвертирование A
690 LD (FLAG),A
700 JR NEXT
710 CONT3 LD B,A ; B=частота
720 LD C,(HL) ; C=длительность
730 INC HL
740 LD (CURADD),HL ; сохранение текущего адреса
750 LD A,(FLAG) ; A=флаг
760 OR A ; A=0?
770 LD A,7 ; A=цвет бордюра
780 JR NZ,NOISE
790 TONE XOR 16 ; воспроизведение тона
800 OUT (254),A
810 PUSH BC
820 PAUSE DJNZ PAUSE
830 POP BC
840 DEC C
850 JR NZ,TONE
860 JR EXIT
870 NOISE LD HL,1000 ; воспроизведение шума
880 LD D,A
890 NOIS2 LD A,(HL)
900 AND 248
910 OR D
920 OUT (254),A
930 PUSH BC
940 PAUS2 DJNZ PAUS2
950 POP BC
960 INC HL
970 DEC C
980 JR NZ,NOIS2
990 EXIT POP HL ; восстановление регистров
1000 POP DE
1010 POP BC
1020 POP AF
1030 RST 56 ; вызов стандартного обработчика
1040 RET ; возврат
Порядок использования этого пакета
1. Инициализация
2. Воспроизведение звука
- Занести в регистр HL адрес блока данных
- В регистр А - число повторений
- Вызвать подпрограмму NEWFX
3. Управление звуком
- Выключить звук
- Продлить его звучание
4. Завершение работы
Адреса подпрограмм
| Подпрограмма | Адрес | Hex |
|---|---|---|
| SINIT | 60000 | #EA60 |
| SSTOP | 60003 | #EA63 |
| NEWFX | 60006 | #EA66 |
| MUTE | 60009 | #EA69 |
Ограничения
Пример использования
Assembler Z80:
10 ORG 50000
20 CALL 60000
30 LD HL,SNDFX
40 LD A,3
50 CALL 60006
60 RET
70 SNDFX DEFB 200,5,250,4,200,5,100,10,75,13,50,20,255
Assembler Z80:
70 SNDFX DEFB 50,20,75,13,100,10,200,5,250,4,50,20,255