#include <stdio.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <alsa/asoundlib.h>

#define BUFF_SIZE 32768 //4096 * 8

typedef struct 
{
  uint32_t samples;
  int16_t *data;
} sound_t;

sound_t hello;

//void adj_pitch(char *buffer, int br, float pitchFactor = )

int main(int argc, char *argv[])
{
  unsigned int sample_rate = 44100;
  snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;//SND_PCM_FORMAT_S16_LE;
  /*--------------------------------------------------------------------------------------*/
  int err;
  snd_pcm_t *handle;
  snd_pcm_hw_params_t *params;
  char *buffer;
  
  err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
  if (err < 0)
    {
      printf("error opening PCM device \n");
      return 1;
    }
  
  err = snd_pcm_hw_params_malloc(&params);
  if (err < 0)
    {
      printf("error allocating hardware\n");
      return 1;
    }

  err = snd_pcm_hw_params_any(handle, paams);
  if (err < 0)
    {
      printf("error initializing hardware parameter structure\n");
      return 1;
    }
  
  if ((err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
    {
      printf("error setting access type\n");
      return 1;
    }

  if ((err = snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE)) < 0)
    {
      printf("error setting format \n");
      return 1;
    }

  if ((err = snd_pcm_hw_params_set_channels(handle, params, 2)) < 0)
    {
      printf("error with configuration space\n");
      return 1;
    }

  if ((err = snd_pcm_hw_params_set_rate_near(handle, params, &sample_rate,0)) < 0)
    {
      printf("error with empty configuration space\n");
      return 1;
    }

  if ((err = snd_pcm_hw_params(handle,params)) < 0)
    {
      printf("errr setting PCM hardware parameters\n");
      return 1;
    }

  buff = (char *)malloc(BUFF_SIZE * snd_pcm_format_width(SND_PCM_FORMAT_S16_LE) / 8 * 2);

  FILE *wavFile = fopen("./mono_voice_file.wav", rb);
  if (!wavFile)
    {
      print("error opening wav file\n");
      return 1;
    }
  
  snd_pcm_hw_params_free (hw_params);

  fprintf(stdout, "hw_params freed\n");
  
  vga_ball_arg_t vla;
  static const char filename[] = "/dev/vga_ball";

  if ( (vga_ball_fd = open(filename, O_RDWR)) == -1) {
    fprintf(stderr, "could not open %s\n", filename);
    return -1;
  }
  

  while(!feof(wavFile)){
    
    /* allocate buffer for audio input */
    size_t nmemb = (BUFF_SIZE * snd_pcm_format_width(SND_PCM_FORMAT_S16_LE) / 8 * 2);
    int br = fread(buffer, 1, nmemb, wavFile);
    if (br < nmemb)
      {
        if((err = snd_pcm_writei(handle, buffer, br / (snd_pcm_format_wiedth(SND_PCM_FORMAT_S16_LE) / 8 * 2))) == -EPIPE)
          {
            snd_pcm_prepare(handle);
            printf("underrun. prepared\n");
          }
        else
          {
            printf("error with received bytes\n");
            free(buffer);
            fclose(wavFile);
            snd_pcm_drain(handle);
            snd_pcm_close(handle);
            return 1;
          }
      }
      //incomp
      unsigned int pitchup = sample_rate * 2;
      snd_pcm_hw_params_set_rate_near(handle, params, &pitchup, 0);
    
  }
  //FREE THEM
  free(buffer);
  fclose(wavFile);
  snd_pcm_drain(handle);
  snd_pcm_close(handle);

  return 0;
}
