|
nedoPC.orgElectronics hobbyists community established in 2002 |
|
Author |
Message |
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Давно у меня уже есть вариант эмулятора "Специалиста МХ" от Шевцова, где он помог
мне "спроецировать" порты в/в "Специалиста" на реальные УВВ IBM PC.
Первоначально все адреса там относились в область макетной платы IBM (300-30Fh),
которая у меня реально была установлена на шине ISA.
Но поскольку в ноутбуках никакой ISA нет - я сделал вариант, где порты в/в
"Специалиста" обращаются к таймеру на системной плате, порту LPT и т.д.
Всё это довольно неплохо работало под DOS и под Вынь-98...
И была у меня такая мысль - запустить звуковую карту под "Специалистом",
ведь у "Специалиста" отродясь звуковой карты не было...
Но руки всё как-то не доходили, а сейчас вот совершенно вынужденно, но дошли...
И причина тому была веская - перетаскиваю я постепенно весь свой софт под Венду 7.1, почему
и возник у меня вопрос - а как Венда 7.1 относится к обращению в порты из программ DOS ?
Только вот ни LPT, ни СОМ-портов в новых ноутах нет. Одни лишь USB...
Поэтому я решил совместить полезное с приятным: добавить в эмулятор "Специалиста МХ"
порты Sound Blaster, запрограммировать обращение к ним в кодах i8080, а затем проверить
на разных платформах...
Поскольку ПДП в эмуляторе "Специалиста МХ" нет, ограничился следующими портами:
Также решил воспроизводить WAV-файл без разбора заголовка, чтобы попроще это всё
было под "Специалистом".
Также задержка между сэмплами - чисто программная, поскольку не было уверенности на
адекватный доступ к таймеру - прерываний в "Специалисте" ведь тоже нет...
В итоге результат превзошел мои не самые радужные ожидания...
-------
Под голым DOS разницы между программой в кодах 8086, воспроизводящей WAV,
и воспроизведением его в среде эмулятора на слух заметно не было...
Под Вендой-98 добавились хрипы и шумы...
А вот под Вендой 7.1 из DOS-BOX звучание приемлемым не назвать никак... не смотря
на различные настройки этого самого DOS-BOX-а.
Хотя радует хотя бы тот момент, что к портам обращение всё же есть.
Без DOS-BOX-а Венда 7.1 их попросту игнорирует.
Но положительный момент есть - опробовал я наконец-то "Специалист МХ" в связке
с Sound Blaster-ом!
Кто захочет в такой вариант "Специалист МХ" поиграться - версия эмулятора SPMX42SE - здесь.
В папке DOC есть информация - как спроецированы порты "Специалиста" на реальные УВВ IBM PC,
и по каким адресам эмуль можно пропатчить, если адреса УВВ IBM PC отличаются.
_________________ iLavr
|
02 Dec 2013 08:58 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
ШИМ-звуковой сигнал на "Специалисте"
В топике про ШИМ-ковокс я собирался сформировать звуковой ШИМ-сигнал на "Специалисте"
программными средствами.
Но прежде всего надо оценить, а с какой максимальной скоростью реальный "Специалист" с
тактовой частотой 2МГц способен работать с портами.
Я такую оценку сделал уже довольно давно и результат её следующий:
То есть, не сказать что большой, но запас для работы с портами в реальном времени у
"Специалиста" есть.
Не такой уж, как хотелось бы для качественной ШИМ, а по разным оценкам для формирования
приличного качества ШИМ-сигнала частота должна быть по меньшей мере Fдискр*256 для 8-бит
звука, " и лучше умножить это значение на n=2..x, если железо позволяет"...
Но это - если подразумевается классическая ШИМ:
Но есть варианты!
Если через магнитофонный вход и компаратор "Специалиста" записывать отсчеты в память,
также получится своеобразный процесс ШИМ.
Если потом эти отсчеты выдавать по биту динамика - то речь, к примеру, звучит весьма разборчиво!
Но этим я давненько баловался, а тут мне захотелось проиграть WAV-файл из эмулятора "Специалиста",
но методом ШИМ.
Сподвинуло меня на это обсуждение одного очень наглого алгоритма, обсуждаемого на Хабре:
Честно говоря, если подумать, то такой алгоритм для современного спикера плоховат... Он более подходит для динамика, включенного через разделительный конденсатор, иначе нет смысла держать паузу на уровне 128. Но я решил попробовать, что даст этот простой алгоритм на "Специалисте" : | | | | Code: ;-------------------------------; ; WAW-FILE ШИМ НА СПЕЦИАЛИСТЕ ; ;_______________________________;
;______________________________________________________________ ORG 0000H START: JMP K00 DELL: MVI A,08FH; SAMPLE DELAY DE0: DCR A JNZ DE0 RET K00: CALL ZAG; Заголовок и сл.стpока K01: CALL INP CPI 1BH; ESC JZ SYS CPI 02H; F3-FILE JZ K03; загрузка CPI 0DH JZ K03; F1->COPY JMP K01
;________Вызов таблицы K03: CALL KCD; флаг - нуль, если прервано, иначе файл ; загружен, в HL - начальный адрес загрузки, ; DE - конечный адрес загрузки. JZ K00; Файл не загрузили PLAY: LXI B,P61; SPeaker & Timer out port LDAX B; (IN AL,61H) ANI 0FCH; Timer - OFF STAX B; (OUT 61H,AL) MT0: MOV A,M; get WAV sample CPI 80H; 128 - zero level JZ MT2 MVI A,0AH; 0000.1010b - set 0 in C5 JC MT1; if sample < 128 MVI A,0BH; 0000.1011b - set 1 in C5 MT1: STA 0FFE3H; Set Speaker through RYS 580BB55 MT2: INX H; next sample CALL CPHLDE; test HL=DE? JZ FIN
CALL DELL; sample delay LDA 0FFE1H; Ask "Shift" ANI 02H JNZ MT0; нуль, если прервано FIN: LDAX B; (IN AL,61H) ORI 03H; Timer - ON STAX B; (OUT 61H,AL) | | | | |
Тут следует учитывать, что, вынесенная в начало программы, константа задержки
жестко завязана со "средней задержкой по больнице" эмулятора на исполнение
каждой команды...
Я был зело удивлён что звук-таки разборчив! Одно дело - что читаем с порта, то и выдаем в порт,
другое дело - что в этом алгоритме никак не учитывается амплитуда сэмпла, а как было видно в
аппаратной реализации ШИМ - она должна влиять на длительность!
Результаты можно послушать, если в эмулятор SPMX42SB из предыдущего поста загрузить
образ памяти с обсуждаемыми программами.
Чтобы было понятно, что за WAV-файл я там мучаю, я его тоже выложил: hellow.wav.
Ну а я ещё парочку более серьёзных методов воспроизведения звукового сигнала
посредством ШИМ пока опробовать хочу...
_________________ iLavr
|
09 Dec 2013 13:06 |
|
|
Stan
Banned
Joined: 04 Jan 2013 10:09 Posts: 397 Location: 95.24.178.158
|
Я чисто из интересу сравнил звучание "Специалиста" со звучанием специальной утилиты для проигрывания WAV-файлов через спикер из дистрибутива Norton Commander 5.0: PLAYWAVE.EXEУдивительно, но "Специалист", на мой взгляд, звучит с этим алгоритмом получше! Существовал еще и драйвер Венды для вывода звука на РС-спикер, и, помню, пользовался я им... Надо будет найти и попробовать сравнить звук как-нибуть, как выберу время.
|
15 Mar 2015 14:31 |
|
|
Stan
Banned
Joined: 04 Jan 2013 10:09 Posts: 397 Location: 95.24.178.158
|
В общем, трудно даже сказать на Хабре ли заимствовали, или с Хабра, но только этот весьма смелый алгоритм подробно описан вот здесь: "Использование звуковых файлов формата wav в программах на Бейсике". Я решил попробовать этот алгоритм и на Бейсике (исходник можно разыскать там же), но поскольку временной интервал между отсчетами формируется программным способом, я решил хотя бы константу задержки вычислять по таймеру, раз уж сам таймер задействовать несколько затруднительно. Получилось у меня вот что: | | | | Code: '======================================================== ' ДЕМОНСТРАЦИЯ ВОСПРОИЗВЕДЕНИЯ WAV-ФАЙЛОВ ЧЕРЕЗ СПИКЕР '======================================================== DEFINT A-Z '&H61 - порт В микросхемы 8255 '&H42 - порт канала 2 таймера (звуковой сигнал) '&H43 - порт настройки таймера '&HB6 - команда установки режима канала 2 ' '--- Заголовок WAV-ФАЙЛОВ TYPE WavHeader RiffID AS STRING * 4 '___ "RIFF" - Четыре буквы заголовка RiffLength AS LONG ' длина файла без этого заголовка WavID AS STRING * 4 '___ "WAVE" сигнатура WAVE-формы FmtID AS STRING * 4 ' "fmt " FmtLength AS LONG ' размер подблока заголовка (12,16 байт) WavFormatTag AS INTEGER ' 1 = PCM Channels AS INTEGER ' 1 = mono, 2 = stereo SamplesPerSec AS LONG ' Samples per Second (11025,22050,44100 и т.д.) BytesPerSec AS LONG ' Bytes Per Second - тоже самое blockAlign AS INTEGER ' выравнивание блоков данных (обычно 1) FmtSpecific AS INTEGER ' Битов на один сэмпл (8/16) DataID AS STRING * 4 '___ "data" - Четыре буквы заголовка DataLength AS LONG ' кол-во байт самих WAV данных END TYPE ' Padding AS STRING * 4 ' only valid if FmtLength = 16 ' ' Далее идут сами данные звукового файла: ' файл 2-х канальный - данные идут по очереди, 1 канал, 2-ой, 1-ый, 2-ой... и т.д. ' если файл 8 битный, то под каждый сэмпл отводится по одному байту, ' если файл 16 битный - то по 2 байта.
DIM SHARED WavFile AS WavHeader '______________ пеpеменная заголовка DIM Buf AS STRING * 1 '---- Буфер длиной 1 байт DIM Mas%(32766) '--------- Буферный массив
Slp% = 900 '--- Задержка между отсчетами звука (подбирается по таймеру) '--------- MAIN PROG ---------------------------------------------- SCREEN 0 CLS 0
'--- Отключение таймера по GATE, спикер=0 OUT &H61, (INP(&H61) AND &HFE)
'--- Ввод имени wav-файла --------------(8 SYMB + 3) ' INPUT "Введите имя wav-файла"; N$ N$ = "C:\QBASIC\HELLOW.WAV" '--- файл должен быть 8 бит 8000...11025... Гц - взять выше
'--- Открытие файла в двоичном режиме OPEN N$ + ".WAV" FOR BINARY AS #1 fl& = LOF(1) '----- Определение длины файл IF LOF(1) < 2 THEN CLOSE #1: KILL WFile$: CLS : PRINT "No Such File!": END GET #1, , WavFile '____ читаем заголовок _
Period% = 1193180 / WavFile.SamplesPerSec PRINT " "; WavFile.SamplesPerSec; "Hz, "; Period%; " = "; HEX$(Period%); "H"
IF fl& > 32766 THEN fl& = 32766 '--- если Файл слишком велик FOR i& = 1 TO fl& '--- Чтение wav-файла в Mas%(i&) GET #1, i&, Buf '--- Читаем байт Mas%(i&) = ASC(Buf) '--- в буферный массив NEXT i&
PRINT PRINT " Press any key to play sound... " PRINT '--- Ожидание нажатия клавиши DO: LOOP WHILE INKEY$ = ""
'--- Вычисляем константу задержки по таймеру PRINT " Set Timer channel_2... " ON TIMER(1) GOSUB TimeUpdate PRINT " Test Timer delay... " TIMER ON FOR Bm& = 0 TO 2147483646 '--- Delay NEXT Bm&
'--- Отключение таймера from GATE OUT &H61, (INP(&H61) AND &HFE) Bm& = Tm& b% = 0 ON ERROR GOTO errorhandler '--- progs compiled from the IDE don't check for int sign overflow b% = 32767 + 1 b% = 2 GOTO noerror:
errorhandler: IF ERR = 6 THEN b% = 3 noerror: PRINT " DbDelay... "; Tm&, Slp%, (Tm& \ WavFile.SamplesPerSec) * b%, b% PRINT " Playing... "; Slp% = (Tm& \ WavFile.SamplesPerSec) * b%
'----- Цикл выдачи бит на спикер --------------- FOR i& = 44 TO fl& '--- Перебор байтов (с 44-го) Bt% = Mas%(i&) '--- Получить байт как число '----- Определение значений громкости ------------- SELECT CASE Bt% CASE 128 '--- Байт 128 - нулевой уровень '--- Задержка без переключения динамика) FOR j% = 0 TO Slp% '---Задержка NEXT j%
CASE IS < 128 '--- Байт больше 128 '---- Подать на динамик 1 (SpeakON) OUT &H61, (INP(&H61) OR &H2) FOR j% = 0 TO Slp% '---Задержка NEXT j%
CASE IS > 128 '--- Байт меньше 128 '---- Подать на динамик 0 (SpeakOFF) OUT &H61, (INP(&H61) AND &HFD) FOR j% = 0 TO Slp% '---Задержка NEXT j% END SELECT ' PRINT " "; i& NEXT i& 'END IF
CLOSE #1 '--- Закрыть wav-файл PRINT " Ready!... "
SLEEP 3 ' STOP END 'SYSTEM '=============================== TimeUpdate: TIMER OFF PRINT " Timer OFF... " Tm& = Bm& Bm& = 2147483646 RETURN '-------------------------------- | | | | |
В общем, с таким же качеством примерно, как и под "Специалистом", эта программа играет WAV-файл через спикер (под Windows - хуже, под DOS - лучше), но очень меня удивил очень неожиданный факт! Будучи скомпилированной под QBasic 4.5 в ЕХЕ-файл, эта программа работает МЕДЛЕННЕЕ! , нежели в режиме интерпретации самим QBasic 4.5 ! Такое мне встретилось просто впервые! Поэтому делитель b% для вычисления константы задержки берется разный для ЕХЕ-файла и для режима интерпретации в среде QBasic 4.5.
|
26 Mar 2015 15:56 |
|
|
jdigreze
God
Joined: 02 Jan 2006 02:28 Posts: 1390 Location: Abakan
|
А я с этим сталкивался неоднократно. Иногда помогала оптимизация кода. P.S. Попробуй вынести цикл задержки за рамки селекта. И чтение портов сделай сначала в переменную, и только потом запись в порт из переменной.
|
26 Mar 2015 23:17 |
|
|
bigmax
Fanat
Joined: 10 Feb 2014 03:37 Posts: 79
|
Это совсем не ШИМ. А первое применение я увидел в статье "Программный "синтезатор" речи для Радио86-РК", Радио 87 год, №12, страница 27. Помню, что позже была то-ли еще одна подобная статья, то-ли рекомендации к этой, но там говорилось, что если добавить гистерезиса магнитофонному компаратору, то звук станет чище, да и качество чтения повысится.
|
26 Mar 2015 23:28 |
|
|
Stan
Banned
Joined: 04 Jan 2013 10:09 Posts: 397 Location: 95.24.178.158
|
Самый, что ни на есть, настоящий ШИМ. В порт выставляем логические уровни "0" и "1", а реактивность спикера и его цепей используем в качестве интегратора для получения некоторого приближения аналогового сигнала. Собственно, в этой статье: " Использование звуковых файлов формата wav в программах на Бейсике" идея очень подробно и по-детски с картинками расписана. А вот метода модуляции " Программный "синтезатор" речи для Радио86-РК" не существует в природе. Это тоже разновидность ШИМ - Манипуляция шириной импульса ( Pulse-width modulation: PWM). Хотя, вполне вероятно, что алгоритм можно попробовать реализовать и эффективнее, что я и хочу сделать.
|
27 Mar 2015 06:09 |
|
|
Stan
Banned
Joined: 04 Jan 2013 10:09 Posts: 397 Location: 95.24.178.158
|
А какое-то логичное объяснение этому факту предложить можете? А то интерпретация Р-кода выполняется БЫСТРЕЕ, а нативный код выполняется МЕДЛЕННЕЕ! - такой факт просто удивляет! Возможно, такое бывало и раньше, просто никогда не было прецедента так наглядно на слух это прочувствовать!
|
27 Mar 2015 06:21 |
|
|
bigmax
Fanat
Joined: 10 Feb 2014 03:37 Posts: 79
|
| | | | Stan wrote: Самый, что ни на есть, настоящий ШИМ. В порт выставляем логические уровни "0" и "1", а реактивность спикера и его цепей используем в качестве интегратора для получения некоторого приближения аналогового сигнала. Собственно, в этой статье: " Использование звуковых файлов формата wav в программах на Бейсике" идея очень подробно и по-детски с картинками расписана. А вот метода модуляции " Программный "синтезатор" речи для Радио86-РК" не существует в природе. Это тоже разновидность ШИМ - Манипуляция шириной импульса ( Pulse-width modulation: PWM). Хотя, вполне вероятно, что алгоритм можно попробовать реализовать и эффективнее, что я и хочу сделать. | | | | |
Если ты посмотрел указанный номер журнала, то увидел бы что слово "синтезатор" там взято в кавычки, а в тексте написано, что на самом деле происходит запись. Далее, память меня не обманула: буквально через пару журналов, Радио 88 год, №2, страница 29. Тот же автор, программа уже с исходниками и разъяснением, откуда растут ноги. Для ленивых покажу некоторые кусочки: Согласно вики, ШИМ это кодирование уровня скважностью однобитного сигнала. В нашем же случае, это просто знак сигнала относительно некого нуля. Т.е., синус преобразуется в прямоугольник, при этом скважность этого прямоугольника будет равна скважности исходного сигнала. Я игрался с этим алгоритмом на спектруме давно, как раз на том самом ленинграде. Интересно, надо опять попробовать на нем те же опыты. А вот тот самый абзац:
|
27 Mar 2015 07:06 |
|
|
Stan
Banned
Joined: 04 Jan 2013 10:09 Posts: 397 Location: 95.24.178.158
|
Ну а теперь проинтегрируйте этот НЕ "прямоугольник", а меандр со скважностью 2, и что Вы получите? Ну тот факт, что Вы игрались, радует, а то, что из игры не вынесли её смысла - огорчает. И Вы зря приводите здесь материалы этой статьи. Здесь мы говорим о совсем ином процессе, который к Вашим играм "с этим алгоритмом" имеет весьма косвенное отношение. Здесь мы WAV-файл, представленный отсчетами через нормальный ADC, пытаемся воспроизвести через РС-спикер, используя методы ШИМ-модуляции. При этом отмечаем, что алгоритм: является довольно грубым, хотя и дает приемлемый на слух результат, но может быть улучшен. И если Вы обратите внимание на графики, то на приведенной ранее картинке мы и наблюдаем " кодирование уровня скважностью однобитного сигнала", что по Вашей же цитате из Вики и есть ШИМ.
|
27 Mar 2015 07:37 |
|
|
Stan
Banned
Joined: 04 Jan 2013 10:09 Posts: 397 Location: 95.24.178.158
|
Приведу здесь также осциллограммы различных способов модуляции, чтобы Вы повышали свой образовательный уровень, а не просто просиживали штаны, оффтопя на форумах. А вот и подходящие Вашему уровню ссылки на повод почитать: https://ru.wikipedia.org/wiki/Частотно-импульсная_модуляция https://ru.wikipedia.org/wiki/Скважностно-импульсная_модуляция https://ru.wikipedia.org/wiki/Широтно-импульсная_модуляция
|
27 Mar 2015 09:05 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22615 Location: Silicon Valley
|
поаккуратнее с русскоязычными урлами - они не детектируются как урлы, так что лучше их преобразовывать в записи с % (мой фаерфокс делает это автоматически)
|
27 Mar 2015 09:45 |
|
|
jdigreze
God
Joined: 02 Jan 2006 02:28 Posts: 1390 Location: Abakan
|
Есть, кое-какие предположения на этот счёт... Сам язык не приспособлен для компиляции. По сути это скрипт, хоть и с попытками типизации. Компилятор тоже трудно назвать хоть как-нибудь оптимизирующим. В любом случае, даже в только компилируемых языках порой приходится для оптимизации подстраиваться под компилятор.
|
27 Mar 2015 10:01 |
|
|
Stan
Banned
Joined: 04 Jan 2013 10:09 Posts: 397 Location: 95.24.178.158
|
А по сабжу заметил, что обращение к портам, как ни странно, сильно притормаживает сформированный компилятором QBasic файл *.ЕХЕ . Не смотрел, во что это компилирует QBasic, но вот Pascal 7.1 создает довольно "тяжелую" конструкцию в коде. И даже понятно почему.
|
27 Mar 2015 10:52 |
|
|
jdigreze
God
Joined: 02 Jan 2006 02:28 Posts: 1390 Location: Abakan
|
В TP7 вроде можно некоторые моменты оптимизировать методом прямой ассемблерной вставки, и я даже этим иногда пользовался. А QB45 позволяет подключать сторонние библиотеки, в том числе скомпилированные ассемблером. К слову сказать, я только экспериментировал в этом направлении, и к моему сожалению, исходники этих экспериментов утеряны. Почти 20 лет с тех пор минуло. Сейчас подсмотрел в оригинальном help - вся информация по этому вопросу имеется в нём. P.S. Ко мне лучше "на ты".
|
27 Mar 2015 21:07 |
|
|
Who is online |
Users browsing this forum: No registered users and 32 guests |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum
|
|