# 一、SDK说明

基于语音识别和评价技术对发音做客观打分,反馈发音正误和定位问题,有助于语音教学,发音练习,也可测试考生的口语水平。 SDK详细的接口介绍及说明请参考:iOS文档

# 二、Demo使用方法

# 1.Project设置

  1. 将OralEvalSDK_Libs目录下所有文件拖到Xcode工程中的libs文件加下(SDK对应版本有真机版本和模拟器版本),在弹出的窗口中勾选 Copy items into destination group’s folder(if needed),确保TARGETS->Build Phases->Link Binary With Libraries引用libusc.a; 注:混合及离线引擎还需将tmp_oral_offline.bundle一并拖入工程(确保关联文件不是红色的错误文件)。 avatar
    avatar
  2. 在 TARGETS->Build Phases->Link Binary With Libraries 标签下,点击按钮“+”,在弹出的窗口中选中AudioToolbox.framework ,SystemConfigration.framework,CoreTelephony.framework,AVFoundation.framework ,libstdc++.6.0.9.dylib等添加至工程;
  3. 然后在你的程序中导入头文件#import "USCRecognizer.h" ;
  4. 将Info.plist文件中的Bundle identifiter 替换成你公司自己的Bundle identifiter;
  5. 在TARGETS->Build Settings->Code Signing Identity中替换自己的证书。

说明

  1. 因为模拟器录音效果不好,目前sdk只提供真机版本,模拟器版本仅支持编译,不提供完整的评测功能。
  2. 静态库采用c++混编,请将相应的.m文件改为.mm文件,开启c++编译选项。
  3. 为了防止编译错误,请将C++ Standard Library设置为Compiler Default或libc++。
  4. 目前SDK不支持armv6的设备。

# 三、SDK集成步骤

# 1.调用流程

注:集成时请考虑每个回调之间的时间差 以下流程请注意:

  1. start是异步调用的,必须等到onBeginOral回调后,录音线程真正启动,再开始录音;
  2. 正常获取到评测结果或是取消评测后,必须要等到onEndOral才能进行下一次评测。
    avatar

# 2.生命周期状态码

调用状态 状态码 说明
OralStart 1 评测开始状态
OralHasBegin 2 评测开始成功
OralStop 3 评测结束录音
OralVadTimeOut 4 Vad超时导致结束录音
OralHasStoped 5 录音结束成功
OralWithResult 6 返回评测结果
OralWithError 7 评测出错
OralCancel 8 调用cancel,取消评测
OralHasEnd 9 评测结束

以上流程,出现的顺序按照数字从小到大排列,不应该出现重复。如果调用过程返回重复的状态码,可能调用流程有误;
其中6和7同时只会出现1个;
状态码4,只有在vad开启的情况下才会出现。

# 3.返回结果说明

英文返回的结果格式

