2017-07-12 34 views
7

Używam interfejsu API rozpoznawania mowy iOS z aplikacji ObjectOS-C iOS. Działa na iPhone 6, 7, ale nie działa na iPhone 5 (iOS, 10.2.1).Rozpoznawanie mowy na iPhone 5

Należy również pamiętać, że działa na iPhone 5s, po prostu nie iPhone 5.

Czy iOS mowy API przypuszczać, aby działać na iPhone 5? Czy musisz zrobić coś innego, aby to zadziałało, czy też ktoś wie, jaki może być problem?

Podstawowy kod znajduje się poniżej. Nie występują żadne błędy, a głośność mikrofonu jest wykrywana, ale nie wykryto mowy.

if (audioEngine != NULL) { 
     [audioEngine stop]; 
     [speechTask cancel]; 
     AVAudioInputNode* inputNode = [audioEngine inputNode]; 
     [inputNode removeTapOnBus: 0]; 
    } 

    recording = YES; 
    micButton.selected = YES; 

    //NSLog(@"Starting recording... SFSpeechRecognizer Available? %d", [speechRecognizer isAvailable]); 
    NSError * outError; 
    //NSLog(@"AUDIO SESSION CATEGORY0: %@", [[AVAudioSession sharedInstance] category]); 
    AVAudioSession* audioSession = [AVAudioSession sharedInstance]; 
    [audioSession setCategory: AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:&outError]; 
    [audioSession setMode: AVAudioSessionModeMeasurement error:&outError]; 
    [audioSession setActive: true withOptions: AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&outError]; 

    SFSpeechAudioBufferRecognitionRequest* speechRequest = [[SFSpeechAudioBufferRecognitionRequest alloc] init]; 
    //NSLog(@"AUDIO SESSION CATEGORY1: %@", [[AVAudioSession sharedInstance] category]); 
    if (speechRequest == nil) { 
     NSLog(@"Unable to create SFSpeechAudioBufferRecognitionRequest."); 
     return; 
    } 

    speechDetectionSamples = 0; 

    // This some how fixes a crash on iPhone 7 
    // Seems like a bug in iOS ARC/lack of gc 
    AVAudioEngine* temp = audioEngine; 
    audioEngine = [[AVAudioEngine alloc] init]; 
    AVAudioInputNode* inputNode = [audioEngine inputNode]; 

    speechRequest.shouldReportPartialResults = true; 

    // iOS speech does not detect end of speech, so must track silence. 
    lastSpeechDetected = -1; 

    speechTask = [speechRecognizer recognitionTaskWithRequest: speechRequest delegate: self]; 

    [inputNode installTapOnBus:0 bufferSize: 4096 format: [inputNode outputFormatForBus:0] block:^(AVAudioPCMBuffer* buffer, AVAudioTime* when) { 
     @try { 
      long millis = [[NSDate date] timeIntervalSince1970] * 1000; 
      if (lastSpeechDetected != -1 && ((millis - lastSpeechDetected) > 1000)) { 
       lastSpeechDetected = -1; 
       [speechTask finish]; 
       return; 
      } 
      [speechRequest appendAudioPCMBuffer: buffer]; 

      //Calculate volume level 
      if ([buffer floatChannelData] != nil) { 
       float volume = fabsf(*buffer.floatChannelData[0]); 

       if (volume >= speechDetectionThreshold) { 
        speechDetectionSamples++; 

        if (speechDetectionSamples >= speechDetectionSamplesNeeded) { 

         //Need to change mic button image in main thread 
         [[NSOperationQueue mainQueue] addOperationWithBlock:^ { 

          [micButton setImage: [UIImage imageNamed: @"micRecording"] forState: UIControlStateSelected]; 

         }]; 
        } 
       } else { 
        speechDetectionSamples = 0; 
       } 
      } 
     } 
     @catch (NSException * e) { 
      NSLog(@"Exception: %@", e); 
     } 
    }]; 

    [audioEngine prepare]; 
    [audioEngine startAndReturnError: &outError]; 
    NSLog(@"Error %@", outError); 
+0

możesz pokazać wypróbowany kod –

+0

'SFSpeechRecognizer.requestAuthorization()' zwraca co? Czy to może być ograniczenie dla iPhone'a 5? Sprawdź również tryb wyciszenia? – Larme

+0

dodano kod, również nie działa na iPhone 5s, problem został zgłoszony przez użytkownika, nie mam iPhone'a 5 do przetestowania na – James

Odpowiedz

2

Myślę, że błąd jest tutaj w tym kodzie:

long millis = [[NSDate date] timeIntervalSince1970] * 1000; 

urządzeń 32-bitowych (iPhone 5 jest urządzeniem 32-bitowy), można zapisać maksymalną liczbę 2^32-1 września tj. 2 147 483 647.

Sprawdziłem na symulatorze iPhone 5, wartość milis ma wartość ujemną. W opublikowanym fragmencie kodu nie ma wzmianki o tym, jak ustawić lastSpeechDetected po ustawieniu go na -1, ale jeśli w jakiś sposób ((millis - lastSpeechDetected) > 1000) jest prawdziwe, to wejdzie do bloku if i zakończy zadanie mowy.

+1

Tak, to był problem. Zmieniłem kod, by użyć "długiego long" i zadziałało na iPhonie 5. Wielkie dzięki. – James

+0

@ James: Cieszę się, że mogę Ci pomóc. Twoje zdrowie! –