Системный динамик вместо звуковой карты

Подключаем наши девайсы к компьютеру. Обсуждаются: порты, протоколы, драйвера, языки программирования и т.д.
А.Андрей
Друг Кота
Сообщения: 6900
Зарегистрирован: Ср май 05, 2010 13:31:29

Системный динамик вместо звуковой карты

Сообщение А.Андрей »

Итак...
Возникла одна идея.
Использовать ВМЕСТО звуковухи "РС-спикер"
Это было возможно (вполне)
Есть два способа достижения этого:
Википедия писал(а):Имеются два способа управления динамиком.
Программируемый таймер, генерирующий прямоугольную звуковую волну заданной частоты без участия центрального процессора. Это позволяет проигрывать простые одноголосые звуковые сигналы. Если программа зависала во время проигрывания звука, таймер продолжал работать, выдавая одну ноту, пока компьютер не перезагрузят.
И прямое управление мембраной через порт 61h с дискретностью в 1 бит. Подавая с большой частотой то 0, то 1, с помощью широтно-импульсной модуляции можно синтезировать низкокачественный оцифрованный звук — правда, за счёт существенного использования ресурсов процессора. Этим в своё время широко пользовались трекеры и некоторые игры (Metal Mutant). Все подобные программы не работают в многозадачных операционных системах.

Драйвер разрабатываю для Win XP.
Считаю, второй способ на уровне ядра вполне возможен.
По обоим вопросам есть определенные наработки:
По обоим СПРАВКА И ПРИМЕРЫ:

