www.pudn.com > raw-wave-lib-v0.1.zip > wave.c


#include "wave.h"
#include 
#include 
/*int normalize_wave_file_rms(wave_file_16_bit* str) {
  double normal_factor = 0.0, accum = 0.0;
  int count;
  for (count = 0; count < str->num_of_samples; ++count)
    accum += (double)(str->samples[count] * str->samples[count]) / str->num_of_samples;
  
  normal_factor = sqrt(accum);
  for (count = 0; count < str->num_of_samples; ++count)
    str->samples[count] = SHRT_MAX * (str->samples[count] / normal_factor);
  

  return 0;
}*/
/*
int normalize_wave_file(wave_file_16_bit* str) {
  double normal_factor = 0.0;
  int count;
  short int current_max_value = -SHRT_MAX;

  for (count = 0; count < str->num_of_samples; ++count)
    if (abs(str->samples[count]) > current_max_value)
      current_max_value = abs(str->samples[count]);
  
  normal_factor = current_max_value;
  for (count = 0; count < str->num_of_samples; ++count)
    str->samples[count] = SHRT_MAX * (str->samples[count] / normal_factor);

  return 0;


}
*/

int write_wave_struct_to_file(FILE* file, wave_file_struct* str) {
  unsigned int length = sizeof(sample_block) * str->num_of_samples * str->channels;
  int total = 4 + 4 + 4 + 2 + 2 + 4 + 4 + 2 + 2 + 4 + 4 + length;
  int temp_int;
  unsigned int written = 0;
  unsigned int assumed_written = 0;
  short int temp_short;
  
  
  assumed_written += 4;
  written += fwrite("RIFF",sizeof(char),4,file);
  assumed_written++;
  written += fwrite(&total,sizeof(int),1,file); //length of file minus 8
  assumed_written += 8;
  written += fwrite("WAVEfmt ",sizeof(char),8,file); // header stuff

  temp_int = 16; temp_short = 1;
  assumed_written++;
  written += fwrite(&temp_int,sizeof(int),1,file);  //16 bytes in header file
  assumed_written++;
  written += fwrite(&temp_short,sizeof(short int),1,file); // 1 means uncompressed wave

  assumed_written++;
  written += fwrite(&(str->channels),sizeof(short int),1,file);
  assumed_written++;
  written += fwrite(&(str->sample_rate),sizeof(int),1,file);

  temp_int = str->sample_rate * str->channels;
  assumed_written++;
  written += fwrite(&temp_int,sizeof(int),1,file);  //combined value of hertz * channels

  temp_short = sizeof(sample_block);
  assumed_written++;
  written += fwrite(&temp_short,sizeof(short int),1,file);  //bytes per sample
  temp_short = sizeof(sample_block) * 8;
  assumed_written++;
  written += fwrite(&temp_short,sizeof(short int),1,file); // bits per sample
  assumed_written += 4;
  written += fwrite("data",sizeof(char),4,file);
  

  assumed_written++;
  written += fwrite(&length,sizeof(int),1,file);
  if (str->channels == 1) {
    assumed_written += str->num_of_samples;
    written += fwrite(str->samples,sizeof(sample_block),str->num_of_samples,file);
  } else {
    assumed_written += str->num_of_samples * str->channels;
    for (temp_int = 0; temp_int < str->num_of_samples; ++temp_int) {
      for (temp_short = 0; temp_short < str->channels; ++temp_short) {
	written += fwrite(str->samples + temp_int + temp_short * str->num_of_samples, sizeof(sample_block), 1, file);
      }
    }
  }


  if (str->appendage != APPENDAGE_NULL) {
    assumed_written++;
    written += fwrite(&(str->appendage),sizeof(unsigned int),1, file);

  }
  if (assumed_written != written) {
    fprintf(stderr,"WARNING: wrote smaller file than assumed.\n");
    fprintf(stderr,"Should have written %d, wrote %d instead. Out of space?\n", assumed_written, written);
  }

  return 0;
}

int initialize_wave_struct(wave_file_struct* str, double* array, unsigned int array_length, int sample_rate, unsigned int appendage, int channels) {
  int count;

  str->num_of_samples = array_length / channels;
  str->channels = channels;
  str->sample_rate = sample_rate;
  str->appendage = appendage;
  str->samples = (sample_block*)malloc(sizeof(sample_block) * str->num_of_samples * channels + 1);
  
  for (count = 0; count < str->num_of_samples * channels; ++count) {
    str->samples[count] = array[count] * (double)(SHRT_MAX);
  }
  return 0;
}
int extract_double_array_from_struct(wave_file_struct* str, double* array) {
  int count;

  for (count = 0; count < str->num_of_samples * str->channels; ++count)
    array[count] = str->samples[count] / (double)(SHRT_MAX);

  return 0;
}


