基于wav文件音量的口形同步(Native)

最終更新: 2021年2月17日

概述

Cubism SDK for Native范例使用口形同步 功能提供基于wav文件音频数据的音量实时移动口形同步的功能。
此范例由Cubism 4 SDK for Native R2或更高版本提供。

使用方法

准备

在.json文件中写入与动态关联的wav文件。请指定各动态的“Sound”键对应的wav文件路径。

{
	・
	・
	・
		"Motions": {
			"Idle": [
			  {"File":"motions/haru_g_idle.motion3.json" ,"FadeInTime":0.5, "FadeOutTime":0.5, "Sound": "sounds/haru_normal_05.wav"},
			  {"File":"motions/haru_g_m15.motion3.json" ,"FadeInTime":0.5, "FadeOutTime":0.5, "Sound": "sounds/haru_normal_06.wav"}
			],
			"TapBody": [
			  {"File":"motions/haru_g_m06.motion3.json" ,"FadeInTime":0.5, "FadeOutTime":0.5, "Sound": "sounds/haru_normal_01.wav"},
			  {"File":"motions/haru_g_m09.motion3.json" ,"FadeInTime":0.5, "FadeOutTime":0.5, "Sound": "sounds/haru_normal_02.wav"},
			  {"File":"motions/haru_g_m20.motion3.json" ,"FadeInTime":0.5, "FadeOutTime":0.5, "Sound": "sounds/haru_normal_03.wav"},
			  {"File":"motions/haru_g_m26.motion3.json" ,"FadeInTime":0.5, "FadeOutTime":0.5, "Sound": "sounds/haru_normal_04.wav"}
			]
		},
	・
	・
	・
}

请将wav文件置入上面指定的位置。如果wav文件路径不正确,将不会进行口形同步。

音量采集开始

在范例中,信息是通过LAppWavFileHandler类从wav文件中获取的。
执行LAppWavFileHandler::Start()后,从wav文件中导入音频数据,原始化口形同步所需的内部状态。

CubismMotionQueueEntryHandle LAppModel::StartMotion(const csmChar* group, csmInt32 no, csmInt32 priority, ACubismMotion::FinishedMotionCallback onFinishedMotionHandler)
{
    ・
    ・
    ・
    //voice
    csmString voice = _modelSetting->GetMotionSoundFileName(group, no);
    if (strcmp(voice.GetRawString(), "") != 0)
    {
        csmString path = voice;
        path = _modelHomeDir + path;
        LAppPal::PrintLog("[APP]start lipsync:%s .", path.GetRawString());
        _wavFileHandler.Start(path);
    }
    ・
    ・
    ・ 
}

状态更新和音量获取

执行LAppWavFileHandler::Update()时,测量经过时间对应部分的音量。测量结果的音量可以通过LAppWavFileHandler::GetRms()获得。使用CubismModel::AddParameterValue函数将获取的音量设置为模型中的口形同步值。

在范例中,采集到的音量乘以0.8得到口形同步值。这里,也可以将从声音工具库等获得的音量设置为口形同步值。

void LAppModel::Update()
{
    ・
    ・
    ・
    // 口形同步设置
    if (_lipSync)
    {
        // 实时进行口形同步时,从系统获取音量,输入0~1范围内的值。
        csmFloat32 value = 0.0f;

        // 状态更新/获取RMS值
        _wavFileHandler.Update(deltaTimeSeconds);
        value = _wavFileHandler.GetRms();

        for (csmUint32 i = 0; i < _lipSyncIds.GetSize(); ++i)
        {
            _model->AddParameterValue(_lipSyncIds[i], value, 0.8f);
        }
    }
    ・
    ・
    ・
}

补充

  • 该范例中没有在设备上播放音频的功能。
  • LAppWavFileHandler::GetRms()返回0~1范围内的当前音量值。
    • 音量单位是RMS(均方根)。
    • 计算所有声道音频的平均值。
      • 例如,在立体声音频的情况下,计算包括左右声道的音频的平均值。

限制事项

该范例支持导入以下wav文件。如果导入不支持以下格式的文件,将不会执行口形同步。

  • Microsoft WAV(小端格式)
  • 直线PCM
    • 不支持以μ-raw、ADPCM等编码的Wav。
  • 声道数:单声道/立体声
  • 支持位深:8、16、24bit符号整数
请问这篇文章对您有帮助吗?
关于本报道,敬请提出您的意见及要求。