#include <stdio.h>
#include <fcntl.h>

#include <unistd.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>

#include <linux/soundcard.h>

#include "mixer.h"





int main()
{
   unsigned char b[2];
   int i;
   int audio_fd;
   int mixer_fd;
   int result;
   int value[256];
   struct
   {
      int max;
      int volume;
      int line;
      int mic;
      int recsrc;
   } store;
   char *text[2][25] =
   {
      {
      },
      {
      }
   };
   int ctl[2][25] =
   {
      {
      },
      {
      }
   };





   audio_fd = open("/dev/audio", O_RDWR);
   if(audio_fd == -1)
   {
      perror("/dev/audio");
      exit(1);
   }
   printf("Filedescriptor of '/dev/audio': %d\n", audio_fd);



   mixer_fd = open("/dev/mixer", O_RDWR);
   if(mixer_fd == -1)
   {
      perror("/dev/mixer");
      close(audio_fd);
      exit(1);
   }
   printf("Filedescriptor of '/dev/mixer': %d\n", mixer_fd);





   result = ioctl(mixer_fd, SOUND_MIXER_READ_DEVMASK, &value[0]);
   if(result < 0)
   {
      perror("SOUND_MIXER_READ_DEVMASK");
      exit(1);
   }
   printf("SOUND_MIXER_READ_DEVMASK: %x\n", value[0]);
   if(!(value[0] & SOUND_MASK_MIC))
   {
      fprintf(stderr, "Soundcard does not support a microphone\n\n");
      exit(1);
   }



   result = ioctl(mixer_fd, SOUND_MIXER_READ_RECMASK, &value[0]);
   if(result < 0)
   {
      perror("SOUND_MIXER_READ_RECMASK");
      exit(1);
   }
   printf("SOUND_MIXER_READ_RECMASK: %x\n", value[0]);
   if(!(value[0] & SOUND_MASK_MIC))
   {
      fprintf(stderr, "Soundcard does not support a recording microphone\n\n");
      exit(1);
   }



   result = ioctl(mixer_fd, SOUND_MIXER_READ_STEREODEVS, &value[0]);
   if(result < 0)
   {
      perror("SOUND_MIXER_READ_STEREODEVS");
      exit(1);
   }
   printf("SOUND_MIXER_READ_STEREODEVS: %x\n", value[0]);
   if(value[0] & SOUND_MASK_MIC)
      puts("Soundcard supports a stereo microphone");
   else
      puts("Soundcard supports a mono microphone");

   

   result = ioctl(mixer_fd, SOUND_MIXER_READ_CAPS, &value[0]);
   if(result < 0)
   {
      perror("SOUND_MIXER_READ_CAPS");
      exit(1);
   }
   printf("SOUND_MIXER_READ_CAPS: %x\n", value[0]);



   result = ioctl(mixer_fd, SOUND_MIXER_READ_RECSRC, &value[0]);
   if(result < 0)
   {
      perror("SOUND_MIXER_READ_RECSRC");
      exit(1);
   }
   printf("SOUND_MIXER_READ_RECSRC: %x ... storing\n", value[0]);
   store.recsrc = value[0];
   


   value[0] = SOUND_MASK_MIC;
   result = ioctl(mixer_fd, SOUND_MIXER_WRITE_RECSRC, &value[0]);
   if(result < 0)
   {
      perror("SOUND_MIXER_WRITE_RECSRC");
      exit(1);
   }
   printf("SOUND_MIXER_WRITE_RECSRC: %x ... written\n", value[0]);
   
   

   result = ioctl(mixer_fd, SOUND_MIXER_READ_LINE, &value[0]);
   if(result < 0)
   {
      perror("SOUND_MIXER_READ_LINE");
      exit(1);
   }
   printf("SOUND_MIXER_READ_LINE: %x ... storing\n", value[0]);
   store.line = value[0];
   


   value[0] = 0;
   result = ioctl(mixer_fd, SOUND_MIXER_WRITE_LINE, &value[0]);
   if(result < 0)
   {
      perror("SOUND_MIXER_WRITE_LINE");
      exit(1);
   }
   printf("SOUND_MIXER_WRITE_LINE: %x ... written\n", value[0]);
   
   

   result = ioctl(mixer_fd, SOUND_MIXER_READ_MIC, &value[0]);
   if(result < 0)
   {
      perror("SOUND_MIXER_READ_MIC");
      exit(1);
   }
   printf("SOUND_MIXER_READ_MIC: %x ... storing\n", value[0]);
   store.mic = value[0];
   


   value[0] = 0xffff;
   result = ioctl(mixer_fd, SOUND_MIXER_WRITE_MIC, &value[0]);
   if(result < 0)
   {
      perror("SOUND_MIXER_WRITE_MIC");
      exit(1);
   }
   printf("SOUND_MIXER_WRITE_MIC: %x ... written\n", value[0]);
   
   

   result = ioctl(audio_fd, SNDCTL_DSP_RESET);
   if(result < 0)
   {
      perror("SNDCTL_DSP_RESET");
      exit(1);
   }
   printf("SNDCTL_DSP_RESET\n");


   result = ioctl(audio_fd, SNDCTL_DSP_SYNC);
   if(result < 0)
   {
      perror("SNDCTL_DSP_RESET");
      exit(1);
   }
   printf("SNDCTL_DSP_SYNC\n");


   value[0] = 4000;
   result = ioctl(audio_fd, SNDCTL_DSP_SPEED, &value[0]);
   if(result < 0)
   {
      perror("SNDCTL_DSP_SPEED");
      exit(1);
   }
   printf("SNDCTL_DSP_SPEED: %d\n", value[0]);



   value[0] = 0;
   result = ioctl(audio_fd, SNDCTL_DSP_STEREO, &value[0]);
   if(result < 0)
   {
      perror("SNDCTL_DSP_STEREO");
      exit(1);
   }
   printf("SNDCTL_DSP_STEREO: %d\n", value[0]);



   result = ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &value[0]);
   if(result < 0)
   {
      perror("SNDCTL_DSP_GETBLKSIZE");
      exit(1);
   }
   printf("SNDCTL_DSP_GETBLKSIZE: %x\n", value[0]);

   
   
   result = ioctl(audio_fd, SOUND_PCM_READ_CHANNELS, &value[0]);
   if(result < 0)
   {
      perror("SOUND_PCM_READ_CHANNELS");
      exit(1);
   }
   printf("SOUND_PCM_READ_CHANNELS: %x\n", value[0]);

   
   
   result = ioctl(audio_fd, SOUND_PCM_READ_RATE, &value[0]);
   if(result < 0)
   {
      perror("SOUND_PCM_READ_RATE");
      exit(1);
   }
   printf("SOUND_PCM_READ_RATE: %d\n", value[0]);

   
   
   result = ioctl(audio_fd, SOUND_PCM_READ_BITS, &value[0]);
   if(result < 0)
   {
      perror("SOUND_PCM_READ_BITS");
      exit(1);
   }
   printf("SOUND_PCM_READ_BITS: %x\n", value[0]);

   
   
