USB audio class 2

Go To Last Post
18 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is there a chance AVR USB parts will have the strength to implement USB Audio Class 2? Asynchronous transfer would be particularly interesting. That is, the DAC requests samples from the PC through the USB interface. It can do this based on its own nice clock. Traditional, synchronous, USB audio is the other way around where the DAC is a slave to the dirty PC clock.

Any news, links etc. appreciated.

Thanks,
Borge

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think you need High-Speed USB for that, and 24-bit processing, which no AVR can manage. XMOS chips can handle it, of course:

https://www.xmos.com/products/development-kits/usbaudio2

Leon Heller G1HSM

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

They can, and (in the case of my LUFA library for them) already do -- although you'll need one of the non ATMEGAxxU2 (or AT90USBxx2) parts since you need the large endpoints.

In my LUFA library there is example code for both audio output (via LEDs, PWM or an external DAC) and audio input (via a microphone) at 44KHz, 16 bit stereo.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you sure about that? He seems to be after USB Audio Class 2.0, not audio over USB 2.0.

Leon Heller G1HSM

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My mistake - I thought he was talking about USB Audio 1 over USB 2.0. LUFA is Audio Specification 1.0 only; in fact, I wasn't aware there WAS a 2.0 specification until now. Time for some reading.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's difficult to find details of it, one probably needs to be a member of the USB consortium. The best overview seems to be on the XMOS web site:

http://www.xmos.com/applications/usb-audio

Leon Heller G1HSM

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My work is primarliy as a DAC designer. Plain-vanilla USB audio up to 48ksps / 16 bits is easy with standard chips (PCM2704 et.al.). It's largest problem is that the audio source is the clock master. The DAC needs to be the clock master in order to reduce jitter problems.

I'm aware of the xmos reference design. A friend of mine is picking it to pieces, and I wondered if there was an AVR approach available. Particulary because I'll be expanding my mega16 design to add a USB control interface.

Borge

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One challenge on MCUs tends to be emulating the I2S interface while staying in sync to the 11-13Mhz master clock commonly used.

I've worked on a few audio reference designs etc, and know that I2S can be done on MCUs if that's the first thing designed into them.

Borge

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It will need far more processing power than you will get from an AVR. You will also need a Hi-Speed USB interface.

Leon Heller G1HSM

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's what I feared. I'm looking forward to a single-chip solution for this interface.

Thanks,
Borge

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

C-Media makes one, but it isn't as flexible as the XMOS solution.

Leon Heller G1HSM

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

That's what I feared.

At which point this becomes off topic for AVR(8) forum so moving to GE.

Moderator.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Might one consider - with 'traditional' push-driven audio - using a time-base corrector? Particularly with the cost of ram so low in the quantities you'd need? It was a standard technology for years in professional video recorders...

Basically, for audio you'd have a buffer big enough to cope with the expected jitter, dual ported. The USB side writes data as and when it has some, the DAC clock drives the read side, half a buffer away from the write address.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

With a suitable processor, techniques like that aren't needed.

Here is a nice XMOS doc. on how their chips were used for a USB Audio Class 2 product:

http://www.xmos.com//system/files/cs-hrt-100525.pdf

Leon Heller G1HSM

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

True enough, but there is more to it than just cleaning up jitter. Using the higher sampling frequencies is also interesting.

Borge

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

leon_heller wrote:
It's difficult to find details of it, one probably needs to be a member of the USB consortium.

Detailed specifications can be found here:
http://www.usb.org/developers/de...
under "Audio Devices Rev. 2.0 Spec and Adopters Agreement".
It doesn't seem to require any extra CPU power to implement this.

I²S, and Japanese format (EIAJ, which is not a standard as such) audio data can be generated with SPI, with the former one being a bit more complicated (it requires logical rotation among two consecutive samples). It gets worse when it comes to oversampling DACs, as they need additional clock signal, however non-oversampling DACs are not a problem.

