Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alpha #66

Merged
merged 21 commits into from Jul 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
34 changes: 17 additions & 17 deletions boards/desktop/src/keys.cpp
Expand Up @@ -29,23 +29,23 @@ namespace otto::board::ui {

if (mods & Modifier::alt) {
switch (key) {
case Key::q: send_midi(core::midi::note_number("C0")); return;
case Key::n2: send_midi(core::midi::note_number("C#0")); return;
case Key::w: send_midi(core::midi::note_number("D0")); return;
case Key::n3: send_midi(core::midi::note_number("D#0")); return;
case Key::e: send_midi(core::midi::note_number("E0")); return;
case Key::r: send_midi(core::midi::note_number("F0")); return;
case Key::n5: send_midi(core::midi::note_number("F#0")); return;
case Key::t: send_midi(core::midi::note_number("G0")); return;
case Key::n6: send_midi(core::midi::note_number("G#0")); return;
case Key::y: send_midi(core::midi::note_number("A1")); return;
case Key::n7: send_midi(core::midi::note_number("A#1")); return;
case Key::u: send_midi(core::midi::note_number("B1")); return;
case Key::i: send_midi(core::midi::note_number("C1")); return;
case Key::n9: send_midi(core::midi::note_number("C#1")); return;
case Key::o: send_midi(core::midi::note_number("D1")); return;
case Key::n0: send_midi(core::midi::note_number("D#1")); return;
case Key::p: send_midi(core::midi::note_number("E1")); return;
case Key::q: send_midi(17); return;
case Key::n2: send_midi(18); return;
case Key::w: send_midi(19); return;
case Key::n3: send_midi(20); return;
case Key::e: send_midi(21); return;
case Key::r: send_midi(22); return;
case Key::n5: send_midi(23); return;
case Key::t: send_midi(24); return;
case Key::n6: send_midi(25); return;
case Key::y: send_midi(26); return;
case Key::n7: send_midi(27); return;
case Key::u: send_midi(28); return;
case Key::i: send_midi(29); return;
case Key::n9: send_midi(30); return;
case Key::o: send_midi(31); return;
case Key::n0: send_midi(32); return;
case Key::p: send_midi(33); return;
default: break;
}
}
Expand Down
2 changes: 2 additions & 0 deletions boards/parts/ui/egl/config.cmake
Expand Up @@ -8,3 +8,5 @@ target_link_libraries(otto PUBLIC ${BCM_EGL})
target_link_libraries(otto PUBLIC ${BCM_GLES})
target_link_libraries(otto PUBLIC dl)
target_include_directories(otto PUBLIC "/opt/vc/include")

otto_option(USE_FBCP "Use FBCP to copy each frame from /dev/fb0 to /dev/fb1. Disable if you dont use FBTFT" OFF)
4 changes: 4 additions & 0 deletions boards/parts/ui/egl/src/egl_ui.cpp
Expand Up @@ -29,8 +29,10 @@ namespace otto::service::ui {
{
EGLConnection egl;
egl.init();
#if OTTO_USE_FBCP
auto fbcp = RpiFBCP{egl.eglData};
fbcp.init();
#endif

NVGcontext* nvg =
nvgCreateGLES2(NVG_ANTIALIAS | NVG_STENCIL_STROKES | NVG_DEBUG);
Expand Down Expand Up @@ -88,7 +90,9 @@ namespace otto::service::ui {
canvas.endFrame();
egl.endFrame();

#if OTTO_USE_FBCP
fbcp.copy();
#endif

lastFrameTime = clock::now() - t0;
std::this_thread::sleep_for(waitTime - lastFrameTime);
Expand Down
41 changes: 41 additions & 0 deletions boards/parts/ui/egl/src/rpi_input.cpp
Expand Up @@ -3,6 +3,8 @@
#include <unistd.h>
#include <string>
#include <vector>
#include <thread>

#include "core/globals.hpp"
#include "services/ui.hpp"
#include "util/filesystem.hpp"
Expand Down Expand Up @@ -101,11 +103,50 @@ namespace otto::board::ui {
}
}

void read_encoders() {
auto file = fopen("/dev/ttyACM0", "r");
if (file == nullptr) return;

char *line = nullptr;
std::size_t len;
std::size_t read;

while (global::running()) {
read = getline(&line, &len, file);
if (len >= 2) {
if (line[1] == 'P') {
switch (line[0]) {
case 'B': service::ui::impl::keypress(core::ui::Key::blue_click); break;
case 'G': service::ui::impl::keypress(core::ui::Key::green_click); break;
case 'Y': service::ui::impl::keypress(core::ui::Key::white_click); break;
case 'R': service::ui::impl::keypress(core::ui::Key::red_click); break;
default: break;
}
continue;
}
RotaryEvent rot;
switch (line[0]) {
case 'B': rot.rotary = Rotary::Blue; break;
case 'G': rot.rotary = Rotary::Green; break;
case 'Y': rot.rotary = Rotary::White; break;
case 'R': rot.rotary = Rotary::Red; break;
default: rot.rotary = Rotary{-1};
}
if (rot.rotary == Rotary{-1}) continue;
char* end = line + len;
rot.clicks = std::strtol(line + 1, &end, 10);
service::ui::impl::rotary(rot);
}
}
}

void read_keyboard()
{
static Modifiers left;
static Modifiers right;
static int keyboard = open_device("0-event-kbd");
static std::thread encoder_thread = std::thread{[] { read_encoders(); }};

if (keyboard == -1) {
throw global::exception(global::ErrorCode::input_error,
"Could not find a keyboard!");
Expand Down
8 changes: 4 additions & 4 deletions boards/parts/ui/glfw/src/glfw_ui.cpp
Expand Up @@ -52,7 +52,7 @@ namespace otto::service::ui {
debug_ui::init();

GLFWwindow* window =
glfwCreateWindow(vg::WIDTH, vg::HEIGHT, "OTTO", NULL, NULL);
glfwCreateWindow(vg::width, vg::height, "OTTO", NULL, NULL);
if (!window) {
glfwTerminate();
return;
Expand All @@ -74,7 +74,7 @@ namespace otto::service::ui {
return;
}

vg::Canvas canvas(vg, vg::WIDTH, vg::HEIGHT);
vg::Canvas canvas(vg, vg::width, vg::height);
vg::initUtils(canvas);

LOG_F(INFO, "Opening GLFW Window");
Expand Down Expand Up @@ -127,8 +127,8 @@ namespace otto::service::ui {
glfwGetFramebufferSize(window, &fbWidth, &fbHeight);

// Calculate pixel ration for hi-dpi devices.
scale = std::min((float) winWidth / (float) vg::WIDTH,
(float) winHeight / (float) vg::HEIGHT);
scale = std::min((float) winWidth / (float) vg::width,
(float) winHeight / (float) vg::height);
canvas.setSize(winWidth, winHeight);

// Update and render
Expand Down
1,128 changes: 1,127 additions & 1 deletion boards/rpi-proto-1/doc/kbfirmware.com.json

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion external/gl3w_gen.cmake
Expand Up @@ -39,17 +39,26 @@ set(UNLICENSE
")

file(MAKE_DIRECTORY ${OUTDIR}/include/GL)
file(MAKE_DIRECTORY ${OUTDIR}/include/KHR)
file(MAKE_DIRECTORY ${OUTDIR}/src)

if(NOT EXISTS ${OUTDIR}/include/GL/glcorearb.h)
message(STATUS "Downloading glcorearb.h to include/GL...")
file(DOWNLOAD
http://www.khronos.org/registry/OpenGL/api/GL/glcorearb.h
https://www.khronos.org/registry/OpenGL/api/GL/glcorearb.h
${OUTDIR}/include/GL/glcorearb.h)
else()
message(STATUS "Reusing glcorearb.h from include/GL...")
endif()

if(NOT EXISTS ${OUTDIR}/include/KHR/khrplatform.h)
message(STATUS "Downloading khrplatform.h to include/KHR...")
file(DOWNLOAD
https://www.khronos.org/registry/EGL/api/KHR/khrplatform.h
${OUTDIR}/include/KHR/khrplatform.h)
else()
message(STATUS "Reusing glcorearb.h from include/GL...")
endif()
message(STATUS "Parsing glcorearb.h header...")

file(STRINGS ${OUTDIR}/include/GL/glcorearb.h GLCOREARB)
Expand Down
91 changes: 89 additions & 2 deletions src/core/audio/voice_manager.cpp
Expand Up @@ -16,21 +16,45 @@ namespace otto::core::audio {
EnvelopeProps& props;
};

struct SettingsScreen : ui::Screen {

SettingsScreen(SettingsProps& props)
: props (props)
{}

void draw(ui::vg::Canvas&) override;
void rotary(ui::RotaryEvent ev) override;

SettingsProps& props;
};

namespace detail {
std::unique_ptr<ui::Screen> make_envelope_screen(EnvelopeProps& props)
{
return std::make_unique<EnvelopeScreen>(props);
}

std::unique_ptr<ui::Screen> make_settings_screen(EnvelopeProps& props)
std::unique_ptr<ui::Screen> make_settings_screen(SettingsProps& props)
{
return std::make_unique<EnvelopeScreen>(props);
return std::make_unique<SettingsScreen>(props);
}
}

std::string to_string(PlayMode pm) noexcept
{
switch (pm) {
case PlayMode::poly: return "Poly";
case PlayMode::mono: return "Mono";
case PlayMode::unison: return "Unison";
default: return "";
};
}

using namespace ui;
using namespace ui::vg;

// ENVELOPE SCREEN //////////////////////////////////////////////////////////

void EnvelopeScreen::rotary(RotaryEvent ctx) {
switch (ctx.rotary) {
case Rotary::Blue:
Expand Down Expand Up @@ -259,4 +283,67 @@ namespace otto::core::audio {
ctx.stroke();
}

// SETTINGS SCREEN //////////////////////////////////////////////////////////

void SettingsScreen::rotary(ui::RotaryEvent ev)
{
switch (ev.rotary) {
case Rotary::Blue: props.play_mode.step(ev.clicks); break;
case Rotary::Green: props.portamento.step(ev.clicks); break;
case Rotary::White: props.octave.step(ev.clicks); break;
case Rotary::Red: props.transpose.step(ev.clicks); break;
}
}

void SettingsScreen::draw(ui::vg::Canvas& ctx)
{
using namespace ui::vg;

ctx.font(Fonts::Bold, 40);

constexpr float x_pad = 30;
constexpr float y_pad = 50;
constexpr float space = (height - 2.f * y_pad) / 3.f;

ctx.beginPath();
ctx.fillStyle(Colours::Blue);
ctx.textAlign(HorizontalAlign::Left, VerticalAlign::Middle);
ctx.fillText("Play Mode", {x_pad, y_pad});

ctx.beginPath();
ctx.fillStyle(Colours::Blue);
ctx.textAlign(HorizontalAlign::Right, VerticalAlign::Middle);
ctx.fillText(to_string(props.play_mode), {width - x_pad, y_pad});

ctx.beginPath();
ctx.fillStyle(Colours::Green);
ctx.textAlign(HorizontalAlign::Left, VerticalAlign::Middle);
ctx.fillText("Portamento", {x_pad, y_pad + space});

ctx.beginPath();
ctx.fillStyle(Colours::Green);
ctx.textAlign(HorizontalAlign::Right, VerticalAlign::Middle);
ctx.fillText(fmt::format("{:3.2}", props.portamento), {width - x_pad, y_pad + space});

ctx.beginPath();
ctx.fillStyle(Colours::Yellow);
ctx.textAlign(HorizontalAlign::Left, VerticalAlign::Middle);
ctx.fillText("Octave", {x_pad, y_pad + 2 * space});

ctx.beginPath();
ctx.fillStyle(Colours::Yellow);
ctx.textAlign(HorizontalAlign::Right, VerticalAlign::Middle);
ctx.fillText(fmt::format("{:+}", props.octave), {width - x_pad, y_pad + 2 * space});

ctx.beginPath();
ctx.fillStyle(Colours::Red);
ctx.textAlign(HorizontalAlign::Left, VerticalAlign::Middle);
ctx.fillText("Transpose", {x_pad, y_pad + 3 * space});

ctx.beginPath();
ctx.fillStyle(Colours::Red);
ctx.textAlign(HorizontalAlign::Right, VerticalAlign::Middle);
ctx.fillText(fmt::format("{:+}", props.transpose), {width - x_pad, y_pad + 3 * space});
}

} // namespace otto::core::audio