From 2ef75a9665f2a598ec25fb4af497a7f9788d5bfd Mon Sep 17 00:00:00 2001
From: atao
Date: Mon, 24 May 2021 07:12:38 +0200
Subject: [PATCH 1/4] feat: allow playing with extended ascii keys
See issue #26
---
brighton/brightonControllers.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/brighton/brightonControllers.c b/brighton/brightonControllers.c
index 00a8f81..15faaad 100644
--- a/brighton/brightonControllers.c
+++ b/brighton/brightonControllers.c
@@ -112,7 +112,10 @@ static void
brightonMapKeyboard(brightonWindow *bwin, brightonApp *app,
int channel, char *param)
{
- int from, to, chan;
+ // int from, to, chan;
+ unsigned char from;
+ int to, chan;
+
from = param[0];
From 3a01f538812c6ea9c2e636cc792dea9ec3062736 Mon Sep 17 00:00:00 2001
From: atao
Date: Mon, 24 May 2021 07:42:43 +0200
Subject: [PATCH 2/4] feat: allow playing with dead keys
See issue #26
---
brighton/brightonControllers.c | 69 +++++++++++++++++++++++++++-
include/brighton/brightoninternals.h | 15 ++++++
libbrighton/brightonWindowMgt.c | 3 ++
3 files changed, 85 insertions(+), 2 deletions(-)
diff --git a/brighton/brightonControllers.c b/brighton/brightonControllers.c
index 15faaad..ad37128 100644
--- a/brighton/brightonControllers.c
+++ b/brighton/brightonControllers.c
@@ -114,8 +114,7 @@ int channel, char *param)
{
// int from, to, chan;
unsigned char from;
- int to, chan;
-
+ int to, chan, key;
from = param[0];
@@ -138,6 +137,17 @@ int channel, char *param)
bwin->kbdmap[from][KM_CHAN] = chan;
/* printf("Keymap %c to %i on channel %i\n", from, to, chan); */
+ if ((param = index(++param, ' ')) == NULL)
+ {
+ /* printf("Keymap %c to %i on channel %i\n", from, to, chan); */
+ return;
+ }
+
+ key = atoi(++param);
+
+ addInAndOutKeysToKeymapFilter(key, from, bwin->filter);
+ /* printf("Keymap %i (%i) to %i on channel %i with key %i\n",
+ getOutkeyForInkeyFromKeymapFilter(key, bwin->filter), from, to, chan, key); */
}
static void
@@ -955,6 +965,60 @@ brightonControlKeyInput(brightonWindow *cid, int asckey, int on)
* one. For best results we would need to disable key repeat on entering the
* window. FFS.
*/
+
+brightonKeymapFilter*
+brightonCreateKeymapFilter()
+{
+ brightonKeymapFilter* filter = malloc(sizeof(brightonKeymapFilter));
+ filter->keyin = NULL;
+ filter->keyout = NULL;
+ filter->size = 0;
+ return filter;
+}
+
+int
+addInAndOutKeysToKeymapFilter(BRIGHTON_MAP_BASE_TYPE in, BRIGHTON_MAP_BASE_TYPE out, brightonKeymapFilter* filter)
+{
+ if (!filter) return BRIGHTON_INVALID_KEYMAP_FILTER;
+ if (in < 0) return BRIGHTON_INVALID_INPUT_KEY;
+ if (out < 0) return BRIGHTON_INVALID_OUTPUT_KEY;
+
+ filter->size++;
+ filter->keyin = realloc(filter->keyin, (filter->size) * sizeof(in));
+ filter->keyout = realloc(filter->keyout, (filter->size) * sizeof(out));
+ filter->keyin[filter->size - 1] = in;
+ filter->keyout[filter->size - 1] = out;
+ return filter->size;
+}
+
+BRIGHTON_MAP_BASE_TYPE
+getOutkeyForInkeyFromKeymapFilter(BRIGHTON_MAP_BASE_TYPE in, brightonKeymapFilter* filter)
+{
+ if (!filter || filter->size == 0) return in;
+
+ int i;
+ for (i = 0; i < filter->size; i++)
+ {
+ if (filter->keyin[i] == in) return filter->keyout[i];
+ }
+ return in;
+}
+
+void*
+deleteKeymapFilter(brightonKeymapFilter* filter)
+{
+ free(filter->keyin);
+ free(filter->keyout);
+ free(filter);
+ return NULL;
+}
+
+void*
+brightonFreeKeymapFilter(brightonWindow * bwin)
+{
+ return deleteKeymapFilter(bwin->filter);
+}
+
void
brightonKeyInput(brightonWindow *cid, int asckey, int on)
{
@@ -964,6 +1028,7 @@ brightonKeyInput(brightonWindow *cid, int asckey, int on)
event.type = BRIGHTON_FLOAT;
event.value = 1.0;
+ asckey = getOutkeyForInkeyFromKeymapFilter(asckey, cid->filter);
if ((asckey < 0) || (asckey > 255))
return;
diff --git a/include/brighton/brightoninternals.h b/include/brighton/brightoninternals.h
index 2e02ded..4dca32d 100644
--- a/include/brighton/brightoninternals.h
+++ b/include/brighton/brightoninternals.h
@@ -192,6 +192,17 @@ typedef struct BrightonNRPcontrol {
#define BRIGHTON_NRP_COUNT 128
#define BRIGHTON_GANG_COUNT 8
+#define BRIGHTON_MAP_BASE_TYPE int
+#define BRIGHTON_INVALID_KEYMAP_FILTER -1
+#define BRIGHTON_INVALID_INPUT_KEY -2
+#define BRIGHTON_INVALID_OUTPUT_KEY -3
+typedef struct BrightonKeymapFilter
+{
+ BRIGHTON_MAP_BASE_TYPE* keyin;
+ BRIGHTON_MAP_BASE_TYPE* keyout;
+ int size;
+} brightonKeymapFilter;
+
typedef struct BrightonWindow {
unsigned int flags;
struct BrightonWindow *next, *last;
@@ -247,6 +258,7 @@ typedef struct BrightonWindow {
/* CC value mapping tables */
u_char valuemap[128][128];
int kbdmap[256][2];
+ brightonKeymapFilter* filter;
int dcTimeout;
} brightonWindow;
@@ -369,5 +381,8 @@ extern void brightonfree(void *);
extern void brightonRegisterController(brightonDevice *);
+extern void* brightonFreeKeymapFilter(brightonWindow *);
+extern brightonKeymapFilter* brightonCreateKeymapFilter();
+
#endif /* BRIGHTONINTERNALS_H */
diff --git a/libbrighton/brightonWindowMgt.c b/libbrighton/brightonWindowMgt.c
index 345d35d..3024d5c 100644
--- a/libbrighton/brightonWindowMgt.c
+++ b/libbrighton/brightonWindowMgt.c
@@ -98,6 +98,8 @@ int cmapsize, int flags, int quality, int gs, int x, int y)
bwin->next = winlist;
winlist = bwin;
+ bwin->filter = brightonCreateKeymapFilter();
+
/*
* Force a fake size to ensure the first configure notify is picked up.
*/
@@ -145,6 +147,7 @@ brightonDestroyWindow(brightonWindow *bwin)
bwin->bitmaps->name);
bwin->flags = 0;
+ brightonFreeKeymapFilter(bwin);
brightonfree(bwin);
}
From 528cd7e25b5bf87ed4e9a7125a2d8e95f168d2ab Mon Sep 17 00:00:00 2001
From: atao
Date: Mon, 24 May 2021 12:32:50 +0200
Subject: [PATCH 3/4] feat: script to get french azerty keyboard profile
Specify the device name (amongst files under /usr/local/share/bristol/memory/profiles)
with env var PROFILE_FILE_NAME ('mini' by default)
The key mapping format is changed and now is:
KM: Extended_ASCII MIDI_note [MIDI_chan [key_code]]
If the changes are made with an editor, the file must be
saved with any ISO 8859 encoding scheme.
Nothing is changed for usual keys.
For a dead key:
- Extended_ASCII is any arbitrary character not present on the keyboard
- key_code is the code returned by the keyboard on hitting the dead key
See issue #26
---
tools/azerty4bristol.sh | 54 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
create mode 100755 tools/azerty4bristol.sh
diff --git a/tools/azerty4bristol.sh b/tools/azerty4bristol.sh
new file mode 100755
index 0000000..11f4094
--- /dev/null
+++ b/tools/azerty4bristol.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+# azerty4bristol.sh
+#
+# Run:
+# [PROFILE_FILE_NAME=] [PROFILE_SRC_DIR=] azerty4bristol.sh
+#
+# By default:
+# - PROFILE_FILE_NAME: mini
+# - PROFILE_SRC_DIR: /usr/local/share/bristol/memory/profiles/ (i.e. default bristol manual installation, see HOWTO § 2.5)
+#
+# If needed, launch this script as sudoer.
+# In any case, owner and group will be set up as current user.
+
+pushd ~/.bristol/memory/profiles/
+
+if [ "$PROFILE_FILE_NAME" = "" ]
+then
+ PROFILE_FILE_NAME="mini"
+fi
+echo "Azerty profile for emulator: $PROFILE_FILE_NAME"
+
+if [ "$PROFILE_SRC_DIR" = "" ]
+then
+ PROFILE_SRC_DIR="/usr/local/share/bristol/memory/profiles/"
+fi
+echo "New profile based on: $PROFILE_SRC_DIR/$PROFILE_FILE_NAME"
+
+[ -e "$PROFILE_FILE_NAME" ] && mv "$PROFILE_FILE_NAME" "${PROFILE_FILE_NAME}.$(date --utc +%Y%m%d_%H%M%SZ)" || true
+
+install -C -o $USER -g $USER "$PROFILE_SRC_DIR/$PROFILE_FILE_NAME" .
+
+sed -i 's/\(^# Keyboard map format is "KM: \)\(.*MIDI_chan\)\(.*$\)/\1Extended_\2 [key_code]\3/' "$PROFILE_FILE_NAME"
+
+sed -i -e '0,/^KM: / {/^KM: /i\KM: * 19 1' -e'}' "$PROFILE_FILE_NAME"
+sed -i -e '0,/^KM: / {/^KM: /i\KM: < 0 1' -e'}' "$PROFILE_FILE_NAME"
+sed -i -e '0,/^KM: / {/^KM: /i\KM: & 23 0' -e'}' "$PROFILE_FILE_NAME"
+
+sed -i -e 's/\(^KM: \)0/\1à/' -e 's/\(^KM: \)2/\1é/' -e 's/\(^KM: \)3/\1"/' "$PROFILE_FILE_NAME"
+sed -i -e 's/\(^KM: \)5/\1(/' -e 's/\(^KM: \)6/\1-/' -e 's/\(^KM: \)7/\1è/' "$PROFILE_FILE_NAME"
+sed -i 's/\(^KM: \)9/\1ç/' "$PROFILE_FILE_NAME"
+
+sed -i 's/\(^KM: \)\[\(.*\)$/\1Æ\2 65106/' "$PROFILE_FILE_NAME"
+sed -i 's/\(^KM: \)\]/\1$/' "$PROFILE_FILE_NAME"
+
+sed -i -e '/^KM:/ s/q/\[q\]/' -e '/^KM:/ s/a/q/' -e '/^KM:/ s/\[q\]/a/' "$PROFILE_FILE_NAME"
+sed -i -e '/^KM:/ s/z/\[z\]/' -e '/^KM:/ s/w/z/' -e '/^KM:/ s/\[z\]/w/' "$PROFILE_FILE_NAME"
+sed -i -e '/^KM:/ s/m/\[m\]/' -e '/^KM:/ s/,/\[,\]/' "$PROFILE_FILE_NAME"
+sed -i -e '/^KM:/ s/\[m\]/,/' -e '/^KM:/ s/\[,\]/;/' "$PROFILE_FILE_NAME"
+sed -i -e '/^KM:/ s|/|!|' -e '/^KM:/ s/\./:/' -e "/^KM:/ s/'/ù/" "$PROFILE_FILE_NAME"
+
+iconv -f UTF8 -t ISO_8859-1 -o "$PROFILE_FILE_NAME" "$PROFILE_FILE_NAME"
+
+popd
From 63f57614d80a433f2951b62fb13b3a5a9550e2b3 Mon Sep 17 00:00:00 2001
From: atao
Date: Mon, 24 May 2021 12:33:09 +0200
Subject: [PATCH 4/4] doc: add howto customize emulator profile
See issue #26
---
HOWTO | 61 +++++++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 47 insertions(+), 14 deletions(-)
diff --git a/HOWTO b/HOWTO
index 37ffeab..61a50aa 100644
--- a/HOWTO
+++ b/HOWTO
@@ -135,7 +135,7 @@ sudo make install
This step need to be run as root as, unless you have been very selective with
the ./configure options then parts of bristol will be written to parts of the
/usr filesystem which is typically read-only for user accounts. By default this
-should install bristol and associated apps to /usr/local/ with data commponets
+should install bristol and associated apps to /usr/local/ with data components
into /usr/local/share. To run the application you should now be able to use the
startBristol script however that does depend on /usr/local/bin being in your
path.
@@ -201,11 +201,11 @@ Many more options, along with the full list of synths can be found by doing
4. ALSA Interface Configuration
To see the MIDI connections that can be built you need to look at aconnect
-commmand:
+command:
aconnect -io
-Here is a sammple of its output:
+Here is a sample of its output:
client 0: 'System' [type=kernel]
0 'Timer '
@@ -263,7 +263,7 @@ audio and midi.
5.1 Using qjackctl
-Using qjackctl you can easily connect midi controlloers by clicking on either
+Using qjackctl you can easily connect midi controllers by clicking on either
the 'Midi' tab or 'Alsa' tab, depending on which midi driver you've selected to
use with bristol and then clicking the controller you want on the left pane and
the 'Bristol' input on the right and clicking 'connect'.
@@ -279,7 +279,7 @@ work in a specific environment gives it flexibility but also makes it sometimes
difficult to use. To quote one person, "It can be an inspiration killer".
There are a few third party apps such as monoBristol that provide graphical
-front ends to the commandline options to make starting bristol easier. Bristol
+front ends to the command line options to make starting bristol easier. Bristol
itself supports a runcom file where a user can specify common preferred params
that are then included with every invocation.
@@ -302,7 +302,7 @@ or
-jack -jackstats -count 256 -rate 48000
Both of these will have the same affect as they are all summed together. If
-bristol is started as 'startBristol -mini' then the actual commmandline will be
+bristol is started as 'startBristol -mini' then the actual command line will be
startBristol -jack -jackstats -count 256 -rate 48000 -mini
@@ -370,15 +370,17 @@ cutoff/resonance, etc.
8.1 Keyboard Mappings.
-Bristol supports GUI shortcuts and playing the synths via a QWERTY keyboard.
-Playing bristol via the QWERTY on the B3 has C2 starting on '\' and going up
+Bristol supports GUI shortcuts and playing the synths with any keyboard. A set of
+emulator profile files is provided by default for QWERTY keyboards.
+
+For alternative keyboards such as AZERTY ones, it is necessary to customize the
+emulator profile files (see § 8.3 below).
+
+Playing bristol with a QWERTY keyboard on the B3 has C2 starting on '\' and going up
to F3 on '/' on the bottom manual, while the top manual goes from C4 on Q to
G5 on ']'. On a single keyboard synth, such as the polysix, C1 starts on '\'
and goes up F2 on '/' and C3 starts on Q and ends at G4 on ']'.
-For alternative mappings such as AZERTY it is necessary to manually edit the
-emulator profile files.
-
8.2 Keyboard Accelerators
Useful shortcuts are:
@@ -395,7 +397,38 @@ Arrow keys can control pot/slider movement with Shift being an accelerator.
The GUI devices also support VI style j/k up/down with Shift and Control
options.
+ 8.3 Customizing profile
+
+Any keyboard can be used, e.g. AZERTY. But only QWERTY emulator profile files are provided by default.
+
+A bash script is provided to generate french AZERTY emulator profile files. Run:
+
+ [PROFILE_FILE_NAME=] [PROFILE_SRC_DIR=] azerty4bristol.sh
+
+The result may not be what you expected. Tune the map with a text editor.
+
+By default:
+- PROFILE_FILE_NAME: mini,
+- PROFILE_SRC_DIR: /usr/local/share/bristol/memory/profiles/ (i.e. default bristol manual installation, see § 2.5 above).
+
+Any key can be used to map a note, even dead keys (e.g. the key "^" between "p" and "$" on
+a french azerty keyboard is one of them...) or extended ascii keys.
+
+The format of key mapping entries is:
+ KM: Extended_ASCII MIDI_note [MIDI_chan [key_code]]
+
+To map a dead key, you have to provide:
+- Extended_ASCII: an arbitrary extended ASCII code not used on the keyboard or with another dead key,
+- key_code: the key code returned by the keyboard on hitting the dead key.
+
+If any extended ascii character is used then the profile file must be coded in some ISO 8859 encoding scheme(°)
+to keep such a character on one byte(°°).
+
+If the changes are made with an editor, the profile file must be saved with some ISO 8859 encoding scheme(°).
+
+Note. (°) To avoid any surprise, stay with ISO 8859-1.
+Note. (°°) At the moment, bristol doesn't manage characters with C type wchar_t, then is unable to deal with UTF-8.
9. Basics of Subtractive Synthesis.
@@ -431,8 +464,8 @@ Low Pass Filter
High Pass
Band Reject
-Low Pass filters remove high frequencies (i.e they pass low freqencies).
-High Pass filters remove low freqencies
+Low Pass filters remove high frequencies (i.e they pass low frequencies).
+High Pass filters remove low frequencies
Band Reject filters remove both low and high filters in a specific range and
allow a certain 'mid-range' of frequencies through.
@@ -443,7 +476,7 @@ Frequency Resonance.
Frequency Cutoff allows you to control how much of the sound gets filtered.
Resonance amplifies the narrow band of frequencies that are close to the cutoff point.
- 9.3.Low Frequency Oscillators (LFOs)
+ 9.3. Low Frequency Oscillators (LFOs)
LFOs are exactly like normal oscillators (they have waveforms, like sine,
square and triangle), but they sound below what a human can hear. In this way,