[colobot] 02/390: Implemented libsndfile loader in PhysFS

Didier Raboud odyx at moszumanska.debian.org
Fri Jun 12 14:21:20 UTC 2015


This is an automated email from the git hooks/post-receive script.

odyx pushed a commit to branch upstream/latest
in repository colobot.

commit 1630cf0ed20ea8df879327af1275ff281a9bc7e0
Author: Krzysztof Dermont <erihel at gmail.com>
Date:   Sat Jun 21 02:58:41 2014 +0200

    Implemented libsndfile loader in PhysFS
---
 src/CMakeLists.txt                                 |   1 +
 src/common/resources/resourcemanager.cpp           |  16 ++-
 src/common/resources/resourcemanager.h             |   3 +
 src/common/resources/sndfile.cpp                   | 130 +++++++++++++++++++++
 .../resources/{resourcemanager.h => sndfile.h}     |  42 ++++---
 src/sound/oalsound/alsound.h                       |  67 ++++++-----
 src/sound/oalsound/buffer.cpp                      |  33 +++---
 src/sound/sound.cpp                                |  10 +-
 8 files changed, 227 insertions(+), 75 deletions(-)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 114793d..db53398 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -77,6 +77,7 @@ common/stringutils.cpp
 common/resources/resourcemanager.cpp
 common/resources/resourcestreambuffer.cpp
 common/resources/inputstream.cpp
+common/resources/sndfile.cpp
 graphics/core/color.cpp
 graphics/engine/camera.cpp
 graphics/engine/cloud.cpp
diff --git a/src/common/resources/resourcemanager.cpp b/src/common/resources/resourcemanager.cpp
index ccef2a3..b01424b 100644
--- a/src/common/resources/resourcemanager.cpp
+++ b/src/common/resources/resourcemanager.cpp
@@ -124,7 +124,13 @@ SDL_RWops* CResourceManager::GetSDLFileHandler(const std::string &filename)
 }
 
 
