Last active
April 19, 2017 20:07
-
-
Save windy1/758288fda029df6887fabc2aff4ed62d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define MAX_SECONDS 5 | |
#define NUM_CHANNELS 2 | |
#define SAMPLE_RATE 44100 | |
#define FRAMES_PER_BUFFER 512 | |
#define SAMPLE_SILENCE 0 | |
#define SAMPLE_FORMAT /*paInt16*/ paInt8 | |
#define ENCODING "LINEAR16" | |
#define LANGUAGE_CODE "en-US" | |
typedef /*uint16_t*/ uint8_t Sample; | |
/** | |
* Represents, raw, recorded, PCM, audio data. | |
*/ | |
struct AudioData { | |
int frameIndex; | |
int maxFrameIndex; | |
Sample *recordedSamples; | |
}; | |
void onStreamFinished(void *audioData) { | |
// close stream and pass callback recorded data | |
assert(callback != NULL); | |
assert(audioData != NULL); | |
// close and terminate pa | |
PaError err = Pa_CloseStream(stream); | |
if (err != paNoError || (err = Pa_Terminate()) != paNoError) { | |
printErr(err); | |
} else { | |
AudioData *data = (AudioData*) audioData; | |
callback(data); // breakpoint: address = same as initialized | |
// free sample memory | |
if (data->recordedSamples) { // breakpoint: address = different from as initialized | |
free(data->recordedSamples); // error | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
bool speech2text(AudioData data, json &result) { | |
assert(sizeof(Sample) == 1); | |
bool success = true; | |
CURL *curl = 0; | |
curl_slist *requestHeaders = NULL; | |
json requestBody; | |
const char *requestBodyRaw; | |
CURLcode responseCode; | |
Response response; | |
size_t numSamples = (size_t) (data.maxFrameIndex * NUM_CHANNELS); | |
size_t numBytes = numSamples * sizeof(Sample); | |
char *buffer = (char*) malloc(numBytes); | |
string encodedAudio; | |
// allocate space for response | |
response.data = (char*) malloc(1); | |
response.size = 0; | |
if (response.data == NULL) { | |
cout << "Error: Could not allocate memory for response" << endl; | |
success = false; | |
goto cleanup; | |
} | |
// copy sample data | |
memcpy(buffer, data.recordedSamples, numBytes); | |
// encode data | |
encodedAudio = base64_encode((const unsigned char*) buffer, (unsigned int) numBytes); | |
requestBody = REQUEST_BODY; | |
requestBody["audio"]["content"] = encodedAudio; | |
requestBodyRaw = requestBody.dump().c_str(); | |
// construct headers | |
requestHeaders = curl_slist_append(requestHeaders, "Accept: application/json"); | |
requestHeaders = curl_slist_append(requestHeaders, "Content-Type: application/json"); | |
requestHeaders = curl_slist_append(requestHeaders, | |
("Content-Length: " + to_string(strlen(requestBodyRaw))).c_str()); | |
requestHeaders = curl_slist_append(requestHeaders, "charsets: utf-8"); | |
// initialize curl | |
curl = curl_easy_init(); | |
if (curl) { | |
// request properties | |
curl_easy_setopt(curl, CURLOPT_URL, SPEECH_API_URL); | |
curl_easy_setopt(curl, CURLOPT_POST, true); | |
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, requestHeaders); | |
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestBodyRaw); | |
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeResponse); | |
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); | |
curl_easy_setopt(curl, CURLOPT_VERBOSE, true); | |
// send request | |
responseCode = curl_easy_perform(curl); | |
if (responseCode == CURLE_OK) { | |
char *contentType; | |
responseCode = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType); | |
if (responseCode == CURLE_OK && string(contentType) == "application/json; charset=UTF-8") { | |
result = json::parse(response.data); | |
goto cleanup; | |
} else { | |
cout << "Error: Invalid content type: " << contentType << endl; | |
success = false; | |
goto cleanup; | |
} | |
} else { | |
cout << "Error: cURL responded with error (code " << responseCode << ")" << endl; | |
success = false; | |
goto cleanup; | |
} | |
} else { | |
cout << "Error: Could not initialize cURL" << endl; | |
success = false; | |
goto cleanup; | |
} | |
cleanup: | |
if (curl) { | |
curl_easy_cleanup(curl); | |
} | |
if (response.data) { | |
free(response.data); | |
} | |
if (buffer) { | |
free(buffer); | |
} | |
return success; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void onRecordFinish(const AudioData *data) { | |
cout << "- Finished recording" << endl; | |
json result; | |
if (speech2text(*data, result)) { // no error when removed | |
cout << result.dump(4) << endl; | |
} | |
recordFinished = true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment