Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 57fa627bed | |||
| 9dbfd34566 | |||
| 3dc2a77529 | |||
| 7dbce62182 | |||
| bb84350591 | |||
| 7db7f4b89e |
+1
-1
@@ -124,7 +124,7 @@ make -f Makefile.dev release-arch
|
||||
- [x] (clean) static functions at top of files
|
||||
- [x] Configurable key codes
|
||||
- [x] Monitor improvements
|
||||
- [ ] Ignore some values in auto random
|
||||
- [x] Ignore some values in auto random
|
||||
- [x] build without video in
|
||||
- [ ] Update README monitor/keymap
|
||||
- [x] Auto reconnect midi input
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
pkgname=forge-steel
|
||||
pkgver=1.1.3
|
||||
pkgver=1.2.0
|
||||
pkgrel=1
|
||||
pkgdesc="Fusion Of Real Time Generative Effects"
|
||||
arch=('i686' 'pentium4' 'x86_64' 'arm' 'armv7h' 'armv6h' 'aarch64' 'riscv64')
|
||||
depends=('glfw>=1:3', 'v4l-utils>=1.32', 'alsa-lib>=1.2', 'libglvnd>=1.7')
|
||||
url="https://git.klemek.fr/klemek/forge-steel"
|
||||
source=("${pkgname}-steel-${pkgver}.tar.gz::https://git.klemek.fr/klemek/forge-steel/releases/download/v${pkgver}/${pkgname}-${pkgver}.tar.gz")
|
||||
sha256sums=('536370c14aaac35729b29270cecca01a6c966bcae306fa2ec20f8a514a3ed8bd')
|
||||
sha256sums=('b04e9159eb3eb809029bf02423e4bf844ecdb3b11cbcb49d8eed8f2505d32a1f')
|
||||
srcdir=build
|
||||
backup=("usr/share/${pkgname}")
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[](https://git.klemek.fr/klemek/forge-steel/actions?workflow=lint.yml) [](https://git.klemek.fr/klemek/forge-steel/actions?workflow=build.yml) 
|
||||
[](https://git.klemek.fr/klemek/forge-steel/actions?workflow=lint.yml) [](https://git.klemek.fr/klemek/forge-steel/actions?workflow=build.yml) 
|
||||
|
||||
<!-- omit from toc -->
|
||||
# F.O.R.G.E. (Steel)
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
AC_INIT([forge], [steel-1.1.3], [klemek.dev@proton.me])
|
||||
AC_INIT([forge], [steel-1.2.0], [klemek.dev@proton.me])
|
||||
AM_INIT_AUTOMAKE
|
||||
AC_PROG_CC
|
||||
|
||||
|
||||
@@ -235,10 +235,11 @@ GROUP_1_6_Y=19
|
||||
GROUP_1_6_Z=
|
||||
|
||||
# Same for group 2
|
||||
GROUP_2_ACTIVE_COUNT=3
|
||||
GROUP_2_ACTIVE_COUNT=4
|
||||
GROUP_2_ACTIVE_1=36
|
||||
GROUP_2_ACTIVE_2=68
|
||||
GROUP_2_ACTIVE_3=52
|
||||
GROUP_2_ACTIVE_4=11077
|
||||
GROUP_2_COUNT=7
|
||||
GROUP_2_1_X=37
|
||||
GROUP_2_1_Y=53
|
||||
@@ -271,6 +272,26 @@ GROUP_3_2_X=0
|
||||
GROUP_3_2_Y=16
|
||||
GROUP_3_2_Z=11089
|
||||
|
||||
# Auto-Random Ignore (ARI) prefixes
|
||||
ARI_COUNT=17
|
||||
ARI_1=GROUP_3_1_Y
|
||||
ARI_2=GROUP_3_2_Z
|
||||
ARI_3=GROUP_2_1_X_4
|
||||
ARI_4=GROUP_2_1_Y_4
|
||||
ARI_5=GROUP_2_1_Z_4
|
||||
ARI_6=GROUP_2_2_X_4
|
||||
ARI_7=GROUP_2_2_Y_4
|
||||
ARI_8=GROUP_2_2_Z_4
|
||||
ARI_9=GROUP_2_4_X_4
|
||||
ARI_10=GROUP_2_4_Y_4
|
||||
ARI_11=GROUP_2_4_Z_4
|
||||
ARI_12=GROUP_2_6_X_4
|
||||
ARI_13=GROUP_2_6_Y_4
|
||||
ARI_14=GROUP_2_6_Z_4
|
||||
ARI_15=GROUP_2_7_X_4
|
||||
ARI_16=GROUP_2_7_Y_4
|
||||
ARI_17=GROUP_2_7_Z_4
|
||||
|
||||
# =====
|
||||
# OTHER
|
||||
# =====
|
||||
|
||||
+1
-5
@@ -16,15 +16,11 @@ uniform sampler2D iTex0;
|
||||
uniform int iSeed8;
|
||||
uniform vec3 iGroup2_3[7];
|
||||
uniform vec3 iGroup3_1[2];
|
||||
uniform int iDemo;
|
||||
uniform int iAutoRand;
|
||||
|
||||
void main() {
|
||||
vec4 color = fx_stage(vUV, iTex9, iTex0, iSeed8, iGroup2_3[0], iGroup2_3[1].xy, iGroup2_3[2], iGroup2_3[3].xy, iGroup2_3[4], iGroup2_3[5].xy, iGroup2_3[6]);
|
||||
|
||||
if (iDemo < 1 && iAutoRand < 1) {
|
||||
color = mix(color, vec4(0), iGroup3_1[0].y);
|
||||
}
|
||||
color = mix(color, vec4(0), iGroup3_1[0].y);
|
||||
|
||||
fragColor = color;
|
||||
}
|
||||
|
||||
+32
-1
@@ -6,8 +6,39 @@
|
||||
in vec2 vUV;
|
||||
out vec4 fragColor;
|
||||
|
||||
#include inc_map.glsl
|
||||
|
||||
uniform sampler2D iTex0;
|
||||
uniform vec3 iGroup2_4[7];
|
||||
|
||||
void main() {
|
||||
fragColor = texture(iTex0, vUV);
|
||||
bool visible = iGroup2_4[0].x > 0;
|
||||
bool invert = iGroup2_4[0].y > 0;
|
||||
float rect = iGroup2_4[0].z;
|
||||
|
||||
vec2 uv2 = vUV;
|
||||
|
||||
if (visible) {
|
||||
vec2 p1 = vec2(iGroup2_4[6].xy);
|
||||
vec2 p2 = vec2(iGroup2_4[1].xy);
|
||||
vec2 p3 = vec2(iGroup2_4[3].xy);
|
||||
vec2 p4 = vec2(iGroup2_4[5].xy);
|
||||
|
||||
p2.x = 1 - p2.x;
|
||||
p3.y = 1 - p3.y;
|
||||
p4.x = 1 - p4.x;
|
||||
p4.y = 1 - p4.y;
|
||||
|
||||
uv2 = project_4p(vUV, p1, p2, p3, p4);
|
||||
}
|
||||
|
||||
vec4 color = texture(iTex0, invert ? vUV : uv2);
|
||||
|
||||
if (visible) {
|
||||
float mask = step(0, uv2.x) * step(-1, -uv2.x) * step(0, uv2.y) * step(-1, -uv2.y);
|
||||
color *= mix(mask, 1 - mask, invert ? 1 : 0);
|
||||
color = mix(color, color + mask * vec4(1), rect * (step(uv2.x, 0.01) + step(uv2.y, 0.01) + step(1 - uv2.y, 0.01) + step(1 - uv2.x, 0.01)));
|
||||
}
|
||||
|
||||
fragColor = color;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef INC_MAP
|
||||
#define INC_MAP
|
||||
|
||||
vec2 project_4p(vec2 uv, vec2 p1, vec2 p2, vec2 p3, vec2 p4) {
|
||||
float k1 = (p4.y - p3.y) / (p2.y - p3.y);
|
||||
float k2 = (p3.y - p1.y) / (p2.y - p3.y);
|
||||
float a = (p4.x - p3.x + k1 * p3.x - k1 * p2.x) / (p1.x - p3.x - k2 * p3.x + k2 * p2.x);
|
||||
float b = k1 + a * k2;
|
||||
float c = 1 - a - b;
|
||||
// https://math.stackexchange.com/questions/296794/finding-the-transform-matrix-from-4-projected-points-with-javascript/339033#339033
|
||||
mat3 projection_a = mat3(
|
||||
a * p1.x, a * p1.y, a,
|
||||
b * p2.x, b * p2.y, b,
|
||||
c * p3.x, c * p3.y, c
|
||||
);
|
||||
mat3 projection_a_prime = inverse(projection_a);
|
||||
mat3 projection_b = mat3(
|
||||
0, 0, -1,
|
||||
1, 0, 1,
|
||||
0, 1, 1
|
||||
);
|
||||
vec3 tmp = projection_b * projection_a_prime * vec3(uv, 1);
|
||||
return tmp.xy / tmp.z;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -12,6 +12,16 @@ unsigned int arr_uint_index_of(UintArray array, unsigned int value) {
|
||||
return ARRAY_NOT_FOUND;
|
||||
}
|
||||
|
||||
bool arr_string_match(StringArray array, const char *needle) {
|
||||
for (unsigned int i = 0; i < array.length; i++) {
|
||||
if (strncmp(array.values[i], needle, strlen(array.values[i])) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int arr_uint_remap_index(UintArray offsets, unsigned int *index) {
|
||||
if (offsets.length == 0) {
|
||||
return 0;
|
||||
|
||||
@@ -7,4 +7,6 @@ unsigned int arr_uint_index_of(UintArray array, unsigned int value);
|
||||
|
||||
unsigned int arr_uint_remap_index(UintArray offsets, unsigned int *index);
|
||||
|
||||
bool arr_string_match(StringArray array, const char *needle);
|
||||
|
||||
#endif /* ARR_H */
|
||||
|
||||
+77
-22
@@ -98,11 +98,15 @@ static void randomize(Context *context, StateConfig state_config) {
|
||||
l = state_config.values_offsets.values[part] +
|
||||
k * state_config.group_counts.values[part] + j;
|
||||
|
||||
if (arr_uint_index_of(state_config.fader_codes,
|
||||
state_config.codes.values[i]) != ARRAY_NOT_FOUND) {
|
||||
context->values[l][i % 3] = (float)rand_uint(MIDI_MAX + 1) / MIDI_MAX;
|
||||
} else {
|
||||
context->values[l][i % 3] = rand_uint(2) == 1 ? 1 : 0;
|
||||
if (arr_uint_index_of(state_config.random_ignored, (l * 3) + (i % 3)) ==
|
||||
ARRAY_NOT_FOUND) {
|
||||
if (arr_uint_index_of(state_config.fader_codes,
|
||||
state_config.codes.values[i]) !=
|
||||
ARRAY_NOT_FOUND) {
|
||||
context->values[l][i % 3] = (float)rand_uint(MIDI_MAX + 1) / MIDI_MAX;
|
||||
} else {
|
||||
context->values[l][i % 3] = rand_uint(2) == 1 ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -271,6 +275,8 @@ void state_parse_config(StateConfig *state_config, const ConfigFile *config) {
|
||||
unsigned int offset;
|
||||
unsigned int count;
|
||||
unsigned int length;
|
||||
unsigned int value_offset;
|
||||
StringArray ignored_codes;
|
||||
char name[STR_LEN];
|
||||
|
||||
length = config_file_get_int(config, "SELECT_PAGE_COUNT", 0);
|
||||
@@ -312,6 +318,18 @@ void state_parse_config(StateConfig *state_config, const ConfigFile *config) {
|
||||
config_file_get_int(config, name, UNSET_MIDI_CODE);
|
||||
}
|
||||
|
||||
length = config_file_get_int(config, "ARI_COUNT", 0);
|
||||
if (length > ARRAY_SIZE) {
|
||||
length = ARRAY_SIZE;
|
||||
}
|
||||
ignored_codes.length = length;
|
||||
|
||||
for (unsigned int i = 0; i < ignored_codes.length; i++) {
|
||||
snprintf(name, STR_LEN, "ARI_%d", i + 1);
|
||||
strlcpy(ignored_codes.values[i],
|
||||
config_file_get_str(config, name, "unkown"), STR_LEN);
|
||||
}
|
||||
|
||||
length = config_file_get_int(config, "GROUP_COUNT", 0);
|
||||
if (length > ARRAY_SIZE) {
|
||||
length = ARRAY_SIZE;
|
||||
@@ -361,26 +379,60 @@ void state_parse_config(StateConfig *state_config, const ConfigFile *config) {
|
||||
length = ARRAY_SIZE;
|
||||
}
|
||||
state_config->codes.length = count * 3;
|
||||
state_config->random_ignored.length = 0;
|
||||
|
||||
for (unsigned int i = 0; i < state_config->group_counts.length; i++) {
|
||||
offset = state_config->group_offsets.values[i];
|
||||
value_offset = state_config->values_offsets.values[i];
|
||||
for (unsigned int j = 0; j < state_config->group_counts.values[i]; j++) {
|
||||
if ((offset + j) * 3 < ARRAY_SIZE) {
|
||||
snprintf(name, STR_LEN, "GROUP_%d_%d_X", i + 1, j + 1);
|
||||
state_config->codes.values[(offset + j) * 3] =
|
||||
config_file_get_int(config, name, UNSET_MIDI_CODE);
|
||||
for (unsigned int k = 0;
|
||||
k < state_config->group_active_counts.values[i]; k++) {
|
||||
snprintf(name, STR_LEN, "GROUP_%d_%d_X_%d", i + 1, j + 1, k + 1);
|
||||
if (arr_string_match(ignored_codes, name)) {
|
||||
state_config->random_ignored
|
||||
.values[state_config->random_ignored.length++] =
|
||||
(value_offset + k * state_config->group_counts.values[i] + j) *
|
||||
3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((offset + j) * 3 + 1 < ARRAY_SIZE) {
|
||||
snprintf(name, STR_LEN, "GROUP_%d_%d_Y", i + 1, j + 1);
|
||||
state_config->codes.values[(offset + j) * 3 + 1] =
|
||||
config_file_get_int(config, name, UNSET_MIDI_CODE);
|
||||
for (unsigned int k = 0;
|
||||
k < state_config->group_active_counts.values[i]; k++) {
|
||||
snprintf(name, STR_LEN, "GROUP_%d_%d_Y_%d", i + 1, j + 1, k + 1);
|
||||
if (arr_string_match(ignored_codes, name)) {
|
||||
state_config->random_ignored
|
||||
.values[state_config->random_ignored.length++] =
|
||||
(value_offset + k * state_config->group_counts.values[i] + j) *
|
||||
3 +
|
||||
1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((offset + j) * 3 + 2 < ARRAY_SIZE) {
|
||||
snprintf(name, STR_LEN, "GROUP_%d_%d_Z", i + 1, j + 1);
|
||||
state_config->codes.values[(offset + j) * 3 + 2] =
|
||||
config_file_get_int(config, name, UNSET_MIDI_CODE);
|
||||
for (unsigned int k = 0;
|
||||
k < state_config->group_active_counts.values[i]; k++) {
|
||||
snprintf(name, STR_LEN, "GROUP_%d_%d_Z_%d", i + 1, j + 1, k + 1);
|
||||
if (arr_string_match(ignored_codes, name)) {
|
||||
state_config->random_ignored
|
||||
.values[state_config->random_ignored.length++] =
|
||||
(value_offset + k * state_config->group_counts.values[i] + j) *
|
||||
3 +
|
||||
2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -477,6 +529,9 @@ static bool compute_event(Context *context, StateConfig state_config,
|
||||
unsigned int j;
|
||||
unsigned int k;
|
||||
unsigned int part;
|
||||
bool found;
|
||||
|
||||
found = false;
|
||||
|
||||
// PAGE CHANGE
|
||||
i = arr_uint_index_of(state_config.select_page_codes, code);
|
||||
@@ -485,7 +540,7 @@ static bool compute_event(Context *context, StateConfig state_config,
|
||||
context->page = i;
|
||||
update_page(context, state_config, midi);
|
||||
}
|
||||
return true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
// TARGET CHANGE
|
||||
@@ -495,7 +550,7 @@ static bool compute_event(Context *context, StateConfig state_config,
|
||||
context->selected = i;
|
||||
update_page(context, state_config, midi);
|
||||
}
|
||||
return true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
// ITEM CHANGE
|
||||
@@ -506,7 +561,7 @@ static bool compute_event(Context *context, StateConfig state_config,
|
||||
context->page * state_config.select_item_codes.length + i;
|
||||
update_page(context, state_config, midi);
|
||||
}
|
||||
return true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
// ACTIVE CHANGE
|
||||
@@ -518,7 +573,7 @@ static bool compute_event(Context *context, StateConfig state_config,
|
||||
update_active(context, state_config, midi, true);
|
||||
update_values(context, state_config, midi);
|
||||
}
|
||||
return true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
// VALUE CHANGE
|
||||
@@ -540,7 +595,7 @@ static bool compute_event(Context *context, StateConfig state_config,
|
||||
safe_midi_write(midi, code, MIDI_MAX);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
// TAP TEMPO
|
||||
@@ -549,7 +604,7 @@ static bool compute_event(Context *context, StateConfig state_config,
|
||||
if (value > 0) {
|
||||
tempo_tap(&context->tempo);
|
||||
}
|
||||
return true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
// OTHER KEYS
|
||||
@@ -559,7 +614,7 @@ static bool compute_event(Context *context, StateConfig state_config,
|
||||
randomize(context, state_config);
|
||||
update_values(context, state_config, midi);
|
||||
}
|
||||
return true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (code == state_config.key_reset) {
|
||||
@@ -568,7 +623,7 @@ static bool compute_event(Context *context, StateConfig state_config,
|
||||
reset(context);
|
||||
update_values(context, state_config, midi);
|
||||
}
|
||||
return true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (code == state_config.key_demo) {
|
||||
@@ -576,7 +631,7 @@ static bool compute_event(Context *context, StateConfig state_config,
|
||||
log_info((context->demo ? "[%d] Demo OFF" : "[%d] Demo ON"), code);
|
||||
context->demo = !context->demo;
|
||||
}
|
||||
return true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (code == state_config.key_autorand) {
|
||||
@@ -585,7 +640,7 @@ static bool compute_event(Context *context, StateConfig state_config,
|
||||
log_info("[%d] Auto Random %s", code,
|
||||
context->auto_random ? "ON" : "OFF");
|
||||
}
|
||||
return true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (code == state_config.key_autorand_down) {
|
||||
@@ -595,7 +650,7 @@ static bool compute_event(Context *context, StateConfig state_config,
|
||||
}
|
||||
log_info("[%d] Auto Random Cycle: %d", code, context->auto_random_cycle);
|
||||
}
|
||||
return true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (code == state_config.key_autorand_up) {
|
||||
@@ -603,7 +658,7 @@ static bool compute_event(Context *context, StateConfig state_config,
|
||||
context->auto_random_cycle += 1;
|
||||
log_info("[%d] Auto Random Cycle: %d", code, context->auto_random_cycle);
|
||||
}
|
||||
return true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (code == state_config.key_tempo_up) {
|
||||
@@ -611,7 +666,7 @@ static bool compute_event(Context *context, StateConfig state_config,
|
||||
tempo_set(&context->tempo, context->tempo.tempo + 1);
|
||||
log_info("[%d] Tempo: %f", code, context->tempo);
|
||||
}
|
||||
return true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (code == state_config.key_tempo_down) {
|
||||
@@ -621,7 +676,7 @@ static bool compute_event(Context *context, StateConfig state_config,
|
||||
}
|
||||
log_info("[%d] Tempo: %f", code, context->tempo.tempo);
|
||||
}
|
||||
return true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
// LOAD STATE
|
||||
@@ -632,7 +687,7 @@ static bool compute_event(Context *context, StateConfig state_config,
|
||||
log_info("[%d] Loading state %d", code, i + 1);
|
||||
load_from_index_file(context, state_config, i + 1);
|
||||
}
|
||||
return true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
// SAVE STATE
|
||||
@@ -643,10 +698,10 @@ static bool compute_event(Context *context, StateConfig state_config,
|
||||
log_info("[%d] Saving state %d", code, i + 1);
|
||||
save_to_index_file(context, state_config, i + 1);
|
||||
}
|
||||
return true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return found;
|
||||
}
|
||||
|
||||
void state_midi_event(Context *context, StateConfig state_config,
|
||||
|
||||
@@ -251,6 +251,7 @@ typedef struct StateConfig {
|
||||
UintArray codes;
|
||||
UintArray fader_codes;
|
||||
UintArray values_offsets;
|
||||
UintArray random_ignored;
|
||||
|
||||
unsigned int value_count;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user