Код: Выделить всё

                            - 31 -

                  Таймер и генерация звука

               Программируемый таймер 8253

      Для задания временных интервалов  и формирования сигналов с
 различными  временными  параметрами   в  IBM  PC/XT  применяется
 программируемый таймер 8253  (отечественный аналог КР580ВН53), в
 AT - 8254.  С точки зрения программиста они  идентичны. В состав
 таймера   входят:   буфер    шины   данных,   схема   управления
 вводом-выводом  и  три  независимых  канала,  каждый  из которых
 содержит  регистр  режима,  схему  управления  каналом,  буфер и
 16-разрядный счетчик.

      Программирование   канала   осуществляется   путем   вывода
 управляющих слов в регистр  режима каналов и начального значения
 в его счетчики. Каждый канал имеет управляющий вход GATE и выход
 OUT и может работать в одном из следующих шести режимов.

       Режим  0   (прерывание  терминального  счета). После записи
 управляющего  слова  в  регистр  режима  канала  на  выходе  ОUT
 устанавливается напряжение низкого  уровня; загрузка счетчика не
 изменяет  это  состояние.  Затем  начинается  декремент счетчика
 (последовательное  вычитание из  него единицы).  В момент, когда
 счетчик  обнулится,  на  выходе  OUT  установливается напряжение
 высокого  уровня  и  сохраняется   до  загрузки  счетчика  новым
 значением.  Счет возможен  только при  наличие сигнала  высокого
 уровня  на   входе  GATE.  Низкий  уровень   этого  сигнала  или
 ниспадающий фронт запрещают счет.

      Перезагрузка  счетчика  во  время  приводит  к  следующему:
 загрузка  младшего  байта  останавливает  текущий счет, загрузка
 старшего байта запускает новый цикл счета. Минимально допустимое
 значение счетчика равно 2.

      Режим 1  (ждущий мультивибратор).  На выходе OUT формируется
 отрицательный  импульс  длительностью  t=n*T,  где  n  -  число,
 загруженное  в счетчик,  T -  период тактовых  импульсов. Низкий
 уровень на выходе OUT  устанавливается со следующего такта после
 подачи на вход GATE сигнала высокого уровня.

      Загрузка в  счетчик нового числа не  влияет на длительность
 текущего   импульса,  а   учитывается  при   следующем  запуске.
 Перезапуск счетчика производится  нарастающим фронтом входа GATE
 (без перезагрузки счетчика). Минимальное допустимое n=1.

      Режим  2  (генератор  частоты). Каждый  раз после достижения
 счетчиком нуля на выходе  OUT появляется отрицательный импульс с
 длительностью  один  такт.   Перезагрузка  счетчика  сказывается
 только  после  перезапуска  счетчика.  При  исчезновении сигнала
 высокого уровня на  входе GATE прекращается счет и  на выход OUT
 подается   напряжение  высокого   уровня.  Перезапуск   счетчика
 происходит при наличии на входе GATE сигнала высокого уровня.

      Режим  3   (генератор  меандра).  Аналогичен  режиму  2,  но
 положительный   уровень   выходного   сигнала   занимает  первый



                            - 32 -

 полупериод, а отрицательный -  второй полупериод. Точнее, если n
 (начальное    значение   счетчика)    четно,   то   длительность
 положительного и  отрицательного полупериодов равна  n*T/2; если
 же  n нечетно  - то  (n+1)*T/2 и  (n-1)*Т/2 соотвественно. Низкй
 уровень  сигнала на  входе GATE  запрещает счет,  на выходе  OUT
 устанавливается  сигнал  высокого  уровня.  Высокий уровень GATE
 разрешает  счет, а  нарастание его  запускает счетчик начального
 состояния. Отметим, что n=3 в этом режиме недопустимо.

      Режим  4   (счетчик  событий).  По  окончании отсчета числа,
 загруженного в счетчик, на  выходе OUT формируется отрицательный
 импульс длительностью один такт. Запись в счетчик во время счета
 младшего  байта не  влияет на  текущий счет,  а запись  старшего
 байта перезапускает счетчик. Низкий уровень входа GATE запрещает
 счет,  высокий  -  разрешает.  Минимальное  допустимое  значение
 счетчика равно 1.

      Режим  5   (счетчик  событий  с  автозагрузкой).  Отличие от
 режима 4 состоит  в том, что каждое нарастание  сигнала на входе
 GATE перезапускает  счетчик. Перезагрузка счетчика  не влияет на
 текущий   цикл,   однако   следующий   цикл  определяется  вновь
 занесенным числом.

      Временные диаграммы режимов  таймера приведены на следующем
 рисунке:

        ¦-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬
   CLK  +-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L
   __   +¬n=5 ----------¬n=4 ----------
   WR   ¦L-----                L-----
        ¦       ----------¬   ---------
   GATE +--------                         L----
        +-----¬           ----------¬               ---
   OUT  ¦     L------------         L----------------
        ¦
   n    ¦      5 4 3 2 1 0           4 3 2     2 1 0
        L-------------------------------------------------

                             Режим 0

        ¦-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬
   CLK  +-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L
   __   +¬n=4 -------¬n=5 ----------
   WR   ¦L-----      L-----
        ¦         ----------¬    --¬    ----------
   GATE +----------          L----- L-----
        +----------¬       --------¬               ---
   OUT  ¦           L--------       L----------------
        ¦
   n    ¦          4 3 2 1 0       5 4 3  5 4 3 2 1 0
        L-------------------------------------------------

                             Режим 1

 


                            - 33 -

        ¦-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬
   CLK  +-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L
   __   +¬n=4 ---¬n=3 ----------
   WR   ¦L-----  L-----
        ¦      ----------¬    ----------
   GATE +-------                        L-----
        +----------¬ -----¬ ------¬ ----------¬ ---
   OUT  ¦             L--    L--     L--          L--
        ¦
   n    ¦      4 3 2 1 0 3 2 1 0 3 2 1 0      3 2 1 0
        L-------------------------------------------------

                             Режим 2

        ¦-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬
   CLK  +-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L
   __   +¬n=4 ----------¬n=5 ----------
   WR   ¦L-----                L-----
        ¦     ----------¬   ----
   GATE +------                                L----
        +----------¬    ------¬    ------¬    ---------
   OUT  ¦          L-----     L-----     L-----
        ¦
   n    ¦      4 3 2 1 0  4 3 2 1 0  4 3 2 1 0  5   5 4
        L-------------------------------------------------

                             Режим 3

        ¦-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬
   CLK  +-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L
   __   +¬n=4 ----------¬n=5 ----------
   WR   ¦L-----                L-----
        +----------¬   ----------
   GATE ¦                              L----
        +----------¬ ----------¬ --
   OUT  ¦              L--                            L--
        ¦
   n    ¦      4 3 2 1 0             5      5 4 3 2 1 0
        L-------------------------------------------------

                             Режим 4

        ¦-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬-¬
   CLK  +-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L-L
   __   +¬n=4 ----------
   WR   ¦L-----
        ¦         ---------¬   --¬   ----------
   GATE +----------        L---- L----
        +----------¬ ----------¬ -------
   OUT  ¦                 L--                 L--
        ¦
   n    ¦         4 3 2 1 0    4 3    4 3 2 1 0
        L-------------------------------------------------

                             Режим 5
 


                            - 34 -

      В  IBM  PC  таймер  имеет  базовый  адрес  40h  и следующие
 программируемые регистры:

  Адрес     Операция        Назначение
 ----------
   40h       запись       Загрузка счетчика канала 0
             чтение       Чтение счетчика канала 0

   41h       запись       Загрузка счетчика канала 1
             чтение       Чтение счетчика канала 1

   42h       запись       Загрузка счетчика канала 2
             чтение       Чтение счетчика канала 2

   43h       запись       Запись управляющего слова
                          в регистр режима канала
 ----------

      Управляющее слово имеет следующий формат:

  7  6  5  4  3  2  1  0
 --T--T--T--T--T--T--T--¬
 ¦    ¦     ¦        ¦  ¦  Биты                          Маска
 L-+--+--+--+--+T-+--+-T-  ----                        -------
   ¦     ¦      ¦      L> 0: 0 = двоичный код,           а & 1
   ¦     ¦      ¦            1 = двоично-десятичный код
   ¦     ¦      L-------> 1-3: режим работы канала:      а & 0Eh
   ¦     ¦                     000 - режим 0
   ¦     ¦                     001 - режим 1
   ¦     ¦                     X10 - режим 2
   ¦     ¦                     X11 - режим 3
   ¦     ¦                     100 - режим 4
   ¦     ¦                     101 - режим 5
   ¦     L--------------> 4-5: вид загрузки счетчика:    а & 30h
   ¦                           00 - "защелкивание"
   ¦                                (биты 0-3 безразличны)
   ¦                           01 - только младший байт
   ¦                           10 - только старший байт
   ¦                           00 - младший байт, затем старший
   L--------------------> 6-7: номер канала:             a & C0h
                               00 - канал 0
                               01 - канал 1
                               10 - канал 2
                               11 - запрещенная комбинация

      Существует  два способа  чтения текущего  значения счетчика
 канала.

      1. Чтение с остановом  счетчика. Для обеспечения стабильных
 показаний  необходимо приостановить  работу канала  либо подачей
 сигнала  низкого  уровня  на  вход  GATE  (кроме режима 1), либо
 блокированием тактовых импульсов.

      2. Чтение "на лету".  Для считывания счетчика без остановки
 процесса  счета  используется  посылка  в  порт 43h управляющего
 


                            - 35 -

 слова в режиме "защелкивания"  (см. выше). Это управляющее слово
 фиксирует  текущее значение  счетчика  и  Вы можете  считать его
 младший байт, а затем старший байт.

             Таймер на системной плате IBM PC

      В IBM PC каналы таймера имеют следующее назначение.

   Канал      Назначение                        Режим
 ----------
     0        системные часы (IRQ0)          3, счетчик=0 (65536)
     1        запрос для канала 0 ПДП
              (регенерация памяти)           2, счетчик=18
     2        генератор звука                      --
 ----------

      Тактовая частота  каждого канала равна  1,19318 МГц, т.  е.
 каждый такт имеет длительность 0,84  мсек. Вход GATE каналов 0 и
 1 всегда  имеют высокий  уровень, поэтому  счет на  этих каналах
 разрешен всегда. Вход GATE канала 2 управляется битом 0 порта PB
 интерфейса 8255 (см. гл. 5), связанного с портом 61h.

      При  начальной  загрузке  BIOS  инициализирует  канал 0 для
 работы в  режиме 3 со  счетчиком 0 (т.  е. 65536 декрементов  на
 цикл счета). Поэтому частота системных часов равна
      1,19 МГц/65536 = 18.2 Гц
 и прерывание IRQ0,  связанное с вектором Int  8, происходит 18,2
 раз в секунду, т. е. каждые 55 мсек.

      Вы можете перепрограммировать канал 0, но тогда

      - BIOS не сможет отслеживать текущее время и дату;

      -  нарушится работа  с гибкими  дисками, т.  к. включение и
 выключение их двигателей отсчитывается по текущему времени.

      Канал  1  работает  в  режиме  2  со  счетчиком 18, поэтому
 регенерация   памяти  происходит   каждые  18   мсек.  Перепрог-
 раммировать  его нельзя,  т. к.  это приведет  к потере данных в
 ОЗУ.

      Программирование канала 2 описано в следующем пункте.

 


                            - 36 -

                     Генерация звука

      На  вход  звукогенератора  поступает  логическое  "И"  двух
 сигналов: выхода  OUT 2-го канала  таймера и содержимого  бита 1
 порта  РВ интерфейса  8255. Поэтому  простейший способ генерации
 звука состоит в программировании канала  2 таймера так, чтобы он
 выдавал  прямоугольный  импульс   заданной  частоты,  лежащий  в
 звуковом  диапазоне  (20  Гц  -   20  КГц).  Для  этого  следует
 использовать  режим таймера  3 с  подходящим начальным значением
 счетчика. Если затем установить биты 0  и 1 порта РВ, то импульс
 начнет поступать на вход звукогенератора  (бит 0 - это вход GATE
 канала 2, разрешающий  счет, а бит 1 -  разрешение выдачи выхода
 OUT  на вход  звукогенератора). Для  выключения звука достаточно
 сбросить биты  0 - 1 в  РВ. Преимущество этого метода  состоит в
 том, что,  запустив генерацию звука,  ЦП может выполнять  другие
 действия. Значение  счетчика 2-го канала  вычисляется по формуле
 n=1193181/f=1234DDh/f (1193181 - тактовая  частота таймера в Гц,
 f - требуемая частота звука).

      Пример:

            ;
            ; подпрограмма генерации звука
            ; Вход: АX= частота звука в Гц
            ;
 Sound      proc     near
            push     ax        ;сохранить регистры
            push     bx
            push     dx
            mov      bx,ax     ;частота
            mov      ax,34DDh
            mov      dx,12h    ;(dx,ax)=1193181
            cmp      dx,bx     ;если bx < 18Гц, то выход
            jnb      Done      ;чтобы избежать переполнения
            div      bx        ;ax=(dx,ax)/bx
            mov      bx,ax     ;счетчик таймера
            in       al,61h    ;порт РВ
            or       al,3      ;установить биты 0-1
            out      61h,al
            mov      al,00001011b   ;управляющее слово таймера:
                               ;канал 2, режим 3, двоичное слово
            mov      dx,43h
            out      dx,al     ;вывод в регистр режима
            dec      dx
            mov      al,bl
            out      dx,al     ;младший байт счетчика
            mov      al,bh
            out      dx,al     ;старший байт счетчика
 Done:
            pop      dx        ;восстановить регистры
            pop      bx
            pop      ax
            ret
 Sound      endp
            ;



                            - 37 -

            ;подпрограмма выключения звука
            ;
 No_Sound   proc     near
            push     ax
            in       al,61h    ;порт РВ
            and      al,not 3  ;сброс битов 0-1
            out      61h,al
            pop      ax
            ret
 No_Sound   endp

      Для генерации музыки можно использовать следующий алгоритм.
 Пусть octave  - номер октавы  (1, 2, ...);  note - номер  ноты в
 октаве (до=1, до#=2, ..., си=12). Тогда:

      f := 32.625;
      for i := 1 to oktave do f := 2*f;
      for i := 1 to note do f := 1.059463094*f
      Sound (round(f));

      Второй  способ   генерации  звука  состоит   в  том,  чтобы
 генерировать звуковые импульсы не  выходом таймера, а установкой
 и сбросом бита 1 в регистре  РВ. Для управления задержками можно
 использовать программный цикл, например:

           ;
           ; Программа генерации звука
           ; Вход: N=количество импульсов
           ;       FREQ=длительность импульса
           ;
           in        al,61h         ;порт РВ
           and       al,not         ;сброс бита 0
           mov       dx,N
 Repeat:
           or        al,2
           out       61h,al         ;установить бит 1
           mov       cx,FREQ
 Wait_On:
           loop      Wait_On
           and       al,not 2       ;сбросить бит 1
           out       61h,al
           mov       cx,FREQ
 Wait_Off:
           loop      Wait_Off
           dec       dx
           jnz       Repeat

      Программирование   этого  способа   основано  на  следующих
 формулах.  Если Т  - длительность  звучания в  сек, f  - частота
 звука в Гц, а t - тактовая частота процессора ПЭВМ, то

      N=T*f; FREQ=t/(34*f).

      Константа 34  объясняется тем, что  длительность каждого из
 циклов Wait_on и Wait_off  приблизительно равна (17*cx) машинных



                            - 38 -

 тактов.

      Неудобство  этого метода  состоит в  том, что  ЦП полностью
 занят  генерацией звука  - любое  прерывание испортит  временную
 диаграмму  звукового  сигнала.  Однако  он  обеспечивает  точную
 подстройку частоты и позволяет создавать несимметричные импульсы
 варьированием задержек в циклах Wait_on и Wait_off.


Сама вся эта книжка как сделать по сути комп(и как его настроить) - кому интересно - вот (в кодировке 866)
По-второму методу - это (пример на асме) Файл-пример работы со спикером по другому методу.
Сейчас напряженно думаю - по какому из двух путей пойти? По-первому - довольно-таки просто, но вот не обеспечивает данный подход гибкости - нужен сквенсор звуков(программный, для определения частоты звука и его длительности), и значит, разные подпрограммы для решения одной задачи - включения\выключения динамика, а еще нужно будет заблокировать прерывания (кто не блокировал прерывания в соотв. драйвере для WIN 3.1 - тот поймет, при обычном проигрывании шло жуткое и противненькое шипение, а при движении мышью/нажатием клавиши - вообще ппц, ибо нет звука, один гром и свист :kill: )
По второму - тоже нужно запрещение прерываний и еще тоже сквенсор - программный ШИМ.
С прерываниями двольно-таки просто - команда RDTSC и подсчет прошедших тактов, после опредееленного числа их - разрешение прерываний и вызов Windows API Sleep(0), чтоб обеспечить многозадачность.
Что посоветуете - какой способ избрать? И как сделать сам драйвер, с какими системными и\или прикладными прогами и\или структурами должен работать драйвер, чтобы программы и система "поверила" в то, что это и есть драйвер звука и направила поток на него?
Сообщения рода "это геморно, иди в школу, а не проще ли пользоваться звуковухой и не е*ать мозги себе и окружающим?" и пр. считаются за ОФФТОПИК, и будут БЕСПОЩАДНО караться модератором, ибо здесь не помойка, а тематический раздел.
За любые полезные советы - заранее спасибо!
Спасибо за внимание.
Tolmi
Говорящий с текстолитом
Сообщения: 1658
Зарегистрирован: Вс дек 11, 2011 05:25:04
Откуда: Киев, Украина
Контактная информация:

Re: Системный динамик вместо звуковой карты

Сообщение Tolmi »

Запретишь прерывания и твоя винда повиснет наглухо. Смысл в звуке, если всё остальное не работает ? Для изначально многозадачных систем такой звук принципиально невозможен. Именно поэтому сейчас нигде и не используется.
In theory, theory and practice are the same. In practice, they're not.
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: Системный динамик вместо звуковой карты

Сообщение Alexeyslav »

Идти нужно по первому пути. Таймер вполне способен формировать ШИМ-сигнал самостоятельно. А собственно, между переполнениями таймера нам делать нечего - и не нужно.

Вот только не помню, спикерный таймер имеет выход на какое-либо прерывание? если нет, то надо следить за временными интервалами вручную или при помощи другого таймера. Но насколько я знаю на одном из них считается системное время, второй... можно использовать, но вдруг он используется для каких-то целей в системе?
Tolmi
Говорящий с текстолитом
Сообщения: 1658
Зарегистрирован: Вс дек 11, 2011 05:25:04
Откуда: Киев, Украина
Контактная информация:

Re: Системный динамик вместо звуковой карты

Сообщение Tolmi »

Alexeyslav писал(а):Таймер вполне способен формировать ШИМ-сигнал самостоятельно.

PC - это не настолько детерминированная архитектура, как, скажем, МК. Вернее, лучше сказать, совсем не детерминированная, об этом никто никогда не заботился, она для другого задумывалась. В PC временные интервалы будут гулять настолько, что нужного звука получить не удастся.
Я одно время пытался получить равномерный ввод в PC со скоростью 1000 отсчётов в секунду. Это задача примерно равная задаче получения звука частотой 100Гц. Ерунда получается. Джиттер настолько велик, что лишает процесс всякого смысла. Чисто программными ухищрениями ничего получить не удастся, нужны ещё аппаратные средства ( для поставленной задачи - саундкарта, для моей - буфер с детерминированным вводом и произвольной по времени выборкой, а дальше уже можно как хочешь обработать)
Хотя, если не обращать внимания на хрип и свист, то звук из динамика можно получить, есть же линуксовые драйвера для вывода звука через PC Speaker. Звучит кошмарно, но для каких-то целей может и сгодится.
In theory, theory and practice are the same. In practice, they're not.
Аватара пользователя
oleg235
Держит паяльник хвостом
Сообщения: 927
Зарегистрирован: Пт ноя 20, 2009 14:32:31
Откуда: Минск

Re: Системный динамик вместо звуковой карты

Сообщение oleg235 »

У меня один вопрос.
На хуа?
DIMON_CHAiNIK\\
Мудрый кот
Сообщения: 1817
Зарегистрирован: Ср июн 30, 2010 22:45:49

Re: Системный динамик вместо звуковой карты

Сообщение DIMON_CHAiNIK\\ »

У меня тот же вопрос. :shock:
А.Андрей
Друг Кота
Сообщения: 6900
Зарегистрирован: Ср май 05, 2010 13:31:29

Re: Системный динамик вместо звуковой карты

Сообщение А.Андрей »

oleg235 писал(а):У меня один вопрос.
На хуа?

Мне это необходимо. Поэтому прошу помощи советом, и нечего разводить помойку, если нечем помочь :wink:
Tolmi писал(а):Запретишь прерывания и твоя винда повиснет наглухо. Смысл в звуке, если всё остальное не работает ? Для изначально многозадачных систем такой звук принципиально невозможен. Именно поэтому сейчас нигде и не используется.

нет.
я лично думаю, что можно запретить прерывания, и считать такты процессора через команду RDTSC, и, по достижении определенного кол-ва тактов, разрешать прерывания.
Alexeyslav писал(а):Идти нужно по первому пути. Таймер вполне способен формировать ШИМ-сигнал самостоятельно. А собственно, между переполнениями таймера нам делать нечего - и не нужно.

Вот только не помню, спикерный таймер имеет выход на какое-либо прерывание? если нет, то надо следить за временными интервалами вручную или при помощи другого таймера. Но насколько я знаю на одном из них считается системное время, второй... можно использовать, но вдруг он используется для каких-то целей в системе?

нужно именно запретить прерывания.
Иначе будет хрип и свист.
вотъ
Tolmi писал(а):
Alexeyslav писал(а):Таймер вполне способен формировать ШИМ-сигнал самостоятельно.

PC - это не настолько детерминированная архитектура, как, скажем, МК. Вернее, лучше сказать, совсем не детерминированная, об этом никто никогда не заботился, она для другого задумывалась. В PC временные интервалы будут гулять настолько, что нужного звука получить не удастся.
Я одно время пытался получить равномерный ввод в PC со скоростью 1000 отсчётов в секунду. Это задача примерно равная задаче получения звука частотой 100Гц. Ерунда получается. Джиттер настолько велик, что лишает процесс всякого смысла. Чисто программными ухищрениями ничего получить не удастся, нужны ещё аппаратные средства ( для поставленной задачи - саундкарта, для моей - буфер с детерминированным вводом и произвольной по времени выборкой, а дальше уже можно как хочешь обработать)
Хотя, если не обращать внимания на хрип и свист, то звук из динамика можно получить, есть же линуксовые драйвера для вывода звука через PC Speaker. Звучит кошмарно, но для каких-то целей может и сгодится.

Вот что не было хрипов и свиста нужно запретить прерывания.
затем разрешать прерывания, и ждать переключения контекста.
тогда хрипов и свиста будет в 2,5 раза меньше.
А временные интервалы - тут все еще проще.
Даем команду CPUID c eax=2, узнавая конфигурацию камня и узнаем частоту колебаний системного таймера путем перехвата в таблице IDT системного таймера, на пару секунд, тестируем, запоминаем настройки. Затем подстраиваем алгоритм под все это. И все.
Кстати, провел эксперимент.
ВСЯ МОЯ СХЕМА ЧАСТИЧНО НА ПРАКТИКЕ РЕАЛЬНО РАБОТАЕТ!

Код: Выделить всё

▓    TESTPROC.TXT  ↓FR       00000000     --------      160 ║ Hiew 6.11 (c)SEN
▓ 00000000:  00 00 00 0A-6C 65 74 6E-49 65 6E 69-75 6E 65 47     ◙letnIeniuneG
▓ 00000010:  00 00 06 FD-00 00 E3 9D-BF EB FB FF-00 02 08 00    ♠¤  уЭ┐ы√  ☻◘
▓ 00000020:  05 B0 B1 01-00 00 00 00-2C B4 30 78-00 56 57 F0  ♣░▒☺    ,┤0x VWЁ
▓ 00000030:  3B 8E F1 3C-00 00 00 00-00 00 3A 72-00 00 00 00  ;Оё<      :r
▓ 00000040:  45 41 58 7C-45 43 58 7C-45 44 58 7C-45 42 58 7C  EAX|ECX|EDX|EBX|
▓ 00000050:  31 2D A5 20-3A 20 43 50-55 49 44 20-41 58 3D 30  1-е : CPUID AX=0
▓ 00000060:  32 2D A5 20-3A 20 43 50-55 49 44 20-41 58 3D 31  2-е : CPUID AX=1
▓ 00000070:  33 2D A5 20-3A 20 43 50-55 49 44 20-41 58 3D 32  3-е : CPUID AX=2
▓ 00000080:  34 2D A5 20-3A 20 52 44-54 53 43 20-81 5C 8F 2E  4-е : RDTSC Б\П.
▓ 00000090:  35 2D A5 20-3A 20 8E 8F-90 5C 90 85-83 2D 8E 82  5-е : ОПР\РЕГ-ОВ













▓1Help   2PutBlk 3Edit   4Mode   5Goto   6       7Search 8Header 9Files 10Quit

Это то что я снял со своей тестовой проги.
Конфигурация камня и НЕЗАВИСИМЫЙ от прерываний счетчик тактов.
Осталось только расшифровать 2-ю и 3-ю строки - конфигурации проца.
И еще необходимо знать, как написать сам звуковой драйвер, как заставить его правильно взаимодействовать с системой?
Спасибо за внимание.
Tolmi
Говорящий с текстолитом
Сообщения: 1658
Зарегистрирован: Вс дек 11, 2011 05:25:04
Откуда: Киев, Украина
Контактная информация:

Re: Системный динамик вместо звуковой карты

Сообщение Tolmi »

А.Андрей писал(а):
Tolmi писал(а):Запретишь прерывания и твоя винда повиснет наглухо. Смысл в звуке, если всё остальное не работает ? Для изначально многозадачных систем такой звук принципиально невозможен. Именно поэтому сейчас нигде и не используется.

нет.
я лично думаю, что можно запретить прерывания, и считать такты процессора через команду RDTSC, и, по достижении определенного кол-ва тактов, разрешать прерывания.

И в это время у тебя не будет работать никакой ввод/вывод? Я про это и говорю, выглядет это будет как висящая винда. Мышка не шевелится, винт не шуршит, на экране ничего не происходит. Зато звук играет. Зашибись. Рассказываю рецепт более простой - грузишь MS DOS и не паришься с драйверами. Результат ведь один и тот же.
Вот что не было хрипов и свиста нужно запретить прерывания.
затем разрешать прерывания, и ждать переключения контекста.

Ага, а в этот момент у операционки что-то затребовало считать что-то с винта. И оно по DMA как полилось.... И пофиг, что прерывания запрещены. А readahead установлен в 128 килобайт. И эта операция заняла 12 миллисекунд. Рассказать, что в терминах звука это означает ? А потом я мышкой пошевелил. А оно бац - и в синий экран. Потому что данные на USB не буферизованы и они ждать не станут, когда это там через несколько миллисекунд разблокируют прерывания.
Короче идея о том, что с современной операционкой можно обращаться как захочется, изначально обречена на постоянные "синие экраны смерти".

oleg235 писал(а):У меня один вопрос.
На хуа?

У меня тот же вопрос. За время написания такого драйвера можно вполне собрать какую-нибудь дешевую USB саундкарту и не морочить себе мозги.
In theory, theory and practice are the same. In practice, they're not.
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: Системный динамик вместо звуковой карты

Сообщение Alexeyslav »

От часового таймера отходит прерывание, его как минимум можно использовать для задания интервалов с которыми будет запускаться другой таймер в режиме однократного счета, или непрерывного но с таким расчетом чтобы сформировать импульс необходимой длительности до прихода следующего прерывания от часового таймера. При этом процесс не обязан постоянно пасти таймер и отмерять интервалы программно. Проблема только будет с ходом часов - ведь мы на себя взяли обработку прерывания от часового таймера, поэтому надо вызывать оригинальный обработчик каждые 18мс и никто не заметит подмены до тех пор пока какое-то приложение не захочет обрабатывать прерывание от таймера... Ну вобщем, никто и не сказал что будет легко.

Кстати, зачем изобретать велосипед? Для Win98 такой драйвер вполне существовал, звук паршивый - 8кГц обеспечивал, но никакого "шума от прерываний".
Tolmi
Говорящий с текстолитом
Сообщения: 1658
Зарегистрирован: Вс дек 11, 2011 05:25:04
Откуда: Киев, Украина
Контактная информация:

Re: Системный динамик вместо звуковой карты

Сообщение Tolmi »

Alexeyslav писал(а):От часового таймера отходит прерывание, его как минимум можно использовать для задания интервалов с которыми будет запускаться другой таймер в режиме однократного счета, или непрерывного но с таким расчетом чтобы сформировать импульс необходимой длительности до прихода следующего прерывания от часового таймера.

:facepalm: почитайте для начала про архитектуру PC ... Это вам не микроконтроллеры...
При этом процесс не обязан постоянно пасти таймер и отмерять интервалы программно. Проблема только будет с ходом часов - ведь мы на себя взяли обработку прерывания от часового таймера, поэтому надо вызывать оригинальный обработчик каждые 18мс и никто не заметит подмены до тех пор пока какое-то приложение не захочет обрабатывать прерывание от таймера...

Какие такие 18 мс? Вопрос для знатоков архитектуры Windows NT и всех более поздних - какова частота системного таймера в этих системах и зачем он там нужен.
И ещё один маленький вопрос, кто в Windows NT и более поздних даст управлять ресурсом (порты IO,прерывания), занятым уже существующим системным драйвером....
Кстати, зачем изобретать велосипед? Для Win98 такой драйвер вполне существовал, звук паршивый - 8кГц обеспечивал, но никакого "шума от прерываний".

Потому что Win98 была надстройкой над MS DOS, а не ОС ;) Шутка конечно, но в каждой шутке есть доля шутки. Win98 не было никакого контроля за поведением драйверов, и именно поэтому она так часто падала. Попробуйте в Windows 7 в драйвере сделать что-то неправильное с точки зрения супервизора. Прерывания запретить, к примеру. Он его отстрелит, скорее всего, и будет прав. Наконец-то они эту фичу доделали до почти рабочего состояния.
In theory, theory and practice are the same. In practice, they're not.
А.Андрей
Друг Кота
Сообщения: 6900
Зарегистрирован: Ср май 05, 2010 13:31:29

