Hi
I'm struggling with understanding USB audio. I am using MCUXpresso and I have my own board based on MKL46Z256 . My end goal is to send I2S stream from a digital microphone chip to PC via USB audio.
I tried the USB frdmkl46z_dev_audio_generator_bm project and it works fine. I can hear voice repeating in my Windows PC. It uses 8 bits per sample and sampling frequency of 8Khz and fixed data.
My application involves speech only but in a noisy environment. I like to use 16 bits and 16kHz sampling rate.
My first modification of the example project should have been just to change the sampling frequency, but I am stuck here:
In my usb_device_descriptor.c
0x01U, /* The number of bytes occupied by one audio subframe. Can be 1, 2, 3 or 4. */
0x08, /* The number of effectively used bits from the available bits in an audio subframe.*/
0x01U, /* Indicates how the sampling frequency can be programmed: */
//0x40, 0x1F, 0x00U, /* Sampling frequency 1 in Hz for this isochronous data endpoint. */
0x80, 0x3E, 0x00U, // changed to 16MHz sampling frequency
From various documentation I found about FS USB I think the USB isochronous method checks data every 1 ms so increasing sampling frequency will mean more data generated and bigger buffers needed. If I got it right 8ksps means 8 bytes every 1ms and thus I need 8 byte buffer in the original example. This would now be 16 bytes.
This is why I changed in my usb_device_descriptor.h the following:
//#define FS_INTERRUPT_IN_PACKET_SIZE (8)
#define FS_INTERRUPT_IN_PACKET_SIZE (16)
and
//#define FS_ISO_IN_ENDP_PACKET_SIZE (8)
#define FS_ISO_IN_ENDP_PACKET_SIZE (16)
I have tried various combinations but all experiments results in no sound on PC side and I don't know why.
I found it very hard to find any information about this topic and would be very happy for any comment. I have looked at a lot of pdf's about usb audio but it does not help me with my example.
I guess the basic question now is:" what else do I need to change when doubling the sampling frequency in the generator example?"
Best regards,
Baldur
Solved! Go to Solution.
Hello @baldurthorgilss,
Asking the applications teams, this issue looks like is a problem with windows, if you want these changes to apply you need to uninstall the driver.
0x80, 0x3E, 0x00U, // changed to 16kHz sampling frequency BÞ
#define FS_ISO_IN_ENDP_PACKET_SIZE (32)
These changes should be enough.
Best Regards,
Alexis Andalon
Hello @baldurthorgilss,
The interrupt size shouldn't change, if you want to check an example that uses a 16-bits and other frequency I will suggest checking the example for the K66 found in the SDK.
Best Regards,
Alexis Andalon
Hi Alexis_A
And thank you for answering my question. I did not notice your reply until now.
I built and downloaded the k66 sdk, but I could not find any generator example in it. I looked at the speaker example, but that was quite different.
My status is now that I can generate sound with the default settings: 8kHz sampling frequency and 8 bit resolution (pcm8). I can also generate sound with 16kHz sampling and 8 bit if I increase the buffer size
//0x40, 0x1F, 0x00U, /* Sampling frequency 1 in Hz for this isochronous data endpoint. */
0x80, 0x3E, 0x00U, // changed to 16kHz sampling frequency BÞ
and
//#define FS_ISO_IN_ENDP_PACKET_SIZE (8)
#define FS_ISO_IN_ENDP_PACKET_SIZE (16)
Next step is to go to 16 bits. Just to not increase the buffer more for them moment, I went back to 8kHz sampling, changed from pcm8 to pcm, change from 1 byte to 2 bytes and from 8 bytes to 16:
//0x02U, 0x00U, /* PCM8 */
0x01U, 0x00U, /* PCM BÞ */
and
//0x01U, /* The number of bytes occupied by one audio subframe. Can be 1, 2, 3 or 4. */
0x02U, /* The number of bytes occupied by one audio subframe. Can be 1, 2, 3 or 4. BÞ: 2 bytes*/
//0x08, /* The number of effectively used bits from the available bits in an audio subframe.*/
0x10, /* The number of effectively used bits from the available bits in an audio subframe. BÞ: 16 bits*/
0x01U, /* Indicates how the sampling frequency can be programmed: */
0x40, 0x1F, 0x00U, /* Sampling frequency 1 in Hz for this isochronous data endpoint. */
//0x80, 0x3E, 0x00U, // changed to 16kHz sampling frequency BÞ
The microphone seems to get active in windows, but no sound is hearable.
I added error messages to the start og USB_DeviceCallback and USB_DeviceAudioCallback functions in auio_generator.c
usb_echo("B: in USB_DeviceAudioCallback");//BÞ
and got this output:
USB device audio generator Pi
B: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceAudioCallbackB: in USB_DeviceAudioCallbackB: in USB_DeviceAudioCallbackB: in USB_DeviceAudioCallbackB: in USB_DeviceAudioCallbackB: in USB_DeviceCallbackB: in USB_DeviceAudioCallbackB: in USB_DeviceAudioCallbackSet Cur Volume : fe0f
B: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallbackB: in USB_DeviceCallback
(then everything is silent)
It seems like the two functions are called several times before the system gives up.
I also had changed the buffer to int:
//extern uint8_t s_wavBuff[];
extern uint16_t s_wavBuff[]; //BÞ
and expect the size FS_ISO_IN_ENDP_PACKET_SIZE in USB_DeviceAudioSend to refer to bytes rather than samples. Is that correct?
I have studied several sample setups on the net and it seems to me like these are the only things to think of. Am I correct? What else might I have to change?
I would be very happy for any hint regarding solving this problem.
Best regards,
Baldur
Hello @baldurthorgilss,
Asking the applications teams, this issue looks like is a problem with windows, if you want these changes to apply you need to uninstall the driver.
0x80, 0x3E, 0x00U, // changed to 16kHz sampling frequency BÞ
#define FS_ISO_IN_ENDP_PACKET_SIZE (32)
These changes should be enough.
Best Regards,
Alexis Andalon
Hi Alexis
Turns out that you had the solution
When I managed to delete the windows audio driver properly (it appeared in two groups in device manager) it turned out that my code was working all the time.
My conclusion is:
that logic analyzers might not reflect the actual situation (the way a root hub would understand the signals) as they flip the state by a single level but USB is defined upper and lower levels.
Wireshark turned out just as good a tool in my case. It reflects the actual understanding of the USB packages.
Also deleting a driver is not trivial, it might appear in more than one group under device manager and in this case it must be deleted in all groups.
Going from 8kHz sampling frequency to 16kHz and from 8 bit to 16 involves:
changing sampling frequency
changing endpoint buffer size
changing audio format (PCM8 to PCM)
changing bits per sample
changing effective number of bits per sample
Thanks for the help,
Baldur
Hi Alexis
I'm still struggling with this problem. At the moment I have doopts that my logic analyzer is interpreting the signals the way the PC does so I have involved Wireshark software. Here is the package sequence for the original version of the generator:
53 2.981347 host 3.11.0 USB 36 GET DESCRIPTOR Request DEVICE
54 2.981576 3.11.0 host USB 46 GET DESCRIPTOR Response DEVICE
55 2.981622 host 3.11.0 USB 36 GET DESCRIPTOR Request CONFIGURATION
56 2.981755 3.11.0 host USB 37 GET DESCRIPTOR Response CONFIGURATION
57 2.981785 host 3.11.0 USB 36 GET DESCRIPTOR Request CONFIGURATION
58 2.982033 3.11.0 host USB 146 GET DESCRIPTOR Response CONFIGURATION
59 2.986505 host 3.11.0 USB 36 SET CONFIGURATION Request
60 2.987241 3.11.0 host USB 28 SET CONFIGURATION Response
61 2.987553 host 3.11.0 USB 27 Unknown type 7f
62 2.987563 3.11.0 host USB 27 Unknown type 7f
63 2.987589 host 3.11.0 USB 27 Unknown type 7f
64 2.987599 3.11.0 host USB 27 Unknown type 7f
65 2.990824 host 3.11.0 USB 36 GET DESCRIPTOR Request STRING
66 2.991067 3.11.0 host USB 32 GET DESCRIPTOR Response STRING
67 2.991106 host 3.11.0 USB 36 GET DESCRIPTOR Request STRING
68 2.991257 3.11.0 host USB 58 GET DESCRIPTOR Response STRING
69 3.008799 host 3.11.0 USB 36 GET DESCRIPTOR Request STRING
70 3.009070 3.11.0 host USB 32 GET DESCRIPTOR Response STRING
71 3.009107 host 3.11.0 USB 36 GET DESCRIPTOR Request STRING
72 3.009263 3.11.0 host USB 58 GET DESCRIPTOR Response STRING
73 3.009777 host 3.11.0 USB 36 URB_CONTROL in
74 3.009934 3.11.0 host USB 29 URB_CONTROL in
75 3.009976 host 3.11.0 USB 36 URB_CONTROL in
76 3.010136 3.11.0 host USB 30 URB_CONTROL in
77 3.010164 host 3.11.0 USB 36 URB_CONTROL in
78 3.010357 3.11.0 host USB 30 URB_CONTROL in
79 3.010384 host 3.11.0 USB 36 URB_CONTROL in
80 3.010542 3.11.0 host USB 30 URB_CONTROL in
81 3.010580 host 3.11.0 USB 36 URB_CONTROL in
82 3.010733 3.11.0 host USB 30 URB_CONTROL in
83 3.010806 host 3.11.0 USB 36 SET INTERFACE Request
84 3.011046 3.11.0 host USB 28 SET INTERFACE Response
85 3.146705 host 3.11.0 USB 37 URB_CONTROL out
86 3.147025 3.11.0 host USB 28 URB_CONTROL out
87 3.159268 host 3.11.0 USB 38 URB_CONTROL out
88 3.159578 3.11.0 host USB 28 URB_CONTROL out
89 3.502870 host 3.11.0 USB 36 SET INTERFACE Request
90 3.503298 3.11.0 host USB 28 SET INTERFACE Response
103 3.517515 3.11.2 host USB 239 URB_ISOCHRONOUS in
105 3.527517 3.11.2 host USB 239 URB_ISOCHRONOUS in
107 3.537521 3.11.2 host USB 239 URB_ISOCHRONOUS in
109 3.547514 3.11.2 host USB 239 URB_ISOCHRONOUS in
(continues sending data)
When I try my own version I get the following
19 3.888895 host 3.29.0 USB 36 GET DESCRIPTOR Request DEVICE
20 3.889139 3.29.0 host USB 46 GET DESCRIPTOR Response DEVICE
21 3.889200 host 3.29.0 USB 36 GET DESCRIPTOR Request CONFIGURATION
22 3.889425 3.29.0 host USB 37 GET DESCRIPTOR Response CONFIGURATION
23 3.889542 host 3.29.0 USB 36 GET DESCRIPTOR Request CONFIGURATION
24 3.889864 3.29.0 host USB 146 GET DESCRIPTOR Response CONFIGURATION
25 3.894468 host 3.29.0 USB 36 SET CONFIGURATION Request
26 3.895379 3.29.0 host USB 28 SET CONFIGURATION Response
27 3.895561 host 3.29.0 USB 27 Unknown type 7f
28 3.895569 3.29.0 host USB 27 Unknown type 7f
29 3.895584 host 3.29.0 USB 27 Unknown type 7f
30 3.895588 3.29.0 host USB 27 Unknown type 7f
31 3.898641 host 3.29.0 USB 36 GET DESCRIPTOR Request STRING
32 3.898915 3.29.0 host USB 32 GET DESCRIPTOR Response STRING
33 3.898967 host 3.29.0 USB 36 GET DESCRIPTOR Request STRING
34 3.899208 3.29.0 host USB 54 GET DESCRIPTOR Response STRING
35 3.913608 host 3.29.0 USB 36 GET DESCRIPTOR Request STRING
36 3.913895 3.29.0 host USB 32 GET DESCRIPTOR Response STRING
37 3.913904 host 3.29.0 USB 36 GET DESCRIPTOR Request STRING
38 3.914125 3.29.0 host USB 54 GET DESCRIPTOR Response STRING
39 3.914244 host 3.29.0 USB 36 URB_CONTROL in
40 3.914412 3.29.0 host USB 29 URB_CONTROL in
41 3.914420 host 3.29.0 USB 36 URB_CONTROL in
42 3.914609 3.29.0 host USB 30 URB_CONTROL in
43 3.914614 host 3.29.0 USB 36 URB_CONTROL in
44 3.914783 3.29.0 host USB 30 URB_CONTROL in
45 3.914790 host 3.29.0 USB 36 URB_CONTROL in
46 3.914957 3.29.0 host USB 30 URB_CONTROL in
47 3.914962 host 3.29.0 USB 36 URB_CONTROL in
48 3.915135 3.29.0 host USB 30 URB_CONTROL in
49 3.915152 host 3.29.0 USB 36 SET INTERFACE Request
50 3.915381 3.29.0 host USB 28 SET INTERFACE Response
51 4.031398 host 3.29.0 USB 37 URB_CONTROL out
52 4.031765 3.29.0 host USB 28 URB_CONTROL out
53 4.043707 host 3.29.0 USB 38 URB_CONTROL out
54 4.044069 3.29.0 host USB 28 URB_CONTROL out
That is, the second "SET INTERFACE Request" seen in the un-modified version (line 89 in the first list) never comes. This must be a hint in my debugging. I would be happy for any advice regarding where/what to look for regarding this stop in communication.
Best regards
Baldur
In my quest to understand the problem I got me a USB analyzer. The USB protocol is of cause extensive, but I start slowly. One common thing is the frame rate package sent every 1 ms. Checking my mouse I got an image like the following
When I run the generator project on my NXP board unchanged from the example I get this every 1 ms (otherwise same setup on logic analyzer):
Almost every frame package has error!
In spite of this large amount of errors, I can still hear the generator sound in my PC.
This is the original example, I have not changed it. Why has my frame (and other) packages error (it can easily be seen e.g. in the D+ signal how strange it looks)? I have tested a number of other devices, no other device behave like this.
My ultimate goal is to understand why my 16-bit, 16kHz signal is not working as streaming audio, but that error drowns in these errors. I need to fix this first.
I would be happy for any comment.
Best regards,
Baldur