http://osp.voicecloud.cn/
//
// ViewController.m
// Custom声纹识别
//
// Created by 谢泽锋 on 15/4/30.
// Copyright (c) 2015年 谢泽锋. All rights reserved.
//
#import "ViewController.h"
#import "TrainViewController.h"
#import <iflyMSC/IFlyISVRecognizer.h>
#define PWDT_FIXED_CODE 1 //固定密码
#define PWDT_FREE_CODE 2 //自由说
#define PWDT_NUM_CODE 3 //数字密码
#pragma mark actionsheet tag
#define SETTING_TAG 1 //设置
#define FIXED_CODE_VERIFY_TAG 3 //核实
#define FIXED_CODE_TRAIN_TAG 2 //训练
#define FIXED_CODE_QUERY_TAG 4 //查询
#define FIXED_CODE_DEL_TAG 5 //删除
#pragma key of isv
#define KEY_PTXT @"ptxt" //ptxt表示查询或者删除的密码文本
#define KEY_RGN @"rgn" // 本次注册需要的训练次数
#define KEY_TSD @"tsd"
#define KEY_SUB @"sub" //服务类型
#define KEY_PWDT @"pwdt" //pwdt表示密码类型
#define KEY_TAIL @"vad_speech_tail"
#define KEY_AUTHID @"auth_id" //auth_id表示用户名
#define KEY_SST @"sst" // 设置业务类型为训练
#define KEY_KEYTIMEOUT @"key_speech_timeout" //演说
#define KEY_VADTIMEOUT @"vad_timeout" //设置有效录音时间
#pragma mark value of key
#define TRAIN_SST @"train"
#define VERIFY_SST @"verify"
#pragma mark del or query
#define DEL @"del"
#define QUERY @"que"
@interface ViewController ()<UIActionSheetDelegate>
{
UIButton * settingButton;
UIButton * trainButton;
UIButton *verifyButt;//测试按钮
int ivppwdt; //atention 声纹密码类型参数
IFlyISVRecognizer *isvRec; //atention 声纹类的单例模式 atention
NSArray * fixCodeArray; //固定密码数组
NSArray * numCodeArray; //数字密码数组
NSString *authID; //atention 声纹用户名
UIButton *deleteButt;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
authID=@"18815251576";
isvRec =[IFlyISVRecognizer sharedInstance];
[self creatButton];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)creatButton
{
settingButton= [[UIButton alloc] initWithFrame:CGRectMake(20, 40, 160, 30)];
[settingButton setTitle:@"设置" forState:UIControlStateNormal];
[settingButton addTarget:self action:@selector(settingHandler) forControlEvents:UIControlEventTouchUpInside];
settingButton.backgroundColor=[UIColor orangeColor];
[self.view addSubview:settingButton];
trainButton =[[UIButton alloc]initWithFrame:CGRectMake(20, 100, 160, 30)];
[trainButton setTitle:@"训练模型" forState:UIControlStateNormal];
[trainButton addTarget:self action:@selector(trainButtonHandler) forControlEvents:UIControlEventTouchUpInside];
[trainButton setBackgroundColor:[UIColor orangeColor]];
[self.view addSubview:trainButton];
verifyButt=[[UIButton alloc ]initWithFrame:CGRectMake(20, 160, 160, 30)];
[verifyButt setTitle:@"测试模式" forState:UIControlStateNormal];
[verifyButt addTarget:self action:@selector(verifyButtonHandler) forControlEvents:UIControlEventTouchUpInside];
[verifyButt setBackgroundColor:[UIColor orangeColor]];
[self.view addSubview:verifyButt];
deleteButt=[[UIButton alloc ]initWithFrame:CGRectMake(20, 220, 160, 30)];
[deleteButt setTitle:@"删除模式" forState:UIControlStateNormal];
[deleteButt addTarget:self action:@selector(deleteButtonHandler) forControlEvents:UIControlEventTouchUpInside];
[deleteButt setBackgroundColor:[UIColor orangeColor]];
[self.view addSubview:deleteButt];
}
//删除模型
-(void)deleteButtonHandler
{
// if( [self netConnectAble] == NO )
// {
// [resultShow setText:@"无网络连接"];
// [self.view addSubview:resultShow];
// return;
// }
// [self buttonDisable];
if( ivppwdt == PWDT_FIXED_CODE ){
[self startRequestFixedCode:DEL];
}else if( ivppwdt == PWDT_NUM_CODE ){
[self startRequestNumCode:DEL];
}else if( ivppwdt == PWDT_FREE_CODE ){
[self startRequestFreeCode:DEL];
}
// [self buttonEanble];
}
#pragma mark request model
//固定密码查询或者删除
-(void) startRequestFixedCode:(NSString *)queryMode
{
fixCodeArray=[self downloadPassworld:PWDT_FIXED_CODE];
if( fixCodeArray != nil ){
if( [queryMode isEqualToString: QUERY] ){
[self generateActionSheetWithArray:fixCodeArray withTag:FIXED_CODE_QUERY_TAG]; //点击生成的actionsheet元素,可进入训练界面
}else if( [queryMode isEqualToString: DEL] ){
[self generateActionSheetWithArray:fixCodeArray withTag:FIXED_CODE_DEL_TAG];
}
}else{
// [resultShow setText:@"获取密码失败"];
// [self.view addSubview:resultShow];
NSLog(@"in %s,固定密码获取密码失败",__func__);
}
}
//查询或者时删除返回的结果处理
-(void)processRequestResult:(NSString*)requestMode ret:(BOOL)ret err:(int)err
{
if( ![requestMode isEqualToString:DEL] && ![requestMode isEqualToString:QUERY]){
NSLog(@"在%s中,queryMode参数错误",__func__);
return;
}
if( [requestMode isEqualToString:QUERY] ){
if( err != 0 ){
NSLog(@"查询错误,错误码:%d",err);
// [resultShow setText:[NSString stringWithFormat:@"查询出错!错误码:%d",err]];
}else{
if( ret == NO ){
NSLog(@"模型不存在");
// [resultShow setText:@"模型不存在"];
}else{
NSLog(@"查询成功");
// [resultShow setText:@"模型存在!"];
}
}
}else if( [requestMode isEqualToString:DEL]){
if( err != 0 ){
NSLog(@"删除错误,错误码:%d",err);
// [resultShow setText:[NSString stringWithFormat:@"删除出错!错误码:%d",err]];
}else{
if( ret == NO ){
NSLog(@"模型不存在");
// [resultShow setText:@"模型不存在"];
}else{
NSLog(@"删除成功");
// [resultShow setText:@"删除成功!"];
}
}
}
// [self.view addSubview:resultShow];
}
//自由说查询或者删除
-(void)startRequestFreeCode:(NSString *)queryMode
{
if( ![queryMode isEqualToString: QUERY] && ![queryMode isEqualToString:DEL] ){
NSLog(@"in %s,queryMode 参数错误",__func__);
return;
}
int err;
BOOL ret;
ret=[isvRec sendRequest:queryMode authid:authID pwdt:PWDT_FREE_CODE ptxt:nil vid:nil err:&err]; // attention isv ++++++++++++++++++++++++++
[self processRequestResult:queryMode ret:ret err:err];
}
//数字密码查询或者删除
-(void)startRequestNumCode:(NSString *)queryMode
{
if( ![queryMode isEqualToString: QUERY] && ![queryMode isEqualToString:DEL] ){
NSLog(@"in %s,queryMode 参数错误",__func__);
return;
}
int err;
BOOL ret;
ret=[isvRec sendRequest:queryMode authid:authID pwdt:PWDT_NUM_CODE ptxt:nil vid:nil err:&err]; // attention isv +++++++++++++++++++++
[self processRequestResult:queryMode ret:ret err:err];
}
//验证模型
-(void)verifyButtonHandler
{
// if( [self netConnectAble] == NO )
// {
// [resultShow setText:@"无网络连接"];
// [self.view addSubview:resultShow];
// return;
// }
[isvRec cancel];
// [self buttonDisable];
if( ivppwdt == PWDT_FIXED_CODE ){
[self trainOrVerifyFixedCode:VERIFY_SST];
}else if( ivppwdt == PWDT_NUM_CODE ){
[self trainOrVerifyNumCode:VERIFY_SST];
}else if( ivppwdt == PWDT_FREE_CODE ){
// [self trainOrVerifyFreeCode:VERIFY_SST];
}
// [self buttonEanble];
}
-(void)trainButtonHandler
{
[isvRec cancel];
[isvRec setParameter:TRAIN_SST forKey:KEY_SST]; // 设置业务类型为训练
if( ivppwdt == PWDT_FIXED_CODE ){
[self trainOrVerifyFixedCode:TRAIN_SST];
}else if( ivppwdt == PWDT_NUM_CODE ){
[self trainOrVerifyNumCode:TRAIN_SST];
}else if( ivppwdt == PWDT_FREE_CODE ){
// [self trainOrVerifyFreeCode:TRAIN_SST];
}
}
//训练或者验证 数字密码
-(void)trainOrVerifyNumCode:(NSString *)sst
{
if( ![sst isEqualToString:VERIFY_SST] && ![sst isEqualToString:TRAIN_SST] ){
NSLog(@"in %s,sst 参数错误",__func__);
return;
}
numCodeArray=[self downloadPassworld:ivppwdt];
if( numCodeArray == nil ){
// [resultShow setText:@"获取密码失败"];
// [self.view addSubview:resultShow];
return;
}
if( [sst isEqualToString:VERIFY_SST] ){
if( numCodeArray!=nil && numCodeArray.count > 0 ){
NSString *ptString=[numCodeArray objectAtIndex:0];
[self defaultSetparam:authID withpdwt: PWDT_NUM_CODE withptxt:ptString trainorverify:VERIFY_SST];
TrainViewController *trainController=[[TrainViewController alloc]init];
trainController.numCodeArray =numCodeArray;
trainController.pwdt=PWDT_NUM_CODE;
trainController.sst=VERIFY_SST;
[self presentViewController:trainController animated:YES completion:nil];
}
}else{
if( numCodeArray!=nil && numCodeArray.count > 0 ){
NSString *ptString=[self numArrayToString:numCodeArray];
[self defaultSetparam:authID withpdwt: PWDT_NUM_CODE withptxt:ptString trainorverify:TRAIN_SST];
TrainViewController *trainController=[[TrainViewController alloc]init];
trainController.numCodeArray =numCodeArray;
trainController.pwdt=PWDT_NUM_CODE;
trainController.sst=TRAIN_SST;
[self presentViewController:trainController animated:YES completion:nil];
}
}
}
//数字密码 把array里面的数字 串起来,ISV 固定规则
-(NSString*)numArrayToString:(NSArray *)numArrayParam
{
if( numArrayParam == nil ){
NSLog(@"在%s中,numArrayParam is nil",__func__);
return nil;
}
NSMutableString *ptxtString = [NSMutableString stringWithCapacity:1];
[ptxtString appendString:[numArrayParam objectAtIndex:0]];
for (int i = 1;i < [numArrayParam count] ; i++ ){
NSString *str = [numArrayParam objectAtIndex:i];
[ptxtString appendString:[NSString stringWithFormat:@"-%@",str]];
}
return ptxtString;
}
#pragma mark train or verify model
//声纹默认参数设置
- (void)defaultSetparam:(NSString *)auth_id withpdwt:(int) pwdt withptxt:(NSString *) ptxt trainorverify:(NSString*)sst
{
if( isvRec != nil ){
[isvRec setParameter:@"ivp" forKey:KEY_SUB];
[isvRec setParameter:[NSString stringWithFormat:@"%d",pwdt] forKey:KEY_PWDT];
[isvRec setParameter:@"50" forKey:KEY_TSD];
[isvRec setParameter:@"3000" forKey:KEY_VADTIMEOUT];
[isvRec setParameter:@"700" forKey:KEY_TAIL];
[isvRec setParameter:ptxt forKey:KEY_PTXT];
[isvRec setParameter:auth_id forKey:KEY_AUTHID];
[isvRec setParameter:sst forKey:KEY_SST]; /* train or test */
[isvRec setParameter:@"180000" forKey:KEY_KEYTIMEOUT];
if( pwdt == PWDT_FIXED_CODE || pwdt == PWDT_NUM_CODE ){
[isvRec setParameter:@"5" forKey:KEY_RGN];
}else{
[isvRec setParameter:@"1" forKey:KEY_RGN];
}
}else{
NSLog(@"isvRec is nil\n");
}
}
//训练或者验证 固定密码
-(void)trainOrVerifyFixedCode:(NSString *)sst
{
if( ![sst isEqualToString:VERIFY_SST] && ![sst isEqualToString:TRAIN_SST] )//判断是否是训练模式或是测试摩丝
{
NSLog(@"in %s,sst 参数错误",__func__);
return;
}
fixCodeArray=[self downloadPassworld:PWDT_FIXED_CODE];//固定密码下载
if( fixCodeArray == nil ){
NSLog(@"获取密码失败");
return;
}
if( [sst isEqualToString:VERIFY_SST] )//测试
{
if( fixCodeArray != nil ){
[self generateActionSheetWithArray:fixCodeArray withTag:FIXED_CODE_VERIFY_TAG]; //点击生成的actionsheet元素,在actionSheet中处理
}else{
NSLog(@"固定密码,获取密码失败");
}
}else{
if( fixCodeArray != nil ){
[self generateActionSheetWithArray:fixCodeArray withTag:FIXED_CODE_TRAIN_TAG];
}else{
NSLog(@"固定密码,获取密码失败");
}
}
}
//根据从网络上获得的密码,生成一个actionsheet并显示所有可用的固定密码
-(BOOL)generateActionSheetWithArray:(NSArray *)arrayParam withTag:(int)tag
{
if( arrayParam ==nil || arrayParam.count == 0 ){
NSLog(@"在%s中,文本密码为空,无法生成actionsheet",__func__);
}
UIActionSheet *showSheet=[[UIActionSheet alloc] initWithTitle:@"选择一个文本密码"
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil,nil];
showSheet.tag=tag;
for(int i =0; i< arrayParam.count; i++){
[showSheet addButtonWithTitle:[arrayParam objectAtIndex:i]];
}
[showSheet addButtonWithTitle:@"取消"];
[showSheet showInView:self.view];
return YES;
}
//下载密码
-(NSArray*)downloadPassworld:(int)pwdtParam
{
if( pwdtParam != PWDT_FIXED_CODE && pwdtParam != PWDT_NUM_CODE )
{
NSLog(@"in %s,pwdtParam 参数错误",__func__);
return nil;
}
NSArray* tmpArray=[isvRec getPasswordList:pwdtParam]; // attention isv +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if( tmpArray == nil ){
NSLog(@"in %s,请求数据有误",__func__);
return nil;
}
return tmpArray; //返回下载
}
#pragma mark 设置模式方法
-(void)settingHandler
{
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:@"选择密码类型"
delegate:self
cancelButtonTitle:@"取消"
destructiveButtonTitle:nil
otherButtonTitles:@"固定密码", @"用户自由说", @"数字密码", nil];
actionSheet.tag = SETTING_TAG;
[actionSheet showInView:self.view];
}
#pragma mark UIActionSheetDelegate
// actionsheet 点击处理函数
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
[self processActionSheet:actionSheet withIndex:buttonIndex];
}
-(void)processActionSheet:(UIActionSheet *)actionSheet withIndex:(NSInteger)buttonIndex
{
if( actionSheet.tag == SETTING_TAG ) {//选择固定密码或者是数字密码或者是自由说
switch (buttonIndex){
case 0:
NSLog(@"选择了固定密码");
ivppwdt = PWDT_FIXED_CODE;
break;
case 1:
NSLog(@"选择了用户自由说");
ivppwdt = PWDT_FREE_CODE;
break;
case 2:
NSLog(@"选择了数字密码");
ivppwdt = PWDT_NUM_CODE;
break;
default:
break;
}
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
//
// TrainViewController.h
// Custom声纹识别
//
// Created by 谢泽锋 on 15/4/30.
// Copyright (c) 2015年 谢泽锋. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface TrainViewController : UIViewController
@property(nonatomic) NSArray *fixCodeArray; //固定密码类型的文本密码数组
@property(nonatomic) NSArray *numCodeArray; //数字密码类型的文本密码数组
@property(nonatomic) int pwdt; //密码类型
@property(nonatomic) NSString *titleString; //录音界面title
@property(nonatomic) NSString *sst; //服务种类,训练还是验证
@end
//
// TrainViewController.m
// Custom声纹识别
//
// Created by 谢泽锋 on 15/4/30.
// Copyright (c) 2015年 谢泽锋. All rights reserved.
//
#import "TrainViewController.h"
#import "iflyMSC/iFlyISVRecognizer.h"
#import "DiagleView.h"
#pragma pwdt type
#define PWDT_FIXED_CODE 1 //固定
#define PWDT_NUM_CODE 3 //数字
#define PWDT_FREE_CODE 2 //自由说
#pragma mark result_dic key
#define SUC_KEY @"suc"
#define RGN_KEY @"rgn"
#pragma mark value of key
#define TRAIN_SST @"train"
#define VERIFY_SST @"verify"
#define DCS @"dcs"
#define SUCCESS @"success"
#define FAIL @"fail"
@interface TrainViewController ()<IFlyISVDelegate>
{
IFlyISVRecognizer *isvRec; //声纹单例
UIButton *startRecButton; //开始录音
UIButton *stopRecButton; //停止录音
}
@property(nonatomic) DiagleView *diagView; //录音界面
@property(nonatomic) int screenWidth ;
@property(nonatomic) int screenHeight;
@property(nonatomic) UIAlertView *trainVerifyAlert;
@end
@implementation TrainViewController
- (void)viewDidLoad {
[super viewDidLoad];
isvRec=[IFlyISVRecognizer sharedInstance];
CGRect rect=[[UIScreen mainScreen] bounds];
CGSize size = rect.size;
self.screenWidth = size.width;
self.screenHeight=size.height;
isvRec.delegate=self;
self.diagView=[[DiagleView alloc]initWithFrame:CGRectMake(0, 0, self.screenWidth, self.screenHeight)];//录音界面
[self.diagView.startRecButton addTarget:self action:@selector(startButtonHandler:) forControlEvents:UIControlEventTouchUpInside];
[self.diagView.stopRecButton addTarget:self action:@selector(stopButtonHandler:) forControlEvents:UIControlEventTouchUpInside];
[self.diagView.cancelButton addTarget:self action:@selector(cancelButtonHandler:) forControlEvents:UIControlEventTouchUpInside];
[self initialDiagViewRecordTtile];//初始化录音界面的titile
[self.view addSubview:self.diagView];
self.trainVerifyAlert=[[UIAlertView alloc]initWithTitle:@"nihao"
message:nil
delegate:self
cancelButtonTitle:@"确定"
otherButtonTitles:nil, nil];
}
#pragma mark button Handler
-(void)startButtonHandler:(id)sender
{
// if( [self netConnectAble] == NO )
// {
// [self.trainVerifyAlert setTitle:@"网络连接异常"];
// [self.trainVerifyAlert show];
// return;
// }
self.diagView.startRecButton.enabled=NO;
[isvRec startListening];//开始录音
}
-(void)stopButtonHandler:(id)sender
{
[isvRec stopListening];//停止录音
}
-(void)cancelButtonHandler:(id)sender
{
[isvRec cancel];//结束会话
[self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark initial recordTitle
-(void)initialDiagViewRecordTtile //录音小窗口标题设置
{
if( self.pwdt == PWDT_FIXED_CODE ){
if( self.fixCodeArray != nil && self.fixCodeArray.count > 0)
self.diagView.recordTitleLable.text=[self.fixCodeArray objectAtIndex:0];
}else if( self.pwdt == PWDT_NUM_CODE ){
if( self.numCodeArray != nil && self.numCodeArray.count !=0 )
self.diagView.recordTitleLable.text=[self.numCodeArray objectAtIndex:0];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//正常结果返回回调
-(void)onResult:(NSDictionary *)dic
{
[self.diagView.recognitionView stopAnimating];
[self.diagView recordViewInit];
[self resultProcess:dic];
self.diagView.startRecButton.enabled=YES;
}
//发生错误
-(void)onError:(IFlySpeechError *)errorCode
{
[self.diagView.recognitionView stopAnimating];
[self.diagView recordViewInit];
if( errorCode.errorCode != 0 ){ //处理错误
self.diagView.startRecButton.enabled=YES;
self.diagView.resultLabel.textColor=[UIColor redColor];
self.diagView.resultLabel.text=[NSString stringWithFormat:@"错误码:%d",errorCode.errorCode];
}
self.diagView.startRecButton.enabled=YES;
}
//音量回调
-(void)onVolumeChanged:(int)volume
{
[self.diagView recordViewChangeWithVolume:volume];
}
//识别中回调
-(void)onRecognition
{
NSLog(@"正在识别中");
[self performSelectorOnMainThread:@selector(hideRecordView) withObject:nil waitUntilDone:YES];
// [self.diagView.recordView removeFromSuperview];//替代方法
[self.diagView.recognitionView startAnimating];
}
#pragma mark result process
//对声纹回调结果进行处理
-(void)resultProcess:(NSDictionary *)dic
{
if( dic == nil ){
NSLog(@"in %s,dic is nil",__func__);
return;
}
if( [self.sst isEqualToString:TRAIN_SST] ){ //训练结果
NSNumber *suc=[dic objectForKey:SUC_KEY] ;
self.diagView.resultLabel.textColor=[UIColor blackColor];
self.diagView.resultLabel.text=[NSString stringWithFormat:@"%d",[suc intValue]];
NSNumber *rgn=[dic objectForKey:RGN_KEY];
if( [suc intValue] >= [rgn intValue] ){
[self.trainVerifyAlert setTitle:@"训练成功"];
[self.trainVerifyAlert show];
}
if( self.pwdt == PWDT_NUM_CODE ){ //数字密码需要更新显示
if( [suc intValue] < [rgn intValue] ){
self.diagView.recordTitleLable.text=[self.numCodeArray objectAtIndex:[suc intValue]];
}
}
}else if( [self.sst isEqualToString:VERIFY_SST] ){ //验证结果
self.diagView.resultLabel.text=@""; //结果label不显示
NSString *successStr=@"";
if( [[dic objectForKey:DCS] isEqualToString:SUCCESS] ){
successStr=@"验证成功";
}else{
successStr=@"验证失败";
}
[self.trainVerifyAlert setTitle:successStr];
[self.trainVerifyAlert show];
}
}
-(void)hideRecordView
{
[self.diagView.recordView setHidden:YES];
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end