.NET 데스크톱 애플리케이션을 사용한 음성 인식. 실제 예제를 사용하여 서버 없이 초고속 음성 인식 Android 6.0의 오프라인 음성 인식

) 실제 가전제품 제어의 Hello World 사례를 사용합니다.
왜 가전제품인가? 예, 그러한 예 덕분에 다음과 같은 점을 이해할 수 있기 때문입니다. 속도와 정확성이는 다음을 사용하여 달성할 수 있습니다. 완전히 지역적이다다음과 같은 서버 없이 음성 인식 구글 ASR또는 Yandex SpeechKit.
또한 프로그램의 모든 소스 코드와 Android용 어셈블리 자체를 기사에 첨부합니다.

왜 갑자기?

최근에 이 문제를 접한 후 나는 저자에게 왜 자신의 프로그램에 서버 기반 음성 인식을 사용하기를 원하는지 물었습니다(제 생각에는 이것은 불필요했고 몇 가지 문제를 일으켰습니다). 이를 위해 아무것도 인식할 필요가 없고 사전이 유한한 단어 집합으로 구성된 프로젝트에 대한 대체 방법의 사용을 더 자세히 설명할 수 있습니까? 그리고 실제 적용 사례를 들어봐도...

Yandex와 Google 외에 다른 것이 필요한 이유는 무엇입니까?

바로 그 "실용적인 적용"을 위해 저는 주제를 선택했습니다 스마트 홈을 위한 음성 제어.
이 예가 정확히 왜 필요한가요? 클라우드 솔루션을 사용한 인식에 비해 완전 로컬 음성 인식의 여러 장점을 보여주기 때문입니다. 즉:
  • 속도- 우리는 서버에 의존하지 않으므로 가용성, 대역폭 등에 의존하지 않습니다. 요인
  • 정확성- 우리 엔진은 우리 애플리케이션에 관심 있는 사전과만 작동하므로 인식 품질이 향상됩니다.
  • 가격- 서버에 대한 각 요청에 대해 비용을 지불할 필요가 없습니다.
  • 음성 활성화- 첫 번째 포인트에 대한 추가 보너스로 - 트래픽을 낭비하지 않고 서버를 로드하지 않고도 지속적으로 "방송을 들을 수" 있습니다.

메모

이런 장점도 장점으로 볼 수 있으니 바로 예약하겠습니다 특정 클래스의 프로젝트에만 해당, 우리를 어디 우리는 미리 확실히 알고 있어요, 사용자가 어떤 사전과 어떤 문법으로 작업할지. 즉, 임의의 텍스트(예: SMS 메시지 또는 검색어)를 인식할 필요가 없는 경우입니다. 그렇지 않으면 클라우드 인식이 필수입니다.

따라서 Android는 인터넷 없이도 음성을 인식할 수 있습니다!
네, 네... JellyBean에서만 가능합니다. 그리고 더 이상은 0.5m에서만 가능합니다. 그리고 이 인식은 훨씬 더 작은 모델만을 사용하는 동일한 받아쓰기입니다. 따라서 우리도 이를 관리하거나 구성할 수 없습니다. 그리고 그녀가 다음에 우리에게 무엇을 돌려줄지는 알 수 없습니다. SMS에는 딱 맞지만!

우리는 무엇을해야합니까?

우리는 몇 미터 거리에서, 심지어 싸고 형편없으며 매우 저렴한 안드로이드 스마트폰, 태블릿, 시계에서도 정확하고 빠르게 작동하는 가전제품용 음성 원격 제어를 구현할 것입니다.
논리는 간단하지만 매우 실용적입니다. 마이크를 활성화하고 하나 이상의 장치 이름을 말합니다. 애플리케이션은 이를 인식하고 현재 상태에 따라 켜고 끕니다. 또는 그는 그들로부터 재산을 받고 그것을 유쾌한 여성 목소리로 발음합니다. 예를 들어 방의 현재 온도입니다.

실용적인 응용 프로그램이 풍부합니다.

아침에는 눈도 뜨지 않은 채 침대 옆 탁자에 놓인 스마트폰 화면을 손바닥으로 치며 “굿모닝!”이라고 인사했다. - 대본이 시작되고, 커피 메이커가 켜지고 웅웅거리며, 즐거운 음악이 재생되고, 커튼이 열립니다.
각 방 벽에 저렴한(2,000개 이하) 스마트폰을 걸어두자. 우리는 퇴근 후 집에 돌아와 허공에 명령한다. “스마트 홈! 조명, TV! - 앞으로 어떻게 될지는 굳이 말할 필요는 없을 것 같아요.

전사



문법은 무엇을 설명합니다 사용자가 말할 수 있는 것. Pocketsphinx가 알기로는, 어떻게그는 그것을 발음할 것이고, 문법의 각 단어가 해당 언어 모델에서 어떻게 들리는지 쓰는 것이 필요합니다. 그건 전사모든 단어. 그것은이라고 사전.

전사는 특수 구문을 사용하여 설명됩니다. 예를 들어:
똑똑해 uu m n ay j 집 d oo m

원칙적으로 복잡한 것은 없습니다. 전사에서 이중 모음은 강세를 나타냅니다. 이중자음은 부드러운 자음 뒤에 모음이 오는 것을 말합니다. 러시아어의 모든 소리에 대해 가능한 모든 조합입니다.

사용자가 장치에 부여할 이름을 미리 알 수 없기 때문에 애플리케이션의 모든 기록을 미리 설명할 수 없다는 것은 분명합니다. 따라서 우리는 러시아어 음성학의 일부 규칙에 따라 "즉시" 이러한 전사를 생성할 것입니다. 이를 위해 문자열을 입력으로 수신하고 이에 대한 올바른 표기를 생성할 수 있는 다음 PhonMapper 클래스를 구현할 수 있습니다.

음성 활성화

이는 미리 정해진 문구(또는 문구)에 반응하기 위해 항상 "방송을 듣는" 음성 인식 엔진의 기능입니다. 동시에 다른 모든 소리와 음성은 삭제됩니다. 이는 문법 설명만 하고 마이크만 켜는 것과는 다릅니다. 여기서는 이 작업의 이론과 작동 방식에 대한 메커니즘을 제시하지 않겠습니다. 최근 Pocketsphinx에서 작업하는 프로그래머가 이러한 기능을 구현했으며 이제는 API에서 즉시 사용할 수 있습니다.

한 가지는 확실히 언급할 가치가 있습니다. 활성화 문구의 경우 전사를 지정하는 것뿐만 아니라 적절한 전사를 선택해야 합니다. 감도 임계값. 값이 너무 작으면 많은 잘못된 긍정이 발생합니다(활성화 문구를 말하지 않았지만 시스템이 이를 인식하는 경우). 그리고 너무 높으면 면역력이 떨어집니다. 따라서 이 설정은 특히 중요합니다. 대략적인 값 범위 - 1e-1에서 1e-40까지 활성화 문구에 따라.

근접 센서 활성화

이 작업은 우리 프로젝트에만 해당되며 인식과 직접적인 관련이 없습니다. 코드는 기본 활동에서 직접 볼 수 있습니다.
그녀는 구현 센서이벤트 리스너접근하는 순간(센서 값이 최대값보다 작을 때) 타이머를 켜고 일정 지연 후에 센서가 여전히 차단되어 있는지 확인합니다. 이는 오탐지를 제거하기 위해 수행됩니다.
센서가 다시 차단되지 않으면 인식을 중단하고 결과를 얻습니다(아래 설명 참조).

인식을 시작해보자

Pocketsphinx는 인식 프로세스를 구성하고 실행하기 위한 편리한 API를 제공합니다. 이것들은 수업입니다 SpechRecognizer그리고 음성 인식기 설정.
인식의 구성 및 시작은 다음과 같습니다.

PhonMapper phonMapper = new PhonMapper(getAssets().open("dict/ru/hotwords")); 문법 문법 = new Grammar(names, phonMapper); Grammar.addWords(핫워드); DataFiles dataFiles = new DataFiles(getPackageName(), "ru"); 파일 hmmDir = new File(dataFiles.getHmm()); 파일 dict = new File(dataFiles.getDict()); 파일 jsgf = new File(dataFiles.getJsgf()); copyAssets(hmmDir); saveFile(jsgf, Grammar.getJsgf()); saveFile(dict, Grammar.getDict()); mRecognizer = SpeechRecognizerSetup.defaultSetup() .setAcousticModel(hmmDir) .setDictionary(dict) .setBoolean("-remove_noise", false) .setKeywordThreshold(1e-7f) .getRecognizer(); mRecognizer.addKeyphraseSearch(KWS_SEARCH, 핫워드); mRecognizer.addGrammarSearch(COMMAND_SEARCH, jsgf);

여기에서는 먼저 필요한 모든 파일을 디스크에 복사합니다(Pocketpshinx에서는 디스크에 기록할 음향 모델, 문법 및 사전이 필요합니다). 그런 다음 인식 엔진 자체가 구성됩니다. 모델 및 사전 파일에 대한 경로와 일부 매개변수(활성화 구문에 대한 민감도 임계값)가 표시됩니다. 다음으로 문법과 활성화 문구가 포함된 파일 경로가 구성됩니다.

이 코드에서 볼 수 있듯이 문법 및 활성화 구문 인식을 위해 하나의 엔진이 구성됩니다. 왜 이런 일이 이루어 집니까? 현재 인식해야 하는 항목 간에 빠르게 전환할 수 있습니다. 활성화 문구 인식 프로세스를 시작하는 방법은 다음과 같습니다.

MRecognizer.startListening(KWS_SEARCH);
그리고 이것은 주어진 문법에 따라 음성이 인식되는 방식입니다.

MRecognizer.startListening(COMMAND_SEARCH, 3000);
두 번째 인수(선택 사항)는 아무도 아무 말도 하지 않으면 인식이 자동으로 종료되는 밀리초 수입니다.
보시다시피 하나의 엔진만 사용하여 두 문제를 모두 해결할 수 있습니다.

인식 결과를 얻는 방법

인식 결과를 얻으려면 인터페이스를 구현하는 이벤트 리스너도 지정해야 합니다. 인식리스너.
이벤트 중 하나가 발생할 때 Pocketsphinx가 호출하는 여러 메서드가 있습니다.
  • onBeginningOfSpeech- 엔진에서 약간의 소리가 들렸습니다. 음성일 수도 있고 아닐 수도 있습니다.
  • onEndOfSpeech- 소리가 끝납니다
  • onPartialResult- 중간 인식 결과가 있습니다. 활성화 문구의 경우 이는 작동했음을 의미합니다. 논쟁 가설
  • 결과에- 최종 인정 결과. 이 메소드는 메소드가 호출된 후에 호출됩니다. 멈추다~에 음성 인식기. 논쟁 가설인식 데이터(문자열 및 점수)가 포함되어 있습니다.

onPartialResult 및 onResult 메서드를 어떤 방식으로든 구현하면 인식 논리를 변경하고 최종 결과를 얻을 수 있습니다. 우리 애플리케이션의 경우 수행되는 방법은 다음과 같습니다.

@Override public void onEndOfSpeech() ( Log.d(TAG, "onEndOfSpeech"); if (mRecognizer.getSearchName().equals(COMMAND_SEARCH)) ( mRecognizer.stop(); ) ) @Override public void onPartialResult(가설 가설) ( if (가설 == null) return; String text = hypothesis.getHypstr(); if (KWS_SEARCH.equals(mRecognizer.getSearchName())) ( startRecognition(); ) else ( Log.d(TAG, text); ) ) @Override public void onResult(가설 가설) ( mMicView.setBackgroundResource(R.drawable.ground_big_mic); mHandler.removeCallbacks(mStopRecognitionCallback); 문자열 텍스트 = 가설 != null ? 가설.getHypstr() : null; Log.d(TAG , "onResult " + 텍스트); if (COMMAND_SEARCH.equals(mRecognizer.getSearchName())) ( if (text != null) ( Toast.makeText(this, text, Toast.LENGTH_SHORT).show(); process(text ); ) mRecognizer.startListening(KWS_SEARCH); ) )

onEndOfSpeech 이벤트를 수신하고 동시에 실행할 명령을 인식하면 인식을 중지해야 하며 그 후 onResult가 즉시 호출됩니다.
onResult에서는 방금 인식된 내용을 확인해야 합니다. 이것이 명령인 경우 실행을 위해 실행하고 활성화 문구를 인식하도록 엔진을 전환해야 합니다.
onPartialResult에서는 활성화 문구를 인식하는 데만 관심이 있습니다. 이를 감지하면 즉시 명령 인식 프로세스를 시작합니다. 그 모습은 다음과 같습니다.

비공개 동기화 void startRecognition() ( if (mRecognizer == null || COMMAND_SEARCH.equals(mRecognizer.getSearchName())) return; mRecognizer.cancel(); new ToneGenerator(AudioManager.STREAM_MUSIC, ToneGenerator.MAX_VOLUME).startTone(ToneGenerator. TONE_CDMA_PIP, 200); post(400, new Runnable() ( @Override public void run() ( mMicView.setBackgroundResource(R.drawable.Background_big_mic_green); mRecognizer.startListening(COMMAND_SEARCH, 3000); Log.d(TAG, "듣기 명령"); post(4000, mStopRecognitionCallback); ) )); )
여기서 우리는 먼저 사용자에게 그의 말을 들었고 그의 명령을 받을 준비가 되었음을 알리기 위해 작은 신호를 재생합니다. 이 시간 동안에는 마이크를 꺼야 합니다. 따라서 짧은 시간 초과(신호의 지속 시간보다 약간 길어서 에코가 들리지 않도록) 후에 인식을 시작합니다. 또한 사용자가 너무 오랫동안 말하면 인식을 강제로 중지하는 스레드를 시작합니다. 이 경우에는 3초입니다.

인식된 문자열을 명령으로 변환하는 방법

음, 여기에 있는 모든 내용은 특정 응용 프로그램에만 적용됩니다. 기본 예의 경우 간단히 라인에서 장치 이름을 꺼내고 원하는 장치를 검색한 다음 스마트 홈 컨트롤러에 대한 HTTP 요청을 사용하여 상태를 변경하거나 현재 상태를 보고합니다(예: 온도 조절기). 이 논리는 Controller 클래스에서 볼 수 있습니다.

음성을 합성하는 방법

음성 합성은 인식의 역동작입니다. 여기서는 반대입니다. 사용자가 들을 수 있도록 텍스트 줄을 음성으로 바꿔야 합니다.
온도 조절기의 경우 Android 기기가 현재 온도를 말하도록 해야 합니다. API 사용 TextToSpeech이것은 매우 쉽습니다(러시아어에 대한 멋진 여성 TTS를 제공한 Google에 감사드립니다).

개인 무효 말하기(문자열 텍스트) ( 동기화됨(mSpeechQueue) ( ​​​​mRecognizer.stop(); mSpeechQueue.add(text); HashMap params = 새로운 HashMap (2); params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, UUID.randomUUID().toString()); params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_MUSIC)); params.put(TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS, "true"); mTextToSpeech.speak(text, TextToSpeech.QUEUE_ADD, params); ) )

진부한 말을 하겠지만, 합성 과정 전에 인식을 비활성화해야 합니다. 일부 장치(예: 모든 Samsung 장치)에서는 일반적으로 마이크를 듣고 동시에 무언가를 합성하는 것이 불가능합니다.
음성 합성의 끝(즉, 합성기에 의한 텍스트 말하기 프로세스의 끝)은 청취자에서 추적할 수 있습니다.

Private final TextToSpeech.OnUtteranceCompletedListener mUtteranceCompletedListener = new TextToSpeech.OnUtteranceCompletedListener() ( @Override public void onUtteranceCompleted(String utteranceId) ( syncified (mSpeechQueue) ( ​​​​mSpeechQueue.poll(); if (mSpeechQueue.isEmpty()) ( mRecognizer.startListening( KWS_SEARCH) ; ) ) ) );

여기서는 합성 대기열에 다른 것이 있는지 간단히 확인하고, 아무것도 없으면 활성화 문구 인식을 활성화합니다.

그리고 그게 다야?

예! 보시다시피 Pocketsphinx와 같은 멋진 프로젝트가 있기 때문에 장치에서 직접 음성을 빠르고 효율적으로 인식하는 것이 전혀 어렵지 않습니다. 음성 명령 인식과 관련된 문제를 해결하는데 사용할 수 있는 매우 편리한 API를 제공합니다.

이 예에서는 완전히 특정한 작업에 인식을 첨부했습니다. 스마트 홈 기기의 음성 제어. 현지 인식으로 인해 매우 빠른 속도와 오류 최소화를 달성했습니다.
다른 음성 관련 작업에도 동일한 코드를 사용할 수 있다는 것은 분명합니다. 꼭 스마트홈일 필요는 없습니다.

  • 음성 제어
  • 음성 엔진
  • 태그 추가

    녹음된 음성을 복사하는 수동 작업을 완전히 대체할 수 있는 프로그램은 없습니다. 그러나 음성을 텍스트로 번역하는 속도를 크게 높이고 촉진할 수 있는, 즉 전사를 단순화할 수 있는 솔루션이 있습니다.

    전사는 오디오 또는 비디오 파일을 텍스트 형식으로 녹음하는 것입니다. 인터넷에는 수행자에게 텍스트 필사 대가로 일정 금액을 지급하는 유료 유료 작업이 있습니다.

    음성을 텍스트로 번역하는 것이 유용합니다.

    • 학생들은 녹음된 오디오나 비디오 강의를 텍스트로 번역하고,
    • 웹사이트와 블로그를 운영하는 블로거,
    • 책과 글을 쓰는 작가, 언론인,
    • 웨비나, 연설 등 후에 문자가 필요한 정보 사업가,
    • 타이핑에 어려움이 있는 사람들 - 편지를 받아쓰고 가족이나 친구에게 보낼 수 있습니다.
    • 다른 옵션.

    PC, 모바일 애플리케이션, 온라인 서비스에서 사용할 수 있는 가장 효과적인 도구에 대해 설명합니다.

    1 웹사이트 speechpad.ru

    이는 Google Chrome 브라우저를 사용하여 음성을 텍스트로 번역할 수 있는 온라인 서비스입니다. 이 서비스는 마이크 및 기성 파일과 함께 작동합니다. 물론 외부 마이크를 사용하고 직접 받아쓰면 품질이 훨씬 높아집니다. 하지만 YouTube 동영상에서도 서비스가 잘 작동합니다.

    "녹음 활성화"를 클릭하고 "마이크 사용"에 대한 질문에 답하십시오. 이렇게 하려면 "허용"을 클릭하십시오.

    그림 1의 버튼 1을 클릭하면 서비스 사용에 대한 긴 지침을 접을 수 있습니다. 3. 간단한 회원가입만으로 광고를 없앨 수 있습니다.

    쌀. 3. 음성 패드 서비스

    완성된 결과는 쉽게 편집할 수 있습니다. 이렇게 하려면 강조 표시된 단어를 수동으로 수정하거나 다시 받아쓰게 해야 합니다. 작업 결과는 개인 계정에 저장되며 컴퓨터로 다운로드할 수도 있습니다.

    스피치 패드 작업에 대한 비디오 강의 목록:

    Youtube나 컴퓨터에서 비디오를 복사할 수 있지만 믹서가 필요합니다. 자세한 내용은 다음과 같습니다.

    비디오 "오디오 전사"

    이 서비스는 7개 언어로 운영됩니다. 작은 마이너스가 있습니다. 완성된 오디오 파일을 복사해야 하는 경우 해당 사운드가 스피커를 통해 들려 에코 형태로 추가 간섭이 발생한다는 사실에 있습니다.

    2 서비스 받아쓰기.io

    무료로 쉽게 음성을 텍스트로 번역할 수 있는 훌륭한 온라인 서비스입니다.

    쌀. 4. 서비스 받아쓰기.io

    그림 1의 4 – 페이지 끝에서 러시아어를 선택할 수 있습니다. Google Chrome 브라우저에서는 언어가 선택되어 있지만 Mozilla에는 어떤 이유로 그러한 옵션이 없습니다.

    완성된 결과물을 자동으로 저장하는 기능이 구현된 점이 주목할 만합니다. 이렇게 하면 탭이나 브라우저를 닫아 실수로 삭제하는 것을 방지할 수 있습니다. 이 서비스는 완성된 파일을 인식하지 못합니다. 마이크와 함께 작동합니다. 받아쓰기할 때 구두점의 이름을 지정해야 합니다.

    텍스트가 매우 정확하게 인식되며 철자 오류가 없습니다. 키보드에서 직접 구두점을 삽입할 수 있습니다. 완성된 결과는 컴퓨터에 저장할 수 있습니다.

    3 리얼스피커

    이 프로그램을 사용하면 사람의 말을 텍스트로 쉽게 번역할 수 있습니다. Windows, Android, Linux, Mac 등 다양한 시스템에서 작동하도록 설계되었습니다. 도움을 받으면 음성을 마이크로 변환하고(예: 노트북에 내장할 수 있음) 오디오 파일로 녹음할 수 있습니다.

    13개 세계 언어를 이해할 수 있습니다. 온라인 서비스로 작동하는 베타 버전의 프로그램이 있습니다.

    위의 링크를 따라가서 러시아어를 선택하고 오디오 또는 비디오 파일을 온라인 서비스에 업로드하고 전사 비용을 지불해야 합니다. 전사 후 결과 텍스트를 복사할 수 있습니다. 전사할 파일이 클수록 처리하는 데 더 많은 시간이 소요됩니다. 자세한 내용은 다음과 같습니다.

    2017년에는 RealSpeaker를 사용하는 무료 전사 옵션이 있었지만 2018년에는 그러한 옵션이 없습니다. 복사된 파일을 모든 사용자가 다운로드할 수 있다는 점은 매우 혼란스럽습니다. 아마도 이 부분은 개선될 것입니다.

    프로그램 개발자의 연락처(VKontakte, Facebook, Youtube, Twitter, 이메일, 전화)는 해당 웹사이트 페이지(보다 정확하게는 사이트 바닥글)에서 확인할 수 있습니다.

    4 스피치로거

    Android에서 실행되는 모바일 장치용 이전 애플리케이션의 대안입니다. 앱 스토어에서 무료로 이용 가능:

    텍스트가 자동으로 편집되고 문장 부호가 추가됩니다. 메모를 직접 받아쓰거나 목록을 만드는 데 매우 편리합니다. 결과적으로 텍스트의 품질은 매우 좋습니다.

    5 드래곤 받아쓰기

    Apple에서 모바일 기기용으로 무료로 배포하는 애플리케이션입니다.

    이 프로그램은 15개 언어로 작동할 수 있습니다. 결과를 편집하고 목록에서 원하는 단어를 선택할 수 있습니다. 모든 소리를 명확하게 발음해야 하며 불필요한 일시 중지를 하지 말고 억양을 피해야 합니다. 가끔 단어의 어미에 오류가 있는 경우가 있습니다.

    예를 들어, Dragon Dictation 애플리케이션은 소유자가 아파트 주변을 이동하는 동안 상점의 쇼핑 목록을 받아쓰는 데 사용됩니다. 그곳에 도착하면 따로 들을 필요 없이 메모에 있는 텍스트를 볼 수 있습니다.

    실습에 어떤 프로그램을 사용하든 결과를 다시 확인하고 특정 조정을 할 수 있도록 준비하십시오. 이것이 오류 없이 완벽한 텍스트를 얻는 유일한 방법입니다.

    또한 유용한 서비스:

    최신 컴퓨터 활용 능력 관련 기사를 받은 편지함으로 직접 받아보세요.
    이미 더 구독자 3,000명

    .

    제품 및 기술:

    Visual Studio, C#, .NET 음성 라이브러리

    이 기사에서는 다음 내용을 설명합니다.

    • 콘솔 애플리케이션에 음성 인식 지원을 추가합니다.
    • 인식된 음성 처리;
    • 음성 인식 라이브러리 설치;
    • Microsoft.Speech와 System.Speech의 비교;
    • Windows Forms 애플리케이션에 음성 인식 지원을 추가합니다.

    음성 활성화 개인 비서인 Windows Phone Cortana(또한 헛되이 이야기할 수 없는 과일 회사의 대응물)의 출현으로 음성 지원 앱이 소프트웨어 개발에서 점점 더 두드러지게 되었습니다. 이 기사에서는 Windows 콘솔 애플리케이션, Windows Forms 애플리케이션 및 WPF(Windows Presentation Foundation)에서 음성 인식 및 합성을 시작하는 방법을 보여 드리겠습니다.

    Windows Phone 앱, ASP.NET 웹 앱, Windows 스토어 앱, Windows RT 및 Xbox Kinect에 음성 기능을 추가할 수도 있지만 기술은 이 문서에서 설명하는 기술과 다릅니다.

    이 기사에서 정확히 무엇을 논의할지에 대한 아이디어를 얻는 좋은 방법은 다음 두 가지 데모 프로그램의 스크린샷을 보는 것입니다. 쌀. 1그리고 2 . 콘솔 애플리케이션을 시작한 후 쌀. 1즉시 "나는 깨어있습니다."라는 문구를 말합니다. 물론, 이 기사를 읽는 동안 데모 애플리케이션을 들을 수 없으므로 컴퓨터가 말하는 내용의 텍스트가 표시됩니다. 그런 다음 사용자는 "Speech on"이라는 명령을 말합니다. 데모 애플리케이션은 인식된 텍스트로 응답한 다음 내부적으로 두 개의 숫자를 추가하라는 요청을 듣고 응답합니다.

    쌀. 1. 콘솔 애플리케이션의 음성 인식 및 합성


    쌀. 2. Windows Forms 애플리케이션의 음성 인식

    사용자는 앱에 1과 2를 추가한 다음 2와 3을 추가하도록 요청했습니다. 이 애플리케이션은 음성 명령을 인식하고 음성으로 답변을 제공했습니다. 나중에 음성 인식을 활용하는 더 유용한 방법에 대해 설명하겠습니다.

    그런 다음 사용자는 추가 명령 듣기를 비활성화하는 음성 명령인 "음성 꺼짐"을 말했지만 음성 인식을 완전히 비활성화하지는 않습니다. 이 구두 명령 뒤에 하나와 둘을 더하는 다음 명령은 무시되었습니다. 마지막으로 사용자는 다시 명령 듣기를 켜고 의미 없는 명령인 "Klatu barada nikto"를 말했는데, 애플리케이션은 이를 음성 인식을 완전히 비활성화하고 자체 종료하라는 명령으로 인식했습니다.

    ~에 쌀. 2더미 음성 지원이 가능한 Windows Forms 애플리케이션을 보여줍니다. 이 애플리케이션은 음성 명령을 인식하지만 음성 출력으로 응답하지 않습니다. 앱을 처음 실행했을 때 Speech On 체크박스가 선택되어 있지 않아 음성 인식이 활성화되지 않았음을 나타냅니다. 사용자는 이 체크박스를 선택한 다음 "안녕하세요"라고 말했습니다. 응용 프로그램은 창 아래쪽에 있는 ListBox 컨트롤에 인식된 텍스트를 표시하여 응답했습니다.

    그러자 사용자는 "텍스트 상자 1을 빨간색으로 설정해 주세요"라고 말했습니다. 애플리케이션은 음성을 인식하고 "텍스트 상자 1을 빨간색으로 설정"이라고 응답했는데, 이는 사용자가 말한 것과 거의 (정확하지는 않지만) 정확합니다. 켜져 있지만 쌀. 2보이지는 않지만 창 상단에 있는 TextBox 컨트롤의 텍스트는 실제로 빨간색입니다.

    그러자 사용자가 “텍스트 상자 1을 흰색으로 설정해 주세요.”라고 말했습니다. 앱은 이를 "텍스트 상자 1 흰색 설정"으로 인식하고 그렇게 했습니다. 사용자가 "안녕하세요"라고 말하며 결론을 내리면 응용 프로그램은 해당 텍스트를 표시했지만 Windows Forms에서는 아무 작업도 수행하지 않았습니다. 예를 들어 Speech On 확인란을 지울 수도 있었습니다.

    신디사이저 객체를 사용하는 것은 매우 간단합니다.

    다음 섹션에서는 필요한 .NET 음성 라이브러리 설치를 포함하여 두 가지 데모 프로그램을 만드는 과정을 안내합니다. 이 기사에서는 사용자가 중급 이상의 프로그래밍 기술을 갖고 있지만 음성 인식 및 합성에 대해서는 아무것도 모른다고 가정합니다.

    콘솔 애플리케이션에 음성 인식 지원 추가

    다음에 표시된 데모를 만들려면 쌀. 1, Visual Studio를 시작하고 ConsoleSpeech라는 새로운 C# 콘솔 애플리케이션을 만들었습니다. Visual Studio 2010 및 2012에서 음성 도구를 성공적으로 사용했지만 비교적 최신 버전이면 괜찮습니다. 템플릿 코드를 편집기에 로드한 후 솔루션 탐색기 창의 Program.cs 파일 이름을 더 설명적인 ConsoleSpeechProgram.cs로 바꾸었고 Visual Studio에서는 Program 클래스 이름을 바꿨습니다.

    다음으로 C:\ProgramFiles (x86)\Microsoft SDKs\Speech\v11.0\Assembly에 있는 Microsoft.Speech.dll 파일에 대한 링크를 추가했습니다. 이 DLL이 내 컴퓨터에 없어 다운로드해야 했습니다. 애플리케이션에 음성 인식 및 합성을 추가하는 데 필요한 파일을 설치하는 것은 그리 간단한 일이 아닙니다. 다음 섹션에서 설치 과정을 자세히 설명하겠지만 지금은 Microsoft.Speech.dll이 시스템에 있다고 가정하겠습니다.

    음성 DLL에 대한 참조를 추가하여 최상위 시스템 네임스페이스를 가리키는 문을 제외하고 코드 상단에서 모든 using 문을 제거했습니다. 그런 다음 Microsoft.Speech.Recognition, Microsoft.Speech.Synesis 및 System.Globalization 네임스페이스에 대한 using 문을 추가했습니다. 처음 두 네임스페이스는 음성 DLL에 매핑됩니다. 혼란스러울 수 있는 System.Speech.Recognition 및 System.Speech.Synesis와 같은 네임스페이스도 있습니다. 이들의 차이점을 곧 설명하겠습니다. 세계화 네임스페이스는 기본적으로 사용 가능하며 프로젝트에 추가하기 위해 새 참조가 필요하지 않았습니다.

    데모 콘솔 애플리케이션의 모든 소스 코드는 다음에서 제공됩니다. 쌀. 삼, 이 기사와 함께 제공되는 소스 패키지에서도 사용할 수 있습니다. 주요 아이디어를 최대한 모호하게 하지 않기 위해 모든 표준 오류 처리를 제거했습니다.

    쌀. 3. 데모 콘솔 애플리케이션 소스 코드

    시스템 사용; Microsoft.Speech.Recognition 사용; Microsoft.Speech.Synesis를 사용합니다. System.Globalization 사용; 네임스페이스 ConsoleSpeech ( 클래스 ConsoleSpeechProgram ( 정적 SpeechSynthesizer ss = new SpeechSynthesizer(); static SpeechRecognitionEngine sre; static bool done = false; static bool speechOn = true; static void Main(string args) ( try ( ss.SetOutputToDefaultAudioDevice(); Console.WriteLine ("\n(말하기: 나는 깨어있습니다)"); ss.Speak("나는 깨어있습니다"); CultureInfo ci = new CultureInfo("en-us"); sre = new SpeechRecognitionEngine(ci); sre.SetInputToDefaultAudioDevice( ; sre.Speechrecognized += sre_Speechrecognized; 선택 ch_startstopcommands = 새 선택(); ch_startstopcommands.add("음성 켜기"); ch_startstopcommands.add("S Peech 끄기"); ch_startStopcommands.add(" Klatu Barada Nikto "); Grammarbuilder GB_StartStop = new GrammarBuilder(); gb_StartStop.Append(ch_StartStopCommands); Grammar g_StartStop = new Grammar(gb_StartStop); 선택 사항 ch_Numbers = new Choices(); ch_Numbers.Add("1"); ch_Numbers.Add("2"); ch_Numbers. Add("3"); ch_Numbers.Add("4"); GrammarBuilder gb_WhatIsXplusY = new GrammarBuilder(); gb_WhatIsXplusY.Append("무엇입니까?"); gb_WhatIsXplusY.Append(ch_Numbers); gb_WhatIsXplusY.Append("plus"); gb_WhatIsXplusY.Append(ch_Numbers); Grammar g_WhatIsXplusY = new Grammar(gb_WhatIsXplusY); sre.LoadGrammarAsync(g_StartStop); sre.LoadGrammarAsync(g_WhatIsXplusY); sre.RecognizeAsync(RecognizeMode.Multiple); while (done == false) ( ; ) Console.WriteLine("\n히트< enter >쉘을 닫으려면\n"); Console.ReadLine(); ) catch (Exception ex) ( Console.WriteLine(ex.Message); Console.ReadLine(); ) ) // Main static void sre_SpeechRecognized(object sender, SpeechRecognizedEventArgs e ) ( string txt = e.Result.Text; float Confidence = e.Result.Confidence; Console.WriteLine("\nRecognized: " + txt); if (신뢰도< 0.60) return; if (txt.IndexOf("speech on") >= 0) ( Console.WriteLine("음성 켜짐"); speechOn = true; ) if (txt.IndexOf("음성 꺼짐") >= 0) ( Console.WriteLine("음성 꺼짐"); speechOn = false; ) if (speechOn == false) return; if (txt.IndexOf("klatu") >= 0 && txt.IndexOf("barada") >= 0) ( ((SpeechRecognitionEngine)sender). RecognizeAsyncCancel(); done = true; Console.WriteLine("(말하기: 작별 인사)"); ss.Speak("작별 인사"); ) if (txt.IndexOf("What") >= 0 && txt.IndexOf("plus") >= 0) ( 문자열 단어 = txt.Split(" "); int num1 = int.Parse(words); int num2 = int.Parse(words); int sum = num1 + num2; Console.WriteLine("(말하기: " + 단어 + " 더하기 " + 단어 + "는 다음과 같습니다. " + sum + ")"); ss.SpeakAsync(words + " plus " +words + " = " + sum); ) ) // sre_SpeechRecognized ) // 프로그램 ) // ns

    using 문 다음에 데모 코드는 다음과 같이 시작됩니다.

    네임스페이스 ConsoleSpeech ( 클래스 ConsoleSpeechProgram ( static SpeechSynthesizer ss = new SpeechSynthesizer(); static SpeechRecognitionEngine sre; static bool done = false; static bool speechOn = true; static void Main(string args) ( ...

    클래스 수준의 SpeechSynthesizer 개체를 사용하면 애플리케이션이 음성을 합성할 수 있습니다. SpeechRecognitionEngine 개체를 사용하면 애플리케이션이 음성 단어나 문구를 듣고 인식할 수 있습니다. done 부울 변수는 전체 애플리케이션이 종료되는 시점을 결정합니다. speechOn 부울 변수는 애플리케이션이 프로그램을 종료하는 명령 이외의 명령을 수신하는지 여부를 제어합니다.

    여기서의 아이디어는 콘솔 응용 프로그램이 키보드 입력을 허용하지 않으므로 항상 명령을 수신한다는 것입니다. 그러나 speechOn이 false인 경우에는 프로그램을 종료하라는 명령만 인식되어 실행됩니다. 다른 명령은 인식되지만 무시됩니다.

    Main 메서드는 다음과 같이 시작됩니다.

    try ( ss.SetOutputToDefaultAudioDevice(); Console.WriteLine("\n(말하기: 깨어있습니다)"); ss.Speak("깨어있습니다");

    SpeechSynthesizer 개체의 인스턴스는 선언될 때 생성되었습니다. 신디사이저 객체를 사용하는 것은 매우 간단합니다. SetOutputToDefaultAudioDevice 메서드는 컴퓨터에 연결된 스피커로 출력을 보냅니다(출력을 파일로 보낼 수도 있음). Speak 메서드는 문자열을 가져와서 말합니다. 그만큼 쉽습니다.

    음성 인식은 음성 합성보다 훨씬 복잡합니다. Main 메서드는 계속해서 확인자 개체를 생성합니다.

    CultureInfo ci = new CultureInfo("en-us"); sre = 새로운 SpeechRecognitionEngine(ci); sre.SetInputToDefaultAudioDevice(); sre.SpeechRecognized += sre_SpeechRecognized;

    먼저 CultureInfo 개체는 인식할 언어(이 경우 미국 영어)를 지정합니다. CultureInfo 개체는 using 문으로 참조한 세계화 네임스페이스에 있습니다. 그런 다음 SpeechRecognitionEngine 생성자를 호출한 후 음성 입력이 기본 오디오 장치(대부분 마이크)에 할당됩니다. 대부분의 노트북에는 마이크가 내장되어 있지만 데스크탑에는 외부 마이크가 필요합니다(요즘에는 종종 헤드폰과 결합됨).

    인식기 개체의 주요 메서드는 SpeechRecognized 이벤트 처리기입니다. Visual Studio를 사용할 때 "sre.SpeechRecognized +="를 입력하고 잠시 기다리면 IntelliSense가 자동으로 이벤트 처리기 이름인 sre_SpeechRecognized로 표현식을 종료합니다. Tab 키를 눌러 제안을 수락하고 이 이름을 기본값으로 사용하는 것이 좋습니다.

    선택사항 ch_Numbers = 새로운 선택사항(); ch_Numbers.Add("1"); ch_Numbers.Add("2"); ch_Numbers.Add("3"); ch_Numbers.Add("4"); // 기술적인 관점에서 보면 // 이는 Add(new string ( "4" )); GrammarBuilder gb_WhatIsXplusY = 새로운 GrammarBuilder(); gb_WhatIsXplusY.Append("무엇입니까?"); gb_WhatIsXplusY.Append(ch_Numbers); gb_WhatIsXplusY.Append("plus"); gb_WhatIsXplusY.Append(ch_Numbers); Grammar g_WhatIsXplusY = new Grammar(gb_WhatIsXplusY);

    여기에 있는 세 가지 주요 개체는 Choices 세트, GrammarBuilder 템플릿 및 Grammar 컨트롤입니다. 인식을 위한 문법을 ​​작성할 때 인식해야 할 내용에 대한 구체적인 예를 나열하는 것부터 시작합니다. "1 더하기 2는 무엇입니까?" 그리고 “3 더하기 4는 무엇입니까?”

    그런 다음 해당 일반 템플릿을 정의합니다. 예를 들어 "What is ...을 더한 ?. 템플릿은 GrammarBuilder이며 템플릿에 전달되는 특정 값은 Choices 집합입니다. Grammar 개체는 템플릿과 선택 사항을 캡슐화합니다.

    데모 프로그램에서는 추가 항목을 1부터 4까지 제한하고 이를 Choices 세트에 문자열로 추가합니다. 보다 효율적인 접근 방식:

    문자열 번호 = 새 문자열 ("1", "2", "3", "4" ); 선택사항 ch_Numbers = 새로운 선택사항(번호);

    저는 두 가지 이유로 Choices 세트를 생성하는 데 있어 덜 효율적인 접근 방식을 제시하고 있습니다. 첫째, 한 번에 한 줄을 추가하는 것이 다른 음성 인식 예제에서 본 유일한 접근 방식이었습니다. 둘째, 한 번에 한 행씩 추가하는 것이 전혀 작동하지 않는다고 생각할 수도 있습니다. Visual Studio IntelliSense는 Add 오버로드 중 하나가 params 문자열 구문 유형의 매개 변수를 허용한다는 것을 실시간으로 보여줍니다. params 키워드를 눈치채지 못했다면 Add 메서드가 단일 문자열이 아닌 문자열 배열만 허용한다고 가정했을 수 있습니다. 그러나 그렇지 않습니다. 그는 둘 다 받아들입니다. 배열을 전달하는 것이 좋습니다.

    일련 번호에서 선택 항목 세트를 생성하는 것은 다소 특별한 경우이며 다음과 같은 프로그래밍 방식의 접근 방식을 허용합니다.

    문자열 번호 = 새 문자열; for (int i = 0; i< 100; ++i) numbers[i] = i.ToString(); Choices ch_Numbers = new Choices(numbers);

    GrammarBuilder 슬롯을 채우기 위해 Choices를 생성한 후 데모 프로그램은 GrammarBuilder를 생성한 다음 제어 Grammar를 생성합니다.

    GrammarBuilder gb_WhatIsXplusY = 새로운 GrammarBuilder(); gb_WhatIsXplusY.Append("무엇입니까?"); gb_WhatIsXplusY.Append(ch_Numbers); gb_WhatIsXplusY.Append("plus"); gb_WhatIsXplusY.Append(ch_Numbers); Grammar g_WhatIsXplusY = new Grammar(gb_WhatIsXplusY);

    데모 프로그램은 유사한 템플릿을 사용하여 시작 및 중지 명령에 대한 문법을 ​​생성합니다.

    선택사항 ch_StartStopCommands = 새로운 선택사항(); ch_StartStopCommands.Add("음성 켜기"); ch_StartStopCommands.Add("음성 끄기"); ch_StartStopCommands.Add("klatu barada nikto"); GrammarBuilder gb_StartStop = new GrammarBuilder(); gb_StartStop.Append(ch_StartStopCommands); Grammar g_StartStop = new Grammar(gb_StartStop);

    문법은 매우 유연하게 정의될 수 있습니다. 여기서 "speech on", "speech off" 및 "klatu barada nikto" 명령은 논리적으로 관련되어 있으므로 하나의 문법에 배치됩니다. 이 세 가지 명령은 세 가지 다른 문법으로 정의될 수 있으며, "speech on" 및 "speech off" 명령은 하나의 문법에 배치되고 "klatu barada nikto" 명령은 1초 안에 배치될 수 있습니다.

    모든 Grammar 개체를 만든 후에 이를 음성 인식기에 넣으면 음성 인식이 활성화됩니다.

    sre.LoadGrammarAsync(g_StartStop); sre.LoadGrammarAsync(g_WhatIsXplusY); sre.RecognizeAsync(RecognizeMode.Multiple);

    RecognizeMode.Multiple 인수는 둘 이상의 문법이 있는 경우 필요하며, 이는 가장 간단한 프로그램을 제외한 모든 경우에 해당됩니다. Main 메서드는 다음과 같이 완료됩니다.

    While (done == false) ( ; ) Console.WriteLine("\nHit< enter >쉘을 닫으려면\n"); Console.ReadLine(); ) catch (Exception ex) ( Console.WriteLine(ex.Message); Console.ReadLine(); ) ) // 메인

    이상하게 보이는 빈 while 루프를 사용하면 콘솔 응용 프로그램의 셸을 계속 실행할 수 있습니다. 클래스 수준 부울 변수 done이 음성 인식 이벤트 핸들러에 의해 true로 설정되면 루프가 완료됩니다.

    인식된 음성 처리

    음성 인식 이벤트를 처리하는 코드는 다음과 같이 시작됩니다.

    static void sre_SpeechRecognized(개체 발신자, SpeechRecognizedEventArgs e) ( string txt = e.Result.Text; float Confidence = e.Result.Confidence; Console.WriteLine("\nRecognized: " + txt); if (신뢰도< 0.60) return; ...

    인식된 텍스트는 SpeechRecognizedEventArgs 개체의 Result.Text 속성에 저장됩니다. 또는 Result.Words 세트를 사용할 수 있습니다. Result.Confidence 속성은 음성 텍스트가 인식기와 연결된 문법과 얼마나 잘 일치하는지에 대한 대략적인 추정치인 0.0에서 1.0 사이의 값을 저장합니다. 데모 프로그램은 인식된 텍스트에서 신뢰도가 낮은 텍스트를 무시하도록 이벤트 핸들러에 지시합니다.

    신뢰도 값은 문법의 복잡성, 마이크 품질 및 기타 요인에 따라 크게 달라집니다. 예를 들어, 데모 프로그램이 1부터 4까지의 숫자만 인식하면 내 컴퓨터의 신뢰도 값은 일반적으로 0.75 정도입니다. 하지만 문법이 1부터 100까지의 숫자를 인식해야 한다면 신뢰도 값은 약 0.25로 떨어진다. 간단히 말해서, 좋은 음성 인식 결과를 얻으려면 일반적으로 신뢰도 값을 실험해야 합니다.

    if (txt.IndexOf("음성 켜짐") >= 0) ( Console.WriteLine("음성이 이제 켜짐"); speechOn = true; ) if (txt.IndexOf("음성 꺼짐") >= 0) ( 콘솔 .WriteLine("음성이 꺼졌습니다."); speechOn = false; ) if (speechOn == false) return;

    처음에는 완전히 명확하지 않을 수도 있지만 이 논리는 생각해 보면 이해가 될 것입니다. 그런 다음 비밀 종료 명령이 처리됩니다.

    if (txt.IndexOf("klatu") >= 0 && txt.IndexOf("barada") >= 0) ( ((SpeechRecognitionEngine)sender).RecognizeAsyncCancel(); done = true; Console.WriteLine("(말하기: 작별 인사)"); ss.Speak("작별 인사"); )

    음성 인식 엔진은 실제로 말도 안되는 단어를 인식할 수 있습니다. Grammar 객체에 객체의 내장 사전에 없는 단어가 포함되어 있는 경우 Grammar는 가능하면 의미론적 휴리스틱을 사용하여 해당 단어를 식별하려고 시도하며 일반적으로 매우 성공적입니다. 그래서 나는 올바른 "klaatu"(오래된 공상 과학 영화에서 나온) 대신 "klatu"를 사용했습니다.

    또한 문법으로 인식되는 모든 텍스트(“klatu barada nikto”)를 처리할 필요는 없습니다. 단지 문법 구문(“klatu” 및 “barada”)을 고유하게 식별할 수 있는 충분한 정보만 있으면 됩니다.

    If (txt.IndexOf("What") >= 0 && txt.IndexOf("plus") >= 0) ( 문자열 단어 = txt.Split(" "); int num1 = int.Parse(words); int num2 = int.Parse(단어); int sum = num1 + num2; Console.WriteLine("(말하기: " + 단어 + " 더하기 " + 단어 + " 같음 " + sum + ")"); ss.SpeakAsync(단어 + " 더하기 " + 단어 + " 같음 " + sum); ) ) // sre_SpeechRecognized ) // 프로그램 ) // ns

    Results.Text의 텍스트는 대소문자를 구분합니다("무엇" 및 "무엇"). 문구를 인식하면 특정 단어로 구문 분석할 수 있습니다. 이 경우 인식된 텍스트는 “What is x plus y” 형식이므로 “What”은 단어로 배치되고 추가된 두 숫자(문자열)는 단어와 단어로 저장됩니다.

    라이브러리 설치

    데모 프로그램에 대한 설명에서는 필요한 모든 음성 라이브러리가 컴퓨터에 설치되어 있다고 가정합니다. 데모 프로그램을 만들고 실행하려면 SDK(Visual Studio에서 데모를 만드는 기능 제공), 런타임(데모가 생성된 후 데모 실행), 인식되고 합성된(발음) 언어 등 네 가지 패키지를 설치해야 합니다.

    SDK를 설치하려면 인터넷에서 "Speech Platform 11 SDK"를 검색하세요. 그러면 Microsoft 다운로드 센터( 쌀. 4). 다운로드 버튼을 클릭하면 다음과 같은 옵션이 표시됩니다. 쌀. 5. SDK는 32비트 및 64비트 버전으로 제공됩니다. 시스템의 비트 크기에 관계없이 32비트 버전을 사용하는 것이 좋습니다. 64비트 버전은 일부 응용프로그램에서 작동하지 않습니다.


    쌀. 4. Microsoft 다운로드 센터의 기본 SDK 설치 페이지


    쌀. 5. 음성 SDK 설치

    x86(32비트 시스템의 경우)에서는 단일 .msi 파일만 필요합니다. 이 파일을 선택하고 다음을 클릭하면 여기에서 설치 프로그램을 직접 실행할 수 있습니다. 음성 라이브러리는 설치가 완료된 시점에 대해 많은 피드백을 제공하지 않으므로 성공 메시지를 찾지 마십시오.


    쌀. 6. 런타임 환경 설치

    SDK와 동일한 플랫폼 버전(데모에서는 11)과 비트 심도(32 또는 64)를 선택하는 것이 매우 중요합니다. 다시 한번 말씀드리지만, 64비트 시스템에서 실행 중이더라도 32비트 버전을 강력히 권장합니다.

    그런 다음 인식 언어를 설정할 수 있습니다. 다운로드 페이지는 다음에서 제공됩니다. 쌀. 7. 데모 프로그램은 MSSpeech_SR_en-us_TELE.msi(영어-미국) 파일을 사용합니다. SR은 음성 인식을 나타내고 TELE는 전화 통신을 나타냅니다. 이는 인식된 언어가 전화나 데스크톱 마이크 등 저품질 오디오 입력과 함께 작동하도록 설계되었음을 의미합니다.


    쌀. 7. 인식 언어 설정

    마지막으로 음성 합성을 위한 언어와 음성을 설정할 수 있습니다. 다운로드 페이지는 다음에서 제공됩니다. 쌀. 8. 데모 프로그램은 MSSpeech_TTS_en-us_Helen.msi 파일을 사용합니다. TTS(텍스트 음성 변환)는 본질적으로 음성 합성과 동의어입니다. 사용 가능한 두 가지 음성은 영어, 미국입니다. 다른 영어 음성도 있지만 미국 음성은 없습니다. 합성 언어 파일을 만드는 것은 매우 어려운 작업입니다. 그러나 다양한 회사에서 다른 음성을 구입하여 설치할 수 있습니다.


    쌀. 8. 음성 및 합성 언어 설정

    흥미롭게도 음성 인식 언어와 음성/음성 합성 언어는 실제로 완전히 다른 것이지만 두 패키지 모두 동일한 다운로드 페이지에 있는 옵션입니다. 다운로드 센터 UI를 사용하면 인식언어와 합성언어를 모두 확인할 수 있는데, 동시에 설치하려니 제겐 너무 아깝기 때문에 따로 설치하는 것을 추천드립니다.

    Microsoft.Speech와 System.Speech 비교

    Windows 애플리케이션용 음성 인식 및 합성을 처음 사용하는 경우 여러 음성 플랫폼이 있으므로 설명서를 보고 쉽게 혼란스러울 수 있습니다. 특히 이 문서의 데모 프로그램에서 사용되는 Microsoft.Speech.dll 라이브러리 외에도 Windows 운영 체제의 일부인 System.Speech.dll이라는 라이브러리가 있습니다. 두 라이브러리는 API가 거의 동일하지만 완전히 동일하지는 않다는 점에서 유사합니다. 따라서 인터넷에서 음성 처리 예제를 찾고 완전한 프로그램이 아닌 코드 조각을 보면 예제가 System.Speech인지 Microsoft.Speech인지 전혀 명확하지 않습니다.

    음성 처리를 처음 사용하는 경우 System.Speech 대신 Microsoft.Speech 라이브러리를 사용하여 .NET 애플리케이션에 음성 지원을 추가하세요.

    두 라이브러리 모두 공통 핵심 코드 기반과 유사한 API를 공유하지만 확실히 다릅니다. 몇 가지 주요 차이점은 다음에 요약되어 있습니다. 테이블 1.

    테이블 1. Microsoft.Speech와 System.Speech의 주요 차이점

    System.Speech DLL은 OS의 일부이므로 모든 Windows 시스템에 설치됩니다. Microsoft.Speech DLL(및 관련 런타임 및 언어)을 시스템에 다운로드하여 설치해야 합니다. System.Speech를 사용한 인식에는 일반적으로 사용자가 일부 텍스트를 읽을 때 특정 사용자에 대한 훈련이 필요하며 시스템은 이 사용자의 발음 특성을 이해하는 방법을 학습합니다. Microsoft.Speech를 사용한 인식은 모든 사용자에게 즉시 적용됩니다. System.Speech는 거의 모든 단어를 인식할 수 있습니다(이를 무료 받아쓰기라고 함). Microsoft.Speech는 프로그램에 정의된 Grammar 개체에 있는 단어와 구만 인식합니다.

    Windows Forms 애플리케이션에 음성 인식 지원 추가

    Windows Forms 또는 WPF 애플리케이션에 음성 인식 및 합성 지원을 추가하는 프로세스는 콘솔 애플리케이션의 프로세스와 유사합니다. 다음과 같은 데모 프로그램을 만들려면 쌀. 2, Visual Studio를 시작하고 새로운 C# Windows Forms 애플리케이션을 만들고 이름을 WinFormSpeech로 바꿨습니다.

    템플릿 코드를 편집기에 로드한 후 콘솔 프로그램에서 했던 것처럼 솔루션 탐색기 창에 Microsoft.Speech.dll 파일에 대한 링크를 추가했습니다. 소스 코드 상단에서 불필요한 using 문을 제거하고 System, Data, Drawing 및 Forms 네임스페이스에 대한 참조만 남겼습니다. 그런 다음 Microsoft.Speech.Recognition 및 System.Globalization 네임스페이스에 대한 두 개의 using 문을 추가했습니다.

    Windows Forms 기반 데모에서는 음성 합성을 사용하지 않으므로 Microsoft.Speech.Synesis 라이브러리에 연결하지 않습니다. Windows Forms 애플리케이션에 음성 합성을 추가하는 것은 콘솔 애플리케이션에서와 동일합니다.

    디자인 모드의 Visual Studio에서 TextBox, CheckBox 및 ListBox 컨트롤을 양식으로 끌어 놓았습니다. CheckBox를 두 번 클릭하면 Visual Studio에서 자동으로 기본 CheckChanged 이벤트 처리기 메서드가 생성됩니다.

    데모 콘솔 프로그램은 즉시 음성 명령을 듣기 시작했고 종료될 때까지 계속해서 듣기 시작했습니다. 이 접근 방식은 Windows Forms 애플리케이션에서 사용할 수 있지만 대신 사용자가 CheckBox 컨트롤(예: 확인란)을 사용하여 음성 인식을 켜거나 끌 수 있도록 허용하기로 결정했습니다.

    부분 클래스가 정의된 데모 프로그램의 Form1.cs 파일에 있는 소스 코드는 다음과 같습니다. 쌀. 9. 음성 인식 엔진 개체가 Form 멤버로 선언되고 생성됩니다. 양식 생성자에서 SpeechRecognized 이벤트 핸들러를 연결한 다음 두 개의 Grammars 개체를 만들고 로드합니다.

    공용 Form1() ( 초기화구성요소(); sre.SetInputToDefaultAudioDevice(); sre.SpeechRecognized += sre_SpeechRecognized; 문법 g_HelloGoodbye = GetHelloGoodbyeGrammar(); 문법 g_SetTextBox = GetTextBox1TextGrammar(); sre.LoadGrammarAsync(g_HelloGoodby e);sre.LoadGram marAsync(g_SetTextBox) ; // sre.RecognizeAsync()는 // CheckBox 이벤트 핸들러에 있습니다)

    쌀. 9. Windows Forms에 음성 인식 지원 추가

    시스템 사용; System.Data 사용; System.드로잉 사용; System.Windows.Forms 사용; Microsoft.Speech.Recognition 사용; System.Globalization 사용; 네임스페이스 WinFormSpeech ( 공개 부분 클래스 Form1: Form ( 정적 CultureInfo ci = new CultureInfo("en-us"); static SpeechRecognitionEngine sre = new SpeechRecognitionEngine(ci); public Form1() ( InitializeComponent(); sre.SetInputToDefaultAudioDevice(); sre .SpeechRecognized += sre_SpeechRecognized; 문법 g_HelloGoodbye = GetHelloGoodbyeGrammar(); 문법 g_SetTextBox = GetTextBox1TextGrammar(); sre.LoadGrammarAsync(g_HelloGoodbye); sre.LoadGrammarAsync(g_SetTextBox); // sre.Recognize Async()는 // CheckBox 이벤트에 있습니다. 핸들러 ) static Grammar GetHelloGoodbyeGrammar() ( 선택사항 ch_HelloGoodbye = new Choices(); ch_HelloGoodbye.Add("hello"); ch_HelloGoodbye.Add("goodbye"); GrammarBuilder gb_result = new GrammarBuilder(ch_HelloGoodbye); Grammar g_result = new Grammar(gb_result) ; g_result 반환; ) static Grammar GetTextBox1TextGrammar() ( Choices ch_Colors = new Choices(); ch_Colors.Add(new string ( "red", "white", "blue" )); GrammarBuilder gb_result = new GrammarBuilder(); gb_result.Append("텍스트 상자 1 설정"); gb_result.Append(ch_Colors); Grammar g_result = new Grammar(gb_result); g_result를 반환; ) private void checkBox1_CheckedChanged(객체 전송자, EventArgs e) ( if (checkBox1.Checked == true) sre.RecognizeAsync(RecognizeMode.Multiple); else if (checkBox1.Checked == false) // 비활성화됨 sre.RecognizeAsyncCancel(); ) void sre_SpeechRecognized(객체 송신자, SpeechRecognizedEventArgs e) ( string txt = e.Result.Text; float conf = e.Result.Confidence; if (conf< 0.65) return; this.Invoke(new MethodInvoker(() =>( listBox1.Items.Add("당신이 말하는 것을 들었습니다: " + txt); ))); // WinForm 관련 사항 if (txt.IndexOf("text") >= 0 && txt.IndexOf("box") >= 0 && txt.IndexOf("1")>= 0) ( 문자열 단어 = txt.Split( " "); this.Invoke(new MethodInvoker(() => ( textBox1.Text = 단어; ))); // WinForm 관련 사항 ) ) ) // Form ) // ns

    콘솔 프로그램에서처럼 두 개의 Grammar 개체를 직접 만들 수도 있었지만, 그 대신 코드를 좀 더 명확하게 만들기 위해 작업을 수행하는 두 개의 도우미 메서드(GetHelloGoodbyeGrammar 및 GetTextBox1TextGrammar)를 정의했습니다.

    static Grammar GetTextBox1TextGrammar() ( 선택 사항 ch_Colors = new Choices(); ch_Colors.Add(새 문자열( "red", "white", "blue" )); GrammarBuilder gb_result = new GrammarBuilder(); gb_result.Append("텍스트 설정 상자 1"); gb_result.Append(ch_Colors); 문법 g_result = new Grammar(gb_result); return g_result; )

    이 도우미 메서드는 "텍스트 상자 1 빨간색 설정"이라는 문구를 인식합니다. 그러나 사용자는 이 문구를 정확하게 발음할 필요는 없습니다. 예를 들어, "텍스트 상자 1의 텍스트를 빨간색으로 설정하세요"라고 말하면 음성 인식 엔진은 문법과의 정확한 일치보다 신뢰도 값이 낮지만 여전히 "텍스트 상자 1의 텍스트를 빨간색으로 설정하세요"라는 문구를 인식합니다. 주형. 즉, Grammar 개체를 만들 때 구문의 모든 변형을 고려할 필요는 없습니다. 이는 음성 인식의 사용을 근본적으로 단순화합니다.

    CheckBox의 이벤트 핸들러는 다음과 같이 정의됩니다.

    private void checkBox1_CheckedChanged(객체 전송자, EventArgs e) ( if (checkBox1.Checked == true) sre.RecognizeAsync(RecognizeMode.Multiple); else if (checkBox1.Checked == false) // 비활성화됨 sre.RecognizeAsyncCancel(); )

    음성 인식 엔진 개체인 sre(음성 인식 엔진)는 Windows Forms 애플리케이션이 작동하는 동안 항상 존재합니다. 이 개체는 사용자가 CheckBox를 각각 전환할 때 RecognizeAsync 및 RecognizeAsyncCancel 메서드를 호출하여 활성화 및 비활성화됩니다.

    SpeechRecognized 이벤트 처리기 정의는 다음으로 시작됩니다.

    void sre_SpeechRecognized(객체 송신자, SpeechRecognizedEventArgs e) ( string txt = e.Result.Text; float conf = e.Result.Confidence; if (conf< 0.65) return; ...

    어느 정도 지속적으로 사용되는 Result.Text 및 Result.Confidence 속성 외에도 Result 개체에는 탐색할 수 있는 유용하지만 더 복잡한 여러 속성이 있습니다. 예를 들어, 동음어 및 교체WordUnits입니다. 또한 음성 인식 엔진은 SpeechHypotheised와 같은 몇 가지 유용한 이벤트를 제공합니다.

    this.Invoke((Action)(() => listBox1.Items.Add("당신이 말하는 것을 들었습니다: " + txt)));

    이론적으로 MethodInvoker는 Windows.Forms 네임스페이스의 일부이고 따라서 Windows Forms 애플리케이션에만 해당되므로 이 상황에서는 MethodInvoker 대리자를 사용하는 것이 Action보다 약간 더 효율적입니다. Action 대리자가 더 다양해졌습니다. 이 예에서는 음성 인식 엔진을 통해 Windows Forms 애플리케이션을 완벽하게 조작할 수 있음을 보여줍니다. 이는 매우 강력하고 유용한 기능입니다.

    결론

    .NET 애플리케이션에서 음성 합성 및 인식을 탐색하려는 경우 이 문서에 제시된 정보를 바로 시작하는 데 도움이 될 것입니다. 초기 학습 곡선과 구성 요소 설치라는 난관을 극복하고 나면 기술 자체를 익히는 것은 매우 쉽습니다. 음성 합성 및 인식의 실제 과제는 그것이 실제로 유용한지를 이해하는 것입니다.

    콘솔 프로그램을 사용하면 사용자가 질문하고 프로그램이 답변하는 흥미로운 대화를 생성하여 본질적으로 Cortana와 유사한 환경을 만들 수 있습니다. 컴퓨터 스피커에서 음성이 나올 때 마이크가 음성을 포착하여 다시 인식할 수 있으므로 주의해야 합니다. 제가 질문을 하면 앱이 그것을 인식하고 응답하지만, 음성 응답이 다음 인식 이벤트를 촉발하고 결국 재미있고 끝이 없는 음성 루프에 빠지는 꽤 재미있는 상황에 처해 있는 것을 발견했습니다.

    콘솔 프로그램에서 음성을 사용할 수 있는 또 다른 방법은 "Launch Notepad" 및 "Launch Word"와 같은 명령을 인식하는 것입니다. 즉, 이러한 콘솔 프로그램을 컴퓨터에서 사용하면 키보드와 마우스를 많이 조작해야 하는 작업을 수행할 수 있습니다.

    제임스 맥카프리(제임스 맥카프리 박사) 워싱턴 주 레드몬드에 있는 Microsoft Research에서 근무합니다. 그는 Internet Explorer 및 Bing을 포함한 여러 Microsoft 제품 개발에 참여했습니다. 그는 다음 주소로 연락할 수 있습니다. [이메일 보호됨].

    이 기사를 검토해 주신 Microsoft Research 전문가 Rob Gruen, Mark Marron 및 Curtis von Veh에게 감사드립니다.