#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

#include "wav_lib.h"



/*
   demux a single channel from a file, probably not a really usefull function,
    but its going to help me figure the complex one out.
*/

unsigned int demuxSingle(wav_sig *from, int8_t * to, unsigned long bsize, int channelNum ){

  int8_t *    rawstream;
  unsigned long count;
  unsigned long sample, samples, index;  
  unsigned int  samplesize;
  unsigned int  channel;
  unsigned int  byte;
    
  samplesize = from->blkalign; 

  if ((rawstream = (int8_t *)malloc(samplesize * bsize)) == NULL) {
    printf("DemuxSingle: can't allocate %d bytes\n", samplesize * bsize );
    return 0;
  }  

  if (from->len < bsize){
    count = read(from->handle, rawstream, from->len);
    from->len -= count;
  } else {
    count = read(from->handle, rawstream, (bsize * from->chans) );
    from->len -= count;
  }
  
  samples = count/samplesize; 
    
  // if (channelNum > from->chans) {
  //   memfill(
  //} else {  
  
  index = 0;  
  for (sample = 0; sample < samples; sample++) {
    for (channel = 0; channel < from->chans; channel++) {
      for (byte = 0; byte < from->depth/8; byte++) {     
        if (channel == channelNum ) {
          to[(sample*from->depth/8)+byte] = rawstream[index];
        }  
        index++;      
      }
    }
  }  
  
  free(rawstream);
  return samples;
  
}




unsigned int demux(wav_sig *from, int8_t ** to, unsigned long bsize){

  int8_t *    rawstream;
  unsigned long count;
  unsigned long sample, samples, index;  
  unsigned int  samplesize;
  unsigned int  channel;
  unsigned int  byte;
    
  samplesize = from->blkalign; 
    
  if ((rawstream = (int8_t *)malloc(samplesize * bsize)) == NULL) {
    printf("demux: can't allocate %d bytes\n", samplesize * bsize );
    return 0;
  }  

  if (from->len < bsize){
    count = read(from->handle, rawstream, from->len);
    from->len -= count;
  } else {
    count = read(from->handle, rawstream, (bsize * from->chans) );
    from->len -= count;
  }
      
  samples = count/samplesize;   
  
  index = 0;  
  for (sample = 0; sample < samples; sample++) {
    for (channel = 0; channel < from->chans; channel++) {
      for (byte = 0; byte < from->depth/8; byte++) {   
        to[channel][(sample*from->depth/8)+byte] = rawstream[index];
        index++;      
      }
    }
  }

  free(rawstream);
  
  return count/from->chans; // samples * depth 
    
}



/*
  this function needs to have had wav_sig initialized with the number of channels etc, 
  it expects 'from' to match 'to'.
*/


unsigned int mux(wav_sig *to, int8_t ** from, unsigned long bsize){

  int8_t *    rawstream;
  unsigned long count;
  unsigned long sample, samples, index;  
  unsigned int  samplesize;
  unsigned int  channel;
  unsigned int  byte;
    
  samplesize = to->blkalign; 
  
  printf("Allocating %d bytes\n", ( to->chans * bsize));  
    
  if ((rawstream = (int8_t *)malloc(to->chans * bsize)) == NULL) {
    printf("mux: can't allocate %d bytes\n", to->chans * bsize );
    return 0;
  }  
      
  samples = bsize/samplesize;   
  
  index = 0;  
  for (sample = 0; sample < samples; sample++) {
    for (channel = 0; channel < to->chans; channel++) {
      for (byte = 0; byte < to->depth/8; byte++) {   
      //  printf(" byte %d of channel %d of sample %d\n", byte, channel, sample);       
        rawstream[index] = from[channel][(sample*to->depth/8)+byte] ;        
        index++;              
      }
    }
  }
  
  printf("index is %d\n", index);

  write(to->handle, rawstream, to->chans * bsize);
  to->sofar += (to->chans * bsize);

  free(rawstream);
    
}


/*
unsigned int mux(wav_sig *to, sample_t ** from, unsigned long bsize ){


  if (from->len < bsize){
    count = read(from->handle, rawstream, from->len);
    from->len -= count;
  } else {
    count = read(from->handle, rawstream, (bsize * from->chans) );
    from->len -= count;
  }


}
*/






/*   --- GARBAGE BIN ---




typedef union sample_u {

  unsigned char ubyte[2];
  signed char   sbyte[2];
  uint16_t      uint;
  int16_t       sint;

} sample_t;



unsigned int demuxSingle(wav_sig *from, int8_t * to, unsigned long bsize, int channelNum ){

  int8_t *    rawstream;
  unsigned long count;
  unsigned long sample, samples, index;  
  unsigned int  samplesize;
  unsigned int  channel;
  unsigned int  byte;
    
  samplesize = from->blkalign; // depth * channels
  
 // printf("Incomming buffer is %d bytes\n", bsize);
//  printf("Chunk size is %d bytes\n", samplesize);
  
  if ((rawstream = (int8_t *)malloc(samplesize * bsize)) == NULL) {
    printf("demuxSingle: can't allocate %d bytes\n", samplesize * bsize );
    return 0;
  }  

  if (from->len < bsize){
    count = read(from->handle, rawstream, from->len);
    from->len -= count;
  } else {
    count = read(from->handle, rawstream, (bsize * from->chans) );
    from->len -= count;
  }
  
//  printf("read %d bytes\n", count);
  
  samples = count/samplesize; //((from->depth/8)* from->chans);
    
 // printf("Depth %d, Channels %d\n", from->depth, from->chans);  
    
 // printf("%d samples in stream\n", samples);  
    
  // if (channelNum > from->chans) {
  //   memfill(
  //} else {  
  
  index = 0;  
  for (sample = 0; sample < samples; sample++) {
   // printf("- sample %d\n", sample);
    for (channel = 0; channel < from->chans; channel++) {
//      printf("-- channel %d of %d\n", channel, from->chans);
      for (byte = 0; byte < from->depth/8; byte++) {   
     //   printf("--- byte %d\n", byte);    
        if (channel == channelNum ) {
          to[(sample*from->depth/8)+byte] = rawstream[index];
        }  
        index++;      
      }
    }
  }

//  printf("Remaining Index is %d\n", index);
  
  
  free(rawstream);
  
  
}




int main(void) {

 sample_t test;
 
 test.ubyte[0] = 31;
 printf("unsinged value: %d signed value: %d\n", test.ubyte[0], test.sbyte[0]);

 test.ubyte[0] = 0;
 test.ubyte[1] = 128;

 printf("unsigned int is %d\n", test.uint);
 printf("signed int is   %d\n", test.sint); 

 return 0;
}


int main(void) {

 sample_t test[5];
 
 test[0].ubyte[0] = 31;
 printf("unsinged value: %d signed value: %d\n", test[0].ubyte[0], test[0].sbyte[0]);

 test[0].ubyte[0] = 0;
 test[0].ubyte[1] = 128;

 printf("unsigned int is %d\n", test[0].uint);
 printf("signed int is   %d\n", test[0].sint); 

 return 0;
}



 for (sampleCount = count; sampleCount > 0; sampleCount--) {
  
      
    if (channelNum > from->chans) { 
      sample = 0;
    } else {
      sample = rawstream
    }
    
    
    
    if (from->depth == 8) {
       to[sampleCount].sbyte = sample;
    } else if (from->depth == 16) {
       to[sampleCount].sint = sample;
    } else {
       printf("unsupported depth %d bits\n", from->depth);
       free(rawstream);
       return 0;
    }
    
    
    
  }
  
  */
