#include "rpi_microphone.h"

#include <alsa/asoundlib.h>
#include <fftw3.h>
#include <limits.h>
#include <stdlib.h>

#define CHANNELS_COUNT 1
#define SAMPLE_RATE 44100

snd_pcm_t *capture_handle;
char const *deviceName = "plughw:1";

void setup_microphone() {
  int err;
  snd_pcm_hw_params_t *hw_params;
  unsigned int rate = 44100;

  if ((err = snd_pcm_open(&capture_handle, deviceName, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
    fprintf(stderr, "cannot open audio device %s (%s)\n", deviceName, snd_strerror(err));
    exit(1);
  }

  if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {
    fprintf(stderr, "cannot allocate hardware parameter structure (%s)\n", snd_strerror(err));
    exit(1);
  }

  if ((err = snd_pcm_hw_params_any(capture_handle, hw_params)) < 0) {
    fprintf(stderr, "cannot initialize hardware parameter structure (%s)\n", snd_strerror(err));
    exit(1);
  }

  if ((err = snd_pcm_hw_params_set_access(capture_handle, hw_params,
                                          SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
    fprintf(stderr, "cannot set access type (%s)\n", snd_strerror(err));
    exit(1);
  }

  if ((err = snd_pcm_hw_params_set_format(capture_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
    fprintf(stderr, "cannot set sample format (%s)\n", snd_strerror(err));
    exit(1);
  }

  if ((err = snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, &rate, 0)) < 0) {
    fprintf(stderr, "cannot set sample rate (%s)\n", snd_strerror(err));
    exit(1);
  }

  if ((err = snd_pcm_hw_params_set_channels(capture_handle, hw_params, 2)) < 0) {
    fprintf(stderr, "cannot set channel count (%s)\n", snd_strerror(err));
    exit(1);
  }

  if ((err = snd_pcm_hw_params(capture_handle, hw_params)) < 0) {
    fprintf(stderr, "cannot set parameters (%s)\n", snd_strerror(err));
    exit(1);
  }

  snd_pcm_hw_params_free(hw_params);

  if ((err = snd_pcm_prepare(capture_handle)) < 0) {
    fprintf(stderr, "cannot prepare audio interface for use (%s)\n", snd_strerror(err));
    exit(1);
  }

  return;
}

#define BUFFERSIZE 1024
short buf[BUFFERSIZE];

void read_microphone() {
  int err;
  short max = SHRT_MIN;

  if ((err = snd_pcm_readi(capture_handle, buf, BUFFERSIZE)) != BUFFERSIZE) {
    fprintf(stderr, "read from audio interface failed (%s)\n", snd_strerror(err));
  } else {
    for (size_t i = 0; i < BUFFERSIZE; ++i) {
      if (buf[i] > max) {
        max = buf[i];
      }
    }
    printf("%d, ", max);
    printf("\n");
  }
}

void fft() {
  // fftw_complex *in, *out;
  // fftw_plan my_plan;
  // in = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * N);
  // out = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * N);
  // my_plan = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
  // fftw_execute(my_plan); /* repeat as needed */
  // fftw_destroy_plan(my_plan);
  // fftw_free(in);
  // fftw_free(out);
  // return;
}

void close_microphone() { snd_pcm_close(capture_handle); }