Skip to content

Commit eb3af0f

Browse files
committed
Added doc for sound streaming
1 parent 78a4c59 commit eb3af0f

File tree

3 files changed

+111
-0
lines changed

3 files changed

+111
-0
lines changed

docs/en/en.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,10 @@
12241224
"path": "/manuals/sound",
12251225
"name": "Sound"
12261226
},
1227+
{
1228+
"path": "/manuals/sound-streaming",
1229+
"name": "Sound Streaming"
1230+
},
12271231
{
12281232
"path": "https://defold.com/assets/fmod/",
12291233
"name": "FMOD"

docs/en/manuals/sound-streaming.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
---
2+
title: Sound Streaming in Defold
3+
brief: This manual explains how to stream sounds into the Defold game engine
4+
---
5+
6+
# Sound Streaming
7+
8+
While the default behaviour is to load sound data in full, it may also be beneficial to load the data in chunks, prior to their use. This is often called "streaming".
9+
10+
One benefit is that the runtime memory is kept low.
11+
12+
Another benefit is that, if you are streaming content from e.g. a http url, you can update the content at any time, and also avoid the initial download.
13+
14+
### Example
15+
16+
There is an example project showcasing this setup: https://github.com/defold/example-sound-streaming
17+
18+
## How to enable streaming sounds
19+
20+
### Easy way
21+
22+
The simplest way to use sound streaming, is by setting the `sound.stream_enabled` to true.
23+
By simply switching on this flag, your project will start streaming the sounds.
24+
25+
Note: If you have lots of sound files loaded at the same time, you may need to up the `sound.stream_cache_size` value.
26+
27+
### Runtime resources
28+
29+
You can also create a new sound data resource, and set it to a sound component.
30+
31+
You do this by:
32+
* Load the initial part of the sound file data
33+
* Note: This is the raw sound file, including the ogg/wav header
34+
* Calling [resource.create_sound_data()](/ref/resource/#resource.create_sound_data) to get a resource
35+
* Setting the resource to the sound component
36+
37+
Here is an excerpt from the example project, using a `http.request()` to get the initial sound file.
38+
Note that the web server you're loading content from has to support ranged requests.
39+
40+
```Lua
41+
local function parse_range(s)
42+
local _, _, rstart, rend, size = string.find(s, "(%d+)-(%d+)/(%d+)") -- "bytes 0-16383/103277"
43+
return rstart, rend, size
44+
end
45+
46+
local function http_result(self, _id, response, extra)
47+
if response.status == 200 or response.status == 206 then
48+
local relative_path = self.filename
49+
local range = response.headers['content-range'] -- content-range = "bytes 0-16383/103277"
50+
local rstart, rend, filesize = parse_range(range)
51+
52+
-- Create the Defold resource, "partial" will enable the streaming mode
53+
print("Creating resource", relative_path)
54+
local hash = resource.create_sound_data(relative_path, { data = response.response, filesize = filesize, partial = true })
55+
56+
go.set(self.component, "sound", hash) -- override the resource data on the component
57+
sound.play(self.component) -- start the playing
58+
end
59+
end
60+
61+
local function load_web_sound(base_url, relative_path)
62+
local url = base_url .. "/" .. relative_path
63+
local headers = {}
64+
headers['Range'] = string.format("bytes=%d-%d", 0, 16384-1)
65+
66+
http.request(url, "GET", http_result, headers, nil, { ignore_cache = true })
67+
end
68+
```
69+
70+
## Resource providers
71+
72+
73+
You can of course use other means to load the initial chunk of the sound file.
74+
The important thing to remember is that the rest of the chunks are loaded from the resource system and our resource providers.
75+
76+
In this example, we have added a new file provider by adding a live update mount, by calling using [liveupdate.add_mount()](/ref/liveupdate/#liveupdate.add_mount).
77+
78+
79+
## Sound chunk cache
80+
81+
You can control how much memory will be consumed by the sounds at runtime, by setting the size of the "sound chunk cache".
82+
Given this limit, the loaded sound data will never exceed this limit.
83+
84+
Some things to note:
85+
86+
* Sound files smaller than the sound chunk size, aren't streamed.
87+
* If a new chunk doesn't fit into the cache, the oldest chunk is evicted
88+
* If the cache is too small, chunks may get evicted the same frame, and the sound won't play properly.
89+
90+
The initial chunk of each sound file cannot be evicted, so they will occupy the cache as long as the resources are loaded.
91+
You can also control the size of each sound chunk. This may help you get the sound cache size down even further if you have many sound files loaded at the same time.
92+
93+
## Configuration
94+
95+
Currently, the streaming is enabled on all sound resources.
96+
We may improve upon this in the future, allowing settings on individual sound files.
97+
98+
The game project supports these settings:
99+
100+
* `sound.stream_enabled` (default 0) - If enabled, enables streaming of all sound files
101+
* `sound.stream_cache_size` (default 2097152 bytes) - The max size of the cache containing _all_ chunks.
102+
* `sound.stream_chunk_size` (default 16384 bytes) - Determines size of each chunk that is loaded from a file at a time
103+

docs/en/manuals/sound.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,7 @@ resource.set_sound(path, boom)
212212
## Project configuration
213213

214214
The *game.project* file has a few [project settings](/manuals/project-settings#sound) related to sound components.
215+
216+
## Sound Streaming
217+
218+
It is also possible to support [streaming sounds](/manuals/sound-streaming)

0 commit comments

Comments
 (0)