forked from ffainelli/openal-example
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathWav.cpp
142 lines (125 loc) · 4.36 KB
/
Wav.cpp
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
// WAV-loading example
// Source code retrieved from http://www.dunsanyinteractive.com/blogs/oliver/?p=72 on May 17, 2013 by Mark Hutcheson
// Copyright (c) 2011 Oliver Plunkett
#include "openal-example.h"
#include <stdio.h>
/*
* Struct that holds the RIFF data of the Wave file.
* The RIFF data is the meta data information that holds,
* the ID, size and format of the wave file
*/
struct RIFF_Header {
char chunkID[4];
int chunkSize;//size not including chunkSize or chunkID
char format[4];
};
/*
* Struct to hold fmt subchunk data for WAVE files.
*/
struct WAVE_Format {
char subChunkID[4];
int subChunkSize;
short audioFormat;
short numChannels;
int sampleRate;
int byteRate;
short blockAlign;
short bitsPerSample;
};
/*
* Struct to hold the data of the wave file
*/
struct WAVE_Data {
char subChunkID[4]; //should contain the word data
int subChunk2Size; //Stores the size of the data block
};
/*
* Load wave file function. No need for ALUT with this
*/
bool loadWavFile(const std::string filename, ALuint* buffer,
ALsizei* size, ALsizei* frequency,
ALenum* format) {
//Local Declarations
FILE* soundFile = NULL;
WAVE_Format wave_format;
RIFF_Header riff_header;
WAVE_Data wave_data;
unsigned char* data;
try {
soundFile = fopen(filename.c_str(), "rb");
if (!soundFile)
throw (filename);
// Read in the first chunk into the struct
fread(&riff_header, sizeof(RIFF_Header), 1, soundFile);
//check for RIFF and WAVE tag in memeory
if ((riff_header.chunkID[0] != 'R' ||
riff_header.chunkID[1] != 'I' ||
riff_header.chunkID[2] != 'F' ||
riff_header.chunkID[3] != 'F') ||
(riff_header.format[0] != 'W' ||
riff_header.format[1] != 'A' ||
riff_header.format[2] != 'V' ||
riff_header.format[3] != 'E'))
throw ("Invalid RIFF or WAVE Header");
//Read in the 2nd chunk for the wave info
fread(&wave_format, sizeof(WAVE_Format), 1, soundFile);
//check for fmt tag in memory
if (wave_format.subChunkID[0] != 'f' ||
wave_format.subChunkID[1] != 'm' ||
wave_format.subChunkID[2] != 't' ||
wave_format.subChunkID[3] != ' ')
throw ("Invalid Wave Format");
//check for extra parameters;
if (wave_format.subChunkSize > 16)
fseek(soundFile, sizeof(short), SEEK_CUR);
//Read in the the last byte of data before the sound file
fread(&wave_data, sizeof(WAVE_Data), 1, soundFile);
//check for data tag in memory
if (wave_data.subChunkID[0] != 'd' ||
wave_data.subChunkID[1] != 'a' ||
wave_data.subChunkID[2] != 't' ||
wave_data.subChunkID[3] != 'a')
throw ("Invalid data header");
//Allocate memory for data
data = new unsigned char[wave_data.subChunk2Size];
// Read in the sound data into the soundData variable
if (!fread(data, wave_data.subChunk2Size, 1, soundFile))
throw ("error loading WAVE data into struct!");
//Now we set the variables that we passed in with the
//data from the structs
*size = wave_data.subChunk2Size;
*frequency = wave_format.sampleRate;
//The format is worked out by looking at the number of
//channels and the bits per sample.
if (wave_format.numChannels == 1) {
if (wave_format.bitsPerSample == 8 )
*format = AL_FORMAT_MONO8;
else if (wave_format.bitsPerSample == 16)
*format = AL_FORMAT_MONO16;
} else if (wave_format.numChannels == 2) {
if (wave_format.bitsPerSample == 8 )
*format = AL_FORMAT_STEREO8;
else if (wave_format.bitsPerSample == 16)
*format = AL_FORMAT_STEREO16;
}
//create our openAL buffer and check for success
alGenBuffers(1, buffer);
//now we put our data into the openAL buffer and
//check for success
alBufferData(*buffer, *format, (void*)data,
*size, *frequency);
//errorCheck();
//clean up and return true if successful
fclose(soundFile);
return true;
} catch(const char* error) {
//our catch statement for if we throw a string
std::cerr << error << " : trying to load "
<< filename << std::endl;
//clean up memory if wave loading fails
if (soundFile != NULL)
fclose(soundFile);
//return false to indicate the failure to load wave
return false;
}
}