S
SynthGate
Hyperfocused Brizzel and Tzwitscher (TM)
Bis dahin habe ich die Bedienung intus und eine lange Liste an Vorschlägen fertig. ^^Vorerst eine Final Version, im Mai geht es dann weiter...
Viel Spaß wo auch immer.
Folge dem Video um zu sehen, wie unsere Website als Web-App auf dem Startbildschirm installiert werden kann.
Anmerkung: This feature may not be available in some browsers.
Bis dahin habe ich die Bedienung intus und eine lange Liste an Vorschlägen fertig. ^^Vorerst eine Final Version, im Mai geht es dann weiter...
Das ist schon wichtig - denn es ist eine Stärke - du kannst auch sehr lange Takte spielen und anpassen - der MT lässt dir nie das Gefühl, dass was nicht geht wegen Länge.Schönen Guten Abend
one more thing
-----------------
Wenn ich so im Manual lese "liest" es sich sehr danach an als wäre das gerät besonders gut dafür kurze loops aufzunehmen und abzuspielen.
Was würde passieren wenn man laaaaaange loops bzw ganze stücke einspielt?
Bitte entschuldigt meine anfängerfragen. bin leider was sequencer angeht unerfahren.
…sind Dir die Gehäuse ausgegangen? - brauchst Du noch welche?…
Viel Spaß wo auch immer.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SEQSIZE 16 /*Pattern Length*/
char* init_Array(char* d, const char* s) {
char* tmp = d;
while (*s) {
*d++ = *s++;
}
*d = '\0';
return tmp;
}
char* append_Array(char* d, const char* s) {
while (*d) {
++d;
}
while (*s) {
*d++ = *s++;
}
*d = '\0';
return d;
}
void euclid(int d[], const int size, const int value) {
char** tmp = (char**)malloc(size * sizeof(char*));
for (int i = 0; i < size; ++i) {
tmp[i] = (char*)malloc((size + 1) * sizeof(char));
}
int z = size;
int p = size;
int t = size;
int s = value;
(p < s) ? (p = s, s = t) : 0;
t = p - s;
for (int i = 0; i < size; ++i) {
(i < s) ? init_Array(tmp[i], "X") : init_Array(tmp[i], "-");
}
while (t > 1) {
(z > 0) ? z-- : 0;
if (t < s) {
p = s;
s = t;
}
else {
p = t;
}
t = p - s;
for (int i = 0; i < s; ++i) {
append_Array(tmp[i], tmp[z - i]);
}
z = p;
}
int n = 0;
for (int i = 0; i < z; ++i) {
int j = 0;
while (tmp[i][j] != '\0') {
d[n++] = (tmp[i][j] == 'X') ? 1 : 0;
++j;
}
}
for (int i = 0; i < size; ++i) {
free(tmp[i]);
}
free(tmp);
}
void shift(int d[], const int size, int shift_Value) {
if (!shift_Value) {
return;
}
(shift_Value < 0) ? (shift_Value += size) : 0;
int* tmp = (int*)malloc(size * sizeof(int));
for (int i = 0; i < size; ++i) {
tmp[(i + shift_Value) % size] = d[i];
}
for (int i = 0; i < size; ++i) {
d[i] = tmp[i];
}
free(tmp);
}
void cmp(int d[], const int s[], const int size, const int bool_operator) {
for (int i = 0; i < size; ++i) {
switch (bool_operator) {
case 0:
d[i] &= s[i];
d[i] = !d[i];
break;
case 1:
d[i] &= s[i];
break;
case 2:
d[i] |= s[i];
break;
case 3:
d[i] ^= s[i];
break;
default:
break;
}
}
}
void print_Seq(const int arr[], const int size) {
for (int i = 0; i < size; ++i) {
if (arr[i] == 1) {
printf(" X ");
}
else {
printf(" - ");
}
}
}
int main() {
/*set random Values*/
srand(time(NULL));
int rnd_STEPS_A = rand() % (SEQSIZE - 1) + 1;
int rnd_STEPS_B = rand() % (SEQSIZE - 1) + 1;
int rnd_SHIFT_A = rand() % (2 * SEQSIZE - 2) - (SEQSIZE-1);
int rnd_SHIFT_B = rand() % (2 * SEQSIZE - 2) - (SEQSIZE-1);
int rnd_SHIFT_C = rand() % (2 * SEQSIZE - 2) - (SEQSIZE-1);
int rnd_CMP_OPERATOR = rand() % 4;
char op[4];
if (rnd_CMP_OPERATOR == 0) init_Array(op,"NOT");
else if (rnd_CMP_OPERATOR == 1) init_Array(op, "AND");
else if (rnd_CMP_OPERATOR == 2) init_Array(op, "OR");
else init_Array(op, "XOR");
/*print Counter*/
for (int i = 0; i < SEQSIZE; ++i) {
printf("%02i|", i + 1);
}
printf(" | Counter\n");
for (int i = 0; i < SEQSIZE; ++i) {
printf("---");
}
printf("\n");
/*init euclidian Sequence*/
int a[SEQSIZE], b[SEQSIZE];
euclid(a, SEQSIZE, rnd_STEPS_A);
euclid(b, SEQSIZE, rnd_STEPS_B);
/*print Seq_A*/
print_Seq(a, SEQSIZE);
printf(" | Seq_A -> %i von %i\n", rnd_STEPS_A, SEQSIZE);
/*shift Seq_A*/
shift(a, SEQSIZE, rnd_SHIFT_A);
/*print shifted Seq_A*/
print_Seq(a, SEQSIZE);
printf(" | Seq_A shift -> %i\n", rnd_SHIFT_A);
printf("\n");
/*print Seq_B*/
print_Seq(b, SEQSIZE);
printf(" | Seq_B -> %i von %i\n", rnd_STEPS_B, SEQSIZE);
/*shift Seq_B*/
shift(b, SEQSIZE, rnd_SHIFT_B);
/*print shifted Seq_B*/
print_Seq(b, SEQSIZE);
printf(" | Seq_B shift -> %i\n", rnd_SHIFT_B);
printf("\n");
/*print Seq_A / Seq_B*/
print_Seq(a, SEQSIZE);
printf(" | Seq_A\n");
print_Seq(b, SEQSIZE);
printf(" | Seq_B\n");
/*compare Seq_A / Seq_B*/
cmp(a, b, SEQSIZE, rnd_CMP_OPERATOR);
/*print Result*/
for (int i = 0; i < SEQSIZE; ++i) {
printf("---");
}
printf("\n");
print_Seq(a, SEQSIZE);
printf(" | cmp Seq_A %s Seq_B\n\n",op);
/*shift Result*/
shift(a, SEQSIZE, rnd_SHIFT_C);
/*print Pattern*/
print_Seq(a, SEQSIZE);
printf(" | Seq_C shift -> %i\n", rnd_SHIFT_C);
for (int i = 0; i < SEQSIZE; ++i) {
printf("===");
}
printf("\n");
return 0;
}
01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16| | Counter
------------------------------------------------
X - - - - - - - - - - - - - - - | Seq_A -> 1 von 16
- - - - X - - - - - - - - - - - | Seq_A shift -> 4
X - X X - X - X X - X X - X - X | Seq_B -> 10 von 16
- X - X X - X X - X - X X - X X | Seq_B shift -> -12
- - - - X - - - - - - - - - - - | Seq_A
- X - X X - X X - X - X X - X X | Seq_B
------------------------------------------------
- X - X - - X X - X - X X - X X | cmp Seq_A XOR Seq_B
X X - X X - X - X - - X X - X - | Seq_C shift -> -11
================================================
** Process exited - Return Code: 0 **
esptool.py --chip esp32 --port /dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0 --baud 460800 --before default_reset --after hard_reset write_flash 0x0 ./MidiTraC.bin
________________ ________________
|Ch: 12 Oct: 3+12| |EuclidSteps: 032|
|RootScale: D-maj| |SeqA: 012 S: 011|
|GTR: 1/16 1/4| |SeqB: 004 S: -10|
|M/P: P Rytm: RND| |A><B: XOR S: 000|
|////////////////| |////////////////|
Sind denn überhaupt noch Geräte verfügbar?
nee, leider nicht..
Wäre es ggf. eine Überlegung wert, für den miditrac eine Bauanleitung, vglb. mit dem MicroDexed?
wie oben erwähnt, theoretisch funktioniert Bluetooth Midi bzw. USB in Verbindung mit Hairless. Unter Verwendung von entsprechenden Bibliotheken, habe ich das schon zum Laufen bekommen. Ich kenne mich aber mit den Protokollen nicht gut genug aus, um das selber zu implementieren...5-pol-din-midi-welt
Jedes Event trägt zusätzlich die Information, nach wieviel Takten es erneut abgespielt werden soll. Dadurch spart man bei Loop basierten Mustern sehr viel Speicherplatz (für einige Bearbeitungsoptionen, wie Transpose Record, Schneiden und Verketten, muss bzw. wird das Pattern konsolidiert). Grundsätzlich ist es egal, wo das Event im Array landet, da jedes Event eine eigene Start und Gate Time Informationen beinhaltet. Schnelle Sortier- und Suchalgorithmen sorgen dafür, dass nicht allzu viel iteriert werden muss beim Abspielen. Doppelt eingespielte Noten, z.B. beim Overdub, werden automatisch erkannt und entfernt. So kann man auf einer existierenden Achtel Hihat Spur einfach mit einem 1/32 oder 1/64 Arpeggiator drüber fahren ohne das die bereits gesetzten Event überfahren werden.das konzept mit den wiederholungen mittels attributen finde ich gut!
ich frage mich noch, wie das mit dem array und den overdubs funktioniert, wie
kommen die events da "an die richtige stelle"?
Das Stimmt, daher besteht die Möglichkeit auch CC# Daten bei Bedarf quantisiert bzw. ausgedünnt aufzunehmen. Insgesamt kann hier aber noch einiges optimiert werden. Besonders Aftertouch bereitet noch Probleme...fuer grosse cc- und pitchbend-orgien sind 1024 events natuerlich schon knapp,
fuer noten wuerde mir das locker reichen.
bluetooth? nee, dann doch lieber 5 pol. haette ja auch noch einige solcher klangerzeuger...wie oben erwähnt, theoretisch funktioniert Bluetooth Midi bzw. USB in Verbindung mit Hairless.
Schnelle Sortier- und Suchalgorithmen sorgen dafür, dass nicht allzu viel iteriert werden muss beim Abspielen.
Das sollte gehen in Abhängigkeit von der maximalen Auflösung & Geschwindigkeit, die unterstützt werden soll. Aktuell läuft der MidiTraC mit 192 Tics pro Takt, 384 Tics funktionieren auch noch problemlos < 250 BPM, also ist noch ein bisschen Luft nach oben. Die Hardware ist eher begrenzt durch den verfügbaren RAM.ok, so kann ich mir das vorstellen. wuerde das denn mit groesseren patterngroessen (auf einer andern mcu etwa)
skalieren?