-int CResourceManager::SDLClose(SDL_RWops* context)
+CSNDFile* CResourceManager::GetSNDFileHandler(const std::string &filename)
+{   
+    return new CSNDFile(filename);
+}
+
+
+int CResourceManager::SDLClose(SDL_RWops *context)
 {
     if (CheckSDLContext(context))
     {
@@ -138,7 +144,7 @@ int CResourceManager::SDLClose(SDL_RWops* context)
 }
 
 
-int CResourceManager::SDLRead(SDL_RWops* context, void* ptr, int size, int maxnum)
+int CResourceManager::SDLRead(SDL_RWops *context, void *ptr, int size, int maxnum)
 {
     if (CheckSDLContext(context))
     {
@@ -152,13 +158,13 @@ int CResourceManager::SDLRead(SDL_RWops* context, void* ptr, int size, int maxnu
 }
 
 
-int CResourceManager::SDLWrite(SDL_RWops* context, const void* ptr, int size, int num)
+int CResourceManager::SDLWrite(SDL_RWops *context, const void *ptr, int size, int num)
 {
     return 0;
 }
 
 
-int CResourceManager::SDLSeek(SDL_RWops* context, int offset, int whence)
+int CResourceManager::SDLSeek(SDL_RWops *context, int offset, int whence)
 {
     if (CheckSDLContext(context))
     {
@@ -188,7 +194,7 @@ int CResourceManager::SDLSeek(SDL_RWops* context, int offset, int whence)
 }
 
 
-bool CResourceManager::CheckSDLContext(SDL_RWops* context)
+bool CResourceManager::CheckSDLContext(SDL_RWops *context)
 {
     if (context->type != 0xc010b04f)
     {
diff --git a/src/common/resources/resourcemanager.h b/src/common/resources/resourcemanager.h
index ba11d73..fec71da 100644
--- a/src/common/resources/resourcemanager.h
+++ b/src/common/resources/resourcemanager.h
@@ -19,6 +19,8 @@
 #include <string>
 #include <SDL.h>
 
+#include "common/resources/sndfile.h"
+
 class CResourceManager
 {
 public:
@@ -30,6 +32,7 @@ public:
     static bool SetSaveLocation(const std::string &location);
     static std::string GetLanguageLocation();
     static SDL_RWops* GetSDLFileHandler(const std::string &filename);
+    static CSNDFile* GetSNDFileHandler(const std::string &filename);
 
 private:
     static int SDLSeek(SDL_RWops *context, int offset, int whence);
diff --git a/src/common/resources/sndfile.cpp b/src/common/resources/sndfile.cpp
new file mode 100644
index 0000000..9e8e729
--- /dev/null
+++ b/src/common/resources/sndfile.cpp
@@ -0,0 +1,130 @@
+// * This file is part of the COLOBOT source code
+// * Copyright (C) 2014 Polish Portal of Colobot (PPC)
+// *
+// * 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 3 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, see  http://www.gnu.org/licenses/.
+
+#include "common/resources/sndfile.h"
+
+#include <cstring>
+
+
+CSNDFile::CSNDFile(const std::string& filename)
+{
+    memset(&m_file_info, 0, sizeof(SF_INFO));
+
+    if (PHYSFS_isInit())
+    {
+        m_file = PHYSFS_openRead(filename.c_str());
+    }
+    else
+    {
+        m_last_error = "Resource system not started!";
+    }
+    
+    if (m_file)
+    {
+        m_snd_file = sf_open_virtual(&snd_callbacks, SFM_READ, &m_file_info, m_file);
+        if (!m_snd_file)
+        {
+            m_last_error = "Could not load file";
+        }
+    }
+    else
+    {
+        m_last_error = std::string(PHYSFS_getLastError());
+    }
+}
+
+
+CSNDFile::~CSNDFile()
+{
+    if (m_file)
+    {
+        PHYSFS_close(m_file);
+    }
+    
+    if (m_snd_file)
+    {
+        sf_close(m_snd_file);
+    }
+}
+
+
+bool CSNDFile::IsOpen()
+{
+    return m_snd_file;
+}
+
+
+SF_INFO &CSNDFile::GetFileInfo()
+{
+    return m_file_info;
+}
+
+
+std::string& CSNDFile::GetLastError()
+{
+    return m_last_error;
+}
+
+
+sf_count_t CSNDFile::Read(short int *ptr, sf_count_t items)
+{
+    return sf_read_short(m_snd_file, ptr, items);
+}
+
+
+sf_count_t CSNDFile::SNDLength(void *data)
+{
+    return PHYSFS_fileLength(static_cast<PHYSFS_File *>(data));
+}
+
+
+sf_count_t CSNDFile::SNDRead(void *ptr, sf_count_t count, void *data)
+{
+    return PHYSFS_read(static_cast<PHYSFS_File *>(data), ptr, 1, count);
+}
+
+
+sf_count_t CSNDFile::SNDSeek(sf_count_t offset, int whence, void *data)
+{
+    PHYSFS_File *file = static_cast<PHYSFS_File *>(data);
+    
+    switch(whence)
+    {
+        case SEEK_CUR:
+            PHYSFS_seek(file, PHYSFS_tell(file) + offset);
+            break;
+        case SEEK_SET:
+            PHYSFS_seek(file, offset);
+            break;
+        case SEEK_END:
+            PHYSFS_seek(file, PHYSFS_fileLength(file) + offset);
+            break;
+    }
+
+    return PHYSFS_tell(file);
+}
+
+
+sf_count_t CSNDFile::SNDTell(void *data)
+{
+    return PHYSFS_tell(static_cast<PHYSFS_File *>(data));
+}
+
+
+sf_count_t CSNDFile::SNDWrite(const void *ptr, sf_count_t count, void *data)
+{
+    return PHYSFS_write(static_cast<PHYSFS_File *>(data), ptr, 1, count);
+}
diff --git a/src/common/resources/resourcemanager.h b/src/common/resources/sndfile.h
similarity index 50%
copy from src/common/resources/resourcemanager.h
copy to src/common/resources/sndfile.h
index ba11d73..5ea6ccc 100644
--- a/src/common/resources/resourcemanager.h
+++ b/src/common/resources/sndfile.h
@@ -17,24 +17,38 @@
 #pragma once
 
 #include <string>
-#include <SDL.h>
+#include <physfs.h>
+#include <sndfile.h>
 
-class CResourceManager
+
+class CSNDFile
 {
 public:
-    CResourceManager(const char *argv0);
-    ~CResourceManager();
+    CSNDFile(const std::string &filename);
+    virtual ~CSNDFile();
 
-    static bool AddLocation(const std::string &location, bool prepend = true);
-    static bool RemoveLocation(const std::string &location);
-    static bool SetSaveLocation(const std::string &location);
-    static std::string GetLanguageLocation();
-    static SDL_RWops* GetSDLFileHandler(const std::string &filename);
+    SF_INFO &GetFileInfo();
+    bool IsOpen();
+    std::string &GetLastError();
+    sf_count_t Read(short int *ptr, sf_count_t items);
 
 private:
-    static int SDLSeek(SDL_RWops *context, int offset, int whence);
-    static int SDLRead(SDL_RWops *context, void *ptr, int size, int maxnum);
-    static int SDLWrite(SDL_RWops *context, const void *ptr, int size, int num);
-    static int SDLClose(SDL_RWops *context);
-    static bool CheckSDLContext(SDL_RWops *context);
+    static sf_count_t SNDLength(void *data);
+    static sf_count_t SNDSeek(sf_count_t offset, int whence, void *data);
+    static sf_count_t SNDRead(void *ptr, sf_count_t count, void *data);
+    static sf_count_t SNDWrite(const void *ptr, sf_count_t count, void *data);
+    static sf_count_t SNDTell(void *data);
+    
+    SF_INFO m_file_info;
+    SNDFILE *m_snd_file;
+    PHYSFS_File *m_file;
+    std::string m_last_error;
+
+    SF_VIRTUAL_IO snd_callbacks = {
+        SNDLength,
+        SNDSeek,
+        SNDRead,
+        SNDWrite,
+        SNDTell
+    };
 };
diff --git a/src/sound/oalsound/alsound.h b/src/sound/oalsound/alsound.h
index bb9bf28..1249f14 100644
--- a/src/sound/oalsound/alsound.h
+++ b/src/sound/oalsound/alsound.h
@@ -48,45 +48,44 @@ public:
     ALSound();
     ~ALSound();
 
-    bool Create();
-    bool Cache(Sound, const std::string &);
-    bool CacheMusic(const std::string &);
-
-    bool GetEnable();
-
-    void SetAudioVolume(int volume);
-    int GetAudioVolume();
-    void SetMusicVolume(int volume);
-    int GetMusicVolume();
-
-    void SetListener(const Math::Vector &eye, const Math::Vector &lookat);
-    void FrameMove(float rTime);
-
-    int Play(Sound sound, float amplitude=1.0f, float frequency=1.0f, bool bLoop = false);
-    int Play(Sound sound, const Math::Vector &pos, float amplitude=1.0f, float frequency=1.0f, bool bLoop = false);
-    bool FlushEnvelope(int channel);
-    bool AddEnvelope(int channel, float amplitude, float frequency, float time, SoundNext oper);
-    bool Position(int channel, const Math::Vector &pos);
-    bool Frequency(int channel, float frequency);
-    bool Stop(int channel);
-    bool StopAll();
-    bool MuteAll(bool bMute);
-
-    bool PlayMusic(int rank, bool bRepeat, float fadeTime=2.0f);
-    bool PlayMusic(const std::string &filename, bool bRepeat, float fadeTime=2.0f);
-    bool RestartMusic();
-    void SuspendMusic();
-    void StopMusic(float fadeTime=2.0f);
-    bool IsPlayingMusic();
-    bool PlayPauseMusic(const std::string &filename, bool repeat);
-    void StopPauseMusic();
-
-    bool CheckChannel(int &channel);
+    bool Create() override;
+    bool Cache(Sound, const std::string &) override;
+    bool CacheMusic(const std::string &) override;
+
+    bool GetEnable() override;
+
+    void SetAudioVolume(int volume) override;
+    int GetAudioVolume() override;
+    void SetMusicVolume(int volume) override;
+    int GetMusicVolume() override;
+
+    void SetListener(const Math::Vector &eye, const Math::Vector &lookat) override;
+    void FrameMove(float rTime) override;
+
+    int Play(Sound sound, float amplitude=1.0f, float frequency=1.0f, bool bLoop = false) override;
+    int Play(Sound sound, const Math::Vector &pos, float amplitude=1.0f, float frequency=1.0f, bool bLoop = false) override;
+    bool FlushEnvelope(int channel) override;
+    bool AddEnvelope(int channel, float amplitude, float frequency, float time, SoundNext oper) override;
+    bool Position(int channel, const Math::Vector &pos) override;
+    bool Frequency(int channel, float frequency) override;
+    bool Stop(int channel) override;
+    bool StopAll() override;
+    bool MuteAll(bool bMute) override;
+
+    bool PlayMusic(int rank, bool bRepeat, float fadeTime=2.0f) override;
+    bool PlayMusic(const std::string &filename, bool bRepeat, float fadeTime=2.0f) override;
+    bool RestartMusic() override;
+    void SuspendMusic() override;
+    void StopMusic(float fadeTime=2.0f) override;
+    bool IsPlayingMusic() override;
+    bool PlayPauseMusic(const std::string &filename, bool repeat) override;
+    void StopPauseMusic() override;
 
 private:
     void CleanUp();
     int GetPriority(Sound);
     bool SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded);
+    bool CheckChannel(int &channel);
 
     bool m_enabled;
     float m_audioVolume;
diff --git a/src/sound/oalsound/buffer.cpp b/src/sound/oalsound/buffer.cpp
index b27029c..d9441ad 100644
--- a/src/sound/oalsound/buffer.cpp
+++ b/src/sound/oalsound/buffer.cpp
@@ -17,7 +17,10 @@
 
 #include "sound/oalsound/buffer.h"
 
-#include <cstring>
+#include <memory>
+
+#include "common/resources/resourcemanager.h"
+
 
 Buffer::Buffer()
 {
@@ -42,19 +45,17 @@ bool Buffer::LoadFromFile(std::string filename, Sound sound)
     m_sound = sound;
     GetLogger()->Debug("Loading audio file: %s\n", filename.c_str());
 
-    SF_INFO fileInfo;
-    memset(&fileInfo, 0, sizeof(SF_INFO));
-    SNDFILE *file = sf_open(filename.c_str(), SFM_READ, &fileInfo);
+    std::unique_ptr<CSNDFile> file = std::unique_ptr<CSNDFile>(CResourceManager::GetSNDFileHandler(filename));
 
-    GetLogger()->Trace("  channels %d\n", fileInfo.channels);
-    GetLogger()->Trace("  format %d\n", fileInfo.format);
-    GetLogger()->Trace("  frames %d\n", fileInfo.frames);
-    GetLogger()->Trace("  samplerate %d\n", fileInfo.samplerate);
-    GetLogger()->Trace("  sections %d\n", fileInfo.sections);
+    GetLogger()->Trace("  channels %d\n", file->GetFileInfo().channels);
+    GetLogger()->Trace("  format %d\n", file->GetFileInfo().format);
+    GetLogger()->Trace("  frames %d\n", file->GetFileInfo().frames);
+    GetLogger()->Trace("  samplerate %d\n", file->GetFileInfo().samplerate);
+    GetLogger()->Trace("  sections %d\n", file->GetFileInfo().sections);
 
-    if (!file)
+    if (!file->IsOpen())
     {
-        GetLogger()->Warn("Could not load file. Reason: %s\n", sf_strerror(file));
+        GetLogger()->Warn("Could not load file. Reason: %s\n", file->GetLastError().c_str());
         m_loaded = false;
         return false;
     }
@@ -64,23 +65,21 @@ bool Buffer::LoadFromFile(std::string filename, Sound sound)
     {
         GetLogger()->Warn("Could not create audio buffer\n");
         m_loaded = false;
-        sf_close(file);
         return false;
     }
 
     // read chunks of 4096 samples
     std::vector<uint16_t> data;
     std::array<int16_t, 4096> buffer;
-    data.reserve(fileInfo.frames);
+    data.reserve(file->GetFileInfo().frames);
     size_t read = 0;
-    while ((read = sf_read_short(file, buffer.data(), buffer.size())) != 0)
+    while ((read = file->Read(buffer.data(), buffer.size())) != 0)
     {
         data.insert(data.end(), buffer.begin(), buffer.begin() + read);
     }
-    sf_close(file);
 
-    alBufferData(m_buffer, fileInfo.channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, &data.front(), data.size() * sizeof(uint16_t), fileInfo.samplerate);
-    m_duration = static_cast<float>(fileInfo.frames) / fileInfo.samplerate;
+    alBufferData(m_buffer, file->GetFileInfo().channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, &data.front(), data.size() * sizeof(uint16_t), file->GetFileInfo().samplerate);
+    m_duration = static_cast<float>(file->GetFileInfo().frames) / file->GetFileInfo().samplerate;
     m_loaded = true;
     return true;
 }
diff --git a/src/sound/sound.cpp b/src/sound/sound.cpp
index 9cae1fd..9c9f483 100644
--- a/src/sound/sound.cpp
+++ b/src/sound/sound.cpp
@@ -46,7 +46,7 @@ void CSoundInterface::CacheAll()
     for ( int i = 1; i < SOUND_MAX; i++ )
     {
         std::stringstream filename;
-        filename << "sound" << std::setfill('0') << std::setw(3) << i << ".wav";
+        filename << "sounds/sound" << std::setfill('0') << std::setw(3) << i << ".wav";
         if ( !Cache(static_cast<Sound>(i), filename.str()) )
             GetLogger()->Warn("Unable to load audio: %s\n", filename.str().c_str());
     }
@@ -54,10 +54,10 @@ void CSoundInterface::CacheAll()
 
 void CSoundInterface::AddMusicFiles()
 {
-    CacheMusic("Intro1.ogg");
-    CacheMusic("Intro2.ogg");
-    CacheMusic("music010.ogg");
-    CacheMusic("music011.ogg");
+    CacheMusic("music/Intro1.ogg");
+    CacheMusic("music/Intro2.ogg");
+    CacheMusic("music/music010.ogg");
+    CacheMusic("music/music011.ogg");
 }
 
 bool CSoundInterface::Cache(Sound bSound, const std::string &bFile)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/colobot.git



More information about the Pkg-games-commits mailing list