The shortest necessary path to playing audio on Intel HDA

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
wishedtobe
Member
Member
Posts: 63
Joined: Sat May 04, 2024 7:48 am
Libera.chat IRC: wishedtobe

The shortest necessary path to playing audio on Intel HDA

Post by wishedtobe »

Code: Select all

send_verb_respond:
mov [edi],word 2
mov [edi-8],eax
mov [edi],word 1
wait2:
mov dx,[edi]
and dl,3
cmp dl,2
jnz wait2
mov edx,[edi-4]
test edx,edx
ret

send_verb:
mov [edi-8],eax
mov [edi],word 1
wait1:
test [edi],byte 1
jnz wait1
ret

start:             ; edi -> HDA register base address + 0x68
xor eax,eax
inc eax
mov [edi-0x60],eax
wait:
test byte [edi-0x60],1    ;Controller is in operational state
jz wait
dec eax
mov [edi-0x48],eax           ;All interrupts are disabled
mov [edi+8],eax             ;disable DMA position buffer
mov [edi-0x34],eax           ;Stream Synchronization
mov [edi-0x30],eax          ; Stream Synchronization
mov [edi-0x1c],eax             ;CORB is stopped
mov [edi-0xc],eax             ;RIRB is stopped
mov eax,0xf00f0000

find_codec:
add eax,0x10000000
call send_verb_respond
jz find_codec
cmp edx,-1
jz find_codec
mov al,4                         ;get node count
call send_verb_respond            
jz find_codec     
xor ecx,ecx
xchg cl,dl
shl edx,4
add eax,edx                      ;starting node number
mov al,9                            ;Audio Widget Capabilities

find_node:
call send_verb_respond
and edx,0xf00000              ;is it an output widget?
jz node_found
node_not_valid:
add eax,0x100000
loop find_node

node_found:
mov al,0x12            ; Amplifier Capabilities
call send_verb_respond
jz node_not_valid

;    get an appropriate volume value in al that is less than dl

xor eax,0xcb000               ;amplifier gain
call send_verb
mov al,0
xor eax,0x4b500                 ;set power state in full power
call send_verb
xor ax,0x310                    ;stream 1
call send_verb
xor eax,0x50601               ;16bits, 2 channels
call send_verb

mov eax,[edi-0x68]
movzx ebx,ah                 ;directy "movzx ebx,byte [edi-0x67]" would cause bl to be 0 in QEMU
shl bl,4
shl ebx,1
lea edi,[ebx+edi+0x18]        ;edi -> stream 1 base address

mov [edi],byte 1            ;reset
wait3:
cmp [edi],byte 1
jnz wait3
mov [edi],byte 0
wait4:
cmp [edi],byte 0
jnz wait4

mov [edi+0x18],esp                 ;	Lower Base Address of Buffer Descriptor List
xor eax,eax
mov [edi+0x1c],eax            ;Upper Base Address of Buffer Descriptor List
mov al,3
mov [edi+0xc],eax           ;Last Valid Index
mov al,0x11
mov [edi+0x12],ax                        ;16 bits and 2 channels as mentioned above
mov al,0x40
mov [edi+8],eax
mov [edi],dword 0x140002           ;launch

jmp $

Nothing happens. Did I miss some steps?
User avatar
wishedtobe
Member
Member
Posts: 63
Joined: Sat May 04, 2024 7:48 am
Libera.chat IRC: wishedtobe

Re: The shortest necessary path to playing audio on Intel HDA

Post by wishedtobe »

I didn't consider the situation where there is no amplifier at all. Now I am abandoning this step and seeking possible software volume controllers to replace it.
User avatar
wishedtobe
Member
Member
Posts: 63
Joined: Sat May 04, 2024 7:48 am
Libera.chat IRC: wishedtobe

Re: The shortest necessary path to playing audio on Intel HDA

Post by wishedtobe »

Code: Select all

