Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-05-18 09:21:20 +0000
committerStijn Buys <ingar@osirion.org>2008-05-18 09:21:20 +0000
commit4a2bad92171ff8a9a248599f47087cfe39e93653 (patch)
treeb8a4fe7f616b3e4f707d89a35fff5e8b5fdcfcc8 /src/audio/wav.cc
parenta185c11f2397c0296a4b62cc266b4fa00a63c1e2 (diff)
OpenAL support
Diffstat (limited to 'src/audio/wav.cc')
-rw-r--r--src/audio/wav.cc119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/audio/wav.cc b/src/audio/wav.cc
new file mode 100644
index 0000000..5d118c6
--- /dev/null
+++ b/src/audio/wav.cc
@@ -0,0 +1,119 @@
+/*
+ audio/wav.h
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+/*
+see
+
+http://ccrma.stanford.edu/CCRMA/Courses/422/projects/WaveFormat/
+*/
+
+#include "string.h"
+
+#include <iostream>
+#include <string>
+
+#include "audio/wav.h"
+#include "filesystem/filesystem.h"
+#include "sys/sys.h"
+
+namespace audio {
+
+PCM *Wav::load(std::string const & name)
+{
+ if (!name.size())
+ return 0;
+
+ std::string filename("sounds/");
+ filename.append(name);
+ filename.append(".wav");
+
+ filesystem::File *wav_file = filesystem::open(filename.c_str());
+ if (!wav_file) {
+ con_warn << "Could not open " << filename << std::endl;
+ return 0;
+ }
+
+ unsigned char header[44];
+ memset(header, 0, sizeof(header));
+ if (!wav_file->read(header, 44)) {
+ con_warn << "Error reading " << filename << std::endl;
+ filesystem::close(wav_file);
+ return 0;
+ }
+
+ // header RIFF
+ if (strncmp((char *)header, "RIFF", 4)) {
+ con_warn << "Error reading " << filename << ": invalid RIFF header!" << std::endl;
+ filesystem::close(wav_file);
+ return 0;
+ }
+
+ // format WAVE
+ if (strncmp((char *)header+8, "WAVE", 4) != 0) {
+ con_warn << "Error reading " << filename << ": invalid WAVE header!" << std::endl;
+ filesystem::close(wav_file);
+ return 0;
+ }
+
+ // file size
+ //size_t chunksize = header[4] + (header[5] << 8) + (header[6] << 16) + (header[7] << 24);
+
+ if (strncmp((char *)header+12, "fmt ", 4) != 0) {
+ con_warn << "Error reading " << filename << ": invalid format header!" << std::endl;
+ filesystem::close(wav_file);
+ return 0;
+ }
+
+ size_t subchunksize1 = header[16] + (header[17] << 8) + (header[18] << 16) + (header[19] << 24);
+ size_t audioformat = header[20] + (header[21] << 8);
+
+ if ((subchunksize1 != 16) || (audioformat != 1)) {
+ con_warn << "Error reading " << filename << ": unrecognized file format!" << std::endl;
+ filesystem::close(wav_file);
+ return 0;
+
+ }
+
+ unsigned int channels = header[22] + (header[23] << 8);
+ if ((channels < 1) || (channels >2)) {
+ con_warn << "Error reading " << filename << ": invalid number of channels!" << std::endl;
+ filesystem::close(wav_file);
+ return 0;
+ }
+
+ unsigned int samplerate = header[24] + ((size_t)header[25] << 8) + ((size_t)header[26] << 16) + ((size_t)header[27] << 24);
+ //size_t byterate = header[28] + (header[29] << 8) + (header[30] << 16) + (header[31] << 24);
+ //size_t blockalign = header[32] + (header[33] << 8);
+ size_t bitspersample = header[34] + (header[35] << 8);
+
+ if (strncmp((char *)header + 36, "data", 4) !=0) {
+ con_warn << "Error reading " << filename << ": invalid data header!" << std::endl;
+ filesystem::close(wav_file);
+ return 0;
+ }
+
+ size_t datasize = header[40] + (header[41] << 8) + (header[42] << 16) + (header[43] << 24);
+
+ PCM *pcm = new PCM(samplerate, bitspersample, channels, datasize);
+ const size_t readblocksize = channels * (bitspersample / 8);
+ size_t total_bytes = 0;
+
+ while ((wav_file->read((void *)(*pcm)[total_bytes], readblocksize)) && (total_bytes < datasize)) {
+ total_bytes += readblocksize;
+ }
+
+ if (total_bytes < datasize) {
+ con_warn << "Error reading " << filename << ": file truncated!" << std::endl;
+ }
+
+ con_print << " " << filename << " " << pcm->samplerate()<< "Hz " << pcm->bitspersample() << "bit " <<
+ pcm->channels() << " chan " << pcm->size() << " bytes" << std::endl;
+
+ filesystem::close(wav_file);
+ return pcm;
+}
+
+}