Skip to content

Commit

Permalink
Merge pull request #78 from subvertnormality/1.1.3
Browse files Browse the repository at this point in the history
1.1.3
  • Loading branch information
subvertnormality authored Dec 30, 2024
2 parents 36c4dff + a317edb commit 2359b72
Show file tree
Hide file tree
Showing 11 changed files with 1,092 additions and 162 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 1.1.3

- Added mute_root_note trig param to silence the root note of chords while allowing other chord notes to play.
- Added global option to fully quantize note masks (quantiser_fully_act_on_note_masks) to make note masks follow scale degree and rotation changes.
- Added fully_quantise_mask trig param to control whether note masks are fully quantised to the current scale, including scale degree and rotation on a per-channel or per-step basis.


## 1.1.2

- Chord masks now follow the root note after random note shifts have been applied.
Expand Down
38 changes: 25 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@


<svg display="none" fill="#000000" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
xml:space="preserve" width="25px" height="25px" viewbox="0 0 500 500">
<symbol id="video-icon">
Expand Down Expand Up @@ -100,6 +98,8 @@ Welcome to _Mosaic_, a powerful rhythm- and harmony-focused sequencer designed t
+ [Chord Spread](#chord-spread)
+ [Chord Velocity Modifier](#chord-velocity-modifier)
+ [Chord Shape Modifier](#chord-shape-modifier)
+ [Mute Root Note](#mute-root-note)
+ [Fully Quantise Mask](#fully-quantise-mask)
* [Scale Editor](#scale-editor)
+ [Transposition](#transposition)
* [Song Editor](#song-editor)
Expand Down Expand Up @@ -168,7 +168,7 @@ For those using an ACL Sinfonion, support is available through a straightforward

Mosaic includes a range of stock midi devices that you can integrate into your setup. Elektron Digitone, Digitakt 2, Syntakt, and the Nord Drum 2 are first class citizens with fully tailored mappings.

First, they need to be configured to appear in the device selector. Heres how to set this up using [maiden](https://monome.org/docs/norns/maiden/):
First, they need to be configured to appear in the device selector. Here's how to set this up using [maiden](https://monome.org/docs/norns/maiden/):

1. **Access Configuration Files**: Open Maiden and navigate to the directory path `code > mosaic > lib > config`. Here, you will find the stock device configuration files.
2. **Create a New Configuration Folder**: Next, go to the directory `data > mosaic`. In this location, create a new folder named `config`.
Expand All @@ -181,7 +181,7 @@ This allows you to easily access and use only your preferred devices within Mosa

Once you've copied the stock device configuration files into the `data > mosaic > config` folder, you can also personalize these configurations to better suit your setup. This is particularly useful for setting common defaults like the MIDI output device.

You can customize Mosaic to perfectly align with your studio setup by configuring it to work seamlessly with your specific devices. If your device is not included in the standard configuration, create a .json file named after your device in the `dust > mosaic > config` folder. Populate this file using a config file customised to match your devices MIDI specifications. You can create, load and edit midi device config files using the [Mosaic Config Creator](https://subvertnormality.github.io/mosaic/config_creator.html).
You can customize Mosaic to perfectly align with your studio setup by configuring it to work seamlessly with your specific devices. If your device is not included in the standard configuration, create a .json file named after your device in the `dust > mosaic > config` folder. Populate this file using a config file customised to match your device's MIDI specifications. You can create, load and edit midi device config files using the [Mosaic Config Creator](https://subvertnormality.github.io/mosaic/config_creator.html).

##### Mods and Software Devices

Expand Down Expand Up @@ -387,7 +387,7 @@ Trigs are added in the pattern editor. Using the top row, pick one of the 16 ava

<img alt="Pattern editor pattern select buttons" src="https://raw.githubusercontent.com/subvertnormality/mosaic/refs/heads/main/images/Grid/pattern_editor/trig_editor/pattern-select-buttons.svg" width="300" />

To set your rhythm, simply tap in steps using the sequencer. Bright steps symbolize a trig. To define its length, press and hold a trig, then choose its ending step. Steps with a subtle glow show the length. In a single pattern, one trigs duration ends upon meeting another.
To set your rhythm, simply tap in steps using the sequencer. Bright steps symbolize a trig. To define its length, press and hold a trig, then choose its ending step. Steps with a subtle glow show the length. In a single pattern, one trig's duration ends upon meeting another.

<img alt="Pattern editor step edit buttons" src="https://raw.githubusercontent.com/subvertnormality/mosaic/refs/heads/main/images/Grid/pattern_editor/trig_editor/pattern-step-trigger-edit-buttons.svg" width="300" />

Expand All @@ -414,11 +414,11 @@ The rightmost fader typically toggles between different banks in the selected al

<img alt="Pattern editor bank select buttons" src="https://raw.githubusercontent.com/subvertnormality/mosaic/refs/heads/main/images/Grid/pattern_editor/trig_editor/bank-select-buttons.svg" width="300" />

To see your algorithm's impact, hit the prime button. This primes the currently selected algorithm's pattern. Potential new steps are shown as flashing bright steps on the sequencer. While these steps flash, they arent painted yet. Any step that would be painted over an existing active step will blink dimly. By painting the new pattern, you'll deactivate the faintly blinking steps. This approach lets you craft intricate sequences, grounded in rhythmic fundamentals, that don't get too busy. You can modify algorithm parameters while the pattern is primed.
To see your algorithm's impact, hit the prime button. This primes the currently selected algorithm's pattern. Potential new steps are shown as flashing bright steps on the sequencer. While these steps flash, they aren't painted yet. Any step that would be painted over an existing active step will blink dimly. By painting the new pattern, you'll deactivate the faintly blinking steps. This approach lets you craft intricate sequences, grounded in rhythmic fundamentals, that don't get too busy. You can modify algorithm parameters while the pattern is primed.

<img alt="Pattern editor prime and paint button" src="https://raw.githubusercontent.com/subvertnormality/mosaic/refs/heads/main/images/Grid/pattern_editor/trig_editor/arm-paint-button.svg" width="300" />

If you havent painted the new pattern, the prime button continues to blink. Pressing it again paints your edits. Pressing the prime button again without tweaking the algorithm or its parameters effectively acts as an undo for the last action.
If you haven't painted the new pattern, the prime button continues to blink. Pressing it again paints your edits. Pressing the prime button again without tweaking the algorithm or its parameters effectively acts as an undo for the last action.

Opt out of a prepared pattern by using the cancel button:

Expand Down Expand Up @@ -547,7 +547,7 @@ MIDI devices can be configured to load a stored patch through the Norns' params

#### Adding Patterns to Channels

The core of your rhythm and harmony sections are formed by adding patterns to channels. To do this, first select a channel using the channel buttons. A single channel can accommodate multiple patterns, and likewise, a single pattern can be assigned to multiple channels. To assign patterns, use the pattern select row, located second from the top on Mosaics Grid UI.
The core of your rhythm and harmony sections are formed by adding patterns to channels. To do this, first select a channel using the channel buttons. A single channel can accommodate multiple patterns, and likewise, a single pattern can be assigned to multiple channels. To assign patterns, use the pattern select row, located second from the top on Mosaic's Grid UI.

<img alt="Channel editor pattern assign buttons" src="https://raw.githubusercontent.com/subvertnormality/mosaic/refs/heads/main/images/Grid/channel_editor/pattern-assign-buttons.svg" width="300" />

Expand Down Expand Up @@ -650,7 +650,7 @@ These settings affect how velocity values are calculated for overlapping steps:
* **Average**: The velocity is the average of the velocities from overlapping steps in each pattern.
* **Higher**: The velocity is calculated by taking the average of each step's velocity, subtracting the lowest velocity, and adding the highest velocity.
* **Lower**: The velocity is calculated by taking the average of each step's velocity, subtracting the lowest velocity, and not adding the highest value back.
* **Pattern**: To use a specific patterns velocity values, hold the velocity merge button and press the pattern's select button.
* **Pattern**: To use a specific pattern's velocity values, hold the velocity merge button and press the pattern's select button.

<img alt="Channel editor velocity merge mode button" src="https://raw.githubusercontent.com/subvertnormality/mosaic/refs/heads/main/images/Grid/channel_editor/velocity-length-merge-mode-select-button.svg" width="300" />

Expand All @@ -661,7 +661,7 @@ These modes dictate how the duration of notes is calculated for overlapping step
* **Average**: The length is the average of the lengths from overlapping steps in each pattern.
* **Longer**: The length is determined by taking the average length, subtracting the shortest length, and adding the longest length.
* **Shorter**: The length is calculated by subtracting the shortest length from the average of each step's length minus the shortest length.
* **Pattern**: To apply a specific patterns length values, hold the length merge button and press the pattern's select button.
* **Pattern**: To apply a specific pattern's length values, hold the length merge button and press the pattern's select button.

Length merge modes are set by holding shift (K1) and pressing the velocity merge mode button.

Expand Down Expand Up @@ -809,6 +809,14 @@ The Chord Velocity Modifier incrementally adjusts the velocity of successive not

The Chord Shape Modifiers alters the order of the chord masks that are played using the Chord Strum and Chord Arpeggio params.

##### Mute Root Note

The Mute Root Note param allows you to silence the root note of a chord while allowing other chord notes to play. When enabled, any chord played on that step will omit its root note while still playing all other chord notes. This can be used to create more varied chord voicings and inversions.

##### Fully Quantise Mask

The Fully Quantise Mask param controls whether note masks on a step are fully quantized to the current scale, including scale degree and rotation adjustments. When enabled, note masks will be quantized to match the current scale's settings exactly. This can be used to override the global quantization settings on a per-channel or per-step basis, allowing for more precise control over how note masks interact with scale changes.

### Scale Editor

Access the scale editor by pressing the second global menu button.
Expand Down Expand Up @@ -1023,7 +1031,7 @@ To ensure the longevity of your work, it's important to save your creations into

### Options

Various aspects of Mosaic can be configured from the param section on your Norns, under the Mosaic section. This flexibility allows you to tailor the sequencers behavior to match your creative needs.
Various aspects of Mosaic can be configured from the param section on your Norns, under the Mosaic section. This flexibility allows you to tailor the sequencer's behavior to match your creative needs.

#### Sequencer Options

Expand Down Expand Up @@ -1063,9 +1071,13 @@ The "Elektron program change channel" setting determines which MIDI channel to s

#### Quantizer Options

##### Quantize Note Masks
##### Snap Note Masks to Scale

"Snap Note Masks to Scale" is also on by default. With this setting enabled, note masks snap to the currently selected scale, but are not altered by scale degree or rotation adjustments.

##### Quantise Note Masks

"Quantize note masks" is also on by default. With this setting enabled, note masks snap to the currently selected scale, but are not altered by scale degree or rotation adjustments.
"Quantise Note Masks" is off by default. With this setting enabled, all note masks are quantised to the currently selected scale and are altered by scale degree or rotation adjustments.

##### Scales Lock Until Pattern End

Expand Down
31 changes: 30 additions & 1 deletion lib/devices/device_map.lua
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,36 @@ local stock_params = {
"<-->"
},
["param_type"] = "stock"
}
},
{
["id"] = "mute_root_note",
["name"] = "Mute Chord Root",
["short_descriptor_1"] = "CHRD",
["short_descriptor_2"] = "1NMT",
["off_value"] = 0,
["cc_min_value"] = 0,
["cc_max_value"] = 1,
["ui_labels"] = {
"OFF",
"ON"
},
["param_type"] = "stock"
},
{
["id"] = "fully_quantise_mask",
["name"] = "Quantise Note Mask",
["short_descriptor_1"] = "QUAN",
["short_descriptor_2"] = "MASK",
["off_value"] = 0,
["cc_min_value"] = 0,
["cc_max_value"] = 2,
["ui_labels"] = {
"X",
"OFF",
"ON"
},
["param_type"] = "stock"
},
}


Expand Down
2 changes: 2 additions & 0 deletions lib/helpers/functions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,8 @@ local stock_id_to_param_id = {
chord_acceleration = "midi_device_params_channel_%d_11",
chord_velocity_modifier = "midi_device_params_channel_%d_12",
chord_strum_pattern = "midi_device_params_channel_%d_13",
mute_root_note = "midi_device_params_channel_%d_14",
fully_quantise_mask = "midi_device_params_channel_%d_15",
}

function fn.get_param_id_from_stock_id(stock_id, channel_number)
Expand Down
1 change: 1 addition & 0 deletions lib/pattern.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ local function sync_pattern_values(merged_pattern, pattern, s)
merged_pattern.lengths[s] = pattern.lengths[s]
merged_pattern.velocity_values[s] = pattern.velocity_values[s]
merged_pattern.note_values[s] = pattern.note_values[s]
merged_pattern.note_mask_values[s] = pattern.note_mask_values[s]
return merged_pattern
end

Expand Down
25 changes: 25 additions & 0 deletions lib/quantiser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,11 @@ local function make_cache_key(root_note, chord_rotation, scale_number, transpose
end

local function process_handler(note_number, octave_mod, transpose, scale_number, do_rotation, do_degree, do_pentatonic)


local root_note = program.get().root_note + 60
local chord_rotation = program.get().chord - 1

local scale_container = program.get_scale(scale_number)

if scale_container.root_note > -1 then
Expand Down Expand Up @@ -332,6 +335,28 @@ function quantiser.process(note_number, octave_mod, transpose, scale_number, do_
return process_handler(note_number, octave_mod, transpose, scale_number, true, true, do_pentatonic)
end

function quantiser.translate_note_mask_to_relative_scale_position(note_mask_value, scale_number)

local scale_container = program.get_scale(scale_number)
if not scale_container then return nil end
if type(note_mask_value) ~= "number" then return nil end

-- Get root note
local root_note = scale_container.root_note > -1 and scale_container.root_note or 0
local octave = math.floor((note_mask_value - 60 - root_note) / 12)

-- Create a transposed scale
local scale = fn.deep_copy(scale_container.scale)
scale = fn.transpose_scale(scale, root_note)

local snapped_note = musicutil.snap_note_to_array(note_mask_value, scale)
local position = fn.find_index_by_value(scale, snapped_note)
local position_in_octave = (position - 1) % 7

return position_in_octave, octave

end

function quantiser.process_chord_note_for_mask(note_mask_value, unscaled_chord_value, octave_mod, transpose, scale_number)
local scale_container = program.get_scale(scale_number)
local scale = fn.deep_copy(scale_container.scale)
Expand Down
Loading

0 comments on commit 2359b72

Please sign in to comment.