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

【C】变速不变调

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

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

完整例子
#include "sami_core.h"

// step 1, create handle
SAMICoreHandle handle;
SAMICoreTimeScalerCreateParameter params;
params.sampleRate = 44100;
params.channels = 2;
int ret = SAMICoreCreateHandleByIdentify(&handle, 
        SAMICoreIdentify::SAMICoreIdentify_TimeScaler, &param);
assert(ret == SAMI_OK);

// step 2, set initial paramters(option)
SAMICoreProperty property;
float scaleRate = 1.2;
property.type = SAMICoreDataType_Float;
property.data = &scaleRate;
property.id = SAMICorePropertyId_TimeScaler_ScaleRate;
property.dataLen = sizeof(float);
ret = SAMICoreSetProperty(handle, SAMICorePropertyId_TimeScaler_ScaleRate, &property);
assert(ret == SAMI_OK);

// setp 3, create input audio block
unsigned block_size = 1024; // n * 1024; such as 1024, 2048, 3072, ...
SAMICoreAudioBuffer in_audio_buffer;
in_audio_buffer.number_channels = num_channels;
in_audio_buffer.number_samples = block_size;
in_audio_buffer.data = new float *[num_channels];

for(int c = 0; c < int(num_channels); ++c){
    in_audio_buffer.data[c] = new float[block_size];
}

SAMICoreBlock in_block;
in_block.dataType = SAMICoreDataType::SAMICoreDataType_AudioBuffer;
in_block.numberAudioData = 1;
in_block.audioData = &in_audio_buffer;

SAMICoreBlock out_block;
unsigned expected_out_number_samples = block_size * scaleRate;

// step 4, process block by block
for(;hasAudioSamples();)
{
    copySamplesToInputBuffer(in_audio_buffer);
    int ret = SAMICoreProcess(handle, &in_block, &out_block);
    assert(ret == SAMI_OK);

    doSomethingAfterProcess(out_audio_buffer);

    for(int c = 0; c < int(num_channels); ++c){
        delete [] out_block.audioData[c];
    }
    delete [] out_block.audioData;
}

// step 5, remember release resource
ret = SAMICoreDestroyHandle(handle);
for(int c = 0; c < int(num_channels); ++c){
    delete [] in_audio_buffer.data[c];
}

delete [] in_audio_buffer.data;
使用步骤

一、创建算法句柄

通过 processor identity 创建。这种情况用 SAMICoreIdentify:: SAMICorePropertyId_TimeScaler_ScaleRate 并传入SAMICoreTimeScalerCreateParameter进行创建。

SAMICoreHandle handle;
SAMICoreTimeScalerCreateParameter params;
params.sampleRate = 44100;
params.channels = 2;
int ret = SAMICoreCreateHandleByIdentify(&handle, 
        SAMICoreIdentify::SAMICoreIdentify_TimeScaler, ¶ms);
assert(ret == SAMI_OK);

二、设置参数

SAMICoreProperty property;
float scaleRate = 1.2;
property.type = SAMICoreDataType_Float;
property.data = &scaleRate;
property.id = SAMICorePropertyId_TimeScaler_ScaleRate;
property.dataLen = sizeof(float);
ret = SAMICoreSetProperty(handle, SAMICorePropertyId_TimeScaler_ScaleRate, &property);
assert(ret == SAMI_OK);

三、创建 SAMICoreBlock 用于存放输入与输出数据

SAMICoreAudioBuffer,用于存放音频数据,它仅支持Planar-Float 类型数据。更多关于音频数据格式请参看名词解释一节
SAMICoreBlock,用于存放需要处理的数据。

// setp 4, create input audio block
unsigned block_size = 1024; // n * 1024; such as 1024, 2048, 3072, ...
SAMICoreAudioBuffer in_audio_buffer;
in_audio_buffer.number_channels = num_channels;
in_audio_buffer.number_samples = block_size;
in_audio_buffer.data = new float *[num_channels];

for(int c = 0; c < int(num_channels); ++c){
 in_audio_buffer.data[c] = new float[block_size];
}

SAMICoreBlock in_block;
in_block.dataType = SAMICoreDataType::SAMICoreDataType_AudioBuffer;
in_block.numberAudioData = 1;
in_block.audioData = &in_audio_buffer;

SAMICoreBlock out_block;
unsigned expected_out_number_samples = block_size * scaleRate;

四、处理音频

拷贝数据进行处理

将待处理的音频数据拷贝到 in_audio_buffer 中,经过 SAMICoreProcess 处理后,结果将拷贝至 out_audio_buffer 中。

// step 5, process block by block
for(;hasAudioSamples();)
{
    copySamplesToInputBuffer(in_audio_buffer);
    int ret = SAMICoreProcess(handle, &in_block, &out_block);
    assert(ret == SAMI_OK);

    doSomethingAfterProcess(out_audio_buffer);

    for(int c = 0; c < int(num_channels); ++c){
        delete [] out_block.audioData[c];
    }
    delete [] out_block.audioData;
}

五、释放资源

ret = SAMICoreDestroyHandle(handle);

此外,还要注意音频数据数据的内存释放(如果有)。例如:

for(int c = 0; c < int(num_channels); ++c){
    delete [] in_audio_buffer.data[c];
}

delete [] in_audio_buffer.data;