| 连续签到天数:1天 | | 签到总天数:1天 | | 签到总奖励:5金币 |
|
我正在制作ESP32蓝牙播放器,根据Github开源的解码器已经在ESP32上成功跑通了AAC、aptX[HD]、LDAC,然后我试图在ESP32上实现LHDCV5,但是注意到目前似乎没人开源过LHDCV5的解码器,我只找到了BES的SDK(包含LHDCV5静态库“.a”文件及对应的api头文件)、AOSP的LHDCV5解码器(缺lhdcv5_util_dec.c文件)、小米手机内置的LHDCV5动态库“.so”文件。
因为我不懂逆向,同时注意到AOSP和ESP32的bluedroid架构几乎一样,且其依赖的外部库只是缺一个源文件,所以我从AOSP移植LHDCV5解码器到ESP-IDF,目前这部分工作已经完成,我将他们开源在Github的liblhdc-collections/tree/main/ESP-IDF/bluedroid;它们包含下列文件:
- └─bluedroid
- ├─api
- │ └─include
- │ esp_a2dp_api.h
- │
- ├─external
- │ └─liblhdcv5dec
- │ │ CMakeLists.txt
- │ │ release_note
- │ │
- │ ├─inc
- │ │ lhdcv5BT_dec.h
- │ │
- │ ├─include
- │ │ lhdcv5_util_dec.h
- │ │
- │ └─src
- │ lhdcv5BT_dec.c
- │ lhdcv5_util_dec.c
- │
- └─stack
- ├─a2dp
- │ a2dp_vendor.c
- │ a2dp_vendor_lhdcv5.c
- │ a2dp_vendor_lhdcv5_decoder.c
- │
- └─include
- └─stack
- a2dp_vendor.h
- a2dp_vendor_lhdcv5.h
- a2dp_vendor_lhdcv5_constants.h
- a2dp_vendor_lhdcv5_decoder.h
- a2dp_vendor_lhdc_constants.h
复制代码
因为AOSP需要使用liblhdcv5外部库,所以移植到IDF的LHDCV5解码器也是,因此我也同步移植了AOSP的LHDCV5外部库,但是正如前面所说,这个外部库缺乏lhdcv5_util_dec.c的实现,因此我依据lhdcv5_util_dec.h中声明的函数和使用的变量逆推了一个lhdcv5_util_dec.c,但是其中的关键部分——LHDCV5解码算法我无法得知,我搜索不到任何与LHDC编码算法相关的文档/代码。
所以我在lhdcv5_util_dec.c的LHDCV5解码函数“int32_t lhdcv5_util_dec_process(uint8_t * pOutBuf, uint8_t * pInput, uint32_t InLen, uint32_t *OutLen)”中调用了正弦发生器进行伪解码,实际输出的是正弦发生器产生的标准音。对于这个liblhdcv5dec,我也将其开源在Github:liblhdcv5dec,完整内容可以在这个Github仓库看到,其中的伪解码函数如下:
- int32_t lhdcv5_util_dec_process(uint8_t * pOutBuf, uint8_t * pInput, uint32_t InLen, uint32_t *OutLen)
- {
- if (!decoder_initialized)
- return LHDCV5_UTIL_DEC_ERROR_NO_INIT;
- if (!pInput || !pOutBuf || !OutLen)
- return LHDCV5_UTIL_DEC_ERROR_PARAM;
- // 计算样本大小和帧样本数 - 使用输出位深
- uint32_t sample_bytes = (g_output_bit_per_sample + 7) / 8;
- uint32_t frame_samples = 256; // LHDC V5典型每声道样本数
- uint32_t channels = (g_channel_type == LHDC_OUTPUT_STEREO) ? 2 : 1;
- *OutLen = frame_samples * sample_bytes * channels;
- // 生成32位正弦波PCM数据,然后根据需要转换
- int32_t *out_32 = (int32_t *)pOutBuf;
- int16_t *out_16 = (int16_t *)pOutBuf;
- uint8_t *out_24 = pOutBuf; // 24位特殊处理,存储为3字节
- for (uint32_t i = 0; i < frame_samples; i++) {
- // 生成左声道样本(始终生成32位样本)
- int32_t sample_32 = generate_sine_sample(g_sampleRate, 32);
-
- // 根据输出位深转换
- switch (g_output_bit_per_sample) {
- case 16:
- // 从32位转换到16位
- int16_t sample_16 = (int16_t)(sample_32 >> 16);
- out_16[i * 2] = sample_16; // 左声道
- if (channels == 2) {
- // 右声道使用稍作修改的样本,制造立体声效果
- out_16[i * 2 + 1] = (int16_t)(sample_16 * 0.9f); // 右声道
- }
- break;
-
- case 24:
- // 从32位转换到24位
- int32_t sample_24 = sample_32 >> 8; // 右移8位得到24位
- // 正确处理有符号24位样本
- int32_t clamped_sample = sample_24;
- // 确保样本在24位范围内
- if (clamped_sample > 8388607) clamped_sample = 8388607;
- if (clamped_sample < -8388608) clamped_sample = -8388608;
-
- // 转换为无符号偏移量(+8388608)以便正确存储符号位
- uint32_t u_sample = clamped_sample + 8388608;
-
- out_24[i * 6] = u_sample & 0xFF; // 低8位
- out_24[i * 6 + 1] = (u_sample >> 8) & 0xFF; // 中8位
- out_24[i * 6 + 2] = (u_sample >> 16) & 0xFF; // 高8位
-
- if (channels == 2) {
- int32_t right_sample = (int32_t)(sample_24 * 0.9f);
- int32_t clamped_right = right_sample;
- if (clamped_right > 8388607) clamped_right = 8388607;
- if (clamped_right < -8388608) clamped_right = -8388608;
-
- uint32_t u_right = clamped_right + 8388608;
- out_24[i * 6 + 3] = u_right & 0xFF;
- out_24[i * 6 + 4] = (u_right >> 8) & 0xFF;
- out_24[i * 6 + 5] = (u_right >> 16) & 0xFF;
- }
- break;
-
- case 32:
- out_32[i * 2] = sample_32; // 左声道
- if (channels == 2) {
- out_32[i * 2 + 1] = (int32_t)(sample_32 * 0.9f); // 右声道
- }
- break;
- }
- }
- LOG_DEBUG("%s: Generated sine wave frame - %u samples, %u bits, %u channels, %u bytes",
- __func__, frame_samples, g_bitPerSample, channels, *OutLen);
- return LHDCV5_UTIL_DEC_SUCCESS;
- }
复制代码
目前在ESP32上已经可以运行伪解码的LHDCV5了,小米14连接ESP32后,以LHDCV5协商,手机播放音乐时,ESP32上听到的是正弦发生器的标准音。我想知道我该如何获取LHDCV5的解码算法源码?官方肯定是不行了,早段时间发过邮件没理我。注意到论坛的大神@O11111和@O2C14已经在这方面有进展,非常佩服,也注意到有人说还有别的大神也实现了,但我不知道怎么联系,我是新来的小白一个,不知大神们可否与我交流一下,我挺想在ESP32等设备上实现真正的LHDCV5解码,可以有偿(不是太贵都能接受),不白拿资料 Github的sprlightning可联系到我,还有我Q是3397935446
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册 
×
|