-
Notifications
You must be signed in to change notification settings - Fork 47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
USB audio discussion #97
Comments
pico-sdk was preventing me to use USB for anything else than stdio when 'pico_enable_stdio_usb' was enabled.
I don't think USB volume is necessary. You control the volume from PC.
On RP2040? I would say no. Even now, with 15625, it's almost at max speed/capabilities (+the additional memory needed).
Yeah, I also noticed some underruns on Linux. I also noticed some RP2040 lockups. Working on it now. Might also improve the underruns. |
I haven't had a chance to test this thoroughly, but it does seem to work very well and audio quality is great! Haven't had a chance to try this on windows yet though. I found that the computer volume control worked as expected, so would propose that the volume control in the menu should only effect the headphones output and that the USB output should be controlled by PC. I have implemented cat control, but I haven't managed to get this working alongside usb audio yet. I think this should be possible by creating a composite usb device with CDC and audio endpoints. I did read somewhere that it might be possible to get usb stdio working alongside other USB stuff too, but not really sure about this. If necessary we could just use CDC API directly instead of stdio. I did experience a software lockup when changing mode, I'm not sure of the cause though. I did notice that the tud_usb_task seems to be called from a timer interrupt, is this safe? I'm also not sure whether the tinyUSB code can be used safely across both cores (probably not a problem at the moment, but cat control more naturally sits on core 0 alongside the ui), I guess we could work around this by using the ring buffer to safely transfer data between cores, allowing the USB callbacks to always be run on the same core. From an architectural point of view, I have an aspiration to keep rx_dsp.cpp code fairly generic so that it could be used in other receivers with minimal changes. I think it should be possible to keep it quite generic by moving the USB code up a level to rx.cpp which is intended to be hardware specific and knows about things like adcs and PWM (and now USB). I think it would make sense to add USB data to the ring buffer after each block is processed in the run function. (My inclination would be to also move the interpolation, volume control and PWM scaling to this level too, this way rx_dsp does the same processing on each block regardless of where it is destined.) I'm really excited about these latest changes, it something I have been working towards for a while👍 |
+1 on the lockups too - forgot to mention that. :( I suspect they're random - I've had it lockup when I picked up the boards, when just sitting there streaming lofi classic hits to the laptop and when using the UI. |
Yeah, so probably not that safe, but I don't think we have other options. From my tests usb_task needs to be run very often and very "uniformly" in time. I tried "spreading" the calls throughout
Yeah, makes sense. I just wanted to make it working ASAP. |
Pushed #98 with some adjustments. Haven't seen a lockup with those changes. |
Concur - 90+ mins with no lockup here. I've had a close look at the audacity data of the dropouts now - not sure if these hint at a cause. Another issue I found is at volume 9 - peaks that hit the ceiling go through it and wrap around to -ve value. |
I spotted a *2 in the code when capturing the usb audio, I wonder if that might be the cause of the second issue? |
The AGC setpoint is at the half way point, e.g. 6dB below full scale, this was to allow headroom for overshoot when the AGC is slow to react to a change in power level. I then apply soft clipping to any signals that exceed this level and hard clip at full scale. With an additional 2*gain I would expect the AGC to scale signals to approximately full scale with a volume of 9, and overshooting signals would cause overflow. This seems to fit quite closely with your observations. |
How do the dropouts show in audacity? In my audacity it doesn't show dropouts (I mean it coalesces the dropouts). I think that here we might want to send full buffer every time, even if it's zeros. |
With the latest code I've verified that occasionally the TinyUSB callback "runs out" of samples. We either produce the samples too slow, or USB stack requests them too fast. I think this in unavoidable. We can only minimize the effect. |
It this where the audio feedback comes in? There are some interesting comments about this here: |
Oh, right, so we need to measure the actual samplerate we have. |
The fact that we're changing CPU clock probably won't make things easier. |
I haven't fully understood it yet, but it looks like there are mechanisms
to cope with the inevitable mismatch in sample frequency between the two
ends. I think the ADC is running from the 48Mhz USB clock, so our sample
rate should remain constant even when the sys_clk frequency changes.
…On Mon, 30 Sep 2024, 17:30 mryndzionek, ***@***.***> wrote:
The fact that we're changing CPU clock probably won't make things easier.
—
Reply to this email directly, view it on GitHub
<#97 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAFPFX3ODWFDQ6DXONMJGL3ZZF4BBAVCNFSM6AAAAABPC5DXRCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOBTGY3DGOBVGI>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Yes, so I was thinking about our "producing" side - the ADCs. We essentially need to track the actual ADC rate and communicate it to the USB stack. |
With the latest code however, when I remove the periodic suspend, I'm not seeing the ring buffer being emptied out. |
Can you make the USB audio send the I/Q signal to the computer? |
No, it currently sends the demodulated and processed audio. Essentially the same signal as on headphones. For IQ a different USB class would be needed. Most likely some ethernet class, like RNDIS etc. |
+1 on the IQ over USB idea. Could it send the IQ data as stereo audio ? Looking at rx_dsp::process_block we could just short circuit most of the for(uint16_t idx=0; idx<adc_block_size/decimation_rate; idx++) {} loop and stuff the IQ samples into the usb buffer.
|
Yeah, so the main issue is to have an interface easily recognizable by all of the SDR apps. |
IQ over stereo audio is a common way to send that signal to sdr programs, at least in my experience. |
Okay, fair enough. I mostly have experience with "pure" USB SDRs. |
FYI When SDR++ outputs the IF of the VFO as audio. Left channel is I branch, right is Q branch. |
The weatherfax results look very impressive! I guess that supplying IQ data would allow compatibility with sound-card based SDR applications like quisk and the like so would probably be a nice to have. I think that outputting demodulated audio is quite important for things like fldigi, wsjtx, freedv, qsstv etc. It also opens the door for an even more minimal "headless" radio that can be connected to a smart-phone or laptop and wouldn't really need its own UI. I'm really very excited about getting this working. I think we probably do need to think about adding CDC support either using stdio, or via the tinyUSB API. Aside from adding a cat capability, we also need some way to upload memory contents via USB. My plan was to extend the ts-480 protocol to add additional commands to read a d write channels to flash. We could then remove the memory upload option from the config menu. |
I made some more weather fax captures today. There are no jumps, but there is a slant corresponding to one sample missing every 6s. I think this is acceptable. The comments in TinyUSB mentioned acceptable accuracy as less than 1sample per second. |
Are the USB recording level and (un)mute controls plumbed in? |
Seems to be working on Linux. |
I wonder if linux is just doing it in software. Windows "audio mixer" does that. Just had a look thru the usb code:
Looks like we need some callbacks for changes of volume and mute. I'll do it |
Unfortunately I don't have a windows 7 machine that I can use to check, but I have tried it with windows 10 and confirmed it worked OK. The USB audio uses a UAC2 device class, it might be necessary to install some third party UAC2 drivers to get it working. |
Ok, I will try find UAC2 driver. |
@mryndzionek excellent work on #96 ! :)
USB stdio: is there an underlying problem blocking this? Is it time I learnt to debug without printf? :)
Volume: should we add a second volume setting ? "Headphone\nVolume" "USB\nVolume" ?
Sample Rate: Can we resample to 22.050 or 44.1k ?
Windows has tiny dropouts: 33ms of audio followed by 1ms of silence (measured approximately with Audacity at 44.1k).
I wonder if this is related to the oddball sample rate.
The text was updated successfully, but these errors were encountered: