성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 그런 부분은 클라우드 업체 쪽에 문의를 하는 것이 더 좋지 않을...
[정성태] 정적 분석과 함께, 이제는 실행 시 성능 분석까지 (비록 Azu...
[정성태] .NET Source Browser를 이용해 Roslyn 소스 ...
[정성태] Experimental C# Interceptors: AOT &...
[정성태] .NET Conf 2023 (Day 2) - Tiny, fast...
[정성태] The end of the Tye Experiment #1622...
[정성태] This is a simple app that converts ...
[정성태] Wrathmark: An Interesting Compute W...
[정성태] FFmpeg Filters Every Youtuber Needs...
[정성태] 일단, PInvokeStackImbalance 오류가 발생했다는...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>C# - Windows 10 운영체제의 데스크톱 앱에서 음성인식(SpeechRecognizer) 사용하는 방법</h1> <p> (업데이트: 2023-03-30) 이 글에 대한 질문은 더 이상 받지 않습니다. (하시다 보면, 제가 왜 이 기술에 대해 흥미를 못 느끼는 지 아시게 될 것입니다. ^^ SpeechRecognitionEngine에 특별한 업데이트가 없는 한 다루지 않을 것입니다.)<br /> <br /> <hr style='width: 50%' /><br /> <br /> TTS(Text-to-Speech)를 다뤘으니,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# - Windows 10 운영체제의 데스크톱 앱에서 TTS(SpeechSynthesizer) 사용하는 방법 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/11412'>http://www.sysnet.pe.kr/2/0/11412</a> </pre> <br /> 당연히 이제 음성인식을 봐야 할 차례입니다. ^^ 새로운 (Windows.Media.SpeechRecognition.)SpeechRecognizer 역시 Windows 10부터 지원하는데,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Windows.Media.SpeechRecognition.SpeechRecognizer ; <a target='tab' href='https://learn.microsoft.com/en-us/uwp/api/windows.media.speechrecognition.speechrecognizer'>https://learn.microsoft.com/en-us/uwp/api/windows.media.speechrecognition.speechrecognizer</a> * 최소 사양: Windows 10 (introduced v10.0.10240.0) </pre> <br /> Windows Phone 예제 코드로 사용법이 잘 공개돼 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Windows-universal-samples/Samples/SpeechRecognitionAndSynthesis/ ; <a target='tab' href='https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/SpeechRecognitionAndSynthesis'>https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/SpeechRecognitionAndSynthesis</a> </pre> <br /> 예제 프로젝트의 xaml 파일명을 보면 대충 어떤 식의 음성 인식이 가능한지 짐작할 수 있습니다.<br /> <br /> <ul> <li>Scenario_ContinuousDictation.xaml</li> <li>Scenario_ContinuousRecognitionListGrammar.xaml</li> <li>Scenario_ContinuousRecognitionSRGSGrammar.xaml</li> <li>Scenario_ListConstraint.xaml</li> <li>Scenario_PauseAsync.xaml</li> <li>Scenario_PredefinedDictationGrammar.xaml</li> <li>Scenario_PredefinedWebSearchGrammar.xaml</li> <li>Scenario_SRGSConstraint.xaml</li> </ul> <br /> <hr style='width: 50%' /><br /> <br /> 방법은 역시 <a target='tab' href='http://www.sysnet.pe.kr/2/0/11412'>지난번</a>과 별반 다르지 않습니다. 우선, UWP 타입을 사용하기 위한 참조를 추가하고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C:\Program Files (x86)\Windows Kits\10\UnionMetadata\Windows.winmd C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\System.Runtime.WindowsRuntime.dll </pre> <br /> 음성 인식을 위한 객체를 생성하면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > _speechRecognizer = new SpeechRecognizer(speechLanguage); </pre> <br /> 그다음 음성 인식을 위한 규칙을 적용하고, (아래의 예에서는 Free Dictation으로 음성 인식을 합니다.)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > var dictationConstraint = new SpeechRecognitionTopicConstraint(<span style='color: blue; font-weight: bold'>SpeechRecognitionScenario.Dictation</span>, "dictation"); _speechRecognizer.Constraints.Add(dictationConstraint); SpeechRecognitionCompilationResult compilationResult = await _speechRecognizer.<span style='color: blue; font-weight: bold'>CompileConstraints</span>Async(); </pre> <br /> 이후, 음성 인식을 시작합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > SpeechRecognitionResult speechRecognitionResult = await <span style='color: blue; font-weight: bold'>_speechRecognizer.RecognizeAsync</span>(); if (speechRecognitionResult.Status == SpeechRecognitionResultStatus.Success) { string txt = <span style='color: blue; font-weight: bold'>speechRecognitionResult.Text</span>; // 사용자가 말한 문장 } </pre> <br /> 그다지 어려운 면이 없습니다. ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> 사실 Free Dictation 형식은 그다지 쓸만한 경우가 거의 없습니다. 대신, 문맥에 따라 정해진 문구를 인식하도록 만드는 것이 더 유용합니다. 가령, "Jarvis, turn off the PC"라는 문장을 인식하도록 만들고, 그 문장이 인식되었으면 TTS로 "Are you sure?"라고 되물은 후 "Yes", "No"를 인식하는 식으로 처리하는 것이 좋습니다.<br /> <br /> 문장 인식이 될 후보군을 지정하는 방법은 SpeechRecognizer.Constraints에 적절한 단어를 Add하면 됩니다. 비교를 위해 Free Dictation은 Constraints에 다음과 같이 포함했지만,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > var dictationConstraint = new <span style='color: blue; font-weight: bold'>SpeechRecognitionTopicConstraint</span>(SpeechRecognitionScenario.Dictation, "dictation"); _speechRecognizer.Constraints.Add(dictationConstraint); </pre> <br /> 문장 인식 후보군은 이렇게 제약 사항으로 추가하면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > string[] list = new[] { "Jarvis! turn off the PC", "Jarvis! open explorer" }; _speechRecognizer.Constraints.Add(new <span style='color: blue; font-weight: bold'>SpeechRecognitionListConstraint</span>(list)); await _speechRecognizer.CompileConstraintsAsync(); </pre> <br /> 위의 문장으로 음성인식을 시작하고 인식이 되면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > SpeechRecognitionResult speechRecognitionResult = await _speechRecognizer.RecognizeAsync(); if (speechRecognitionResult.Status == SpeechRecognitionResultStatus.Success) { string txt = speechRecognitionResult.Text; } </pre> <br /> 기존 제약 사항을 제거하고 새로운 제약 사항으로 채우면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > string[] list = new[] { "Yes", "No" }; _speechRecognizer.Constraints.Clear(); _speechRecognizer.Constraints.Add(new SpeechRecognitionListConstraint(list)); await _speechRecognizer.CompileConstraintsAsync(); </pre> <br /> 간단합니다. ^^<br /> <br /> (<a target='tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1209&boardid=331301885'>첨부 파일은 이 글의 예제 코드를 포함</a>합니다.)<br /> <br /> <hr style='width: 50%' /><br /> <br /> 이하 오류 정리입니다.<br /> <br /> 다음과 같은 오류가 발생한다면?<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > {"'System.__ComObject' does not contain a definition for 'GetAwaiter'"} at CallSite.Target(Closure , CallSite , ComObject ) at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0) at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0) at Listener10.MainWindow.<InitSpeechRecognizer>d__3.MoveNext() in F:\Listener10\MainWindow.xaml.cs:line 59 </pre> <br /> Task가 아닌 객체를 await 했을 때 발생하는 것입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > dynamic result = GetTest(); await result; </pre> <br /> <hr style='width: 50%' /><br /> <br /> 데스크톱 형식의 응용 프로그램에서 IAsyncOperation을 사용하면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Windows.Foundation.IAsyncOperation<SpeechRecognitionResult> result = _speechRecognizer.RecognizeAsync(); </pre> <br /> 이런 오류가 발생합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Error CS0433 The type 'IAsyncOperation<TResult>' exists in both 'Windows.Foundation.FoundationContract, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime' and 'Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime' </pre> <br /> 오류 메시지에 따라 Windows.Foundation.IAsyncOperation<TResult> 타입이 Windows.winmd에도 있고, Windows.Foundation.FoundationContract.winmd에도 있기 때문입니다. 이런 경우에는 TResult 타입을 곧바로 반환받도록 다음과 같이 처리를 하면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > SpeechRecognitionResult speechRecognitionResult = <span style='color: blue; font-weight: bold'>await</span> _speechRecognizer.RecognizeAsync(); </pre> <br /> <hr style='width: 50%' /><br /> <br /> 다음의 코드를 호출 시,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > _speechRecognizer.RecognizeWithUIAsync(); </pre> <br /> 이런 예외가 발생할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > The text associated with this error code could not be found. The speech privacy policy was not accepted prior to attempting a speech recognition. </pre> <br /> 검색해 보면, <br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Exception: The speech privacy policy was not accepted prior to attempting a speech recognition ; <a target='tab' href='https://stackoverflow.com/questions/42391526/exception-the-speech-privacy-policy-was-not-accepted-prior-to-attempting-a-spee'>https://stackoverflow.com/questions/42391526/exception-the-speech-privacy-policy-was-not-accepted-prior-to-attempting-a-spee</a> </pre> <br /> "Settings" / "Time & Language" / "Speech"에서 "Related settings" 범주의 "Speech, inking, & typing privacy settings" 링크를 눌러 나오는 다음의 화면에서,<br /> <br /> <img onclick='toggle_img(this)' class='imgView' alt='asr_rec_error_1.png' src='/SysWebRes/bbs/asr_rec_error_1.png' /><br /> <br /> "Turn on speech services and typing suggestions" 버튼을 눌러 "Turn on"을 설정하면 됩니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 빌드 시 다음과 같은 오류가 발생한다면?<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 1>------ Rebuild All started: Project: SpeechAndTTS, Configuration: Debug ARM ------ 1>E:\git_clone\uwp_samples\Samples\SpeechRecognitionAndSynthesis\cs\SpeechAndTTS.csproj : XamlCompiler error WMC1006: Cannot resolve Assembly or Windows Metadata file 'Type universe cannot resolve assembly: System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.' 1>CSC : error CS2001: Source file 'E:\git_clone\uwp_samples\Samples\SpeechRecognitionAndSynthesis\cs\obj\ARM\Debug\App.g.i.cs' could not be found. ========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ========== </pre> <br /> 당황하지 마시고 ^^ 솔루션 탐색기의 솔루션 이름을 마우스 우 클릭해, "Restore NuGet Packages" 메뉴를 실행한 후 다시 빌드하면 됩니다.<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
7890
(왼쪽의 숫자를 입력해야 합니다.)