Как получить на звуковом устройстве
больше бит?
Предположим, у нас нет DMA US, GS или
подобных устройств,дающих аппаратную гром-
кость. Иначе бы задача решалась слишком
просто (один подканал в,например,левом ухе
дать с громкостью 64, другой в том же ухе
- с громкостью 1). У нас стандартный Spec-
trum не более чем с Covox'ом.
Так вот, для него существует по меньшей
мере три принципиально различных метода.
1. ШИМ (широтно-импульсная модуляция).
Сигнал с некоторой частотой делится на
временные интервалы короче 1/20000 секун-
ды, в каждом из которых содержится два со-
седних уровня напряжения. В зависимости от
соотношения длительностей этих уровней
внутри временных интервалов на выходе с
фильтром вырабатываются те или иные проме-
жуточные уровни напряжения. Условие по ча-
стоте необходимо, чтобы сигнал не свистел.
2. ШИМ. То же самое,но чередуются не со-
седние уровни,а 0 и уровень. Кроме высокой
пульсации и низкой громкости этот метод
содержит проблему реализации - неизвестно,
как организовать для него таблицы, чтобы
перекодировать 16 бит в реальном времени.
3. Метод без названия. Я полагал, что к
нему относится название ИКМ (импульсно-ко-
довая модуляция),но Михаил Клинковский на-
отрез отказался это принять,правда,без по-
каза своих источников.Здесь в ЦАП выдается
уровень сигнала, округленный до ближайшего
целого снизу.Ошибка представления накапли-
вается в регистре и, когда она превысит
единицу,то эта единица прибавляется в оче-
редному данному в ЦАП.Из регистра при этом
она,естественно,вычитается.Если этот метод
реализовать аппаратно,то при тех же часто-
тах переключения он обеспечивает более вы-
сокую частоту свиста,чем ШИМ (что является
преимуществом:свист менее слышен).Невыгода
его на ZX в том, что цикл при программиро-
вании на Z80 получается длиннее, чем пико-
вая скорость изменения данных для ШИМ. В
ШИМ для пиковой скорости в порт просто вы-
плёвывают подряд 2 байта и дальше ждут,по-
ка не пройдет стандартный временной интер-
вал. Если нужен уровень поближе к первому
выплюнутому байту, в ШИМ нужно просто раз-
делить эти выплевывания паузой побольше. И
так далее. Нужен лишь небольшой блок под-
программ,их даже меньше,чем вариантов дро-
бной части уровня напряжения.
В случае Beeper'а методы (1) и (2) эк-
вивалентны и реализуются особенно просто
для 64 дробных вариантов уровня (при час-
тоте 22.4kHz, близкой к стандартной 22100,
это обеспечивает запас в 96=160-64 тактов
для думания и ползания по подпрограммам).
В этом случае имеется всего четыре п/п вы-
вода с разными микропаузами по модулю 4 и
четыре п/п паузы с разными микропаузами по
модулю 4. Они содержат перед собой кучу
NOP и вызываются с разных адресов для ре-
гулировки пауз. Это всего 500 байт,включая
таблицу переходов. Можно реализовать и бо-
льше дробных уровней, но тогда число под-
программ резко подпрыгнет (думание придё-
тся внести во все подпрограммы). Beeper
неплохо заменяет Covox и идеально (!) за-
меняет AY по MCC методу приснопамятного
Monster/Sage. Не звучит только на эмулято-
рах (Unreal Speccy, ZXMAK, ZX Emul DOS, ZX
Emul WIN, Z80 Stealth и на остальных наве-
рняка тоже).
В случае Covox эти же 64 дробных уровня
реализовать нельзя. Для Beeper крайними
уровнями были далеко не чистый 0 и чистая
1. Их трудно использовать, т.к. расстояние
до соседнего уровня из-за конечности ско-
рости Z80 было бы больше, чем расстояние
между всеми остальными соседними уровнями.
Для Covox чистые (целые) уровни всё же
приходится использовать как мостик между
высшим возможным дробным уровнем для пре-
дыдущей пары (целых чередуемых) и низшим
возможным - для следующей. А времянки для
этих высших и низших отличаются от ближай-
шего целого на 11 тактов процессора (сами
понимаете почему). Следовательно,между со-
седними дробными уровнями тоже должно быть
около 11 тактов про времянке - для линей-
ности. Это в идеале,на практике приходится
довольствоваться 5 тактами и 32 уровнями
(вместо 16) при частоте дискретизации 22.4
кГц, то есть длине временного интервала
ШИМ 5*32=160 тактов. Это звучит чуть хуже
13 бит (вместо 12 ),т.к.два дробных уровня
выпадают. Но на слух 13 бит и 8 бит звучат
как небо и земля. Попробуйте. Мы с John'ом
пробовали.
Откуда в случае Covox брать время на то
же самое думание программы? Делается так:
при дробной части уровня <0.5 уровни вып-
лёвываются в порт в порядке младший-стар-
ший, при >0.5 - в порядке старший-младший.
Тогда в любом случае остается полцикла
свободного времени.
Для Covox на КР572ПА1 метод (1) не сра-
батывает - уровень шума образуется больше,
чем при стандартных 8 битах. Когда я при
первом же эксперименте услышал этот шум,то
подумал на глюк в программе,т.к. 8 бит ПА1
можно проверить непосредственно, прямо в
бейсике. Вот так:
FOR n=0 TO 255:OUT 251,n:OUT 251,0:NEXT n
Однако Владимир Макаров на вопрос о
его интерпретации проблемы ответил: "по-
весь конденсатор между выходным сигналом и
землёй". Мол,поможет. Но есть очень веские
причины предполагать, что Макаров ошибает-
ся. Дело в токовых ключах. Они, в отличие
от R-2R матрицы, срабатывают медленно. Это
означает, что быстрое чередование посылае-
мых в ЦАП байтов 127-128-127... вызовет
щёлкание ключей в разных фазах,что в опре-
деленные моменты может звучать даже как 0
или 255. Если бы оно переключалось мгно-
венно и выдавало только два соседних уров-
ня,то и конденсатор бы не понадобился. Ко-
нденсатор лишь приведёт напряжение к сред-
нему уровню, а чему он равен? Он был бы в
промежутке между 127 и 128 (это необходи-
мое условие того, что метод звучит лучше,
чем 8 бит) лишь при весьма линейной харак-
теристике ЦАП. Я не верю в столь точную её
линейность. ПА1 могла бы, вероятно, быть
более эффективной в методе (2) с чередова-
нием 0 и уровня, но для этого метода нужна
большая таблица, он непригоден для практи-
ческого использования.
Естественно, вешать конденсатор я всё-
таки пробовал, но это никак не помогло.
Под эмуляторами Unreal Speccy, ZX Emul
0.34 (DOS) и Z80 Stealth ШИМ для Covox
улучшает звук. Вероятно,в эмуляторах испо-
льзованы фильтры,сглаживающие выход Covox,
однако не исключено, что это делает звуко-
вая карта.Другие эмуляторы не проверялись.
Исходник SHIM.H - в приложении. К нему
нужен 16-битный сэмпл.При удержании кнопок
"P" и "Enter" звуковое устройство меняется
с Covox'а на Beeper или Covox-13 соответс-
твенно. По умолчанию Beeper тоже эмулиру-
ется на Covox (чтобы было удобнее сравни-
вать качество звука),это настраивается ме-
ткой beeper. Порт Covox настраивается мет-
кой covox. Перед проигрыванием сэмпл ухуд-
шается на 2 бита (делится на 4 ),чтобы лу-
чше слышать разницу. Но это тоже можно от-
ключить.
A. Coder