You need to enable JavaScript to run this app.
导航
【OC】自动增益
最近更新时间:2023.07.07 11:16:17首次发布时间:2023.03.16 11:40:13
使用步骤

1. 创建handle

SAMICore_CreateParameter *create_param = [[SAMICore_CreateParameter alloc] init];
create_param.sampleRate = sample_rate;
create_param.maxBlockSize = pre_define_block_size;
create_param.modelBuffer = nullptr;
create_param.modelLen = 0;
create_param.numChannel = num_channels;
int ret = 0;
SAMICore *sami_core_handle = [[SAMICore alloc] initWithIdentify:SAMICore_Identify_AGC  param:create_param result:&ret];
if(ret != SAMI_OK) {
    std::cerr << "create handler failed: " << ret;
    exit(-1);
}

maxBlockSize:表示每一次处理单个通道的最大sample数
注:AGC以每次传入的块数据为单位进行处理,不同数据块大小处理结果不同

2. 设置参数

AGC有三种可调节参数,根据需要进行调整

ID含义取值范围默认值
SAMICore_PropertyID_AGC_SetTargetLevel设置最大的音量界限,改变增益不会超过这个值,单位是dbfs,比如默认值为3,即最大音量是-3dbfs[0,100]3
SAMICore_PropertyID_AGC_SetGain设置音频的增益,单位是dbfs,比如默认值为9,即+9dbfs[0, 100]9
SAMICore_PropertyID_AGC_SetEnableLimiter设置是否开启限制器0/11
SAMICore_Property *property = [[SAMICore_Property alloc] init];
property.type = SAMICore_DataType_Float;
property.data = [[NSNumber alloc] initWithFloat:value];
property.id = SAMICore_PropertyId_AGC_SetTargetLevel;
int ret = [handle_ setProperty:property withId:SAMICore_PropertyId_AGC];
if(ret != SAMI_OK) return NO;

3. 初始化buffer

SAMICore_AudioBuffer *in_audio_buffer = [[SAMICore_AudioBuffer alloc] init];
in_audio_buffer.numberChannels = num_channels;
in_audio_buffer.numberSamples = pre_define_block_size;
in_audio_buffer.data = new float*[num_channels];
in_audio_buffer.isInterleave = 0;

SAMICore_AudioBuffer *out_audio_buffer = [[SAMICore_AudioBuffer alloc] init];
out_audio_buffer.numberChannels = num_channels;
out_audio_buffer.numberSamples = pre_define_block_size;
out_audio_buffer.data = new float*[num_channels];
out_audio_buffer.isInterleave = 0;

for(int c = 0; c < int(num_channels); ++c) {
    ((float**)in_audio_buffer.data)[c] = new float[pre_define_block_size];
    ((float**)out_audio_buffer.data)[c] = new float[pre_define_block_size];
}

SAMICore_AudioBlock *in_block = [[SAMICore_AudioBlock alloc] init];
in_block.dataType = SAMICore_DataType_AudioBuffer;
in_block.numberAudioData = 1;
in_block.audioData = in_audio_buffer;

SAMICore_AudioBlock *out_block = [[SAMICore_AudioBlock alloc] init];
out_block.dataType = SAMICore_DataType_AudioBuffer;
out_block.numberAudioData = 1;
out_block.audioData = out_audio_buffer;

4. 处理数据

size_t inx = 0;
while(inx < (size_t)num_frames) {
    int actual_block_size = getNextBlockSize(inx, num_frames, pre_define_block_size);
    in_audio_buffer.numberSamples = actual_block_size;
    out_audio_buffer.numberSamples = actual_block_size;
    for(int i = 0; i < num_channels; i++) {
        memcpy(((float**)in_audio_buffer.data)[i], input_file.samples[i].data() + inx, actual_block_size * sizeof(float));
    }

    ret = [sami_core_handle processWithInBlock:in_block outBlock:out_block];

    SAMICore_AudioBuffer* outBuffer = (__bridge SAMICore_AudioBuffer *)out_block.audioData;
    if(ret != SAMI_OK || outBuffer == nullptr) {
        std::cerr << "process error: " << ret;
        exit(-1);
    }

    // write output block to file
    audio_encoder->writePlanarData((float**)outBuffer.data, outBuffer.numberChannels, actual_block_size);
    
    inx += actual_block_size;
}

5. 释放handle

for(int i = 0; i < num_channels; i++) {
    delete[] ((float**)in_audio_buffer.data)[i];
    ((float**)in_audio_buffer.data)[i] = nullptr;
    delete[] ((float**)out_audio_buffer.data)[i];
    ((float**)out_audio_buffer.data)[i] = nullptr;
}
delete[] (float**)in_audio_buffer.data;
delete[] (float**)out_audio_buffer.data;
sami_core_handle = nil;