Re: Системный динамик вместо звуковой карты

Сообщение А.Андрей »

Tolmi писал(а):
А.Андрей писал(а):нет.
я лично думаю, что можно запретить прерывания, и считать такты процессора через команду RDTSC, и, по достижении определенного кол-ва тактов, разрешать прерывания.

И в это время у тебя не будет работать никакой ввод/вывод? Я про это и говорю, выглядет это будет как висящая винда. Мышка не шевелится, винт не шуршит, на экране ничего не происходит. Зато звук играет. Зашибись. Рассказываю рецепт более простой - грузишь MS DOS и не паришься с драйверами. Результат ведь один и тот же.
Вот что не было хрипов и свиста нужно запретить прерывания.
затем разрешать прерывания, и ждать переключения контекста.

Ага, а в этот момент у операционки что-то затребовало считать что-то с винта. И оно по DMA как полилось.... И пофиг, что прерывания запрещены. А readahead установлен в 128 килобайт. И эта операция заняла 12 миллисекунд. Рассказать, что в терминах звука это означает ? А потом я мышкой пошевелил. А оно бац - и в синий экран. Потому что данные на USB не буферизованы и они ждать не станут, когда это там через несколько миллисекунд разблокируют прерывания.
Короче идея о том, что с современной операционкой можно обращаться как захочется, изначально обречена на постоянные "синие экраны смерти".