hda_set_volume:
 mov dword [verb_verb], 0xF00
 mov dword [verb_command], 0x12 ;get amplifier info
 call hda_send_verb

 mov eax, dword [hda_response]
 and eax, 0xFF00
 cmp eax, 0
 je .done ;volume can not be changed
-bleskos
wtf this guy is lying to me
User avatar
wishedtobe
Member
Member
Posts: 63
Joined: Sat May 04, 2024 7:48 am
Libera.chat IRC: wishedtobe

Re: The shortest necessary path to playing audio on Intel HDA

Post by wishedtobe »

I misunderstood the meaning of "Cyclic Buffer Length". if I failed again, I'll give up.
User avatar
wishedtobe
Member
Member
Posts: 63
Joined: Sat May 04, 2024 7:48 am
Libera.chat IRC: wishedtobe

Re: The shortest necessary path to playing audio on Intel HDA

Post by wishedtobe »

wishedtobe wrote: Tue Jul 29, 2025 3:53 am wtf this guy is lying to me
He/She maybe right. It's a lot of stuff there.
User avatar
wishedtobe
Member
Member
Posts: 63
Joined: Sat May 04, 2024 7:48 am
Libera.chat IRC: wishedtobe

Re: The shortest necessary path to playing audio on Intel HDA

Post by wishedtobe »

There is no shortest way to achieve it.
User avatar
eekee
Member
Member
Posts: 960
Joined: Mon May 22, 2017 5:56 am
Location: Kerbin
Discord: eekee
Contact:

Re: The shortest necessary path to playing audio on Intel HDA

Post by eekee »

wishedtobe wrote: Wed Jul 30, 2025 2:13 am There is no shortest way to achieve it.
I can believe that. I used to chat with a dev working on Intel HDA, he hated it. The same dev also used to say that the documentation always lies. ;) He meant it contains mistakes, but when you're on the receiving end, it doesn't much matter if it's a mistake or a lie.
Kaph — a modular OS intended to be easy and fun to administer and code for.
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
VSlezak
Member
Member
Posts: 341
Joined: Sat Mar 10, 2018 10:16 am

Re: The shortest necessary path to playing audio on Intel HDA

Post by VSlezak »

Hello, I am behind BleskOS. I am not exactly sure what code are you looking at, as my driver is written in C. If you would be interested, you can find it at https://github.com/VendelinSlezak/Blesk ... ound/hda.c.

I would be glad to help you, however you need to specify where exactly is your driver now. Can you send verbs to card? Can you read types of nodes? Can you read how are those nodes connected? If yes, it would be helpful if you would post it here, so we can manually find shortest path.
User avatar
wishedtobe
Member
Member
Posts: 63
Joined: Sat May 04, 2024 7:48 am
Libera.chat IRC: wishedtobe

Re: The shortest necessary path to playing audio on Intel HDA

Post by wishedtobe »

eekee wrote: Wed Jul 30, 2025 5:40 am I can believe that. I used to chat with a dev working on Intel HDA, he hated it. The same dev also used to say that the documentation always lies. ;) He meant it contains mistakes, but when you're on the receiving end, it doesn't much matter if it's a mistake or a lie.
It's all my fault. Due to my poor English, I had no idea what pins, AFGs, and widgets are, and I mistakenly connected AFG as a widget to the stream. Further suggestions are appreciated.
User avatar
wishedtobe
Member
Member
Posts: 63
Joined: Sat May 04, 2024 7:48 am
Libera.chat IRC: wishedtobe

Re: The shortest necessary path to playing audio on Intel HDA

Post by wishedtobe »

VSlezak wrote: Wed Jul 30, 2025 3:17 pm Hello, I am behind BleskOS. I am not exactly sure what code are you looking at, as my driver is written in C. If you would be interested, you can find it at https://github.com/VendelinSlezak/Blesk ... ound/hda.c.

I would be glad to help you, however you need to specify where exactly is your driver now. Can you send verbs to card? Can you read types of nodes? Can you read how are those nodes connected? If yes, it would be helpful if you would post it here, so we can manually find shortest path.
But I remembered you had been coding that in assembly when I found it in 2023 on github.com
rdos
Member
Member
Posts: 3396
Joined: Wed Oct 01, 2008 1:55 pm

