mirror of
https://github.com/luanti-org/luanti.git
synced 2025-12-23 15:05:29 +01:00
Split sound_openal_internal into serval files
This commit is contained in:
119
src/client/sound/sound_constants.h
Normal file
119
src/client/sound/sound_constants.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
Minetest
|
||||
Copyright (C) 2022 DS
|
||||
|
||||
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; ifnot, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
*
|
||||
* The coordinate space for sounds (sound-space):
|
||||
* ----------------------------------------------
|
||||
*
|
||||
* * The functions from ISoundManager (see sound.h) take spatial vectors in node-space.
|
||||
* * All other `v3f`s here are, if not told otherwise, in sound-space, which is
|
||||
* defined as node-space mirrored along the x-axis.
|
||||
* (This is needed because OpenAL uses a right-handed coordinate system.)
|
||||
* * Use `swap_handedness()` from `al_helpers.h` to convert between those two
|
||||
* coordinate spaces.
|
||||
*
|
||||
*
|
||||
* How sounds are loaded:
|
||||
* ----------------------
|
||||
*
|
||||
* * Step 1:
|
||||
* `loadSoundFile` or `loadSoundFile` is called. This adds an unopen sound with
|
||||
* the given name to `m_sound_datas_unopen`.
|
||||
* Unopen / lazy sounds (`ISoundDataUnopen`) are ogg-vorbis files that we did not yet
|
||||
* start to decode. (Decoding an unopen sound does not fail under normal circumstances
|
||||
* (because we check whether the file exists at least), if it does fail anyways,
|
||||
* we should notify the user.)
|
||||
* * Step 2:
|
||||
* `addSoundToGroup` is called, to add the name from step 1 to a group. If the
|
||||
* group does not yet exist, a new one is created. A group can later be played.
|
||||
* (The mapping is stored in `m_sound_groups`.)
|
||||
* * Step 3:
|
||||
* `playSound` or `playSoundAt` is called.
|
||||
* * Step 3.1:
|
||||
* If the group with the name `spec.name` does not exist, and `spec.use_local_fallback`
|
||||
* is true, a new group is created using the user's sound-pack.
|
||||
* * Step 3.2:
|
||||
* We choose one random sound name from the given group.
|
||||
* * Step 3.3:
|
||||
* We open the sound (see `openSingleSound`).
|
||||
* If the sound is already open (in `m_sound_datas_open`), we take that one.
|
||||
* Otherwise we open it by calling `ISoundDataUnopen::open`. We choose (by
|
||||
* sound length), whether it's a single-buffer (`SoundDataOpenBuffer`) or
|
||||
* streamed (`SoundDataOpenStream`) sound.
|
||||
* Single-buffer sounds are always completely loaded. Streamed sounds can be
|
||||
* partially loaded.
|
||||
* The sound is erased from `m_sound_datas_unopen` and added to `m_sound_datas_open`.
|
||||
* Open sounds are kept forever.
|
||||
* * Step 3.4:
|
||||
* We create the new `PlayingSound`. It has a `shared_ptr` to its open sound.
|
||||
* If the open sound is streaming, the playing sound needs to be stepped using
|
||||
* `PlayingSound::stepStream` for enqueuing buffers. For this purpose, the sound
|
||||
* is added to `m_sounds_streaming` (as `weak_ptr`).
|
||||
* If the sound is fading, it is added to `m_sounds_fading` for regular fade-stepping.
|
||||
* The sound is also added to `m_sounds_playing`, so that one can access it
|
||||
* via its sound handle.
|
||||
* * Step 4:
|
||||
* Streaming sounds are updated. For details see [Streaming of sounds].
|
||||
* * Step 5:
|
||||
* At deinitialization, we can just let the destructors do their work.
|
||||
* Sound sources are deleted (and with this also stopped) by ~PlayingSound.
|
||||
* Buffers can't be deleted while sound sources using them exist, because
|
||||
* PlayingSound has a shared_ptr to its ISoundData.
|
||||
*
|
||||
*
|
||||
* Streaming of sounds:
|
||||
* --------------------
|
||||
*
|
||||
* In each "bigstep", all streamed sounds are stepStream()ed. This means a
|
||||
* sound can be stepped at any point in time in the bigstep's interval.
|
||||
*
|
||||
* In the worst case, a sound is stepped at the start of one bigstep and in the
|
||||
* end of the next bigstep. So between two stepStream()-calls lie at most
|
||||
* 2 * STREAM_BIGSTEP_TIME seconds.
|
||||
* As there are always 2 sound buffers enqueued, at least one untouched full buffer
|
||||
* is still available after the first stepStream().
|
||||
* If we take a MIN_STREAM_BUFFER_LENGTH > 2 * STREAM_BIGSTEP_TIME, we can hence
|
||||
* not run into an empty queue.
|
||||
*
|
||||
* The MIN_STREAM_BUFFER_LENGTH needs to be a little bigger because of dtime jitter,
|
||||
* other sounds that may have taken long to stepStream(), and sounds being played
|
||||
* faster due to Doppler effect.
|
||||
*
|
||||
*/
|
||||
|
||||
// constants
|
||||
|
||||
// in seconds
|
||||
constexpr f32 REMOVE_DEAD_SOUNDS_INTERVAL = 2.0f;
|
||||
// maximum length in seconds that a sound can have without being streamed
|
||||
constexpr f32 SOUND_DURATION_MAX_SINGLE = 3.0f;
|
||||
// minimum time in seconds of a single buffer in a streamed sound
|
||||
constexpr f32 MIN_STREAM_BUFFER_LENGTH = 1.0f;
|
||||
// duration in seconds of one bigstep
|
||||
constexpr f32 STREAM_BIGSTEP_TIME = 0.3f;
|
||||
// step duration for the OpenALSoundManager thread, in seconds
|
||||
constexpr f32 SOUNDTHREAD_DTIME = 0.016f;
|
||||
|
||||
static_assert(MIN_STREAM_BUFFER_LENGTH > STREAM_BIGSTEP_TIME * 2.0f,
|
||||
"See [Streaming of sounds].");
|
||||
static_assert(SOUND_DURATION_MAX_SINGLE >= MIN_STREAM_BUFFER_LENGTH * 2.0f,
|
||||
"There's no benefit in streaming if we can't queue more than 2 buffers.");
|
||||
Reference in New Issue
Block a user