How to do USB audio
Pages: 1 ... 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
Colin (478) 2433 posts |
I’d just use Dave’s module. My modules are a lower level. |
jim lesurf (2082) 1438 posts |
OK. That’s fair enough for my ‘ROSS Document’ purposes. Although I may say something brief about using the approach in your Isoc programs I’ll focus on USBAudio methods. I guess your changes/addition may need documenting elsewhere in any future PRM updates wrt USB, but I can regard that as someone else’s problem. Suits me as I don’t really understand all the USB details. :-) Jim |
Dave Higton (1515) 3526 posts |
I can’t remember the numbers now; I’m at work. However, I expect to put a new module and API document on my web site tonight (unless my wife decides we’re going out to watch a film, in which case the update may be delayed until tomorrow). I finished testing the module and updating the document last night, but I want to have one more check over it all for any obvious mistakes or omissions before I make it public. |
Dave Higton (1515) 3526 posts |
It’s up there now: http://davehigton.me.uk/Audio |
jim lesurf (2082) 1438 posts |
Thanks, Dave. :-) I’ve now started writing the USB Audio portion of the ROSS Doc. Once I have a version that seems readable I’ll make a copy available so people can read it and point out my errors. You may be pleased to know that I now also plan to change all the SWI numbers I list in it to hex. :-) Jim |
Ronald May (387) 407 posts |
Jim, your player has been working well at detecting and operating at speeds between 44100 and 48000 on the two CMedia devices I have, so nothing bad to report in that area. On a non-driver related subject, the USB-RJ45-USB extender |
jim lesurf (2082) 1438 posts |
Hard for me to comment on that. It works OK on my (RO5.18) Iyonix for rates up to and including 96k/24. But it may depend on the DAC details (USB audio class, etc). On my Iyonix 192k/24 has pauses, particularly for files being played from the main hard disc. I’m not trying to do anything else at the time as the programs are just test/demos and my interest is in situations where the music is what is wanted. I’m not certain I know what you mean by “upset general usage” but if it means things like juddery desktop behaviour, etc, my reaction is based on my approach to music. If I’m listening to music I’m not doing anything else. :-) You chould check if any other apps you are using are wimp hogs. Its possible that a different choice of buffer size would be better. After initial experiments and suggestions from Colin I settled on 0.2 sec for all rates. But for all I know some other size would give better results on an Iyonix. However once the modules worked on my ARMiniX I switched to useing that for most tests and programming. Only occasionally checked the Iyonix when there was a specific reason. You may find playback from ramdisc or an external device works better. Colin’s player doesn’t use the USBAudio module so it perhaps more ‘direct’, but Colin/Dave would have to comment on that.
Some do say their USB sockets have ‘galvanic isolation’ or similar. Others may be switchable. However I’ve not personally noticed much difference when considering the good DACs. Jim |
Dave Higton (1515) 3526 posts |
The USBAudio module takes no part in any recording or replay process. It doesn’t transport audio. It doesn’t control the transport of audio. It will open a stream at the start of replay if you call USBAudio_OpenOut, and it will close the stream whe you’ve finished if you call USBAudio_Close. It has no other interaction with the stream. If you call USBAudio_SetVolume, it will set the volume… etc. etc. Of course, most of the time you won’t be doing that. In fact, if either the player or the DAC doesn’t have a volume control, you won’t be doing it at all. In summary, the USBAudio module cannot have any bearing on gaps in replay or similar effects. |
jim lesurf (2082) 1438 posts |
Given that, I have no idea why Colin’s player might differ from mine on the Iyonix beyond two possible aspects. 1) If my player is having to play an N-bytes-per-sample file into a device that requires more than N bytes per sample transfer. That then causes my player to use a section of code to pad out the values. Maybe Colin does this in a faster and more ingenious way. 2) My player does count loops (0.2 sec per block) and print out an elapsed time in seconds once a second. However I did modify Colin’s player to do much the same and it seemed fine. Beyond that I’m just spooling out the blocks via OS_GBPB much like Colin so far as I know. IIRC he is also using 0.2 sec blocks. But I don’t know if his player maintains the same block duration for all sample rates, etc, as my player does. Maybe the size isn’t optimum on an Iyonix. Dunno. Seems OK here though on mine for all but > 96k/24. Hence my wondering if I’m simply not bothering to do the things with other programs that cause problems with the Iyonix. TBH I’m surprised it works at all for 96k/24 given the age of the hardware! :-) Jim |
jim lesurf (2082) 1438 posts |
BTW I’m still trying to get a maker or dealer to tell me something about various possibly suitable USB ADC/DACs that can do at least 96k/24. I’ll give that a few more days, then if I get no answers I’ll just buy one that looks most promising. Fingers crossed I can then get it to work. My main canditate at present is the Focusrite Scarlett 2i2. 2in 2out 96k/24. Jim |
Colin (478) 2433 posts |
I use a 1 second usb buffer ie samplesize*samplerate eg 8*192000 for 192/24 audio. The disc buffer size is 8000*samplesize. I can play 192/24 on my Iyonix on everything except a filecore formatted USB hard disc. The usb buffer size allows up to 1 second delays in buffer filling. The disc buffer size seems to be the critical one. Too small and the usbbuffer doesn’t fill fast enough and you get pulsing. Too big and the time taken to read the disc is too long and you get pulsing – its a bit like goldilocks :-) If you are using stdio to read from the disc that has its own buffer so you will be adding another buffer layer. You may like to try setting the stdio stream to unbuffered. |
jim lesurf (2082) 1438 posts |
FWIW I use fread to grab input buffer fills from the source (e.g. hard disc). If the data doesn’t need any changes I then give that buffer to the OS_GBPB. However if it needs stuffing with added padding bytes I copy across to another buffer and give that to the OS_GBPB. Both buffer sizes are scaled to be 0.2 sec long for whatever sample rate and depth is needed for a given file and output device. The main exception BTW is that I haven’t bothered to deal with a situation where the input data needs its least significant bytes discarded. I’m not planning to change my demos at present as I’m trying to do some other things. However I could alter them sometime to give the user the ability to choose the buffer period, so it could be, say, 1 sec or less as they prefer. That said, anyone who wants is quite welcome to pinch chunks of my poor ‘C’ and DIY their own improvements as they wish. :-) As an aside, I’m also hoping sometime to add to the player and recorder some peak reading level indicators like the ones I added to !DigitalCD. These show the levels with a quasi-log scale covering 0 to -40dB. Probably more useful for when using something like the UCA202 to record or capture to avoid excess levels. In practice I’ll probably add this to the !USBScope program first when I get around to it. Jim |
Colin (478) 2433 posts |
That may be slowing the filling of the buffer that you send to USB. Instead of one big read from the disc you may be doing multiple smaller ones.
after fopen will disable buffering for fread. |
jim lesurf (2082) 1438 posts |
To check: Do you mean simply using fread for getting chunks of data from the disc may be slow and done in multiple sections unless I use what you suggest? i.e. its slowing the process of reading from disc, which then gives less time for the final bufferfull to be sent out to USB? Not played this particular game before. 8-] But I’ll give it a try when I get a chance. (Probably tomorrow as I’m cooking dinner!) Jim |
Colin (478) 2433 posts |
Yes. |
jim lesurf (2082) 1438 posts |
OK. Thanks. :-) Have to go shopping this morning. I’ll make the change this afternoon and put up the new version after I’ve tested it on my Iyonix. I assume all I need is to add the setvbuf on the line after the fopen for the file I’m going to read in. Must admit I’m puzzled by why this isn’t the default behaviour for freads anyway if it speeds things up. Does this depend on circumstances so not adding the setvbuf after the fopen is faster in many cases? Or is there some other difference? i.e. Is this something I should always do if using fread rather than some fscanfs for ‘text’ values? Guess this shows that the only ‘computing’ course I ever took was a single undergrad module on FORTRAN for ICL1900s! All my ‘C’ etc has been based on “monkey see, monkey do”. 8-] Jim |
Colin (478) 2433 posts |
If you were reading 1 byte (or a small number) of bytes at a time then the default setting is preferable because large disk reads are faster. So normally you read bytes and fread keeps filling its buffer in large chunks. You want to read a large chunk so don’t want the data read in fread buffer sized chunks. The complexity is due to the nature of playing audio – you have to make the data arrive on time. If the computer system was a lot faster using the stdio buffer may not be a problem but we are trying to squeeze the last ounce of performance out of what we have. Having said all that it may not make any difference. |
Dave Higton (1515) 3526 posts |
You may find that it’s fastest to read from the disc in chunks that are an integral multiple of the LFAU size. You don’t need to fill the USB buffer completely every time – just keep it from emptying completely. |
Colin (478) 2433 posts |
Yes I’ve suspected that differences in performance when using different discs is related to the LFAU size. Not filling the usb buffer though is a waste of memory. The purpose of the buffer is to allow the audio to continue while the filling process is eratic. You can’t know what will delay the filling so you have to fill it when you get the chance. |
Dave Higton (1515) 3526 posts |
It’s a compromise. Filling it incompletely, but from blocks that are read as multiples of the LFAU, may work better. Remember that I wrote “may” above, not “will”. Some experimentation would be welcome. (And if someone tries, let’s also remember that the results are unlikely to be universally applicable.) |
jim lesurf (2082) 1438 posts |
Just tried adding the setvbuf after the fopen. On my ARMiniX that causes 192k/24 files to play broken up by pulsing pauses. So it clearly is happier on the ARMiniX with the buffers as defaulted by an fopen. Of course, this is an SD card as the HD, not spinning rust. So even if adding a setvbuf to disable bufferring fixes the problem on an Iyonix it gives a problem on my ARMiniX. (Low rate files seem fine either way as you’d guess.) Is the problem here the LFAU? This is an area I don’t understand at all apart from the most elementary concepts. Is there a way for the program to tell what setting for the buffer size, etc, would be best? Or does it end up as being something you’d have to let each user have the ability to tweak? I can easily put a Y/N for the setvbuf(filehandle,NULL,_IONBF,0); line into the user settings file. But that adds complications and would a simple yes/no be worthwhile? Or would it be better to add the ability to choose a buffer size so people can experiment and then we’d know? BTW Am I the only person using the ‘Acorn’ C complier rather than GCC? I’d be quite happy for others to experiment with modifying what I wrote and saying what changes help them. However is my using the Acorn ‘C’ a barrier? Afraid I long ago got used to the Acorn compiler and the ways I use. I’ve more recently started using GCC for Linux, but find that there I have to use ALSA anyway, so the two situations are very different! Jim |
Colin (478) 2433 posts |
The thing to check now is whether you can reduce the size of the buffer you read with fread I found the smaller that was the better. If you cause problems I wouldn’t worry about it and leave your program as it was originally. |
jim lesurf (2082) 1438 posts |
So having encouraged me to go from 0.1 sec to 0.2 ages ago you’re saying I should reduce it again? 8→ I can consider making this a user chosen ‘settings’ value in, say, 0.05 sec steps. If nothing else, that would make my tests easier as – once done – I won’t have to keep altering the code and recompiling. But if doing this, should I add in setvbuf NBF, or omit setvbuf, or make that another settings option? I can add such things as user choices, but the flexibility may then lead to some users being confused and ‘lost in space’. FWIW So far as I’m concerned the progs are for test/demo purposes, so I don’t mind experimenting. However I’ll probably be spending more time on other things this week. If only because of finally sighing at the lack of response from makers and buying an ADC. [more on that in another posting.] Jim |
jim lesurf (2082) 1438 posts |
I’ve been exchanging emails with someone using Linux who has been trying to get an E-MU0202 ADC/DAC working with Linux. This device is interesting as it should record/capure 192k/24 as well as play it. However it seems to only ‘half work’ with Linux and looks not to be totally standards compatible (what a surprise! :-/) The problem seems to be it requires a special input to get it to change ‘clock’ between 44/88/172k and 48/96/192k but we’re not yet sure. I’ll give the makers of the Focusrite 2i2 a day or two more to reply, then buy one. Some reports say it works fine with Linux, whilst others say it doesn’t. So may be the familiar story of works if you know how to set up ALSA/Jack/whatever correctly. Which is at least promising. Its max is ‘only’ 96k/24 though. Good but not the best I’d hoped for. Jim |
Dave Higton (1515) 3526 posts |
I’d be very interested to see its device descriptor. I wonder if its clock chain contains a clock multiplier? |
Pages: 1 ... 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52