SAMICore_CreateParameter *createParameter = [[SAMICore_CreateParameter alloc] init]; createParameter.sampleRate = sample_rate; createParameter.maxBlockSize = block_size; createParameter.numChannel = 2; int ret = 0; SAMICore *handle = [[SAMICore alloc] initWithIdentify:SAMICore_Identify_LoudNorm param:createParameter result:&ret]; if(ret != SAMI_OK) return NO;
parameter.maxBlockSize:表示每一次处理单个通道的最大sample数
将 source_lufs(源文件响度) 、source_peak(源文件峰值) (参考响度检测和【C】响度检测)和 target_lufs(目标响度) 参数组成对象,通过 SAMICoreSetProperty 设置参数。
target_lufs(默认值-16dB),(-24到-12,建议实验值为-12,-16,-20)
source_lufs(默认值0dB),(-inf:输入为零数据时,-70 - 0:正常范围)
source_peak(默认值99),(0到1,部分歌曲可能大于1,截取到1)
SAMICore_LoudNormProperty *Loudnorm_property = [[SAMICore_LoudNormProperty alloc] init]; Loudnorm_property.source_lufs = 0; Loudnorm_property.source_peak = 99; Loudnorm_property.target_lufs = -16; SAMICore_Property *core_property = [[SAMICore_Property alloc] init]; core_property.id = SAMICore_PropertyId_Processor_Loudnorm; core_property.data = Loudnorm_property; core_property.writable = 0; core_property.type = SAMICore_DataType_LoudNorm; SAMICore_PropertyId property_id = SAMICore_PropertyId_Processor_Loudnorm; int ret = [handle_ setProperty:core_property withId:property_id]; if(ret != SAMI_OK) return NO;
SAMICore_AudioBuffer *in_audio_buffer = [[SAMICore_AudioBuffer alloc] initWithNumberSamples:pre_define_block_size numberChannels:num_channels isInterleave:false]; SAMICore_AudioBuffer *out_audio_buffer = [[SAMICore_AudioBuffer alloc] initWithNumberSamples:pre_define_block_size numberChannels:num_channels isInterleave:false]; 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;
numberChannels : 需要跟创建handle设置的一致
numberSamples:每一个处理的实际帧数,要求 numberSamples<= parameter.maxBlockSize
for(int inx = 0; inx + pre_define_block_size < (int)num_frames;) { // build in_block for(auto c = 0; c < num_channels; ++c) { std::copy_n(in_samples[c].data() + inx, pre_define_block_size, ((float**)in_audio_buffer.data)[c]); } result = [sami_core_handle processWithInBlock:in_block outBlock:out_block]; if(result != SAMI_OK) { std::cerr << "process error: " << result; exit(-1); } // write output block to file audio_encoder->writePlanarData((float**)out_audio_buffer.data, num_channels, pre_define_block_size); inx += pre_define_block_size; }
注意检查 SAMICoreProcess 函数的返回值,处理输入不正确或者内部处理错误都会有返回值,错误码可以查看错误检查一节
sami_core_handle = nil;