Skip to content

Commit

Permalink
Sound refactor and improvements (#12764)
Browse files Browse the repository at this point in the history
  • Loading branch information
Desour committed Jun 16, 2023
1 parent 8e1af25 commit edcbfa3
Show file tree
Hide file tree
Showing 52 changed files with 2,790 additions and 1,199 deletions.
2 changes: 2 additions & 0 deletions LICENSE.txt
Expand Up @@ -83,6 +83,8 @@ SmallJoker:
DS:
games/devtest/mods/soundstuff/textures/soundstuff_bigfoot.png
games/devtest/mods/soundstuff/textures/soundstuff_jukebox.png
games/devtest/mods/soundstuff/textures/soundstuff_racecar.png
games/devtest/mods/soundstuff/sounds/soundstuff_sinus.ogg
games/devtest/mods/testtools/textures/testtools_branding_iron.png

License of Minetest source code
Expand Down
11 changes: 11 additions & 0 deletions builtin/client/misc.lua
Expand Up @@ -5,3 +5,14 @@ function core.setting_get_pos(name)
end
return core.string_to_pos(value)
end


-- old non-method sound functions

function core.sound_stop(handle, ...)
return handle:stop(...)
end

function core.sound_fade(handle, ...)
return handle:fade(...)
end
2 changes: 2 additions & 0 deletions builtin/mainmenu/init.lua
Expand Up @@ -28,6 +28,8 @@ local basepath = core.get_builtin_path()
defaulttexturedir = core.get_texturepath_share() .. DIR_DELIM .. "base" ..
DIR_DELIM .. "pack" .. DIR_DELIM

dofile(menupath .. DIR_DELIM .. "misc.lua")

dofile(basepath .. "common" .. DIR_DELIM .. "filterlist.lua")
dofile(basepath .. "fstk" .. DIR_DELIM .. "buttonbar.lua")
dofile(basepath .. "fstk" .. DIR_DELIM .. "dialog.lua")
Expand Down
6 changes: 6 additions & 0 deletions builtin/mainmenu/misc.lua
@@ -0,0 +1,6 @@

-- old non-method sound function

function core.sound_stop(handle, ...)
return handle:stop(...)
end
4 changes: 2 additions & 2 deletions doc/client_lua_api.md
Expand Up @@ -754,9 +754,9 @@ Call these functions only at load time!
* `minetest.sound_play(spec, parameters)`: returns a handle
* `spec` is a `SimpleSoundSpec`
* `parameters` is a sound parameter table
* `minetest.sound_stop(handle)`
* `handle:stop()` or `minetest.sound_stop(handle)`
* `handle` is a handle returned by `minetest.sound_play`
* `minetest.sound_fade(handle, step, gain)`
* `handle:fade(step, gain)` or `minetest.sound_fade(handle, step, gain)`
* `handle` is a handle returned by `minetest.sound_play`
* `step` determines how fast a sound will fade.
Negative step will lower the sound volume, positive step will increase
Expand Down
165 changes: 115 additions & 50 deletions doc/lua_api.md
Expand Up @@ -994,16 +994,21 @@ Only Ogg Vorbis files are supported.
For positional playing of sounds, only single-channel (mono) files are
supported. Otherwise OpenAL will play them non-positionally.

Mods should generally prefix their sounds with `modname_`, e.g. given
Mods should generally prefix their sound files with `modname_`, e.g. given
the mod name "`foomod`", a sound could be called:

foomod_foosound.ogg

Sounds are referred to by their name with a dot, a single digit and the
file extension stripped out. When a sound is played, the actual sound file
is chosen randomly from the matching sounds.
Sound group
-----------

A sound group is the set of all sound files, whose filenames are of the following
format:
`<sound-group name>[.<single digit>].ogg`
When a sound-group is played, one the files in the group is chosen at random.
Sound files can only be referred to by their sound-group name.

When playing the sound `foomod_foosound`, the sound is chosen randomly
Example: When playing the sound `foomod_foosound`, the sound is chosen randomly
from the available ones of the following files:

* `foomod_foosound.ogg`
Expand All @@ -1012,20 +1017,111 @@ from the available ones of the following files:
* (...)
* `foomod_foosound.9.ogg`

Examples of sound parameter tables:
`SimpleSoundSpec`
-----------------

Specifies a sound name, gain (=volume), pitch and fade.
This is either a string or a table.

In string form, you just specify the sound name or
the empty string for no sound.

Table form has the following fields:

* `name`:
Sound-group name.
If == `""`, no sound is played.
* `gain`:
Volume (`1.0` = 100%), must be non-negative.
At the end, OpenAL clamps sound gain to a maximum of `1.0`. By setting gain for
a positional sound higher than `1.0`, one can increase the radius inside which
maximal gain is reached.
Furthermore, gain of positional sounds doesn't increase inside a 1 node radius.
The gain given here describes the gain at a distance of 3 nodes.
* `pitch`:
Applies a pitch-shift to the sound.
Each factor of `2.0` results in a pitch-shift of +12 semitones.
Must be positive.
* `fade`:
If > `0.0`, the sound is faded in, with this value in gain per second, until
`gain` is reached.

`gain`, `pitch` and `fade` are optional and default to `1.0`, `1.0` and `0.0`.

Examples:

* `""`: No sound
* `{}`: No sound
* `"default_place_node"`: Play e.g. `default_place_node.ogg`
* `{name = "default_place_node"}`: Same as above
* `{name = "default_place_node", gain = 0.5}`: 50% volume
* `{name = "default_place_node", gain = 0.9, pitch = 1.1}`: 90% volume, 110% pitch

Sound parameter table
---------------------

Table used to specify how a sound is played:

```lua
{
gain = 1.0,
-- Scales the gain specified in `SimpleSoundSpec`.

pitch = 1.0,
-- Overwrites the pitch specified in `SimpleSoundSpec`.

fade = 0.0,
-- Overwrites the fade specified in `SimpleSoundSpec`.

start_time = 0.0,
-- Start with a time-offset into the sound.
-- The behavior is as if the sound was already playing for this many seconds.
-- Negative values are relative to the sound's length, so the sound reaches
-- its end in `-start_time` seconds.
-- It is unspecified what happens if `loop` is false and `start_time` is
-- smaller than minus the sound's length.

loop = false,
-- If true, sound is played in a loop.

pos = {x = 1, y = 2, z = 3},
-- Play sound at a position.
-- Can't be used together with `object`.

object = <an ObjectRef>,
-- Attach the sound to an object.
-- Can't be used together with `pos`.

to_player = name,
-- Only play for this player.
-- Can't be used together with `exclude_player`.

exclude_player = name,
-- Don't play sound for this player.
-- Can't be used together with `to_player`.

max_hear_distance = 32,
-- Only play for players that are at most this far away when the sound
-- starts playing.
-- Needs `pos` or `object` to be set.
-- `32` is the default.
}
```

Examples:

```lua
-- Play locationless on all clients
{
gain = 1.0, -- default
fade = 0.0, -- default, change to a value > 0 to fade the sound in
fade = 0.0, -- default
pitch = 1.0, -- default
}
-- Play locationless to one player
{
to_player = name,
gain = 1.0, -- default
fade = 0.0, -- default, change to a value > 0 to fade the sound in
fade = 0.0, -- default
pitch = 1.0, -- default
}
-- Play locationless to one player, looped
Expand All @@ -1034,17 +1130,18 @@ Examples of sound parameter tables:
gain = 1.0, -- default
loop = true,
}
-- Play at a location
-- Play at a location, start the sound at offset 5 seconds
{
pos = {x = 1, y = 2, z = 3},
gain = 1.0, -- default
max_hear_distance = 32, -- default, uses a Euclidean metric
max_hear_distance = 32, -- default
start_time = 5.0,
}
-- Play connected to an object, looped
{
object = <an ObjectRef>,
gain = 1.0, -- default
max_hear_distance = 32, -- default, uses a Euclidean metric
max_hear_distance = 32, -- default
loop = true,
}
-- Play at a location, heard by anyone *but* the given player
Expand All @@ -1055,45 +1152,10 @@ Examples of sound parameter tables:
}
```

Looped sounds must either be connected to an object or played locationless to
one player using `to_player = name`.

A positional sound will only be heard by players that are within
`max_hear_distance` of the sound position, at the start of the sound.

`exclude_player = name` can be applied to locationless, positional and object-
bound sounds to exclude a single player from hearing them.

`SimpleSoundSpec`
-----------------

Specifies a sound name, gain (=volume) and pitch.
This is either a string or a table.

In string form, you just specify the sound name or
the empty string for no sound.

Table form has the following fields:

* `name`: Sound name
* `gain`: Volume (`1.0` = 100%)
* `pitch`: Pitch (`1.0` = 100%)

`gain` and `pitch` are optional and default to `1.0`.

Examples:

* `""`: No sound
* `{}`: No sound
* `"default_place_node"`: Play e.g. `default_place_node.ogg`
* `{name = "default_place_node"}`: Same as above
* `{name = "default_place_node", gain = 0.5}`: 50% volume
* `{name = "default_place_node", gain = 0.9, pitch = 1.1}`: 90% volume, 110% pitch

Special sound files
-------------------
Special sound-groups
--------------------

These sound files are played back by the engine if provided.
These sound-groups are played back by the engine if provided.

* `player_damage`: Played when the local player takes damage (gain = 0.5)
* `player_falling_damage`: Played when the local player takes
Expand Down Expand Up @@ -8804,7 +8866,10 @@ Used by `minetest.register_node`.

footstep = <SimpleSoundSpec>,
-- If walkable, played when object walks on it. If node is
-- climbable or a liquid, played when object moves through it
-- climbable or a liquid, played when object moves through it.
-- Sound is played at the base of the object's collision-box.
-- Gain is multiplied by `0.6`.
-- For local player, it's played position-less, with normal gain.

dig = <SimpleSoundSpec> or "__group",
-- While digging node.
Expand Down
2 changes: 1 addition & 1 deletion doc/menu_lua_api.md
Expand Up @@ -81,7 +81,7 @@ Filesystem
* `core.sound_play(spec, looped)` -> handle
* `spec` = `SimpleSoundSpec` (see `lua_api.md`)
* `looped` = bool
* `core.sound_stop(handle)`
* `handle:stop()` or `core.sound_stop(handle)`
* `core.get_video_drivers()`
* get list of video drivers supported by engine (not all modes are guaranteed to work)
* returns list of available video drivers' settings name and 'friendly' display name
Expand Down
1 change: 1 addition & 0 deletions games/devtest/mods/soundstuff/init.lua
Expand Up @@ -3,3 +3,4 @@ local path = minetest.get_modpath("soundstuff") .. "/"
dofile(path .. "sound_event_items.lua")
dofile(path .. "jukebox.lua")
dofile(path .. "bigfoot.lua")
dofile(path .. "racecar.lua")

0 comments on commit edcbfa3

Please sign in to comment.