#pragma once #include #include #include #include "agc.h" // #ifndef min // #define min(A, B) ((A) < (B) ? (A) : (B)) // #endif inline int vad_frame_process(void *state, int16_t *buffer, int frame_size) { VadEnergy *st = (VadEnergy *)state; int i, VAD_amp = 0, buf_mean = 0; for (i = 0; i < frame_size; i++) { buf_mean += buffer[i]; } buf_mean = buf_mean / frame_size; for (i = 0; i < frame_size; i++) { VAD_amp = VAD_amp + abs(buffer[i] - buf_mean); } VAD_amp = VAD_amp / frame_size; if (st->VAD == 0) { if (VAD_amp > st->amth) { st->specnt = st->specnt + 1; if (st->specnt >= st->sil2spe) { st->VAD = 1; st->silcnt = 0; } } else { st->specnt = 0; st->silcnt++; } } else { if (VAD_amp < st->amth) { st->silcnt = st->silcnt + 1; if (st->silcnt >= st->spe2sil) { st->VAD = 0; } } else { st->silcnt = 0; st->specnt = 0; } } return 0; } inline void* agc_init(uint32_t sampleRate, int16_t agcMode, int gaindb, int tlevel) { WebRtcAgcConfig agcConfig; agcConfig.compressionGaindB = gaindb; // default 9 dB agcConfig.limiterEnable = 1; // default kAgcTrue (on) agcConfig.targetLevelDbfs = tlevel; // default 3 (-3 dBOv) int minLevel = 0; int maxLevel = 255; void *agcInst = WebRtcAgc_Create(); if (agcInst == NULL) return 0; int status = WebRtcAgc_Init(agcInst, minLevel, maxLevel, agcMode, sampleRate); if (status != 0) { printf("WebRtcAgc_Init fail\n"); WebRtcAgc_Free(agcInst); return 0; } status = WebRtcAgc_set_config(agcInst, agcConfig); if (status != 0) { printf("WebRtcAgc_set_config fail\n"); WebRtcAgc_Free(agcInst); return 0; } return agcInst; } inline void agc_destory(void *agcInst) { WebRtcAgc_Free(agcInst); } inline int agc_sample_process(void *agcInst, int16_t *in_buffer, int16_t *out_buffer, uint32_t sampleRate, uint32_t in_buffer_len) { int i; LegacyAgc *stt = (LegacyAgc *)agcInst; if (in_buffer == NULL || in_buffer_len < 160) return -1; int samples = std::min(160, (int)sampleRate / 100); if (samples == 0) return -1; int16_t *input = in_buffer; size_t num_bands = 1; int inMicLevel, outMicLevel = -1; int16_t *out16 = out_buffer; uint8_t saturationWarning = 1; int16_t echo = 0; int nAgcRet = 0; int time , process_len; time = in_buffer_len / samples; process_len = samples * time; for (i = 0; i < time; i++) { inMicLevel = 127; vad_frame_process(&stt->vad_energy, input, samples); if (stt->agcMode == kAgcModeAdaptiveDigital && stt->vad_energy.VAD == 1) { if (WebRtcAgc_VirtualMic(stt, (int16_t *const *)&input, num_bands, samples, inMicLevel, &outMicLevel)) { return -1; } nAgcRet = WebRtcAgc_Process(stt, (int16_t *const *)&input, num_bands, samples, (int16_t *const *)&out16, outMicLevel, &outMicLevel, echo, &saturationWarning); } else if (stt->agcMode == kAgcModeFixedDigital && stt->vad_energy.VAD == 1) { nAgcRet = WebRtcAgc_Process(stt, (int16_t *const *)&input, num_bands, samples, (int16_t *const *)&out16, inMicLevel, &outMicLevel, echo, &saturationWarning); } else { memcpy(out16, input, samples * sizeof(int16_t)); } if (nAgcRet != 0) { printf("failed in Agc_Process\n"); return -1; } input += samples; out16 += samples; } return process_len; } inline int agc_process(void *agcInst, int16_t *in, int16_t *out, uint32_t sampleRate, uint32_t frame_size) { int i, process_len = 0; LegacyAgc *st = (LegacyAgc *)agcInst; size_t samplesCount; size_t samples = std::min(160, (int)sampleRate / 100); if (samples == 0) return -1; st->bufferAgc.frame_size = frame_size; memcpy(&st->bufferAgc.buffer_in[st->bufferAgc.in_uselen], in, sizeof(int16_t) * frame_size); st->bufferAgc.in_uselen += frame_size; process_len = agc_sample_process(agcInst, st->bufferAgc.buffer_in, &st->bufferAgc.buffer_out[st->bufferAgc.out_uselen], sampleRate, st->bufferAgc.in_uselen); if (process_len > 0) { memcpy(st->bufferAgc.buffer_in, &st->bufferAgc.buffer_in[process_len], sizeof(int16_t) * (st->bufferAgc.in_uselen - process_len)); st->bufferAgc.in_uselen -= process_len; st->bufferAgc.out_uselen += process_len; } if (st->bufferAgc.out_uselen >= frame_size) { memcpy(out, st->bufferAgc.buffer_out, sizeof(int16_t) * frame_size); memcpy(st->bufferAgc.buffer_out, &st->bufferAgc.buffer_out[frame_size], sizeof(int16_t) * (st->bufferAgc.out_uselen - frame_size)); st->bufferAgc.out_uselen -= frame_size; } return 0; }