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

【Java】单音效处理器

最近更新时间2024.02.28 19:12:49

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

使用步骤

1. 创建handle

音效相关的跟其他3A的处理有点差异,需要prepare的过程,内部进行一些buffer的申请。

  1. 创建handle,具体音效的Identify可以在上面的表格中查看
int ret = samiCore.SAMICoreCreateHandleByIdentify(SAMICoreIdentify.SAMICoreIdentify_Processor_TimeDomainPitchShifter,null);
if (ret != SAMICoreCode.SAMI_OK) {
    System.out.println("SAMICoreCreateHandleByIdentify failed, ret " + ret);
    return ret;
}else{
    createHandleDone = true;
}
  1. prepare
SAMICoreProcessorPrepareParameter prepareParameter = new SAMICoreProcessorPrepareParameter();
prepareParameter.blockSize = max_block_size;
prepareParameter.sampleRate = sampleRate;
prepareParameter.numChannel = numChannel;
SAMICoreProperty property = new SAMICoreProperty();
property.id = SAMICorePropertyId.SAMICorePropertyID_Processor_Prepare;
property.type = SAMICoreDataType.SAMICoreDataType_ContextPrepareParameter;
property.dataObjectArray = new Object[1];
property.dataObjectArray[0] = prepareParameter;
property.dataArrayLen = 1;
ret = samiCore.SAMICoreSetProperty(SAMICorePropertyId.SAMICorePropertyID_Processor_Prepare, property);
if (ret != SAMICoreCode.SAMI_OK) {
    System.out.println("SAMICorePropertyID_Processor_ContextPrepare failed, ret " + ret);
    return ret;
}

2. 设置参数

参数的设置可以分为两种情况:

  1. 在主线程中创建了 handle,但音频线程还 未启动 音频处理时。这种情况下,调用 离线参数 设置接口。

  2. 音频线程 已经启动 ,并正在进行音频处理时。这种情况下,调用 实时参数 设置接口

离线设置参数

SAMICoreProperty offline_property = new SAMICoreProperty();
String param_str = "{\"parameters\": {\"Pitch Ratio\": 0.5} }";
offline_property.type = SAMICoreDataType.SAMICoreDataType_String;
offline_property.id = SAMICorePropertyId.SAMICorePropertyID_Processor_SetParametersOffline;
offline_property.dataObjectArray = new Object[1];
offline_property.dataObjectArray[0] = param_str;
offline_property.dataArrayLen = 1;
ret = samiCore.SAMICoreSetProperty(SAMICorePropertyId.SAMICorePropertyID_Processor_SetParametersOffline, offline_property);
if (ret != SAMICoreCode.SAMI_OK) {
    System.out.println("SAMICorePropertyID_Processor_SetParametersOffline failed, ret " + ret);
    return ret;
}

实时设置参数

SAMICoreContextParameterEvent param_event = new SAMICoreContextParameterEvent();
param_event.parameterIndex = SAMICoreProcessorTimeDomainPitchShifterParameter.TimeDomainPitchShifter_Pitch_Ratio.getValue();
param_event.plainValue = 2.0f;

SAMICoreProperty update_property = new SAMICoreProperty();
update_property.dataObjectArray  =  new Object[1];
update_property.dataObjectArray[0] = param_event;
update_property.dataArrayLen = 1;
update_property.type = SAMICoreDataType.SAMICoreDataType_ParameterEvent;
update_property.id = SAMICorePropertyId.SAMICorePropertyID_Processor_ContextEmplaceParameterEventNowWithPlainValue;

int ret = samiCore.SAMICoreSetProperty(
        SAMICorePropertyId.SAMICorePropertyID_Processor_ContextEmplaceParameterEventNowWithPlainValue,
        update_property);
if(ret != SAMICoreCode.SAMI_OK) {
    System.out.println("SAMICorePropertyID_Processor_ContextEmplaceParameterEventNowWithPlainValue failed, ret " + ret);
    return ret;
}

SAMICoreContextParameterEvent 描述了参数的位置和值

  • parameterIndex,参数下标,index可以在对应参数的枚举类中查看

  • plainValue,参数值,有三种数据类型:float/bool/choice,processor列表

以“TimeDomainPitchShifter”为例:

数据类型内容
Float直接填写需要的数值
Bool0 表示 false,1 表示 true
Choice"Interpolation Mode" 的 0 表示 "Linear",1 表示 "Lagrange4",以此类推
  1. 初始化buffer

inBlock = new SAMICoreBlock();
outBlock = new SAMICoreBlock();

inBlock.dataType = SAMICoreDataType.SAMICoreDataType_AudioBuffer;
inAudioBuffer = new SAMICoreAudioBuffer();
inAudioBuffer.numberChannels = numChannel;
inAudioBuffer.numberSamples = max_block_size;
inAudioBuffer.data = new float[inAudioBuffer.numberChannels][inAudioBuffer.numberSamples];
inBlock.audioData = new SAMICoreAudioBuffer[1];
inBlock.audioData[0] = inAudioBuffer;

outBlock.dataType = SAMICoreDataType.SAMICoreDataType_AudioBuffer;
outAudioBuffer = new SAMICoreAudioBuffer();
outAudioBuffer.numberChannels = numChannel;
outAudioBuffer.numberSamples = max_block_size;
outAudioBuffer.data = new float[outAudioBuffer.numberChannels][outAudioBuffer.numberSamples];
outBlock.audioData = new SAMICoreAudioBuffer[1];
outBlock.audioData[0] = outAudioBuffer;
  1. 处理数据

for (int numSamples = 0; numSamples < totalNumSamples;) {
    if((numSamples + inAudioBuffer.numberSamples) > totalNumSamples) {
        inAudioBuffer.numberSamples = totalNumSamples - numSamples;
        outAudioBuffer.numberSamples = totalNumSamples - numSamples;
    }

    for (int i = 0; i < inAudioBuffer.numberChannels; i++) {
        for (int j = 0; j < inAudioBuffer.numberSamples; j++) {
            inAudioBuffer.data[i][j] = in_planar_float_data[i][numSamples + j];
        }
    }

    int ret = samiCore.SAMICoreProcess(inBlock, outBlock);
    if (ret != SAMICoreCode.SAMI_OK) {
        System.out.println("DenoiseV2 process audio data failed, ret " + ret);
        return ret;
    }

    for (int i = 0; i < inAudioBuffer.numberChannels; i++) {
        for (int j = 0; j < inAudioBuffer.numberSamples; j++) {
            out_planar_float_data[i][j+numSamples] = outAudioBuffer.data[i][j];
        }
    }
    // update index
    numSamples = numSamples + inAudioBuffer.numberSamples;
}
  1. 释放handle

if (createHandleDone){
    samiCore.SAMICoreDestroyHandle();
}