]> git.mxchange.org Git - simgear.git/commitdiff
Remove ALUT usage from SimGear .
authorJames Turner <zakalawe@mac.com>
Tue, 21 Aug 2012 12:18:45 +0000 (13:18 +0100)
committerJames Turner <zakalawe@mac.com>
Tue, 21 Aug 2012 12:24:35 +0000 (13:24 +0100)
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.

19 files changed:
CMakeLists.txt
CMakeModules/FindALUT.cmake [deleted file]
simgear/CMakeLists.txt
simgear/io/raw_socket.cxx
simgear/misc/stdint.hxx
simgear/scene/material/EffectBuilder.cxx
simgear/scene/material/EffectBuilder.hxx
simgear/sound/CMakeLists.txt
simgear/sound/openal_test1.cxx
simgear/sound/readwav.cxx [new file with mode: 0644]
simgear/sound/readwav.hxx [new file with mode: 0644]
simgear/sound/sample_openal.hxx
simgear/sound/sample_queue.hxx
simgear/sound/soundmgr_openal.cxx
simgear/sound/soundmgr_openal.hxx
simgear/structure/exception.cxx
simgear/structure/exception.hxx
simgear/structure/subsystem_mgr.cxx
simgear/timing/timezone.cxx

index 1f4db46f664f47bdda873b8d6044eda4df32e0d4..008d7a9a83e39042a6bfc7c17eb727a85973d28c 100644 (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)
diff --git a/CMakeModules/FindALUT.cmake b/CMakeModules/FindALUT.cmake
deleted file mode 100644 (file)
index 48e6e04..0000000
+++ /dev/null
@@ -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)
-
index 46a22b6571f7be7e24584ee9bde3aea5e8dd8b2a..1ab291e375d76249149c207327d89619f9da4a57 100644 (file)
@@ -75,7 +75,7 @@ if(SIMGEAR_SHARED)
             SimGearCore
             ${ZLIB_LIBRARY}
             ${OPENSCENEGRAPH_LIBRARIES}
-            ${OPENAL_LIBRARY} ${ALUT_LIBRARY}
+            ${OPENAL_LIBRARY}
             ${OPENGL_LIBRARY}
             ${JPEG_LIBRARY})
     
index d61d71f99204eeaa88bcd12a21bec86611c83c9e..d93d971653e15a8904d777f2bc1b7f5e3d1a27a1 100644 (file)
@@ -63,6 +63,8 @@
 #include <simgear/structure/exception.hxx>
 #include <simgear/threads/SGThread.hxx>
 
+using std::string;
+
 namespace {
 
 class Resolver : public SGThread
index f90734edc6eb6c49e61de814c9a425620fa0b5ce..94fbd60a50db759b6b3687e053cd03d20faa5440 100644 (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); }
index 7eb5580ff43fd98d3c45057b66f535f853759b18..446659426523bc0c08b9deaebcfdca047c2b7e06 100644 (file)
@@ -8,6 +8,8 @@
 #include "EffectBuilder.hxx"
 #include "Effect.hxx"
 
+using std::string;
+
 namespace simgear
 {
 
index 949b5f4e12fd8c9cb29e7f84b8fc3e5ef678254a..5624aaa2ba03a1ed6b8a4bd53d409cca1558d7ed 100644 (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));
index 6290f60fce0f654ffb5dfd7ced20062f33f4487a..18141118570f82a49e526a20e7efc3db50f83331 100644 (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)
index 0a6dc885a2961584d79977acc092d612d3f4ae03..60aba9f80211b3580a9b42a3abcab828268d7025 100644 (file)
 # 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;
 }
diff --git a/simgear/sound/readwav.cxx b/simgear/sound/readwav.cxx
new file mode 100644 (file)
index 0000000..54acda5
--- /dev/null
@@ -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
diff --git a/simgear/sound/readwav.hxx b/simgear/sound/readwav.hxx
new file mode 100644 (file)
index 0000000..5e0a4b2
--- /dev/null
@@ -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
index a32b8719c7d6fb6e38d5d41ed56563ba7c9af942..55ec41cb39055d41b464376082be3f497e451dbd 100644 (file)
@@ -513,7 +513,7 @@ private:
     bool _out_of_range;
     bool _is_file;
 
-    string random_string();
+    std::string random_string();
 };
 
 
index b2f961856f945f47d7db2863d14ad7650f2c0c90..dada5d1eb048915352e6b699da5a46a9584da384 100644 (file)
@@ -148,7 +148,7 @@ private:
     bool _playing;
     bool _changed;
 
-    string random_string();
+    std::string random_string();
 };
 
 
index 35d5b02e62a384c8dd4ea04b3f6ab3e351066fe0..385e918fcb1e3c3b99f25d70756747de40b22fd8 100644 (file)
 #  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,48 +550,15 @@ 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;
-    }
-
-#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;
+    if (data == NULL) {
+        throw sg_io_exception("Failed to load wav file", sg_location(samplepath));
     }
-#endif
 
     if (format == AL_FORMAT_STEREO8 || format == AL_FORMAT_STEREO16) {
         free(data);
@@ -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;
-}
index e34d62668940126f6edfbb0c8c4d6880ff876de9..34ca6427ac81e5d1c6ec97ca172f2402d69b655f 100644 (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();
index 0766eb4502f58b73cf8b4d9ab5e4954b03a02d56..082d12e4ef782558b15c4e7c76f602f36b5f17a0 100644 (file)
@@ -6,10 +6,13 @@
 
 
 #include "exception.hxx"
+
 #include <stdio.h>
 #include <cstring>
 #include <sstream>
 
+#include <simgear/misc/sg_path.hxx>
+
 using std::string;
 \f
 ////////////////////////////////////////////////////////////////////////
@@ -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 ()
 {
 }
index bfa978ee82dba26c884135ddaab87987f2d2fe0a..0feffd5bb30cd2ad8f2e39ae3d162fb9ac745966 100644 (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;
index df2c0ef38349bcc60f124a6b9869ae3da07e9574..4df51a6eee0cf88201b10101e3392a40049c0f30 100644 (file)
@@ -33,6 +33,8 @@
 
 const int SG_MAX_SUBSYSTEM_EXCEPTIONS = 4;
 
+using std::string;
+
 ////////////////////////////////////////////////////////////////////////
 // Implementation of SGSubsystem
 ////////////////////////////////////////////////////////////////////////
index 26174c7538f513d3c27333ee6bb1b0d7215bf3d6..4fa6746ca2cd742fc245a10bb440606d7207fd3c 100644 (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 + '\'');
     }