sound, SB, AC97 и другое

Drivers for sound cards
  • В следующей версии собираюсь сделать теоретическую поддержку до 4 млд. каналов, где найти такой стадион и такое железо? :)
  • Hater

    Присылай, только напиши подробнее как работает, а то разбираться в асме тяжело.
  • to Serge
    Объясни, пожалуйста, как драйвер звука (SOUND) в текущей реализации получает данные от микшера (INFINITY), я не смог разобраться. И, если не затруднит, вкратце чем работа с DMA в защищённом режиме отличается от реального.
  • Infinity ставит программный обработчик прерывания, который будет вызывать драйвер звуковой карты.

    Code: Select all

               stdcall set_handler, [hSound], new_mix
    
    set_handler пересылает его драйверу звуковой карты через вызов DEV_CALLBACK
    
    proc set_handler stdcall, hsrv:dword, handler_proc:dword
               ...
               ...
               mov eax, [hsrv]
               lea ecx, [handler_proc]
               xor ebx, ebx
    
               mov [handler], eax
               mov [io_code], DEV_CALLBACK
               mov [input], ecx
               mov [inp_size], 4
               mov [output], ebx
               mov [out_size], 0
    
               lea eax, [handler]
               stdcall ServiceHandler, eax
               ret
    endp
               
    ;;;;;;;;;;;;;;;;;;;;;
    
    sound.asm
    
    proc service_proc stdcall, ioctl:dword
    
               ...
               ...
               cmp eax, DEV_CALLBACK
               jne @F
               mov ebx, [edi+input]
               stdcall set_callback, [ebx]
               ret
    ;;;;;;;;;;;;;;;
    proc set_callback stdcall, handler:dword
               mov eax, [handler]
               mov [ctrl.user_callback], eax
               ret
    endp
    
    и наконец в обработчике прерывания ac97_irq
    
               stdcall [ctrl.user_callback], ebx
    
    ebx - адрес буфера который надо заполнить ( 16 Кб)
    
    Мне не приходилось программировать старые ДМА. Вообще в ядре Колибри уже есть работающий код для SB. Надо только учитывать что ДМА работает с физическими адресами а не с линейными. Если память для ДМА выделена в ядре статически то физ.адр = лин.адр - OS_BASE. Если динамически то физ.адр = get_pg_addr(лин.адр)
  • Спасибо, Serge
    Программный обработчик я заметил, просто не въехал, что подразумевалось под callback. А смысл моего вопроса про DMA (ПДП по-русски) в том, что в реальном режиме область для DMA может лежать только в первом метре памяти и не должна пересекать 64k DMA bound, т.е. если эта область 64k, то она должна быть выровнена на 0x10000. Про физические адреса я знаю, не знал бы даже такого - не брался бы. А код в ядре, как я и говорил ранее, работает просто в DMA режиме, а не в auto-init DMA, как нужно для непрерывного воспроизведения, а там есть различия в программировании DMA, есть даже мысль, что не карта гоняет буфер по кругу, а DMA контролер, но эта мысль будет скоро проверена, после тщательного прочтения одной доки. Кстати, а можно ли в Колибри резервировать IRQ с возвратом, т.е. на время, а то единственный способ, не спрашивая пользователя (PNP\BIOS не сознается, не все карты PNP) определить на каком IRQ висит карта - зарезервировать, все доступные, скомандовать карте что-нибудь очень короткое воспроизвести (выключив программно динамик, чтоб не пугать никого), а какое IRQ прийдёт, то и оставить, остальные вернуть на место.
  • Nable

    Первый мегабайт это 8-ми битный ДМА. SB16 кажется работает с 16-ти битной ДМА. В ядре уже зарезервировано 64 Кб для SB16
    SB16Buffer equ (OS_BASE+0x2A0000). С auto-init DMA я не разбирался но не думаю что отличия слишком большие. У меня принцип работы обработчика такой: когда приходит прерывание все данные для воспроизведения уже готовы. Поэтому обработчик вычисляет адрес следующего сегмента (точнее он берётся из заранее расчитанной таблицы) и вызывает infinity.

    > можно ли в Колибри резервировать IRQ с возвратом

    Пока нет, надо будет дописать код.
  • to Serge
    Hi! I'm sorry but here is another stupid question. I've almost done the driver but I can't hook IRQ5, kernel says that this is busy, already hooked. For example, IRQ7 hooks correctly, but I don't need it, SB is at IRQ5 as an only non-built-in ISA device.
    Kernel code doesn't reserve IRQ5, but it is the fact that I can't hook it through AttachIntHandler. Could you help me?
    Another interesting thing: the documentation says that SB cards is capable to play sound only with up to 44,1kHz discret. clock, but I really got sound clocking my old SBPro (DSP v.3.1) to 48kHz. It works!
  • Забавно, но прерывание уже зарезервировано за SB.

    Code: Select all

    reserve_irqs_ports:
    
            pushad
    
            mov  [irq_owner+4*0], 1    ; timer
            ;mov  [irq_owner+4*1], 1    ; keyboard
            
    >>>>>>  mov  [irq_owner+4*5], 1    ; sound blaster   ;
            mov  [irq_owner+4*6], 1    ; floppy diskette
            mov  [irq_owner+4*13], 1   ; math co-pros
            mov  [irq_owner+4*14], 1   ; ide I
            mov  [irq_owner+4*15], 1   ; ide II
    
    надо убрать эту строчку а заодно и весь код для SB из ядра.

    Вероятно 48 КГц поддерживают клоны SB, а оригинальные чипы только 44100. Надо точно определять какую частоту держит чип или принудительно выставлять их все на 44100.
  • to Serge
    Извини, о таком я и подумать не мог, что это подвох на этапе инициализации.
    А на тему частоты фишка такая. Ковыряться в коде INFINITY не хотелось и я решил, в общем по-русски это называется н""бать судьбу, кажется так, т.е. собрал файлик WAV PCM mono 8-bit 48kHz, отрезал от него заголовок, чтоб не мешался и с помощью RAWOUT и ещё некоторых других досовых прог попробовал его вывести. Одна из прог, сейчас точного названия дать не смогу воспроизводила стабильно, но с отвратительным качеством, по-видимому с меньшей частотой, но две других прекрасно всё воспроизводили, правда недолго, ровно один DMA пакет, но я уверен, что не карта вешалась, а дело оказалось в том, что они были заточены под IRQ7, а у меня 5, а пересобирать их трудновато, проги на C.
    Кстати, чем собран проигрыватель AC97 под Колибри, мне конечный код очень понравился, похоже на MSVC++, он умеет оптимизировать так.
    Короче, надо постараться закончить в ближайшее время этот драйвер, пока есть время.
  • VC2005 и LTG оптимизация. Качество кода действительно очень хорошее.
  • В дистрибутиве 730pre при попытке проигрывания эмпэтришек система намертво зависает. Доска отладки успевает вывести характеристики звуковой подсистемы(nforce2) и выведя start play система виснет. В ревизии 794 зависание происходит после закрытия AC97SND.
  • Баг появился в #774. Исправил.
  • to Serge
    Хотя я и убрал из ядра эту часть, но обломился на баге, который появился в одном из ядер, начиная примерно с SVN750, или 760.
    Смотри viewtopic.php?f=4&t=1031&p=18555#p18555. Кстати вышеописаный (товарищем Maxis) баг я наблюдал. Он в ядре или в проигрывателе?
  • 1)Я не понял что за баг ? Не вызывается установленный обработчик IRQ ?
    Скинь мне исходники я попробую проверить в Боше или Qemu

    2) Баг был в ядре. По-ошибке владельцем обработчика IRQ становился поток загрузивший драйвер. Когда поток закрывался обработчик снимался и система зависала. Вообще если нет установленных обработчиков IRQ надо маскировать линию.
  • Who is online

    Users browsing this forum: No registered users and 46 guests