Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src/audio
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2011-04-17 14:21:29 +0000
committerStijn Buys <ingar@osirion.org>2011-04-17 14:21:29 +0000
commit09d68d3d1d77d45343e3562c0b5e0cd6816d47d3 (patch)
tree6b89c585fe8cd8bd49699cdb349566d3f382010e /src/audio
parent8264546908f1722b4d0f0e91c42dd791ba8535c4 (diff)
Initial Ogg Vorbis sounds effect support.
Diffstat (limited to 'src/audio')
-rw-r--r--src/audio/Makefile.am2
-rw-r--r--src/audio/buffers.cc32
-rw-r--r--src/audio/pcm.cc31
-rw-r--r--src/audio/pcm.h14
-rw-r--r--src/audio/vorbisfile.cc71
-rw-r--r--src/audio/vorbisfile.h24
-rw-r--r--src/audio/wavfile.cc11
-rw-r--r--src/audio/wavfile.h2
8 files changed, 171 insertions, 16 deletions
diff --git a/src/audio/Makefile.am b/src/audio/Makefile.am
index 11b7749..8b76cc9 100644
--- a/src/audio/Makefile.am
+++ b/src/audio/Makefile.am
@@ -12,6 +12,7 @@ noinst_HEADERS = \
buffers.h \
pcm.h \
sources.h \
+ vorbisfile.h \
wavfile.h
libaudio_la_SOURCES = \
@@ -19,6 +20,7 @@ libaudio_la_SOURCES = \
buffers.cc \
pcm.cc \
sources.cc \
+ vorbisfile.cc \
wavfile.cc
libaudio_la_DEPENDENCIES = \
diff --git a/src/audio/buffers.cc b/src/audio/buffers.cc
index 41103ad..99c9e2e 100644
--- a/src/audio/buffers.cc
+++ b/src/audio/buffers.cc
@@ -9,6 +9,7 @@
#include "audio/audio.h"
#include "audio/buffers.h"
#include "audio/pcm.h"
+#include "audio/vorbisfile.h"
#include "audio/wavfile.h"
#include "sys/sys.h"
@@ -66,9 +67,36 @@ size_t Buffers::load(std::string name)
return 0;
}
- // load wav file
- PCM *pcm = Wav::load(name);
+ std::string filename;
+
+ PCM *pcm = 0;
+
+ // try the .oga version
+ if (!pcm) {
+ filename.assign("sounds/");
+ filename.append(name);
+ filename.append(".oga");
+ pcm = Vorbis::load(filename);
+ }
+
+ // try the .oga version
+ if (!pcm) {
+ filename.assign("sounds/");
+ filename.append(name);
+ filename.append(".ogg");
+ pcm = Vorbis::load(filename);
+ }
+
+ // try the .wav version
+ if (!pcm) {
+ filename.assign("sounds/");
+ filename.append(name);
+ filename.append(".wav");
+ pcm = Wav::load(filename);
+ }
+
if (!pcm) {
+ con_warn << "Could not open sound " << name << std::endl;
registry[name] = 0;
return 0;
}
diff --git a/src/audio/pcm.cc b/src/audio/pcm.cc
index b04e080..2ef7381 100644
--- a/src/audio/pcm.cc
+++ b/src/audio/pcm.cc
@@ -7,6 +7,8 @@
#include <stdlib.h>
#include <string.h>
+#include <cassert>
+
#include "audio/pcm.h"
#include "audio/wavfile.h"
@@ -15,12 +17,12 @@ namespace audio
PCM::PCM(unsigned int samplerate, unsigned int bitspersample, unsigned int channels, size_t size)
{
+ pcm_size = size;
+ pcm_buff_size = size;
pcm_bitspersample = bitspersample;
pcm_samplerate = samplerate;
- pcm_size = size;
pcm_channels = channels;
-
- pcm_data = (unsigned char *) malloc(pcm_size);
+ pcm_data = (unsigned char *) malloc(pcm_buff_size);
clear();
}
@@ -31,7 +33,28 @@ PCM::~PCM()
void PCM::clear()
{
- memset(pcm_data, 0, pcm_size);
+ memset(pcm_data, 0, pcm_buff_size);
}
+void PCM::set_size(size_t size) {
+ assert(size <= pcm_buff_size);
+ pcm_size = size;
+}
+
+void PCM::grow(size_t size) {
+ assert (size >= pcm_buff_size);
+
+ // store a pointer to the previous buffer
+ unsigned char *old_data = pcm_data;
+
+ // allocate a new, larger buffer
+ pcm_buff_size = size;
+ pcm_data = (unsigned char *) malloc(pcm_buff_size);
+
+ // copy the content
+ memcpy(pcm_data, old_data, pcm_size);
+
+ free(old_data);
}
+
+} // namespace audio
diff --git a/src/audio/pcm.h b/src/audio/pcm.h
index 8df44e8..62052bf 100644
--- a/src/audio/pcm.h
+++ b/src/audio/pcm.h
@@ -21,6 +21,12 @@ public:
~PCM();
void clear();
+
+ /// set the data size
+ void set_size(size_t size);
+
+ /// grow the buffer
+ void grow(size_t size);
/// pointer to the raw pcm data
inline unsigned char *data() {
@@ -32,7 +38,12 @@ public:
return &pcm_data[index];
}
- /// size in bytes
+ /// size of the buffer
+ inline size_t buff_size() {
+ return pcm_buff_size;
+ }
+
+ /// size of the audio data, in bytes
inline size_t size() {
return pcm_size;
}
@@ -59,6 +70,7 @@ private:
unsigned int pcm_samplerate;
unsigned int pcm_bitspersample;
size_t pcm_size;
+ size_t pcm_buff_size;
};
}
diff --git a/src/audio/vorbisfile.cc b/src/audio/vorbisfile.cc
new file mode 100644
index 0000000..572b945
--- /dev/null
+++ b/src/audio/vorbisfile.cc
@@ -0,0 +1,71 @@
+/*
+ audio/vorbis.cc
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#include "string.h"
+
+#include <iostream>
+#include <string>
+
+#include "audio/vorbisfile.h"
+#include "filesystem/filesystem.h"
+#include "sys/sys.h"
+
+#include <vorbis/codec.h>
+#include <vorbis/vorbisfile.h>
+
+namespace audio
+{
+
+PCM *Vorbis::load(std::string const & filename)
+{
+ if (!filename.size())
+ return 0;
+
+ filesystem::File *fs_file = filesystem::open(filename.c_str());
+ if (!fs_file) {
+ return 0;
+ }
+
+ std::string vorbis_path(fs_file->path());
+ vorbis_path.append(fs_file->name());
+ filesystem::close(fs_file);
+
+ OggVorbis_File vorbis_file;
+ if (ov_fopen(vorbis_path.c_str(), &vorbis_file) < 0 ) {
+ return 0;
+ }
+
+ vorbis_info* vorbis_streaminfo;
+ vorbis_streaminfo = ov_info(&vorbis_file, -1);
+
+ unsigned int samplerate = vorbis_streaminfo->rate;
+ unsigned int channels = vorbis_streaminfo->channels;
+ unsigned int bitspersample = 16; // always.
+
+ const size_t blocksize = 1024*1024; // 1Mb blocks
+
+ PCM *pcm = new PCM(samplerate, bitspersample, channels, blocksize);
+ pcm->set_size(0);
+
+ long bytesread = 0;
+
+ do {
+ // enlarge the pcm buffer if required
+ if (pcm->size() + 4096 > pcm->buff_size()) {
+ pcm->grow(pcm->buff_size() + blocksize);
+ }
+ bytesread = ov_read(&vorbis_file, (char *)pcm->data() + pcm->size(),4096,0,2,1,0);
+ pcm->set_size( pcm->size() + bytesread);
+ } while (bytesread > 0);
+
+ ov_clear(&vorbis_file);
+ con_debug << " " << filename << " " << pcm->samplerate() << "Hz " << pcm->bitspersample() << "bit "
+ << pcm->channels() << " chan " << pcm->size() << " bytes" << std::endl;
+
+ return pcm;
+}
+
+}
diff --git a/src/audio/vorbisfile.h b/src/audio/vorbisfile.h
new file mode 100644
index 0000000..aef7181
--- /dev/null
+++ b/src/audio/vorbisfile.h
@@ -0,0 +1,24 @@
+/*
+ audio/vorbis.h
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#ifndef __INCLUDED_AUDIO_VORBIS_H__
+#define __INCLUDED_AUDIO_VORBIS_H__
+
+#include "audio/pcm.h"
+
+namespace audio
+{
+
+/// class to read Xiph ogg vorbis files
+class Vorbis
+{
+public:
+ static PCM *load(std::string const & filename);
+};
+
+}
+
+#endif // __INCLUDED_AUDIO_VORBIS_H__
diff --git a/src/audio/wavfile.cc b/src/audio/wavfile.cc
index 3e3ca2b..58afca7 100644
--- a/src/audio/wavfile.cc
+++ b/src/audio/wavfile.cc
@@ -16,18 +16,13 @@
namespace audio
{
-PCM *Wav::load(std::string const & name)
+PCM *Wav::load(std::string const & filename)
{
- if (!name.size())
+ if (!filename.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;
}
@@ -115,7 +110,7 @@ PCM *Wav::load(std::string const & name)
}
if (total_bytes < datasize) {
- con_warn << "Error reading " << filename << ": file truncated!" << std::endl;
+ con_warn << "Error reading " << filename << ": file appears to be truncated!" << std::endl;
}
con_debug << " " << filename << " " << pcm->samplerate() << "Hz " << pcm->bitspersample() << "bit " <<
diff --git a/src/audio/wavfile.h b/src/audio/wavfile.h
index f987b80..ae61ab5 100644
--- a/src/audio/wavfile.h
+++ b/src/audio/wavfile.h
@@ -16,7 +16,7 @@ namespace audio
class Wav
{
public:
- static PCM *load(std::string const & name);
+ static PCM *load(std::string const & filename);
};
}