forked from Mirrorlandia_minetest/minetest
187 lines
6.1 KiB
C++
187 lines
6.1 KiB
C++
/*
|
|
Minetest
|
|
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser 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.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "irr_v3d.h"
|
|
#include <limits>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <unordered_set>
|
|
#include <vector>
|
|
|
|
struct SoundSpec;
|
|
|
|
class SoundFallbackPathProvider
|
|
{
|
|
public:
|
|
virtual ~SoundFallbackPathProvider() = default;
|
|
std::vector<std::string> getLocalFallbackPathsForSoundname(const std::string &name);
|
|
protected:
|
|
virtual void addThePaths(const std::string &name, std::vector<std::string> &paths);
|
|
// adds <common>.ogg, <common>.1.ogg, ..., <common>.9.ogg to paths
|
|
void addAllAlternatives(const std::string &common, std::vector<std::string> &paths);
|
|
private:
|
|
std::unordered_set<std::string> m_done_names;
|
|
};
|
|
|
|
|
|
/**
|
|
* IDs for playing sounds.
|
|
* 0 is for sounds that are never modified after creation.
|
|
* Negative numbers are invalid.
|
|
* Positive numbers are allocated via allocateId and are manually reference-counted.
|
|
*/
|
|
using sound_handle_t = int;
|
|
|
|
constexpr sound_handle_t SOUND_HANDLE_T_MAX = std::numeric_limits<sound_handle_t>::max();
|
|
|
|
class ISoundManager
|
|
{
|
|
private:
|
|
std::unordered_map<sound_handle_t, u32> m_occupied_ids;
|
|
sound_handle_t m_next_id = 1;
|
|
std::vector<sound_handle_t> m_removed_sounds;
|
|
|
|
protected:
|
|
void reportRemovedSound(sound_handle_t id);
|
|
|
|
public:
|
|
virtual ~ISoundManager() = default;
|
|
|
|
/**
|
|
* Removes finished sounds, steps streamed sounds, and does similar tasks.
|
|
* Should not be called while paused.
|
|
* @param dtime In seconds.
|
|
*/
|
|
virtual void step(f32 dtime) = 0;
|
|
/**
|
|
* Pause all sound playback.
|
|
*/
|
|
virtual void pauseAll() = 0;
|
|
/**
|
|
* Resume sound playback after pause.
|
|
*/
|
|
virtual void resumeAll() = 0;
|
|
|
|
/**
|
|
* @param pos In node-space.
|
|
* @param vel In node-space.
|
|
* @param at Vector in node-space pointing forwards.
|
|
* @param up Vector in node-space pointing upwards, orthogonal to `at`.
|
|
*/
|
|
virtual void updateListener(const v3f &pos, const v3f &vel, const v3f &at,
|
|
const v3f &up) = 0;
|
|
virtual void setListenerGain(f32 gain) = 0;
|
|
|
|
/**
|
|
* Adds a sound to load from a file (only OggVorbis).
|
|
* @param name The name of the sound. Must be unique, otherwise call fails.
|
|
* @param filepath The path for
|
|
* @return true on success, false on failure (ie. sound was already added or
|
|
* file does not exist).
|
|
*/
|
|
virtual bool loadSoundFile(const std::string &name, const std::string &filepath) = 0;
|
|
/**
|
|
* Same as `loadSoundFile`, but reads the OggVorbis file from memory.
|
|
*/
|
|
virtual bool loadSoundData(const std::string &name, std::string &&filedata) = 0;
|
|
/**
|
|
* Adds sound with name sound_name to group `group_name`. Creates the group
|
|
* if non-existent.
|
|
* @param sound_name The name of the sound, as used in `loadSoundData`.
|
|
* @param group_name The name of the sound group.
|
|
*/
|
|
virtual void addSoundToGroup(const std::string &sound_name,
|
|
const std::string &group_name) = 0;
|
|
|
|
/**
|
|
* Plays a random sound from a sound group (position-less).
|
|
* @param id Id for new sound. Move semantics apply if id > 0.
|
|
*/
|
|
virtual void playSound(sound_handle_t id, const SoundSpec &spec) = 0;
|
|
/**
|
|
* Same as `playSound`, but at a position.
|
|
* @param pos In node-space.
|
|
* @param vel In node-space.
|
|
*/
|
|
virtual void playSoundAt(sound_handle_t id, const SoundSpec &spec, const v3f &pos,
|
|
const v3f &vel) = 0;
|
|
/**
|
|
* Request the sound to be stopped.
|
|
* The id should be freed afterwards.
|
|
*/
|
|
virtual void stopSound(sound_handle_t sound) = 0;
|
|
virtual void fadeSound(sound_handle_t sound, f32 step, f32 target_gain) = 0;
|
|
/**
|
|
* Update position and velocity of positional sound.
|
|
* @param pos In node-space.
|
|
* @param vel In node-space.
|
|
*/
|
|
virtual void updateSoundPosVel(sound_handle_t sound, const v3f &pos,
|
|
const v3f &vel) = 0;
|
|
|
|
/**
|
|
* Get and reset the list of sounds that were stopped.
|
|
*/
|
|
std::vector<sound_handle_t> pollRemovedSounds()
|
|
{
|
|
std::vector<sound_handle_t> ret;
|
|
std::swap(m_removed_sounds, ret);
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* Returns a positive id.
|
|
* The id will be returned again until freeId is called.
|
|
* @param num_owners Owner-counter for id. Set this to 2, if you want to play
|
|
* a sound and store the id also otherwhere.
|
|
*/
|
|
sound_handle_t allocateId(u32 num_owners);
|
|
|
|
/**
|
|
* Free an id allocated via allocateId.
|
|
* @param num_owners How much the owner-counter should be decreased. Id can
|
|
* be reused when counter reaches 0.
|
|
*/
|
|
void freeId(sound_handle_t id, u32 num_owners = 1);
|
|
};
|
|
|
|
class DummySoundManager final : public ISoundManager
|
|
{
|
|
public:
|
|
void step(f32 dtime) override {}
|
|
void pauseAll() override {}
|
|
void resumeAll() override {}
|
|
|
|
void updateListener(const v3f &pos, const v3f &vel, const v3f &at, const v3f &up) override {}
|
|
void setListenerGain(f32 gain) override {}
|
|
|
|
bool loadSoundFile(const std::string &name, const std::string &filepath) override { return true; }
|
|
bool loadSoundData(const std::string &name, std::string &&filedata) override { return true; }
|
|
void addSoundToGroup(const std::string &sound_name, const std::string &group_name) override {};
|
|
|
|
void playSound(sound_handle_t id, const SoundSpec &spec) override { reportRemovedSound(id); }
|
|
void playSoundAt(sound_handle_t id, const SoundSpec &spec, const v3f &pos,
|
|
const v3f &vel) override { reportRemovedSound(id); }
|
|
void stopSound(sound_handle_t sound) override {}
|
|
void fadeSound(sound_handle_t sound, f32 step, f32 target_gain) override {}
|
|
void updateSoundPosVel(sound_handle_t sound, const v3f &pos, const v3f &vel) override {}
|
|
};
|