GiGA Genie AI API 서비스가이드 <GiGA Genie AI 음성인식 API> 1 / 21

Similar documents
KT AI MAKERS KIT 사용설명서 (Node JS 편).indd

GiGA Genie AI API 서비스가이드 <GiGA Genie AI 영상분석 API> 1 / 33

K&R2 Reference Manual 번역본

Polly_with_Serverless_HOL_hyouk

PowerPoint 프레젠테이션

6주차.key

PowerPoint 프레젠테이션

API STORE 키발급및 API 사용가이드 Document Information 문서명 : API STORE 언어별 Client 사용가이드작성자 : 작성일 : 업무영역 : 버전 : 1 st Draft. 서브시스템 : 문서번호 : 단계 : Docum

bn2019_2

chap7.key

1217 WebTrafMon II

Analytics > Log & Crash Search > Unity ios SDK [Deprecated] Log & Crash Unity ios SDK. TOAST SDK. Log & Crash Unity SDK Log & Crash Search. Log & Cras

PowerPoint 프레젠테이션

C프로-3장c03逞풚

untitled

03장.스택.key

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CC0E7B0EDB0FCB8AE5C53746F636B5F4D616E D656E74732E637070>

(Asynchronous Mode) ( 1, 5~8, 1~2) & (Parity) 1 ; * S erial Port (BIOS INT 14H) - 1 -

PowerPoint 프레젠테이션

Microsoft Word - ntasFrameBuilderInstallGuide2.5.doc

歯9장.PDF

untitled

SRC PLUS 제어기 MANUAL

02 C h a p t e r Java

5.스택(강의자료).key

Mobile Service > IAP > Android SDK [ ] IAP SDK TOAST SDK. IAP SDK. Android Studio IDE Android SDK Version (API Level 10). Name Reference V

Modern Javascript

PowerPoint 프레젠테이션

프로그램을 학교 등지에서 조금이라도 배운 사람들을 위한 프로그래밍 노트 입니다. 저 역시 그 사람들 중 하나 입니다. 중고등학교 시절 학교 도서관, 새로 생긴 시립 도서관 등을 다니며 책을 보 고 정리하며 어느정도 독학으르 공부하긴 했지만, 자주 안하다 보면 금방 잊어


Something that can be seen, touched or otherwise sensed

13주-14주proc.PDF

thesis

8 장데이터베이스 8.1 기본개념 - 데이터베이스 : 데이터를조직적으로구조화한집합 (cf. 엑셀파일 ) - 테이블 : 데이터의기록형식 (cf. 엑셀시트의첫줄 ) - 필드 : 같은종류의데이터 (cf. 엑셀시트의각칸 ) - 레코드 : 데이터내용 (cf. 엑셀시트의한줄 )


untitled

untitled

<C0CCBCBCBFB52DC1A4B4EBBFF82DBCAEBBE7B3EDB9AE2D D382E687770>

아래 항목은 최신( ) 이미지를 모두 제대로 설치하였을 때를 가정한다

gcloud storage 사용자가이드 1 / 17

강의10

Todo list Universal app

( )부록

The Pocket Guide to TCP/IP Sockets: C Version

Microsoft PowerPoint - chap13-입출력라이브러리.pptx

JMF3_심빈구.PDF

T100MD+

4. #include <stdio.h> #include <stdlib.h> int main() { functiona(); } void functiona() { printf("hihi\n"); } warning: conflicting types for functiona

JMF2_심빈구.PDF

Microsoft PowerPoint - 04-UDP Programming.ppt

MasoJava4_Dongbin.PDF

3ÆÄÆ®-11

10주차.key

Eclipse 와 Firefox 를이용한 Javascript 개발 발표자 : 문경대 11 년 10 월 26 일수요일

No Slide Title

BEA_WebLogic.hwp

슬라이드 1

신림프로그래머_클린코드.key

rmi_박준용_final.PDF

Windows 8에서 BioStar 1 설치하기

Chapter 4. LISTS

Interstage5 SOAP서비스 설정 가이드

Week13

PowerPoint 프레젠테이션

DocsPin_Korean.pages

Connection 8 22 UniSQLConnection / / 9 3 UniSQL OID SET

PowerPoint 프레젠테이션

비긴쿡-자바 00앞부속

교육2 ? 그림

thesis

