WE HAVE SOUND!
This commit is contained in:
parent
47b43e7f33
commit
b7d82fd4df
3 changed files with 168 additions and 10 deletions
|
@ -1,5 +1,8 @@
|
||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace games {
|
namespace games {
|
||||||
int callback_func(libwebsocket_context * context, libwebsocket * wsi, libwebsocket_callback_reasons reason, void * user, void * in, size_t len){
|
int callback_func(libwebsocket_context * context, libwebsocket * wsi, libwebsocket_callback_reasons reason, void * user, void * in, size_t len){
|
||||||
unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 + LWS_SEND_BUFFER_POST_PADDING];
|
unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 + LWS_SEND_BUFFER_POST_PADDING];
|
||||||
|
@ -14,6 +17,7 @@ namespace games {
|
||||||
break;
|
break;
|
||||||
case LWS_CALLBACK_CLIENT_WRITEABLE:
|
case LWS_CALLBACK_CLIENT_WRITEABLE:
|
||||||
libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 1, LWS_WRITE_TEXT);
|
libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 1, LWS_WRITE_TEXT);
|
||||||
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -24,9 +28,12 @@ namespace games {
|
||||||
{ NULL, NULL, 0 }
|
{ NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
void Client::add_line(AbstractLine const & line){
|
void Client::add_line(cheap_line_type const & line_in){
|
||||||
|
auto line = create_instrument(line_in);
|
||||||
|
line->sound.reset(new motor::al::Source(sounds[line->line_kind]));
|
||||||
lines.push_back(line);
|
lines.push_back(line);
|
||||||
for(auto & l : line.calculate_lines()){
|
|
||||||
|
for(auto & l : line->calculate_lines()){
|
||||||
sim.lines.push_back(l);
|
sim.lines.push_back(l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,15 +42,25 @@ namespace games {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update_pitches(Client& client){
|
||||||
|
for(auto & l : client.lines){
|
||||||
|
auto& sound = l->sound;
|
||||||
|
sound->set_pitch(pitch_for_midi_note(client.scale.note_for_length(std::sqrt(l->sqr_length()))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Client::Client(int window_width_, int window_height_, std::shared_ptr<Base>& active_base_)
|
Client::Client(int window_width_, int window_height_, std::shared_ptr<Base>& active_base_)
|
||||||
: Base(window_width_, window_height_, active_base_)
|
: Base(window_width_, window_height_, active_base_)
|
||||||
{
|
{
|
||||||
// simulation
|
// simulation
|
||||||
beat.notes.emplace_back(note_type::kQuarterNote, note_info{100.0f, 100.0f});
|
beat.notes.emplace_back(note_type::kQuarterNote, note_info{100.0f, 100.0f});
|
||||||
|
cheap_line_type line{{{50.0f, 100.0f}, {150.0f, 200.0f}, simulation::kOneWay}};
|
||||||
AbstractLine line(Vec2{50.0f, 100.0f}, Vec2{150.0f, 200.0f}, simulation::kOneWay);
|
|
||||||
add_line(line);
|
add_line(line);
|
||||||
|
|
||||||
|
// sound
|
||||||
|
scale = Scale::load_from_file(*current_scale);
|
||||||
|
update_pitches(*this);
|
||||||
|
|
||||||
// websockets
|
// websockets
|
||||||
lws_context_creation_info info;
|
lws_context_creation_info info;
|
||||||
memset(&info, 0, sizeof info);
|
memset(&info, 0, sizeof info);
|
||||||
|
@ -54,11 +71,11 @@ namespace games {
|
||||||
info.uid = -1;
|
info.uid = -1;
|
||||||
|
|
||||||
context = libwebsocket_create_context(&info);
|
context = libwebsocket_create_context(&info);
|
||||||
assert(context);
|
if(!context) throw std::runtime_error("context could not be created.");
|
||||||
|
|
||||||
std::string address = "127.0.0.1";
|
std::string address = "127.0.0.1";
|
||||||
wsi = libwebsocket_client_connect(context, address.c_str(), 7681, false, "/", address.c_str(), "origin", "uberclient", -1);
|
wsi = libwebsocket_client_connect(context, address.c_str(), 7681, false, "/", address.c_str(), "origin", "uberclient", -1);
|
||||||
assert(wsi);
|
if(!wsi) throw std::runtime_error("socket could not be created.");
|
||||||
|
|
||||||
// motor
|
// motor
|
||||||
{
|
{
|
||||||
|
@ -106,7 +123,7 @@ namespace games {
|
||||||
|
|
||||||
// simulation
|
// simulation
|
||||||
for(auto x : sim.update(dt)){
|
for(auto x : sim.update(dt)){
|
||||||
std::cout << "plop\n";
|
x.line.information->play();
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto n : beat.update(dt)){
|
for(auto n : beat.update(dt)){
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <motor/sound/sound.hpp>
|
#include <motor/sound/sound.hpp>
|
||||||
#include <motor/basic/texture_label.hpp>
|
#include <motor/basic/texture_label.hpp>
|
||||||
|
|
||||||
#include <lib/libwebsockets.h>
|
#include <lib/libwebsockets.h>
|
||||||
|
|
||||||
|
#include "../globals.hpp"
|
||||||
#include "../Base.hpp"
|
#include "../Base.hpp"
|
||||||
#include "../input.hpp"
|
#include "../input.hpp"
|
||||||
|
|
||||||
#include "../../../beats-server/src/app_common.h"
|
#include "client_common.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace games {
|
namespace games {
|
||||||
|
@ -22,12 +26,24 @@ namespace games {
|
||||||
|
|
||||||
// simulation part
|
// simulation part
|
||||||
int balluid{0};
|
int balluid{0};
|
||||||
std::vector<AbstractLine> lines;
|
std::vector<std::shared_ptr<Instrument>> lines;
|
||||||
|
|
||||||
simu_type sim;
|
simu_type sim;
|
||||||
beat_type beat;
|
beat_type beat;
|
||||||
|
|
||||||
void add_line(AbstractLine const & line);
|
void add_line(cheap_line_type const & line);
|
||||||
|
|
||||||
|
// Sound part
|
||||||
|
const std::vector<std::string> scales{
|
||||||
|
::bundle.get_sound_path() + "maj7.txt",
|
||||||
|
::bundle.get_sound_path() + "pentatonic"
|
||||||
|
};
|
||||||
|
const std::vector<std::shared_ptr<motor::al::Buffer>> sounds{
|
||||||
|
resource_cache.get_sound_buffer(::bundle.get_sound_path() + "marimba.wav"),
|
||||||
|
resource_cache.get_sound_buffer(::bundle.get_sound_path() + "guitar440.wav")
|
||||||
|
};
|
||||||
|
std::vector<std::string>::const_iterator current_scale{scales.begin()};
|
||||||
|
Scale scale;
|
||||||
|
|
||||||
// Base part
|
// Base part
|
||||||
Client(int window_width, int window_height, std::shared_ptr<Base>& active_base);
|
Client(int window_width, int window_height, std::shared_ptr<Base>& active_base);
|
||||||
|
|
125
src/client/client_common.hpp
Normal file
125
src/client/client_common.hpp
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <motor/sound/sound.hpp>
|
||||||
|
#include "../../../beats-server/src/basics.h"
|
||||||
|
#include "../../../beats-server/src/adaptions.h"
|
||||||
|
|
||||||
|
#include "../../../beats-server/simulation/Simulation.h"
|
||||||
|
#include "../../../beats-server/simulation/Beat.h"
|
||||||
|
#include "../../../beats-server/simulation/Scales.h"
|
||||||
|
|
||||||
|
using Vec2 = math::Vec2;
|
||||||
|
using LineKind = simulation::LineKind;
|
||||||
|
|
||||||
|
struct Instrument;
|
||||||
|
using ball_info = int;
|
||||||
|
using line_info = Instrument const *;
|
||||||
|
using ball_type = simulation::Ball<ball_info>;
|
||||||
|
using line_type = simulation::Line<line_info>;
|
||||||
|
using simu_type = simulation::Simulation<ball_info, line_info>;
|
||||||
|
|
||||||
|
using note_info = Vec2;
|
||||||
|
using note_type = Note<note_info>;
|
||||||
|
using beat_type = Beat<note_info>;
|
||||||
|
|
||||||
|
const float hsize = 5.0f;
|
||||||
|
|
||||||
|
struct Instrument {
|
||||||
|
std::unique_ptr<motor::al::Source> sound;
|
||||||
|
|
||||||
|
math::Vec2 starting_point;
|
||||||
|
math::Vec2 end_point;
|
||||||
|
|
||||||
|
int line_kind;
|
||||||
|
|
||||||
|
Instrument() = default;
|
||||||
|
|
||||||
|
Instrument(math::Vec2 starting_point, math::Vec2 end_point, int line_kind)
|
||||||
|
: starting_point(starting_point)
|
||||||
|
, end_point(end_point)
|
||||||
|
, line_kind(line_kind)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// create 6 lines, to emulate width, and rounded edges
|
||||||
|
std::vector<line_type> calculate_lines() const {
|
||||||
|
auto dir = normalize(end_point - starting_point);
|
||||||
|
auto normal = rotate_ccw(dir);
|
||||||
|
LineKind lk = static_cast<LineKind>(line_kind);
|
||||||
|
|
||||||
|
if(line_kind == simulation::kOneWay){
|
||||||
|
std::vector<line_type> ret;
|
||||||
|
ret.emplace_back(starting_point + hsize*normal, end_point + hsize*normal, lk, this);
|
||||||
|
ret.emplace_back(end_point + hsize*normal, end_point + hsize*dir, lk, this);
|
||||||
|
ret.emplace_back(end_point + hsize*dir, end_point - hsize*normal, lk, this);
|
||||||
|
ret.emplace_back(end_point - hsize*normal, starting_point - hsize*normal, lk, this);
|
||||||
|
ret.emplace_back(starting_point - hsize*normal, starting_point - hsize*dir, lk, this);
|
||||||
|
ret.emplace_back(starting_point - hsize*dir, starting_point + hsize*normal, lk, this);
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
std::vector<line_type> ret;
|
||||||
|
ret.emplace_back(starting_point, end_point, lk, this);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float sqr_length() const {
|
||||||
|
auto d = end_point - starting_point;
|
||||||
|
return d.sqr_length();
|
||||||
|
}
|
||||||
|
|
||||||
|
void play() const {
|
||||||
|
sound->play();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOST_FUSION_DEFINE_STRUCT(
|
||||||
|
, IntVec2,
|
||||||
|
(int, x)
|
||||||
|
(int, y)
|
||||||
|
)
|
||||||
|
|
||||||
|
inline math::Vec2 to_FloatVec2(IntVec2 v){
|
||||||
|
return {static_cast<float>(v.x), static_cast<float>(v.y)};
|
||||||
|
}
|
||||||
|
|
||||||
|
struct cheap_ball_type {
|
||||||
|
IntVec2 position;
|
||||||
|
ball_info information;
|
||||||
|
|
||||||
|
cheap_ball_type(ball_type const & b)
|
||||||
|
: position(b.position)
|
||||||
|
, information(b.information)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOST_FUSION_ADAPT_STRUCT(
|
||||||
|
cheap_ball_type,
|
||||||
|
(IntVec2, position)
|
||||||
|
(ball_info, information)
|
||||||
|
)
|
||||||
|
|
||||||
|
struct cheap_line_type {
|
||||||
|
IntVec2 starting_point;
|
||||||
|
IntVec2 end_point;
|
||||||
|
int line_kind;
|
||||||
|
|
||||||
|
cheap_line_type(Instrument const & l)
|
||||||
|
: starting_point(l.starting_point)
|
||||||
|
, end_point(l.end_point)
|
||||||
|
, line_kind(l.line_kind)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::shared_ptr<Instrument> create_instrument(cheap_line_type l){
|
||||||
|
return std::make_shared<Instrument>(
|
||||||
|
to_FloatVec2(l.starting_point),
|
||||||
|
to_FloatVec2(l.end_point),
|
||||||
|
l.line_kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FUSION_ADAPT_STRUCT(
|
||||||
|
cheap_line_type,
|
||||||
|
(IntVec2, starting_point)
|
||||||
|
(IntVec2, end_point)
|
||||||
|
(int, line_kind)
|
||||||
|
)
|
Reference in a new issue