-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathalexa.go
151 lines (124 loc) · 3.94 KB
/
alexa.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// for the speech to speech to occur the speech needs to be converted into a text.
// the text is used to query the wolfram alpha api.
//the the answer is a text/string and is written to an xml file
//the xml file is read to produce a wav file for the user
package main
import (
"fmt"
"errors"
"io/ioutil"
"net/http"
"bytes"
"strings"
"log"
"encoding/xml"
"os"
)
//used to build the xml file
type speak struct {
Version string `xml:"version,attr"`
Language string `xml:"xml:lang,attr"`
Voice voice `xml:"Voice"`
}
//used to build the xml file
type voice struct {
Language string `xml:"xml:lang,attr"`
Name string `xml:"name,attr"`
Words string `xml:",chardata"`
}
const (
REGION = "uksouth"
URI = "https://" + REGION + ".stt.speech.microsoft.com/" +
"speech/recognition/conversation/cognitiveservices/v1?" +
"language=en-US"
KEY = "19c1cb3c0aa848608fed5a5a8a23d640"
)
func check( e error ) { if e != nil { panic( e ) } }
//text to speech function
func TextToSpeech( text []byte ) ( []byte, error ) {
client := &http.Client{}
req, err := http.NewRequest( "POST", URI, bytes.NewBuffer( text ) )
check( err )
req.Header.Set( "Content-Type", "application/ssml+xml" )
req.Header.Set( "Ocp-Apim-Subscription-Key", KEY )
req.Header.Set( "X-Microsoft-OutputFormat", "riff-16khz-16bit-mono-pcm" )
rsp, err2 := client.Do( req )
check( err2 )
defer rsp.Body.Close()
if rsp.StatusCode == http.StatusOK {
body, err3 := ioutil.ReadAll( rsp.Body )
check( err3 )
return body, nil
} else {
return nil, errors.New( "cannot convert text to speech" )
}
}
func SpeechToText( speech []byte ) ( string, error ) {
client := &http.Client{}
req, err := http.NewRequest( "POST", URI, bytes.NewReader( speech ) )
check( err )
req.Header.Set( "Content-Type",
"audio/wav;codecs=audio/pcm;samplerate=16000" )
req.Header.Set( "Ocp-Apim-Subscription-Key", KEY )
rsp, err2 := client.Do( req )
check( err2 )
defer rsp.Body.Close()
if rsp.StatusCode == http.StatusOK {
body, err3 := ioutil.ReadAll( rsp.Body )
check( err3 )
return string( body ), nil
} else {
return "", errors.New( "cannot convert to speech to text" )
}
}
func main() {
//declaring question text
var question string
speech, err1 := ioutil.ReadFile( "testwav.wav" ) //example wav file is inputed here
check( err1 )
text, err2 := SpeechToText( speech ) //retrieved the text from wav file
check( err2 )
fmt.Println( text )
//text is the question string for the wolfram alpha short answers api
question = text
//string being modified to fit inside the url used to access api
question = strings.ReplaceAll(question, " ", "+")
//wolframalpha appid is already in the link and not stored in a variable
resp, getErr := http.Get("http://api.wolframalpha.com/v1/result?appid=H4RUYV-2WP4YG72XJ&i=" + question)
if getErr != nil {
log.Fatal(getErr)
}
//body is the result string
body, readErr := ioutil.ReadAll(resp.Body)
if readErr != nil {
log.Fatal(readErr)
}
fmt.Println(string(body)) //retrieved the resulting string
//the string is to be written to the xml file
var answer string
answer = string(body)
x := &speak{Version: "1.0", Language: "en-US",
Voice: voice{Language: "en-US", Name: "en-US-JennyNeural", Words: answer},//inserts answer
}
enc := xml.NewEncoder(os.Stdout)
enc.Indent("", " ")
if err := enc.Encode(x); err != nil {
fmt.Printf("error: %v\n", err)
}
data, err := xml.MarshalIndent(x, " ", " ")
if err != nil {
log.Fatal(err)
}
err = ioutil.WriteFile("test.xml", data, 0666)
if err != nil {
log.Fatal(err)
}
//after making an xml file, use this file to read the speech
//after making an xml file, use this file to read the speech
text2, err := ioutil.ReadFile( "test.xml" ) //reads the file
check( err )
speech2, err2 := TextToSpeech( text2 )//converts to wav file
check( err2 )
err3 := ioutil.WriteFile( "speech.wav", speech2, 0644 )//outputs wav file
check( err3 )
}