From b7d82fd4df38e422a6f9b84a94abdf41189ef295 Mon Sep 17 00:00:00 2001 From: Joshua Moerman Date: Tue, 16 Apr 2013 20:00:10 +0200 Subject: [PATCH] WE HAVE SOUND! --- src/client/client.cpp | 31 +++++++-- src/client/client.hpp | 22 +++++- src/client/client_common.hpp | 125 +++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 10 deletions(-) create mode 100644 src/client/client_common.hpp diff --git a/src/client/client.cpp b/src/client/client.cpp index 854c188..7536316 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -1,5 +1,8 @@ #include "client.hpp" +#include +#include + namespace games { 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]; @@ -14,6 +17,7 @@ namespace games { break; case LWS_CALLBACK_CLIENT_WRITEABLE: libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 1, LWS_WRITE_TEXT); + break; default: break; } return 0; @@ -24,9 +28,12 @@ namespace games { { 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); - for(auto & l : line.calculate_lines()){ + + for(auto & l : line->calculate_lines()){ sim.lines.push_back(l); } } @@ -35,15 +42,25 @@ namespace games { 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& active_base_) : Base(window_width_, window_height_, active_base_) { // simulation beat.notes.emplace_back(note_type::kQuarterNote, note_info{100.0f, 100.0f}); - - AbstractLine line(Vec2{50.0f, 100.0f}, Vec2{150.0f, 200.0f}, simulation::kOneWay); + cheap_line_type line{{{50.0f, 100.0f}, {150.0f, 200.0f}, simulation::kOneWay}}; add_line(line); + // sound + scale = Scale::load_from_file(*current_scale); + update_pitches(*this); + // websockets lws_context_creation_info info; memset(&info, 0, sizeof info); @@ -54,11 +71,11 @@ namespace games { info.uid = -1; 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"; 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 { @@ -106,7 +123,7 @@ namespace games { // simulation for(auto x : sim.update(dt)){ - std::cout << "plop\n"; + x.line.information->play(); } for(auto n : beat.update(dt)){ diff --git a/src/client/client.hpp b/src/client/client.hpp index 1bb82db..c35ef69 100644 --- a/src/client/client.hpp +++ b/src/client/client.hpp @@ -1,14 +1,18 @@ #pragma once +#include +#include + #include #include #include +#include "../globals.hpp" #include "../Base.hpp" #include "../input.hpp" -#include "../../../beats-server/src/app_common.h" +#include "client_common.hpp" namespace games { @@ -22,12 +26,24 @@ namespace games { // simulation part int balluid{0}; - std::vector lines; + std::vector> lines; simu_type sim; beat_type beat; - void add_line(AbstractLine const & line); + void add_line(cheap_line_type const & line); + + // Sound part + const std::vector scales{ + ::bundle.get_sound_path() + "maj7.txt", + ::bundle.get_sound_path() + "pentatonic" + }; + const std::vector> 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::const_iterator current_scale{scales.begin()}; + Scale scale; // Base part Client(int window_width, int window_height, std::shared_ptr& active_base); diff --git a/src/client/client_common.hpp b/src/client/client_common.hpp new file mode 100644 index 0000000..35608a6 --- /dev/null +++ b/src/client/client_common.hpp @@ -0,0 +1,125 @@ +#pragma once + +#include +#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; +using line_type = simulation::Line; +using simu_type = simulation::Simulation; + +using note_info = Vec2; +using note_type = Note; +using beat_type = Beat; + +const float hsize = 5.0f; + +struct Instrument { + std::unique_ptr 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 calculate_lines() const { + auto dir = normalize(end_point - starting_point); + auto normal = rotate_ccw(dir); + LineKind lk = static_cast(line_kind); + + if(line_kind == simulation::kOneWay){ + std::vector 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 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(v.x), static_cast(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 create_instrument(cheap_line_type l){ + return std::make_shared( + 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) +)