From 09d68d3d1d77d45343e3562c0b5e0cd6816d47d3 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 17 Apr 2011 14:21:29 +0000 Subject: Initial Ogg Vorbis sounds effect support. --- src/audio/Makefile.am | 2 ++ src/audio/buffers.cc | 32 ++++++++++++++++++++-- src/audio/pcm.cc | 31 ++++++++++++++++++--- src/audio/pcm.h | 14 +++++++++- src/audio/vorbisfile.cc | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ src/audio/vorbisfile.h | 24 +++++++++++++++++ src/audio/wavfile.cc | 11 +++----- src/audio/wavfile.h | 2 +- 8 files changed, 171 insertions(+), 16 deletions(-) create mode 100644 src/audio/vorbisfile.cc create mode 100644 src/audio/vorbisfile.h (limited to 'src/audio') 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 #include +#include + #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 +#include + +#include "audio/vorbisfile.h" +#include "filesystem/filesystem.h" +#include "sys/sys.h" + +#include +#include + +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); }; } -- cgit v1.2.3