音效初始化过程内部进行一些buffer的申请。
SAMICore_BinaryContextCreateParameter *create_param = [[SAMICore_BinaryContextCreateParameter alloc] init]; create_param.sampleRate = sample_rate; create_param.numChannel = num_channels; create_param.maxBlockSize = block_size; create_param.type = SAMICore_BinaryType::SAMICore_BinaryTypeFile; create_param.data = (void*)res_path.c_str(); int ret = 0; SAMICore *sami_core_handle = [[SAMICore alloc] initWithIdentify:SAMICore_Identify_Processor_ContextWithBinaryRes param:create_param result:&ret]; if(ret != SAMI_OK) { std::cerr << "create handler failed: " << ret; exit(-1); }
//初始化处理buffer SAMICore_AudioBuffer *in_audio_buffer = [[SAMICore_AudioBuffer alloc] init]; in_audio_buffer.numberChannels = num_channels; in_audio_buffer.numberSamples = 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 = 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[block_size]; ((float**)out_audio_buffer.data)[c] = new float[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;
for(; inx + block_size < (int)num_frames;) { for(auto c = 0u; c < num_channels; ++c) { std::copy_n(in_samples[c].data() + inx, block_size, ((float**)in_audio_buffer.data)[c]); } ret = [sami_core_handle processWithInBlock:in_block outBlock:out_block]; if(ret != SAMI_OK) { std::cerr << "ret: " << ret << std::endl; } inx += block_size; }
预置音效的使用场景一般是在k歌场景,需要实时更新配置,sdk提供了动态更新的接口,接口保证了线程安全,可在不同于process的线程更新,并且内部做了平滑处理。
SAMICore_BinaryContextUpdateParameter *updateParameter = [[SAMICore_BinaryContextUpdateParameter alloc] init]; updateParameter.type = SAMICore_BinaryTypeFile; updateParameter.data = (void*)another_res_path.c_str(); SAMICore_Property* update_property = [[SAMICore_Property alloc] init]; update_property.data = updateParameter; update_property.type = SAMICore_DataType_ResourceParameter; ret = [sami_core_handle setProperty:update_property withId:SAMICore_PropertyId_Processor_ContextUpdateFromBinaryFile]; if(ret != SAMI_OK) { cout << "sami_core update data error:" << ret << endl; return 0; } changed_effect = true;
sami_core_handle = nil;