2. 音频控制接口初始化

任务说明

本案例完成USB音频设备类中音频控制接口(AudioControl Interface)的初始化逻辑,为后续处理音量(Volume)、静音(Mute)等类特定控制请求建立默认状态。初始化完成后,设备应能对主机发来的控制请求返回当前默认值,并支持后续通过请求处理函数修改这些值。

核心实现

// audio_control.h
#ifndef AUDIO_CONTROL_H
#define AUDIO_CONTROL_H

#include <stdint.h>

// 音频控制接口的通道数量(立体声:左/右)
#define AC_NUM_CHANNELS 2

// 控制请求选择子(USB Audio Class 1.0)
#define AC_FEATURE_UNIT_CONTROL   0x03
#define AC_MUTE_CONTROL           0x01
#define AC_VOLUME_CONTROL         0x02

// 音量范围(-60dB ~ 0dB,分辨率0.5dB,以0.5dB为单位)
#define VOLUME_MIN   (-120)   // -60dB
#define VOLUME_MAX   0        // 0dB
#define VOLUME_RES   1        // 0.5dB步进

typedef struct {
    uint16_t mute;          // 0=非静音, 1=静音
    int16_t  volume[AC_NUM_CHANNELS];  // 当前音量值
} ac_feature_state_t;

// 初始化音频控制接口状态
void ac_init(ac_feature_state_t *state);

// 获取当前控制值(供请求处理回调调用)
uint16_t ac_get_mute(const ac_feature_state_t *state);
int16_t  ac_get_volume(const ac_feature_state_t *state, uint8_t channel);

// 设置控制值(供请求处理回调调用)
void ac_set_mute(ac_feature_state_t *state, uint16_t mute);
void ac_set_volume(ac_feature_state_t *state, uint8_t channel, int16_t volume);

#endif // AUDIO_CONTROL_H
// audio_control.c
#include "audio_control.h"

void ac_init(ac_feature_state_t *state) {
    if (!state) return;
    state->mute = 0;  // 默认非静音
    for (int i = 0; i < AC_NUM_CHANNELS; i++) {
        state->volume[i] = VOLUME_MAX;  // 默认0dB
    }
}

uint16_t ac_get_mute(const ac_feature_state_t *state) {
    return state ? state->mute : 0;
}

int16_t ac_get_volume(const ac_feature_state_t *state, uint8_t channel) {
    if (!state || channel >= AC_NUM_CHANNELS) return 0;
    return state->volume[channel];
}

void ac_set_mute(ac_feature_state_t *state, uint16_t mute) {
    if (state) state->mute = mute ? 1 : 0;
}

void ac_set_volume(ac_feature_state_t *state, uint8_t channel, int16_t volume) {
    if (!state || channel >= AC_NUM_CHANNELS) return;
    // 限制在有效范围内
    if (volume < VOLUME_MIN) volume = VOLUME_MIN;
    if (volume > VOLUME_MAX) volume = VOLUME_MAX;
    state->volume[channel] = volume;
}
// 使用示例(main.c 或请求处理回调中)
#include "audio_control.h"

ac_feature_state_t ac_state;

void usb_audio_control_init(void) {
    ac_init(&ac_state);
}

// 处理主机发来的 GET_CUR 请求时调用
uint16_t handle_get_cur(uint8_t control_selector, uint8_t channel) {
    switch (control_selector) {
        case AC_MUTE_CONTROL:
            return ac_get_mute(&ac_state);
        case AC_VOLUME_CONTROL:
            return (uint16_t)ac_get_volume(&ac_state, channel);
        default:
            return 0;
    }
}

// 处理主机发来的 SET_CUR 请求时调用
void handle_set_cur(uint8_t control_selector, uint8_t channel, uint16_t value) {
    switch (control_selector) {
        case AC_MUTE_CONTROL:
            ac_set_mute(&ac_state, value);
            break;
        case AC_VOLUME_CONTROL:
            ac_set_volume(&ac_state, channel, (int16_t)value);
            break;
        default:
            break;
    }
}

编译与验证

将上述三个文件加入工程编译(或直接编译audio_control.c与包含main的测试文件)。验证路径如下:

  1. 调用ac_init()后,断言ac_get_mute()返回0,ac_get_volume(ch0)与ac_get_volume(ch1)均返回0(即0dB)。
  2. 调用ac_set_volume(0, -60),再读取ac_get_volume(0),应返回-60。
  3. 调用ac_set_volume(1, 100)(超出上限),读取应被钳位到0。
  4. 调用ac_set_mute(1)后,ac_get_mute()返回1。

通过条件:以上断言全部成立,且handle_get_cur/handle_set_cur能正确映射到状态读写。该初始化逻辑为USB音频类控制请求处理提供了确定的默认状态与访问接口,可直接接入UDC(USB Device Controller)的EP0回调中。