169 lines
5.1 KiB
C
169 lines
5.1 KiB
C
#include "deepgram_client.h"
|
|
#include <string.h>
|
|
|
|
// Returns string that caller must free
|
|
static char *dg_find_transcript(char *json_response) {
|
|
printf("Parsing response: %s \n", 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;
|
|
}
|
|
|
|
char *dg_transcribe(FILE *audio_file) {
|
|
CURL *curl;
|
|
CURLcode res;
|
|
struct curl_slist *headers = NULL;
|
|
|
|
// Initialize response buffer
|
|
struct curl_response_data response = {0};
|
|
response.data = malloc(1);
|
|
response.size = 0;
|
|
|
|
// Get file size
|
|
fseek(audio_file, 0, SEEK_END);
|
|
long file_size = ftell(audio_file);
|
|
fseek(audio_file, 0, SEEK_SET);
|
|
|
|
struct curl_file_data data;
|
|
data.file = audio_file;
|
|
data.size = file_size;
|
|
|
|
curl = curl_easy_init();
|
|
if (curl) {
|
|
// Set headers for Deepgram API
|
|
char *deepgram_api_key = getenv("DEEPGRAM_API_KEY");
|
|
if (!deepgram_api_key) {
|
|
fprintf(stderr, "DEEPGRAM_API_KEY environment variable not set\n");
|
|
free(response.data);
|
|
curl_easy_cleanup(curl);
|
|
return NULL;
|
|
}
|
|
|
|
char auth_header[256];
|
|
snprintf(auth_header, sizeof(auth_header), "Authorization: Token %s", deepgram_api_key);
|
|
headers = curl_slist_append(headers, auth_header);
|
|
|
|
curl_easy_setopt(curl, CURLOPT_URL,
|
|
"https://api.deepgram.com/v1/"
|
|
"listen?encoding=linear16&sample_rate=48000&channels=1");
|
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
|
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
|
curl_easy_setopt(curl, CURLOPT_READFUNCTION, curl_read_callback_file);
|
|
curl_easy_setopt(curl, CURLOPT_READDATA, &data);
|
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, file_size);
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_callback_response);
|
|
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;
|
|
}
|
|
|
|
printf("done performing curl\n");
|
|
|
|
curl_slist_free_all(headers);
|
|
curl_easy_cleanup(curl);
|
|
}
|
|
|
|
// Parse transcript from complete response
|
|
char *transcript = dg_find_transcript(response.data);
|
|
free(response.data);
|
|
|
|
return transcript;
|
|
}
|
|
|
|
struct curl_response_data *dg_text_to_speech(char *text) {
|
|
CURL *curl;
|
|
CURLcode res;
|
|
struct curl_slist *headers = NULL;
|
|
|
|
// Create JSON payload - need to escape the text properly
|
|
// Worst case: every char needs escaping, so allocate 2x + overhead
|
|
size_t text_len = strlen(text);
|
|
size_t payload_size = text_len * 2 + 100;
|
|
char *json_payload = malloc(payload_size);
|
|
|
|
// Simple approach: replace problematic chars with spaces
|
|
char *escaped_text = malloc(text_len + 1);
|
|
strcpy(escaped_text, text);
|
|
for (int i = 0; escaped_text[i]; i++) {
|
|
if (escaped_text[i] == '"' || escaped_text[i] == '\n' ||
|
|
escaped_text[i] == '\r' || escaped_text[i] == '\t') {
|
|
escaped_text[i] = ' ';
|
|
}
|
|
}
|
|
|
|
snprintf(json_payload, payload_size,
|
|
"{"
|
|
"\"text\":\"%s\""
|
|
"}",
|
|
escaped_text);
|
|
|
|
free(escaped_text);
|
|
|
|
// Initialize response buffer
|
|
struct curl_response_data *response =
|
|
malloc(sizeof(struct curl_response_data));
|
|
response->data = malloc(1);
|
|
response->size = 0;
|
|
|
|
curl = curl_easy_init();
|
|
if (curl) {
|
|
char *deepgram_api_key = getenv("DEEPGRAM_API_KEY");
|
|
if (!deepgram_api_key) {
|
|
fprintf(stderr, "DEEPGRAM_API_KEY environment variable not set\n");
|
|
free(response->data);
|
|
curl_easy_cleanup(curl);
|
|
return NULL;
|
|
}
|
|
|
|
char auth_header[256];
|
|
snprintf(auth_header, sizeof(auth_header), "Authorization: Token %s", deepgram_api_key);
|
|
headers = curl_slist_append(headers, auth_header);
|
|
headers = curl_slist_append(headers, "Content-Type: application/json");
|
|
|
|
curl_easy_setopt(curl, CURLOPT_URL,
|
|
"https://api.deepgram.com/v1/"
|
|
"speak?encoding=linear16&sample_rate=48000");
|
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
|
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_payload);
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_callback_response);
|
|
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);
|
|
free(response);
|
|
curl_slist_free_all(headers);
|
|
curl_easy_cleanup(curl);
|
|
return NULL;
|
|
}
|
|
|
|
curl_slist_free_all(headers);
|
|
curl_easy_cleanup(curl);
|
|
}
|
|
|
|
printf("received audio of %d length for tts\n", (int)response->size);
|
|
|
|
// Debug: print first 100 chars to see if it's audio or error message
|
|
printf("First 100 chars: %.100s\n", response->data);
|
|
|
|
free(json_payload);
|
|
return response;
|
|
}
|