@@ -224,8 +224,7 @@ class Source : public ISource {
224224 void unbind () final { m_sound.reset (); }
225225
226226 [[nodiscard]] auto is_playing () const -> bool final {
227- if (!is_bound ()) { return false ; }
228- return ma_sound_is_playing (m_sound.get ()) == MA_TRUE;
227+ return is_bound () && ma_sound_is_playing (m_sound.get ()) == MA_TRUE;
229228 }
230229
231230 void play () final {
@@ -261,17 +260,38 @@ class Source : public ISource {
261260 return get_float (&ma_sound_get_cursor_in_seconds);
262261 }
263262
264- void set_cursor (std::chrono::duration<float > const position) final {
265- if (!is_bound ()) { return ; }
263+ auto set_cursor (std::chrono::duration<float > const position) -> bool final {
264+ if (!is_bound () || position < 0s || position > get_duration ()) { return false ; }
266265 ma_sound_seek_to_second (m_sound.get (), position.count ());
266+ return true ;
267+ }
268+
269+ [[nodiscard]] auto is_spatialized () const -> bool final {
270+ return is_bound () && ma_sound_is_spatialization_enabled (m_sound.get ()) == MA_TRUE;
271+ }
272+
273+ auto set_spatialized (bool const spatialized) -> bool final {
274+ if (!is_bound ()) { return false ; }
275+ ma_sound_set_spatialization_enabled (m_sound.get (), spatialized ? MA_TRUE : MA_FALSE);
276+ return true ;
267277 }
268278
269- [[nodiscard]] auto is_looping () const -> bool final {
279+ auto set_fade_in (std::chrono::duration< float > duration, float const gain) -> bool final {
270280 if (!is_bound ()) { return false ; }
271- return ma_sound_is_looping (m_sound.get ()) == MA_TRUE;
281+ ma_sound_set_fade_in_milliseconds (m_sound.get (), 0 .0f , gain, to_ms (duration));
282+ return true ;
272283 }
273284
285+ auto set_fade_out (std::chrono::duration<float > duration) -> bool final {
286+ if (!is_bound ()) { return false ; }
287+ ma_sound_set_fade_in_milliseconds (m_sound.get (), -1 .0f , 0 .0f , to_ms (duration));
288+ return true ;
289+ }
290+
291+ [[nodiscard]] auto is_looping () const -> bool final { return m_state.looping ; }
292+
274293 void set_looping (bool const looping) final {
294+ m_state.looping = looping;
275295 if (!is_bound ()) { return ; }
276296 ma_sound_set_looping (m_sound.get (), looping ? MA_TRUE : MA_FALSE);
277297 }
@@ -282,61 +302,44 @@ class Source : public ISource {
282302 }
283303
284304 void set_gain (float const gain) final {
305+ m_state.gain = std::clamp (gain, 0 .0f , 1 .0f );
285306 if (!is_bound ()) { return ; }
286- ma_sound_set_volume (m_sound.get (), std::clamp (gain, 0 .0f , 1 .0f ));
287- }
288-
289- [[nodiscard]] auto is_spatialized () const -> bool final {
290- if (!is_bound ()) { return false ; }
291- return ma_sound_is_spatialization_enabled (m_sound.get ()) == MA_TRUE;
292- }
293-
294- void set_spatialized (bool const spatialized) final {
295- if (!is_bound ()) { return ; }
296- ma_sound_set_spatialization_enabled (m_sound.get (), spatialized ? MA_TRUE : MA_FALSE);
307+ ma_sound_set_volume (m_sound.get (), m_state.gain );
297308 }
298309
299- [[nodiscard]] auto get_position () const -> Vec3f final {
300- if (!is_bound ()) { return {}; }
301- return std::bit_cast<Vec3f>(ma_sound_get_position (m_sound.get ()));
302- }
310+ [[nodiscard]] auto get_position () const -> Vec3f final { return m_state.position ; }
303311
304312 void set_position (Vec3f const & pos) final {
313+ m_state.position = pos;
305314 if (!is_bound ()) { return ; }
306315 ma_sound_set_position (m_sound.get (), pos.x , pos.y , pos.z );
307316 }
308317
309- [[nodiscard]] auto get_pan () const -> float final {
310- if (!is_bound ()) { return {}; }
311- return ma_sound_get_pan (m_sound.get ());
312- }
318+ [[nodiscard]] auto get_pan () const -> float final { return m_state.pan ; }
313319
314320 void set_pan (float const pan) final {
321+ m_state.pan = pan;
315322 if (!is_bound ()) { return ; }
316323 ma_sound_set_pan (m_sound.get (), pan);
317324 }
318325
319- [[nodiscard]] auto get_pitch () const -> float final {
320- if (!is_bound ()) { return -1 .0f ; }
321- return ma_sound_get_pitch (m_sound.get ());
322- }
326+ [[nodiscard]] auto get_pitch () const -> float final { return m_state.pitch ; }
323327
324328 void set_pitch (float const pitch) final {
329+ m_state.pitch = std::max (pitch, 0 .0f );
325330 if (!is_bound ()) { return ; }
326- ma_sound_set_pitch (m_sound.get (), std::max (pitch, 0 .0f ));
327- }
328-
329- void set_fade_in (std::chrono::duration<float > duration, float const gain) final {
330- if (!is_bound ()) { return ; }
331- ma_sound_set_fade_in_milliseconds (m_sound.get (), 0 .0f , gain, to_ms (duration));
332- }
333-
334- void set_fade_out (std::chrono::duration<float > duration) final {
335- if (!is_bound ()) { return ; }
336- ma_sound_set_fade_in_milliseconds (m_sound.get (), -1 .0f , 0 .0f , to_ms (duration));
331+ ma_sound_set_pitch (m_sound.get (), m_state.pitch );
337332 }
338333
339334 private:
335+ struct State {
336+ Vec3f position{};
337+ float gain{1 .0f };
338+ float pan{0 .0f };
339+ float pitch{0 .0f };
340+ bool looping{};
341+ };
342+
340343 [[nodiscard]] static constexpr auto to_ms (std::chrono::duration<float > const duration) -> std::uint64_t {
341344 return std::uint64_t (std::chrono::duration_cast<std::chrono::milliseconds>(duration).count ());
342345 }
@@ -357,6 +360,7 @@ class Source : public ISource {
357360
358361 m_sound = std::move (sound);
359362 m_buffer.reset ();
363+ copy_state_to_ma ();
360364 set_cursor (0s);
361365 static auto const callback = +[](void * self, ma_sound* /* sound*/ ) { static_cast <Source*>(self)->on_end (); };
362366 ma_sound_set_end_callback (m_sound.get (), callback, this );
@@ -368,9 +372,20 @@ class Source : public ISource {
368372 m_ended.notify_one ();
369373 }
370374
375+ void copy_state_to_ma () const {
376+ assert (is_bound ());
377+ ma_sound_set_volume (m_sound.get (), m_state.gain );
378+ ma_sound_set_looping (m_sound.get (), m_state.looping ? MA_TRUE : MA_FALSE);
379+ auto const & pos = m_state.position ;
380+ ma_sound_set_position (m_sound.get (), pos.x , pos.y , pos.z );
381+ ma_sound_set_pan (m_sound.get (), m_state.pan );
382+ ma_sound_set_pitch (m_sound.get (), m_state.pitch );
383+ }
384+
371385 ma_engine* m_engine{};
372386 std::shared_ptr<Buffer const > m_buffer{};
373387 std::unique_ptr<Sound> m_sound{};
388+ State m_state{};
374389 std::atomic_bool m_ended{};
375390};
376391
0 commit comments