非流式节拍检测的跟其他功能的差异点在于处理必须一次性把所有要处理的数据送进去之后再获取结果,所以createParam.maxBlockSize应该是要处理的文件的帧数
SAMICore_CreateParameter *create_param = [[SAMICore_CreateParameter alloc] init]; create_param.sampleRate = sample_rate; create_param.maxBlockSize = num_frames; create_param.modelBuffer = reinterpret_cast<char*>(modelBin.data()); create_param.modelLen = modelBin.size(); create_param.numChannel = num_channels; SAMICore *sami_core_handle = [[SAMICore alloc] initWithIdentify:SAMICore_Identify_Extractor_BeatTrackingOffline param:create_param result:&result]; if(result != SAMI_OK) { std::cerr << "create handler failed: " << result; exit(-1); }
SAMICore_AudioBuffer *in_audio_buffer = [[SAMICore_AudioBuffer alloc] initWithNumberSamples:num_frames 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;
for(auto c = 0; c < num_channels; ++c) { std::copy_n(in_samples[c].data(), num_frames, ((float**)in_audio_buffer.data)[c]); } result = [sami_core_handle processWithInBlock:in_block outBlock:nil]; if(result != SAMI_OK) { std::cerr << "process error: " << result; exit(-1); } // 获取检测结果 SAMICore_Property *samiCoreProperty = [[SAMICore_Property alloc] init]; result = [sami_core_handle getProperty:samiCoreProperty withId:SAMICore_PropertyId_OverallFeatures]; if(result == SAMI_OK && samiCoreProperty.data != nil) { if (samiCoreProperty.type == SAMICore_DataType_FeatureSet) { SAMICore_FeatureSet *dstSet = (SAMICore_FeatureSet*)samiCoreProperty.data; NSArray *set = dstSet.set; for(int i = 0; i < dstSet.numFeatureTypes; ++i) { SAMICore_FeatureArray* featureArray = [dstSet.set objectAtIndex:i]; if(featureArray.featureID == SAMICore_PropertyId_FrameFeature_BEAT_TRACKING || featureArray.featureID == SAMICore_PropertyId_OverallFeature_TRACKING_OFFLINE_OVERALL) { for (unsigned int j = 0; j < featureArray.numFeatures; ++j) { SAMICore_Feature* feature = [featureArray.array objectAtIndex:j]; float timestamp = feature.time; float beat = feature.values[0]; printf("time: %.2f, %d \n", timestamp, (int)beat); } } } dstSet.set = [set copy]; samiCoreProperty.data = dstSet; } } samiCoreProperty = nil;
sami_core_handle = nil;