Remove ALUT usage from SimGear .

Adapt the freealut code into a WAV-file reader. As a side-effect, it would now be possible to deploy WAV files compressed with gzip, since we use ZLib's gzread functions to read from disk.
This commit is contained in:
James Turner
2012-08-21 13:18:45 +01:00
parent 9ca112c362
commit c4f6aa2f90
19 changed files with 401 additions and 220 deletions

View File

@@ -111,7 +111,6 @@ if (MSVC AND MSVC_3RDPARTY_ROOT)
set (BOOST_ROOT ${MSVC_3RDPARTY_ROOT}/boost_1_44_0)
message(STATUS "BOOST_ROOT is ${BOOST_ROOT}")
set (OPENAL_INCLUDE_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include)
set (ALUT_INCLUDE_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include)
set (OPENAL_LIBRARY_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib)
endif (MSVC AND MSVC_3RDPARTY_ROOT)
@@ -124,7 +123,6 @@ else()
message(STATUS "SimGear mode: NORMAL")
find_package(OpenGL REQUIRED)
find_package(OpenAL REQUIRED)
find_package(ALUT REQUIRED)
find_package(OpenSceneGraph 3.0.0 REQUIRED osgText osgSim osgDB osgParticle osgGA osgUtil)
endif(SIMGEAR_HEADLESS)
@@ -257,7 +255,7 @@ include_directories(${PROJECT_BINARY_DIR}/simgear/xml)
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR}
${ALUT_INCLUDE_DIR} ${OPENAL_INCLUDE_DIR} )
${OPENAL_INCLUDE_DIR} )
add_definitions(-DHAVE_CONFIG_H)
add_definitions(-DHAVE_EXPAT_CONFIG_H)

View File

@@ -1,67 +0,0 @@
# Locate ALUT
# This module defines
# ALUT_LIBRARY
# ALUT_FOUND, if false, do not try to link to ALUT
# ALUT_INCLUDE_DIR, where to find the headers
#
# $ALUTDIR is an environment variable that would
# correspond to the ./configure --prefix=$ALUTDIR
# used in building ALUT.
#
# Created by James Turner. This was influenced by the FindOpenAL.cmake module.
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distributed this file outside of CMake, substitute the full
# License text for the above reference.)
# Per my request, CMake should search for frameworks first in
# the following order:
# ~/Library/Frameworks/OpenAL.framework/Headers
# /Library/Frameworks/OpenAL.framework/Headers
# /System/Library/Frameworks/OpenAL.framework/Headers
#
# On OS X, this will prefer the Framework version (if found) over others.
# People will have to manually change the cache values of
# OPENAL_LIBRARY to override this selection or set the CMake environment
# CMAKE_INCLUDE_PATH to modify the search paths.
FIND_LIBRARY(ALUT_LIBRARY
NAMES ALUT alut
HINTS
$ENV{ALUTDIR}
PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/opt
)
FIND_PATH(ALUT_INCLUDE_DIR
NAMES ALUT/alut.h alut.h
HINTS
$ENV{ALUTDIR}
PATH_SUFFIXES include/AL include
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/opt
)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ALUT DEFAULT_MSG ALUT_LIBRARY ALUT_INCLUDE_DIR)
MARK_AS_ADVANCED(ALUT_LIBRARY ALUT_INCLUDE_DIR)

View File

@@ -75,7 +75,7 @@ if(SIMGEAR_SHARED)
SimGearCore
${ZLIB_LIBRARY}
${OPENSCENEGRAPH_LIBRARIES}
${OPENAL_LIBRARY} ${ALUT_LIBRARY}
${OPENAL_LIBRARY}
${OPENGL_LIBRARY}
${JPEG_LIBRARY})

View File

