Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 47 additions & 14 deletions HOWTO
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 '
Expand Down Expand Up @@ -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'.
Expand All @@ -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.

Expand All @@ -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

Expand Down Expand Up @@ -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:
Expand All @@ -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=<emulator name>] [PROFILE_SRC_DIR=<qwerty emulator file directory>] 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.

Expand Down Expand Up @@ -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.

Expand All @@ -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,
Expand Down
70 changes: 69 additions & 1 deletion brighton/brightonControllers.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ 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, key;

from = param[0];

Expand All @@ -135,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
Expand Down Expand Up @@ -952,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)
{
Expand All @@ -961,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;

Expand Down
15 changes: 15 additions & 0 deletions include/brighton/brightoninternals.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -369,5 +381,8 @@ extern void brightonfree(void *);

extern void brightonRegisterController(brightonDevice *);

extern void* brightonFreeKeymapFilter(brightonWindow *);
extern brightonKeymapFilter* brightonCreateKeymapFilter();

#endif /* BRIGHTONINTERNALS_H */

3 changes: 3 additions & 0 deletions libbrighton/brightonWindowMgt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -145,6 +147,7 @@ brightonDestroyWindow(brightonWindow *bwin)
bwin->bitmaps->name);

bwin->flags = 0;
brightonFreeKeymapFilter(bwin);
brightonfree(bwin);
}

54 changes: 54 additions & 0 deletions tools/azerty4bristol.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/bin/bash

# azerty4bristol.sh
#
# Run:
# [PROFILE_FILE_NAME=<emulator name>] [PROFILE_SRC_DIR=<qwerty emulator file directory>] 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