Gondwana Game Engine Development (master) - 2.6.1
Gondwana is a cross-platform 2.5D game and rendering engine written in C#/.NET 8. It provides fine-grained control over rendering, timing, and scene composition, with built-in support for parallax, z-ordering, pixel overhang, collision detection, and particle effects. Gondwana targets desktop and web platforms using SkiaSharp for graphics and pluggable audio backends for desktop and browser targets.
Loading...
Searching...
No Matches
BrowserAudioPlaybackHandle.cs
1using System.Runtime.Versioning;
2
4
5[SupportedOSPlatform("browser")]
6internal sealed class BrowserAudioPlaybackHandle : IAudioPlaybackHandle
7{
8 private readonly string _key;
9 private bool _disposed;
10 private bool _isLooping;
11 private float _volume;
12 private float _pan;
13 private float _playbackSpeed;
14
23 public BrowserAudioPlaybackHandle(string key, string uri, float volume, float pan, float playbackSpeed)
24 {
25 // Each handle owns its JS entry, including during replacement of a manager key.
26 _key = Guid.NewGuid().ToString("N");
27 _volume = Math.Clamp(volume, 0f, 1f);
28 _pan = Math.Clamp(pan, -1f, 1f);
29 _playbackSpeed = Math.Clamp(playbackSpeed, AudioResource.MinimumPlaybackSpeed, AudioResource.MaximumPlaybackSpeed);
30 BrowserAudioInterop.Load(_key, uri, loop: false, _volume, _pan, _playbackSpeed, OnEnded);
31 }
32
42 public BrowserAudioPlaybackHandle(string key, byte[] data, string mimeType, float volume, float pan, float playbackSpeed)
43 {
44 ArgumentNullException.ThrowIfNull(data);
45
46 // Packed/stream-backed browser audio is exposed to HTMLAudioElement through a
47 // short-lived Blob URL owned by the JavaScript entry.
48 _key = Guid.NewGuid().ToString("N");
49 _volume = Math.Clamp(volume, 0f, 1f);
50 _pan = Math.Clamp(pan, -1f, 1f);
51 _playbackSpeed = Math.Clamp(playbackSpeed, AudioResource.MinimumPlaybackSpeed, AudioResource.MaximumPlaybackSpeed);
52 BrowserAudioInterop.LoadBytes(
53 _key,
54 Convert.ToBase64String(data),
55 mimeType,
56 loop: false,
57 _volume,
58 _pan,
59 _playbackSpeed,
60 OnEnded);
61 }
62
64 public event EventHandler? PlaybackCompleted;
65
66 private void OnEnded()
67 {
68 if (!_disposed && !_isLooping)
69 PlaybackCompleted?.Invoke(this, EventArgs.Empty);
70 }
71
73 public AudioPlaybackState State => BrowserAudioInterop.GetState(_key) switch
74 {
75 1 => AudioPlaybackState.Playing,
76 2 => AudioPlaybackState.Paused,
77 _ => AudioPlaybackState.Stopped
78 };
79
81 public TimeSpan CurrentTime => TimeSpan.FromSeconds(Math.Max(0d, BrowserAudioInterop.GetCurrentTime(_key)));
82
84 public TimeSpan Duration => TimeSpan.FromSeconds(Math.Max(0d, BrowserAudioInterop.GetDuration(_key)));
85
87 public string? TemporaryFilePath => null;
88
90 public bool IsLooping
91 {
92 get => _isLooping;
93 set
94 {
95 _isLooping = value;
96 BrowserAudioInterop.SetLoop(_key, value);
97 }
98 }
99
101 public float Volume
102 {
103 get => _volume;
104 set
105 {
106 _volume = Math.Clamp(value, 0f, 1f);
107 BrowserAudioInterop.SetVolume(_key, _volume);
108 }
109 }
110
112 public float Pan
113 {
114 get => _pan;
115 set
116 {
117 _pan = Math.Clamp(value, -1f, 1f);
118 BrowserAudioInterop.SetPan(_key, _pan);
119 }
120 }
121
123 public float PlaybackSpeed
124 {
125 get => _playbackSpeed;
126 set
127 {
128 _playbackSpeed = Math.Clamp(value, AudioResource.MinimumPlaybackSpeed, AudioResource.MaximumPlaybackSpeed);
129 BrowserAudioInterop.SetPlaybackSpeed(_key, _playbackSpeed);
130 }
131 }
132
134 public void Play(bool fromStart = true)
135 {
136 ThrowIfDisposed();
137 BrowserAudioInterop.Play(_key, fromStart);
138 }
139
141 public void Pause()
142 {
143 ThrowIfDisposed();
144 BrowserAudioInterop.Pause(_key);
145 }
146
148 public void Resume()
149 {
150 ThrowIfDisposed();
151 if (State == AudioPlaybackState.Paused)
152 BrowserAudioInterop.Play(_key, fromStart: false);
153 }
154
156 public void Seek(TimeSpan position)
157 {
158 ThrowIfDisposed();
159 var seconds = Math.Max(0d, position.TotalSeconds);
160 BrowserAudioInterop.SetCurrentTime(_key, seconds);
161 }
162
164 public void Stop()
165 {
166 ThrowIfDisposed();
167 BrowserAudioInterop.Stop(_key);
168 }
169
170 private void ThrowIfDisposed()
171 {
172 ObjectDisposedException.ThrowIf(_disposed, this);
173 }
174
178 public void Dispose()
179 {
180 if (_disposed)
181 return;
182
183 BrowserAudioInterop.Unload(_key);
184 PlaybackCompleted = null;
185 _disposed = true;
186 }
187}
void Resume()
Resume playback after a pause.
void Pause()
Pause playback. Calling Resume should continue from the paused position.
void Stop()
Stop playback and reset the current position to the start.
AudioPlaybackState
Describes the current playback state of an audio resource without exposing backend-specific playback ...