Re: The shortest necessary path to playing audio on Intel HDA

Post by rdos »

Playing on hda is easy, even in assembly, but the problem is to calculate a path from source to the output (speaker) and to enable the right widgets on that path. I did the former in assembly but the latter in C.
VSlezak
Member
Member
Posts: 341
Joined: Sat Mar 10, 2018 10:16 am

Re: The shortest necessary path to playing audio on Intel HDA

Post by VSlezak »

wishedtobe wrote: Wed Jul 30, 2025 8:44 pm But I remembered you had been coding that in assembly when I found it in 2023 on github.com
Yes, I was coding in assembly at that time, but my code developed a lot from then, so if something feels wrong, it probably is.

Anyway, to actual playing audio. You need to take PIN node with device you want to use (probably speakers), and then start to look at how nodes are connected to find path to Audio Output node. Fortunately, many codecs are designed in way, that if you simply follow first connected node, you will get to Audio Output node in shortest possible way. It is not guaranteed, but for simplistic design (as testing driver) good enough. From my experience, shortest path on most codecs has three nodes and looks like this: Audio Output -> Mixer -> PIN. However depending on you codec, you can get completely different path.

When you collected all nodes in path, next step is to enable all of them + AFG node. Here is list what to do:

AFG node
  • Reset
  • Turn on power
Audio Output
  • Turn on power
  • Connect node to stream and channel you will use to stream audio data
  • Unmute node
Mixer
  • Turn on power
  • Unmute node
Selector
  • Turn on power
  • Unmute node
  • Select node that will be next in path
PIN
  • Turn on power
  • Enable PIN
  • Enable EAPD
  • Unmute node
You will also want to control volume. To do it, you need to collect Audio Output Capabilities of every node in path. If some node do have them, you can then use informations from it to control volume of that node. If no node in path has them, it mean that volume is controlled by Audio Output node and Capabilities are taken from AFG node.

After this you have initalized your output path, and you only need to start streaming data, and nodes will correctly process them and deliver to device at output PIN.

If you need help with something specific, just send here how does your codec nodes looks like, so we can analyze them.
User avatar
wishedtobe
Member
Member
Posts: 63
Joined: Sat May 04, 2024 7:48 am
Libera.chat IRC: wishedtobe

Re: The shortest necessary path to playing audio on Intel HDA

Post by wishedtobe »

VSlezak wrote: Sat Aug 02, 2025 7:12 am Mixer
  • Turn on power
  • Unmute node
What does the mixer do?
VSlezak
Member
Member
Posts: 341
Joined: Sat Mar 10, 2018 10:16 am

Re: The shortest necessary path to playing audio on Intel HDA

Post by VSlezak »

From specification:
7.2.3.4 Mixer (Summing Amp) Widget
The Mixer Widget provides the facility to arbitrarily mix multiple channels (sources). It has two or more inputs and one output.
It takes audio streams from all input sources, mixes them to one audio and outputs it to next node. You can think of it as when in program for cutting audio (as Audacity) you have multiple sounds at same position on timeline, and then you play it - program needs to transform those multiple sounds to one output sound. Mixer is doing exactly the same thing.
User avatar
wishedtobe
Member
Member
Posts: 63
Joined: Sat May 04, 2024 7:48 am
Libera.chat IRC: wishedtobe

Re: The shortest necessary path to playing audio on Intel HDA

Post by wishedtobe »

VSlezak wrote: Thu Aug 14, 2025 5:14 am It takes audio streams from all input sources, mixes them to one audio and outputs it to next node. You can think of it as when in program for cutting audio (as Audacity) you have multiple sounds at same position on timeline, and then you play it - program needs to transform those multiple sounds to one output sound. Mixer is doing exactly the same thing.
Is it necessary? I think software mixer is absolutely competent at this job.
Post Reply