목차 BUG offline replicator 에서유효하지않은로그를읽을경우비정상종료할수있다... 3 BUG 각 partition 이서로다른 tablespace 를가지고, column type 이 CLOB 이며, 해당 table 을 truncate

5 167 Python Jon Franklin Python Python Python Python USB USB RS485 C Python DLL Python Python dll Python Python ctypes dll ctypes Python C Linux Wind

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

DE1-SoC Board

3주차_Core Audio_ key

10.

초보자를 위한 C# 21일 완성

1. Windows 설치 (Client 설치 ) 원하는위치에다운받은발송클라이언트압축파일을해제합니다. Step 2. /conf/config.xml 파일수정 conf 폴더에서 config.xml 파일을텍스트에디터를이용하여 Open 합니다. config.xml 파일에서, 아

chap01_time_complexity.key

14-Servlet

À©µµ³×Æ®¿÷ÇÁ·Î±×·¡¹Ö4Àå_ÃÖÁ¾

슬라이드 1

Microsoft PowerPoint - 3ÀÏ°_º¯¼ö¿Í »ó¼ö.ppt

Secure Programming Lecture1 : Introduction

PowerPoint 프레젠테이션

untitled

ORANGE FOR ORACLE V4.0 INSTALLATION GUIDE (Online Upgrade) ORANGE CONFIGURATION ADMIN O

12-file.key

11 템플릿적용 - Java Program Performance Tuning (김명호기술이사)

USER GUIDE

vi 사용법

HLS(HTTP Live Streaming) 이용가이드 1. HLS 소개 Apple iphone, ipad, ipod의운영체제인 ios에서사용하는표준 HTTP 기반스트리밍프로토콜입니다. 2. HLS 지원대상 - 디바이스 : iphone/ipad/ipod - 운영체제 :

05-class.key

MPLAB C18 C

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C D616E2E637070>

CD-RW_Advanced.PDF

Mango-AM335x LCD Type 커널 Module Parameter에서 변경하기

USB USB DV25 DV25 REC SRN-475S REC SRN-475S LAN POWER LAN POWER Quick Network Setup Guide xdsl/cable Modem PC DVR 1~3 1.. DVR DVR IP xdsl Cable xdsl C

PowerPoint 프레젠테이션

슬라이드 1

Transcription:

GiGA Genie AI API 서비스가이드 <GiGA Genie AI 음성인식 API> 1 / 21

GiGA Genie AI API 신청방법 회원가입방법 1. ucloud biz 포탈메인페이지에서회원가입이가능합니다 2. 자세한방법은고객센터 > 매뉴얼 > Server > 사용자가이드중첫걸음떼기의 내용을참조하시기바랍니다 사전준비사항 1. 상품 > 컴퓨팅 > Server 항목에서 ucloud server 상품을먼저싞청합니다 GiGA Genie AI API 은 Running 상태인 VM(Virtual Machine) 이최소 1 대는존재해야 싞청가능하도록제한하고있습니다. 이미 ucloud server 상품을사용하고계싞사용자라면, 본과정을넘어가면됩니다. 2 / 21

2. ucloud server 상품싞청후클라우드콘솔에접속합니다 3. 클라우드콘솔에서서버를 1 개생성합니다 4. 서버생성후상품 > GiGA Genie AI API 항목으로이동하여, 상품싞청을진행합니다 3 / 21

GiGA Genie AI API 상품신청 1. 상품 > GiGA Genie AI API 을선택하여해당페이지로접근합니다 2. 우측플로팅버튼 [ 상품싞청하기 ] 를클릭하여, 상품싞청을진행합니다 3. ucloud biz 포탈에서의상품싞청으로, 기가지니개발자센터 (www.gigagenie.ai) 의회원가입처리가자동으로이루어집니다. 사용자는두개의웹사이트에별도로회원가입하실필요가없습니다. 기가지니개발자센터의회원가입이자동처리되는만큼, 해당사이트의약관을제공하고있습니다. 약관확인후동의하셔야다음단계가진행됩니다 4 / 21

4. 상품가입이완료되면, 기가지니개발자포탈 (www.gigagenie.ai) 에서해당사이트의 임시비밀번호를메일로전달합니다. 해당임시비밀번호는기가지니개발자포탈 에로그인할때필요합니다 5 / 21

