创建handle,具体音效的Identify可以在单音效处理器介绍中查看
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 = 2; int result = 0; SAMICore *sami_core_handle = [[SAMICore alloc] initWithIdentify:SAMICore_Identify_Processor_TimeDomainPitchShifter param:create_param result:&result]; if(result != SAMI_OK) { std::cerr << "create handler failed: " << result; exit(-1); }
参数的设置可以分为两种情况:
在主线程中创建了 handle,但音频线程还 未启动 音频处理时。这种情况下,调用 离线参数 设置接口。
音频线程 已经启动 ,并正在进行音频处理时。这种情况下,调用 实时参数 设置接口
SAMICore_Property* offline_property = [[SAMICore_Property alloc] init]; NSString* json_param = [[NSString alloc] initWithUTF8String:"{\"parameters\": {\"Pitch Ratio\": 2} }"]; offline_property.type = SAMICore_DataType_String; offline_property.id = SAMICore_PropertyId_Processor_SetParametersOffline; offline_property.data = json_param; result = [sami_core_handle setProperty:offline_property withId:SAMICore_PropertyId_Processor_SetParametersOffline]; if(result != SAMI_OK) { std::cerr << "set property failed: " << result; exit(-1); }
SAMICore_ContextParameterEvent* param_event = [[SAMICore_ContextParameterEvent alloc] init]; param_event.parameterIndex = SAMICore_ProcessorTimeDomainPitchShifterParameter::SAMICore_TimeDomainPitchShifter_Pitch_Ratio; param_event.plainValue = 2.0f; SAMICore_Property* update_property = [[SAMICore_Property alloc] init]; update_property.data = param_event; update_property.type = SAMICore_DataType_ParameterEvent; result = [sami_core_handle setProperty:update_property withId:SAMICore_PropertyId_Processor_ContextEmplaceParameterEventNowWithPlainValue]; if(result != SAMI_OK) { std::cerr << "set property failed: " << result; exit(-1); }
SAMICoreContextParameterEvent 描述了参数的位置和值 ,可以在SAMICoreEffectParam.h找到参数和范围,其中
parameterIndex,参数下标,
plainValue,参数值,有三种数据类型:float/bool/choice
以“TimeDomainPitchShifter”为例:
数据类型 | 内容 |
---|---|
Float | 直接填写需要的数值 |
Bool | 设置为0表示选择false,设置为1表示选择true |
Choice | "Interpolation Mode" 的 0 表示 "Linear",1 表示 "Lagrange4",以此类推 |
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;
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; }
in_audio_buffer = nil; out_audio_buffer = nil; in_block = nil; out_block = nil; sami_core_handle = nil;