fix cr/lfs and remove trailing whitespaces...
[supertux.git] / src / audio / sound_file.cpp
index 0012661..48c2e9e 100644 (file)
@@ -1,3 +1,22 @@
+//  $Id$
+//
+//  SuperTux
+//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program 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 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
 /** Used SDL_mixer and glest source as reference */
 #include <config.h>
 
@@ -12,6 +31,7 @@
 #include <physfs.h>
 #include <vorbis/codec.h>
 #include <vorbis/vorbisfile.h>
+#include "log.hpp"
 
 class WavSoundFile : public SoundFile
 {
@@ -24,7 +44,7 @@ public:
 
 private:
   PHYSFS_file* file;
-  
+
   PHYSFS_sint64 datastart;
 };
 
@@ -54,13 +74,13 @@ WavSoundFile::WavSoundFile(PHYSFS_file* file)
   if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1)
     throw std::runtime_error("Couldn't read file magic (not a wave file)");
   if(strncmp(magic, "RIFF", 4) != 0) {
-    printf("MAGIC: %4s.\n", magic);
+    log_debug << "MAGIC: " << magic << std::endl;
     throw std::runtime_error("file is not a RIFF wav file");
   }
 
   uint32_t wavelen = read32LE(file);
   (void) wavelen;
-  
+
   if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1)
     throw std::runtime_error("Couldn't read chunk header (not a wav file?)");
   if(strncmp(magic, "WAVE", 4) != 0)
@@ -72,9 +92,9 @@ WavSoundFile::WavSoundFile(PHYSFS_file* file)
   // search audio data format chunk
   do {
     if(PHYSFS_read(file, chunkmagic, sizeof(chunkmagic), 1) != 1)
-      throw std::runtime_error("EOF while searching format chunk");    
+      throw std::runtime_error("EOF while searching format chunk");
     chunklen = read32LE(file);
-    
+
     if(strncmp(chunkmagic, "fmt ", 4) == 0)
       break;
 
@@ -86,11 +106,11 @@ WavSoundFile::WavSoundFile(PHYSFS_file* file)
     } else {
       throw std::runtime_error("complex WAVE files not supported");
     }
-  } while(true); 
+  } while(true);
 
   if(chunklen < 16)
     throw std::runtime_error("Format chunk too short");
+
   // parse format
   uint16_t encoding = read16LE(file);
   if(encoding != 1)
@@ -111,7 +131,7 @@ WavSoundFile::WavSoundFile(PHYSFS_file* file)
   // set file offset to DATA chunk data
   do {
     if(PHYSFS_read(file, chunkmagic, sizeof(chunkmagic), 1) != 1)
-      throw std::runtime_error("EOF while searching data chunk");    
+      throw std::runtime_error("EOF while searching data chunk");
     chunklen = read32LE(file);
 
     if(strncmp(chunkmagic, "data", 4) == 0)
@@ -145,11 +165,28 @@ WavSoundFile::read(void* buffer, size_t buffer_size)
   PHYSFS_sint64 cur = PHYSFS_tell(file);
   if(cur >= end)
     return 0;
-  
+
   size_t readsize = std::min(static_cast<size_t> (end - cur), buffer_size);
   if(PHYSFS_read(file, buffer, readsize, 1) != 1)
     throw std::runtime_error("read error while reading samples");
 
+#ifdef WORDS_BIGENDIAN
+  if (bits_per_sample != 16)
+    return readsize;
+  char *tmp = (char*)buffer;
+
+  size_t i;
+  char c;
+  for (i = 0; i < readsize / 2; i++)
+  {
+    c          = tmp[2*i];
+    tmp[2*i]   = tmp[2*i+1];
+    tmp[2*i+1] = c;
+  }
+
+  buffer = tmp;
+#endif
+
   return readsize;
 }
 
@@ -169,7 +206,7 @@ private:
   static int cb_seek(void* source, ogg_int64_t offset, int whence);
   static int cb_close(void* source);
   static long cb_tell(void* source);
-  
+
   PHYSFS_file* file;
   OggVorbis_File vorbis_file;
 };
@@ -201,9 +238,14 @@ OggSoundFile::read(void* _buffer, size_t buffer_size)
   size_t totalBytesRead= 0;
 
   while(buffer_size>0){
-    long bytesRead 
-      = ov_read(&vorbis_file, buffer, static_cast<int> (buffer_size), 0, 2, 1,
-          &section);
+    long bytesRead
+      = ov_read(&vorbis_file, buffer, static_cast<int> (buffer_size),
+#ifdef WORDS_BIGENDIAN
+1,
+#else
+0,
+#endif
+          2, 1, &section);
     if(bytesRead==0){
       break;
     }
@@ -211,7 +253,7 @@ OggSoundFile::read(void* _buffer, size_t buffer_size)
     buffer += bytesRead;
     totalBytesRead += bytesRead;
   }
-  
+
   return totalBytesRead;
 }
 
@@ -225,8 +267,8 @@ size_t
 OggSoundFile::cb_read(void* ptr, size_t size, size_t nmemb, void* source)
 {
   PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
-  
-  PHYSFS_sint64 res 
+
+  PHYSFS_sint64 res
     = PHYSFS_read(file, ptr, static_cast<PHYSFS_uint32> (size),
         static_cast<PHYSFS_uint32> (nmemb));
   if(res <= 0)
@@ -262,7 +304,7 @@ OggSoundFile::cb_seek(void* source, ogg_int64_t offset, int whence)
   }
   return 0;
 }
-  
+
 int
 OggSoundFile::cb_close(void* source)
 {
@@ -289,7 +331,7 @@ SoundFile* load_sound_file(const std::string& filename)
     msg << "Couldn't open '" << filename << "': " << PHYSFS_getLastError();
     throw std::runtime_error(msg.str());
   }
-    
+
   try {
     char magic[4];
     if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1)
@@ -307,4 +349,3 @@ SoundFile* load_sound_file(const std::string& filename)
     throw std::runtime_error(msg.str());
   }
 }
-