Да будет вам известно, милейший, что в определенный момент времени исполняется ТОЛЬКО! одна задача! (есть правда многоядерные системы, но там используется команда-префикс LOCK).
И соответственно, запрещаем прерывания.
И маскируем немаскируемое прерывание одной подпрограммой.
И, соответственно, как система о чем то узнает? Все по фигу, система ни фига не видит, она просто не выполняется.
Про Семеру я вообще молчу - ВЕЗДЕ там (во всех нтишках) НУЛЕВОЕ КОЛЬЦО ЗАЩИТЫ!
А значит, всем ВСЕ там МОЖНО!!!!!!!
А в человеческих терминах - перехват прерывания осуществляется ОЧЕНЬ просто! Запоминаем предыдущий указатель в таблице IDT, переписываем. Через определенное число "тиков" - LOCK CLI и вся проблема :))
Меня больше интересует - Что должен делать в системе звуковой драйвер, чтобы определяться системой как драйвер и как звуковой и чтобы система перенаправляла туда свой сетевой поток? :))
но поэтому надо юзать ИМЕННО ТАЙМЕР! тогда таких проблем не будет, хотя надо проверить.
Спасибо за внимание.
Tolmi
Говорящий с текстолитом
Сообщения: 1658
Зарегистрирован: Вс дек 11, 2011 05:25:04
Откуда: Киев, Украина
Контактная информация:

