Skip to content

Commit

Permalink
simple piano roll view
Browse files Browse the repository at this point in the history
  • Loading branch information
laamaa committed Sep 9, 2024
1 parent 47e041d commit d8879a5
Show file tree
Hide file tree
Showing 11 changed files with 305 additions and 33 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#Set all your object files (the object files of all the .c files in your project, e.g. main.o my_sub_functions.o )
OBJ = src/main.o src/serial.o src/slip.o src/command.o src/render.o src/ini.o src/config.o src/input.o src/gamecontrollers.o src/fx_cube.o src/usb.o src/audio.o src/usb_audio.o src/ringbuffer.o src/inprint2.o
OBJ = src/main.o src/serial.o src/slip.o src/command.o src/render.o src/ini.o src/config.o src/input.o src/gamecontrollers.o src/fx_cube.o src/fx_piano.o src/usb.o src/audio.o src/usb_audio.o src/ringbuffer.o src/inprint2.o

#Set any dependant header files so that if they are edited they cause a complete re-compile (e.g. main.h some_subfunctions.h some_definitions_file.h ), or leave blank
DEPS = src/serial.h src/slip.h src/command.h src/render.h src/ini.h src/config.h src/input.h src/gamecontrollers.h src/fx_cube.h src/audio.h src/ringbuffer.h src/inline_font.h
DEPS = src/serial.h src/slip.h src/command.h src/render.h src/ini.h src/config.h src/input.h src/gamecontrollers.h src/fx_cube.h src/fx_piano.h src/audio.h src/ringbuffer.h src/inline_font.h

#Any special libraries you are using in your project (e.g. -lbcm2835 -lrt `pkg-config --libs gtk+-3.0` ), or leave blank
INCLUDES = $(shell pkg-config --libs sdl2 libserialport | sed 's/-mwindows//')
Expand Down
4 changes: 2 additions & 2 deletions src/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,12 @@ int process_command(uint8_t *data, uint32_t size) {
break;
}

char *hwtype[4] = {"Headless", "Beta M8", "Production M8", "Production M8 Model:02"};
const char *hw_type[4] = {"Headless", "Beta M8", "Production M8", "Production M8 Model:02"};

static int system_info_printed = 0;