Here's a bit of code for driving the TDA1543A DAC (EIAJ format). (Almost) successfully implemented with LUFA at 16 bit, 48 kHz, stereo.
I've wasted 3 days trying to figure out what is wrong with the audio output, and it turned out to be a problem with EIAJ digital signal format. For 16-bit audio there should be more than 16 bits transmitted with MSb replicated, due to lack of any specifications (or my bad luck while I was looking for it) it was a bit hard to figure it out.
With the approach taken in LUFA one can really say, that large jitter makes music sound bad. By "large" I mean several microseconds, not the 10 ps, which some audiophiles can "hear". Sample output should be done with interrupts, not by polling the OCF0A flag.
DMA for SPI would be very helpful, this little piece of code consumes about 50% CPU running at 16 MHz, mostly waiting for SPI transfer to complete.

	// MOSI (DATA), SCK (BCK) and SS (WS) - outputs
	DDRB = _BV(PB2) | _BV(PB1) | _BV(PB0);
	// enable, master, CLK/2, MSb first, sampling on rising clock edge, data change on falling edge, idle clk = 0
	SPCR = _BV(SPE) | _BV(MSTR);
	SPSR = _BV(SPI2X);

		int16_t  LeftSample_16Bit   = Audio_Device_ReadSample16(&Speaker_Audio_Interface);
		int16_t  RightSample_16Bit  = Audio_Device_ReadSample16(&Speaker_Audio_Interface);

		int16_t sampleshift = LeftSample_16Bit >> 8;
		PORTB |= _BV(PB0);		// WS=1 - left channel
		SPDR = (sampleshift >> 8) & 0xff;	// MSb repeated
		while(!(SPSR & _BV(SPIF))) {};
		SPDR = sampleshift & 0xff;			// MSB
		while(!(SPSR & _BV(SPIF))) {};
		SPDR = LeftSample_16Bit & 0xff;	// LSB
		while(!(SPSR & _BV(SPIF))) {};

		sampleshift = RightSample_16Bit >> 8;
		PORTB &= ~_BV(PB0);		// WS=0 - right channel
		SPDR = (sampleshift >> 8) & 0xff;
		while(!(SPSR & _BV(SPIF))) {};
		SPDR = sampleshift & 0xff;
		while(!(SPSR & _BV(SPIF))) {};
		SPDR = RightSample_16Bit & 0x00ff;
		while(!(SPSR & _BV(SPIF))) {};
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It looks like you are having the same experiences and I do myself, namely that getting I2S etc. to work on an MCU is a major hassle. On all the systems where I have needed this, I have ended up having to code the I2S transfer first and then put all other protocols around it. And with a bit of luck you can actually run an application in there as well...

Every time I talk to people from the big chip vendors, I suggest they make an SPI/I2C to I2S fifo chip. Then the MCU does SPI bursts while interrupts tell it when the fifo is getting low.

I'm in the rather lucky situation where the I2S is consumed by an FPGA. This means that when I own both sides of that cable I can change the protocol layer as I wish, and put a FIFO on the FPGA instead, blasting over, say, 16 samples at a time.

Unfortunately, I'm a complete novice when it comes to USB. I just happen to know that I will need to support asynchronous USB audio it in the end product. Asynchronous means the reference clock for the audio samples is generated at the DAC, not in the host.

The requirement there is for 24-bit stereo audio at 192ksps.

Cheers,
Borge

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

borge.strand wrote:
Unfortunately, I'm a complete novice when it comes to USB. I just happen to know that I will need to support asynchronous USB audio it in the end product. Asynchronous means the reference clock for the audio samples is generated at the DAC, not in the host.

This is not a problem, asynchronous transmission is supported even by USB Audio 1.0 class. However I've seen some people reporting having troubles with asynchronous transfers under Windows. The whole idea is relatively simple and all it requires is an additional IN endpoint (with appropriate descriptor), which sends back an information about actual number of samples played per frame, or something like that.

borge.strand wrote:
The requirement there is for 24-bit stereo audio at 192ksps.

Now, this is impossible. The isochronous endpoint for full-speed device requires only one transfer per frame. The maximum endpoint size is 1023 bytes, however I'm not aware of any AVR MCUs having endpoint larger than 256 bytes.
Frames are transmitted every 1 ms, which gives the maximum rate per endpoint of 256 kB/s, which is too low to meet your requirements (1152 kB/s), even for single channel, unless you go down to 8 bits per sample.
I think, that it could be possible to split the stream between several endpoints (one channel per endpoint), but still it's not enough, because you can use only two endpoints. For two endpoints the most robust configuration is 512 bytes per EP, wich gives 1024 kB/s.

The required rate can be achieved with five endpoints, 256 bytes each (1280 kB/s, the theoretical maximum for isochronous transfer over full-speed bus), but you definitely can not split the stream to 5 endpoints.
In addition to this, all AVR devices have only one (or none) endpoint which is larger than the rest (AFAIK).

On the other hand, high-speed USB gives you possibility not only to send more transactions per microframe (three of them, I think), but also the microframe rate is 8 times higher than for full-speed, so it will easily meet your bandwidth requirements. An AVR32 with full-speed interface maybe?, but these are quite expensive.