/*   
   result = ioctl(audio_fd, SNDCTL_DSP_SETDUPLEX);
   if(result < 0)
   {
      perror("SNDCTL_DSP_SETDUPLEX");
      exit(1);

   }
   
   printf("SNDCTL_DSP_SETDUPLEX\n");

*/
   
   result = ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &value[0]);
   if(result < 0)
   {
      perror(text[0][i]);
      exit(1);

   }
   
   printf("SNDCTL_DSP_GETFMTS: %x\n", value[0]);



   value[0] = AFMT_U8;
   //value[0] = AFMT_S16_LE;
   //value[0] = AFMT_MPEG;
   
   result = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &value[0]);
   if(result < 0)
   {
      perror(text[0][i]);
      exit(1);

   }
   
   printf("SNDCTL_DSP_SETFMT: AFMT_U8\n");


   
   result = ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &value[0]);
   if(result < 0)
   {
      perror(text[0][i]);
      exit(1);

   }
   
   printf("SNDCTL_DSP_GETCAPS: %x\n", value[0]);


   b[0] = 0x00;
   b[1] = 0xff;
   for(i=0; i<0x1000; i++)
   {
      read(audio_fd, &b[0], 1);
      //printf("mic: %x\n", b[0]);
      putchar(b[0]);
   }

/*
   for(i=0; i<25; i++)
   {
      result = ioctl(audio_fd, ctl[0][i], &value[i]);
      if(result < 0)
      {
         perror(text[0][i]);
         exit(1);

      } *//* if(audio_fd == -1) *//*

      printf("%-27s: %x\n", text[0][i], value[i]);
   }
*/


   value[0] = store.mic;
   result = ioctl(mixer_fd, SOUND_MIXER_WRITE_MIC, &value[0]);
   if(result < 0)
   {
      perror("SOUND_MIXER_WRITE_MIC");
      exit(1);
   }
   printf("SOUND_MIXER_WRITE_MIC: %x ... restored\n", value[0]);
   

   value[0] = store.line;
   result = ioctl(mixer_fd, SOUND_MIXER_WRITE_LINE, &value[0]);
   if(result < 0)
   {
      perror("SOUND_MIXER_WRITE_LINE");
      exit(1);
   }
   printf("SOUND_MIXER_WRITE_LINE: %x ... restored\n", value[0]);
   

   value[0] = store.recsrc;
   result = ioctl(mixer_fd, SOUND_MIXER_WRITE_RECSRC, &value[0]);
   if(result < 0)
   {
      perror("SOUND_MIXER_WRITE_RECSRC");
      exit(1);
   }
   printf("SOUND_MIXER_WRITE_RECSRC: %x ... restored\n", value[0]);
   

   close(mixer_fd);
   close(audio_fd);

   return(0);

} /* int main() */
