Skip to content

Instantly share code, notes, and snippets.

@windy1
Last active April 19, 2017 20:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save windy1/758288fda029df6887fabc2aff4ed62d to your computer and use it in GitHub Desktop.
Save windy1/758288fda029df6887fabc2aff4ed62d to your computer and use it in GitHub Desktop.
#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
}
}
}
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;
}
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