본문 바로가기
Android

STT(Speech to text)

by mangstory 2021. 5. 20.

Speech Recognition(음성인식) : 사람이 말하는 음성 언어를 컴퓨터가 해석해 그 내용을 문자 데이터로 전환하는 처리

 

App의 기본 기능인 STT를 간단히 구현.

 

 

1. manifest 파일

STT를 활용하기 위한 permission을 추가해준다.

//STT를 위한 permission추가
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />

 

2. XML파일

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <ImageButton
        android:id="@+id/imageButton"
        android:layout_width="50dp"
        android:layout_height="60dp"
        android:layout_marginTop="300dp"
        android:adjustViewBounds="true"
        android:cropToPadding="false"
        android:onClick="STTButton"
        android:scaleType="fitCenter"
        android:src="@drawable/no_voice"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="Press the button and speak!"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageButton" />
</android.support.constraint.ConstraintLayout>

 

현재 음성상태를 나타내주고 음성인식의 시작과 끝을 확인할 수 있는 imagebutton과 text를 나타내는 textview를 만든다.

 

 

 

이제 MainActivity로 와서

 

3. Recognizer intent 객체 생성

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textview = findViewById(R.id.textView);
        imageButton = findViewById(R.id.imageButton);

	//version확인하여 permission 체크
        if(Build.VERSION.SDK_INT>=23){
            ActivityCompat.requestPermissions(this,new String[]{
                    Manifest.permission.INTERNET,Manifest.permission.RECORD_AUDIO}, PERMISSION);
            }
        intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,getPackageName());
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE,"ko-KR");

    }

 

recognizer intent객체 생성하고 언어를 한국어로 설정해준다.

 

 

4. onClick 이벤트 

public void STTButton(View view) {
        imageButton.setImageResource(R.drawable.voice);
        mRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
        mRecognizer.setRecognitionListener(listener);
        mRecognizer.startListening(intent);

    }

 

xml파일에서 onClick 속성을 부여하였기에 버튼 클릭 시 STTButton 함수가 실행된다.

버튼이 클릭되면 이미지를 교체해주고,

SpeechRecognizer 객체에 listener를 할당해주고 음성인식을 시작한다.

 

 

5. Recognition listener

private RecognitionListener listener = new RecognitionListener() {
        @Override
        public void onReadyForSpeech(Bundle params) {
            Toast.makeText(getApplicationContext(),"음성인식을 시작합니다.",Toast.LENGTH_SHORT).show();

        }

        @Override
        public void onBeginningOfSpeech() {
            imageButton.setImageResource(R.drawable.voice_search);
        }

        @Override
        public void onRmsChanged(float rmsdB) {

        }

        @Override
        public void onBufferReceived(byte[] buffer) {

        }

        @Override
        public void onEndOfSpeech() {
            imageButton.setImageResource(R.drawable.no_voice);
        }

        @Override
        public void onError(int error) {
            Toast.makeText(getApplicationContext(), "에러가 발생하였습니다. " ,Toast.LENGTH_SHORT).show();

        }

        @Override
        public void onResults(Bundle results) {
            ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
            for(int i = 0; i < matches.size() ; i++){
                textview.setText(matches.get(i));

            }
        }


        @Override
        public void onPartialResults(Bundle partialResults) {

        }

        @Override
        public void onEvent(int eventType, Bundle params) {

        }
    };

 

음성인식 시작과 끝에 이미지를 교체해주어 상태를 보여주고

error는 toast message로 처리해준다. 다양한 error가 있지만 생략하고 한꺼번에 처리해주었다.

 

onResults함수에서 결과를 Arraylist에 넣고 testview에 할당해준다.

그런데 저 포문은 대체 왜 있는 건지 모르겠다ㅠㅠ

 

6. 실행결과

왼쪽부터 차례대로

시작화면 - 버튼클릭 - 말하는 중 - 말 끝남

 

 

7. 전체 코드

package com.example.teststt;

import android.Manifest;
import android.content.Intent;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.widget.Toast;

import java.util.ArrayList;


public class MainActivity extends AppCompatActivity {
    final int PERMISSION = 1;
    SpeechRecognizer mRecognizer;
    Intent intent;
    TextView textview;
    ImageButton imageButton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textview = findViewById(R.id.textView);
        imageButton = findViewById(R.id.imageButton);


        if(Build.VERSION.SDK_INT>=23){
            ActivityCompat.requestPermissions(this,new String[]{
                    Manifest.permission.INTERNET,Manifest.permission.RECORD_AUDIO}, PERMISSION);
            }
        intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,getPackageName());
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE,"ko-KR");

    }

    public void STTButton(View view) {
        imageButton.setImageResource(R.drawable.voice);
        mRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
        mRecognizer.setRecognitionListener(listener);
        mRecognizer.startListening(intent);

    }

    private RecognitionListener listener = new RecognitionListener() {

        @Override
        public void onReadyForSpeech(Bundle params) {
            Toast.makeText(getApplicationContext(),"음성인식을 시작합니다.",Toast.LENGTH_SHORT).show();

        }

        @Override
        public void onBeginningOfSpeech() {
            imageButton.setImageResource(R.drawable.voice_search);
        }

        @Override
        public void onRmsChanged(float rmsdB) {

        }

        @Override
        public void onBufferReceived(byte[] buffer) {

        }

        @Override
        public void onEndOfSpeech() {
            imageButton.setImageResource(R.drawable.no_voice);
        }

        @Override
        public void onError(int error) {
            Toast.makeText(getApplicationContext(), "에러가 발생하였습니다. " ,Toast.LENGTH_SHORT).show();

        }

        @Override
        public void onResults(Bundle results) {
            ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
            for(int i = 0; i < matches.size() ; i++){
                textview.setText(matches.get(i));
            }
        }


        @Override
        public void onPartialResults(Bundle partialResults) {

        }

        @Override
        public void onEvent(int eventType, Bundle params) {

        }
    };
}

'Android' 카테고리의 다른 글

Real Time Activity  (2) 2021.03.04
Sensor - Gyro, Magno, Light, Pressure, Temp, Humi  (4) 2021.03.02
Sensor - Accelerometer  (3) 2021.02.25