Skip to content
This repository was archived by the owner on May 8, 2024. It is now read-only.

Commit e31c1c8

Browse files
authored
Add more audio features and versioning system (#8)
* Improve audio system - Add loop points - Add volume and pitch control - Move `AudioDecoder` functionality into AudioSource - Make audio buffer size and count customizable * Fix documentation for `Application` class * Improve crash messages to incent bug reports * Add versioning system * Remove SemVer dependancy, fix .zwversion bug when out/ doesn't exist * Small changes - Null out deferred functions - Change Asset mangle to FQN - Make AudioThread synchronized * Fix versioning system Keeping it the way it was seemed to cause a recompilation of the engine every time. This is now fixed. * Fix LDC crashes, with caveats - AudioThread code is run on main thread currently - AudioStream is instantiated on heap for no apparent reason * Fix accidental commenting in dub.sdl * Change pointer to value-type again * Audio bug fix - Add state property to AudioSource - Made AudioThread an actual thread again - Disable automatic GC collection again - Change Timer deregistration to swap deletion
1 parent e9a1a92 commit e31c1c8

File tree

20 files changed

+368
-411
lines changed

20 files changed

+368
-411
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ bin/
99
*.a
1010
.vscode
1111
dub.selections.json
12-
core.zpk
12+
out/*
13+
.zwversion

VERSIONING.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# ZyeWare versioning system
2+
3+
In general, we'll use a versioning system similar to [Semantic versioning](https://semver.org/):
4+
5+
MAJOR.MINOR.PATCH, which increment:
6+
1. MAJOR version when we make incompatible public API changes
7+
2. MINOR version when we add functionality in a backwards compatible manner
8+
3. PATCH version when we make backwards compatible bug fixes
9+
10+
(Public API in this case is every piece of code that is reachable by the client application, in the case of D when the `public` modifier is applied)
11+
12+
## Version string
13+
14+
A small "v" should be prepended in front of the actual version number.
15+
16+
If appropriate, a pre-release version name is appended with a hyphen (-), usually "alpha", "beta" and "rc".
17+
18+
Which would result in this hypothetical version string:
19+
`v0.1.2-alpha`
20+
21+
Major version zero (0.y.z) is, as defined by SemVer, used for initial development and incompatible changes may happen anytime.
22+
23+
With the introduction of this versioning schema, we'll arbitrarily start at 0.3.0, because 3 is
24+
a nice number.
25+
26+
## Querying the version number
27+
28+
It should always be possible to get the version number from `ZyeWare.engineVersion`

dub.sdl

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,23 @@ description "Simple, general purpose 2D and 3D game engine."
33
authors "ZyeByte"
44
copyright "Copyright © 2022, ZyeByte"
55
license "LGPL-3.0"
6-
dependency "inmath" version="~>1.0.5"
76
dependency "terminal" version="~>1.0.0"
87
dependency "imagefmt" version="~>2.1.1"
98
dependency "sdlang-d" version="~>0.10.6"
10-
dependency "bmfont" version="~>0.2.0"
119
dependency "audio-formats" version="~>2.0.2"
10+
dependency "bmfont" version="~>0.2.0"
11+
dependency "inmath" version="~>1.0.5"
1212
targetType "library"
1313
targetPath "out"
14-
postBuildCommands "dub run zpklink -- -i res/core-package -o out/core.zpk"
15-
copyFiles "out/core.zpk"
16-
1714
sourcePaths "source"
18-
15+
copyFiles "out/core.zpk"
16+
postBuildCommands "dub run zpklink -- -i res/core-package -o out/core.zpk"
1917
configuration "sdl-opengl" {
2018
platforms "posix" "windows"
21-
2219
dependency "bindbc-opengl" version="~>1.0.0"
23-
dependency "bindbc-sdl" version="~>1.0.1"
2420
dependency "bindbc-openal" version="~>1.0.0"
25-
21+
dependency "bindbc-sdl" version="~>1.0.1"
22+
targetType "library"
2623
sourcePaths "platform/opengl" "platform/openal"
2724
versions "GL_41" "SDL_204" "GL_KHR_debug"
2825
}

platform/openal/buffer.d

Lines changed: 52 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -5,86 +5,82 @@
55
// Copyright 2021 ZyeByte
66
module zyeware.audio.buffer;
77

8+
import std.sumtype;
9+
810
import bindbc.openal;
911

1012
import zyeware.common;
1113
import zyeware.audio;
1214

13-
// TODO: Check memory constness someday.
1415
@asset(Yes.cache)
15-
class AudioStream
16+
class Audio
1617
{
1718
protected:
1819
const(ubyte)[] mEncodedMemory;
20+
LoopPoint mLoopPoint;
1921

2022
public:
21-
this(const(ubyte)[] encodedMemory)
23+
this(const(ubyte)[] encodedMemory, AudioProperties properties = AudioProperties.init)
2224
{
2325
mEncodedMemory = encodedMemory;
26+
mLoopPoint = properties.loopPoint;
2427
}
2528

26-
const(ubyte)[] encodedMemory() pure nothrow
27-
{
28-
return mEncodedMemory;
29-
}
30-
31-
static AudioStream load(string path)
29+
LoopPoint loopPoint() pure const nothrow
3230
{
33-
VFSFile source = VFS.getFile(path);
34-
ubyte[] bestCommunityData = source.readAll!(ubyte[])();
35-
source.close();
36-
37-
Logger.core.log(LogLevel.debug_, "Loaded file '%s' as audio.", path);
38-
39-
return new AudioStream(bestCommunityData);
31+
return mLoopPoint;
4032
}
41-
}
42-
43-
/*
44-
@asset(Yes.cache)
45-
class Sound
46-
{
47-
protected:
48-
uint mId;
4933

50-
public:
51-
this(size_t channels, size_t sampleRate, in float[] data) nothrow
34+
void loopPoint(LoopPoint value) pure nothrow
5235
{
53-
alGenBuffers(1, &mId);
54-
alBufferData(mId, channels == 1 ? AL_FORMAT_MONO_FLOAT32 : AL_FORMAT_STEREO_FLOAT32,
55-
data.ptr, cast(int) (data.length * float.sizeof), cast(int) sampleRate);
36+
mLoopPoint = value;
5637
}
5738

58-
~this()
59-
{
60-
alDeleteBuffers(1, &mId);
61-
}
62-
63-
uint id() const pure nothrow
39+
const(ubyte)[] encodedMemory() pure nothrow
6440
{
65-
return mId;
41+
return mEncodedMemory;
6642
}
6743

68-
static Sound load(string path)
44+
static Audio load(string path)
6945
{
70-
auto decoder = AudioDecoder(VFS.getFile(path));
71-
72-
float[] data;
73-
float[] readBuffer = new float[2048];
74-
size_t readCount;
75-
76-
while ((readCount = decoder.read(readBuffer)) != 0)
77-
data ~= readBuffer[0 .. readCount];
78-
79-
Logger.core.log(LogLevel.debug_, "data size: %d", data.length);
46+
VFSFile source = VFS.getFile(path);
47+
ubyte[] bestCommunityData = source.readAll!(ubyte[])();
48+
source.close();
8049

81-
return new Sound(decoder.channels, decoder.sampleRate, data);
50+
AudioProperties properties;
51+
52+
if (VFS.hasFile(path ~ ".props")) // Properties file exists
53+
{
54+
import std.conv : to;
55+
import sdlang;
56+
57+
VFSFile propsFile = VFS.getFile(path ~ ".props");
58+
Tag root = parseSource(propsFile.readAll!string);
59+
propsFile.close();
60+
61+
try
62+
{
63+
if (Tag loopTag = root.getTag("loop-point"))
64+
{
65+
int v1, v2;
66+
67+
if ((v1 = loopTag.getAttribute!int("sample")) != int.init)
68+
properties.loopPoint = LoopPoint(v1);
69+
else if ((v1 = loopTag.getAttribute!int("pattern")) != int.init
70+
&& (v2 = loopTag.getAttribute!int("row")) != int.init)
71+
properties.loopPoint = LoopPoint(ModuleLoopPoint(v1, v2));
72+
else
73+
throw new Exception("Could not interpret loop point.");
74+
}
75+
}
76+
catch (Exception ex)
77+
{
78+
Logger.core.log(LogLevel.warning, "Failed to parse properties file for '%s': %s", path, ex.msg);
79+
}
80+
}
81+
82+
Logger.core.log(LogLevel.debug_, "Loaded file '%s' into memory for streaming.", path);
83+
84+
return new Audio(bestCommunityData, properties);
8285
}
83-
}
84-
85-
@asset(Yes.cache)
86-
class StreamingSound
87-
{
88-
public:
89-
static StreamingSound load(string path);
90-
}*/
86+
}

0 commit comments

Comments
 (0)