audio.hpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#pragma once


#include <planet/audio.hpp>
#include <planet/sdl/handle.hpp>

#include <mutex>
#include <thread>

#include <SDL.h>
#undef main


namespace planet::sdl {

Audio output

Connect an audio source to this and have it play out through SDL. There should only be a single instance of this type ever active with other audio channels used for different types of audio. These should have their own gain controls, with the master gain control being used here on the final output.

25
26
27
28
29
    class audio_output final {
        SDL_AudioDeviceID device = {};
        SDL_AudioSpec configuration = {};

        void reset();

All of these items are accessed from the SDL audio thread

32
33
34
35
36
37
38
39
40
        std::mutex mtx;
        static void audio_callback(void *, Uint8 *, int);
        audio::mixer desk;
        audio::stereo_generator desk_output = desk.output();
        felspar::memory::holding_pen<audio::stereo_buffer> playing;
        std::size_t playing_marker = {};


      public:

Construction/destruction

42
        audio_output(std::optional<std::string_view>, audio::channel &);

Construct with audio sources

44
45
46
47
48
49
50
51
52
53
54
        template<typename Source, typename... Sources>
        audio_output(
                std::optional<std::string_view> const device_name,
                audio::channel &c,
                Source &s,
                Sources &...ss)
        : audio_output{device_name, c} {
            desk.add_track(s.output());
            (desk.add_track(ss.output()), ...);
        }
        ~audio_output();

Adds a new sound source

Normally prefer to use the constructor that takes the sound sources. A game will generally know exactly which main audio outputs are to be mixed together.

63
        void add_sound_source(audio::stereo_generator);

Switch connection to a different device

67
68
69
70
71
        void reconnect(std::optional<std::string_view>);
    };


}