How to do USB audio
Pages: 1 ... 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 ... 52
Dave Higton (1515) 3526 posts |
“No matching parameter set” happens when you try to play a file that requires a resolution, number of channels, sampling rate and subframe size that your USB audio device doesn’t support. UAPlayer doesn’t attempt to do any translation of the samples to meet the device’s requirements. Well there is a small mitigation: if you provide (for example) 24 bit or 32 bit samples and 4 bytes per subframe to a 20 bit device, UAPlayer works out that there is a compatible set of parameters and asks for those. What are the resolution, number of channels and sampling rate of the file you’re trying to play? What device are you trying to play it through? |
Dave Higton (1515) 3526 posts |
I’m increasingly worried that the sample rates supported by modern audio devices often don’t include some of the rates we want and we used to have on earlier hardware. For example, iyoPhone requires 8 kHz, which is supported by the Iyonix’s internal sound card, but not by any inexpensive USB audio device I’ve yet seen. It’s fairly common for devices to support only 48 kHz, which is no use even for playing a CD. Sample rate conversion, done properly and efficiently, requires lots of CPU cycles (multiply-accumulates). It’s OK on a general purpose DSP, but would consume an intolerable amount on any ARM CPU. So, to be useful in practice, what sample rates do we need so support, and what devices can we short-list that support them? Or can we get DSP going on one of the modern platforms that includes a DSP? |
Raik (463) 2061 posts |
The device is the reportet and the samples are yours (48kHz and 44,1kHz). Both shouldt work. |
Colin (478) 2433 posts |
Raik. Your device plays 44100 and 48000 2 channel 16 bit audio so after loading the new USBModules run !IsocPlayer then double clicking an a 44100/2/16 or 48000/2/16 wav file should play. To get !IsocRecorder to work change line 44 in Run from
to
ie change the &13c to &139 !IsocRecorder will start recording as soon as it is run and save the recorded file on the ram disc. You device can only record 48000 or 44100 16bit mono After recording double clicking on the recorded file will play it. |
Dave Higton (1515) 3526 posts |
Raik: if you mean the samples from my web site, they are mono (recorded from a headset). Your device only supports stereo replay. If you rip a track from a CD as a stereo WAV file, it should play OK. There are some devices that support both mono and stereo playback (I have one, and I have access to another), but the cheapest ones don’t in my experience. |
Colin (478) 2433 posts |
What strikes me about the devices I’ve seen is how many use ‘C-Media Electronics Inc’ firmware. Even one of Jim’s expensive dacs has it. |
jim lesurf (2082) 1438 posts |
For me the problems are that I’ve never successfully written anything as a desktop wimp apps, and don’t know enough to do something like !PlaySound + PlayIt which does as you suggest. So I’d have to do a lot of hard puzzling to deal with that in addition to checking I can get Colin/Dave’s modules to work and that I understand them. So I initially will write something that runs in a taskwindow just for test purposes, then look at using the graphics ability of GraphTask to do something that provides a more convenient interface. Which means that after the most simple starting tests I’ll try using GraphTask. I appreciate this seems odd to anyone competent programmer who finds writing wimp tasks easy. But alas the plain truth is that I’m not much of a programmer and haven’t had any success with wimp apps in the past, and am baffled by module code. As I’ve said before, I’d urge anyone who is cleverer than me to do a decent wimp amp + modules player. Something I’d welcome. I’m doing this to try and focus on my own learning how to explain. I can then explain Colin/Dave’s modules and their interfaces in terms similar to the examples I’ve given for other areas in the ‘ROSS’ document which I did to bring together audio details not in the PRMs. Helps me to learn and explain. Not trying to write a player that everyone else will then use. I’m happy if they just sigh when they see it and someone decides to do it properly. I’d encourage an urge by someone to nudge me out of the way and do it properly because I’m clearly making a mess. :-) Failing that I’ll muddle along as best I can. As the French nearly say: It’s not magnificent, it’s a railway station. ;→ Jim |
jim lesurf (2082) 1438 posts |
This is why I was makin a fuss about upsampling, etc, a while ago. From the tests I did (and the !Upsampling demo) it seems quite feasible with modern RO software to do the resampling in the player. Have my doubts it can be done so well at the module level, but I’m not competent to really say on that. I doubt anyone who wanted to play an 8k rate file would complain if the result wasn’t superb audio quality. But 44.1k to 48k is a real PITA to do well. Should be feasible in an app, though. That said, 44.1k to 96k is easier to do well. FWIW for anyone who has missed them and interested: The Upsampling demos are on my audiomisc.co.uk software page. They use x2 as the simplest example. But using pre-computed sets of coefficients other ratios would work about as quickly. Just need sets of coefficients to cycle around as the phases change between the sample instants. At present I’m assuming any ‘learning’ player I write will just ensure a match of byte-depths so as to play, say, 16bit on a device that wants 24 or 32. But I could add a demo of resampling as part of the player as well if I ever get that far and its would be useful. I’m a long way from that at present, though! Jim |
jim lesurf (2082) 1438 posts |
I think many makers have simply used the same USB interface chip/software as it works OK. This may be a “good thing” from our POV as it makes for a more stable target. :-) How they process the data once it emerges from their USB interface in the DAC is another issue. For an audio company that’s probably where their focus is placed and what they sell on. Jim |
Ronald May (387) 407 posts |
Re Downsampling- Using Colins record prog I put an inbetween buffer that discards every second 16 bits and sets the affected words in the header. This did achieve a 24000 mono wav but the quality is not good due to a mosquito like static proportional to the amplitude of the audio. From googling, the approach for downsampling seems to be to use a low pass filter /before/ |
Dave Higton (1515) 3526 posts |
Absolutely right. Once you’ve removed energy above the new lower Nyquist frequency, you are justified in removing the excess samples.
The low pass filtering inherently smooths the reduced samples. |
jim lesurf (2082) 1438 posts |
You can do the filtering and downsampling in the same calculation. e.g. just use the same sort of method I use for upsampling via a ‘transverse array’ in the time domain. This also covers any “smoothing” you want to do. The demos show how you can either use the classic sinc-based way or mimic an analogue low-pass filter, etc.
Converting to 8bit isn’t likely to reduce the HF. Indeed, unless you dither it may add garbage. An analog filter on the input can fix the problem if it works well enough. Indeed, in principle all ADC processes should be preceeded by a filter to define the accepted bandwidth to a range that avoids such problems. Although you may find a cheap ADC lacks this because they saved the money. Jim |
Colin (478) 2433 posts |
No you get the data in the format sent from the device. |
jim lesurf (2082) 1438 posts |
I’m making some progress with using Dave’s USBAudio calls, but this has thown up something I’d like to clarify. EnumerateResolutions gives me one resolution for my DAC Magic Plus. This is 24 bits. However to play a wave file via Colin’s player that gives me something like SDFS::ARMiniX.$.CD_tracks.wav_in.SACD_Britten/wav96000 2 3 24 USB10 1 1 1 4 24 2 1 ClockID: 41 usb_control: bmRType=0×21 bRequest=0×1 wValue=0×100 wIndex=0×2900 wLength=0×4 buf=0xA7F48 usb_control: bmRType=0xA1 bRequest=0×1 wValue=0×100 wIndex=0×2900 wLength=0×4 buf=0xA7F48 Sample Frequency get: 96000 USB10#nopad;noblock;size768000;samplerate96000;samplesize8;interface1;alternate1;endpoint1: which looks like the USB2.0 method using 4 bytes per value to me. Does that mean that EnumerateResolutions does indeed specify the actual DAC resolution and not the size of the values that have to be sent for a DAC like this? I was hoping that USBAudio calls would tell me the number of bits/bytes per value to be streamed/saved. That in turn raises another matter I’ve not got to testing yet. Hope to sometime tomorrow. I’d thought I could try using the USBAudio calls to tell me what I’d need to save to a ‘file’ using the naming system Colin’s modules / prog uses. But the above implies I’ve either missed something or that isn’t the case. I’ll have another look at your test codes tomorrow, had enough for today, but I thought I’d post this in case you can clarify my dimness! BTW Not previously had much to do with Unicode. So I was surprised to see that the DAC ‘names’ returned have a first byte that gives the length of the unicode string. Convenient. Is that standard? If so, makes life much easier. :-) Jim |
Raik (463) 2061 posts |
@Colin I have a short try on my Pandora. Wow, both IsocPlayer and -Recorder are working fine. Record and Play the mono wav. |
Ronald May (387) 407 posts |
‘No you get the data in the format sent from the device.’ Dave and Jim, thanks for the support regarding filtering. a bit later, maybe. |
Dave Higton (1515) 3526 posts |
Yes. That’s what I have always understood resolution to mean.
To find the subframe size (the number of bytes per sample for one channel), use EnumerateSampleRates. |
Colin (478) 2433 posts |
Ronald. I don’t think you need to double buffer. The DeviceFS buffer is circular so as a block of data is removed by your program the space becomes available for filling by usb. So you have to deal with the data removed before the circular buffer fills again in the background. |
jim lesurf (2082) 1438 posts |
FWIW I’ve written an article or two on this for ‘Archive’ mag that should appear soon. There is also some stuff on the web, which I’ll add to in time. Jim |
jim lesurf (2082) 1438 posts |
Ta! :-) I’d stopped last night before I had reached looking at that swi. Have a go today. Thanks, Jim |
Dave Higton (1515) 3526 posts |
Would it be more useful if EnumerateResolutions returned resolution and subframe size pairs, instead of just resolutions? |
Colin (478) 2433 posts |
I see that you are returning values on an error in your API. This isn’t a good idea because The other point I noticed is that the list of sample frequencies in enumerate sample rates is either a list of samples or a range – following the class 1 audio descriptor model. But class 2 audio allows multiple sample ranges. I think it would be better to just return a list of sample ranges. |
Dave Higton (1515) 3526 posts |
I may be having a dense moment (my mind is full of Windows rubbish right now!), but I don’t understand what you mean. Can you put some detail on what you wrote, or provide an example, please?
Well, at least be able to return a list of ranges in addition to single values, yes. Right now the module only stores one range. When I can raise some enthusiasm, I’ll update it. |
Colin (478) 2433 posts |
if you have
size is unchanged if e != NULL.
Then you need a separate flag to tell the user that the list is a range list or a value list. May as well save the user having to write 2 procedures 1 to cope with ranges and one to cope with discrete values. |
jim lesurf (2082) 1438 posts |
OK, I can now get the DAC to list its details OK using the USBAudio calls. But I’m clearly not understanding what to do to get playout. Initially I tried just “write to a file” using fwrite and using a file with a name following the syntax like USB10#nopad;noblock;size768000;samplerate96000;samplesize8;interface1;alternate1;endpoint1: However such attempts compiled and ran with no complaint, but gave no output. So that’s clearly wrong. I then tried going via USBAudio_OpenOut, etc. But there I get either no audio or the program crashes. e.g. if I use
The I get the program halting after ‘start play’ appears, and when I try to close the GraphTask window the machine stiffs. So this is also wrong. If I try the above with just “USB10” the program runs but gives no output. Sorry about this, I clearly still don’t get it. Can you kindly explain how the above should be changed or got to work? Jim Sorry if anyone read the utter mess that this site made of the above code until I found the magic formula of using pre and code nested. Afraid I find ‘textile’ a right PITA! |
Pages: 1 ... 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 ... 52