24bit USB Sample Rate Support - windows
My question is quite similar to this question: Link, but i am not allowed to comment.
I'm implementing a PIC32 as a soundcard, and i now have a working USB audio stream, supporting 16-bit at 32kHz and 48kHz sample rates. I now want to change the bit depth to 24-bit, so i change my USB Descriptors to:
bSubFrameSize = 0x03, // 3 bytes per sample
bBitResolution = 0x18, // 24-bit resolution
When i do this, he bit resolution is changed as it is suppose to, but in the properties of the microphone, the dropdown menu where i could change the sampling frequency is grey.
I havn't changed anything in the endpoint descriptors, where both 32kHz and 48kHz still is supported.
My USB topology has 1 Audio control interface with a couple of Units, and 2 Audio Streaming Interfaces, for streaming IN and OUT.
Marc O answered his question by saying that something in his Input Terminal, i have tried changing wChannelConfig but i doesn't work.
I have tried Uninstalling and Installing the device drivers, but doesn't work.
What more do i need to change in the descriptors, to be able to select the sampling Frequency?
Thanks :)
Edit: Added Descriptor code and descriped progress
When i changed the no of channels to 2, and made the wChannelConfig = 0x03 -> right + Left Front, i saw the the field on he picture change to: "2 channel, 24 bit, 48000 Hz (Studio Quality)", but it still didn't make the dropdown menu white, and i couldn't change sample rate.
Below i've added the Audio funcion descriptors:
//CD
0x09, // Size : 9 Bytes
USB_DESCRIPTOR_CONFIGURATION, // Configuration Descriptor (0x02)
0x10, // Total length in bytes of data returned
0x01, // 2. Byte af Total Length
0x05, // Number of Interfaces: 5 3 Audio + 2 Comm
0x01, // Configuration Value, Value to use as an argument to select this configuration
0x00, // iConfiguration, Index of String Descriptor describing this configuration
_DEFAULT | _SELF, // bmAttributes, selfpowered
0xFA, // Maximum Power : 250 mA
// ######## Audio Control Interface Descriptor
//ID - Interface Descriptor
0x09, // Size : 9 Bytes
USB_DESCRIPTOR_INTERFACE, // Interface Descriptor (0x04)
0x00, // Number of Interface: Interface nr 0
0x00, // Value used to select alternative setting
0x00, // Number of Endpoints used for this interface, 0
AUDIO_DEVICE, // Class Code (Assigned by USB Org), AUDIO
AUDIOCONTROL, // Subclass Code (Assigned by USB Org), AUDIOCONTROL
0x00, // Protocol Code (Assigned by USB Org)
0x00, // Index of String Descriptor Describing this interface
// HEADER
0x0A, // Size : 10 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
HEADER, // HEADER descriptor subtype
0x00,0x01, // Audio Device compliant to the USB Audio specification version 1.00
0x46,0x00, // 64 bytes - Total number of bytes returned for the class-specific AudioControl interface descriptor. // Includes the combined length of this descriptor header and all Unit and Terminal descriptors.
0x02, // bInCollection -> Number of streaming interfaces = 2
0x01, // en form for index: "AudioStreaming interface 1 belongs to this AudioControl interface."
0x02, // beskriver nok streaming interface 2's index
// INPUT_TERMINAL ID = 1 USB Stream
0x0B, // size : 12 bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
INPUT_TERMINAL, // INPUT_TERMINAL - Descriptor subtype = 2
INPUT_TER_USB, // ID of this Input Terminal. // Constant uniquely identifying the Terminal within the audio function.
USB_STREAMING, // wTerminalType -> 0x0101 = USB streamming
0x00, // bAssocTerminal -> 0x00 = No association.
0x02, // bNrChannels -> 0x01 two channel.
0x03, // wChannelConfig -> 0x03 = right + Left Front
0x00, // iChannelNames -> 0x00 = Unused.
0x00, // iTerminal -> 0x00 = Unused.
// INPUT_TERMINAL ID = 4 MICROPHONE
0x0B, // size : 12 bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
INPUT_TERMINAL, // INPUT_TERMINAL - Descriptor subtype
INPUT_TER_MIC, // bTerminalID -> ID of this Input Terminal = 4
MICROPHONE, // wTerminalType -> 0x0201 = Microphone
0x00, // bAssocTerminal -> 0x00 = No association.
0x02, // bNrChannels -> 0x01 one channel.
0x03, // wChannelConfig -> 0x03 = right + Left Front
0x00, // iChannelNames -> 0x00 = Unused.
0x00, // iTerminal -> 0x00 = Unused.
// OUTPUT_TERMINAL ID = 3 SPEAKER
0x09, // size : 9 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
OUTPUT_TERMINAL, // OUTPUT_TERMINAL - Descriptor subtype
OUTPUT_TER_SPEAK, // bTerminalID -> ID of this Output Terminal = 3
SPEAKER, // wTerminalType -> 0x0301 = Speaker
0x00, // bAssocTerminal -> 0x00 = Unused
FEATURE_OUT, // bSourceID -> 0x02 = From Input Terminal ID 2 = USB stream
0x00, // iTerminal -> 0x00 = Unused.
// OUTPUT_TERMINAL ID = 6 USB Stream
0x09, // Size : 9 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
OUTPUT_TERMINAL, // OUTPUT_TERMINAL - Descriptor subtype
OUTPUT_TER_USB, // bTerminalID -> ID of this Output Terminal = 6
USB_STREAMING, // wTerminalType -> 0x0101 = USB streaming
0x00, // bAssocTerminal -> 0x00 = Unused
FEATURE_IN, // bSourceID -> 0x05 = Feature Unit that sets IN features SOURCE = 5 (Feature_IN)
0x00, // iTerminal -> 0x00 = Unused.
// FEATURE_UNIT ID = 2
0x0A, // Size : 10 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
FEATURE_UNIT, // FEATURE_UNIT - Descriptor subtype
FEATURE_OUT, // bUnitID -> ID 2
INPUT_TER_USB, // bSourceID -> 0x01 = connected to Input Terminal 1 SOURCE = 1 (Input USB)
0x01, // bControlSize -> 0x01 = 1 Byte
0x03, // bmaControls(n = channel nr) -> 0x03 = Mute + volume
0x03, // bmaControls(n = channel nr) -> 0x03 = Mute + volume
0x00, // bmaControls(n = channel nr) -> 0x00 = no master control
0x00, // iFeature -> string Descriptor Unused
// FEATURE_UNIT ID = 5
0x0A, // Size : 9 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
FEATURE_UNIT, // FEATURE_UNIT - Descriptor subtype
FEATURE_IN, // bUnitID -> ID 5
INPUT_TER_MIC, // bSourceID -> 0x04 = Connected to Unit ID 4 SOURCE = 4 (Input Mic.)
0x01, // bControlSize -> 0x01 = 1 Byte
0x03, // bmaControls(1) -> 0b0000011 = Mute + Volume no. of Channels +1 = no. of bmaControls
0x03, // bmaControls(2) -> 0b0000011 = Mute + Volume no. of Channels +1 = no. of bmaControls
0x00, // bmaControls(3) -> 0x00 = No controls supperted no. of Channels +1 = no. of bmaControls
0x00, // iFeature -> string Descriptor Unused
// ######## AUDIO STREAM INTERFACE 1 OUT SPEAKER
//ID // Alternate Setting 0 - 0 endpoint
0x09, // Size : 9 Bytes
USB_DESCRIPTOR_INTERFACE, // Interface Descriptor (0x04)
0x01, // bInterfaceNumber -> 0x01 Interface ID = 1
0x00, // bAlternateSetting -> 0x00 = index of this interface's alternate setting
0x00, // bNumEndpoints -> 0x00 = 0 Endpoints to this interface
AUDIO_DEVICE, // bInterfaceClass -> 0x01 = Audio Interface
AUDIOSTREAMING, // bInterfaceSubclass -> 0x02 = AUDIO_STREAMING
0x00, // bInterfaceProtocol -> 0x00 = Unused
0x00, // iInterface -> 0x00 = Unused
//ID // Alternate Setting 1 - 1 endpoint
0x09, // Size : 9 Bytes
USB_DESCRIPTOR_INTERFACE, // Interface Descriptor (0x04)
0x01, // bInterfaceNumber -> 0x01 Interface ID = 1
0x01, // bAlternateSetting -> 0x01 = index of this interface's alternate setting
0x01, // bNumEndpoints -> 0x01 = 1 Endpoints to this interface
0x01, // bInterfaceClass -> 0x01 = Audio Interface
0x02, // bInterfaceSubclass -> 0x02 = AUDIO_STREAMING
0x00, // bInterfaceProtocol -> 0x00 = Unused
0x00, // iInterface -> 0x00 = Unused
// ASID GENERAL
0x07, // Size : 7 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
AS_GENERAL, // bDescriptorSubtype -> 0x01 = GENERAL subtype
0x01, // bTerminalLink -> 0x01 = The Terminal ID of the Terminal to which the endpoint of this interface is connected.
0x01, // bDelay -> 0x01 = Delay (delta) introduced by the data path (see Section 3.4, ?Inter Channel Synchronization? - in Audio Devices). Expressed in number of frames.
0x01,0x00, // wFormatTag -> 0x0001 = PCM
// ASID FORMAT_TYPE
0x0E, // Size : 14 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
FORMAT_TYPE, // bDescriptorSubtype -> 0x02 = FORMAT_TYPE
0x01, // bFormatType -> 0x01 = FORMAT_TYPE_I -> ref: A.1.1 Audio Data Format Type I Codes -> Audio Data Format Dok
0x02, // bNrChannels -> 0x02 = Two channels
BYTES_PR_SAMPLE, // bSubFrameSize -> 0x03 = 3 bytes pr audio subframe
BIT_RESOLUTION, // bBitResolution -> 0x18 = 24 bit pr sample
0x02, // bSamFreqType -> 0x02 = 2 sample frequencies supported
0x00,0x7D,0x00, // tSamFreq -> 0x7D00 = 32000 Hz
0x80,0xBB,0x00, // tSamFreq -> 0xBB80 = 48000 Hz
//ED ENDPOINT OUT
0x09, // Size : 9 Bytes
USB_DESCRIPTOR_ENDPOINT, // 0x05 -> ENDPOINT Descriptor Type
0x01, // bEndpointAddress -> 0x01 = adress 1, OUT, -> ref 9.6.6 Endpoint -> usb_20 Dok
0x09, // bmAttributes -> 0b00001001 -> Bits 0-1 = 01 = Isochronous , Bits 2-3 = 10 = Adaptive
AUDIO_MAX_SAMPLES * sizeof ( AUDIO_PLAY_SAMPLE ), AUDIO_MAX_SAMPLES * sizeof ( AUDIO_PLAY_SAMPLE )>>8,
0x01, // bInterval -> 0x01 = 1 millisecond
0x00, // Unused
0x00, // Unused
//AS ENDPOINT
0x07, // Size : 7 Bytes
CS_ENDPOINT, // CS_ENDPOINT
EP_GENERAL, // bDescriptorSubtype -> 0x01 = GENERAL
SAMPLING_FREQ_CONTROL, // bmAttributes -> 0b00000001 = Bit 1 = 1 => Sample Freq Control is supported by this endpoint
0x00, // bLockDelayUnits -> 0x00 = Indicates the units used for the wLockDelay field: 0 = Undefined
0x00,0x00, // the time it takes this endpoint to reliably lock its internal clock recovery circuitry.
// ######## AUDIO STREAM INTERFACE 2 IN MICROPHONE
//ID // Alternate Setting 0 - 0 endpoint
0x09, // Size : 9 Bytes
USB_DESCRIPTOR_INTERFACE, // Interface Descriptor (0x04)
0x02, // bInterfaceNumber -> 0x02 Interface ID = 2
0x00, // bAlternateSetting -> 0x00 = Value used to select this alternate setting for the interface identified in the prior field
0x00, // bNumEndpoints -> 0x00 = 0 -> Number of endpoints used by this interface
AUDIO_DEVICE, // bInterfaceClass -> 0x01 = 1 = AUDIO
AUDIOSTREAMING, // bInterfaceSubClass -> 0x02 = AUDIO_STREAMING
0x00, // bInterfaceProtocol -> 0x00 = Unused
0x00, // iInterface -> 0x00 = Unused -> Index of string descriptor.
//ID // Alternate Setting 1 - 1 endpoint
0x09, // Size : 9 Bytes
USB_DESCRIPTOR_INTERFACE, // Interface Descriptor (0x04)
0x02, // bInterfaceNumber -> 0x02 Interface ID = 2
0x01, // bAlternateSetting -> 0x01 = Value used to select this alternate setting for the interface identified in the prior field
0x01, // bNumEndpoints -> 0x01 = 1 -> Number of endpoints used by this interface
0x01, // bInterfaceClass -> 0x01 = 1 = AUDIO
0x02, // bInterfaceSubClass -> 0x02 = AUDIO_STREAMING
0x00, // bInterfaceProtocol -> 0x00 = Unused
0x00, // iInterface -> 0x00 = Unused -> Index of string descriptor.
// ASID GENERAL
0x07, // Size : 7 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
AS_GENERAL, // GENERAL Descriptor
0x06, // bTerminalLink -> 0x06 = The Terminal ID of the Terminal to which the endpoint of this interface is connected. = 6
0x01, // bDelay -> 0x01 = Delay (delta) introduced by the data path (see Section 3.4, ?Inter Channel Synchronization? - in Audio Devices). Expressed in number of frames.
0x01,0x00, // wFormatTag -> 0x0001 = PCM
// ASID FORMAT_TYPE
0x0E, // Size : 14 Bytes
CS_INTERFACE, // CS_INTERFACE Descriptor Type
FORMAT_TYPE, // bDescriptorSubtype -> 0x02 = FORMAT_TYPE
0x01, // bFormatType -> 0x01 = FORMAT_TYPE_I -> ref: A.1.1 Audio Data Format Type I Codes -> Audio Data Format Dok
0x02, // bNrChannels -> 0x02 = Two channels
BYTES_PR_SAMPLE, // bSubFrameSize -> 0x03 = 3 bytes pr audio subframe
BIT_RESOLUTION, // bBitResolution -> 0x18 = 24 bit pr sample
0x02, // bSamFreqType -> 0x02 = 2 sample frequencies supported
0x00,0x7D,0x00, // tSamFreq -> 0x7D00 = 32000 Hz
0x80,0xBB,0x00, // tSamFreq -> 0xBB80 = 48000 Hz
//ED ENDPOINT IN
0x09, // Size : 9 Bytes
USB_DESCRIPTOR_ENDPOINT, // 0x05 -> ENDPOINT Descriptor Type
0x82, // bEndpointAddress -> 0x82 = adress 2, IN, -> ref 9.6.6 Endpoint -> usb_20 Dok
0x05, // bmAttributes -> 0b00000101 -> Bits 0-1 = 01 = Isochronous , Bits 2-3 = 01 = Asynchronous
AUDIO_MAX_SAMPLES * sizeof ( AUDIO_PLAY_SAMPLE ), AUDIO_MAX_SAMPLES * sizeof ( AUDIO_PLAY_SAMPLE )>>8,
0x01, // bInterval -> 0x01 = 1 millisecond
0x00, // unused
0x00, // unused
//AS ENDPOINT
0x07, // Size : 7 Bytes
CS_ENDPOINT, // bDescriptorType -> 0x25 = CS_ENDPOINT
EP_GENERAL, // bDescriptorSubtype -> 0x01 = GENERAL
SAMPLING_FREQ_CONTROL, // bmAttributes -> 0b00000001 = Bit 1 = 1 => Sample Freq Control is supported by this endpoint
0x00, // bLockDelayUnits -> 0x00 = Indicates the units used for the wLockDelay field: 0 = Undefined
0x00,0x00, // the time it takes this endpoint to reliably lock its internal clock recovery circuitry.
This post is quite old but my reply maybe helpful to others facing the same difficulty.
I noticed that windows does not make changes to the installed drivers when the interface changes. You must manually uninstall the windows driver for your device and let windows reinstall it either on USB re-connection or reset of the device.
Related
Audio frame sample type in PCM?
So I'm taking CMSampleBufferRef buffers with audio content. AudioStreamBasicDescription is as follows { mSampleRate: 44100.000000 mFormatID: 'lpcm' mFormatFlags: 0xe mBytesPerPacket: 4 mFramesPerPacket: 1 mBytesPerFrame: 4 mChannelsPerFrame: 2 mBitsPerChannel: 16 } Apparently a it's an interleaved video with 2 bytes per channel = sample size. What is the encoding of this sample size? Is that a (short) int? Is a frame consisting of 2 shorts? Or one int? or one float? How do I know this? I guess it's 32bpp interleaved audio, correct?
A value of 0xe for mFormatFlags is 0b1110 which equates to: kAudioFormatFlagIsBigEndian = (1U << 1), // 0x2 kAudioFormatFlagIsSignedInteger = (1U << 2), // 0x4 kAudioFormatFlagIsPacked = (1U << 3), // 0x8 So a frame consists of two interleaved big-endian int16_t samples.
Read Data ST25DV
I made my own board with an STM32L031K6 and an ST25DV64K NFC chip. I am using the android App "NFC Tools". I can read the UID of the NFC chip with the app, so the antenna is correctly tuned. I can also read the UID with the microcontroleur via the I2C bus. When I write into the eeprom memory of the NFC chip with the microcontroleur, I can't read the data with the NFC app. It says that the tag is empty. I think I am missing a configuration, but I can't find which one. Here is my code, executed once: uint8_t ToWrite = 15; uint8_t Password[17] = {0}; //Default password is"00000000" Password[8] = 0x09; //Validation Code // ST25DV_Address_E21 0x57 << 1; // Device select code= 0b1010111 ; E2 = 1 Password_Address = 0x900 HAL_I2C_Mem_Write(&hi2c1, ST25DV_Address_E21, Password_Address, 2, Password, 17, 0xFFF); HAL_Delay(200); //Read the UID HAL_I2C_Mem_Read(&hi2c1, ST25DV_Address_E21, 0x18, 2, UID_Read, 8, 0xFFF); // This line works, UID displayed in the app and in the debugger are the same HAL_Delay(500); //Write some data in the eepprom memory (first address: 0x00) for(int i = 0; i< 250; i++) { ToWrite++; HAL_I2C_Mem_Write(&hi2c1,ST25DV_Address_E21, i, 2, &ToWrite, 1, 0xFF); }
When you are writing the data in the EEPROM from address/block 0, you are simply overwriting the capability container values with all zeros. The correct way to do is initialize your tag, then write the data from block 4 and onwards. The CC values look something like this: 0xE1, /* (block 0) */ 0x40, /* (block 1) */ 0x40, /* (block 2) */ 0x05 /* (block 3) */ Followed by other key header values depending on the NDEF message type. Here I am illustrating for NDEF TEXT: 0x03, /*(block 4) NDEF message type (block 4) */ 0x0D, /*(block 5) NDEF message length (blobk 5) eg, 13 byte message starting from here */ 0xD1, /*(block 6) NDEF Record header: MB = 1, ME = 1, CF = 0, SR = 1, IL = 0, TNF = 001 > 0xD1 */ 0x01, /*(block 7) Type length */ 0x09, /*(block 8) Payload length = 9 (from language code) */ 0x54, /*(block 9) Msg Type = Text */ 0x02, /*(block 10) Language code size */ 0x65, /*(block 11) Language = English, 'e', */ 0x6E, /*(block 12) 'n', */ 'A', /*(block 13+)Payload data */ 'B', 'C', 'D', 'E', 'F' A good reading resource to understand the NDEF payload format is here. Hope this helps!
GoLang bitwise calculation
I have a buffer : buffer := bytes.NewBuffer([]byte{ 0x85, 0x02, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x41, 0x42, 0x43, }) I am trying to return the int value of buffer[8:24] I get [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] Not sure how to shift such a large section. of the byte. new to this. Any help would be great. my initial approach was requestid := (uint64(buffer.Bytes()[8]&0xff)<<24 + uint64(buffer.Bytes()[9]&0xff)<<16 + uint64(buffer.Bytes()[10]&0xff)<<8 + uint64(buffer.Bytes()[11]&0xff.....))) but this got tedious, and I know there has to be an easier way.
You have to do the manual bit shifting and OR'ing, but your code can be cleaned up by removing all those buffer.Bytes() calls. You also do not need the &0xff parts. What n&0xff does, is clear out all bits outside of the 0-255 range. Since each value in the buffer is already a byte (0-255), these operations do nothing at all. If we want to do 22 & 255, we get the following: Hexadecimal | Decimal | Binary --------------|-------------|---------------------- x 0x16 | 22 | 00010110 y 0xff | 255 | 11111111 --------------|-------------|---------------------- AND (&) 0x16 | 22 | 00010110 = x As you can see, the operation has no effect at all. Replace x with any 8-bit value and you will see the same result. The outcome of x & 0xff is always x. Additionally, when you assign to the requestId, you start by shifting by 24 bits. This tells me you are reading a 32-bit integer. Why then do you continue reading values beyond 32 bits and converting it all to a 64 bit integer? If you are reading a 64-bit int in Big Endian, try this: data := buf.Bytes()[8:] requestid := uint64(data[0])<<56 | uint64(data[1])<<48 | uint64(data[2])<<40 | uint64(data[3])<<32 | uint64(data[4])<<24 | uint64(data[5])<<16 | uint64(data[6])<<8 | uint64(data[7]) If you are reading a 64-bit int in Little Endian, try this: data := buf.Bytes()[8:] requestid := uint64(data[7])<<56 | uint64(data[6])<<48 | uint64(data[5])<<40 | uint64(data[4])<<32 | uint64(data[3])<<24 | uint64(data[2])<<16 | uint64(data[1])<<8 | uint64(data[0]) If you are reading a 32-bit int in Big Endian, try this: data := buf.Bytes()[8:] requestid := uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3]) If you are reading a 32-bit int in Little Endian, try this: data := buf.Bytes()[8:] requestid := uint32(data[3])<<24 | uint32(data[2])<<16 | uint32(data[1])<<8 | uint32(data[0]) binary package Alternatively, you can use the encoding/binary package: var value uint64 err := binary.Read(buf, binary.LittleEndian, &value) ....
Is [0x02, 0x03, 0x00] valid data?
I am trying to write a program that returns valid data according to a message protocol within a byte[] array. I have: STX: 0x02 ETX: 0X03 DLE: 0x10 //Delimiter Valid data is when the byte[] array contains STX, ETX, data and a correctly calculated LRC, for example: byte[] validMsg1 = {0x02, // STX 0x10,0x2,0xA,0x10,0x10,0x7,0x8, // Data 2 A 10 7 8 0x03, // ETX 0x2^0xA^0x10^0x7^0x8^0x03}; // LRC calculated from the data (with the DLE removed) plus the ETX Invalid data example: byte[] invalidMsg1 = {0x02, // STX 0x10,0x2,0xA, // Data 2 A 0x03, // ETX 0x2^0xA^0x10^0x7^0x8^0x03, 0x02, //STX 0x05,0x44}; The byte might also contain random values around the valid data: byte[] validMsgWithRandomData1 = {0x32,0x32,0x32, //Random data 0x02, // STX 0x31,0x32,0x10,0x02,0x33, // Data 31 32 02 33 0x03, // ETX 0x31^0x32^0x02^0x33^0x03,// LRC calculated from the data (with the DLE removed) plus the ETX 0x2,0x3,0x00,0x02 //Random data }; My problems is that when I use the message with random data in and have 0x2,0x3,0x00,0x02 it breaks because it sees 0x02 and 0x03 as the STX and ETX and then it calculates LRC which results in 0x03 which results in this being returned: 0x2,0x3,0x00 with the last 0x03 seens as the LRC. Question is this valid data: byte[] data = { 0x02, // STX 0x03, // ETX 0x00, // LRC }; I am supposed to return the most recent valid data which is that but there is better data within this which is: byte[] validData = { 0x02, // STX 0x31,0x32,0x10,0x02,0x33, // Data 31 32 02 33 0x03, // ETX 0x31^0x32^0x02^0x33^0x03,// LRC calculated from the data (with the DLE removed) plus the ETX };
Where can I find a list of Mac virtual key codes?
I'm using CGEventCreateKeyboardEvent and need to know what CGKeyCode values to use. Specifically, I am after the key code for the Command key. The docs give examples for other keys: z is 6, shift is 56. There must be a list of Mac virtual keycodes somewhere?
Below is a list of the common key codes for quick reference, taken from Events.h. If you need to use these keycodes in an application, you should include the Carbon framework: Objective-C: #include <Carbon/Carbon.h> Swift: import Carbon.HIToolbox You can then use the kVK_ANSI_A constants directly. WARNING The key constants reference physical keys on the keyboard. Their output changes if the typist is using a different keyboard layout. The letters in the constants correspond only to the U.S. QWERTY keyboard layout. For example, the left ring-finger key on the homerow: QWERTY keyboard layout > s > kVK_ANSI_S > "s" Dvorak keyboard layout > o > kVK_ANSI_S > "o" Strategies for layout-agnostic conversion of keycode to string, and vice versa, are discussed here: How to convert ASCII character to CGKeyCode? From Events.h: /* * Summary: * Virtual keycodes * * Discussion: * These constants are the virtual keycodes defined originally in * Inside Mac Volume V, pg. V-191. They identify physical keys on a * keyboard. Those constants with "ANSI" in the name are labeled * according to the key position on an ANSI-standard US keyboard. * For example, kVK_ANSI_A indicates the virtual keycode for the key * with the letter 'A' in the US keyboard layout. Other keyboard * layouts may have the 'A' key label on a different physical key; * in this case, pressing 'A' will generate a different virtual * keycode. */ enum { kVK_ANSI_A = 0x00, kVK_ANSI_S = 0x01, kVK_ANSI_D = 0x02, kVK_ANSI_F = 0x03, kVK_ANSI_H = 0x04, kVK_ANSI_G = 0x05, kVK_ANSI_Z = 0x06, kVK_ANSI_X = 0x07, kVK_ANSI_C = 0x08, kVK_ANSI_V = 0x09, kVK_ANSI_B = 0x0B, kVK_ANSI_Q = 0x0C, kVK_ANSI_W = 0x0D, kVK_ANSI_E = 0x0E, kVK_ANSI_R = 0x0F, kVK_ANSI_Y = 0x10, kVK_ANSI_T = 0x11, kVK_ANSI_1 = 0x12, kVK_ANSI_2 = 0x13, kVK_ANSI_3 = 0x14, kVK_ANSI_4 = 0x15, kVK_ANSI_6 = 0x16, kVK_ANSI_5 = 0x17, kVK_ANSI_Equal = 0x18, kVK_ANSI_9 = 0x19, kVK_ANSI_7 = 0x1A, kVK_ANSI_Minus = 0x1B, kVK_ANSI_8 = 0x1C, kVK_ANSI_0 = 0x1D, kVK_ANSI_RightBracket = 0x1E, kVK_ANSI_O = 0x1F, kVK_ANSI_U = 0x20, kVK_ANSI_LeftBracket = 0x21, kVK_ANSI_I = 0x22, kVK_ANSI_P = 0x23, kVK_ANSI_L = 0x25, kVK_ANSI_J = 0x26, kVK_ANSI_Quote = 0x27, kVK_ANSI_K = 0x28, kVK_ANSI_Semicolon = 0x29, kVK_ANSI_Backslash = 0x2A, kVK_ANSI_Comma = 0x2B, kVK_ANSI_Slash = 0x2C, kVK_ANSI_N = 0x2D, kVK_ANSI_M = 0x2E, kVK_ANSI_Period = 0x2F, kVK_ANSI_Grave = 0x32, kVK_ANSI_KeypadDecimal = 0x41, kVK_ANSI_KeypadMultiply = 0x43, kVK_ANSI_KeypadPlus = 0x45, kVK_ANSI_KeypadClear = 0x47, kVK_ANSI_KeypadDivide = 0x4B, kVK_ANSI_KeypadEnter = 0x4C, kVK_ANSI_KeypadMinus = 0x4E, kVK_ANSI_KeypadEquals = 0x51, kVK_ANSI_Keypad0 = 0x52, kVK_ANSI_Keypad1 = 0x53, kVK_ANSI_Keypad2 = 0x54, kVK_ANSI_Keypad3 = 0x55, kVK_ANSI_Keypad4 = 0x56, kVK_ANSI_Keypad5 = 0x57, kVK_ANSI_Keypad6 = 0x58, kVK_ANSI_Keypad7 = 0x59, kVK_ANSI_Keypad8 = 0x5B, kVK_ANSI_Keypad9 = 0x5C }; /* keycodes for keys that are independent of keyboard layout*/ enum { kVK_Return = 0x24, kVK_Tab = 0x30, kVK_Space = 0x31, kVK_Delete = 0x33, kVK_Escape = 0x35, kVK_Command = 0x37, kVK_Shift = 0x38, kVK_CapsLock = 0x39, kVK_Option = 0x3A, kVK_Control = 0x3B, kVK_RightShift = 0x3C, kVK_RightOption = 0x3D, kVK_RightControl = 0x3E, kVK_Function = 0x3F, kVK_F17 = 0x40, kVK_VolumeUp = 0x48, kVK_VolumeDown = 0x49, kVK_Mute = 0x4A, kVK_F18 = 0x4F, kVK_F19 = 0x50, kVK_F20 = 0x5A, kVK_F5 = 0x60, kVK_F6 = 0x61, kVK_F7 = 0x62, kVK_F3 = 0x63, kVK_F8 = 0x64, kVK_F9 = 0x65, kVK_F11 = 0x67, kVK_F13 = 0x69, kVK_F16 = 0x6A, kVK_F14 = 0x6B, kVK_F10 = 0x6D, kVK_F12 = 0x6F, kVK_F15 = 0x71, kVK_Help = 0x72, kVK_Home = 0x73, kVK_PageUp = 0x74, kVK_ForwardDelete = 0x75, kVK_F4 = 0x76, kVK_End = 0x77, kVK_F2 = 0x78, kVK_PageDown = 0x79, kVK_F1 = 0x7A, kVK_LeftArrow = 0x7B, kVK_RightArrow = 0x7C, kVK_DownArrow = 0x7D, kVK_UpArrow = 0x7E }; Macintosh Toolbox Essentials illustrates the physical locations of these virtual key codes for the Apple Extended Keyboard II in Figure 2-10:
The more canonical reference is in <HIToolbox/Events.h>: /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/Events.h In newer Versions of MacOS the "Events.h" moved to here: /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/Events.h
Found an answer here. So: Command key is 55 Shift is 56 Caps Lock 57 Option is 58 Control is 59.
Here are the all keycodes. Here is a table with some keycodes for the three platforms. It is based on a US Extended keyboard layout. http://web.archive.org/web/20100501161453/http://www.classicteck.com/rbarticles/mackeyboard.php Or, there is an app in the Mac App Store named "Key Codes". Download it to see the keycodes of the keys you press. Key Codes: https://itunes.apple.com/tr/app/key-codes/id414568915?l=tr&mt=12
I found this wonderful article while doing the research for LibOS. P.S: Mac's virtual key codes are the worst
In addition to the keycodes supplied in other answers, there are also "usage IDs" used for key remapping in the newer APIs introduced in macOS Sierra: Technical Note TN2450 Remapping Keys in macOS 10.12 Sierra Under macOS Sierra 10.12, the mechanism for key remapping was changed. This Technical Note is for developers of key remapping software so that they can update their software to support macOS Sierra 10.12. We present 2 solutions for implementing key remapping functionality for macOS 10.12 in this Technical Note. https://developer.apple.com/library/archive/technotes/tn2450/_index.html Keyboard a and A - 0x04 Keyboard b and B - 0x05 Keyboard c and C - 0x06 Keyboard d and D - 0x07 Keyboard e and E - 0x08 ...
macOS 10.12+ Since macOS Sierra 10.12, keyCode has been according to the Universal Serial Bus HID Usage Tables (go to section: 10 Keyboard/Keypad Page, page 51). Usage Usage ID (hex) Keyboard a and A 0x04 Keyboard b and B 0x05 Keyboard c and C 0x06 Keyboard d and D 0x07 Keyboard e and E 0x08 Keyboard f and F 0x09 Keyboard g and G 0x0A Keyboard h and H 0x0B Keyboard i and I 0x0C Keyboard j and J 0x0D Keyboard k and K 0x0E Keyboard l and L 0x0F Keyboard m and M 0x10 Keyboard n and N 0x11 Keyboard o and O 0x12 Keyboard p and P 0x13 Keyboard q and Q 0x14 Keyboard r and R 0x15 Keyboard s and S 0x16 Keyboard t and T 0x17 Keyboard u and U 0x18 Keyboard v and V 0x19 Keyboard w and W 0x1A Keyboard x and X 0x1B Keyboard y and Y 0x1C Keyboard z and Z 0x1D Keyboard 1 and ! 0x1E Keyboard 2 and # 0x1F Keyboard 3 and # 0x20 Keyboard 4 and $ 0x21 Keyboard 5 and % 0x22 Keyboard 6 and ^ 0x23 Keyboard 7 and & 0x24 Keyboard 8 and * 0x25 Keyboard 9 and ( 0x26 Keyboard 0 and ) 0x27 Keyboard Return (Enter) 0x28 Keyboard Escape 0x29 Keyboard Delete (Backspace)0x2A Keyboard Tab 0x2B Keyboard Spacebar 0x2C Keyboard - and _ 0x2D Keyboard = and + 0x2E Keyboard [ and { 0x2F Keyboard ] and } 0x30 Keyboard \ and | 0x31 Keyboard Non-US # and ~ 0x32 Keyboard ; and : 0x33 Keyboard ' and " 0x34 Keyboard Grave Accent and Tilde 0x35 Keyboard , and "<" 0x36 Keyboard . and ">" 0x37 Keyboard / and ? 0x38 Keyboard Caps Lock 0x39 Keyboard F1 0x3A Keyboard F2 0x3B Keyboard F3 0x3C Keyboard F4 0x3D Keyboard F5 0x3E Keyboard F6 0x3F Keyboard F7 0x40 Keyboard F8 0x41 Keyboard F9 0x42 Keyboard F10 0x43 Keyboard F11 0x44 Keyboard F12 0x45 Keyboard Print Screen 0x46 Keyboard Scroll Lock 0x47 Keyboard Pause 0x48 Keyboard Insert 0x49 Keyboard Home 0x4A Keyboard Page Up 0x4B Keyboard Delete Forward 0x4C Keyboard End 0x4D Keyboard Page Down 0x4E Keyboard Right Arrow 0x4F Keyboard Left Arrow 0x50 Keyboard Down Arrow 0x51 Keyboard Up Arrow 0x52 Keypad Num Lock and Clear 0x53 Keypad / 0x54 Keypad * 0x55 Keypad - 0x56 Keypad + 0x57 Keypad Enter 0x58 Keypad 1 and End 0x59 Keypad 2 and Down Arrow 0x5A Keypad 3 and Page Down 0x5B Keypad 4 and Left Arrow 0x5C Keypad 5 0x5D Keypad 6 and Right Arrow 0x5E Keypad 7 and Home 0x5F Keypad 8 and Up Arrow 0x60 Keypad 9 and Page Up 0x61 Keypad 0 and Insert 0x62 Keypad . and Delete 0x63 Keyboard Non-US \ and | 0x64 Keyboard Application 0x65 Keyboard Power 0x66 Keypad = 0x67 Keyboard F13 0x68 Keyboard F14 0x69 Keyboard F15 0x6A Keyboard F16 0x6B Keyboard F17 0x6C Keyboard F18 0x6D Keyboard F19 0x6E Keyboard F20 0x6F Keyboard F21 0x70 Keyboard F22 0x71 Keyboard F23 0x72 Keyboard F24 0x73 Keyboard Left Control 0xE0 Keyboard Left Shift 0xE1 Keyboard Left Alt 0xE2 Keyboard Left GUI 0xE3 Keyboard Right Control 0xE4 Keyboard Right Shift 0xE5 Keyboard Right Alt 0xE6 Keyboard Right GUI 0xE7
Here's some prebuilt Objective-C dictionaries if anyone wants to type ansi characters: NSDictionary *lowerCaseCodes = #{ #"Q" : #(12), #"W" : #(13), #"E" : #(14), #"R" : #(15), #"T" : #(17), #"Y" : #(16), #"U" : #(32), #"I" : #(34), #"O" : #(31), #"P" : #(35), #"A" : #(0), #"S" : #(1), #"D" : #(2), #"F" : #(3), #"G" : #(5), #"H" : #(4), #"J" : #(38), #"K" : #(40), #"L" : #(37), #"Z" : #(6), #"X" : #(7), #"C" : #(8), #"V" : #(9), #"B" : #(11), #"N" : #(45), #"M" : #(46), #"0" : #(29), #"1" : #(18), #"2" : #(19), #"3" : #(20), #"4" : #(21), #"5" : #(23), #"6" : #(22), #"7" : #(26), #"8" : #(28), #"9" : #(25), #" " : #(49), #"." : #(47), #"," : #(43), #"/" : #(44), #";" : #(41), #"'" : #(39), #"[" : #(33), #"]" : #(30), #"\\" : #(42), #"-" : #(27), #"=" : #(24) }; NSDictionary *shiftCodes = #{ // used in conjunction with the shift key #"<" : #(43), #">" : #(47), #"?" : #(44), #":" : #(41), #"\"" : #(39), #"{" : #(33), #"}" : #(30), #"|" : #(42), #")" : #(29), #"!" : #(18), #"#" : #(19), #"#" : #(20), #"$" : #(21), #"%" : #(23), #"^" : #(22), #"&" : #(26), #"*" : #(28), #"(" : #(25), #"_" : #(27), #"+" : #(24) };