123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820 |
- #include "includes.h"
- #include "asm/includes.h"
- #include "app_config.h"
- #include "system/timer.h"
- #include "device/ioctl_cmds.h"
- #include "device_drive.h"
- #if TCFG_HOST_AUDIO_ENABLE
- #include "usb/host/usb_host.h"
- #include "usb_ctrl_transfer.h"
- #include "usb_bulk_transfer.h"
- #include "audio.h"
- #include "usb_config.h"
- #define LOG_TAG_CONST USB
- #define LOG_TAG "[AUDIO]"
- #define LOG_ERROR_ENABLE
- #define LOG_DEBUG_ENABLE
- #define LOG_INFO_ENABLE
- /* #define LOG_DUMP_ENABLE */
- #define LOG_CLI_ENABLE
- #include "debug.h"
- /* #define USB_AUDIO_PLAY_TEST */
- struct usb_audio_play {
- u32 sample_rate;
- u8 Cur_AlternateSetting;
- u8 src_channel;
- u8 play_state;
- u8 mute;
- u8 *send_buf;
- u8 *usb_audio_play_buf;
- u8 *usb_audio_play_buf2;
- cbuffer_t usb_audio_play_cbuf;
- u32 usb_audio_remain_len;
- OS_SEM sem;
- int (*put_buf)(void *ptr, u32 len);
- };
- struct usb_audio_mic {
- u8 Cur_AlternateSetting;
- u32 sample_rate;
- u8 record_state;
- u8 *usb_audio_record_buf;
- u8 *usb_audio_record_buf2;
- cbuffer_t usb_audio_record_cbuf;
- int *(*get_buf)(void *ptr, u32 len);
- };
- struct usb_audio_info {
- usb_dev usb_id;
- struct usb_audio_play player;
- struct usb_audio_mic microphone;
- };
- enum {
- AUDIO_PLAY_IDLE = 0,
- AUDIO_PLAY_START,
- AUDIO_PLAY_STOP,
- AUDIO_PLAY_PAUSE,
- };
- enum {
- AUDIO_RECORD_IDLE = 0,
- AUDIO_RECORD_START,
- AUDIO_RECORD_STOP,
- AUDIO_RECORD_PAUSE,
- };
- #define EP_MAX_PACKET_SIZE (192)
- struct usb_audio_info _usb_audio_info = {0};
- #define __this (&_usb_audio_info)
- struct audio_device_t audio_device[USB_MAX_HW_NUM][MAX_HOST_INTERFACE];
- static u8 ep_in_dma_buf[256] __attribute__((aligned(4)));
- static u8 ep_out_dma_buf[256] __attribute__((aligned(4)));
- static int set_power(struct usb_host_device *host_dev, u32 value)
- {
- const usb_dev usb_id = host_device2id(host_dev);
- return DEV_ERR_NONE;
- }
- static int get_power(struct usb_host_device *host_dev, u32 value)
- {
- return DEV_ERR_NONE;
- }
- static const struct interface_ctrl uac_ctrl = {
- .interface_class = USB_CLASS_AUDIO,
- .set_power = set_power,
- .get_power = get_power,
- .ioctl = NULL,
- };
- static const struct usb_interface_info _uac_if[USB_MAX_HW_NUM][MAX_HOST_INTERFACE] = {
- {
- {
- .ctrl = (struct interface_ctrl *) &uac_ctrl,
- .dev.audio = &audio_device[0][0],
- },
- {
- .ctrl = (struct interface_ctrl *) &uac_ctrl,
- .dev.audio = &audio_device[0][1],
- },
- {
- .ctrl = (struct interface_ctrl *) &uac_ctrl,
- .dev.audio = &audio_device[0][2],
- },
- {
- .ctrl = (struct interface_ctrl *) &uac_ctrl,
- .dev.audio = &audio_device[0][3],
- },
- },
- };
- int usb_audio_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf)
- {
- struct usb_interface_descriptor *interface = (struct usb_interface_descriptor *)pBuf;
- const usb_dev usb_id = host_device2id(host_dev);
- const struct usb_interface_info *usb_if = &_uac_if[usb_id][interface_num];
- struct audio_streaming_t *as_t = NULL;
- memset(usb_if->dev.p, 0, sizeof(struct audio_device_t));
- host_dev->interface_info[interface_num] = usb_if;
- usb_if->dev.audio->parent = host_dev;
- if (interface->bInterfaceSubClass == USB_SUBCLASS_AUDIOCONTROL) {
- log_info("audio control interface : %d\n", interface_num);
- pBuf += sizeof(struct usb_interface_descriptor);
- usb_if->dev.audio->subclass = interface->bInterfaceSubClass;
- usb_if->dev.audio->interface_num = interface_num;
- return sizeof(struct usb_interface_descriptor);
- }
- if (interface->bInterfaceSubClass == USB_SUBCLASS_AUDIOSTREAMING) {
- usb_if->dev.audio->subclass = interface->bInterfaceSubClass;
- usb_if->dev.audio->interface_num = interface_num;
- if (interface->bNumEndpoints == 0) {
- pBuf += sizeof(struct usb_interface_descriptor);
- do {
- struct usb_interface_descriptor *as_interface = (struct usb_interface_descriptor *)pBuf;
- if (as_interface->bNumEndpoints == 0 || as_interface->bInterfaceClass != USB_CLASS_AUDIO) {
- break;
- }
- log_info("audio streaming interface : %d ep_num:%d Altersetting:%d", interface_num, as_interface->bNumEndpoints, as_interface->bAlternateSetting);
- as_t = &usb_if->dev.audio->as[as_interface->bAlternateSetting - 1];
- as_t->bNumEndpoints = as_interface->bNumEndpoints;
- pBuf += (USB_DT_INTERFACE_SIZE + UAC_DT_AS_HEADER_SIZE);
- //解析format
- struct uac_format_type_i_discrete_descriptor *uac_format_desc = (struct uac_format_type_i_discrete_descriptor *)pBuf;
- if (uac_format_desc->bDescriptorSubtype == UAC_FORMAT_TYPE) {
- as_t->bFormatType = uac_format_desc->bFormatType;
- as_t->bNrChannels = uac_format_desc->bNrChannels;
- as_t->bSubframeSize = uac_format_desc->bSubframeSize;
- as_t->bBitResolution = uac_format_desc->bBitResolution;
- as_t->bSamFreqType = uac_format_desc->bSamFreqType;
- for (u8 i = 0; i < as_t->bSamFreqType; i++) {
- memcpy(&as_t->tSamFreq[i], &uac_format_desc->tSamFreq[i], 3);
- log_info("as bNrChannels:%d bBitResolution:%d tSamFreq : %d", as_t->bNrChannels, as_t->bBitResolution, as_t->tSamFreq[i]);
- }
- //Endpointdescriptor
- pBuf += uac_format_desc->bLength;
- /* for (int i = 0; i < as_t->bNumEndpoints; i++) { */
- struct usb_endpoint_descriptor *endpoint = (struct usb_endpoint_descriptor *)pBuf;
- if (endpoint->bDescriptorType == USB_DT_ENDPOINT) {
- as_t->ep_Interval = endpoint->bInterval;
- as_t->ep_max_packet_size = endpoint->wMaxPacketSize;
- if (endpoint->bEndpointAddress & USB_DIR_IN) {
- as_t->ep = endpoint->bEndpointAddress & 0xf;
- log_info("ep in : %x\n", as_t->ep);
- usb_if->dev.audio->support = MICROPHONE_SUPPORTED;
- } else {
- as_t->ep = endpoint->bEndpointAddress;
- log_info("ep out : %x\n", as_t->ep);
- usb_if->dev.audio->support = HEADPHONE_SUPPORTED;
- }
- pBuf += (USB_DT_ENDPOINT_AUDIO_SIZE + UAC_ISO_ENDPOINT_DESC_SIZE);
- }
- /* } */
- } else {
- log_error("uac_format_desc->bDescriptorSubtype err!!\n");
- goto __exit;
- }
- } while (1);
- /* log_info("lennnn:%d\n",pBuf - (u8 *)interface); */
- return pBuf - (u8 *)interface ;
- } else {
- log_info("audio streaming interface : %d ep_num:%d Altersetting:%d\n", interface_num, interface->bNumEndpoints, interface->bAlternateSetting);
- }
- }
- __exit:
- return USB_DT_INTERFACE_SIZE;
- }
- static struct audio_device_t *__find_microphone_interface(const struct usb_host_device *host_dev)
- {
- struct audio_device_t *audio = NULL;
- for (u8 i = 0; i < MAX_HOST_INTERFACE; i++) {
- const struct usb_interface_info *usb_if = host_dev->interface_info[i];
- if (usb_if &&
- (usb_if->ctrl->interface_class == USB_CLASS_AUDIO)) {
- audio = usb_if->dev.audio;
- if (audio->subclass == USB_SUBCLASS_AUDIOSTREAMING &&
- audio->support == MICROPHONE_SUPPORTED) {
- // find microphone
- return audio;
- }
- }
- }
- return NULL;
- }
- static struct audio_device_t *__find_headphone_interface(const struct usb_host_device *host_dev)
- {
- struct audio_device_t *audio = NULL;
- for (u8 i = 0; i < MAX_HOST_INTERFACE; i++) {
- const struct usb_interface_info *usb_if = host_dev->interface_info[i];
- if (usb_if &&
- (usb_if->ctrl->interface_class == USB_CLASS_AUDIO)) {
- audio = usb_if->dev.audio;
- if (audio->subclass == USB_SUBCLASS_AUDIOSTREAMING &&
- audio->support == HEADPHONE_SUPPORTED) {
- // find headphone
- return audio;
- }
- }
- }
- return NULL;
- }
- static u32 play_vol_convert(u16 v)
- {
- //固定音量表,更换声卡需要修改音量表
- const u16 vol_table[] = {
- //0-100
- 0xd300, //0
- 0xd58f, 0xd7bf, 0xd9a8, 0xdb5b, 0xdce1, 0xde45, 0xdf8a, 0xe0b6, 0xe1cd, 0xe2d1,
- 0xe3c5, 0xe4ab, 0xe583, 0xe651, 0xe714, 0xe7cd, 0xe87f, 0xe928, 0xe9ca, 0xea66,
- 0xeafc, 0xeb8d, 0xec18, 0xec9e, 0xed20, 0xed9e, 0xee18, 0xee8e, 0xef00, 0xef6f,
- 0xefdc, 0xf045, 0xf0ab, 0xf10f, 0xf171, 0xf1d0, 0xf22c, 0xf287, 0xf2e0, 0xf336,
- 0xf38b, 0xf3de, 0xf42f, 0xf47e, 0xf4cc, 0xf518, 0xf563, 0xf5ad, 0xf5f5, 0xf63c,
- 0xf681, 0xf6c6, 0xf709, 0xf74b, 0xf78c, 0xf7cb, 0xf80a, 0xf848, 0xf885, 0xf8c1,
- 0xf8fc, 0xf936, 0xf96f, 0xf9a8, 0xf9df, 0xfa16, 0xfa4c, 0xfa81, 0xfab6, 0xfaea,
- 0xfb1d, 0xfb50, 0xfb82, 0xfbb3, 0xfbe4, 0xfc14, 0xfc43, 0xfc72, 0xfca0, 0xfcce,
- 0xfcfc, 0xfd28, 0xfd55, 0xfd80, 0xfdab, 0xfdd6, 0xfe01, 0xfe2a, 0xfe54, 0xfe7d,
- 0xfea5, 0xfece, 0xfef5, 0xff1d, 0xff43, 0xff6a, 0xff90, 0xffb6, 0xffdb, 0x0000,
- };
- if (v <= 100) {
- return vol_table[v];
- }
- for (int i = 0; i < sizeof(vol_table) / 2; i++) {
- if (v <= vol_table[i]) {
- return i;
- }
- }
- return 0;
- }
- void set_usb_audio_play_volume(u16 vol)
- {
- const struct usb_host_device *host_dev = host_id2device(__this->usb_id);
- u8 featureUnitID = 6;
- usb_audio_volume_control(host_dev, featureUnitID, 1, play_vol_convert(vol));
- usb_audio_volume_control(host_dev, featureUnitID, 2, play_vol_convert(vol));
- if (vol == 0) {
- __this->player.mute = 1;
- usb_audio_mute_control(host_dev, featureUnitID, __this->player.mute); //mute
- } else {
- if (__this->player.mute == 1) {
- __this->player.mute = 0;
- usb_audio_mute_control(host_dev, featureUnitID, __this->player.mute);
- }
- }
- }
- #ifdef USB_AUDIO_PLAY_TEST
- static const s16 sin_48k[] = {
- 0, 2139, 4240, 6270, 8192, 9974, 11585, 12998,
- 14189, 15137, 15826, 16244, 16384, 16244, 15826, 15137,
- 14189, 12998, 11585, 9974, 8192, 6270, 4240, 2139,
- 0, -2139, -4240, -6270, -8192, -9974, -11585, -12998,
- -14189, -15137, -15826, -16244, -16384, -16244, -15826, -15137,
- -14189, -12998, -11585, -9974, -8192, -6270, -4240, -2139
- };
- #endif
- static void usb_audio_tx_isr(struct usb_host_device *host_dev, u32 ep)
- {
- const usb_dev usb_id = host_device2id(host_dev);
- struct audio_device_t *audio = NULL;
- struct audio_streaming_t *as_t = NULL;
- u16 ep_max_packet_size = 0;
- u8 channel = 0;
- u32 rlen = 0;
- static u32 usb_audio_tx_len = 0;
- if (__this->player.play_state != AUDIO_PLAY_START) {
- return;
- }
- audio = __find_headphone_interface(host_dev);
- if (!audio) {
- log_error("no find headphone interface!");
- return;
- }
- as_t = &audio->as[__this->player.Cur_AlternateSetting - 1];
- /* ep_max_packet_size = as_t->ep_max_packet_size; */
- ep_max_packet_size = EP_MAX_PACKET_SIZE;
- channel = as_t->bNrChannels;
- //iso send
- #ifdef USB_AUDIO_PLAY_TEST
- //For Test
- int tx_len = 0;
- #if 1 // 单声道双声道输出
- s16 buf[240 / 2];
- for (u8 i = 0, j = 0; i < 240 / 2; i += 2) {
- buf[i] = sin_48k[j];
- buf[i + 1] = sin_48k[j];
- j++;
- if (j >= sizeof(sin_48k) / sizeof(sin_48k[0])) {
- j = 0;
- }
- }
- #else
- //单声道直接输出
- u8 buf[248];
- do {
- memcpy(&buf[tx_len], sin_48k, sizeof(sin_48k));
- tx_len += sizeof(sin_48k);
- } while (tx_len < ep_max_packet_size);
- #endif
- usb_h_ep_write_async(usb_id, ep, ep_max_packet_size, as_t->ep, buf, ep_max_packet_size, USB_ENDPOINT_XFER_ISOC, 0);
- #else
- if (__this->player.usb_audio_remain_len == 0) {
- cbuf_read_alloc(&__this->player.usb_audio_play_cbuf, &__this->player.usb_audio_remain_len);
- usb_audio_tx_len = 0;
- }
- if (__this->player.usb_audio_remain_len) {
- if (usb_audio_tx_len == 0) {
- rlen = cbuf_read(&__this->player.usb_audio_play_cbuf, __this->player.usb_audio_play_buf2, __this->player.usb_audio_remain_len);
- if (!rlen) {
- __this->player.usb_audio_remain_len = 0;
- usb_audio_tx_len = 0;
- putchar('C');
- usb_h_ep_write_async(usb_id, ep, ep_max_packet_size, as_t->ep, NULL, ep_max_packet_size, USB_ENDPOINT_XFER_ISOC, 1);
- os_sem_post(&__this->player.sem);
- return;
- }
- os_sem_post(&__this->player.sem);
- }
- u8 *send_buf = __this->player.send_buf;
- u8 *play_buf = __this->player.usb_audio_play_buf2;
- if (channel == 2) {
- if (__this->player.src_channel == 1) {
- //源数据是单声道数据,转双声道输出
- int j = 0;
- for (u8 i = 0; i < ep_max_packet_size; i += 4) {
- //left
- *(send_buf + i) = *(play_buf + (usb_audio_tx_len + j));
- *(send_buf + i + 1) = *(play_buf + (usb_audio_tx_len + j + 1));
- //right
- *(send_buf + i + 2) = *(play_buf + (usb_audio_tx_len + j));
- *(send_buf + i + 3) = *(play_buf + (usb_audio_tx_len + j + 1));
- j += 2;
- }
- usb_audio_tx_len += j;
- usb_h_ep_write_async(usb_id, ep, ep_max_packet_size, as_t->ep, send_buf, ep_max_packet_size, USB_ENDPOINT_XFER_ISOC, 0);
- } else if (__this->player.src_channel == 2) {
- //源数据是双声道数据,直接双声道输出
- usb_h_ep_write_async(usb_id, ep, ep_max_packet_size, as_t->ep, play_buf + usb_audio_tx_len, ep_max_packet_size, USB_ENDPOINT_XFER_ISOC, 0);
- usb_audio_tx_len += ep_max_packet_size;
- }
- } else if (channel == 1) {
- }
- if (usb_audio_tx_len >= __this->player.usb_audio_remain_len) {
- __this->player.usb_audio_remain_len = 0;
- usb_audio_tx_len = 0;
- }
- } else {
- //audio buf null ,send null packet
- putchar('E');
- usb_h_ep_write_async(usb_id, ep, ep_max_packet_size, as_t->ep, NULL, ep_max_packet_size, USB_ENDPOINT_XFER_ISOC, 1);
- }
- #endif
- }
- void set_vol_test(void *p)
- {
- struct usb_host_device *host_dev = (struct usb_host_device *)p;
- static u16 vol = 100;
- set_usb_audio_play_volume(vol);
- /* static u8 f = 0; */
- /* void usb_audio_pause_play(void); */
- /* void usb_audio_resume_play(void); */
- /* if (!f) { */
- /* usb_audio_pause_play(); */
- /* } else { */
- /* usb_audio_resume_play(); */
- /* } */
- /* f = !f; */
- vol -= 10;
- }
- void audio_play_task(void *p)
- {
- log_info(">>> Enter usb audio play task");
- struct usb_host_device *host_dev = (struct usb_host_device *)p;
- const usb_dev usb_id = host_device2id(host_dev);
- u8 *ptr = NULL;
- u32 wlen = 0;
- u32 ret = 0;
- struct audio_device_t *audio = NULL;
- audio = __find_headphone_interface(host_dev);
- struct audio_streaming_t *as_t = &audio->as[__this->player.Cur_AlternateSetting - 1];
- /* u32 ep_max_packet_size = as_t->ep_max_packet_size; */
- u32 ep_max_packet_size = EP_MAX_PACKET_SIZE;
- log_info("ep max packet : %d\n", ep_max_packet_size);
- if (__this->player.send_buf) {
- free(__this->player.send_buf);
- __this->player.send_buf = NULL;
- }
- __this->player.send_buf = zalloc(ep_max_packet_size);
- u32 usb_audio_buf_size = ep_max_packet_size * 5; //预留5个包的缓存
- /* sys_timer_add(host_dev,set_vol_test,5000); */
- os_sem_create(&__this->player.sem, 0);
- u32 host_ep = as_t->host_ep;
- __this->player.play_state = AUDIO_PLAY_START;
- //分配双缓存
- // 一个缓存保存读卡的数据,一个用于usb发送
- if (!__this->player.usb_audio_play_buf) {
- __this->player.usb_audio_play_buf = zalloc(usb_audio_buf_size);
- cbuf_init(&__this->player.usb_audio_play_cbuf, __this->player.usb_audio_play_buf, usb_audio_buf_size);
- usb_h_ep_write_async(usb_id, host_ep, ep_max_packet_size, as_t->ep, NULL, ep_max_packet_size, USB_ENDPOINT_XFER_ISOC, 1); //启动iso传输
- }
- if (!__this->player.usb_audio_play_buf2) {
- __this->player.usb_audio_play_buf2 = zalloc(usb_audio_buf_size);
- }
- while (1) {
- if (__this->player.Cur_AlternateSetting == 0 || __this->player.play_state != AUDIO_PLAY_START) {
- putchar('C');
- os_time_dly(50);
- continue;
- }
- ptr = cbuf_write_alloc(&__this->player.usb_audio_play_cbuf, &wlen);
- if (wlen) {
- putchar('R');
- ret = __this->player.put_buf(ptr, wlen);
- if (ret != wlen) {
- __this->player.play_state = AUDIO_PLAY_STOP;
- goto __task_exit;
- }
- cbuf_write_updata(&__this->player.usb_audio_play_cbuf, wlen);
- } else {
- log_w("usb audio play buf not enough!\n");
- }
- __task_exit:
- os_sem_pend(&__this->player.sem, 0);
- }
- }
- void usb_audio_start_play(const usb_dev usb_id, u8 channel, u8 bit_reso, u32 sample_rate)
- {
- log_info(" usb audio play\n");
- const struct usb_host_device *host_dev = host_id2device(usb_id);
- struct audio_device_t *audio = NULL;
- struct audio_streaming_t *as_t = NULL;
- u8 *ep_buffer = ep_out_dma_buf;
- u8 find_alternatesetting = 0;
- audio = __find_headphone_interface(host_dev);
- if (!audio) {
- log_error("no find headphone interface!");
- return;
- }
- for (u8 i = 0; i < ARRAY_SIZE(audio->as); i++) {
- as_t = &audio->as[i];
- if (as_t->bBitResolution == bit_reso) {
- for (u8 j = 0; j < as_t->bSamFreqType; j++) {
- if (as_t->tSamFreq[j] == sample_rate) {
- find_alternatesetting = i + 1;
- break;
- }
- }
- }
- }
- if (!find_alternatesetting) {
- log_e("can not find Alternatesetting,please check bit_reso and sample_rate\n");
- return;
- }
- __this->usb_id = usb_id;
- //端点分配
- u32 host_ep = usb_get_ep_num(usb_id, USB_DIR_OUT, USB_ENDPOINT_XFER_ISOC);
- ASSERT(host_ep != -1, "ep not enough");
- __this->player.Cur_AlternateSetting = find_alternatesetting; //选择Alternatesetting
- __this->player.sample_rate = sample_rate; //选择采样率
- __this->player.src_channel = channel;
- as_t = &audio->as[find_alternatesetting - 1];
- u8 target_ep = as_t->ep;
- u8 ep_interval = as_t->ep_Interval;
- as_t->host_ep = host_ep;
- usb_set_interface(host_dev, audio->interface_num, find_alternatesetting); //interface Alternatesetting
- usb_audio_sampling_frequency_control(host_dev, target_ep, sample_rate);//设置采样率
- //设置音量
- /* usb_audio_volume_control(host_dev, 6, 1, vol_convert(5)); */
- /* usb_audio_volume_control(host_dev, 6, 2, vol_convert(5)); */
- log_info("H2D ep: %x --> %x interval: %d", host_ep, target_ep, ep_interval);
- usb_h_set_ep_isr(host_dev, host_ep, usb_audio_tx_isr, host_dev);
- usb_h_ep_config(usb_id, host_ep, USB_ENDPOINT_XFER_ISOC, 1, ep_interval, ep_buffer, sizeof(ep_out_dma_buf));
- task_create(audio_play_task, host_dev, "uac_play");
- }
- void usb_audio_stop_play(const usb_dev usb_id)
- {
- const struct usb_host_device *host_dev = host_id2device(usb_id);
- usb_h_set_ep_isr(NULL, 0, NULL, NULL);
- __this->player.put_buf(NULL, 0);
- __this->player.Cur_AlternateSetting = 0;
- __this->player.sample_rate = 0;
- __this->player.src_channel = 0;
- if (__this->player.usb_audio_play_buf) {
- free(__this->player.usb_audio_play_buf);
- __this->player.usb_audio_play_buf = NULL;
- }
- if (__this->player.usb_audio_play_buf2) {
- free(__this->player.usb_audio_play_buf2);
- __this->player.usb_audio_play_buf2 = NULL;
- }
- if (__this->player.send_buf) {
- free(__this->player.send_buf);
- __this->player.send_buf = NULL;
- }
- printf("\n[ debug ]--func=%s line=%d\n", __func__, __LINE__);
- task_kill("uac_play");
- printf("\n[ debug ]--func=%s line=%d\n", __func__, __LINE__);
- }
- void usb_audio_pause_play(void)
- {
- __this->player.play_state = AUDIO_PLAY_PAUSE;
- }
- void usb_audio_resume_play(void)
- {
- const struct usb_host_device *host_dev = host_id2device(__this->usb_id);
- struct audio_device_t *audio = __find_headphone_interface(host_dev);
- struct audio_streaming_t *as_t = &audio->as[__this->player.Cur_AlternateSetting - 1];
- __this->player.play_state = AUDIO_PLAY_START;
- usb_h_ep_write_async(__this->usb_id, as_t->host_ep, as_t->ep_max_packet_size, as_t->ep, NULL, as_t->ep_max_packet_size, USB_ENDPOINT_XFER_ISOC, 1); //重新启动传输
- }
- static u32 record_vol_convert(u16 v)
- {
- //固定音量表,更换声卡需要修改音量表
- const u16 vol_table[] = {
- //0-100
- 0xf400,
- 0xf479, 0xf4ee, 0xf560, 0xf5cf, 0xf63a, 0xf6a3, 0xf709, 0xf76c, 0xf7cd, 0xf82b,
- 0xf887, 0xf8e1, 0xf939, 0xf98f, 0xf9e4, 0xfa36, 0xfa87, 0xfad6, 0xfb23, 0xfb6f,
- 0xfbba, 0xfc03, 0xfc4b, 0xfc91, 0xfcd6, 0xfd1a, 0xfd5d, 0xfd9f, 0xfde0, 0xfe1f,
- 0xfe5e, 0xfe9b, 0xfed8, 0xff14, 0xff4e, 0xff88, 0xffc1, 0xfff9, 0x0003, 0x0069,
- 0x00a3, 0x00de, 0x0119, 0x0155, 0x0193, 0x01d1, 0x0210, 0x0251, 0x0292, 0x02d5,
- 0x0318, 0x035d, 0x03a3, 0x03eb, 0x0434, 0x047e, 0x04c9, 0x0517, 0x0565, 0x05b5,
- 0x0607, 0x065b, 0x06b1, 0x0708, 0x0762, 0x07bd, 0x081b, 0x087c, 0x08de, 0x0943,
- 0x09ab, 0x0a16, 0x0a84, 0x0af4, 0x0b69, 0x0be1, 0x0c5c, 0x0cdc, 0x0d60, 0x0de9,
- 0x0e77, 0x0f0a, 0x0fa2, 0x1041, 0x10e7, 0x1195, 0x124a, 0x1308, 0x13d0, 0x14a3,
- 0x1582, 0x166e, 0x176a, 0x1877, 0x1998, 0x1ad0, 0x1c24, 0x1d98, 0x1f33, 0x2100,
- };
- if (v <= 100) {
- return vol_table[v];
- }
- for (int i = 0; i < sizeof(vol_table) / 2; i++) {
- if (v <= vol_table[i]) {
- return i;
- }
- }
- return 0;
- }
- void set_usb_audio_record_volume(u16 vol)
- {
- const struct usb_host_device *host_dev = host_id2device(__this->usb_id);
- u8 featureUnitID = 5;
- usb_audio_volume_control(host_dev, featureUnitID, 0, record_vol_convert(vol));
- }
- static u32 write_file_len = 0;
- static void usb_audio_rx_isr(struct usb_host_device *host_dev, u32 ep)
- {
- u8 buffer[192] = {0};
- u8 *ptr = NULL;
- int rlen, wlen = 0;
- usb_dev usb_id = host_device2id(host_dev);
- struct audio_device_t *audio = NULL;
- struct audio_streaming_t *as_t = NULL;
- audio = __find_microphone_interface(host_dev);
- if (!audio) {
- log_error("no find microphone interface!");
- return;
- }
- if (__this->microphone.record_state != AUDIO_RECORD_START) {
- return;
- }
- as_t = &audio->as[__this->microphone.Cur_AlternateSetting - 1];
- u8 channel = as_t->bNrChannels;
- u32 rx_len = usb_h_ep_read_async(usb_id, ep, as_t->ep, buffer, sizeof(buffer), USB_ENDPOINT_XFER_ISOC, 0);
- /* g_printf("RX:%d\n",rx_len); */
- /* printf_buf(buffer, rx_len); */
- cbuf_write(&__this->microphone.usb_audio_record_cbuf, buffer, rx_len);
- cbuf_write_alloc(&__this->microphone.usb_audio_record_cbuf, &wlen);
- if (wlen == 0) {
- putchar('O');
- if (write_file_len) {
- log_w("write againnnnn\n");
- }
- /* [> printf("R:%d W:%d\n", rx_len,wlen); <] */
- cbuf_read_alloc(&__this->microphone.usb_audio_record_cbuf, &rlen);
- cbuf_read(&__this->microphone.usb_audio_record_cbuf, __this->microphone.usb_audio_record_buf2, rlen);
- write_file_len = rlen;
- os_taskq_post_msg("uac_record", 2, 0x01, rlen);
- /* return; */
- }
- usb_h_ep_read_async(usb_id, ep, as_t->ep, NULL, 0, USB_ENDPOINT_XFER_ISOC, 1); //触发下一个接收中断
- }
- void audio_record_task(void *p)
- {
- log_info(">>> Enter usb audio record task");
- struct usb_host_device *host_dev = (struct usb_host_device *)p;
- const usb_dev usb_id = host_device2id(host_dev);
- u8 *ptr = NULL;
- u32 rlen = 0;
- u32 ret = 0;
- int msg[16];
- struct audio_device_t *audio = NULL;
- audio = __find_microphone_interface(host_dev);
- struct audio_streaming_t *as_t = &audio->as[__this->microphone.Cur_AlternateSetting - 1];
- /* u32 ep_max_packet_size = as_t->ep_max_packet_size; */
- u32 ep_max_packet_size = EP_MAX_PACKET_SIZE;
- log_info("ep max packet : %d\n", ep_max_packet_size);
- u32 usb_audio_buf_size = ep_max_packet_size * 50;
- u32 host_ep = as_t->host_ep;
- u8 target_ep = as_t->ep;
- //分配双缓存
- // 一个缓存写卡的数据,一个用于usb接收
- if (!__this->microphone.usb_audio_record_buf) {
- __this->microphone.usb_audio_record_buf = zalloc(usb_audio_buf_size);
- cbuf_init(&__this->microphone.usb_audio_record_cbuf, __this->microphone.usb_audio_record_buf, usb_audio_buf_size);
- }
- if (!__this->microphone.usb_audio_record_buf2) {
- __this->microphone.usb_audio_record_buf2 = zalloc(usb_audio_buf_size);
- }
- usb_h_ep_read_async(usb_id, host_ep, target_ep, NULL, 0, USB_ENDPOINT_XFER_ISOC, 1); //启动iso
- while (1) {
- ret = os_taskq_pend(NULL, msg, ARRAY_SIZE(msg));
- if (ret == OS_TASKQ) {
- switch (msg[1]) {
- case 0x01:
- ptr = __this->microphone.usb_audio_record_buf2;
- rlen = msg[2];
- putchar('W');
- __this->microphone.get_buf(ptr, rlen);
- write_file_len = 0;
- break;
- }
- }
- }
- }
- void usb_audio_start_record(const usb_dev usb_id, u8 bit_reso, u32 sample_rate)
- {
- log_info(" usb audio record\n");
- const struct usb_host_device *host_dev = host_id2device(usb_id);
- struct audio_device_t *audio = NULL;
- struct audio_streaming_t *as_t = NULL;
- u8 *ep_buffer = ep_in_dma_buf;
- u8 find_alternatesetting = 0;
- audio = __find_microphone_interface(host_dev);
- if (!audio) {
- log_error("no find microphone interface!");
- return;
- }
- for (u8 i = 0; i < ARRAY_SIZE(audio->as); i++) {
- as_t = &audio->as[i];
- if (as_t->bBitResolution == bit_reso) {
- for (u8 j = 0; j < as_t->bSamFreqType; j++) {
- if (as_t->tSamFreq[j] == sample_rate) {
- find_alternatesetting = i + 1;
- break;
- }
- }
- }
- }
- if (!find_alternatesetting) {
- log_e("can not find Alternatesetting,please check bit_reso and sample_rate\n");
- return;
- }
- //端点分配
- u32 host_ep = usb_get_ep_num(usb_id, USB_DIR_IN, USB_ENDPOINT_XFER_ISOC);
- ASSERT(host_ep != -1, "ep not enough");
- __this->usb_id = usb_id;
- host_ep = host_ep | USB_DIR_IN;
- __this->microphone.Cur_AlternateSetting = find_alternatesetting; //选择Alternatesetting
- __this->microphone.sample_rate = sample_rate; //选择采样率
- as_t = &audio->as[find_alternatesetting - 1];
- u8 target_ep = as_t->ep;
- u8 ep_interval = as_t->ep_Interval;
- as_t->host_ep = host_ep;
- usb_set_interface(host_dev, audio->interface_num, find_alternatesetting); //interface 1 Alternatesetting 1
- usb_audio_sampling_frequency_control(host_dev, target_ep, sample_rate);//设置采样率
- //设置音量
- /* usb_audio_volume_control(host_dev, 6, 1, vol_convert(5)); */
- /* usb_audio_volume_control(host_dev, 6, 2, vol_convert(5)); */
- log_info("D2H ep: %x --> %x", target_ep, host_ep);
- usb_h_set_ep_isr(host_dev, host_ep, usb_audio_rx_isr, host_dev);
- usb_h_ep_config(usb_id, host_ep, USB_ENDPOINT_XFER_ISOC, 1, ep_interval, ep_buffer, sizeof(ep_in_dma_buf));
- task_create(audio_record_task, host_dev, "uac_record");
- __this->microphone.record_state = AUDIO_RECORD_START;
- }
- void usb_audio_stop_record(const usb_dev usb_id)
- {
- const struct usb_host_device *host_dev = host_id2device(usb_id);
- usb_h_set_ep_isr(NULL, 0, NULL, NULL);
- __this->microphone.get_buf(NULL, 0);
- __this->microphone.Cur_AlternateSetting = 0;
- __this->microphone.sample_rate = 0;
- if (__this->microphone.usb_audio_record_buf) {
- free(__this->microphone.usb_audio_record_buf);
- __this->microphone.usb_audio_record_buf = NULL;
- }
- if (__this->microphone.usb_audio_record_buf2) {
- free(__this->microphone.usb_audio_record_buf2);
- __this->microphone.usb_audio_record_buf2 = NULL;
- }
- printf("\n[ debug ]--func=%s line=%d\n", __func__, __LINE__);
- task_kill("uac_record");
- printf("\n[ debug ]--func=%s line=%d\n", __func__, __LINE__);
- }
- void usb_audio_pause_record(void)
- {
- __this->microphone.record_state = AUDIO_RECORD_PAUSE;
- }
- void usb_audio_resume_record(void)
- {
- const struct usb_host_device *host_dev = host_id2device(__this->usb_id);
- struct audio_device_t *audio = __find_microphone_interface(host_dev);
- struct audio_streaming_t *as_t = &audio->as[__this->microphone.Cur_AlternateSetting - 1];
- __this->microphone.record_state = AUDIO_RECORD_START;
- usb_h_ep_read_async(__this->usb_id, as_t->host_ep, as_t->ep, NULL, 0, USB_ENDPOINT_XFER_ISOC, 1); //重新启动接收
- }
- void usb_audio_start_process(u32 id)
- {
- usb_audio_start_play(id, 1, 16, 48000); //开启headphone
- usb_audio_start_record(id, 16, 48000); //开启microphone
- }
- void usb_audio_stop_process(u32 id)
- {
- usb_audio_stop_play(id);
- usb_audio_stop_record(id);
- }
- static void usb_audio_event_handler(struct sys_event *event, void *priv)
- {
- const char *audio = NULL;
- switch (event->type) {
- case SYS_DEVICE_EVENT:
- if ((u32)event->arg == DEVICE_EVENT_FROM_USB_HOST) {
- if ((event->u.dev.event == DEVICE_EVENT_IN) ||
- (event->u.dev.event == DEVICE_EVENT_CHANGE)) {
- audio = (const char *)event->u.dev.value;
- usb_audio_start_process(audio[5] - '0');
- } else if (event->u.dev.event == DEVICE_EVENT_OUT) {
- log_error("device out %x", event->u.dev.value);
- usb_audio_stop_process(audio[5] - '0');
- }
- break;
- }
- }
- }
- void usb_host_audio_init(int (*put_buf)(void *ptr, u32 len), int *(*get_buf)(void *ptr, u32 len))
- {
- memset(__this, 0, sizeof(struct usb_audio_info));
- __this->player.put_buf = put_buf;
- __this->microphone.get_buf = get_buf;
- register_sys_event_handler(SYS_DEVICE_EVENT, DEVICE_EVENT_FROM_USB_HOST, 2,
- usb_audio_event_handler);
- }
- void usb_host_audio_exit()
- {
- unregister_sys_event_handler(usb_audio_event_handler);
- __this->player.put_buf = NULL;
- __this->microphone.get_buf = NULL;
- }
- #endif
|