After 1 year of time-to-time exprerimenting I successfuly have made a very nice hardware volume control inside DAC instead of digital volume control inside XMOS by default. So, yes, guy, it's possible, though not too easy. No, source code sharing makes no sense, as a reference open-source software is not ready for that and need to be rewritten completely from scratches.
Anyway. Some helpful information. Starting point is:
1. Disable digital volume control inside XMOS to exclude double volume changing:
//updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl);
2. Getting volume from FU_USBOUT event:
if ((sp.wValue & 0xff) == 1) new_volume = ((signed char)buffer[1])*-2;
where ((sp.wValue & 0xff) == 1) is a magical condition when OS volume is changed exactly.
3. Then use new_volume as absolute volume for you DAC through I2C bus.
I use more advanced technics, as I need to show the current volume on screen too, not only change it.
More advanced problem I faced is in synchronizing my hardware volume knob (encoder) with OS volume slider. So vice versa, from device to host. We see a hint in the source code:
/* Direction: Device-to-host */
If someone knows how to send this kind of event from any part of your source code to AudioClassRequests_2 event handler, please let me know. Any small hint would be very welcome.
Volume Control?
-
- XCore Addict
- Posts: 179
- Joined: Mon Apr 16, 2018 9:14 am
-
- Experienced Member
- Posts: 76
- Joined: Mon Sep 24, 2018 9:56 pm
Maxim,
I developed a product years ago that used HID to update the volume control so that they were both at the same level. When someone changed the rotary knob instead of updating the volume by I2C, I instead sent an HID that the volume had increased or decreased and when I received the call back from the HOST I made the I2C change.
I was informed by Alison @ Apple that a better way to do this was through Status Interrupt calls to the HOST. If you are an apple developer, look under TN2274 USB Audio on the Mac. Now of course I have no idea how Windows handles this as they seem to be pretty far behind the curve on these kind of full prospective of USB specifications.
My way worked fine and it's not creating a bunch of traffic and was easy to implement considering all changes to the volume would come from the HOST. You would also display changes to volume when receiving the indicator from the HOST.
Thanks,
Gordon
I developed a product years ago that used HID to update the volume control so that they were both at the same level. When someone changed the rotary knob instead of updating the volume by I2C, I instead sent an HID that the volume had increased or decreased and when I received the call back from the HOST I made the I2C change.
I was informed by Alison @ Apple that a better way to do this was through Status Interrupt calls to the HOST. If you are an apple developer, look under TN2274 USB Audio on the Mac. Now of course I have no idea how Windows handles this as they seem to be pretty far behind the curve on these kind of full prospective of USB specifications.
My way worked fine and it's not creating a bunch of traffic and was easy to implement considering all changes to the volume would come from the HOST. You would also display changes to volume when receiving the indicator from the HOST.
Thanks,
Gordon
Wavelength Audio, ltd.
-
- XCore Addict
- Posts: 179
- Joined: Mon Apr 16, 2018 9:14 am
Thank you, Gordon! That's very nice from you. Yes, you are right. HID is the 100% answer here.
For me it isn't an ideal solution, as my product could work in stand-alone mode just with SPDIF input as a sound source, not only USB. So, it's better for me to find an alternative way. To do not lose ability for customers of direct volume control by I2C bus too. So it's interesting if anyone has even tried and got any success in sending device to host events in particular. I cannot understand yet how to set in queue to drop a message to USB. USB part of firmware looks like a pure nightmare for me, despite the fact I am very skilled in the rest parts. Not my cup of tea. :)
For me it isn't an ideal solution, as my product could work in stand-alone mode just with SPDIF input as a sound source, not only USB. So, it's better for me to find an alternative way. To do not lose ability for customers of direct volume control by I2C bus too. So it's interesting if anyone has even tried and got any success in sending device to host events in particular. I cannot understand yet how to set in queue to drop a message to USB. USB part of firmware looks like a pure nightmare for me, despite the fact I am very skilled in the rest parts. Not my cup of tea. :)
-
- Experienced Member
- Posts: 76
- Joined: Mon Sep 24, 2018 9:56 pm
Maxim,
Probably the easiest way to do this is if you are attached and selected as SPDIF, then use the I2C from the rotary. If you are connected and active with USB then use HID no matter what the selected input is. If you are selected SPDIF and USB is connected but not active then use I2C and when USB becomes active it will ask for the current setting and provide that to the HOST then you are all set.
I think a bigger problem with sending an Interrupt over endpoint 0 to the host for a feature update is that Windows probably does not support this. They don't support a lot of the Endpoint 0 calls, including user interrupt and so forth that are included in macOS and Linux.
Believe me.... living he!! right now on Windows because of some of the things Windows doesn't support.
If you have a USB analyzer it should be pretty easy to figure out what to do.
Thanks,
Gordon
Probably the easiest way to do this is if you are attached and selected as SPDIF, then use the I2C from the rotary. If you are connected and active with USB then use HID no matter what the selected input is. If you are selected SPDIF and USB is connected but not active then use I2C and when USB becomes active it will ask for the current setting and provide that to the HOST then you are all set.
I think a bigger problem with sending an Interrupt over endpoint 0 to the host for a feature update is that Windows probably does not support this. They don't support a lot of the Endpoint 0 calls, including user interrupt and so forth that are included in macOS and Linux.
Believe me.... living he!! right now on Windows because of some of the things Windows doesn't support.
If you have a USB analyzer it should be pretty easy to figure out what to do.
Thanks,
Gordon
Wavelength Audio, ltd.
-
- XCore Addict
- Posts: 179
- Joined: Mon Apr 16, 2018 9:14 am
Gordon, thank you. I googled your name and watched your Youtube interview. Very interesting. Is that true that you are the person who invented or took part in invention of USB asynchronous mode? If so, THANK YOU million times from all music industry! Thank you once again for all your advices. It's priceless. It's a big honour.
It's interesting though why we could see /* Direction: Device-to-host */ subsection in firmware. What is it for? Could we use it somehow for common goods?
"else" subsection mean if we got FU_VOLUME_CONTROL event but command is not equal to USB_BM_REQTYPE_DIRECTION_H2D
I see audiorequest.xc file "Implements relevant requests from the USB Audio 2.0 Specification".
I would like to try sending some mystery "else" event (USB_BM_REQTYPE_DIRECTION_D2H seems to be) and see what Windows could do in this case. I also cannot get how to send this request to USB from other part of code, i.e. from my own code. It's really looks like a mess.
It's interesting though why we could see /* Direction: Device-to-host */ subsection in firmware. What is it for? Could we use it somehow for common goods?
Code: Select all
else /* Direction: Device-to-host */
{
if(unitID == FU_USBOUT)
{
if ((sp.wValue & 0xff) <= NUM_USB_CHAN_OUT)
{
buffer[0] = volsOut[ sp.wValue&0xff ];
buffer[1] = volsOut[ sp.wValue&0xff ] >> 8;
return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 2, sp.wLength);
}
}
else
{
if ((sp.wValue & 0xff) <= NUM_USB_CHAN_IN)
{
buffer[0] = volsIn[ sp.wValue&0xff ];
buffer[1] = volsIn[ sp.wValue&0xff ] >> 8;
return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 2, sp.wLength);
}
}
}
I see audiorequest.xc file "Implements relevant requests from the USB Audio 2.0 Specification".
I would like to try sending some mystery "else" event (USB_BM_REQTYPE_DIRECTION_D2H seems to be) and see what Windows could do in this case. I also cannot get how to send this request to USB from other part of code, i.e. from my own code. It's really looks like a mess.
-
- Experienced Member
- Posts: 76
- Joined: Mon Sep 24, 2018 9:56 pm
Maxim,
No I didn't invent async, I did make it very popular. So here is what really happened. A large company made a USB DAC headphone amplifier (I have one of these) and Texas Instruments made them a USB capable DSP for this. The design originally was for adaptive but on some Windows machines the USB-DSP chip could not change the MCLK enough to keep synced with the host. The company had a already produced I guess a boat load of these. So TI and this other company went to USB.org and said we need a new protocol set that is async and requires feedback. It got adopted and I took it from there back in 2003 and moved it into audio.
~~~
That code looks like it would effect the feature unit on the host. It would be pretty easy to give it a try. Again you would want to test this on Windows and Linux (if you support it). If you have a Windows driver for Win7 & Win8 then trying it on them also would be beneficial.
Thanks,
Gordon
No I didn't invent async, I did make it very popular. So here is what really happened. A large company made a USB DAC headphone amplifier (I have one of these) and Texas Instruments made them a USB capable DSP for this. The design originally was for adaptive but on some Windows machines the USB-DSP chip could not change the MCLK enough to keep synced with the host. The company had a already produced I guess a boat load of these. So TI and this other company went to USB.org and said we need a new protocol set that is async and requires feedback. It got adopted and I took it from there back in 2003 and moved it into audio.
~~~
That code looks like it would effect the feature unit on the host. It would be pretty easy to give it a try. Again you would want to test this on Windows and Linux (if you support it). If you have a Windows driver for Win7 & Win8 then trying it on them also would be beneficial.
Thanks,
Gordon
Wavelength Audio, ltd.
-
- XCore Addict
- Posts: 179
- Joined: Mon Apr 16, 2018 9:14 am
Gordon, thank you for so detailed history excursion! Fantastic! Very interesting. Though some audiophilic people still claim "USB is not capable to provide any decent sound quality, unlike SPDIF".
Yes, I support any UAC2.0 OS, as these days it's very simple to do. http://xcore.com/viewtopic.php?p=34745#p34745 Extremely helpful topic with the latest descriptor bugfix. Everything works fine.
Hope, some day I could make device-to-host volume works. Seems to be I need to pass USB_BM_REQTYPE_DIRECTION_D2H to some pipeline to initiate OS volume change.
Yes, I support any UAC2.0 OS, as these days it's very simple to do. http://xcore.com/viewtopic.php?p=34745#p34745 Extremely helpful topic with the latest descriptor bugfix. Everything works fine.
Hope, some day I could make device-to-host volume works. Seems to be I need to pass USB_BM_REQTYPE_DIRECTION_D2H to some pipeline to initiate OS volume change.
Last edited by MaximLiadov on Thu Feb 27, 2020 6:50 am, edited 1 time in total.
-
- Experienced Member
- Posts: 76
- Joined: Mon Sep 24, 2018 9:56 pm
Maxim,
SPDIF sucks as you always have to fix the jitter. It's so much easier to just do it right the first time. It does take a lot of work and analysis. I have a full lab setup with Tektronix USB analyzers and a couple of different protocol analyzers to help me out with this stuff.
I still have some boards with SPDIF BNC input at 44.1 only with really low jitter VCXO controlled by a real elaborate setup that runs the SPDIF receiver in slave mode and then reclocks with the same VCXO. I get good results with that but not as good as putting the oscillator at the dac chip then reclock everything from the XMOS with the output MCLK from the dac chip. I also rewrite the async routines to better the flow of data.
Thanks,
Gordon
SPDIF sucks as you always have to fix the jitter. It's so much easier to just do it right the first time. It does take a lot of work and analysis. I have a full lab setup with Tektronix USB analyzers and a couple of different protocol analyzers to help me out with this stuff.
I still have some boards with SPDIF BNC input at 44.1 only with really low jitter VCXO controlled by a real elaborate setup that runs the SPDIF receiver in slave mode and then reclocks with the same VCXO. I get good results with that but not as good as putting the oscillator at the dac chip then reclock everything from the XMOS with the output MCLK from the dac chip. I also rewrite the async routines to better the flow of data.
Thanks,
Gordon
Wavelength Audio, ltd.
-
- XCore Addict
- Posts: 179
- Joined: Mon Apr 16, 2018 9:14 am
Dear Gordon,
That's not the only crazy thing I heard. Just try to do not fall down. I heard some "musical" USB cables with golden connectors affect on sound quality dramatically (sound stage is more wide, trebles more crystal), and even software media player (especially Aurvana for $70) with standard API and different OSes even being bit accurate sending some unknown fluids through a standard USB bus that affect much on sound quality. Modern science just cannot explain this, because engineering is helpless when it comes to music stuff. I am facing with this everyday. It's interesting what do you think, as you are closely standing behind physical part of USB interface and have proper equipment. Is that possible somehow? Did you see any difference on hardware level with "better" USB cables or with OS changing? Bit perfection really sucks and means nothing? Audiophilic approach rules? By your personal opinion.
That's not the only crazy thing I heard. Just try to do not fall down. I heard some "musical" USB cables with golden connectors affect on sound quality dramatically (sound stage is more wide, trebles more crystal), and even software media player (especially Aurvana for $70) with standard API and different OSes even being bit accurate sending some unknown fluids through a standard USB bus that affect much on sound quality. Modern science just cannot explain this, because engineering is helpless when it comes to music stuff. I am facing with this everyday. It's interesting what do you think, as you are closely standing behind physical part of USB interface and have proper equipment. Is that possible somehow? Did you see any difference on hardware level with "better" USB cables or with OS changing? Bit perfection really sucks and means nothing? Audiophilic approach rules? By your personal opinion.
-
- Experienced Member
- Posts: 76
- Joined: Mon Sep 24, 2018 9:56 pm
Maxim,
It's not the gold it's the configuration of the cables. With Full Speed you could basically make a cable out of zip cord. But the problem with High Speed is the changing of direction and the geometry of the cable can make all the differences in the world. I have a Tektronix compliance system and USB analyzer with HS differential probe that I can insert into my testing. I have tested probably 80 USB cables, some over $1K and they suck. The trick with HS USB is that the data lines cannot be shielded, but the problem with VBUS/GND interfering with the signal is then a problem. This has led to design of dual cables with the VBUS/GND in one and data pair in another. Some of these are then gathered together to look like one cable and others are not.
I can see errors on the TEK screen with HS running say a sine wave into a DAC at 1Khz. Changing the sample rate from 44.1K -> 384K you will see and increase of errors as the packets get larger.
Or if the cable has a lot of hangover (when the signal transmitted stays active and the receiver has to switch to transmit back, say the Feed Back packet IN request) then the HOST will error that packet received and that causes pops and clicks as the Async protocol will then fail.
Software: I did research for 4 years trying to figure out why the software effects the sound. I setup the following system:
BootCamp macOS MacBook Pro and Windows <--USB with TEK Analyzer-->DAC with breakout I2S
I would test with a flat file WAV is easier than AIFF at 24/88.2 and compare the data as seen on the TEK and the I2S in a perfect setup. Meaning the data was the same from File, USB and I2S without errors.
I did find a few applications that were not bit perfect, but in general they all were the same. BUT!!! None of them sounded the same. I repeated this test at the RMAF show in Denver (without all the testing equipment, but same system) and the results were the same.
So why do they sound different. I had a problem with my Mac in that one core was spinning. So I bought iStat Monitor plug in and found a device driver was just eating one of the cores at 100%. I removed it and all was good. I then tested a DAC I designed for another company running the suite of software through it, Bit Perfect, iTunes, Audirvana, Decibel, Roon, Pure Music.... and I noticed on iStat Monitor the amount of usage each program had. The correlation between the usage and sound was identical to their performance. Audirvana was the best, then Roon/Decibel and so forth. The switching noise associated with the processor usage was invading the stereo through both the mains and over cables and even from the monitors.
Everything makes a difference!
Thanks,
Gordon
It's not the gold it's the configuration of the cables. With Full Speed you could basically make a cable out of zip cord. But the problem with High Speed is the changing of direction and the geometry of the cable can make all the differences in the world. I have a Tektronix compliance system and USB analyzer with HS differential probe that I can insert into my testing. I have tested probably 80 USB cables, some over $1K and they suck. The trick with HS USB is that the data lines cannot be shielded, but the problem with VBUS/GND interfering with the signal is then a problem. This has led to design of dual cables with the VBUS/GND in one and data pair in another. Some of these are then gathered together to look like one cable and others are not.
I can see errors on the TEK screen with HS running say a sine wave into a DAC at 1Khz. Changing the sample rate from 44.1K -> 384K you will see and increase of errors as the packets get larger.
Or if the cable has a lot of hangover (when the signal transmitted stays active and the receiver has to switch to transmit back, say the Feed Back packet IN request) then the HOST will error that packet received and that causes pops and clicks as the Async protocol will then fail.
Software: I did research for 4 years trying to figure out why the software effects the sound. I setup the following system:
BootCamp macOS MacBook Pro and Windows <--USB with TEK Analyzer-->DAC with breakout I2S
I would test with a flat file WAV is easier than AIFF at 24/88.2 and compare the data as seen on the TEK and the I2S in a perfect setup. Meaning the data was the same from File, USB and I2S without errors.
I did find a few applications that were not bit perfect, but in general they all were the same. BUT!!! None of them sounded the same. I repeated this test at the RMAF show in Denver (without all the testing equipment, but same system) and the results were the same.
So why do they sound different. I had a problem with my Mac in that one core was spinning. So I bought iStat Monitor plug in and found a device driver was just eating one of the cores at 100%. I removed it and all was good. I then tested a DAC I designed for another company running the suite of software through it, Bit Perfect, iTunes, Audirvana, Decibel, Roon, Pure Music.... and I noticed on iStat Monitor the amount of usage each program had. The correlation between the usage and sound was identical to their performance. Audirvana was the best, then Roon/Decibel and so forth. The switching noise associated with the processor usage was invading the stereo through both the mains and over cables and even from the monitors.
Everything makes a difference!
Thanks,
Gordon
Wavelength Audio, ltd.