iOS 集成文档

最近更新时间:2023-06-26 15:35:11 前往 Coding 编辑

导出文档

语音命令(commands)

要开始在iOS上使用语音命令,我们建议您下载SpeechRecognition

功能介绍

SpeechRecognition 是一个语音命令识别应用程序,演示了如何在iOS上使用PyTorch C++库。该代码是用Objective-C编写。

要求

  • Xcode 12.4 or later
  • iOS 12.0或更高版本
  • iOS Cocoapods LibTorch-Lite 1.13.0.1

集成步骤

1.准备模型

将模型文件speechcommand-demo.ptl保存到SpeechRecognition文件夹。


模型下载地址
https://qpt-dev-voices-1251626569.cos.ap-beijing.myqcloud.com/ican/speechcommand-demo.ptl

2.通过Cocoapods安装LibTorch-Lite

要将PyTorch C++库集成到我们的项目中,只需运行


在Podfile中引用
pod 'LibTorch-Lite', '~>1.13.0'

执行
pod install

然后在XCode中打开SpeechRecognition.xcworkspace,选择一个iOS模拟器并启动它(cmd + R)。如果一切顺利,我们应该在模拟器屏幕上看到录音识别页面。

代码简介

在这一部分中,我们将逐步完成代码。

模型

将模型加载到应用程序中。


NSString *filePath = [[NSBundle mainBundle] pathForResource:@"speechcommand-demo" ofType:@"ptl"];

if (filePath) {
    m_module = [[ForwardModule alloc] initWithFileAtPath:filePath];
    messageLog = [messageLog  stringByAppendingString:@"模型加载成功 \n"];
}else {
    messageLog = [messageLog  stringByAppendingString:@"找不到模型文件!\n"];
}

请注意,ForwardModule类是torch::jit::mobile::Module的Objective-C包装器。


torch::jit::mobile::Module module = torch::jit::_load_for_mobile(filePath.UTF8String);

由于Swift不能直接与C++交谈,必须使用Objective-C类作为桥接器,或者为C++库创建C包装器。为了演示,我们将在这个Objective-C类中包装所有内容。

静音检测

获取音频输入语音流,通过_vad逐帧检测是否静音,如果满足有效的音频条件,就会进行识别

1s 16K采样率 16位 单声道的音频所采集数据大小为  1s -> 16000 * 16 * 1 = 256000bit = 32000 byte  = 16000 short
正常的音频传输为 20ms 一帧,即 20ms -> 640 byte -> 320 short
//检测是否静音
int voice = 0;
voice = [_vad  isVoice:&stateInp.audioBufferI16[buffIndex * 320] sample_rate:16000  length:320];

buffIndex += 1;
if(voice == 1){
    muteTempCount = 0;
    soundCount += 1;
    isContainSpeechBuffer = true;
}else{
    muteTempCount += 1;
    //持续0.5s没有声音,认为当前是 静音 状态 (25: 25帧 -> 25 * 320 short -> 0.5s)
    if(muteTempCount >= 25){
        if(isContainSpeechBuffer){
            //语音最少时长为0.3s认为是有效时长 (16000 * 0.3)
            if(soundCount * 320 >= 16000 * 0.3){
                [self onTranscribe];
            }
        }
        muteTempCount = 0;
        soundCount = 0;
        return;
    }
}

语音命令识别

进行语音命令识别并获得结果。


NSString *result = [self->m_module recognize: self->stateInp.audioBufferF32  bufLength:self->stateInp.n_samples];

recognize方法只是一个Objective-C包装器。在引擎盖下,它调用C++forward函数。实现方法如下:

at::Tensor tensorInputs = torch::from_blob((void*)wavBuffer, {1, bufLength}, at::kFloat);
float* floatInput = tensorInputs.data_ptr<**float**>();
if (!floatInput) {
    return nil;
}
NSMutableArray* inputs = [[NSMutableArray  alloc] init];
for (int i = 0; i < bufLength; i++) {
    [inputs addObject:@(floatInput[i])];
}
c10::InferenceMode guard;

CFTimeInterval startTime = CACurrentMediaTime();
auto result = _impl.forward({ tensorInputs }).toStringRef();

C++函数torch::from_blob将从wav缓冲区创建一个输入Tensor。


c10::InferenceMode guard;

最后,调用这个forward函数来获取语音命令识别结果。


auto result = _impl.forward({ tensorInputs }).toStringRef();