#include #include #include #include #include #include // NOTE: find this via `arecord -l` #define ALSA_MIC_HARDWARE_DEVICE "hw:3" void print_pcm_state(snd_pcm_t *pcm_handle) { snd_pcm_state_t state = snd_pcm_state(pcm_handle); const char *state_name = snd_pcm_state_name(state); printf("State of pcm handle: %s\n", state_name); } 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); return total_size; } void test_request() { CURL *curl; CURLcode res; curl = curl_easy_init(); if (curl) { curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com"); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); res = curl_easy_perform(curl); if (res != CURLE_OK) { fprintf(stderr, "curl failed: %s\n", curl_easy_strerror(res)); return; } curl_easy_cleanup(curl); } } int main() { snd_pcm_t *pcm_handle = NULL; int err; err = snd_pcm_open(&pcm_handle, ALSA_MIC_HARDWARE_DEVICE, SND_PCM_STREAM_CAPTURE, 0); if (err < 0) { printf("unable to open pcm device"); return -1; } print_pcm_state(pcm_handle); const char *name = snd_pcm_name(pcm_handle); printf("found this device: %s\n", name); snd_pcm_info_t *pcm_info; snd_pcm_info_malloc(&pcm_info); err = snd_pcm_info(pcm_handle, pcm_info); if (err < 0) { snd_pcm_close(pcm_handle); printf("unable to get info of pcm device"); return -1; } name = snd_pcm_info_get_name(pcm_info); if (err < 0) { printf("unable to get card info"); snd_pcm_close(pcm_handle); snd_pcm_info_free(pcm_info); return -1; } printf("got pcm name: %s \n", name); print_pcm_state(pcm_handle); snd_pcm_info_free(pcm_info); snd_pcm_hw_params_t *params; err = snd_pcm_hw_params_malloc(¶ms); if (err < 0) { fprintf(stderr, "unable to mallow hw params"); return -1; } err = snd_pcm_hw_params_any(pcm_handle, params); if (err < 0) { fprintf(stderr, "unable to find ranges for hw device"); snd_pcm_close(pcm_handle); snd_pcm_hw_params_free(params); return -1; } uint period_size = 1024; uint buffer_size = 4096; uint channel_count = 1; uint bytes_per_sample = 2; // FORMAT_S16_LE uint samples_per_second = 48000; snd_pcm_hw_params_set_access(pcm_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_hw_params_set_channels(pcm_handle, params, channel_count); snd_pcm_hw_params_set_buffer_size(pcm_handle, params, buffer_size); snd_pcm_hw_params_set_format(pcm_handle, params, SND_PCM_FORMAT_S16_LE); snd_pcm_hw_params_set_rate(pcm_handle, params, samples_per_second, 0); snd_pcm_hw_params_set_periods(pcm_handle, params, period_size, 0); err = snd_pcm_hw_params(pcm_handle, params); if (err < 0) { fprintf(stderr, "unable to prepare pcm\n"); snd_pcm_close(pcm_handle); snd_pcm_hw_params_free(params); return -1; } print_pcm_state(pcm_handle); err = snd_pcm_start(pcm_handle); if (err < 0) { fprintf(stderr, "unable to start pcm"); snd_pcm_close(pcm_handle); snd_pcm_hw_params_free(params); return -1; } print_pcm_state(pcm_handle); const uint seconds_to_capture = 5; const uint periods_to_read = (samples_per_second * seconds_to_capture) / period_size; char *buf = malloc(period_size * channel_count * bytes_per_sample); uint periods_read = 0; /* Read one period at a time from the hardware buffer * We set the hardware buffer to read 4096 frames. * The period size is 1024 frames. * Each period is 2048 BYTES because each frame is 2 bytes. * Each frame is 2 bytes because of 1 channel, and 16 bit format */ FILE *file = fopen("output.pcm", "wb"); if (file == NULL) { perror("Error opening file"); return 1; } while (snd_pcm_readi(pcm_handle, (void *)buf, period_size) > 0 && periods_read < periods_to_read) { printf("======READING FRAMES========\n"); // Because each frame is 2 bytes (format/bit rate), cast to int16 // int16_t *samples = (int16_t *)buf; // for (int i = 0; i < period_size; i++) { // printf("%d ", samples[i]); // } fwrite(buf, sizeof(int16_t), period_size, file); printf("\n"); periods_read++; } // TODO: keep appending above frames into one buffer, and send to deepgram fclose(file); free((void *)buf); snd_pcm_close(pcm_handle); snd_pcm_hw_params_free(params); return 0; }