@@ -63,6 +63,8 @@
#include <simgear/structure/exception.hxx>
#include <simgear/threads/SGThread.hxx>
using std::string;
namespace {
class Resolver : public SGThread

View File

@@ -84,6 +84,9 @@ inline bool sgIsBigEndian() {
return (*((char *) &sgEndianTest ) == 0);
}
inline void sgEndianSwap(int32_t *x) { *x = (int32_t) sg_bswap_32((int32_t) *x); }
inline void sgEndianSwap(float *x) { *x = (float) sg_bswap_32((float) *x); }
inline void sgEndianSwap(uint16_t *x) { *x = sg_bswap_16(*x); }
inline void sgEndianSwap(uint32_t *x) { *x = sg_bswap_32(*x); }
inline void sgEndianSwap(uint64_t *x) { *x = sg_bswap_64(*x); }

View File

@@ -8,6 +8,8 @@
#include "EffectBuilder.hxx"
#include "Effect.hxx"
using std::string;
namespace simgear
{

View File

@@ -167,7 +167,7 @@ EffectPropertyMap<T>::EffectPropertyMap(const EffectNameValue<T> (&attrs)[N])
template<typename T>
struct SimplePropertyMap
{
typedef std::map<string, T> map_type;
typedef std::map<std::string, T> map_type;
map_type _map;
template<int N>
SimplePropertyMap(const EffectNameValue<T> (&attrs)[N])
@@ -197,8 +197,8 @@ void findAttr(const effect::EffectPropertyMap<T>& pMap,
typename EffectPropertyMap<T>::BMap::iterator itr
= pMap._map.template get<from>().find(name);
if (itr == pMap._map.end()) {
throw effect::BuilderException(string("findAttr: could not find attribute ")
+ string(name));
throw effect::BuilderException(std::string("findAttr: could not find attribute ")
+ std::string(name));
} else {
result = itr->second;
}
@@ -373,7 +373,7 @@ public:
template<typename T>
struct InstallAttributeBuilder
{
InstallAttributeBuilder(const string& name)
InstallAttributeBuilder(const std::string& name)
{
PassAttributeBuilder::PassAttrMapSingleton::instance()
->passAttrMap.insert(make_pair(name, new T));

View File

@@ -6,6 +6,7 @@ set(HEADERS
sample_queue.hxx
soundmgr_openal.hxx
xmlsound.hxx
readwav.hxx
)
set(SOURCES
@@ -14,6 +15,7 @@ set(SOURCES
sample_queue.cxx
soundmgr_openal.cxx
xmlsound.cxx
readwav.cxx
)
simgear_scene_component(sound sound "${SOURCES}" "${HEADERS}")
@@ -27,7 +29,7 @@ else()
sgsound sgio sgmath sgstructure sgthreads sgtiming sgmisc sgdebug
${CMAKE_THREAD_LIBS_INIT}
${RT_LIBRARY}
${ALUT_LIBRARY} ${OPENAL_LIBRARY})
${OPENAL_LIBRARY})
endif()
function(create_test TEST_NAME)

View File

@@ -12,20 +12,19 @@
# define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION
# include <OpenAL/al.h>
# include <OpenAL/alc.h>
# include <ALUT/alut.h>
#elif defined(OPENALSDK)
# include <al.h>
# include <alc.h>
# include <AL/alut.h>
#else
# include <AL/al.h>
# include <AL/alc.h>
# include <AL/alut.h>
#endif
#define AUDIOFILE SRC_DIR"/jet.wav"
#include <simgear/sound/readwav.hxx>
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx>
static void print_openal_error( ALuint error ) {
if ( error == AL_INVALID_NAME ) {
@@ -44,22 +43,24 @@ static void print_openal_error( ALuint error ) {
}
int main( int argc, char *argv[] ) {
// initialize OpenAL
ALCdevice *dev;
ALCcontext *context;
alutInit(&argc, argv);
int main( int argc, char *argv[] )
{
sglog().setLogLevels( SG_ALL, SG_ALERT );
// initialize OpenAL
if ( (dev = alcOpenDevice( NULL )) != NULL
&& ( context = alcCreateContext( dev, NULL )) != NULL ) {
alcMakeContextCurrent( context );
} else {
context = 0;
SG_LOG( SG_GENERAL, SG_ALERT, "Audio initialization failed!" );
ALCdevice *dev = alcOpenDevice(NULL);
if (!dev) {
SG_LOG( SG_GENERAL, SG_ALERT, "Audio device initialization failed!" );
return EXIT_FAILURE;
}
ALCcontext *context = alcCreateContext(dev, NULL);
if (!context) {
SG_LOG( SG_GENERAL, SG_ALERT, "Audio context initialization failed!" );
return EXIT_FAILURE;
}
alcMakeContextCurrent( context );
// Position of the listener.
ALfloat listener_pos[3];
@@ -108,50 +109,15 @@ int main( int argc, char *argv[] ) {
source_pos[0] = 0.0; source_pos[1] = 0.0; source_pos[2] = 0.0;
source_vel[0] = 0.0; source_vel[1] = 0.0; source_vel[2] = 0.0;
// create an OpenAL buffer handle
alGenBuffers(1, &buffer);
ALuint error = alGetError();
if ( error != AL_NO_ERROR ) {
print_openal_error( error );
SG_LOG( SG_GENERAL, SG_ALERT, "Failed to gen OpenAL buffer." );
} else {
SG_LOG( SG_GENERAL, SG_ALERT, "Buffer created ok!" );
}
// Load the sample file
#if defined(ALUT_API_MAJOR_VERSION) && ALUT_API_MAJOR_VERSION >= 1
buffer = alutCreateBufferFromFile(AUDIOFILE);
if (buffer == AL_NONE) {
SG_LOG( SG_GENERAL, SG_ALERT, "Failed to buffer data.");
}
#else
ALenum format;
ALsizei size;
ALvoid* data;
ALsizei freq;
# if defined (__APPLE__)
alutLoadWAVFile( (ALbyte *)AUDIOFILE, &format, &data, &size, &freq );
# else
alutLoadWAVFile( (ALbyte *)AUDIOFILE, &format, &data, &size, &freq, &loop );
# endif
if (alGetError() != AL_NO_ERROR) {
SG_LOG( SG_GENERAL, SG_ALERT, "Failed to load wav file.");
}
// Copy data to the internal OpenAL buffer
alBufferData( buffer, format, data, size, freq );
if (alGetError() != AL_NO_ERROR) {
buffer = simgear::createBufferFromFile(SGPath(AUDIOFILE));
if (buffer == AL_NONE) {
SG_LOG( SG_GENERAL, SG_ALERT, "Failed to buffer data.");
}
alutUnloadWAV( format, data, size, freq );
#endif
}
alGenSources(1, &source);
if (alGetError() != AL_NO_ERROR) {
ALuint error = alGetError();
print_openal_error( error );
}
@@ -165,7 +131,10 @@ int main( int argc, char *argv[] ) {
alSourcePlay( source );
sleep(10);
alutExit();
alcMakeContextCurrent(NULL);
alcDestroyContext(context);
alcCloseDevice(dev);
return 0;
}

310
simgear/sound/readwav.cxx Normal file
View File

@@ -0,0 +1,310 @@
// Copyright (C) 2012 James Turner - zakalawe@mac.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// adapted from the freealut sources, especially alutBufferData.c, alutLoader.c
// and alutCodec.c (freealut is also LGPL licensed)
#include "readwav.hxx"
#include <cassert>
#include <zlib.h> // for gzXXX functions
#include <simgear/misc/sg_path.hxx>
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/stdint.hxx>
#include <simgear/structure/exception.hxx>
namespace
{
class Buffer {
public:
ALvoid* data;
ALenum format;
ALsizei length;
ALfloat frequency;
SGPath path;
Buffer() : data(NULL), format(AL_NONE), length(0), frequency(0.0f) {}
~Buffer()
{
if (data) {
free(data);
}
}
};
ALenum formatConstruct(ALint numChannels, ALint bitsPerSample)
{
switch (numChannels)
{
case 1:
switch (bitsPerSample) {
case 8: return AL_FORMAT_MONO8;
case 16: return AL_FORMAT_MONO16;
}
break;
case 2:
switch (bitsPerSample) {
case 8: return AL_FORMAT_STEREO8;
case 16: return AL_FORMAT_STEREO16;
}
break;
}
return AL_NONE;
}
// function prototype for decoding audio data
typedef void Codec(Buffer* buf);
void codecLinear(Buffer* /*buf*/)
{
}
void codecPCM16 (Buffer* buf)
{
// always byte-swaps here; is this a good idea?
uint16_t *d = (uint16_t *) buf->data;
size_t i, l = buf->length / 2;
for (i = 0; i < l; i++) {
*d = sg_bswap_16(*d);
}
}
/*
* From: http://www.multimedia.cx/simpleaudio.html#tth_sEc6.1
*/
int16_t mulaw2linear (uint8_t mulawbyte)
{
static const int16_t exp_lut[8] = {
0, 132, 396, 924, 1980, 4092, 8316, 16764
};
int16_t sign, exponent, mantissa, sample;
mulawbyte = ~mulawbyte;
sign = (mulawbyte & 0x80);
exponent = (mulawbyte >> 4) & 0x07;
mantissa = mulawbyte & 0x0F;
sample = exp_lut[exponent] + (mantissa << (exponent + 3));
return sign ? -sample : sample;
}
void codecULaw (Buffer* b)
{
uint8_t *d = (uint8_t *) b->data;
size_t newLength = b->length * 2;
int16_t *buf = (int16_t *) malloc(newLength);
size_t i;
if (buf == NULL)
throw sg_exception("malloc failed decoing ULaw WAV file");
for (i = 0; i < b->length; i++) {
buf[i] = mulaw2linear(d[i]);
}
free(b->data);
b->data = buf;
b->length = newLength;
}
bool gzSkip(gzFile fd, int skipCount)
{
int r = gzseek(fd, skipCount, SEEK_CUR);
return (r >= 0);
}
const int32_t WAV_RIFF_4CC = 0x52494646; // 'RIFF'
const int32_t WAV_WAVE_4CC = 0x57415645; // 'WAVE'
const int32_t WAV_DATA_4CC = 0x64617461; // 'data'
const int32_t WAV_FORMAT_4CC = 0x666d7420; // 'fmt '
template<class T>
bool wavReadBE(gzFile fd, T& value)
{
if (gzread(fd, &value, sizeof(T)) != sizeof(T))
return false;
if (sgIsLittleEndian())
sgEndianSwap(&value);
return true;
}
template<class T>
bool wavReadLE(gzFile fd, T& value)
{
if (gzread(fd, &value, sizeof(T)) != sizeof(T))
return false;
if (sgIsBigEndian())
sgEndianSwap(&value);
return true;
}
void loadWavFile(gzFile fd, Buffer* b)
{
assert(b->data == NULL);
bool found_header = false;
uint32_t chunkLength;
int32_t magic;
uint16_t audioFormat;
uint16_t numChannels;
uint32_t samplesPerSecond;
uint32_t byteRate;
uint16_t blockAlign;
uint16_t bitsPerSample;
Codec *codec = codecLinear;
if (!wavReadBE(fd, magic))
throw sg_io_exception("corrupt or truncated WAV data", b->path);
if (magic != WAV_RIFF_4CC) {
throw sg_io_exception("not a .wav file", b->path);
}
if (!wavReadLE(fd, chunkLength) || !wavReadBE(fd, magic))
throw sg_io_exception("corrupt or truncated WAV data", b->path);
if (magic != WAV_WAVE_4CC) /* "WAVE" */
{
throw sg_io_exception("unrecognized WAV magic", b->path);
}
while (1) {
if (!wavReadBE(fd, magic) || !wavReadLE(fd, chunkLength))
throw sg_io_exception("corrupt or truncated WAV data", b->path);
if (magic == WAV_FORMAT_4CC) /* "fmt " */
{
found_header = true;
if (chunkLength < 16) {
throw sg_io_exception("corrupt or truncated WAV data", b->path);
}
if (!wavReadLE (fd, audioFormat) ||
!wavReadLE (fd, numChannels) ||
!wavReadLE (fd, samplesPerSecond) ||
!wavReadLE (fd, byteRate) ||
!wavReadLE (fd, blockAlign) ||
!wavReadLE (fd, bitsPerSample))
{
throw sg_io_exception("corrupt or truncated WAV data", b->path);
}
if (!gzSkip(fd, chunkLength - 16))
throw sg_io_exception("corrupt or truncated WAV data", b->path);
switch (audioFormat)
{
case 1: /* PCM */
codec = (bitsPerSample == 8 || sgIsLittleEndian()) ? codecLinear : codecPCM16;
break;
case 7: /* uLaw */
bitsPerSample *= 2; /* ToDo: ??? */
codec = codecULaw;
break;
default:
throw sg_io_exception("unsupported WAV encoding", b->path);
}
b->frequency = samplesPerSecond;
b->format = formatConstruct(numChannels, bitsPerSample);
} else if (magic == WAV_DATA_4CC) {
if (!found_header) {
/* ToDo: A bit wrong to check here, fmt chunk could come later... */
throw sg_io_exception("corrupt or truncated WAV data", b->path);
}
b->data = malloc(chunkLength);
b->length = chunkLength;
size_t read = gzread(fd, b->data, chunkLength);
if (read != chunkLength) {
throw sg_io_exception("insufficent data reading WAV file", b->path);
}
break;
} else {
if (!gzSkip(fd, chunkLength))
throw sg_io_exception("corrupt or truncated WAV data", b->path);
}
if ((chunkLength & 1) && !gzeof(fd) && !gzSkip(fd, 1))
throw sg_io_exception("corrupt or truncated WAV data", b->path);
} // of file chunk parser loop
codec(b); // might throw if something really bad occurs
} // of loadWav function
} // of anonymous namespace
namespace simgear
{
ALvoid* loadWAVFromFile(const SGPath& path, ALenum& format, ALsizei& size, ALfloat& freqf)
{
if (!path.exists()) {
throw sg_io_exception("loadWAVFromFile: file not found", path);
}
Buffer b;
b.path = path;
gzFile fd;
fd = gzopen(path.c_str(), "rb");
if (!fd) {
throw sg_io_exception("loadWAVFromFile: unable to open file", path);
}
loadWavFile(fd, &b);
ALvoid* data = b.data;
b.data = NULL; // don't free when Buffer does out of scope
format = b.format;
size = b.length;
freqf = b.frequency;
gzclose(fd);
return data;
}
ALuint createBufferFromFile(const SGPath& path)
{
ALenum format;
ALsizei size;
ALfloat sampleFrequency;
ALvoid* data = loadWAVFromFile(path, format, size, sampleFrequency);
assert(data);
ALuint buffer;
alGenBuffers(1, &buffer);
if (alGetError() != AL_NO_ERROR) {
free(data);
throw sg_io_exception("OpenAL buffer allocation failed", sg_location(path.str()));
}
alBufferData (buffer, format, data, size, (ALsizei) sampleFrequency);
if (alGetError() != AL_NO_ERROR) {
alDeleteBuffers(1, &buffer);
free(data);
throw sg_io_exception("OpenAL setting buffer data failed", sg_location(path.str()));
}
return buffer;
}
} // of namespace simgear

24
simgear/sound/readwav.hxx Normal file
View File

@@ -0,0 +1,24 @@
#ifndef SG_SOUND_READWAV_HXX
#define SG_SOUND_READWAV_HXX
#if defined( __APPLE__ )
# include <OpenAL/al.h>
#elif defined(OPENALSDK)
# include <al.h>
#else
# include <AL/al.h>
#endif
// forward decls
class SGPath;
namespace simgear
{
ALvoid* loadWAVFromFile(const SGPath& path, ALenum& format, ALsizei& size, ALfloat& freqf);
ALuint createBufferFromFile(const SGPath& path);
}
#endif // of SG_SOUND_READWAV_HXX

View File

@@ -513,7 +513,7 @@ private:
bool _out_of_range;
bool _is_file;
string random_string();
std::string random_string();
};

View File

@@ -148,7 +148,7 @@ private:
bool _playing;
bool _changed;
string random_string();
std::string random_string();
};

View File

@@ -29,17 +29,12 @@
# include <simgear_config.h>
#endif
#if defined( __APPLE__ )
# include <ALUT/alut.h>
#else
# include <AL/alut.h>
#endif
#include <iostream>
#include <algorithm>
#include <cstring>
#include "soundmgr_openal.hxx"
#include "readwav.hxx"
#include <simgear/structure/exception.hxx>
#include <simgear/debug/logstream.hxx>
@@ -61,8 +56,6 @@ extern bool isNaN(float *v);
// Sound Manager
//
int SGSoundMgr::_alut_init = 0;
// constructor
SGSoundMgr::SGSoundMgr() :
_working(false),
@@ -81,17 +74,6 @@ SGSoundMgr::SGSoundMgr() :
_renderer("unknown"),
_vendor("unknown")
{
#if defined(ALUT_API_MAJOR_VERSION) && ALUT_API_MAJOR_VERSION >= 1
if (_alut_init == 0) {
if ( !alutInitWithoutContext(NULL, NULL) ) {
testForALUTError("alut initialization");
return;
}
}
_alut_init++;
#else
//#error ALUT 1.1 required, ALUT 1.0 is no longer supported, please upgrade
#endif
}
// destructor
@@ -99,12 +81,6 @@ SGSoundMgr::SGSoundMgr() :
SGSoundMgr::~SGSoundMgr() {
stop();
#if defined(ALUT_API_MAJOR_VERSION) && ALUT_API_MAJOR_VERSION >= 1
_alut_init--;
if (_alut_init == 0) {
alutExit ();
}
#endif
}
// initialize the sound manager
@@ -564,7 +540,7 @@ void SGSoundMgr::update_pos_and_orientation() {
_absolute_pos = _base_pos;
}
bool SGSoundMgr::load(string &samplepath, void **dbuf, int *fmt,
bool SGSoundMgr::load(const string &samplepath, void **dbuf, int *fmt,
size_t *sz, int *frq )
{
if ( !_working ) return false;
@@ -574,49 +550,16 @@ bool SGSoundMgr::load(string &samplepath, void **dbuf, int *fmt,
ALsizei freq;
ALvoid *data;
#if defined(ALUT_API_MAJOR_VERSION) && ALUT_API_MAJOR_VERSION >= 1
ALfloat freqf;
// ignore previous errors to prevent the system from halting on silly errors
alGetError();
alcGetError(_device);
data = alutLoadMemoryFromFile(samplepath.c_str(), &format, &size, &freqf );
data = simgear::loadWAVFromFile(samplepath, format, size, freqf );
freq = (ALsizei)freqf;
int error = alutGetError();
if (data == NULL || error != ALUT_ERROR_NO_ERROR) {
string msg = "Failed to load wav file: ";
msg.append(alutGetErrorString(error));
throw sg_io_exception(msg.c_str(), sg_location(samplepath));
return false;
if (data == NULL) {
throw sg_io_exception("Failed to load wav file", sg_location(samplepath));
}
#else
ALbyte *fname = (ALbyte *)samplepath.c_str();
# if defined (__APPLE__)
alutLoadWAVFile( fname, &format, &data, &size, &freq );
# else
ALboolean loop;
alutLoadWAVFile( fname, &format, &data, &size, &freq, &loop );
# endif
ALenum error = alGetError();
if ( error != AL_NO_ERROR ) {
string msg = "Failed to load wav file: ";
const ALchar *errorString = alGetString(error);
if (errorString) {
msg.append(errorString);
} else {
// alGetString returns NULL when an unexpected or OS specific error
// occurs: e.g. -43 on Mac when file is not found.
// In this case, alGetString() sets 'Invalid Enum' error, so
// showing with the original error number is helpful.
std::stringstream ss;
ss << alGetString(alGetError()) << "(" << error << ")";
msg.append(ss.str());
}
throw sg_io_exception(msg.c_str(), sg_location(samplepath));
return false;
}
#endif
if (format == AL_FORMAT_STEREO8 || format == AL_FORMAT_STEREO16) {
free(data);
throw sg_io_exception("Warning: STEREO files are not supported for 3D audio effects: " + samplepath);
@@ -690,18 +633,3 @@ bool SGSoundMgr::testForALCError(string s)
}
return false;
}
bool SGSoundMgr::testForALUTError(string s)
{
#if defined(ALUT_API_MAJOR_VERSION) && ALUT_API_MAJOR_VERSION >= 1
ALenum error;
error = alutGetError ();
if (error != ALUT_ERROR_NO_ERROR) {
SG_LOG( SG_SOUND, SG_ALERT, "ALUT Error (sound manager): "
<< alutGetErrorString(error) << " at "
<< s);
return true;
}
#endif
return false;
}

View File

@@ -266,7 +266,7 @@ public:
* @param freq Pointer to a vairable that gets the sample frequency in Herz
* @return true if succesful, false on error
*/
bool load(string &samplepath, void **data, int *format,
bool load(const string &samplepath, void **data, int *format,
size_t *size, int *freq );
/**
@@ -281,7 +281,6 @@ public:
const std::string& get_renderer() { return _renderer; }
private:
static int _alut_init;
bool _working;
bool _active;
@@ -317,7 +316,6 @@ private:
bool testForALError(std::string s);
bool testForALCError(std::string s);
bool testForALUTError(std::string s);
bool testForError(void *p, std::string s);
void update_pos_and_orientation();

View File

@@ -6,10 +6,13 @@
#include "exception.hxx"
#include <stdio.h>
#include <cstring>
#include <sstream>
#include <simgear/misc/sg_path.hxx>
using std::string;
////////////////////////////////////////////////////////////////////////
@@ -24,7 +27,7 @@ sg_location::sg_location ()
_path[0] = '\0';
}
sg_location::sg_location (const string& path, int line, int column)
sg_location::sg_location (const std::string& path, int line, int column)
: _line(line),
_column(column),
_byte(-1)
@@ -97,7 +100,7 @@ sg_location::setByte (int byte)
_byte = byte;
}
string
std::string
sg_location::asString () const
{
std::ostringstream out;
@@ -268,6 +271,12 @@ sg_io_exception::sg_io_exception (const string& message,
{
}
sg_io_exception::sg_io_exception (const string &message, const SGPath& origin)
: sg_exception(message, origin.str())
{
}
sg_io_exception::~sg_io_exception () throw ()
{
}

View File

@@ -14,7 +14,7 @@
#include <simgear/compiler.h>
#include <string>
using std::string;
class SGPath;
/**
* Information encapsulating a single location in an external resource
@@ -135,7 +135,8 @@ public:
sg_io_exception (const std::string &message, const std::string &origin = "");
sg_io_exception (const std::string &message, const sg_location &location,
const std::string &origin = "");
sg_io_exception (const std::string &message, const SGPath& origin);
virtual ~sg_io_exception () throw ();
virtual const std::string getFormattedMessage () const;
virtual const sg_location &getLocation () const;

View File

@@ -33,6 +33,8 @@
const int SG_MAX_SUBSYSTEM_EXCEPTIONS = 4;
using std::string;
////////////////////////////////////////////////////////////////////////
// Implementation of SGSubsystem
////////////////////////////////////////////////////////////////////////

View File

@@ -136,7 +136,7 @@ SGTimeZoneContainer::SGTimeZoneContainer(const char *filename)
char buffer[256];
FILE* infile = fopen(filename, "rb");
if (!(infile)) {
string e = "Unable to open time zone file '";
std::string e = "Unable to open time zone file '";
throw sg_exception(e + filename + '\'');
}