The new SoundDMA module
Jeffrey Lee (213) 6048 posts |
This message is basically just a quick “heads up” to say that I’m starting work on the new version of the SoundDMA module (which will make use of the DMAManager module and a proper HAL audio interface, as suggested by Ben in this post) And – this is the important bit – this new version will not retain compatability with the existing PCI/AC97/HAL implementation which the Iyonix uses. I.e. the new module won’t work on the Iyonix (unless the Iyonix HAL audio device is rewritten to comply with the new API). The new version of the module will be added as a new “branch” in CVS, under the moniker Sound0HAL. To me this seems like the most sensible thing to do, as it will keep the source code clean and allow me to more easily make architectural changes (e.g. Sound0Trid currently updates some of the AC97 registers during the interrupt routine, which won’t work too well on the OMAP since the registers will have to be updated via IIC) So if ROOL have any objections to the creation of the new “branch”, they’d better mention them soon before I rip out too much code ;) |
Steve Revill (20) 1361 posts |
No objections here… |
Alan Robertson (52) 420 posts |
Sound like this will be another important piece of work to improve the foundations of RISC OS. Go for it. |
Jeffrey Lee (213) 6048 posts |
As a brief update, sound is now in a semi-working state. There are a couple of major issues that could each take a few days of troubleshooting to resolve (problems with the mixer settings causing distorted sound output, and some kind of DMA problem causing underflow in the sound buffers), but once they’ve been resolved it should only take another day or two of tidying the code before it’s ready for release. I’m also wondering whether increasing the size of the audio buffer will stop the sound stuttering on the Iyonix when the IOP DMA is in use. I’m not sure about anyone else, but when trying to find a solution to the problem in the past I’ve only tried looking at the size of the IOP DMA transfers, and forgotten completely about being able to use Sound_Configure to control the size of the audio DMA. The default buffer size is only 208 stereo samples per DMA transfer, but it can be increased to 1024. I’ll try to have a quick play with this tonight and report my results. |
Trevor Johnson (329) 1645 posts |
Nice one! Must chase up my Beagleboard order :-) |
Jeffrey Lee (213) 6048 posts |
Answer: No :( |
Jeffrey Lee (213) 6048 posts |
The sound code is mostly working now. The only thing that’s really holding me back from making a release is that there’s a bug which occasionally causes the stereo channels to be swapped, and I’m restructuring the code in various ways to try and find a fix. So while I’m working on that, I was wondering if ROOL/someone could provide some feedback on what I should do with the mu-law to 16bit conversion code. The problem is that it’s using unaligned LDR’s, so doesn’t work as intended on ARMv6/v7 (or at all if alignment exceptions are enabled). The easiest fix would be to change it to use LDRSH, but that would prevent us from using this version of SoundDMA on RiscPC’s with the IOMD HAL. Alternatively the code could be rewritten to use aligned LDR’s (making it less optimal for all platforms), or the code generator1 could be modified so that it’s able to detect at runtime what machine type is in use and generate the appropriate code (which would produce optimal code for each machine type, but make the generator significantly more complex). What are ROOL’s thoughts on this? Are we ever likely to want to run this version of SoundDMA on IOMD, or is the plan just to use the original pre-HAL version? (once it’s been taught about the variable IOMD address, according to the comment in the IOMD32 components file) 1 For those who aren’t familiar with the code, the mu-law to 16bit conversion routine is generated at runtime so it can provide optimal performance for the current 8-bit sound configuration (number of sound channels and their stereo positions). So modifying the generator so it’s able to generate code suitable for two different ARM architectures may make it significantly more convoluted than it already is. |
Peter Naulls (143) 147 posts |
Can you just make use of conditional assembly here, for the target machine (of which the RO code makes extensive use of anyway)? A concern here might be the if the module was distributed by itself for generic use, as was often done in the past, but I think in practice, it’s rather more likely it’d be part of a whole ROM image and therefore contain only instructions for that specific ROM/machine. This would presumably be a lot simpler than a complex per-machine code generator. I appreciate that you end up with a module that has the same version for all machines but actually has different code, and the module versioning is orthogonal to this. |
Jeffrey Lee (213) 6048 posts |
Yes, conditional assembly would be fairly easy, and wouldn’t adversely affect the readability of the source. |
Dave Higton (281) 668 posts |
One thing to bear in mind about audio buffering: the possibility of use for VoIP, which mandates low latency, which in turn mandates short buffers. |
Jeffrey Lee (213) 6048 posts |
It looks like there are two situations in which this bug occurs. Information below, for the curious: The first cause, which I’ve spent most of my time looking at, is a FIFO overflow when attempting to disable the DMA that’s used to fill the FIFO. This cause has me worried because the FIFO threshold and DMA transmit size are identical – i.e. the buffer containing the sound data will only be DMA’d to the FIFO once the FIFO contains enough space to contain the entire buffer. So by all reason there should be no way for the FIFO to overflow, especially when I’m in the middle of disabling the DMA! To me this smells suspiciously like a hardware bug, which is why I’m so worried about it. But, the good news is, it won’t ever cause the stereo channels to swap when used with the real driver, because the real driver (unlike the test driver I managed to recreate this bug with) will only disable the DMA when it’s about to disable & flush the FIFO anyway. The second cause, which I only diagnosed today after giving up on the first one, is a FIFO underflow when enabling the sound hardware that lies on the other side of the FIFO. This one’s a bit odd because the code makes sure the FIFO is mostly full before enabling the sound hardware – so it must mean that after I enable sound RISC OS does something silly like leave IRQs disabled for a long time (the current OMAP DMA driver doesn’t support looping or infinite-length transfers, so the DMAManager module must manually set up the next DMA transfer after previous one completes). I haven’t yet checked with my fiqprof tool to see if RISC OS is misbehaving here or not. Anyway the good news is that although I might not be able to fix the root cause of the underflows & overflows, I can at least add some code to listen out for the under/overflow IRQ and re-initialise the sound hardware when one is detected. Even if I hadn’t found these bug(s) it would be a good idea to include this fix anyway, just to make sure everything continues to work OK should something go wrong when under normal use. |
Jeffrey Lee (213) 6048 posts |
The new SoundDMA, and the rest of the OMAP sound code, is now in CVS. A few brief notes:
Sometime this weekend I’ll also try to update the wiki with the details of the new version of the audio HAL device API. |
Rob Heaton (274) 515 posts |
Thanks excellent! To save bandwidth on the ROOL CVS, I have uploaded the OMAP3 CVS tree as it was at 9:15 this morning. Download from here – http://www.robheaton.co.uk/beagleboard/src-omap.5.15.tar.bz2 OMAP3 ROM, built from the sources today, including sound support – http://www.robheaton.co.uk/beagleboard/rom-omap.5.15.zip |
Jeffrey Lee (213) 6048 posts | |
Jeffrey Lee (213) 6048 posts |
Last night I checked in my first batch of SoundDMA/Sound0HAL changes, to get things working with the (VCHIQ-based) Pi sound driver. Main changes are that the decision to use stereo reversal is now made at runtime instead of compile time, and the module now supports devices which don’t use DMAManager for transferring data. In the next few days I’m hoping to tweak things a bit further, so that the module won’t die horribly if the sound device vanishes. Apart from being useful for the Pi (since the sound HAL device is currently managed by a softloaded module), this should also pave the way towards having a version of the module which can switch between different devices at runtime (e.g. onboard sound and USB audio). At some point I’m hoping Sound0HAL will become generic enough that I can switch the IOMD & Tungsten ROMs over to using it, so that we’ve only got one version of SoundDMA in use instead of three. But I suspect we’re still a little bit away from that goal. |
Jess Hampshire (158) 865 posts |
This is excellent news. Will the Pi have the choice of HDMI and Analogue audio? |
Jeffrey Lee (213) 6048 posts |
At the moment it just lets the GPU decide which output to use. This is because the Pi only allows you to have one output active at once, but the way the mixer/volume settings work under RISC OS assumes you can have any number of outputs active at once. So we’ll have to have a think about the best way of adding support for audio routing switches – I’m sure that in the future there’ll be other platforms with similar limitations. |
Jess Hampshire (158) 865 posts |
So yes, really. :) Could they be treated as one output by RISC OS? With a switch between where the sound goes. (even if it just changed the config.txt file, so the next boot changes) |