You need to enable JavaScript to run this app.
导航

【OC】非流式节拍检测

最近更新时间2023.03.16 11:40:14

首次发布时间2023.03.16 11:40:14

实现

1. 创建handle 与 加载模型

非流式节拍检测的跟其他功能的差异点在于处理必须一次性把所有要处理的数据送进去之后再获取结果,所以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);
}

2. 初始化buffer

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;

3. 处理数据并获取结果

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;

4. 释放handle

sami_core_handle = nil;