1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
// Reads Header and Data from WAVE file
// 2017-01-03
/*
* wave file header format:
* (4 byte) type = "RIFF"
* (4 byte) size (data, not file)
* (4 byte) type = "WAVE"
* (4 byte) type = "fmt "
*
* (32 bit) chunk_size
* (16 bit) format_type = 1 (1 = PCM, uncompressed)
* (16 bit) number_of_channels (1 = mono, 2 = stereo, can go on to several channels)
* (32 bit) sample_rate (samples per second)
* (32 bit) average_bytes_per_second
* (16 bit) bytes_per_sample
* (16 bit) bits_per_sample (bytes_per_sample * 8) (quality of sound, 8 bit, 16 bit)
*
* (4 byte) data = "data"
* (32 bit) size (size of data)
*
*/
//#include "stdafx.h" // Visual Studio only
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <vector>
#include <windows.h>
using namespace std;
void fopen_s(FILE ** file_pointer, const char * fname, const char * mode)
{
*file_pointer = fopen(fname, mode);
}
int main()
{
// create a file pointer
FILE *file_pointer = NULL;
// open file
fopen_s(&file_pointer, "440.wav", "rb"); // binary mode
if (!file_pointer)
{
cout << "Error: missing / bad file" << endl;
return 1;
}
// declare variables
// TODO - make wave header class
char type_1[5] = { 0 }; // "RIFF"
char type_2[5] = { 0 }; // "WAVE"
char type_3[5] = { 0 }; // "fmt "
DWORD size, chunk_size;
short format_type, channels;
DWORD sample_rate, avg_bytes_per_sec;
short bytes_per_sample, bits_per_sample;
char type_4[5] = { 0 }; // "data"
DWORD data_size;
// check for RIFF format
fread(type_1, sizeof(char), 4, file_pointer);
if (strcmp(type_1, "RIFF"))
{
cout << "Error: not RIFF format";
return 1;
}
// data size
fread(&size, sizeof(DWORD), 1, file_pointer);
// check for WAVE format
fread(type_2, sizeof(char), 4, file_pointer);
if (strcmp(type_2, "WAVE"))
{
cout << "Error: not WAVE format";
return 1;
}
// check for "fmt " string
fread(type_3, sizeof(char), 4, file_pointer);
if (strcmp(type_3, "fmt "))
{
cout << "Error: missing format string";
return 1;
}
// chunk size
fread(&chunk_size, sizeof(DWORD), 1, file_pointer);
// format type
fread(&format_type, sizeof(short), 1, file_pointer);
// number of channels
fread(&channels, sizeof(short), 1, file_pointer);
// sample rate
fread(&sample_rate, sizeof(DWORD), 1, file_pointer);
// average bytes per second
fread(&avg_bytes_per_sec, sizeof(DWORD), 1, file_pointer);
// bytes per sample
fread(&bytes_per_sample, sizeof(short), 1, file_pointer);
// bits per sample
fread(&bits_per_sample, sizeof(short), 1, file_pointer);
// check for "data" string
fread(type_4, sizeof(char), 4, file_pointer);
if (strcmp(type_4, "data"))
{
cout << "Error: missing data string";
return 1;
}
// data size
fread(&data_size, sizeof(DWORD), 1, file_pointer);
// output header info
cout << "chunk size " << chunk_size << endl;
cout << "format type " << format_type << endl;
cout << "channels " << channels << endl;
cout << "sample rate " << sample_rate << endl;
cout << "average bytes per second " << avg_bytes_per_sec << endl;
cout << "bytes per sample " << bytes_per_sample << endl;
cout << "bits per sample " << bits_per_sample << endl;
cout << "data size " << data_size << endl;
Sleep(100);
// attempt data collection for wave file
cout << "attempting data collection" << endl;
unsigned long number_of_samples = data_size/bytes_per_sample;
std::cout << "number of samples = " << number_of_samples << '\n';
std::vector<short> samples(number_of_samples);
size_t elements_read = fread(samples.data(), sizeof(short), number_of_samples, file_pointer);
fclose(file_pointer);
cout << "samples read = " << elements_read << "\n";
// for (size_t i = 0; i<samples.size(); ++i) // this works but could take a long time
for (size_t i = 0; i<50; ++i)
{
cout << setw(10) << i << setw(10) << samples[i] << '\n';
}
return 0;
}
|