GiGA Genie AI API 서비스생성 1. 클라우드콘솔 > AI API Cloud 아이콘을선택합니다. 2. GiGA Genie AI API를사용하기위해선서비스생성이필요합니다. 서비스란 AI API를통해개발하는새로운서비스프로젝트개념에가깝습니다. 1개계정에는하나의 GiGA Genie AI 서비스만생성가능합니다. 서비스마다키가부여되어 AI API를호출할수있게됩니다. 3. [GiGA Genie AI 서비스생성 ] 버튼을클릭합니다 서비스명 : GiGA Genie AI를활용하기위한프로젝트명칭입니다. 개발시작일 : YYYY-MM-DD 형식으로 API를사용할시점을입력합니다. 개발종료일 : YYYY-MM-DD 형식으로 API 사용을종료할시점을입력합니다. 앱명 : 서비스의하위개념으로, 앱설명 : 해당앱의관리를위해필요한정보를텍스트로기술하시면됩니다사용자ID: ucloud biz 계정정보가노출됩니다. 위정보를입력한후싞청버튼을클릭합니다. GiGA Genie AI API는 API 호출건수를기준으로사용한만큼과금됩니다. 서비스생성시개발시작일과개발종료일을입력할때요금때문에종료일을짧게설정하실필요는없습니다. 6 / 21

GiGA Genie AI API 키확인 1. [GiGA Genie AI 키보기 ] 버튼을클릭합니다. 2. API 호출을위한 Client Key, Client ID, Client Secret 값을확인하실수있습니다. 3. API Key 가타인에게유출되지않도록유의하시기바랍니다. GIGA Genie AI API 사용전준비 키확인및파일다운로드 1. GiGA Genie AI API 키보기버튼을클릭합니다. 2. API 호출을위한 Client Key, Client ID, Client Secret값을확인하실수있습니다. 3. 음성인식, 대화 API 사용을위해 GRPC Spec인 gigagenierpc.proto 파일과인증서번들 ca-bundle.pem 파일을다운로드하여 API 호출시사용합니다. - curl https://connector.gigagenie.ai/sdk/grpcapi > gigagenierpc.proto - curl https://connector.gigagenie.ai/sdk/certbundle > ca-bundle.pem GRPC 설치 1. Python 1) grpcio 설치 : $ python -m pip install grpcio 2) grpc tool 설치 : $ python -m pip install grpcio-tools 3) gigagenierpc.proto 파일을 python code로 generate $ python -m grpc_tools.protoc -I../../protos --python_out=. -- grpc_python_out=.../../protos/gigagenierpc.proto -I../../protos 옵션 ( 예시 ) 설명 proto 파일이있는소스디렉토리 7 / 21

--python_out=. --grpc_python_out=.../../protos/gigagenierpc.proto gigagenierpc_pb2.py 파일이생성될디렉토리 gigagenierpc_pb2_grpc.py 파일이생성될디렉토리 proto 파일정의 4) 3) 에서생성된 gigagenierpc_pb2.py, gigagenierpc_pb2_grpc.py 파일을 python 내 import 하여사용 2. C++ 1) protoc 설치 (Linux 환경 ) - git clone https://github.com/google/protobuf.git cd protobuf git submodule update init recursive./autogen.sh./configure make;sudo make install;sudo ldconfig 2) grpc 설치 (Linux 환경 ) - git clone b $(curl L https://grpc.io/release) https://github.com/grpc/grpc cd grpc git submodule update init make; sudo make install 3) proto 소스생성 (.pb.h 및.pb.cc) - protoc I./ --cpp_out=. gigagenierpc.proto 4) grpc 소스생성 (.grpc.pb.h 및.grpc.pb.cc) - protoc I./ --grpc_out=. plugin=protoc-gen-grpc=`which grpc_cpp_plugin` gigagenierpc.proto 옵션 ( 예시 ) 설명 -I../../protos proto파일이있는소스디렉토리 --cpp_out=. gigagenierpc.pb.h 및 gigagenierpc.pb.cc 가 생성되는폴더 --grpc_out=. gigagenierpc.grpc.pb.h 및 gigagenierpc.grpc.pb.cc 가생성되는폴더 -plugin=protoc-gen-grpc 이용 plugin 패스 8 / 21

