Friday, 31 August 2018

Speech-to-Text

Speech-to-Text 




UIViewController.h

#import <UIKit/UIKit.h>
#import <Speech/Speech.h>
#import "GlobalAssistant.h"

@interface FreeTextView : UIViewController <SFSpeechRecognizerDelegate>
{
    __weak IBOutlet UIImageView *animationImageView;
    
    SFSpeechRecognizer *speechRecognizer;
    SFSpeechAudioBufferRecognitionRequest *recognitionRequest;
    SFSpeechRecognitionTask *recognitionTask;
    SFSpeechURLRecognitionRequest *urlRequest;
    
    // Record speech using audio Engine
    AVAudioInputNode *inputNode;
    AVAudioEngine *audioEngine;
}

// --------- Initialize GlobalAssistant

@property (strong , nonatomic) GlobalAssistant *globalObject ;

@property(strong, nonatomic)IBOutlet UITextView *txtAnswer ;

- (IBAction)microPhoneTapped:(id)sender ;

@end




UIViewController.m



#import "FreeTextView.h"
#import "UIImage+animatedGIF.h"

@interface FreeTextView ()

@end

@implementation FreeTextView
@synthesize btnSpeech, txtAnswer ;
@synthesize globalObject ;

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    // --------- Initialize GlobalAssistant
    
    globalObject = [[GlobalAssistant alloc] init] ;
}

#pragma mark - Button Click (Speech Recognization)

- (IBAction)microPhoneTapped:(id)sender {

    if (audioEngine.isRunning) {
        [globalObject showActivityIndicator];
        recognitionTask =[speechRecognizer recognitionTaskWithRequest:recognitionRequest resultHandler:^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error) {
            [self->globalObject removeActivityIndicator];
            if (result != nil) {
                NSString *transcriptText = result.bestTranscription.formattedString;
                self->txtAnswer.text = transcriptText;
            }
            else {
                [self->audioEngine stop];;
                self->recognitionTask = nil;
                self->recognitionRequest = nil;
            }
        }];
        // make sure you release tap on bus else your app will crash the second time you record.
        [inputNode removeTapOnBus:0];
        
        [audioEngine stop];
        [recognitionRequest endAudio];
        [btnSpeech setBackgroundImage:[UIImage imageNamed:@"mic"] forState:UIControlStateNormal];
        animationImageView.hidden = YES;
        
    }
    else {
        [self startRecording];
    }
}

#pragma mark - Voice SCAN

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    
    audioEngine = [[AVAudioEngine alloc] init];
    
    NSLocale *local =[[NSLocale alloc] initWithLocaleIdentifier:@"en-US"];
    speechRecognizer = [[SFSpeechRecognizer alloc] initWithLocale:local];
    
    
    //  for (NSLocale *locate in [SFSpeechRecognizer supportedLocales]) {
    //      NSLog(@"%@", [locate localizedStringForCountryCode:locate.countryCode]);
    //  }
    
    // Check Authorization Status
    // Make sure you add "Privacy - Microphone Usage Description" key and reason in Info.plist to request micro permison
    // And "NSSpeechRecognitionUsageDescription" key for requesting Speech recognize permison
    [SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) {
        
        dispatch_async(dispatch_get_main_queue(), ^{
            switch (status) {
                case SFSpeechRecognizerAuthorizationStatusAuthorized: {
                    self->btnSpeech.enabled = YES;
                    break;
                }
                case SFSpeechRecognizerAuthorizationStatusDenied: {
                    self->btnSpeech.enabled = NO;
                    //  resultTextView.text = @"User denied access to speech recognition";
                }
                case SFSpeechRecognizerAuthorizationStatusRestricted: {
                    self->btnSpeech.enabled = NO;
                    //  resultTextView.text = @"User denied access to speech recognition";
                }
                case SFSpeechRecognizerAuthorizationStatusNotDetermined: {
                    self->btnSpeech.enabled = NO;
                    //  resultTextView.text = @"User denied access to speech recognition";
                }
            }
        });
        
    }];
}

// Transcript from a file
- (void)transcriptExampleFromAFile {
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"checkFile" withExtension:@"m4a"];
    urlRequest = [[SFSpeechURLRecognitionRequest alloc] initWithURL:url];
    recognitionTask = [speechRecognizer recognitionTaskWithRequest:urlRequest resultHandler:^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error) {
        if (result != nil) {
            NSString *text = result.bestTranscription.formattedString;
            self->txtAnswer.text = text;
        }
        else {
            NSLog(@"Error, %@", error.description);
        }
    }];
}

