How to do USB audio
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ... 52
Rick Murray (539) 13840 posts |
There. Fixed that for you. At least with RISC OS, a module running on a ticker ought to continue regardless of what the foreground is doing. I had a tracker player a long time ago that would play even during print jobs, and once it kept playing through that cascading Address Exception error that takes out everything one by one. Just, please, as you are talking about streaming audio, can you please be careful of MIDI. It is streaming audio:MIDI; or class 3 subclass 1 (or is it 1.3?). |
Colin (478) 2433 posts |
Darn I thought “some guarantee” as a description of the quality of service was variable enough I should have known better :-) Midi class is all yours. |
Steffen Huber (91) 1953 posts |
Colin, I am completely with you. DeviceFS tries to adhere to the unixy philosophy of “everything is a file”. My experience with many things USB is: nothing behaves like a file. Most of the time trying to control this USB stuff you are fighting that f*cking streaming interface. Please Colin, relieve us from the burden that is DeviceFS when talking to USB devices. |
Dave Higton (1515) 3526 posts |
That’s right, Colin. And the plan was to make it offer a call to open a stream, given the sample rate, number of channels, etc., returning a stream number. The stream number would be returned by a call to DeviceFS, built up from the parameters passed in. (So far I’ve got a call that returns the interface/alternate/endpoint, but clearly it’s only a small step from there to do as the previous sentence describes.) I don’t yet understand the detail of feedback, so I have nothing to add to the discussion of it as yet. But I see that there is a problem that needs solving, I agree with you. |
Dave Higton (1515) 3526 posts |
Is there any mileage in the idea of linking a file with a stream opend via the USBAudio module, so that the file is handled automatically in the background? For replaying a file, the mystery background process has to keep the USB isochronous buffer filled (prevented from emptying completely, anyway) by reading chunks when necessary and putting them into the USB buffer. Similarly, for recording a file, the background process has to write chunks to the file to prevent the USB buffer from filling completely. There is an interesting problem of initialisation for both directions. Replay doesn’t necessarily start from the first byte of the file – even if you’re playing or recording a WAV file from the first audio byte, it isn’t the first byte of the file. |
jim lesurf (2082) 1438 posts |
Ah! Ok, thanks. I’ve clearly got in a muddle about this! Andrew did send me a ‘beta’ upgrade to test ages ago, but I got busy with other matters and I’ve clearly lost track of the OS situation. I’ll see about updating to 5.21 in the next couple of days. WRT the sound interface. I’m too ignorant of the details to comment beyond my usual generalisation at this point. i.e. That a ‘for now’ situation which established decent output would be fine as a first stab. But that in the longer term I’d agree we need something more universally accessible. I’ve been thinking that it should like a USB version of SoundControl/SharedSound. i.e. similar swis, etc, to make adapting existing players/drivers like PlayIt easier. That said, I personally much prefer an approach like the DigitalRenderer’s filing system. Not just because it is more linuxy, but I simply find that far easier to get working – even if the playout has to keep checking some kind of state value to know when more batches of data are required, etc. Jim |
Rick Murray (539) 13840 posts |
;-) Would it be difficult to add some sort of hook to notify of the arrival of data? The current method (repeatedly read from the file and see if this works) seems really inefficient. |
Colin (478) 2433 posts |
For audio any interface that can be used in a wimp application has to be a “streaming” API because the data has to be available to the device even when the program is paged out. So basically an application has to transfer data into module space before paging out (calling wimp_poll) So at the application programmer level you have something like:
This can be riscosified into swis but the above is for illustration. Sockets work like this. A Note audioWrite has to be nonblocking if you want to multitask which means DeviceFS could be used at this level but I don’t see any advantages – it wasn’t considered an advantage to use it for sockets. At the module level however things change, To write the audioOpenOut() and audioWrite(), or for that matter DeviceFS for Audio, functions you want as direct access to the hardware as you can get. So you end up with an application programmers API for the different device classes. Other bones of contention I have is that I don’t see an Audio Device Class driver module as being USB Specific – but thats another story. |
Colin (478) 2433 posts |
Rick. The notification problem with USB is the same as the socket one. Getting notification inside a module is easy, inside application space its difficult. If you are already using Null wimp events polling the read is as quick as it gets. The only other option I see to do it is the Pollword nonzero wimp event. Which would basically be a null event whenever there is activity and they are very lightweight to implement from interrupt routines. |
jim lesurf (2082) 1438 posts |
Andrew has now replied to me and clarifed the ARminiX situation wrt the assertion that “He has released 5.21 targetted on the ARMiniX.” I was puzzled because what I have, and have more recently have had upgrades for, are all labelled 5.19. His reply is that he has not released a 5.21. But the current version of 5.19 on the ARMiniX should already have included the relevant features required. So I should be OK to do some tests. Beyond that he doesn’t want to comment as work is still under way. That said, I’d be interested to know which specific relatively recent developments of RO are needed for the USB Audio. Jim |
Colin (478) 2433 posts |
It was only the fixes to DeviceFS |
Colin (478) 2433 posts |
I think it would be a useful addition to play a wav file or record a wav file but it wouldn’t be universally useful as playing may need conversions. You would just have to fail if you couldn’t handle it natively and it would be up to the user to ensure the a played wav was in a format supported by the device. |
jim lesurf (2082) 1438 posts |
From my POV simply being able to stream out an LPCM series of (stereo) samples would be fine. The kind of model I’d have in mind is exampled by the way my “!DRplayer” does this via the DigitalRenderer module. I found the DR ‘filing system’ approach very useful. Makes processing an input file and playing the results easy. Jim |
Colin (478) 2433 posts |
Looking at your !DRPlayer it just uses stdio in C to write the sound. You can do that now with USB – thats how DeviceFS works – but the problem with fwrite is that it blocks which isn’t good in a multitasking situation. If you used RISC OS streams instead of C streams OS_GBPB – which is the equivalent of fwrite – does allow you to use DeviceFS streams in non blocking mode. Filling an audio buffer – which is what fwrite does – from any wimp application in application space is going to fail as soon as f12 is pressed. |
Rick Murray (539) 13840 posts |
That’s fine, it’s a module… ;-) |
Colin (478) 2433 posts |
If you are doing a wimp application in the module you still have to use pollword nonzero to return control back to your application. |
Rick Murray (539) 13840 posts |
No, the module just strips out MIDI data to fill a buffer to provide a MIDI module implementation (link somewhere else on the forum, or get the original Acorn doc from ChrisWhy, it is mostly the same). The “front end” reads the data on its own volition using whatever means it likes… What I need is just to have a way of knowing whether or not any MIDI data has arrived instead of this constant check-check-check-check-check arrangement. The thing I wonder though, is that MIDI is a “bulk” device, so it is possible for a bulk device to signal that there is data available? |
Colin (478) 2433 posts |
For bulk if there is no timeout set a request for data will wait until some data is returned by the device. At that point the data is put into the devicefs buffer. When the number of bytes passes the buffer threshold you get a bufferfilling upcall. Use an upcall handler to trap this. The upcall handler will be called in an interrupt context so I’d use a callback from the upcall handler. And do your stuff in the callback handler until you empty the buffer. Once empty data entering the buffer will start it all again. You can set the buffer threshold to trigger when any data enters an empty buffer with the buffer swis. |
Rick Murray (539) 13840 posts |
Is no timeout and non-blocking compatible with one another? Can I request data via GBPB, have control come back to me (so as not to block the system) and then just await the buffer filling notification? Would that work? |
Colin (478) 2433 posts |
Its usbtimeout I’m talking about not the task window timeout Non-blocking doesn’t affect things. Just doing an initial non-blocking osgbpb read and then reading from the callback should work. That’s the theory anyway :) |
Dave Higton (1515) 3526 posts |
I think this may be simply confirming what was already said some time ago, but I’m now in a position to confirm it… All my USB audio devices are full speed only. When they are plugged directly into one of the Iyonix’s USB sockets, all is well – I can open an isochronous pipe to them. USBinfo shows that they go into a full speed root hub (green icon). I plug most of my USB devices into an external high speed 7 port powered hub. USBinfo shows this to be connected to a high speed root hub (yellow icon). However, if I plug a USB audio device into the external hub, I can’t open an isochronous pipe to it. All the control functions work, but, without the audio pipe, that isn’t much use. I also have an external USB 1.1 hub. If I interpose it between the high speed external hub and the Iyonix, USBinfo now shows connection via a full speed root hub. In this configuration, USB audio devices plugged into the 7 port hub work fully. Since the BeagleBoard only has high speed root hubs, I don’t think USB audio devices are going to work with it, in the present state of the USB stack. |
Dave Higton (1515) 3526 posts |
I’ve just started reading up about how isochronous transactions take place between a high speed host and a full speed device through a high speed hub. The USB 2 standard makes it look simple: for an output, issue a split start, the data (in one microframe of a frame), and a split end. We’ll be having trouble with split ends :-) What I haven’t seen yet is how the host knows that the device is full speed. Or maybe it doesn’t need to know – maybe the host does the above sequence regardless. |
jim lesurf (2082) 1438 posts |
Sorry to have not responded sooner but I’ve had a ‘time out’ due to a computer malfunction…. However two points: I have reason to believe that DR may be re-written to use SharedSound rather than SoundDMA. Although I’ll have to clarify the future status of the DR ‘file system’. Personally I want an audio output to ‘block’. One of the primary requirements of best-quality audio is to avoid any mixing with other streams that may generate beeps or hoots or cause the audio level to be rescaled, etc, without user permission. If I wanted mixing, I’d do in in the app or driver feeding the USB. Slainte, Jim |
jim lesurf (2082) 1438 posts |
I can’t comment on that. However the ARMiniX and PandaRo are PandaBoard. Does that make a difference? Jim |
Dave Higton (1515) 3526 posts |
All it means is that I can’t comment because I don’t have one. |
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ... 52