psemek/examples/audio.cpp
2022-10-05 22:55:30 +03:00

94 lines
2 KiB
C++

#include <psemek/audio/engine.hpp>
#include <psemek/audio/wave/silence.hpp>
#include <psemek/audio/wave/sine.hpp>
#include <psemek/audio/wave/sawtooth.hpp>
#include <psemek/audio/wave/square.hpp>
#include <psemek/audio/wave/triangle.hpp>
#include <psemek/audio/effect/volume.hpp>
#include <psemek/audio/duplicate.hpp>
#include <psemek/audio/stereo.hpp>
#include <psemek/audio/mixer.hpp>
#include <psemek/app/app.hpp>
#include <psemek/app/main.hpp>
#include <psemek/util/clock.hpp>
#include <psemek/geom/constants.hpp>
#include <map>
using namespace psemek;
static std::map<SDL_Keycode, int> const key_to_midi
{
{SDLK_a, 69},
{SDLK_s, 70},
{SDLK_d, 71},
{SDLK_f, 72},
{SDLK_g, 73},
{SDLK_h, 74},
{SDLK_j, 75},
{SDLK_k, 76},
{SDLK_l, 77},
{SDLK_SEMICOLON, 78},
{SDLK_QUOTE, 79},
};
struct audio_app
: app::app
{
audio_app()
: app::app("Audio example")
{
mixer_ = audio::make_mixer();
auto [ dup1, dup2 ] = audio::duplicate(mixer_);
left_volume_ = audio::volume(dup1, 0.f, 0.1f);
right_volume_ = audio::volume(dup2, 0.f, 0.1f);
auto result = audio::stereo(left_volume_, right_volume_);
engine_.output(result);
}
void on_key_down(SDL_Keycode key) override
{
app::app::on_key_down(key);
if (key_to_midi.contains(key) && !channels_.contains(key))
{
int midi = key_to_midi.at(key);
auto tone = audio::sine_wave(440.f * std::pow(2.f, (midi - 69) / 12.f));
channels_[key] = mixer_->add(tone);
}
}
void on_key_up(SDL_Keycode key) override
{
app::app::on_key_up(key);
if (channels_.contains(key))
{
channels_[key]->stop();
channels_.erase(key);
}
}
void update() override
{
float const time = clock_.count();
float volume = std::sin(time);
left_volume_->gain(0.5f + 0.5f * volume);
right_volume_->gain(0.5f - 0.5f * volume);
}
private:
audio::engine engine_;
audio::mixer_ptr mixer_;
std::shared_ptr<audio::volume_control> left_volume_, right_volume_;
std::map<SDL_Keycode, audio::mixer::channel_ptr> channels_;
util::clock<> clock_;
};
int main()
{
return app::main<audio_app>();
}