Logo Search packages:      
Sourcecode: qarecord version File versions  Download package

wavmix.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <string.h>
#include <math.h>

void display_header(char *fn);
void mix32(char **fn);

#define MAX 2147483647.0

char *fn[256];
double gain[2][256], gain[2][256];
int n;

int main(int argc, char **argv) {

  int l1;
  
  if (argc < 7) {
    fprintf(stderr, "\nwavmix <file_1> <gain_1_l> <gain_1_r> <file_2> <gain_2_l> <gain_2_r> ... <file_n> <gain_n_l> <gain_n_r>\n\n");
    exit(1);
  }
  n = argc / 3;
  printf("\nMixing %d files.\n", n);
  for (l1 = 0; l1 < n; l1++) {
    fn[l1] = strdup(argv[l1 * 3 + 1]);
    gain[0][l1] = atof(argv[l1 * 3 + 2]);
    gain[1][l1] = atof(argv[l1 * 3 + 3]);
    printf("\nFile: %s Gain Left: %f Gain Right: %f\n", fn[l1], gain[0][l1], gain[1][l1]);
    display_header(fn[l1]);
  }
  mix32(fn);
}

void display_header(char *fn) {

  FILE *f;
  char ChunkID[5], Format[5], SubChunk1ID[5], SubChunk2ID[5];
  int ChunkSize, Subchunk1Size, AudioFormat, NumChannels, SampleRate, ByteRate, BlockAlign, BitsPerSample, Subchunk2Size;
  int l1;
  unsigned char c[4];
   
  f = fopen(fn, "r");
  fread(ChunkID, 1, 4, f);
  ChunkID[4] = 0;
  printf("\nChunkID......: %s\n", ChunkID);
  fread(c, 1, 4, f);
  ChunkSize = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
  printf("ChunkSize....: %d\n", ChunkSize);
  fread(Format, 1, 4, f);
  Format[4] = 0;
  printf("Format.......: %s\n", Format);
  fread(SubChunk1ID, 1, 4, f);
  SubChunk1ID[4] = 0;
  printf("SubChunk1ID..: %s\n", SubChunk1ID);
  fread(c, 1, 4, f);
  Subchunk1Size = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
  printf("Subchunk1Size: %d\n", Subchunk1Size);
  fread(c, 1, 2, f);
  AudioFormat = c[0] | (c[1] << 8);
  printf("AudioFormat..: %d\n", AudioFormat);
  fread(c, 1, 2, f);
  NumChannels = c[0] | (c[1] << 8);
  printf("NumChannels..: %d\n", NumChannels);
  fread(c, 1, 4, f);
  SampleRate = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
  printf("SampleRate...: %d\n", SampleRate);
  fread(c, 1, 4, f);
  ByteRate = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
  printf("ByteRate.....: %d\n", ByteRate);
  fread(c, 1, 2, f);
  BlockAlign = c[0] | (c[1] << 8);
  printf("BlockAlign...: %d\n", BlockAlign);
  fread(c, 1, 2, f);
  BitsPerSample = c[0] | (c[1] << 8);
  printf("BitsPerSample: %d\n", BitsPerSample);
  fread(SubChunk2ID, 1, 4, f);
  SubChunk2ID[4] = 0;
  printf("SubChunk2ID..: %s\n", SubChunk2ID);
  fread(c, 1, 4, f);
  Subchunk2Size = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
  printf("Subchunk2Size: %d\n", Subchunk2Size);
  fclose(f);
}

void mix32(char **fn) {

  FILE *f[256], *fw;
  char *fnw;
  int l1, l2, l3, index, i[2], size, ival;
  unsigned char c[4], buf[64];
  double global_gain, val[2], max;
  
  fnw = (char *)malloc(strlen(fn[0]) + 11);
  strcpy (fnw, fn[0]);
  fnw = strcat (fnw, "_mix.wav");
  if (!(fw = fopen(fnw, "w"))) {
    fprintf(stderr, "Could not open %s for writing.\n", fnw);
  } else {
    printf("Writing to %s.\n", fnw);
  }
  for(l1 = 0; l1 < n; l1++) {
    f[l1] = fopen(fn[l1], "r");
    fseek(f[l1], 44, SEEK_SET);
  }
  fseek(f[0], 40, SEEK_SET);
  fread(c, 1, 4, f[0]);
  size = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
  size /= 8;
  max = 0;
  for(l1 = 0; l1 < size; l1++) {
    for (l2 = 0; l2 < 2; l2++) {
      val[l2] = 0;
      for(l3 = 0; l3 < n; l3++) {        
        if (!feof(f[l3])) {
          fread(c, 1, 4, f[l3]);
          i[l2] = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
        } else {
          i[l2] = 0;
        }
        val[l2] += gain[l2][l3] * (double)i[l2]; 
      }  
      if (fabs(val[l2]) > max) max = fabs(val[l2]);
    }
  }
  printf("Found Maximum %f in Mix.\n", max);
  global_gain = MAX / max;
  rewind(f[0]);
  fread(buf, 1, 44, f[0]);
  fwrite(buf, 1, 44, fw);
  for(l1 = 0; l1 < n; l1++) {
    fseek(f[l1], 44, SEEK_SET);
  }
  for(l1 = 0; l1 < size; l1++) {
    for (l2 = 0; l2 < 2; l2++) {
      val[l2] = 0;
      for(l3 = 0; l3 < n; l3++) {        
        if (!feof(f[l3])) {
          fread(c, 1, 4, f[l3]);
          i[l2] = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
        } else {
          i[l2] = 0;
        }
        val[l2] += global_gain * gain[l2][l3] * (double)i[l2]; 
      }  
      if (fabs(val[l2]) > max) max = fabs(val[l2]);
      ival =  (int)val[l2]; 
      c[3] = ival >> 24;
      c[2] = (ival >> 16) - ((ival >> 24) << 8);
      c[1] = (ival >> 8) - ((ival >> 16) << 8);
      c[0] = (unsigned char)ival;
      fwrite(c, 1, 4, fw);
    }
  }
  for(l1 = 0; l1 < n; l1++) {
     fclose(f[l1]);
  }
  fclose(fw);            
}

Generated by  Doxygen 1.6.0   Back to index