8

ボタンを押すと音声認識が起動し、同時にユーザーの発言を録音する機能に取り組んでいます。コードは次のとおりです。

    button_start.setOnTouchListener( new View.OnTouchListener() 
    {
        @Override
        public boolean onTouch(View arg0, MotionEvent event) 
        {   
                if (pressed == false)
                {
                    Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);        
                    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
                    intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,"voice.recognition.test");
                    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "zh-HK");
                    intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS,1); 
                    sr.startListening(intent);
                    Log.i("111111","11111111");
                    pressed = true;
                }

                recordAudio();

            }

            if((event.getAction()==MotionEvent.ACTION_UP || event.getAction()==MotionEvent.ACTION_CANCEL))
            {                   
                stopRecording();
            }
            return false;
        }
    });             
}

   public void recordAudio()
   {
      isRecording = true;   
      try 
      {
          mediaRecorder = new MediaRecorder();
          mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
          mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
          mediaRecorder.setOutputFile(audioFilePath);
          mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
          mediaRecorder.prepare();
      } 
      catch (Exception e) 
      {
          e.printStackTrace();
      }
      mediaRecorder.start();            
   }    

   public void stopRecording()
   {            
       if (isRecording)
       {    
           mediaRecorder.stop();
           mediaRecorder.reset();    // set state to idle
           mediaRecorder.release();
           mediaRecorder = null;
           isRecording = false;
       }
       else 
       {
           mediaPlayer.release();
           mediaPlayer.reset();
           mediaPlayer = null;
       }
   }




class listener implements RecognitionListener          
{
    // standard codes onReadyForSpeech, onBeginningOfSpeech, etc
}

質問:

アプリを段階的に作成しましたが、最初はアプリに録音機能がなく、音声認識は完全に機能します。

何度もテストして音声認識は大丈夫だと判断した後、 を使用して録音機能を組み込み始めMediaRecorderます。

次に、button_start を押すERROR3 AUDIOと、話そうとする前でもすぐにメッセージが表示されることをテストしました。

録音した音声を再生します。音声もきちんと録音・保存されています。

何が起こっている?音声認識で同時に録音できないのはなぜですか?

ありがとう!

4

1 に答える 1

5

--EDIT-- Opus-Record WHILE Speech-Recognition のモジュールも実行されます

--EDIT--「V1BETA1」ストリーミング、連続、サンプルプロジェクトへのマイナーチェンジを伴​​う認識。その ' readData() ' を変更して、'sData' の生の PCM が 2 つのスレッド (サンプル プロジェクトの fileSink スレッド、認識 API スレッド) で共有されるようにします。シンクの場合は、'sData' IO ごとに更新される PCM ストリームを使用してエンコーダーを接続するだけです。ストリームを CLO することを忘れないでください。fileSink の詳細については、 「writeAudiaDataToFile()」を参照してください。

--編集--このスレッドを参照してください

次のことをしようとすると、HAL とマイク バッファで基本的な競合が発生します。

speechRecognizer.startListening(recognizerIntent); // <-- needs mutex use of mic

mediaRecorder.start(); // <-- needs mutex use of mic

上記のアクションのいずれかを選択して、マイクの基礎となるオーディオ API を所有することができます。

一度だけ話す Google Keep の機能を模倣したい場合は、1 つの入力プロセス (マイクへの音声) からの出力として、2 つの別々のタイプの出力 (STT と MP3 などの fileSink) を取得し、分割する必要があります。マイクから HAL レイヤーを出るときの何か。

例えば:

  1. マイクのバッファから出てくる PCM 16 として RAW オーディオをピックアップします。

  2. 上記のバッファのバイトを分割します(バッファからストリームを取得し、ストリームを 2 か所にパイプできます)。

  3. STRM 1 から STT 用 API へのエンコード前またはエンコード後のいずれか (Raw PCM 16 またはエンコード済みの両方を受け入れる STT API があります)

  4. STRM 2 をエンコーダーに送信し、次に録音をキャプチャするために fileSink に送信します。

Split は、マイクによって生成された実際のバッファ、またはそれらの同じバイトの派生ストリームのいずれかで動作できます。

あなたが何をしているのかについては、getCurrentRecording()consumeRecording() ここをご覧になることをお勧めします。

STT API リファレンス: Google "pultz speech-api" . そこに記載されている API にはユースケースがあることに注意してください。

于 2014-07-23T13:12:19.740 に答える