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); }