if (system_info_printed == 0) {
SDL_Log("** Hardware info ** Device type: %s, Firmware ver %d.%d.%d", hwtype[recv_buf[1]],
SDL_Log("** Hardware info ** Device type: %s, Firmware ver %d.%d.%d", hw_type[recv_buf[1]],
recv_buf[2], recv_buf[3], recv_buf[4]);
system_info_printed = 1;
}
Expand Down
7 changes: 6 additions & 1 deletion src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ config_params_s init_config() {
c.key_jazz_inc_velocity = SDL_SCANCODE_KP_MINUS;
c.key_jazz_dec_velocity = SDL_SCANCODE_KP_PLUS;
c.key_toggle_audio = SDL_SCANCODE_F12;
c.key_toggle_overlay_fx = SDL_SCANCODE_F11;

c.gamepad_up = SDL_CONTROLLER_BUTTON_DPAD_UP;
c.gamepad_left = SDL_CONTROLLER_BUTTON_DPAD_LEFT;
Expand Down Expand Up @@ -86,7 +87,7 @@ void write_config(const config_params_s *conf) {

SDL_Log("Writing config file to %s", config_path);

const unsigned int INI_LINE_COUNT = 50;
const unsigned int INI_LINE_COUNT = 51;
const unsigned int LINELEN = 50;

// Entries for the config file
Expand Down Expand Up @@ -132,6 +133,7 @@ void write_config(const config_params_s *conf) {
snprintf(ini_values[initPointer++], LINELEN, "key_jazz_dec_velocity=%d\n",
conf->key_jazz_dec_velocity);
snprintf(ini_values[initPointer++], LINELEN, "key_toggle_audio=%d\n", conf->key_toggle_audio);
snprintf(ini_values[initPointer++], LINELEN, "key_toggle_overlay_fx=%d\n", conf->key_toggle_overlay_fx);
snprintf(ini_values[initPointer++], LINELEN, "[gamepad]\n");
snprintf(ini_values[initPointer++], LINELEN, "gamepad_up=%d\n", conf->gamepad_up);
snprintf(ini_values[initPointer++], LINELEN, "gamepad_left=%d\n", conf->gamepad_left);
Expand Down Expand Up @@ -281,6 +283,7 @@ void read_key_config(const ini_t *ini, config_params_s *conf) {
const char *key_jazz_inc_velocity = ini_get(ini, "keyboard", "key_jazz_inc_velocity");
const char *key_jazz_dec_velocity = ini_get(ini, "keyboard", "key_jazz_dec_velocity");
const char *key_toggle_audio = ini_get(ini, "keyboard", "key_toggle_audio");
const char *key_toggle_overlay_fx = ini_get(ini, "keyboard", "key_toggle_overlay_fx");

if (key_up)
conf->key_up = SDL_atoi(key_up);
Expand Down Expand Up @@ -320,6 +323,8 @@ void read_key_config(const ini_t *ini, config_params_s *conf) {
conf->key_jazz_dec_velocity = SDL_atoi(key_jazz_dec_velocity);
if (key_toggle_audio)
conf->key_jazz_dec_velocity = SDL_atoi(key_toggle_audio);
if (key_toggle_overlay_fx)
conf->key_jazz_dec_velocity = SDL_atoi(key_toggle_overlay_fx);
}

void read_gamepad_config(const ini_t *ini, config_params_s *conf) {
Expand Down
1 change: 1 addition & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ typedef struct config_params_s {
unsigned int key_jazz_inc_velocity;
unsigned int key_jazz_dec_velocity;
unsigned int key_toggle_audio;
unsigned int key_toggle_overlay_fx;

int gamepad_up;
int gamepad_left;
Expand Down
169 changes: 169 additions & 0 deletions src/fx_piano.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
//
// Created by jonne on 9/8/24.
//

#include "fx_piano.h"
#include "render.h"
#include "inline_font.h"
#include <SDL2/SDL.h>

struct active_notes {
uint8_t note;
uint8_t sharp;
uint8_t octave;
};

static int width = 320;
static int height = 240;
static SDL_Texture *fx_texture;
static uint32_t *framebuffer;
struct active_notes active_notes[8] = {0};
static int is_initialized = 0;

static const uint32_t bgcolor = 0xA0000000;

// Pastel Rainbow from https://colorkit.co/palettes/8-colors/
uint32_t palette[8] = {0xEFFFADAD, 0xEFFFD6A5, 0xEFFDFFB6, 0xEFCAFFBF,
0xEF9BF6FF, 0xEFA0C4FF, 0xEFBDB2FF, 0xEFFFC6FF};

static int get_active_note_from_channel(int ch) {
if (ch >= 0 && ch < 8)
return active_notes[ch].note + active_notes[ch].sharp + active_notes[ch].octave;
else
return 0;
}

void fx_piano_init(SDL_Texture *output_texture) {
fx_texture = output_texture;
SDL_QueryTexture(fx_texture, NULL, NULL, &width, &height);
framebuffer = SDL_malloc(sizeof(uint32_t) * width * height);
SDL_memset4(framebuffer, bgcolor, width * height);
is_initialized = 1;
}

void fx_piano_update() {
//Shift everything up by one row and clear bottom row
for (int y = 1; y < height; y++) {
for (int x = 0; x < width; x++) {
int buffer_pos = x + (y * width);
// Top rows have a fading alpha value
if (y<60 && (framebuffer[buffer_pos] >> 24) > 0x04){
framebuffer[buffer_pos-width] = framebuffer[buffer_pos]-((0x05 << 24));
} else {
framebuffer[buffer_pos-width] = framebuffer[buffer_pos];
}
}
}

for (int x = 0; x < width; x++) {
framebuffer[width*(height-1)+x] = bgcolor;
framebuffer[x] = bgcolor;
}

int notes[8];
for (int i = 0; i < 8; i++) {
notes[i] = get_active_note_from_channel(i);

int last_row = (height-1)*width;
int spacing = width / 128;
if (notes[i]>0) {
int pos = last_row + (notes[i] * spacing);
uint32_t color = (framebuffer[pos] + palette[i]) | (0xCF <<24);
for (int bar_width = 0; bar_width < spacing; bar_width++) {
framebuffer[pos++] = color;
}
framebuffer[pos] = color | (0x20 << 24);
}
}

SDL_UpdateTexture(fx_texture, NULL, framebuffer,
width * sizeof(framebuffer[0]));
};

void fx_piano_destroy() {
if (is_initialized) {
SDL_free(framebuffer);
is_initialized = 0;
}
}

/* Converts the note characters displayed on M8 screen to hex values for use in
* visualizers */
int note_to_hex(int note_char) {
switch (note_char) {
case 45: // - = note off
return 0x00;
case 67: // C
return 0x01;
case 68: // D
return 0x03;
case 69: // E
return 0x05;
case 70: // F
return 0x06;
case 71: // G
return 0x08;
case 65: // A
return 0x0A;
case 66: // B
return 0x0C;
default:
return 0x00;
}
}

// Updates the active notes information array with the current command's data
void update_active_notes_data(struct draw_character_command *command, int font_mode) {

int line_spacing;
int character_spacing;
int playback_info_offset_x;

switch (font_mode) {
case 1:
case 4:
// Note name sidebar not visible all the time on MK1 / MK2
return;
case 2:
case 3:
line_spacing = 14;
character_spacing = 12;
playback_info_offset_x = 432;
break;
default:
line_spacing = 10;
character_spacing = 8;
playback_info_offset_x = 288;
break;
}

// Channels are 10 pixels apart, starting from y=70
int channel_number = command->pos.y / line_spacing - 7;


// Note playback information starts from X=288
if (command->pos.x == playback_info_offset_x) {
active_notes[channel_number].note = note_to_hex(command->c);
}

// Sharp notes live at x = 296
if (command->pos.x == playback_info_offset_x + character_spacing && !strcmp((char *)&command->c, "#"))
active_notes[channel_number].sharp = 1;
else
active_notes[channel_number].sharp = 0;

// Note octave, x = 304
if (command->pos.x == playback_info_offset_x + 2*character_spacing) {
int8_t octave = command->c - 48;

// Octaves A-B
if (octave == 17 || octave == 18)
octave -= 7;

// If octave hasn't been applied to the note yet, do it
if (octave > 0)
active_notes[channel_number].octave = octave * 0x0C;
else
active_notes[channel_number].octave = 0;
}
}
17 changes: 17 additions & 0 deletions src/fx_piano.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// Created by jonne on 9/8/24.
//

#ifndef FX_PIANO_H
#define FX_PIANO_H

#include "SDL_render.h"
#include "command.h"

void fx_piano_init(SDL_Texture *output_texture);
void fx_piano_update();
void fx_piano_destroy();

void update_active_notes_data(struct draw_character_command *command, int font_mode);

#endif //FX_PIANO_H
2 changes: 2 additions & 0 deletions src/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ static input_msg_s handle_normal_keys(const SDL_Event *event, const config_param
key = (input_msg_s){special, msg_reset_display, 0, 0};
} else if (event->key.keysym.scancode == conf->key_toggle_audio) {
key = (input_msg_s){special, msg_toggle_audio, 0, 0};
} else if (event->key.keysym.scancode == conf->key_toggle_overlay_fx) {
key = (input_msg_s){special, msg_toggle_overlay_fx, 0, 0};
} else {
key.value = 0;
}
Expand Down
3 changes: 2 additions & 1 deletion src/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ typedef enum input_type_t { normal, keyjazz, special } input_type_t;
typedef enum special_messages_t {
msg_quit = 1,
msg_reset_display = 2,
msg_toggle_audio = 3
msg_toggle_audio = 3,
msg_toggle_overlay_fx = 4
} special_messages_t;

typedef struct input_msg_s {
Expand Down
9 changes: 5 additions & 4 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
#include "audio.h"
#include "command.h"
#include "config.h"
#include "input.h"
#include "gamecontrollers.h"
#include "input.h"
#include "render.h"
#include "serial.h"
#include "slip.h"
Expand Down Expand Up @@ -220,6 +220,9 @@ int main(const int argc, char *argv[]) {
case msg_toggle_audio:
toggle_audio(conf.audio_buffer_size, conf.audio_device_name);
break;
case msg_toggle_overlay_fx:
toggle_special_fx();
break;
default:
break;
}
Expand Down Expand Up @@ -284,9 +287,7 @@ int main(const int argc, char *argv[]) {

// exit, clean up
SDL_Log("Shutting down\n");
if (conf.audio_enabled == 1) {
audio_destroy();
}
audio_destroy();
gamecontrollers_close();
close_renderer();
close_serial_port();
Expand Down
Loading

0 comments on commit d8879a5

Please sign in to comment.