#ifndef usbaudio_h
#define usbaudio_h

#include "usb.h"

/*
 * Class, SubClass, Protocol (CSP) values
 */
#define USB_AUDIO_CLASS                 1
#define USB_AUDIO_CONTROL_SUBCLASS      1
#define USB_AUDIO_STREAMING_SUBCLASS    2
#define USB_AUDIO_CS_CONTROL            0x101
#define USB_AUDIO_CS_STREAMING          0x102

/*
 * Audio Control (AC) Interface descriptor subtypes
 */
#define USB_AUDIO_AC_UNDEFINED          0

typedef __packed struct
{
    USB_DescriptorSubBase;
                #define USB_AUDIO_AC_HEADER             1
    uint16_t            bcdADC;             // Revision of class specification
    uint16_t            wTotalLength;       // Total size of class specific descriptors
    uint8_t             bInCollection;      // Number of streaming interfaces
    uint8_t             baInterfaceNr[];    // index = interface number -1
} USBAudio_ACHeader;


typedef __packed struct
{
    USB_DescriptorSubBase;
                #define USB_AUDIO_AC_INPUT_TERMINAL     2
    uint8_t             bTerminalID;        // ID of this input terminal
    uint16_t            wTerminalType;      
                #define USB_AUDIO_TT_MICROPHONE         0x201
    uint8_t             bAssocTerminal;
    uint8_t             bNrChannels;
    uint16_t            wChannelConfig;
    uint8_t             iChannelNames;
    uint8_t             iTerminal;
} USBAudio_ACInputTerminal;

typedef __packed struct
{
    USB_DescriptorSubBase;
                #define USB_AUDIO_AC_OUTPUT_TERMINAL    3
    uint8_t             bTerminalID;
    uint16_t            wTerminalType;
                #define USB_AUDIO_TT_STREAMING          0x101
    uint8_t             bAssocTerminal;
    uint8_t             bSourceID;
    uint8_t             iTerminal;
} USBAudio_ACOutputTerminal;

/*******************************************************************************
 * USBAudio_ACMixerUnit is split into 3 parts because of variable length fields.
 * MACROS are included to access the other parts from the USBAudio_ACMixerUnit*
 */

typedef __packed struct
{
    USB_DescriptorSubBase;
                #define USB_AUDIO_AC_MIXER_UNIT         4
    uint8_t             bUnitID;
    uint8_t             bNrInPins;
    uint8_t             baSourceID[];
} USBAudio_ACMixerUnit;


typedef __packed struct
{
    uint8_t             bNrChannels;
    uint16_t            wChannelConfig;
    uint8_t             iChannelNames;
    uint8_t             bmControls[];
} USBAudio_ACMixerUnitPart2;

typedef __packed struct
{
    uint8_t             iMixer;
} USBAudio_ACMixerUnitPart3;


// sizeof(bmControls)
#define SIZEOF_USBAudio_ACMU_bmCONTROL(mixu) ((mixu)->bLength - 10 - (mixu)->bNrInPins)

// Equivalent to: USBAudio_ACMixerUnitPart2* USBAudio_ACMixerUnit2(USBAudio_ACMixerUnit*)
#define USBAudio_ACMixerUnit2(mixu) ((USBAudio_ACMixerUnitPart2*)(&(mixu)->baSourceID[(mixu)->bNrInPins]))

// Equivalent to: USBAudio_ACMixerUnitPart3* USBAudio_ACMixerUnit2(USBAudio_ACMixerUnit*)
#define USBAudio_ACMixerUnit3(mixu) ((USBAudio_ACMixerUnitPart3*)(((char*)mixu))+(mixu)->bLength-sizeof(USBAudio_ACMixerUnitPart3)))

//*******************************************************************************


    #define USB_AUDIO_AC_SELECTOR_UNIT      5
    #define USB_AUDIO_AC_FEATURE_UNIT       6
    #define USB_AUDIO_AC_PROCESSING_UNIT    7
        /*
         * Processing Unit (PU) wProcessType type
         */
        #define USB_AUDIO_PU_UNDEFINED          0
        #define USB_AUDIO_PU_UP_DOWN_MIX        1
        #define USB_AUDIO_PU_DOLBY_PROLOGIC     2
        #define USB_AUDIO_PU_STEREO_EXTENDER    3
        #define USB_AUDIO_PU_REVERBERATION      4
        #define USB_AUDIO_PU_CHORUS             5
        #define USB_AUDIO_PU_DYN_RANGE_COMP     6

    #define USB_AUDIO_AC_EXTENSION_UNIT     8

/*
 * Audio Streaming (AS) interface descriptor subtypes
 */
#define USB_AUDIO_AS_UNDEFINED          0

typedef __packed struct
{
    USB_DescriptorSubBase;
                #define USB_AUDIO_AS_GENERAL            1
    uint8_t             bTerminalLink;              // UnitID of the output terminal
    uint8_t             bDelay;                     // Interface delay
    uint16_t            wFormatFlag;
                #define USB_AUDIO_FF_PCM                1
} USBAudio_ASGeneral;

typedef __packed struct
{
    USB_DescriptorSubBase;
                #define USB_AUDIO_AS_FORMAT_TYPE        2
    uint8_t             bFormatType;
    uint8_t             bNrChannels;
    uint8_t             bSubFrameSize;              // bytes per audio sub frame
    uint8_t             bBitResolution;             // bits per sample
    uint8_t             bSamFreqType;
    uint8_t             tSamFreq[3];                // Sample frequency (Hz)
} USBAudio_ASFormatType;

#define USB_AUDIO_AS_FORMAT_SPECIFIC    3


/*
 * Audio Endpoint (EP) descriptor subtypes
 */
#define USB_AUDIO_EP_UNDEFINED          0

typedef __packed struct
{
    USB_DescriptorSubBase;
                        #define USB_AUDIO_EP_GENERAL            1
    uint8_t             bmAttributes;
    uint8_t             bLockDelayUnits;
    uint16_t            wLockDelay;
} USBAudio_EPGeneral;






typedef __packed struct
{
    USB_DescriptorSubBase;
    uint8_t             bUnitID;
    uint8_t             bNrInPins;
    uint8_t             baSourceID0;
    uint8_t             baSourceID1;
    uint8_t             bNrChannels;
    uint16_t            wChannelConfig;
    uint8_t             iChannelNames;
    uint8_t             bmControls;
    uint8_t             iMixer;
} USBAudio_HeadMixerUnit;
#define USB_AUDIO_HEAD_MIXER_UNIT       4

typedef __packed struct
{
    USB_DescriptorSubBase;
    uint8_t             bUnitID;
    uint8_t             bSourceID;
    uint8_t             bControlSize;
    uint16_t            bmaControls0;
    uint16_t            bmaControls1;
    uint8_t             iFeature;
} USBAudio_FeatureUnitDescriptor;
#define USB_AUDIO_FEATURE_UNIT          6


#endif