GiGA Genie AI 음성인식 API 개요및안내사항 사용자의음성을스트리밍형식으로입력받아, 텍스트로인식값을반환해주는 API로, GRPC 형식의 API를제공합니다. * API 1회호출시 ( 인식 1회 ) 의 Time Limit은 15초입니다. GiGA Genie AI 음성인식 API 명세 Endpoint https://connector.gigagenie.ai:4080 Package kt.gigagenie.ai.speech Method getvoice2text Credentials Server connector.gigagenie.ai 인증서 (ca-bundle.pem) Metadata name type Description x-auth-clientkey String 발급받은 client-key x-auth-timestamp String Signature생성 Timestamp x-auth-signature String Signature 값 ( 하단참고 ) Request Name reqvoice Type Streaming Parameters Union reqvoiceopt 또는 audiocontent Fields name type description reqoptions reqvoiceopt 음성인식요청옵션 audiocontent bytes PCM 데이터 Response Name restext Type Streaming Parameters Fields name type description resultcd Int32 결과코드 recognizedtext string 인식텍스트 Messages Name reqvoiceopt Fields name type description mode Int32 음성인식모드로 현재 0(Streaming) 만지원한다. lang Int32 음성인식언어로현재 0( 한국어 ) 만지원한다. ResultCode ResultCode Desc 200 부분음성인식결과 201 음성인식결과 ( 완료 ) 202 음성인식타임아웃발생 401 Signature 불일치 9 / 21