// recording
- (void)startRecording {
    
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"micon" withExtension:@"gif"];
    animationImageView.image = [UIImage animatedImageWithAnimatedGIFURL:url];
    animationImageView.hidden = NO;
    [btnSpeech setBackgroundImage:[UIImage imageNamed:@"micon"] forState:UIControlStateNormal];
    
    if (recognitionTask) {
        [recognitionTask cancel];
        recognitionTask = nil;
    }
    
    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategoryRecord mode:AVAudioSessionModeMeasurement options:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
    [session setActive:TRUE withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
    
    inputNode = audioEngine.inputNode;
    
    recognitionRequest = [[SFSpeechAudioBufferRecognitionRequest alloc] init];
    recognitionRequest.shouldReportPartialResults = NO;
    //  recognitionRequest.detectMultipleUtterances = YES;
    
    AVAudioFormat *format = [inputNode outputFormatForBus:0];
    
    [inputNode installTapOnBus:0 bufferSize:1024 format:format block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) {
        [self->recognitionRequest appendAudioPCMBuffer:buffer];
    }];
    [audioEngine prepare];
    NSError *error1;
    [audioEngine startAndReturnError:&error1];
    NSLog(@"%@", error1.description);
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#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



//***************** OR 

2nd Method (Word Detect)

//***************** 


#pragma mark - Button Click (Speech Recognization)

- (IBAction)microPhoneTapped:(id)sender {

    if (audioEngine.isRunning) {
        [audioEngine stop];
        [recognitionRequest endAudio];
        
        [btnSpeech setBackgroundImage:[UIImage imageNamed:@"mic"] forState:UIControlStateNormal];
        animationImageView.hidden = YES;
        
    } else {
        [self startRecording];
    }
}

#pragma mark - Voice SCAN

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    
    audioEngine = [[AVAudioEngine alloc] init];
    
    NSLocale *local =[[NSLocale alloc] initWithLocaleIdentifier:@"en-US"];
    speechRecognizer = [[SFSpeechRecognizer alloc] initWithLocale:local];
    
    
    //  for (NSLocale *locate in [SFSpeechRecognizer supportedLocales]) {
    //      NSLog(@"%@", [locate localizedStringForCountryCode:locate.countryCode]);
    //  }
    
    // Check Authorization Status
    // Make sure you add "Privacy - Microphone Usage Description" key and reason in Info.plist to request micro permison
    // And "NSSpeechRecognitionUsageDescription" key for requesting Speech recognize permison
    [SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) {
        
        dispatch_async(dispatch_get_main_queue(), ^{
            switch (status) {
                case SFSpeechRecognizerAuthorizationStatusAuthorized: {
                    self->btnSpeech.enabled = YES;
                    break;
                }
                case SFSpeechRecognizerAuthorizationStatusDenied: {
                    self->btnSpeech.enabled = NO;
                    //  resultTextView.text = @"User denied access to speech recognition";
                }
                case SFSpeechRecognizerAuthorizationStatusRestricted: {
                    self->btnSpeech.enabled = NO;
                    //  resultTextView.text = @"User denied access to speech recognition";
                }
                case SFSpeechRecognizerAuthorizationStatusNotDetermined: {
                    self->btnSpeech.enabled = NO;
                    //  resultTextView.text = @"User denied access to speech recognition";
                }
            }
        });
        
    }];
}

// recording
- (void)startRecording {
    
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"micon" withExtension:@"gif"];
    animationImageView.image = [UIImage animatedImageWithAnimatedGIFURL:url];
    animationImageView.hidden = NO;
    [btnSpeech setBackgroundImage:[UIImage imageNamed:@"micon"] forState:UIControlStateNormal];
    
    // Initialize the AVAudioEngine
    audioEngine = [[AVAudioEngine alloc] init];
    
    // Make sure there's not a recognition task already running
    if (recognitionTask) {
        [recognitionTask cancel];
        recognitionTask = nil;
    }
    
    // Starts an AVAudio Session
    NSError *error;
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryRecord error:&error];
    [audioSession setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&error];
    
    // Starts a recognition process, in the block it logs the input or stops the audio
    // process if there's an error.
    recognitionRequest = [[SFSpeechAudioBufferRecognitionRequest alloc] init];
    AVAudioInputNode *inputNode = audioEngine.inputNode;
    recognitionRequest.shouldReportPartialResults = YES;
    recognitionTask = [speechRecognizer recognitionTaskWithRequest:recognitionRequest resultHandler:^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error) {
        BOOL isFinal = NO;
        if (result) {
            // Whatever you say in the microphone after pressing the button should be being logged
            // in the console.
            NSLog(@"RESULT:%@",result.bestTranscription.formattedString);
            isFinal = !result.isFinal;
            
            self->txtAnswer.text = result.bestTranscription.formattedString ;
            
            self->lblPlaceHolder.hidden = YES ;
        }
        if (error) {
            [self->audioEngine stop];
            [inputNode removeTapOnBus:0];
            self->recognitionRequest = nil;
            self->recognitionTask = nil;
        }
    }];
    
    // Sets the recording format
    AVAudioFormat *recordingFormat = [inputNode outputFormatForBus:0];
    [inputNode installTapOnBus:0 bufferSize:1024 format:recordingFormat block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) {
        [self->recognitionRequest appendAudioPCMBuffer:buffer];
    }];
    
    // Starts the audio engine, i.e. it starts listening.
    [audioEngine prepare];
    [audioEngine startAndReturnError:&error];
    NSLog(@"Say Something, I'm listening");
    

}



1 comment:

  1. Thanks for information i also interested in learning for your blog.
    Speech To Text



    ReplyDelete