{
    "end": 1.111,
    "usertext": "good morning",
    "pronunciation": 92.932,
    "fluency": 43.75,
    "score": "92.85",
    "words": [
        {
            "end": 0.441,
            "text": "sil",
            "score": 4.442,
            "subwords": [
                {
                    "end": 0.441,
                    "subtext": "sil",
                    "volume": 1.122,
                    "begin": 0.081
                }
            ],
            "type": 4,
            "volume": 1.122,
            "begin": 0.081
        },
        {
            "end": 0.621,
            "text": "good",
            "score": 8.87,
            "subwords": [
                {
                    "end": 0.501,
                    "subtext": "g",
                    "volume": 6.905,
                    "begin": 0.441
                },
                {
                    "end": 0.561,
                    "subtext": "ʊ",
                    "volume": 5.6,
                    "begin": 0.501
                },
                {
                    "end": 0.621,
                    "subtext": "d",
                    "volume": 7.678,
                    "begin": 0.561
                }
            ],
            "type": 2,
            "volume": 6.728,
            "begin": 0.441
        },
        {
            "end": 1.091,
            "text": "morning",
            "score": 8.893,
            "subwords": [
                {
                    "end": 0.731,
                    "subtext": "m",
                    "volume": 8.989,
                    "begin": 0.621
                },
                {
                    "end": 0.851,
                    "subtext": "ɔː",
                    "volume": 9,
                    "begin": 0.731
                },
                {
                    "end": 0.911,
                    "subtext": "n",
                    "volume": 9,
                    "begin": 0.851
                },
                {
                    "end": 1.001,
                    "subtext": "ɪ",
                    "volume": 7.723,
                    "begin": 0.911
                },
                {
                    "end": 1.091,
                    "subtext": "ŋ",
                    "volume": 2.106,
                    "begin": 1.001
                }
            ],
            "type": 2,
            "volume": 7.364,
            "begin": 0.621
        },
        {
            "end": 1.111,
            "text": "sil",
            "score": 4.236,
            "subwords": [
                {
                    "end": 1.111,
                    "subtext": "sil",
                    "volume": 1.044,
                    "begin": 1.091
                }
            ],
            "type": 4,
            "volume": 1.044,
            "begin": 1.091
        }
    ],
    "sample": "good morning",
    "integrity": 100,
    "begin": 0
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
字段 类型 说明 备注
version String 引擎版本信息
EvalType String 评测题型 general:普通朗读型
askandanwser:问答题型
composition:作文题型
score double 评测打分结果 百分制的打分结果
lines object 节点标志 单个单词返回一组数据,多行评测文本,依次返回每行的评测结果
- sample String 评测文本内容 用户传入的评测文本
- integrity int 朗读完整度 音频对应评测文本的朗读完整度
- begin double 评测文本在音频中的开始时间
- end double 评测文本在音频中的结束时间
- usertext String 识别出来的评测内容 引擎通过音频文件,识别出的用户朗读内容
- fluency double 朗读流利度
- pronunciation double 标准度 朗读的标准度
- score double 评测打分结果 百分制的打分结果
- words object 节点标志 评测文本每一行的每个单词的评测结果
-- begin double 评测单词在音频中的开始时间
-- end double 评测单词在音频中的结束时间
-- StressOfWord int 单词重音标志 0:重音朗读错误
1:重音朗读正确
-- volume int 音量大小 范围0-10
-- type int 识别朗读内容的类型 0:多词
1:漏词
2:正常词
3:错误词
4:静音
5:重复词
7:空格或标点
8:生词
-- phonetic String 评测文本音标
-- text String 评测单词
-- score double 该单词的打分结果
-- subwords object 音素评测结果节点
--- begin double 音频里的开始时间
--- end double 音频里的结束时间
--- volume int 音量 范围0-10
--- score double 音素评测分数 范围0-10
--- subtext String 音素

中文返回的结果格式

{
    "lines":[
        {
            "begin":0,
            "businessLevel":"1",
            "end":1.161,
            "fluency":68,
            "integrity":100,
            "pronunciation":91.997,
            "sample":"你好",
            "score":91.951,
            "standardScore":6,
            "usertext":"你好",
            "words":[
                {
                    "begin":0.241,
                    "end":0.621,
                    "score":9.128,
                    "subwords":[
                        {
                            "begin":0.241,
                            "end":0.421,
                            "score":8.833,
                            "standardScore":2,
                            "subtext":"n",
                            "toneofphone":-1,
                            "volume":6.665
                        },
                        {
                            "begin":0.421,
                            "end":0.621,
                            "score":9.352,
                            "standardScore":2,
                            "subtext":"i3",
                            "toneofphone":2,
                            "volume":8.59
                        }
                    ],
                    "sylbStress":"",
                    "text":"你",
                    "type":2,
                    "volume":7.627
                },
                {
                    "begin":0.621,
                    "end":1.161,
                    "score":9.456,
                    "subwords":[
                        {
                            "begin":0.621,
                            "end":0.781,
                            "score":8.846,
                            "standardScore":2,
                            "subtext":"h",
                            "toneofphone":-1,
                            "volume":8.812
                        },
                        {
                            "begin":0.781,
                            "end":1.161,
                            "score":10,
                            "standardScore":2,
                            "subtext":"ao3",
                            "toneofphone":2,
                            "volume":5.234
                        }
                    ],
                    "sylbStress":"",
                    "text":"好",
                    "type":2,
                    "volume":7.023
                }
            ]
        }
    ],
    "score":91.951,
    "standardScore":6,
    "version":"full 1.0"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
字段 类型 说明 备注
version String 引擎版本信息
score double 评测打分结果 百分制的打分结果
lines object 节点标志 单个单词返回一组数据,多行评测文本,依次返回每行的评测结果
- sample String 评测文本内容 用户传入的评测文本
- integrity int 朗读完整度 音频对应评测文本的朗读完整度
- begin double 评测文本在音频中的开始时间
- end double 评测文本在音频中的结束时间
- usertext String 识别出来的评测内容 引擎通过音频文件,识别出的用户朗读内容
- fluency double 朗读流利度
- pronunciation double 标准度 朗读的标准度
- businesslevel double 打分系数 返回打分的难易度,范围0.6-1.9(该接口暂时不生效)
- score double 评测打分结果 百分制的打分结果
- standardScore int 三挡分制(按照普通话标准进行划分) 0错误,1瑕疵,2正确
- words object 节点标志 评测文本每一行的每个字的评测结果
-- begin double 评测单词在音频中的开始时间
-- end double 评测单词在音频中的结束时间
-- volume int 音量大小 范围0-10
-- type int 识别朗读内容的类型 0:多词
1:漏词
2:正常词
3:错误词
4:静音
5:重复词
7:空格或标点
8:生词
9:可选词
-- text String 评测单字
-- score double 该单词的打分结果 范围0-10
-- subwords object 声韵母评测结果节点
--- begin double 音频里的开始时间
--- end double 音频里的结束时间
--- volume int 音量 范围0-10
--- score double 声母/韵母评测分数 范围0-10,十分制得分
--- standardScore Int 生母/韵母评测分数 按照普通话标准输出的3档得分值:0(错误),1(瑕疵)2(正确)
--- subtext String 声母/韵母
--- toneofphone 韵母的声调对错字段 -1:代表是声母
0:代表声调错误
1:代表声调发音有瑕疵
2:代表声调完全正确

# 四、错误码

错误码查询 (opens new window)

# 五、常见问题

# 1. demo工程有红色文件导致编译不过

SDK在无特定要求的情况下,默认的打包是纯在线的,demo编译中如果存在tmp_oral_offline.bundle 红色文件,该文件是编译离在线混合版本需要,纯在线版本,在编译的时候,将报错的红色文件删除即可。

# 2. SDK真机版和模拟版可以合并吗

真机版和模拟器版可以合并,如果云知声合并后再提供给你们,业务层无法拆分,在正式上线的时候包会变大,所以建议业务层在开发的过程中,自己参照网上的资料进行合并,参考网址:https://www.jianshu.com/p/840badb8a861。

# 3. 在模拟器上调试业务功能时编译报SDK平台错误

SDK的录音功能在模拟器上不能用,如果是调试业务的其他功能,可以将SDK的真机版与模拟器版本进行合并。

# 4. SDK调用start后可以立即stop吗

SDK的start是异步的,在调用时需要等到录音启动成功后再进行stop,即在收到录音启动的回调onBeginOral的时候,才可以进行stop,否则生命周期会返回对应的错误码。

# 5. 评测oralTask是什么,在哪设置

iOS中的oralTask 是指评测模式,在评测开始前的代码中设置,单词、句子评测设置E模式,篇章评测设置C模式,口头作文或是半开放题型设置A模式。详见模式说明
可在如下代码的位置设置。
avatar

# 6. SDK音频评分异常

如果SDK在正确朗读的情况下出现评分比较低,首先确认是人读的,不是其他外放音频的录音; 如果是人正常朗读的,可以调用3.2.8的录音回调函数,将音频保存在本地,查看原始录音是否有问题。