404 존재하지않는 Client Key 500 시스템에러 509 호출제한초과 Sample Code 1. node.js /* node-record-lpcm16 module을사용하기위해서는 sox 설치가필요합니다. */ const record=require('node-record-lpcm16'); const grpc=require('grpc') const proto=grpc.load('./gigagenierpc.proto').kt.gigagenie.ai.speech; const fs=require('fs'); const crypto=require('crypto'); const dateformat=require('dateformat'); const sslcred=grpc.credentials.createssl( fs.readfilesync('./ca-bundle.pem')); const client_id='your_client_id'; const client_key='your_client_key'; const client_secret='your_client_secret'; function gettimestamp(){ return dateformat(new Date(),'yyyymmddHHmmssL'); ; function createsignature(id,timestamp,secret){ return crypto.createhmac('sha256',secret).update(id+':'+timestamp).digest('hex'); ; function generatemetadata(params,callback){ const metadata=new grpc.metadata(); const timestamp=gettimestamp(); metadata.add('x-auth-clientkey',client_key); metadata.add('x-auth-timestamp',timestamp); const signature=createsignature(client_id,timestamp,client_secret); metadata.add('x-auth-signature',signature);; callback(null,metadata); ; function initmic(){ return record.start({ sampleratehertz: 16000, threshold: 0, verbose: false, recordprogram: 'rec', silence: '10.0', ) ; console.log(gettimestamp()); const authcred=grpc.credentials.createfrommetadatagenerator(generatemetadata); console.log(authcred); 10 / 21

const credentials=grpc.credentials.combinechannelcredentials(sslcred,authcred); const client=new proto.gigagenie('connector.gigagenie.ai:4080',credentials); const pcm=client.getvoice2text().on('error',(error)=>{ console.log('error:'+error); ).on('data',(data)=>{ console.log('data:'+json.stringify(data)); ) pcm.on('end',()=>{ console.log('pcm end'); record.stop(); ); pcm.write({reqoptions:{mode:0,lang:0); const mic=initmic(); mic.on('data',(data)=>{ pcm.write({audiocontent:data); ); 2. Python #!/usr/bin/env python # -*- coding: utf-8 -*- """The Python implementation of GiGA Genie grpc client""" from future import print_function import grpc import gigagenierpc_pb2 import gigagenierpc_pb2_grpc import os import datetime import hmac import hashlib # Config for GiGA Genie grpc CLIENT_ID = 'YOUR_CLIENT_ID' CLIENT_KEY = 'YOUR_CLIENT_KEY' CLIENT_SECRET = 'YOUR_CLIENT_SECRET' HOST = 'connector.gigagenie.ai' PORT = 4080 ### COMMON : Client Credentials ### def getmetadata(): timestamp = datetime.datetime.now().strftime("%y%m%d%h%m%s%f")[:-3] message = CLIENT_ID + ':' + timestamp 11 / 21

signature = hmac.new(client_secret, message, hashlib.sha256).hexdigest() metadata = [('x-auth-clientkey', CLIENT_KEY), ('x-auth-timestamp', timestamp), ('x-auth-signature', signature)] return metadata def credentials(context, callback): callback(getmetadata(), None) def getcredentials(): with open('ca-bundle.pem', 'rb') as f: trusted_certs = f.read() sslcred = grpc.ssl_channel_credentials(root_certificates=trusted_certs) authcred = grpc.metadata_call_credentials(credentials) return grpc.composite_channel_credentials(sslcred, authcred) ### END OF COMMON ### ### STT import pyaudio import audioop from six.moves import queue FORMAT = pyaudio.paint16 CHANNELS = 1 RATE = 16000 CHUNK = 1024 # MicrophoneStream - original code in https://goo.gl/7xy3tt class MicrophoneStream(object): """Opens a recording stream as a generator yielding the audio chunks.""" def init (self, rate, chunk): self._rate = rate self._chunk = chunk # Create a thread-safe buffer of audio data self._buff = queue.queue() self.closed = True def enter (self): self._audio_interface = pyaudio.pyaudio() self._audio_stream = self._audio_interface.open( format=pyaudio.paint16, 12 / 21

) channels=1, rate=self._rate, input=true, frames_per_buffer=self._chunk, # Run the audio stream asynchronously to fill the buffer object. # This is necessary so that the input device's buffer doesn't # overflow while the calling thread makes network requests, etc. stream_callback=self._fill_buffer, self.closed = False return self def exit (self, type, value, traceback): self._audio_stream.stop_stream() self._audio_stream.close() self.closed = True # Signal the generator to terminate so that the client's # streaming_recognize method will not block the process termination. self._buff.put(none) self._audio_interface.terminate() def _fill_buffer(self, in_data, frame_count, time_info, status_flags): """Continuously collect data from the audio stream, into the buffer.""" self._buff.put(in_data) return None, pyaudio.pacontinue def generator(self): while not self.closed: # Use a blocking get() to ensure there's at least one chunk of # data, and stop iteration if the chunk is None, indicating the # end of the audio stream. chunk = self._buff.get() if chunk is None: return data = [chunk] # Now consume whatever other data's still buffered. while True: try: chunk = self._buff.get(block=false) if chunk is None: return data.append(chunk) except queue.empty: break yield b''.join(data) # [END audio_stream] 13 / 21

def print_rms(rms): out = '' for _ in xrange(int(round(rms/30))): out = out + '*' print (out) def generate_request(): with MicrophoneStream(RATE, CHUNK) as stream: audio_generator = stream.generator() for content in audio_generator: message = gigagenierpc_pb2.reqvoice() message.audiocontent = content yield message rms = audioop.rms(content,2) print_rms(rms) def getvoice2text(): print ("Ctrl+\ to quit...") channel = grpc.secure_channel('{:{'.format(host, PORT), getcredentials()) stub = gigagenierpc_pb2_grpc.gigageniestub(channel) request = generate_request() resulttext = '' for response in stub.getvoice2text(request): if response.resultcd == 200: # partial print('resultcd=%d recognizedtext= %s' % (response.resultcd, response.recognizedtext)) resulttext = response.recognizedtext elif response.resultcd == 201: # final print('resultcd=%d recognizedtext= %s' % (response.resultcd, response.recognizedtext)) resulttext = response.recognizedtext break else: print('resultcd=%d recognizedtext= %s' % (response.resultcd, response.recognizedtext)) break print ("TEXT: %s" % (resulttext)) return resulttext 14 / 21

def main(): # STT text = getvoice2text() if name == ' main ': main() 3. C++ #define ALSA_PCM_NEW_HW_PARAMS_API #define PCM_DEVICE "default" #include <iostream> #include <string> #include <fstream> #include <grpcpp/grpcpp.h> #include <openssl/hmac.h> #include <alsa/asoundlib.h> #include <alsa/control.h> #include <time.h> #include <sys/time.h> #include <thread> #include "gigagenierpc.pb.h" #include "gigagenierpc.grpc.pb.h" using namespace std; using namespace grpc; using namespace kt::gigagenie::ai::speech; //for metadata credential processing class GigagenieRPCAuthenticator:public grpc::metadatacredentialsplugin{ public: GigagenieRPCAuthenticator(const grpc::string& clientid,const grpc::string& clientkey,const grpc::string& clientsecret):clientid_(clientid),clientkey_(clientkey),clientsecret_(clientsecret){ grpc::status GetMetadata( grpc::string_ref service_url, grpc::string_ref method_name, const grpc::authcontext& channel_auth_context, std::multimap<grpc::string, grpc::string>* metadata) override { metadata->insert(std::make_pair("x-auth-clientkey",clientkey_)); timestamp_=maketimestamp(); metadata->insert(std::make_pair("x-auth-timestamp",timestamp_)); metadata->insert(std::make_pair("x-auth-signature",makesignature())); return grpc::status::ok; 15 / 21

private: grpc::string clientkey_; grpc::string clientid_; grpc::string clientsecret_; grpc::string timestamp_; grpc::string maketimestamp(){ char buffer[15];//yyyymmddhhmmss buffer[14]=0x00; int millisec; struct tm* tm_info; struct timeval tv; gettimeofday(&tv, NULL); millisec = lrint(tv.tv_usec/1000.0); if (millisec>=1000) { millisec -=1000; tv.tv_sec++; tm_info = localtime(&tv.tv_sec); strftime(buffer,14,"%y%m%d%h%m%s",tm_info); char milli[4]; milli[3]=0x00; sprintf(milli,"%03d",millisec); grpc::string time2(milli); grpc::string returnstr(buffer); returnstr=returnstr+time2; return returnstr; grpc::string makesignature(){ unsigned char* result=(unsigned char *)malloc(hmac_max_md_cblock); unsigned int len=0; auto ctx=hmac_ctx_new(); const char* key=clientsecret_.c_str(); HMAC_Init_ex(ctx,key,clientSecret_.length(),EVP_sha256(),NULL); grpc::string shadata=clientid_+":"+timestamp_; const unsigned char* data=(unsigned char*)shadata.c_str(); HMAC_Update(ctx,data,shaData.length()); HMAC_Final(ctx,result,&len); HMAC_CTX_free(ctx); grpc::string returnstr; for(int i=0;i!=len;i++) { char hex[2]; sprintf(hex,"%02x",(unsigned int)result[i]); returnstr.append(hex); free(result); cout<<"signature:"<<returnstr<<endl; 16 / 21

return returnstr; ; //for read certificate static std::string get_file_contents(const char *fpath) { std::ifstream finstream(fpath); std::string contents((std::istreambuf_iterator<char>(finstream)), std::istreambuf_iterator<char>()); return contents; int main() { //SSL Credentials SslCredentialsOptions sslopts; auto server_ca_pem = get_file_contents("/home/ca-bundle.pem"); sslopts.pem_root_certs=server_ca_pem; auto creds=sslcredentials(sslopts); //Meta Credentials grpc::string clientid="your_client_id"; grpc::string clientkey="your_client_key"; grpc::string clientsecret="your_client_secret "; auto call_creds=grpc::metadatacredentialsfromplugin( std::unique_ptr<grpc::metadatacredentialsplugin>(new GigagenieRPCAuthenticator(clientId,clientKey,clientSecret)) ); //composite Credentials auto compositechannelcreds=grpc::compositechannelcredentials(creds,call_creds); //create Channel auto channel=grpc::createchannel("connector.gigagenie.ai:4080",compositechannelcreds); //Create Stub ClientContext context; resquerytext reply; auto callstub=gigagenie::newstub(channel); //Sound Capture int num_channels=1; int samplebit=16; snd_pcm_uframes_t read_frames=2048; 17 / 21

int dir; snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE; int err; int size; snd_pcm_hw_params_t *hw_params; unsigned int rate = 16000; snd_pcm_uframes_t frames=16; unsigned char *buffer; unsigned int period_time; long loops;//to remove later int rc; snd_pcm_t *capture_handle; if ((err = snd_pcm_open (&capture_handle, "default", SND_PCM_STREAM_CAPTURE, 0)) < 0) { fprintf (stderr, "cannot open audio device %s (%s)\n",pcm_device,snd_strerror (err)); exit (1); if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) { fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",snd_strerror (err)); exit (1); if ((err = snd_pcm_hw_params_any (capture_handle, hw_params)) < 0) { fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n", snd_strerror (err)); exit (1); if ((err = snd_pcm_hw_params_set_access (capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { fprintf (stderr, "cannot set access type (%s)\n",snd_strerror (err)); exit (1); if ((err = snd_pcm_hw_params_set_format (capture_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) { fprintf (stderr, "cannot set sample format (%s)\n",snd_strerror (err)); exit (1); if ((err = snd_pcm_hw_params_set_channels (capture_handle, hw_params, 1)) < 0) { fprintf (stderr, "cannot set channel count (%s)\n",snd_strerror (err)); exit (1); //if ((err = snd_pcm_hw_params_set_rate_near (capture_handle, hw_params, &rate, &dir)) < 0) { if ((err = snd_pcm_hw_params_set_rate_near (capture_handle, hw_params, &rate, 0)) < 0) { fprintf (stderr, "cannot set sample rate (%s)\n",snd_strerror (err)); 18 / 21

exit (1); if ((err = snd_pcm_hw_params_set_period_size_near(capture_handle, hw_params, &frames, &dir)) < 0) { fprintf (stderr, "cannot set frame (%s)\n",snd_strerror (err)); exit (1); if ((err = snd_pcm_hw_params (capture_handle, hw_params)) < 0) { fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror (err)); exit (1); snd_pcm_hw_params_get_period_size(hw_params,&frames, &dir); size=frames*2;/* 2bytes/sample, 1Channels*/ buffer=(unsigned char*)malloc(size); snd_pcm_hw_params_get_period_time(hw_params,&period_time, &dir); loops = 5000000/period_time; reqvoice getvoicetextreqvoice; getvoicetextreqvoice.mutable_reqoptions()->set_lang(0); getvoicetextreqvoice.mutable_reqoptions()->set_mode(0); CompletionQueue cq; void* got_tag_write; void* got_tag_read; void* got_tag_finish; bool ok=false; //async processing. auto stream(callstub->asyncgetvoice2text(&context,&cq,got_tag_read)); cq.next(&got_tag_read,&ok); cout<<"write ReqOption Async"<<endl; stream->write(getvoicetextreqvoice,got_tag_write); cq.next(&got_tag_write,&ok); bool loop=true; reqvoice getvoicetextreqvoicestream; restext reptext; //read async stream->read(&reptext,got_tag_read); Status finstatus; //check finish status bool checkfinstat=false; while(loop){ rc = snd_pcm_readi(capture_handle, buffer, frames); if (rc == -EPIPE) { 19 / 21

fprintf(stderr, "overrun occurred\n"); snd_pcm_prepare(capture_handle); else if (rc < 0) { fprintf(stderr,"error from read: %s\n", snd_strerror(rc)); else if (rc!= (int)frames) { fprintf(stderr, "short read, read %d frames\n", rc); //auto sendbufferbas64=base64encode(buffer,size); //cout<<"write Audio Data Size:"<<rc<<endl; getvoicetextreqvoicestream.set_audiocontent((void*)buffer,size); stream->write(getvoicetextreqvoicestream,got_tag_write); cq.next(&got_tag_write,&ok); auto readstat=cq.asyncnext(&got_tag_read,&ok,std::chrono::system_clock::now()+std::chrono::milliseconds(1)); switch(readstat){ case grpc::completionqueue::got_event: if(ok) { cout<<"read Success ResultCd:"<<repText.resultcd()<<" recogtext:"<<reptext.recognizedtext()<<endl; //check finish condition if(reptext.resultcd()==202){ stream- >Finish(&finStatus,got_tag_finish); checkfinstat=true; else stream->read(&reptext,got_tag_read); else { cout<<"read Failed"<<endl; stream->finish(&finstatus,got_tag_finish); checkfinstat=true; break; case grpc::completionqueue::shutdown: cout<<"shutdown"<<endl; break; case grpc::completionqueue::timeout: //cout<<"timeout"<<endl; break; if(checkfinstat){ auto finstat=cq.asyncnext(&got_tag_finish,&ok,std::chrono::system_clock::now()+std::chrono::milliseconds(5)); switch(finstat){ case grpc::completionqueue::got_event: cout<<"finstat GOT_EVETN"<<endl; loop=false; break; case grpc::completionqueue::shutdown: 20 / 21

cout<<"finstat SHUTDOWN"<<endl; break; case grpc::completionqueue::timeout: //cout<<"timeout"<<endl; break; snd_pcm_drain(capture_handle); snd_pcm_close(capture_handle); free(buffer); cout<<"everything is done"<<endl; return 0; Signature 생성 1. Signature는발급받은 client_id와 client_secret을이용해서생성합니다. 2. Signature는 timestamp를생성하고 client_id, timestamp을조합한 Text를 client_secret으로 sign 하는방식으로 digest 합니다. 3. timestamp 형식은 YYYYMMDD24hhmmssSSS 입니다. (milliseconds 3자리까지 ) ex) 20180425113110123 4. Signature는 hex string으로최종생성합니다. Signature=HMAC-SHA256(client_secret, client_id+ : +timestamp) 21 / 21