int initialize_wave_struct_from_file(FILE* file, wave_file_struct* str, int to_mono) {
  int read_items;
  char text[13];
  short int temp_short;
  long int temp_int;
  
  short int channels;
  unsigned int length;
  
  read_items = fread(text,sizeof(char),12,file);
  if (feof(file)) {
    fprintf(stderr,"end of file detected\n");
  }
  if (ferror(file)) {
    fprintf(stderr, "error in stream... :( \n");
  }
  if (read_items != 12) {
    fprintf(stderr, "file not big enough to be a wav file: %d of 12\n", read_items);
    return 1;
  }
  if (text[0] == 'R' && text[1] == 'I' && text[2] == 'F' && text[3] == 'F') {
    
  } else {
    //not a wav file
    fprintf(stderr,"not a wav file, no riff header\n");
    return 1;
  }

  if (text[8] == 'W' && text[9] == 'A' && text[10] == 'V' && text[11] == 'E') {
  } else {
    fprintf(stderr, "not a wav file, no 'WAVE' found\n");
    return 1;
  }
  
  read_items = fread(text,sizeof(char),4,file);  //fmt_
  if (read_items != 4) {
    fprintf(stderr, "EOF before reading 4 bytes of fmt_\n");
    return 1;
  }
  if (text[0] == 'f' && text[1] == 'm' && text[2] == 't' && text[3] == ' ') {
  } else {
    fprintf(stderr, "fmt  not in header of wav\n");
    return 1;
  }

  
  read_items = fread(&temp_int,sizeof(int),1,file); //this is probably 16
  if (read_items != 1) {
    fprintf(stderr, "EOF: couldn't read fmt_ header length\n");
    return 1;
  }
  if (temp_int != 16) {
    fprintf(stderr,"header length of fmt_ is not 16 bytes like expected\n");
    return 1;
  }
  read_items = fread(&temp_short,sizeof(short int),1,file);
  if (read_items != 1) {
    fprintf(stderr, "EOF: couldn't read uncompressed WAV signature\n");
  }
  if (temp_short != 1) {
    fprintf(stderr,"this isn't a wav file... wav header isn't one\n");
    return 1;
  }
  read_items = fread(&channels, sizeof(short int), 1, file);
  if (to_mono)
    str->channels = 1;
  else
    str->channels = channels;
  if (read_items != 1) {
    fprintf(stderr, "EOF before reading channel data\n");
    return 1;
  }
  if (1) {
    fprintf(stderr, "Channels: %d\n",channels);

  }
  read_items = fread(&(str->sample_rate), sizeof(int), 1, file);
  if (read_items != 1) {
    fprintf(stderr, "EOF before reading hertz data\n");
    return 1;
  }
  fprintf(stderr, "Sample rate: %d\n", str->sample_rate);
  read_items = fread(&temp_int, sizeof(int), 1, file);
  if (read_items != 1) {
    fprintf(stderr, "EOF before reading size of second in bytes data\n");
    return 1;
  }
  read_items = fread(&temp_short, sizeof(short int), 1, file);
  if (read_items != 1) {
    fprintf(stderr, "EOF before reading bytes per sample data\n");
    return 1;
  }
  read_items = fread(&temp_short,sizeof(short int),1,file);
  if (read_items != 1) {
    fprintf(stderr, "EOF before reading bits per sample data\n");
    return 1;
  }
  if (temp_short != sizeof(sample_block) * 8) {
    fprintf(stderr, "This file is not 16 bits per sample\nThis program can only handle 16 bit samples\n");
    return 1;
  }
  //now...
  
  read_items = fread(text,sizeof(char),4,file);
  if (read_items != 4) {
    fprintf(stderr, "EOF before reading next header title: data?\n");
    return 1;
  }
  if (text[0] == 'd' && text[1] == 'a' && text[2] == 't' && text[3] == 'a') {

  } else {
    fprintf(stderr, "chuck error: \"data\" is not defined\n");
    return 1;
  }
  
  read_items = fread(&length,sizeof(int),1,file);
  if (read_items != 1) {
    fprintf(stderr, "EOF before reading length of wave file\n");
    return 1;
  }
  str->num_of_samples = length / channels / sizeof(sample_block);
  fprintf(stderr, "Number of samples: %d\n",str->num_of_samples);
  str->samples = (sample_block*)malloc(str->num_of_samples * sizeof(sample_block) * str->channels + 1);
  if (channels == 1) {
    read_items = fread(str->samples,sizeof(sample_block),str->num_of_samples,file);
    if (read_items != str->num_of_samples) {
      fprintf(stderr,"%d samples attempted to be read in one-channel file\n%d samples achieved\n",str->num_of_samples, read_items);
      return 1;
    }
    
  } else {
    sample_block sam;
    if (to_mono) {
      int count, count_sub;
      for (count = 0; count < str->num_of_samples; ++count) {
	for (count_sub = 0; count_sub < channels; ++count_sub) {
	  read_items = fread(&sam,sizeof(sample_block),1,file);
	  if (read_items != 1) {
	    fprintf(stderr, "EOF while reading samples from a multichannel file\n");
	    return 1;
	  }
	  
	}
	str->samples[count] = sam;
	
      }
    } else {
      int count, count_sub, N = str->num_of_samples;
      for (count = 0; count < N; ++count) {
	for (count_sub = 0; count_sub < channels; ++count_sub) {
	  read_items = fread(&sam,sizeof(short int),1,file);
	  if (read_items != 1) {
	    fprintf(stderr, "EOF while reading samples from a multichannel file into a multichannel struct\n");
	    return 1;
	  }
	  str->samples[count + N * count_sub] = sam;
	}
      }
    }
    //} else {//end_to_mono
    
  }
  
  
  

  temp_short = fread(&(str->appendage), sizeof(unsigned int), 1, file);
  if (temp_short == 0)
    str->appendage = APPENDAGE_NULL;
  fprintf(stderr,"%d = fread(%x)\n",temp_short, str->appendage);

  return 0;
}

void free_wave_struct(wave_file_struct* str) {
  free(str->samples);
}