Audio server and low latency audio
Audio server and low latency audio
Hi, I want to know how audio management works ?.. In my design, I have an audio manager in kernel space from where user application obtain 4k buffer, each application writes it's samples to the buffer. If I want to play wav file of 44 mb, application obtain a buffer from the audio manager and writes the first 4k of the file to the buffer and start the audio manager than audio manager request the next block to the application again it reads next block and write it to the audio sample buffer and so on. But it causes click effects and latency. How do you handle this latency and how matured operating system handle this? Is this related to scheduler? I use simple round robin scheduler.
Thanks,
Manas Kamal
Thanks,
Manas Kamal
-
- Member
- Posts: 5563
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Audio server and low latency audio
Your application needs to finish filling the next buffer before the current buffer is done playing. You're not waiting until the buffer is done playing before you request the next one, right?
Re: Audio server and low latency audio
My application wait untill the buffer get finished playing, than the audio manager request a next block of buffer from the application and write it to the next hardware buffer i.e 2nd buffer.. I have 4 buffer descriptor with 4k buffer each..is this method is wrong?..I tried using ring buffer than also it produces click sound..Octocontrabass wrote:Your application needs to finish filling the next buffer before the current buffer is done playing. You're not waiting until the buffer is done playing before you request the next one, right?
-
- Member
- Posts: 5563
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Audio server and low latency audio
Have you tried making the buffer bigger? If your application is having trouble keeping up because of the scheduler, a bigger buffer will give it more time to catch up.
Re: Audio server and low latency audio
There is a trade-off between buffer size and delay. You want to play your audio as quickly as possible, but this requires the use of small buffers. OTOH, if your audio feed thread runs out of buffer space and cannot keep up with hardware, you get distortion (and possibly click sounds).
Therefore, you want your audio feed thread to have above normal priority (or some other means to guarantee it will run when it needs to run). The decoder in user space which sends audio data either can read/create the audio stream ahead of time or needs to be able to decode it in real time.
Initially, you need two full buffers, and when the first buffer has played you need to fill it with the 3:rd buffer data and hand it over to the feed thread before the 2:nd buffer has finished playing.
Therefore, you want your audio feed thread to have above normal priority (or some other means to guarantee it will run when it needs to run). The decoder in user space which sends audio data either can read/create the audio stream ahead of time or needs to be able to decode it in real time.
Initially, you need two full buffers, and when the first buffer has played you need to fill it with the 3:rd buffer data and hand it over to the feed thread before the 2:nd buffer has finished playing.
Re: Audio server and low latency audio
I got the concept...my pci interrupts are not working, that's why I use thread to check current buffer position...
-
- Member
- Posts: 5563
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Audio server and low latency audio
Interrupts are important for audio latency. I think you should fix your PCI interrupts before you do anything else with audio.Kamal123 wrote:my pci interrupts are not working,
Re: Audio server and low latency audio
Yes, I am trying to disable the interrupt disable bit from pci command register, still it doesn't fire interrupt, I use ioapic, where interrupt line is 10 for hdaudio in vbox.Octocontrabass wrote:Interrupts are important for audio latency. I think you should fix your PCI interrupts before you do anything else with audio.Kamal123 wrote:my pci interrupts are not working,
My repository-> https://github.com/manaskamal/aurora-xeneva
-
- Member
- Posts: 5563
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Audio server and low latency audio
The interrupt line field in the PCI configuration space is only valid for legacy PICs, not IOAPIC.Kamal123 wrote:Yes, I am trying to disable the interrupt disable bit from pci command register, still it doesn't fire interrupt, I use ioapic, where interrupt line is 10 for hdaudio in vbox.
You need to use a different method to determine how a PCI IRQ is routed to the IOAPIC.
Re: Audio server and low latency audio
Your easiest solution is to look for MSI or MSI-X functionality in PCI space of the device. You will need ACPI or IRQ detection to get the interrupt line mapping. Also, many PCI interrupts are shared among multiple devices which makes them unattractive.Kamal123 wrote:Yes, I am trying to disable the interrupt disable bit from pci command register, still it doesn't fire interrupt, I use ioapic, where interrupt line is 10 for hdaudio in vbox.Octocontrabass wrote:Interrupts are important for audio latency. I think you should fix your PCI interrupts before you do anything else with audio.Kamal123 wrote:my pci interrupts are not working,
My repository-> https://github.com/manaskamal/aurora-xeneva
Re: Audio server and low latency audio
Your always going to have interrupt sharing, regardless of what method you use. The architecture supports far too few interrupts to support every possible device, and things like the IOAPIC are just hacky workarounds to try to solve this problem. This is especially aggravating given that we're starting to see more and more devices being able to allocate over a thousand MSI-X interrupt entries to themselves (NVMe is a good example, since every I/O queue can have its own interrupt allocated to it) and then we have to squish them into a single tiny set of interrupts. I think that RISC-V has (sort-of) solved this problem, but I don't know how much. And I suspect that the only reason Intel hasn't made the IDT support 2^32 interrupts is because it would break existing OSes. Even if doing so would be a very, very good idea, IMO, and would support the (probably impossible) case of 16777216 devices in PCIe, and would support practically every kind of computer setup for centuries to come, if not longer.rdos wrote:many PCI interrupts are shared among multiple devices which makes them unattractive.
-
- Member
- Posts: 5563
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Audio server and low latency audio
Devices that can allocate over a thousand interrupts are designed for use in high-end servers where you might want to allocate one interrupt per CPU and there can be hundreds of CPUs.Ethin wrote:This is especially aggravating given that we're starting to see more and more devices being able to allocate over a thousand MSI-X interrupt entries to themselves (NVMe is a good example, since every I/O queue can have its own interrupt allocated to it)
There's one IDT per CPU. A high-end server might have a hundred thousand available IDT entries.Ethin wrote:and then we have to squish them into a single tiny set of interrupts.
Re: Audio server and low latency audio
Right, but you can't tell MSI-X which processor to route an interrupt to. I mean, you sort-of can, by telling each device "Hey, all your interrupts should go over to processor 32200", but you can't go "Hey, send interrupts 1, 2, 3, and 4 to processor 330, and send interrupts 10-2048 to processors 32200-32215" or something. At least, not without a bunch of extra hardware like the IOAPIC. Unless I've missed something in MSI-X, that is. So its really MSI/MSI-X that needs extension, but nobody wants to do that because it'd break mainstream OSes.Octocontrabass wrote:Devices that can allocate over a thousand interrupts are designed for use in high-end servers where you might want to allocate one interrupt per CPU and there can be hundreds of CPUs.Ethin wrote:This is especially aggravating given that we're starting to see more and more devices being able to allocate over a thousand MSI-X interrupt entries to themselves (NVMe is a good example, since every I/O queue can have its own interrupt allocated to it)
There's one IDT per CPU. A high-end server might have a hundred thousand available IDT entries.Ethin wrote:and then we have to squish them into a single tiny set of interrupts.
-
- Member
- Posts: 5563
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Audio server and low latency audio
I think you have missed something. MSI-X allows you to specify a different address for each message, and x86 uses 8 bits of the address to specify an APIC ID, so you usually can send each interrupt to a different processor without extra hardware.Ethin wrote:Right, but you can't tell MSI-X which processor to route an interrupt to. I mean, you sort-of can, by telling each device "Hey, all your interrupts should go over to processor 32200", but you can't go "Hey, send interrupts 1, 2, 3, and 4 to processor 330, and send interrupts 10-2048 to processors 32200-32215" or something. At least, not without a bunch of extra hardware like the IOAPIC. Unless I've missed something in MSI-X, that is.
Re: Audio server and low latency audio
You know, I'd like the exact opposite of that: Could we please take a page from PowerPC and get a way to receive all external interrupts at a single place, then maybe push an identifier to the stack? Because right now, I already have two-hundred twenty-four interrupt handler routines that are all doing basically that in software. This also can't be a big problem in the CPU as it already knows which interrupt is being invoked, and it already has a way to push things on stack. (It also can't be a big problem to make the new feature switchable with a bit in, say, EFER. Or make a new MSR if you must.)Ethin wrote:And I suspect that the only reason Intel hasn't made the IDT support 2^32 interrupts is because it would break existing OSes. Even if doing so would be a very, very good idea, IMO, and would support the (probably impossible) case of 16777216 devices in PCIe, and would support practically every kind of computer setup for centuries to come, if not longer.
Or to make it short, I want the interrupt number as data, not as a code address.
For those curious, on PowerPC, all exceptional conditions end up at a certain address defined in the architecture, and "external interrupt" is one such condition. All external interrupts go to address 0x700 (physical). To find out which device interrupted you, you have to ask the PIC, thus making the interrupt number available as data. The architecture only supports this one interrupt level, and a given machine could have any PIC implementation desired, supporting however many interrupts you want.
Carpe diem!