Inferno #06
03 декабря 2004

For Coderz - Как получить на звуковом устройстве больше бит.

   Как получить на звуковом устройстве
               больше бит?
 

   Предположим, у  нас  нет 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 




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

Похожие статьи:
Бред к ночи - На диске со всевозможными прогами на Spectrum, жил себе в убовольствие байт по имени Магнет.
Компьютерная новелла - По игре " The Saga"
Small Coding - Процедуры возведение в квадрат и квадратный корень.

В этот день...   18 ноября