将音频数据累积到缓冲区,达到阈值时触发处理

实现了音频处理中的 AEC(声学回声消除)和 AES(音频增强)功能,其核心功能是:

  • 数据缓冲管理:将输入的麦克风和扬声器音频数据块累积到缓冲区中
  • 块处理机制:当缓冲区填满预设大小(512 个样本)时触发处理
  • 音频算法调用:调用外部库函数SmarthoAlgo.aec_aes_process进行回声消除和音频增强处理
  • 结果返回:返回处理后的音频数据,如果缓冲区未满则返回 null
public class HandleRawData {
    // 说明:数组长度,取决于算法需要的数据长度。
    // 为什么是512?
    // 因为采样率是8k,512/8000 = 0.064s,即64ms,64ms是aec+aes算法处理的时间间隔;通常要求在100ms以内。
    // 现在采样率是4k,512/4000 = 0.128s,即128ms。
    // 虽然,间隔超过了100ms,但是c++算法中还是按512处理的,避免算法改动太大,所以这里未改。


    private final int AEC_AES_LENGTH = 512;
    private short[] micBuffer = new short[AEC_AES_LENGTH];
    private short[] spkBuffer = new short[AEC_AES_LENGTH];
    private int bufferIndex = 0;

    /**
     * 处理音频数据(必须处理完整块512样本)
     *
     * @param micData      麦克风输入数据
     * @param spkData      扬声器输入数据(必须与micData长度相同)
     * @param aecAesHandle 算法句柄
     * @return 处理后的AES数据(如果输入不足512样本且是第一次调用,返回null)
     */
    public short[] aec_aes_ProcessData(short[] micData, short[] spkData, long aecAesHandle) {
        // 输入验证
        if (micData == null || spkData == null || micData.length != spkData.length) {
            return null;
        }

        int remainingInput = micData.length;
        int inputOffset = 0;

        while (remainingInput > 0) {
            // 计算本次可以填充的样本数
            int samplesToFill = Math.min(remainingInput, AEC_AES_LENGTH - bufferIndex);

            // 填充缓冲区
            System.arraycopy(micData, inputOffset, micBuffer, bufferIndex, samplesToFill);
            System.arraycopy(spkData, inputOffset, spkBuffer, bufferIndex, samplesToFill);

            // 更新索引和剩余输入
            bufferIndex += samplesToFill;
            inputOffset += samplesToFill;
            remainingInput -= samplesToFill;

            // 如果缓冲区已满,处理数据
            if (bufferIndex == AEC_AES_LENGTH) {
                short[] aecOut = new short[AEC_AES_LENGTH];
                short[] aesOut = new short[AEC_AES_LENGTH];

                // 处理数据
                SmarthoAlgo.aec_aes_process(aecAesHandle, micBuffer, spkBuffer, aecOut, aesOut);

                // 重置缓冲区
                bufferIndex = 0;

                // 返回处理结果(完整块的结果)
                return aesOut;
            }
        }

        // 如果输入数据不足512且是第一次调用(bufferIndex=0),返回null
        // 如果输入数据不足512但不是第一次调用(bufferIndex > 0),继续填充缓冲区
        // 下次调用会继续处理
        return null;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值