diff --git a/ai-conversation/audio_capture.c b/ai-conversation/audio_capture.c index 17cb8ac..f88a027 100644 --- a/ai-conversation/audio_capture.c +++ b/ai-conversation/audio_capture.c @@ -14,30 +14,109 @@ void print_pcm_state(snd_pcm_t *pcm_handle) { printf("State of pcm handle: %s\n", state_name); } +struct file_data { + FILE *file; + size_t size; +}; + +struct response_data { + char *data; + size_t size; +}; + +size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userdata) { + struct file_data *data = (struct file_data *)userdata; + size_t bytes_to_read = size * nmemb; + return fread(ptr, 1, bytes_to_read, data->file); +} + +// Returns string that caller must free +char* find_transcript(char* json_response) +{ + char* start = strstr(json_response, "\"transcript\":\""); + if (!start) return NULL; + + start += 14; // Skip past "transcript":" + char* end = strchr(start, '"'); // Find closing quote + // Copy substring between start and end + size_t len = end - start; + char* result = malloc(len + 1); + strncpy(result, start, len); + result[len] = '\0'; + return result; +} + size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) { size_t total_size = size * nmemb; - printf("%.*s", (int)total_size, (char*)contents); + struct response_data *response = (struct response_data *)userp; + + // Reallocate buffer to fit new data + response->data = realloc(response->data, response->size + total_size + 1); + if (response->data == NULL) { + return 0; // Error + } + + // Copy new data to buffer + memcpy(&response->data[response->size], contents, total_size); + response->size += total_size; + response->data[response->size] = '\0'; // Null terminate + return total_size; } -void test_request() { - CURL *curl; - CURLcode res; - curl = curl_easy_init(); +// Returns transcript of audio +char* transcribe(FILE* audio_file) { + CURL *curl; + CURLcode res; + struct curl_slist *headers = NULL; + + // Initialize response buffer + struct response_data response = {0}; + response.data = malloc(1); + response.size = 0; - if (curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com"); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + // Get file size + fseek(audio_file, 0, SEEK_END); + long file_size = ftell(audio_file); + fseek(audio_file, 0, SEEK_SET); - res = curl_easy_perform(curl); - if (res != CURLE_OK) - { - fprintf(stderr, "curl failed: %s\n", curl_easy_strerror(res)); - return; + struct file_data data; + data.file = audio_file; + data.size = file_size; + + curl = curl_easy_init(); + if (curl) { + // Set headers for Deepgram API + headers = curl_slist_append(headers, "Authorization: Token YOUR_DEEPGRAM_API_KEY"); + headers = curl_slist_append(headers, "Content-Type: audio/*"); + + curl_easy_setopt(curl, CURLOPT_URL, "https://api.deepgram.com/v1/listen"); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); + curl_easy_setopt(curl, CURLOPT_READDATA, &data); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, file_size); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); + + res = curl_easy_perform(curl); + if (res != CURLE_OK) { + fprintf(stderr, "curl failed: %s\n", curl_easy_strerror(res)); + free(response.data); + curl_slist_free_all(headers); + curl_easy_cleanup(curl); + return NULL; + } + + curl_slist_free_all(headers); + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); - } + // Parse transcript from complete response + char* transcript = find_transcript(response.data); + free(response.data); + + return transcript; } int main() { @@ -150,9 +229,19 @@ int main() { periods_read++; } - // TODO: keep appending above frames into one buffer, and send to deepgram - fclose(file); + + // Reopen file for reading and transcribe + file = fopen("output.pcm", "rb"); + if (file != NULL) { + char* transcript = transcribe(file); + if (transcript) { + printf("Transcript: %s\n", transcript); + free(transcript); + } + fclose(file); + } + free((void *)buf); snd_pcm_close(pcm_handle); snd_pcm_hw_params_free(params);