Page 1 of 3

The shortest necessary path to playing audio on Intel HDA

Posted: Mon Jul 28, 2025 11:48 pm
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?

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

Posted: Tue Jul 29, 2025 2:59 am
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.

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

Posted: Tue Jul 29, 2025 3:53 am
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

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

Posted: Tue Jul 29, 2025 10:59 pm
by wishedtobe
I misunderstood the meaning of "Cyclic Buffer Length". if I failed again, I'll give up.

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

Posted: Wed Jul 30, 2025 12:13 am
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.

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

Posted: Wed Jul 30, 2025 2:13 am
by wishedtobe
There is no shortest way to achieve it.

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

Posted: Wed Jul 30, 2025 5:40 am
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.

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

Posted: Wed Jul 30, 2025 3:17 pm
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.

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

Posted: Wed Jul 30, 2025 8:25 pm
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.

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

Posted: Wed Jul 30, 2025 8:44 pm
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

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

Posted: Fri Aug 01, 2025 11:38 am
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.

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

Posted: Sat Aug 02, 2025 7:12 am
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.

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

Posted: Thu Aug 14, 2025 1:31 am
by wishedtobe
VSlezak wrote: Sat Aug 02, 2025 7:12 am Mixer
  • Turn on power
  • Unmute node
What does the mixer do?

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

Posted: Thu Aug 14, 2025 5:14 am
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.

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

Posted: Fri Aug 15, 2025 7:14 pm
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.