Page 1 of 1

Linux bit depth crash - fixed

Posted: Thu Feb 08, 2018 10:15 am
by LumiCore
Hi All,

This is for anyone who experienced USB audio dropouts on Linux based hosts. I could not find any references to this issue online, forgive me if I post something here that is old news.

Our design is based on the sw_usb_audio-[sw]_6.15.2rc1 release. The issue we encountered is that if you play music on Linux based hosts and go from a track with a certain bit depth to another one, the system would hang. A short white noise like sound is to be heard, after which the host looses connection with the USB stack.

So for example switching from a 44.1k/16b to a 48k/24b is no problem, but if the sample rate stays equal; (for example 44.1/16b to 44.1/24b) you will get this bug.
(Assuming you have your alternate defines set to "STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS 16")
Test platform in our case is a Roon Ready app (v1.1.27) running on a Antipodes (v2.5) server, the USB output to our Kii Control. In hindsight we have also experienced this bug with other Linux based streamers, but never have been able to connect the dots.

I've hooked up the XTAG to our Kii Control to see what happened during a crash. It turns out that there was a readout of an array (outAudioBuff) which was out of bounds. The read pointer (g_aud_from_host_rdptr) was way beyond anything valid.
If I am correct, it is caused by the fact that "aud_data_remaining_to_device" does not get reset when there is a "SET_STREAM_FORMAT_OUT" action. So just add "SET_SHARED_GLOBAL(aud_data_remaining_to_device, 0);" to this part of the code:

Code: Select all

else if(tmp == SET_STREAM_FORMAT_OUT)
{
   unsigned dataFormat, sampRes;
   unsigned dsdMode = DSD_MODE_OFF;

   /* Change in OUT channel count - note we expect this on every stream start event */
   DISABLE_INTERRUPTS();
   SET_SHARED_GLOBAL(g_freqChange_flag, 0);
   GET_SHARED_GLOBAL(g_numUsbChan_Out, g_formatChange_NumChans);
   GET_SHARED_GLOBAL(g_curSubSlot_Out, g_formatChange_SubSlot);
   GET_SHARED_GLOBAL(dataFormat, g_formatChange_DataFormat);
   GET_SHARED_GLOBAL(sampRes, g_formatChange_SampRes);

   /* Reset OUT buffer state */
   SET_SHARED_GLOBAL(g_aud_from_host_rdptr, aud_from_host_fifo_start);
   SET_SHARED_GLOBAL(g_aud_from_host_wrptr, aud_from_host_fifo_start);
   SET_SHARED_GLOBAL(aud_data_remaining_to_device, 0);
   unpackState = 0;

   outUnderflow = 1;
   if(outOverflow)
   {
      /* If we were previously in overflow we wont have marked as ready */
      XUD_SetReady_OutPtr(aud_from_host_usb_ep, aud_from_host_fifo_start+4);
      outOverflow = 0;
    }

   #ifdef NATIVE_DSD
   if(dataFormat == UAC_FORMAT_TYPEI_RAW_DATA)
   {
      dsdMode = DSD_MODE_NATIVE;
   }
   #endif
                
   /* Wait for the audio code to request samples and respond with command */
   inuint(c_mix_out);
   outct(c_mix_out, SET_STREAM_FORMAT_OUT);
   outuint(c_mix_out, dsdMode);
   outuint(c_mix_out, sampRes);

   /* Wait for handshake back */
   chkct(c_mix_out, XS1_CT_END);
    asm volatile("outct res[%0],%1"::"r"(buffer_aud_ctl_chan),"r"(XS1_CT_END));

   SET_SHARED_GLOBAL(g_freqChange, 0);
   ENABLE_INTERRUPTS();
}
Maybe I'm wrong here, but it fixes the problem on our end. If anyone else can reproduce this in the field, that would be great!

Another thing i've noticed is that in the start of decouple thread a buffer limit seems to be invalid:

Code: Select all

aud_from_host_fifo_end = aud_from_host_fifo_start + BUFF_SIZE_OUT*4;
Because the buffer size is set to:

Code: Select all

unsigned outAudioBuff[BUFF_SIZE_OUT + (MAX_USB_AUD_PACKET_SIZE>>2) + 4];
Which in my case (max sample rate is 768k) results in a buffer size of 1053, where the limit is now set to 3168.
Maybe someone at XMOS can shed some light on this?

Cheers,
Bart van der Laan

Re: Linux bit depth crash - fixed

Posted: Mon Feb 19, 2018 3:21 pm
by infiniteimprobability
Hi Bart,
thanks for reporting this and appreciate the level of detail provided. The buffer sizes have been calculated and tested (pretty rigorously in house and by hundreds of customers) but few designers have pushed it to such high rates and array bounds checking is disabled at runtime for performance reasons. We are not immune to latent bugs that have not yet been exposed so it is certainly possible that issues may creep in at high (and less well tested) rates.

Your fix looks completely sensible - I cannot see why we shouldn't reset aud_data_remaining_to_device always just as we do in the SET_SAMPLE_FREQ case. I'll file a bug against the latest version.

Thanks again for reporting this.

Re: Linux bit depth crash - fixed

Posted: Thu Apr 25, 2019 11:38 am
by nixz
Hi,

This thread have over a year now and you didn't release this fix in your SDK yet. Similarly DSD playback still have no fix for eg. XU208 devices and doesn't work without extra patches.
In fact you din't release any new USB Audio SDK since 2016... The only change I see for a 2 years is new fancy website...

It means XMOS obsolete/abandon USB Audio 2.0 area? Shall we urgently switch something that has any support?

best regards
Mikołaj

Re: Linux bit depth crash - fixed

Posted: Fri Apr 26, 2019 10:21 am
by nixz
Hi,

This thread have over a year now and you didn't included this fix in your SDK yet. Similarly DSD playback still have no fix for xCORE-200 devices (eg. XU208) and doesn't work without extra patches.
In fact you didn't release any new USB Audio SDK since 2016... :-(

It means XMOS obsolete/abandon USB Audio 2.0 area? Shall we urgently switch something that has any support?

best regards
Mikołaj

Re: Linux bit depth crash - fixed

Posted: Mon Apr 29, 2019 9:44 am
by johned
Hi Mikołaj,
Thank you very much for your message.
I can confirm that we are currently looking to release an update to the USB Audio firmware so keep your eye open for announcements.
I can also confirm that we have no plans to obsolete/abandon the USB Audio area and have many exciting plans for the future.
Best regards,
John

Re: Linux bit depth crash - fixed

Posted: Thu Sep 12, 2019 11:22 am
by pasnew
Hello John,

Do you have any update about the new audio software ?

Best regards,

Re: Linux bit depth crash - fixed

Posted: Thu Sep 12, 2019 11:32 am
by johned
No updates yet but they will be here, when released : https://www.xmos.com/software/usb-audio

J

Re: Linux bit depth crash - fixed

Posted: Sat Jun 05, 2021 8:41 pm
by paprika27
It is now a few years later and I seem to be running into the same issue, still. I am on a new XCore-200 XU216, attached to linux 3.18.25.

It last happened by changing songs in mpd using alsa from flac 44.1/16 to mp3 44.1/24 but doesn't seem to be reproducible directly after restarting XMOS.
To me, this indicates that it is still an overflowing buffer.

This is not a bug I as the consumer am willing to live with. Please advise urgently on how exactly to fix this issue.