Re: Системный динамик вместо звуковой карты

Сообщение Tolmi »

А.Андрей писал(а):И соответственно, запрещаем прерывания.
И маскируем немаскируемое прерывание одной подпрограммой.

:facepalm:
Для начала почитайте MSDN, прежде чем браться за такую задачу. Об проблемах с длительным монопольным захватом процессора на уровне драйвера я уже писал.
Декларируемый подход сработает в MS DOS и Win95/Win98 и не будет работать в Win XP. В семерке драйвер, который попытается такое сделать, будет отстрелен системой.
IDT в WinNT подобных системах напрямую драйверам недоступен, они им манипулируют через соответствующее ядерное API.
Про Семеру я вообще молчу - ВЕЗДЕ там (во всех нтишках) НУЛЕВОЕ КОЛЬЦО ЗАЩИТЫ!
А значит, всем ВСЕ там МОЖНО!!!!!!!

Правда? ;) Значит зря программисты Microsoft столько кода написали :)
Сходите ка лучше куда-нибудь на любой программистский форум по этой тематике, и там повеселите народ.
In theory, theory and practice are the same. In practice, they're not.
А.Андрей
Друг Кота
Сообщения: 6900
Зарегистрирован: Ср май 05, 2010 13:31:29

Re: Системный динамик вместо звуковой карты

