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以每次传入的块数据为单位进行处理,不同数据块大小处理结果不同
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/1 | 1 |
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;
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;
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; }
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;