DSD playing with volume control

Sub forums for various specialist XMOS applications. e.g. USB audio, motor control and robotics.
User avatar
williamc1014
Junior Member
Posts: 4
Joined: Thu Apr 03, 2014 10:54 am

DSD playing with volume control

Post by williamc1014 »

Hi,

I know that when playing the DSD, the host volume output should be set to the maximum to ensure each DSD bit correctly delivering to USB audio device.
But the question is, if I want to do some volume control on the USB audio device side when playing DSD, how can I do that?
I noted that all control feature descriptors in descriptors.h are disabled so that the USB host (PC) is not able to send the volume control to the USB audio device; so if I want to do some volume control when playing DSD by setting DAC volume register, I need to enable this control feature at first, how can I do this?
And then, where and how can I to add some code when the command is sent and do the DAC register setting for volume control?

Thank you.


User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

This is an interesting question..

In the reference design, volume control is handled in *decouple (one side of the buffer) before samples are sent off to audio to get put on the ports to the DAC. Bascially it does a scaling using a LMUL instruction.
*as long as mixer is disabled.

However, as you correctly say, DSD bits can't be messed with in the normal way. There are two reasons for this - Firstly DoP scaling will trash the DoP marker so it won't be recognised as DoP anymore, and secondly any DSD (native or DoP) can't be scaled using a MUL instruction as can LPCM.

So doing DSD in DSP is tricky - you could probably add random bits of 50% density to the stream as a sort of attenuator, but no idea if this would sound OK.

To add control of the DAC's volume registers is a good idea - that's a sensible way to control the gain.
However, I2C configuration of the DAC currently happens when I2S (or DSD!) streaming has stopped.. basically in between sample rate or stream format changes. This way the same core can handle it (cuts down on device usage).

To access the I2C master function whilst audio was streaming would need either:
1. A dedicated core to handle I2C
2. Some sort of time sliced I2C function crammed into audio (I2C slaves don't mind the edges beign delayed, as long as they are in the right order)
3. Or possibly I2C inside decouple (which gets interrupted anyhow)

You wouldn't need the above if you could tolerate a gap in streaming on volume change, but that would probably not sound nice (clicks/pops on vol change).

For the first two options, you'd likely need to modify the channel protocol to pass down volume information to the audio core, which is not currently done.

Finally, you'd need to modify the descriptors to re-enable volume.

So certainly not a trivial modification, but sounds doable.. although I may have missed something.
User avatar
Ross
XCore Expert
Posts: 966
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

Are you talking about the Windows controls disappearing when the device is used in DSD "native" mode via ASIO?
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

Having thought about this a bit more, it may be possible to implement gain control in the DAC over I2C from EP0 OK without interrupting audio. In audiorequests.xc, you can insert code to initiate the I2C control of the DAC volume registers. I2C master will block, but that *should* be OK as EP0 should NAK until the request is complete. You will need to use module I2C shared to avoid any conflict from multiple cores accessing the same resource. You will also need to chose whether the behaviour is for DSD only or PCM too...