Сообщение А.Андрей »

IDT доступен через ядро о_О
А команда LIDT и команда SIDT вам ни о чем не говорят?
А.. вы будете спорить что есть ТОЛЬКО нулевое и третье кольца?.. о да, это суровая правда времени!!!!1111 :)))
Сначала нтишку портировали на другие процы, и там было лишь 2 кольца защиты, а в "интел" - их 4, да вот только ничего не поменялось.
Да вот еще вопрос:
Что должен делать в системе звуковой драйвер, чтобы определяться системой как драйвер и как звуковой и чтобы система перенаправляла туда свой сетевой поток?

На который знатоки до сих пор не дали ответа :(
Спасибо за внимание.
Tolmi
Говорящий с текстолитом
Сообщения: 1658
Зарегистрирован: Вс дек 11, 2011 05:25:04
Откуда: Киев, Украина
Контактная информация:

Re: Системный динамик вместо звуковой карты

Сообщение Tolmi »

А.Андрей писал(а):IDT доступен через ядро о_О
А команда LIDT и команда SIDT вам ни о чем не говорят?

Говорят, говорят. Ну почитайте MSDN всё же, для начала, тогда будет меньше вопросов.
PS Линейный адрес для IDTR откуда мы узнаем ? От экстрасенсов?
И это... Страничная защита работает и в нулевом кольце тоже. Обломс....
In theory, theory and practice are the same. In practice, they're not.
А.Андрей
Друг Кота
Сообщения: 6900
Зарегистрирован: Ср май 05, 2010 13:31:29

Re: Системный динамик вместо звуковой карты

Сообщение А.Андрей »

хорошо.
Тогда используем первый путь, не требущий запрета прерываний.
С таймером.
И еще:
Что должен делать в системе звуковой драйвер, чтобы определяться системой как драйвер и как звуковой и чтобы система перенаправляла туда свой сетевой поток?
Спасибо за внимание.
Tolmi
Говорящий с текстолитом
Сообщения: 1658
Зарегистрирован: Вс дек 11, 2011 05:25:04
Откуда: Киев, Украина
Контактная информация:

Re: Системный динамик вместо звуковой карты

Сообщение Tolmi »

А.Андрей писал(а):Что должен делать в системе звуковой драйвер, чтобы определяться системой как драйвер и как звуковой и чтобы система перенаправляла туда свой сетевой поток?

Ещё раз, по шагам.
1. ставим Visual Studio, особо обращаем внимание на то, чтобы поставить Visual C, Kernel Debugging, Remote Kernel Debugging, Windows Driver Kit
2. ставим MSDN, особо обращаем внимание на то, чтобы поставить секцию Windows Driver Development.
3. Читаем последовательно Getting Started with Windows Drivers, Kernel-Mode Driver Architecture, Windows Driver Frameworks, Developing, Testing, and Deploying Drivers, Device and Driver Development Tools
4. Если после внимательного прочтения указанных материалов останутся вопросы, через полгода, я думаю, я на них отвечу. Полгода на изучение имхо вполне достаточно.
In theory, theory and practice are the same. In practice, they're not.
А.Андрей
Друг Кота
Сообщения: 6900
Зарегистрирован: Ср май 05, 2010 13:31:29

Re: Системный динамик вместо звуковой карты

Сообщение А.Андрей »

Пожалуйста, дайте мне сведения, ЧТО ДОЛЖЕН ДЕЛАТЬ ДРАЙВЕР ЧТОБЫ ПРОИГРЫВАТЬ ЗВУК И УСПЕШНО ОПРЕДЕЛЯТЬСЯ В СИСТЕМЕ???
Базовые знания для построения драйвера у меня ЕСТЬ, поэтому прошу дать максимально КОНКРЕТНЫЙ ответ.
Дайте ссылку на этот ответ, на худой конец.
Если стесняетесь, пишите в личку :roll:
Спасибо за внимание.
Tolmi
Говорящий с текстолитом
Сообщения: 1658
Зарегистрирован: Вс дек 11, 2011 05:25:04
Откуда: Киев, Украина
Контактная информация:

Re: Системный динамик вместо звуковой карты

Сообщение Tolmi »

А.Андрей писал(а):Дайте ссылку на этот ответ, на худой конец.
Если стесняетесь, пишите в личку :roll:

Через полгода. Читайте документацию. Более того, там даже пример есть, как раз нужный и даже с исходниками. Ссылку не дам из вредности. Ищите и обрящете.
In theory, theory and practice are the same. In practice, they're not.
А.Андрей
Друг Кота
Сообщения: 6900
Зарегистрирован: Ср май 05, 2010 13:31:29

Re: Системный динамик вместо звуковой карты

Сообщение А.Андрей »

Ну я вас прошу по человечески, пожалуйста.
Вы получите персональную версию :wink:
Спасибо за внимание.
Аватара пользователя
Bear2011
Друг Кота
Сообщения: 13253
Зарегистрирован: Ср апр 06, 2011 09:58:13
Откуда: Кузбасс

Re: Системный динамик вместо звуковой карты

Сообщение Bear2011 »

Не знаю как под ХР но вот когда звуковые карты не были интегрированы на материнки для Win3.11 существовал драйвер speaker.sys (или .drv) который работал и под Win95 Выдавал неплохой звук. Правда тогда и динамики были не пьезо а с нормальным диффузором
Ответить

Вернуться в «Интеграция с ПК»