From f8e9ec5c0d5f8e4434fe338c17814e037487917c Mon Sep 17 00:00:00 2001 From: Dan Sim Date: Tue, 5 Dec 2023 08:08:07 -0600 Subject: [PATCH 01/33] add Particle font (#1745) * add Particle font * move particle font to end of font list --- lua/core/screen.lua | 5 +++-- matron/src/hardware/screen.c | 5 ++++- resources/Particle.ttf | Bin 0 -> 20712 bytes 3 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 resources/Particle.ttf diff --git a/lua/core/screen.lua b/lua/core/screen.lua index 943200e58..ca5831fb6 100644 --- a/lua/core/screen.lua +++ b/lua/core/screen.lua @@ -286,7 +286,7 @@ Screen.current_point = function() return _norns.screen_current_point() end -- 66 unscii-8-tall.pcf -- 67 unscii-8-thin.pcf Screen.font_face = function(index) _norns.screen_font_face(index) end -Screen.font_face_count = 67 +Screen.font_face_count = 68 Screen.font_face_names = { "04B_03__", "liquid", @@ -354,7 +354,8 @@ Screen.font_face_names = { "bmp/unscii-8-mcr", "bmp/unscii-8", "bmp/unscii-8-tall", - "bmp/unscii-8-thin" + "bmp/unscii-8-thin", + "Particle", } --- set font size. diff --git a/matron/src/hardware/screen.c b/matron/src/hardware/screen.c index b72477225..486e0d12f 100644 --- a/matron/src/hardware/screen.c +++ b/matron/src/hardware/screen.c @@ -25,7 +25,7 @@ #include "hardware/screen.h" #include "hardware/screen/ssd1322.h" -#define NUM_FONTS 67 +#define NUM_FONTS 68 #define NUM_OPS 29 static char font_path[NUM_FONTS][32]; @@ -228,6 +228,9 @@ void init_font_faces(void) { strcpy(font_path[font_idx++], "bmp/unscii-8.pcf"); strcpy(font_path[font_idx++], "bmp/unscii-8-tall.pcf"); strcpy(font_path[font_idx++], "bmp/unscii-8-thin.pcf"); + //------------------ + // not specifically bitmap but added to the tail of the font list to avoid breaking changes + strcpy(font_path[font_idx++], "Particle.ttf"); assert(font_idx == NUM_FONTS); diff --git a/resources/Particle.ttf b/resources/Particle.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1f4b3180640ff67c846584a0ee44270d314002e0 GIT binary patch literal 20712 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 A7XSbN literal 0 HcmV?d00001 From b3e6c03e08bf646628bbe4e3c741ac05f4bc7038 Mon Sep 17 00:00:00 2001 From: dan derks Date: Tue, 9 Jan 2024 10:32:01 -0500 Subject: [PATCH 02/33] fix lfo constructor ahead of params (#1753) * fix lfo constructor ahead of params * fix period --- lua/lib/lfo.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lua/lib/lfo.lua b/lua/lib/lfo.lua index b3cabd938..1072cadb6 100755 --- a/lua/lib/lfo.lua +++ b/lua/lib/lfo.lua @@ -14,7 +14,7 @@ local lfo_shapes = {'sine','tri','square','random','up','down'} local beat_sec = clock.get_beat_sec() -local params_per_entry = 14 +local params_per_entry = 15 function LFO.init() if norns.lfo == nil then @@ -485,7 +485,7 @@ function LFO:add_params(id,sep,group) end) local mode_options = {'clocked', 'free'} - params:add_option("lfo_mode_"..id, "lfo mode", mode_options, mode_options[self:get('mode')]) + params:add_option("lfo_mode_"..id, "lfo mode", mode_options, tab.key(mode_options,self:get('mode'))) params:set_action("lfo_mode_"..id, function(x) self:set('mode',params:lookup_param("lfo_mode_"..id).options[x]) @@ -504,7 +504,7 @@ function LFO:add_params(id,sep,group) end ) - local current_period_as_rate = self:get('mode') == 'clocked' and lfo_rates[lfo_rates_as_strings[self:get('period')]] or lfo_rates[self:get('period')] + local current_period_as_rate = self:get('mode') == 'clocked' and lfo_rates[lfo_rates_as_strings[self:get('period')]] or self:get('period') local rate_index = tab.key(lfo_rates,self:get('period')) params:add_option("lfo_clocked_"..id, "lfo rate", lfo_rates_as_strings, rate_index) params:set_action("lfo_clocked_"..id, @@ -530,8 +530,8 @@ function LFO:add_params(id,sep,group) params:add_trigger("lfo_reset_"..id, "reset lfo") params:set_action("lfo_reset_"..id, function(x) self:reset_phase() end) - local reset_destinations = {"floor","ceiling","mid: rising","mid: falling"} - params:add_option("lfo_reset_target_"..id, "reset lfo to", reset_destinations, reset_destinations[self:get('reset_target')]) + local reset_destinations = {"floor", "ceiling", "mid: rising", "mid: falling"} + params:add_option("lfo_reset_target_"..id, "reset lfo to", reset_destinations, tab.key(reset_destinations,self:get('reset_target'))) params:set_action("lfo_reset_target_"..id, function(x) self:set('reset_target', params:lookup_param("lfo_reset_target_"..id).options[x]) end) From 666bf5af3c7ed9f87265cea6981105956944a011 Mon Sep 17 00:00:00 2001 From: ezra buchla Date: Sun, 21 Jan 2024 19:56:08 -0800 Subject: [PATCH 03/33] [WIP] Midi clock filter (#1755) * add ability to enable/disable midi clock for selected devices define new system parameter `clock_midi_in` * remove debug prints, fix param menu --------- Co-authored-by: tehn --- lua/core/clock.lua | 18 ++++++++++++++++-- lua/core/midi.lua | 30 ++++++++++++++++++++++++++++++ lua/core/state.lua | 2 ++ matron/src/device/device_midi.c | 10 +++++++--- matron/src/device/device_midi.h | 1 + matron/src/weaver.c | 17 +++++++++++++++++ 6 files changed, 73 insertions(+), 5 deletions(-) diff --git a/lua/core/clock.lua b/lua/core/clock.lua index 5ddf8dd0e..8306802df 100755 --- a/lua/core/clock.lua +++ b/lua/core/clock.lua @@ -201,7 +201,7 @@ end function clock.add_params() local send_midi_clock = {} - params:add_group("CLOCK", 27) + params:add_group("CLOCK", 29) params:add_option("clock_source", "source", {"internal", "midi", "link", "crow"}, norns.state.clock.source) @@ -275,6 +275,20 @@ function clock.add_params() end params:set_save("clock_midi_out_"..i, false) end + + params:add_separator("midi_clock_in_separator", "midi clock in") + local midi_clock_in_options = { "all", "none"} + for i=1,16 do + table.insert(midi_clock_in_options, tostring(i)) + end + params:add_option("clock_midi_in", "midi clock in", + midi_clock_in_options, norns.state.clock.midi_in) + params:set_action("clock_midi_in", function(x) + norns.state.clock.midi_in = x + midi.update_clock_receive() + end) + params:set_save("clock_midi_in", false) + params:add_separator("crow_clock_separator", "crow") params:add_option("clock_crow_out", "crow out", {"off", "output 1", "output 2", "output 3", "output 4"}, norns.state.clock.crow_out) @@ -375,4 +389,4 @@ end -------------------------------------------------------------------------------- ]] -return clock \ No newline at end of file +return clock diff --git a/lua/core/midi.lua b/lua/core/midi.lua index 8b82cbdd5..2c9ae4e39 100755 --- a/lua/core/midi.lua +++ b/lua/core/midi.lua @@ -175,6 +175,13 @@ function Midi:song_select(val) self:send{type="song_select", val=val} end +--- enable/disable clock reception from this device +-- @tparam boolean enabled +function Midi:clock_receive(enabled) + --print("Midi:clock_receive: "..enabled) + _norns.midi_clock_receive(self.dev, enabled) +end + --- create device, returns object with handler and send. -- @tparam integer n : vport index function Midi.connect(n) @@ -401,6 +408,29 @@ function Midi.update_connected_state() _menu.rebuild_params() end +function Midi.update_clock_receive() + local x = norns.state.clock.midi_in + if x == 1 then + --- enable all devices + for _, dev in pairs(Midi.devices) do + dev:clock_receive(1) + end + else + -- disable all devices... + for _, dev in pairs(Midi.devices) do + dev:clock_receive(0) + end + -- re-enable the selected one if called for + if x > 2 then + --print("enabling clock input; x = "..x) + local dev = Midi.vports[x-2].device + if dev ~= nil then + dev:clock_receive(1) + end + end + end +end + -- add a device. _norns.midi.add = function(id, name, dev) print(string.format("_norns.midi.add: %d, %s, %s",id,name,dev)) diff --git a/lua/core/state.lua b/lua/core/state.lua index 506fac95b..28a69e875 100755 --- a/lua/core/state.lua +++ b/lua/core/state.lua @@ -51,6 +51,7 @@ state.clock.tempo = 90 state.clock.link_quantum = 4 state.clock.link_start_stop_sync = 1 state.clock.midi_out = {} +state.clock.midi_in = 1 -- all clock input enabled state.clock.crow_out = 1 state.clock.crow_out_div = 4 state.clock.crow_in_div = 4 @@ -151,6 +152,7 @@ state.save_state = function() for i = 1,16 do io.write("norns.state.clock.midi_out["..i.."] = " .. norns.state.clock.midi_out[i] .. "\n") end + io.write("norns.state.clock.midi_in = " .. norns.state.clock.midi_in .. "\n") io.write("norns.state.clock.crow_out = " .. norns.state.clock.crow_out .. "\n") io.write("norns.state.clock.crow_out_div = " .. norns.state.clock.crow_out_div .. "\n") io.write("norns.state.clock.crow_in_div = " .. norns.state.clock.crow_in_div .. "\n") diff --git a/matron/src/device/device_midi.c b/matron/src/device/device_midi.c index 0929f7b78..b8dbbe734 100644 --- a/matron/src/device/device_midi.c +++ b/matron/src/device/device_midi.c @@ -99,12 +99,14 @@ int dev_midi_init(void *self, unsigned int port_index, bool multiport_device) { } if (midi->handle_in != NULL) { - base->start = &dev_midi_start; + base->start = &dev_midi_start; } else { - base->start = NULL; + base->start = NULL; } base->deinit = &dev_midi_deinit; + midi->clock_enabled = true; + return 0; } @@ -282,7 +284,9 @@ static inline ssize_t dev_midi_consume_buffer(midi_input_state_t *state, ssize_t byte = state->buffer[i]; if (byte >= 0xf8) { - clock_midi_handle_message(byte); + if (midi->clock_enabled) { + clock_midi_handle_message(byte); + } } if (is_status_byte(byte) && (byte != 0xf7)) { diff --git a/matron/src/device/device_midi.h b/matron/src/device/device_midi.h index 9e4eff24a..c91eec6c1 100644 --- a/matron/src/device/device_midi.h +++ b/matron/src/device/device_midi.h @@ -6,6 +6,7 @@ struct dev_midi { struct dev_common dev; + bool clock_enabled; snd_rawmidi_t *handle_in; snd_rawmidi_t *handle_out; }; diff --git a/matron/src/weaver.c b/matron/src/weaver.c index e7a7f6dc5..e1a0fa8b2 100644 --- a/matron/src/weaver.c +++ b/matron/src/weaver.c @@ -169,6 +169,7 @@ static int _osc_send_crone(lua_State *l); // midi static int _midi_send(lua_State *l); +static int _midi_clock_receive(lua_State *l); // crow static int _crow_send(lua_State *l); @@ -507,6 +508,7 @@ void w_init(void) { // midi lua_register_norns("midi_send", &_midi_send); + lua_register_norns("midi_clock_receive", &_midi_clock_receive); // get list of available crone engines lua_register_norns("report_engines", &_request_engine_report); @@ -1662,6 +1664,21 @@ int _midi_send(lua_State *l) { return 0; } +/*** + * midi: clock_receive + * @function midi_receive + */ +int _midi_clock_receive(lua_State *l) { + struct dev_midi *md; + lua_check_num_args(2); + luaL_checktype(l, 1, LUA_TLIGHTUSERDATA); + md = lua_touserdata(l, 1); + int enabled = lua_tointeger(l, 2); + md->clock_enabled = enabled > 0; + //fprintf(stderr, "set clock_enabled to %d on device %p\n", enabled, md); + return 0; +} + /*** * grid: set led * @function grid_set_led From aa1b34ab97046a16c75bf0f94278d297be932130 Mon Sep 17 00:00:00 2001 From: Rylee Alanza Lyman <46907231+ryleelyman@users.noreply.github.com> Date: Tue, 13 Feb 2024 07:57:34 -0500 Subject: [PATCH 04/33] fix: more aggressively debounce tape playback (#1759) closes #1758 --- lua/lib/fileselect.lua | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/lua/lib/fileselect.lua b/lua/lib/fileselect.lua index a715ca4ea..02d179270 100755 --- a/lua/lib/fileselect.lua +++ b/lua/lib/fileselect.lua @@ -151,12 +151,18 @@ end local function start() if fs.previewing_timeout_counter ~= nil then return end - timeout() - stop() - fs.previewing = fs.pos - audio.tape_play_open(fs.getdir() .. fs.file) - audio.tape_play_start() - fs.redraw() + fs.previewing_timeout_counter = clock.run(function() + if fs.previewing then + stop() + clock.sleep(0.5) + end + fs.previewing = fs.pos + audio.tape_play_open(fs.getdir() .. fs.file) + audio.tape_play_start() + fs.redraw() + clock.sleep(1) + fs.previewing_timeout_counter = nil + end) end fs.key = function(n, z) @@ -195,7 +201,11 @@ fs.key = function(n, z) end end elseif z == 0 and fs.done == true then - fs.exit() + clock.run(function() + stop() + clock.sleep(0.5) + fs.exit() + end) end end From 2d16d43b6c275db57456aa62cf959aba13ff8d91 Mon Sep 17 00:00:00 2001 From: dan derks Date: Tue, 13 Feb 2024 13:36:20 -0500 Subject: [PATCH 05/33] fix field accessors in grid example (#1760) https://llllllll.co/t/midigrid-use-launchpads-midi-grid-controllers-with-norns/42336/550 --- lua/core/grid.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lua/core/grid.lua b/lua/core/grid.lua index a9aed0cc4..d3416d489 100755 --- a/lua/core/grid.lua +++ b/lua/core/grid.lua @@ -249,11 +249,11 @@ grid.connect( port ) create a grid table using device [port] this should be redefined by the script .tilt( x, y, z ) function called with incoming grid tilt event this should be redefined by the script -.led( x, y, level ) set LED at [x,y] to [level] +:led( x, y, level ) set LED at [x,y] to [level] [level] range is 0..15 -.all( level ) set all grid LED to [level] +:all( level ) set all grid LED to [level] [level] range is 0..15 -.refresh() update the grid LED state +:refresh() update the grid LED state -------------------------------------------------------------------------------- -- example @@ -274,9 +274,9 @@ end -- simple draw function draw_grid() - g.all(0) - g.led(lx,ly,lz) - g.refresh() + g:all(0) + g:led(lx,ly,lz) + g:refresh() end -------------------------------------------------------------------------------- ]] From 5cd51e4835f5fe3b1609e62621351b27d8b6fe8c Mon Sep 17 00:00:00 2001 From: tehn Date: Wed, 14 Feb 2024 10:43:52 -0500 Subject: [PATCH 06/33] remove logging on next update --- update/update.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/update/update.sh b/update/update.sh index 7889d84e7..d12b4c355 100755 --- a/update/update.sh +++ b/update/update.sh @@ -21,12 +21,13 @@ sudo cp -a /home/we/norns/build/maiden-repl/maiden-repl /home/we/bin/ cp version.txt /home/we/ cp changelog.txt /home/we/ -# fix logrotate +# remove logging +sudo apt -y remove rsyslog sudo cp config/logrotate.conf /etc/ - -# rewrite journalctl sudo cp config/journald.conf /etc/systemd/ -sudo mkdir -p /var/log/journal +sudo rm -rf /var/log/journal +sudo rm -rf /var/log/daemon.log +sudo rm -rf /var/log/user.log # disable hciuart sudo systemctl disable hciuart From 0e46a5173b5461e0fb7bdab814e36aa5b9a2b4a4 Mon Sep 17 00:00:00 2001 From: Jonathan Snyder <52048666+jaseknighter@users.noreply.github.com> Date: Mon, 19 Feb 2024 12:51:32 -0800 Subject: [PATCH 07/33] Create hotswap.lua (#1762) copied from the crow hotswap.lua file --- lua/lib/hotswap.lua | 51 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100755 lua/lib/hotswap.lua diff --git a/lua/lib/hotswap.lua b/lua/lib/hotswap.lua new file mode 100755 index 000000000..6c3a662f9 --- /dev/null +++ b/lua/lib/hotswap.lua @@ -0,0 +1,51 @@ +--- hotswap library + +--- globals are available on crow, otherwise require for norns +local require = require or function() end +local s = sequins or require 'lib/sequins' +local tl = timeline or require 'lib/timeline' + +local HS = { + _reg = {} -- a place to register updateable sequins +} + +HS.cleanup = function() + HS._reg = {} +end + +-- to add support for a new type you need: +-- 1) add an elseif predicate for capturing the type +-- 2) give the type a single character identifier +-- 3) add a swap function to HS._swap table + +HS._type = function(o) + -- return a char representing the type + if s.is_sequins(o) then return 's' + elseif tl.is_timeline(o) then return 't' + else print 'hotswap does not know this type' + end +end + +HS._swap = { + s = function(t, v) t:settable(v) end, + t = function(t, v) t:hotswap(v) end, +} + + +HS.__index = function(self, ix) + return HS._reg[ix][2] +end + +HS.__newindex = function(self, ix, v) + local t = HS._type(v) + if t then + if HS._reg[ix] then -- key already exists + -- warning! we assume the new type matches + HS._swap[t](HS._reg[ix][2], v) + else -- new key + HS._reg[ix] = {t,v} -- register with type annotation + end + end +end + +return setmetatable(HS, HS) From cc291b7c1d4533faed57528e23f954911d98cc71 Mon Sep 17 00:00:00 2001 From: brian crabtree Date: Wed, 21 Feb 2024 10:50:09 -0500 Subject: [PATCH 08/33] support i2c adc inf pots for encoders (#1763) * done * adjust rollover threshold * adc tuning --- matron/src/hardware/i2c.c | 235 +++++++++++++++++++++++++++++++------- matron/src/main.c | 3 +- 2 files changed, 193 insertions(+), 45 deletions(-) diff --git a/matron/src/hardware/i2c.c b/matron/src/hardware/i2c.c index e6d79a592..e1547917f 100644 --- a/matron/src/hardware/i2c.c +++ b/matron/src/hardware/i2c.c @@ -1,13 +1,13 @@ /* i2c.c * * hp driver: TPA6130A2 - * digipots: DS1881 * */ #include #include #include +#include #include #include #include @@ -17,63 +17,210 @@ #include #include +#include "events.h" #include "i2c.h" #include "platform.h" #define ADDR_HP 0x60 -#define ADDR_IN 0x29 +#define ADDR_ADC 0x1D static int file; static char buf[10]; -void *i2c_write(void *); +static pthread_t p; + +static int pos[3] = {0,0,0}; +// division of pot 0-1 range for ticks, TH is for wrap detection +#define DIV 64 +#define DIVTH 32 +#define ADC_RATE 30000 + +void *adc_read(void *); void i2c_init(void) { - if (platform() != PLATFORM_CM3) return; - - char filename[40]; - - sprintf(filename, "/dev/i2c-1"); - if ((file = open(filename, O_RDWR | O_NONBLOCK)) < 0) { - fprintf(stderr, "ERROR (i2c) failed to open bus\n"); - return; - } - - // setup peripherals - - // enable hp - if (ioctl(file, I2C_SLAVE, ADDR_HP) < 0) { - fprintf(stderr, "ERROR (i2c) failed to acquire bus access and/or talk to slave\n"); - return; - } - buf[0] = 1; // reg for settings p21 - buf[1] = 192; - if (write(file, buf, 2) != 2) { - fprintf(stderr, "ERROR (i2c/hp) failed to write\n"); - return; - } + if (platform() != PLATFORM_CM3) return; + char filename[40]; + + fprintf(stderr, "i2c init...\n"); + + sprintf(filename, "/dev/i2c-1"); + if ((file = open(filename, O_RDWR | O_NONBLOCK)) < 0) { + fprintf(stderr, "ERROR (i2c) failed to open bus\n"); + return; + } + + // HP + if (ioctl(file, I2C_SLAVE, ADDR_HP) < 0) { + fprintf(stderr, "ERROR (i2c) failed to acquire bus access and/or talk to device\n"); + return; + } + buf[0] = 1; // reg for settings p21 + buf[1] = 192; + if (write(file, buf, 2) != 2) { + fprintf(stderr, "ERROR (i2c/hp) failed to write\n"); + return; + } + + // ADC + if (ioctl(file, I2C_SLAVE, ADDR_ADC) < 0) { + fprintf(stderr, "(i2c) ADC connect fail\n"); + return; + } + + buf[0] = 8; // 0-5 only + buf[1] = 0xC0; + if (write(file, buf, 2) != 2) { + fprintf(stderr, "ERROR (i2c/adc) failed to write\n"); + return; + } + buf[0] = 7; // continuous + buf[1] = 1; + if (write(file, buf, 2) != 2) { + fprintf(stderr, "ERROR (i2c/adc) failed to write\n"); + return; + } + buf[0] = 0xB; // ext vref + buf[1] = 1; + if (write(file, buf, 2) != 2) { + fprintf(stderr, "ERROR (i2c/hp) failed to write\n"); + return; + } + buf[0] = 0; // config, p20 + buf[1] = 1; // start + if (write(file, buf, 2) != 2) { + fprintf(stderr, "ERROR (i2c/adc) failed to write\n"); + return; + } + + if (pthread_create(&p, NULL, adc_read, 0)) { + fprintf(stderr, "i2c/ADC: Error creating thread\n"); + } } void i2c_deinit() { } void i2c_hp(int level) { - if (platform() != PLATFORM_CM3) return; - - if (level < 0) { - level = 0; - } else if (level > 63) { - level = 63; - } - - if (ioctl(file, I2C_SLAVE, ADDR_HP) < 0) { - fprintf(stderr, "ERROR (i2c) failed to acquire bus access and/or talk to slave\n"); - return; - } - buf[0] = 2; // reg for set level p17 - buf[1] = level; - if (write(file, buf, 2) != 2) { - fprintf(stderr, "ERROR (i2c/hp) failed to write\n"); - return; - } + if (platform() != PLATFORM_CM3) return; + + if (level < 0) { + level = 0; + } else if (level > 63) { + level = 63; + } + + if (ioctl(file, I2C_SLAVE, ADDR_HP) < 0) { + fprintf(stderr, "ERROR (i2c) failed to acquire bus access and/or talk to slave\n"); + return; + } + buf[0] = 2; // reg for set level p17 + buf[1] = level; + if (write(file, buf, 2) != 2) { + fprintf(stderr, "ERROR (i2c/hp) failed to write\n"); + return; + } +} + + +float angle_360(float a, float b){ + // interpolant coefficient + float c; + if(b > 0.5){ + c = 2.0 * (1.0 - b); + } else { + c = b * 2.0; + } + + // shift quadrants into (0..1) range + float aa = a; + float bb = b; + // flips + if(b > 0.5){ + aa = 1.0 - aa; + } + if(a < 0.5){ + bb = 1.0 - bb; + } + // shifts + if(b > 0.5){ + aa += 0.5; + } else if(a > 0.5){ + aa -= 0.5; + } else{ // a < 0.5 + aa += 1.5; + } + if(a < 0.5){ + bb += 1.0; + } + // down-scale + aa *= 0.5; + bb *= 0.5; + + // linear interpolate + return aa + c*(bb-aa); +} + + +void *adc_read(void *x) { + (void)x; + int now[6]; + const int reorder[3] = {1,3,2}; + + fprintf(stderr, "(i2c) ADC thread start...\n"); + + usleep(100000); // settling time before first read + + if (ioctl(file, I2C_SLAVE, ADDR_ADC) < 0) { + fprintf(stderr, "(i2c) ADC connect fail\n"); + } + + // read initial positions + for(int i=0;i<6;i++) { + buf[0] = 0x20 + i; + if (write(file, buf, 1) != 1) { + fprintf(stderr, "ERROR (i2c/adc) failed to write\n"); + break; + } + read(file, buf, 2); + now[i] = ((buf[0]<<4) + (buf[1]>>4)); + } + for(int i=0;i<3;i++) { + pos[i] = (int)DIV*angle_360((float)now[i*2]/4096,(float)now[i*2+1]/4096); + } + + while(1) { + if (ioctl(file, I2C_SLAVE, ADDR_ADC) < 0) { + fprintf(stderr, "(i2c) ADC connect fail\n"); + } + for(int i=0;i<6;i++) { + buf[0] = 0x20 + i; + if (write(file, buf, 1) != 1) { + fprintf(stderr, "ERROR (i2c/adc) failed to write\n"); + break; + } + + read(file, buf, 2); + //fprintf(stderr, "%x\t%x\t\t",buf[0],buf[1]); + now[i] = ((buf[0]<<4) + (buf[1]>>4)); + } + for(int i=0;i<3;i++) { + int n = (int)DIV*angle_360((float)now[i*2]/4096,(float)now[i*2+1]/4096); + int d = pos[i] - n; + if(d>(DIV-DIVTH)) d -= DIV; // for rollover + else if(d<(DIVTH-DIV)) d += DIV; + + if(d) { + pos[i] = n; + //fprintf(stderr, "%d %d\n",reorder[i],d); + union event_data *ev = event_data_new(EVENT_ENC); + ev->enc.n = reorder[i]; + ev->enc.delta = d; + event_post(ev); + } + + //fprintf(stderr, "%f\t", angle_360((float)adc[i*2]/4096,(float)adc[i*2+1]/4096)); + } + + usleep(ADC_RATE); + } } diff --git a/matron/src/main.c b/matron/src/main.c index 146960266..792d07c72 100644 --- a/matron/src/main.c +++ b/matron/src/main.c @@ -73,7 +73,6 @@ int main(int argc, char **argv) { battery_init(); stat_init(); - i2c_init(); osc_init(); jack_client_init(); ssd1322_init(); @@ -111,6 +110,8 @@ int main(int argc, char **argv) { // start reading input to interpreter input_init(); + i2c_init(); + fprintf(stderr, "running startup...\n"); // i/o subsystems are ready; run user startup routine w_startup(); From ba6c1a994fae11cf3926ceaf2084f9a347246acc Mon Sep 17 00:00:00 2001 From: brian crabtree Date: Wed, 21 Feb 2024 10:58:20 -0500 Subject: [PATCH 09/33] remove system/log (#1764) --- lua/core/menu.lua | 1 - lua/core/menu/log.lua | 30 ------------------------------ lua/core/menu/system.lua | 4 ++-- 3 files changed, 2 insertions(+), 33 deletions(-) delete mode 100644 lua/core/menu/log.lua diff --git a/lua/core/menu.lua b/lua/core/menu.lua index 81a0633b2..4bcde7a58 100644 --- a/lua/core/menu.lua +++ b/lua/core/menu.lua @@ -344,4 +344,3 @@ m["SLEEP"] = require 'core/menu/sleep' m["MIX"] = require 'core/menu/mix' m["TAPE"] = require 'core/menu/tape' m["MODS"] = require 'core/menu/mods' -m["LOG"] = require 'core/menu/log' diff --git a/lua/core/menu/log.lua b/lua/core/menu/log.lua deleted file mode 100644 index 98c7c27bb..000000000 --- a/lua/core/menu/log.lua +++ /dev/null @@ -1,30 +0,0 @@ -local m = {} - -m.init = function() - go = false -end - -m.key = function(n,z) - if (n==2 or n==3) and z==1 then - print("export logs!") - os.execute("echo '//////// current boot\n\n' > ~/dust/data/system.log") - os.execute("journalctl --output=with-unit --boot=-0 >> ~/dust/data/system.log") - os.execute("echo '\n\n//////// previous boot\n\n' >> ~/dust/data/system.log") - os.execute("journalctl --output=with-unit --boot=-1 >> ~/dust/data/system.log") - _menu.set_page("SYSTEM") - end -end - -m.enc = norns.none - -m.redraw = function() - screen.clear() - screen.move(64,40) - screen.level(15) - screen.text_center("logs exported!") - screen.update() -end - -m.deinit = norns.none - -return m diff --git a/lua/core/menu/system.lua b/lua/core/menu/system.lua index acbda2dd1..1e3cb2001 100644 --- a/lua/core/menu/system.lua +++ b/lua/core/menu/system.lua @@ -1,7 +1,7 @@ local m = { pos = 1, - list = {"DEVICES > ", "WIFI >", "MODS >", "SETTINGS >", "RESTART", "UPDATE", "LOG"}, - pages = {"DEVICES", "WIFI", "MODS", "SETTINGS", "RESTART", "UPDATE", "LOG"} + list = {"DEVICES > ", "WIFI >", "MODS >", "SETTINGS >", "RESTART", "UPDATE"}, + pages = {"DEVICES", "WIFI", "MODS", "SETTINGS", "RESTART", "UPDATE"} } m.key = function(n,z) From 76a06b2ef303b328363c05926899f3f72416486a Mon Sep 17 00:00:00 2001 From: tehn Date: Wed, 21 Feb 2024 11:15:11 -0500 Subject: [PATCH 10/33] 240221 --- releases.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/releases.txt b/releases.txt index 8e5c9466d..18a819341 100644 --- a/releases.txt +++ b/releases.txt @@ -5,8 +5,8 @@ releases = { sha="https://github.com/monome/norns/releases/download/v2.8.1/norns231114.sha256" }, beta = { - version="231114", - url="https://github.com/monome/norns/releases/download/v2.8.1/norns231114.tgz", - sha="https://github.com/monome/norns/releases/download/v2.8.1/norns231114.sha256" + version="240221", + url="https://github.com/monome/norns/releases/download/v2.8.2/norns240221.tgz", + sha="https://github.com/monome/norns/releases/download/v2.8.2/norns240221.sha256" } } From 2dfe8fedc07dca6a2049b6ed3898129e977a394c Mon Sep 17 00:00:00 2001 From: brian crabtree Date: Wed, 21 Feb 2024 11:17:02 -0500 Subject: [PATCH 11/33] 240221 (#1765) * 240221 * 240221 * 240221 --- releases.txt | 6 +++--- update/changelog.txt | 16 ++++++++++++++++ update/version.txt | 2 +- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/releases.txt b/releases.txt index 8e5c9466d..18a819341 100644 --- a/releases.txt +++ b/releases.txt @@ -5,8 +5,8 @@ releases = { sha="https://github.com/monome/norns/releases/download/v2.8.1/norns231114.sha256" }, beta = { - version="231114", - url="https://github.com/monome/norns/releases/download/v2.8.1/norns231114.tgz", - sha="https://github.com/monome/norns/releases/download/v2.8.1/norns231114.sha256" + version="240221", + url="https://github.com/monome/norns/releases/download/v2.8.2/norns240221.tgz", + sha="https://github.com/monome/norns/releases/download/v2.8.2/norns240221.sha256" } } diff --git a/update/changelog.txt b/update/changelog.txt index 37c5c1892..c14eabee6 100644 --- a/update/changelog.txt +++ b/update/changelog.txt @@ -1,3 +1,19 @@ +# 240221 + +# norns 2.8.2 + +- NEW support for i2c adc inf pots, as encoders @tehn +- NEW particle font @dansimco +- NEW hotswap lib (from crow) @trentgill +- NEW midi clock in port selection @catfact +- FIX remove system/log @tehn +- FIX link start/stop @artfwo + +# norns-image + +- FIX disable logging @catfact + + # 231114 # norns 2.8.1 diff --git a/update/version.txt b/update/version.txt index d5c6c470d..6dd15d09d 100644 --- a/update/version.txt +++ b/update/version.txt @@ -1 +1 @@ -231114 +240221 From 030d3205173354eff2b4408dfb266675be811936 Mon Sep 17 00:00:00 2001 From: tehn Date: Wed, 21 Feb 2024 13:49:42 -0500 Subject: [PATCH 12/33] releases.txt --- releases.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/releases.txt b/releases.txt index 18a819341..90fdd8d93 100644 --- a/releases.txt +++ b/releases.txt @@ -1,8 +1,8 @@ releases = { stable = { - version="231114", - url="https://github.com/monome/norns/releases/download/v2.8.1/norns231114.tgz", - sha="https://github.com/monome/norns/releases/download/v2.8.1/norns231114.sha256" + version="240221", + url="https://github.com/monome/norns/releases/download/v2.8.2/norns240221.tgz", + sha="https://github.com/monome/norns/releases/download/v2.8.2/norns240221.sha256" }, beta = { version="240221", From 28bb75c621927959e1a3f9ee1a2c2b13c42599a7 Mon Sep 17 00:00:00 2001 From: brian crabtree Date: Tue, 27 Feb 2024 11:48:53 -0500 Subject: [PATCH 13/33] i2c adc hotfix (#1766) * i2c adc tuning * fix enc sens, add adc_rev query * cleanup --- lua/core/encoders.lua | 21 +++++++++++++++----- lua/core/menu.lua | 2 +- lua/core/menu/mix.lua | 1 + lua/core/norns.lua | 3 ++- matron/src/hardware/i2c.c | 42 +++++++++++++++++++++++++++------------ matron/src/hardware/i2c.h | 2 ++ matron/src/weaver.c | 8 ++++++++ 7 files changed, 59 insertions(+), 20 deletions(-) diff --git a/lua/core/encoders.lua b/lua/core/encoders.lua index 3fdaca96d..6fefa7464 100644 --- a/lua/core/encoders.lua +++ b/lua/core/encoders.lua @@ -41,10 +41,21 @@ end --- process delta encoders.process = function(n,d) + encoders.tick[n] = encoders.tick[n] + d + if math.abs(encoders.tick[n]) >= encoders.sens[n] then + local val = encoders.tick[n] / encoders.sens[n] + val = (val > 0) and math.floor(val) or math.ceil(val) + encoders.callback(n,val) + encoders.tick[n] = math.fmod(encoders.tick[n],encoders.sens[n]) + screen.ping() + end +end + +--- process delta, selected if _norns.adc_rev() == 0 in norns.lua +encoders.process_with_accel = function(n,d) now = util.time() local diff = now - encoders.time[n] encoders.time[n] = now - if encoders.accel[n] then if diff < 0.005 then d = d*6 elseif diff < 0.01 then d = d*4 @@ -52,18 +63,18 @@ encoders.process = function(n,d) elseif diff < 0.03 then d = d*2 end end - encoders.tick[n] = encoders.tick[n] + d - if math.abs(encoders.tick[n]) >= encoders.sens[n] then - local val = math.floor(encoders.tick[n] / encoders.sens[n]) + local val = encoders.tick[n] / encoders.sens[n] + val = (val > 0) and math.floor(val) or math.ceil(val) encoders.callback(n,val) - encoders.tick[n] = 0 + encoders.tick[n] = math.fmod(encoders.tick[n],encoders.sens[n]) screen.ping() end end + -- script state local accel = {true,true,true} diff --git a/lua/core/menu.lua b/lua/core/menu.lua index 4bcde7a58..bbee81b3e 100644 --- a/lua/core/menu.lua +++ b/lua/core/menu.lua @@ -166,7 +166,7 @@ _menu.set_mode = function(mode) norns.encoders.callback = enc norns.enc.resume() redraw() - elseif mode == true then -- ACTIVATE MENu MODE + elseif mode == true then -- ACTIVATE MENU MODE if _menu.mode == false then _norns.screen_save() end _menu.mode = true _menu.alt = false diff --git a/lua/core/menu/mix.lua b/lua/core/menu/mix.lua index 54f2f5589..aac638a55 100644 --- a/lua/core/menu/mix.lua +++ b/lua/core/menu/mix.lua @@ -130,6 +130,7 @@ m.init = function() m.out2 = 0 norns.encoders.set_accel(2,true) norns.encoders.set_sens(2,1) + norns.encoders.set_accel(3,true) norns.encoders.set_sens(3,1) end diff --git a/lua/core/norns.lua b/lua/core/norns.lua index 8eee05c0a..f5312623e 100644 --- a/lua/core/norns.lua +++ b/lua/core/norns.lua @@ -130,7 +130,8 @@ norns.script = require 'core/script' norns.state = require 'core/state' norns.encoders = require 'core/encoders' -_norns.enc = norns.encoders.process +--_norns.enc = _norns.adc_rev() and norns.encoders.process or norns.encoders.process_with_accel +_norns.enc = norns.encoders.process_with_accel -- extend paths config table local p = _path diff --git a/matron/src/hardware/i2c.c b/matron/src/hardware/i2c.c index e1547917f..9c474feae 100644 --- a/matron/src/hardware/i2c.c +++ b/matron/src/hardware/i2c.c @@ -1,6 +1,7 @@ /* i2c.c * * hp driver: TPA6130A2 + * adc: ADC128D818 * */ @@ -21,6 +22,9 @@ #include "i2c.h" #include "platform.h" +#include +#include + #define ADDR_HP 0x60 #define ADDR_ADC 0x1D @@ -30,10 +34,15 @@ static char buf[10]; static pthread_t p; static int pos[3] = {0,0,0}; -// division of pot 0-1 range for ticks, TH is for wrap detection #define DIV 64 -#define DIVTH 32 -#define ADC_RATE 30000 +#define ADC_RATE 75000 +// adc rate ~12 * 6ch + +// adc revision +// 0 = none +// 1 = ADC128D818 +static int adc_revision = 0; +int adc_rev() { return adc_revision; } void *adc_read(void *); @@ -95,8 +104,11 @@ void i2c_init(void) { if (pthread_create(&p, NULL, adc_read, 0)) { fprintf(stderr, "i2c/ADC: Error creating thread\n"); } + + adc_revision = 1; } + void i2c_deinit() { } @@ -185,42 +197,46 @@ void *adc_read(void *x) { now[i] = ((buf[0]<<4) + (buf[1]>>4)); } for(int i=0;i<3;i++) { - pos[i] = (int)DIV*angle_360((float)now[i*2]/4096,(float)now[i*2+1]/4096); + pos[i] = (int)4096*angle_360((float)now[i*2]/4096,(float)now[i*2+1]/4096); } while(1) { if (ioctl(file, I2C_SLAVE, ADDR_ADC) < 0) { fprintf(stderr, "(i2c) ADC connect fail\n"); } + for(int i=0;i<6;i++) { buf[0] = 0x20 + i; if (write(file, buf, 1) != 1) { fprintf(stderr, "ERROR (i2c/adc) failed to write\n"); break; } - read(file, buf, 2); //fprintf(stderr, "%x\t%x\t\t",buf[0],buf[1]); now[i] = ((buf[0]<<4) + (buf[1]>>4)); } for(int i=0;i<3;i++) { - int n = (int)DIV*angle_360((float)now[i*2]/4096,(float)now[i*2+1]/4096); + int n = (int)4096*angle_360((float)now[i*2]/4096,(float)now[i*2+1]/4096); int d = pos[i] - n; - if(d>(DIV-DIVTH)) d -= DIV; // for rollover - else if(d<(DIVTH-DIV)) d += DIV; + // rollover + if(d>(2048)) { + d -= (4096); + //fprintf(stderr, "."); + } else if(d<-2048) { + d += (4096); + //fprintf(stderr, "."); + } - if(d) { + if(abs(d)>DIV) { pos[i] = n; - //fprintf(stderr, "%d %d\n",reorder[i],d); + d = (int)(d / DIV); + //fprintf(stderr, "%d\t%d\t%d%\n",reorder[i],n,d); union event_data *ev = event_data_new(EVENT_ENC); ev->enc.n = reorder[i]; ev->enc.delta = d; event_post(ev); } - - //fprintf(stderr, "%f\t", angle_360((float)adc[i*2]/4096,(float)adc[i*2+1]/4096)); } - usleep(ADC_RATE); } } diff --git a/matron/src/hardware/i2c.h b/matron/src/hardware/i2c.h index 5960878f9..cb4297976 100644 --- a/matron/src/hardware/i2c.h +++ b/matron/src/hardware/i2c.h @@ -6,3 +6,5 @@ extern void i2c_init(void); extern void i2c_deinit(void); extern void i2c_hp(int level); + +extern int adc_rev(void); diff --git a/matron/src/weaver.c b/matron/src/weaver.c index e1a0fa8b2..660e63cd2 100644 --- a/matron/src/weaver.c +++ b/matron/src/weaver.c @@ -162,6 +162,7 @@ static int _screen_display_image_region(lua_State *l); // i2c static int _gain_hp(lua_State *l); +static int _adc_rev(lua_State *l); // osc static int _osc_send(lua_State *l); @@ -501,6 +502,7 @@ void w_init(void) { // analog output control lua_register_norns("gain_hp", &_gain_hp); + lua_register_norns("adc_rev", &_adc_rev); // osc lua_register_norns("osc_send", &_osc_send); @@ -1460,6 +1462,12 @@ int _gain_hp(lua_State *l) { return 0; } +int _adc_rev(lua_State *l) { + int rev = adc_rev(); + lua_pushinteger(l, (lua_Integer)rev); + return 1; +} + /*** * osc: send to arbitrary address * @function osc_send From f5c3f3c6c12e2f48e42710b7cbfee2c8df838c71 Mon Sep 17 00:00:00 2001 From: ezra buchla Date: Mon, 11 Mar 2024 08:19:26 -0700 Subject: [PATCH 14/33] tape: return false immediately on open() if stream is running (#1770) * tape: return false immediately on open() if stream is running * tape: cleanup prints and comments --- crone/src/Tape.h | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/crone/src/Tape.h b/crone/src/Tape.h index adf495f31..f7b2c8e8f 100644 --- a/crone/src/Tape.h +++ b/crone/src/Tape.h @@ -70,10 +70,13 @@ namespace crone { virtual // from any thread void start() { if (isRunning) { + std::cout << "Tape::SfStream::start(): already running" << std::endl; return; } else { + std::cout << "Tape::SfStream: starting..." << std::endl; envIdx = 0; envState = Starting; + this->th = std::make_unique( [this]() { this->diskLoop(); @@ -127,7 +130,7 @@ namespace crone { envIdx = 0; envState = Stopped; shouldStop = true; - std::cerr << "Tape: fade-out finished; stopping" << std::endl; + std::cout << "Tape: fade-out finished; stopping" << std::endl; } } @@ -164,7 +167,7 @@ namespace crone { if (bytesToPush > bytesAvailable) { #if 0 - std::cerr << "Tape: writer overrun: " + std::cout << "Tape: writer overrun: " << bytesAvailable << " bytes available; " << bytesToPush << " bytes to push; " << numFramesCaptured << " frames captured" @@ -229,7 +232,7 @@ namespace crone { if (framesToWrite > (int) maxFramesToWrite) { // _really_ shouldn't happen - std::cerr << "warning: Tape::Writer has too many frames to write" << std::endl; + std::cout << "warning: Tape::Writer has too many frames to write" << std::endl; framesToWrite = (int) maxFramesToWrite; } @@ -243,22 +246,22 @@ namespace crone { if (sf_writef_float(this->file, diskOutBuf, framesToWrite) != framesToWrite) { char errstr[256]; sf_error_str(nullptr, errstr, sizeof(errstr) - 1); - std::cerr << "error: Tape::writer failed to write (libsndfile: " << errstr << ")" << std::endl; + std::cout << "error: Tape::writer failed to write (libsndfile: " << errstr << ")" << std::endl; this->status = EIO; break; } numFramesCaptured += framesToWrite; if (numFramesCaptured >= maxFrames) { - std::cerr << "Tape: writer exceeded max frame count; aborting."; + std::cout << "Tape: writer exceeded max frame count; aborting."; break; } } - std::cerr << "Tape::writer closing file..."; + std::cout << "Tape::writer closing file..."; sf_close(this->file); - std::cerr << " done." << std::endl; + std::cout << " done." << std::endl; SfStream::isRunning = false; } @@ -267,6 +270,13 @@ namespace crone { size_t maxFrames = JACK_MAX_FRAMES, // <-- ridiculous big number int sampleRate = 48000, int bitDepth = 24) { + + if (SfStream::isRunning) { + std::cout << "Tape Writer::open(): stream is running; no action was taken" << std::endl; + return false; + } + + SF_INFO sf_info; int short_mask; @@ -295,7 +305,7 @@ namespace crone { if ((this->file = sf_open(path.c_str(), SFM_WRITE, &sf_info)) == NULL) { char errstr[256]; sf_error_str(nullptr, errstr, sizeof(errstr) - 1); - std::cerr << "cannot open sndfile" << path << " for output (" << errstr << ")" << std::endl; + std::cout << "cannot open sndfile" << path << " for output (" << errstr << ")" << std::endl; return false; } @@ -337,6 +347,7 @@ namespace crone { private: // prime the ringbuffer void prime() { + // std::cout << "priming tape reader" << std::endl; jack_ringbuffer_t *rb = this->ringBuf.get(); size_t framesToRead = jack_ringbuffer_write_space(rb) / frameSize; if (framesToRead > maxFramesToRead) { framesToRead = maxFramesToRead; }; @@ -347,7 +358,7 @@ namespace crone { // couldn't read enough, file is shorter than the buffer if (framesRead < framesToRead) { - std::cerr << "Tape::Reader: short file, disable loop" << std::endl; + std::cout << "Tape::Reader: short file, disable loop" << std::endl; SfStream::shouldStop = false; } } @@ -425,22 +436,26 @@ namespace crone { // from any thread bool open(const std::string &path) { - SF_INFO sfInfo; + if (SfStream::isRunning) { + std::cout << "Tape Reader::open(): stream is running; no action was taken" << std::endl; + return false; + } + SF_INFO sfInfo; if ((this->file = sf_open(path.c_str(), SFM_READ, &sfInfo)) == NULL) { char errstr[256]; sf_error_str(0, errstr, sizeof(errstr) - 1); - std::cerr << "Tape Reader:: cannot open sndfile" << path << " for output (" << errstr << ")" << std::endl; + std::cout << "Tape Reader:: cannot open sndfile" << path << " for output (" << errstr << ")" << std::endl; return false; } if (sfInfo.frames < 1) { - std::cerr << "Tape Reader:: error reading file " << path << " (no frames available)" << std::endl; + std::cout << "Tape Reader:: error reading file " << path << " (no frames available)" << std::endl; return false; } this->frames = static_cast(sfInfo.frames); - std::cerr << "Tape Reader:: file size " << this->frames << " samples" << std::endl; + std::cout << "Tape Reader:: file size " << this->frames << " samples" << std::endl; inChannels = sfInfo.channels; if (inChannels > NumChannels) return 0;//more than stereo is going to break things @@ -498,12 +513,13 @@ namespace crone { if (loopFile) { // couldn't perform full read so must be end of file. Seek to start of file and keep reading while (framesRead < framesToRead) { + // std::cout << "tape reader: couldn't perform full read; looping file..." << std::endl; sf_seek(this->file,0, SEEK_SET); auto nextRead = (size_t) sf_readf_float(this->file, diskBufPtr, framesToRead-framesRead); if (nextRead < 1) { //Shouldn't happen - std::cerr << "Tape::Reader: unable to read file" << std::endl; + std::cout << "Tape::Reader: unable to read file" << std::endl; SfStream::shouldStop = true; break; } @@ -514,7 +530,6 @@ namespace crone { } } else { - std::cerr << "Tape::Reader::diskloop() reached EOF" << std::endl; SfStream::shouldStop = true; } @@ -525,7 +540,6 @@ namespace crone { } sf_close(this->file); - std::cerr << "Tape::reader closed file" << std::endl; } }; // Reader class From 934c0875f78a803a13d986b9c003e60f11427b81 Mon Sep 17 00:00:00 2001 From: tehn Date: Sat, 16 Mar 2024 17:43:40 -0400 Subject: [PATCH 15/33] fix update.sh to prevent black screen update fail --- update/update.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/update/update.sh b/update/update.sh index d12b4c355..edbf38daa 100755 --- a/update/update.sh +++ b/update/update.sh @@ -39,15 +39,6 @@ sudo cp --remove-destination config/norns-jack.service /etc/systemd/system/norns find ~/dust -name .DS_Store -delete find ~/dust -name ._.DS_Store -delete -# get common audio if not present -if [ ! -d /home/we/dust/audio/common ]; then - echo "does not exist, downloading" - cd /home/we/dust/audio - wget https://github.com/monome/norns/releases/download/v2.7.1/dust-audio-common.tgz - tar xzvf dust-audio-common.tgz - rm dust-audio-common.tgz -fi - # set alsa volume amixer --device hw:sndrpimonome set Master 100% on sudo alsactl store @@ -66,6 +57,15 @@ rm /home/we/matronrc.lua cd /home/we/maiden ./project-setup.sh +# get common audio if not present +if [ ! -d /home/we/dust/audio/common ]; then + echo "does not exist, downloading" + cd /home/we/dust/audio + wget https://github.com/monome/norns/releases/download/v2.7.1/dust-audio-common.tgz + tar xzvf dust-audio-common.tgz + rm dust-audio-common.tgz +fi + # cleanup rm -rf ~/update/* From e1d59ea94d42739e15add89b80b543069d59c474 Mon Sep 17 00:00:00 2001 From: brian crabtree Date: Tue, 19 Mar 2024 11:04:10 -0400 Subject: [PATCH 16/33] fix grid quads during rotation (#1772) * grid refresh correct quads during rotation * store modified quads so multi-device works --- matron/src/device/device_monome.c | 24 +++++++++++++++++++----- matron/src/device/device_monome.h | 2 ++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/matron/src/device/device_monome.c b/matron/src/device/device_monome.c index a1e792aac..f1949ae2e 100644 --- a/matron/src/device/device_monome.c +++ b/matron/src/device/device_monome.c @@ -14,6 +14,10 @@ #include "device.h" #include "device_monome.h" +// quad offset defaults +static const int quad_xoff[] = {0, 8, 0, 8}; +static const int quad_yoff[] = {0, 0, 8, 8}; + //------------------------ //-- static functions static void dev_monome_handle_press(const monome_event_t *e, void *p); @@ -61,6 +65,9 @@ int dev_monome_init(void *self) { md->quads); } + memcpy(md->quad_xoff,quad_xoff,sizeof(quad_xoff)); + memcpy(md->quad_yoff,quad_yoff,sizeof(quad_yoff)); + monome_register_handler(m, MONOME_BUTTON_DOWN, dev_monome_handle_press, md); monome_register_handler(m, MONOME_BUTTON_UP, dev_monome_handle_lift, md); monome_register_handler(m, MONOME_ENCODER_DELTA, dev_monome_handle_encoder_delta, md); @@ -93,7 +100,17 @@ static inline uint8_t dev_monome_quad_offset(uint8_t x, uint8_t y) { // set grid rotation void dev_monome_set_rotation(struct dev_monome *md, uint8_t rotation) { - monome_set_rotation(md->m, rotation); + // for 16x8 grid, only update relevant quads which must change with rotation + if(md->quads == 2) { + if(rotation == 0 || rotation == 2) { + md->quad_xoff[1] = 8; + md->quad_yoff[1] = 0; + } else { + md->quad_xoff[1] = 0; + md->quad_yoff[1] = 8; + } + } + monome_set_rotation(md->m, rotation); } // enable/disable grid tilt @@ -129,9 +146,6 @@ void dev_monome_all_led(struct dev_monome *md, uint8_t val) { // transmit all dirty quads void dev_monome_refresh(struct dev_monome *md) { - static const int quad_xoff[4] = {0, 8, 0, 8}; - static const int quad_yoff[4] = {0, 0, 8, 8}; - if (md->m == NULL) { return; } @@ -141,7 +155,7 @@ void dev_monome_refresh(struct dev_monome *md) { if (md->type == DEVICE_MONOME_TYPE_ARC) { monome_led_ring_map(md->m, quad, md->data[quad]); } else { - monome_led_level_map(md->m, quad_xoff[quad], quad_yoff[quad], md->data[quad]); + monome_led_level_map(md->m, md->quad_xoff[quad], md->quad_yoff[quad], md->data[quad]); } md->dirty[quad] = false; } diff --git a/matron/src/device/device_monome.h b/matron/src/device/device_monome.h index fdea8db4f..a6cb0df38 100644 --- a/matron/src/device/device_monome.h +++ b/matron/src/device/device_monome.h @@ -22,6 +22,8 @@ struct dev_monome { int cols; int rows; int quads; + int quad_xoff[4]; + int quad_yoff[4]; }; // set a single grid led From 03b15ce0dfe4559b8bfb496deff42d4b1a97c74a Mon Sep 17 00:00:00 2001 From: brian crabtree Date: Tue, 19 Mar 2024 11:04:26 -0400 Subject: [PATCH 17/33] Revert "fix: more aggressively debounce tape playback (#1759)" (#1771) This reverts commit aa1b34ab97046a16c75bf0f94278d297be932130. --- lua/lib/fileselect.lua | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/lua/lib/fileselect.lua b/lua/lib/fileselect.lua index 02d179270..a715ca4ea 100755 --- a/lua/lib/fileselect.lua +++ b/lua/lib/fileselect.lua @@ -151,18 +151,12 @@ end local function start() if fs.previewing_timeout_counter ~= nil then return end - fs.previewing_timeout_counter = clock.run(function() - if fs.previewing then - stop() - clock.sleep(0.5) - end - fs.previewing = fs.pos - audio.tape_play_open(fs.getdir() .. fs.file) - audio.tape_play_start() - fs.redraw() - clock.sleep(1) - fs.previewing_timeout_counter = nil - end) + timeout() + stop() + fs.previewing = fs.pos + audio.tape_play_open(fs.getdir() .. fs.file) + audio.tape_play_start() + fs.redraw() end fs.key = function(n, z) @@ -201,11 +195,7 @@ fs.key = function(n, z) end end elseif z == 0 and fs.done == true then - clock.run(function() - stop() - clock.sleep(0.5) - fs.exit() - end) + fs.exit() end end From 7d8560e7f6dbdfcc1b8bb86cf524faffcd52d17d Mon Sep 17 00:00:00 2001 From: brian crabtree Date: Wed, 24 Apr 2024 12:40:58 -0400 Subject: [PATCH 18/33] accel for potentiometers (#1776) --- lua/core/encoders.lua | 4 ++++ lua/core/norns.lua | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lua/core/encoders.lua b/lua/core/encoders.lua index 6fefa7464..412c1d199 100644 --- a/lua/core/encoders.lua +++ b/lua/core/encoders.lua @@ -42,6 +42,10 @@ end --- process delta encoders.process = function(n,d) encoders.tick[n] = encoders.tick[n] + d + if encoders.accel[n] then + local s = d<0 and -1 or 1 + d = s * math.pow(math.abs(d),1.6) + end if math.abs(encoders.tick[n]) >= encoders.sens[n] then local val = encoders.tick[n] / encoders.sens[n] val = (val > 0) and math.floor(val) or math.ceil(val) diff --git a/lua/core/norns.lua b/lua/core/norns.lua index f5312623e..87c6e49ac 100644 --- a/lua/core/norns.lua +++ b/lua/core/norns.lua @@ -130,8 +130,8 @@ norns.script = require 'core/script' norns.state = require 'core/state' norns.encoders = require 'core/encoders' ---_norns.enc = _norns.adc_rev() and norns.encoders.process or norns.encoders.process_with_accel -_norns.enc = norns.encoders.process_with_accel +_norns.enc = _norns.adc_rev() and norns.encoders.process or norns.encoders.process_with_accel +--_norns.enc = norns.encoders.process_with_accel -- extend paths config table local p = _path From 9cd6212892baf72c60387ba9feeab90ff08d850d Mon Sep 17 00:00:00 2001 From: tehn Date: Wed, 24 Apr 2024 15:16:54 -0400 Subject: [PATCH 19/33] 240424 --- update/changelog.txt | 10 ++++++++++ update/version.txt | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/update/changelog.txt b/update/changelog.txt index c14eabee6..2093a349c 100644 --- a/update/changelog.txt +++ b/update/changelog.txt @@ -1,3 +1,13 @@ +# 240424 + +# norns 2.8.3 + +- NEW acceleration for inf pots #1776 @tehn +- FIX grid rotation #1772 @tehn +- FIX tape play return on open #1770 @catfact +- FIX update.sh apply shield update correctly + + # 240221 # norns 2.8.2 diff --git a/update/version.txt b/update/version.txt index 6dd15d09d..6b11c906b 100644 --- a/update/version.txt +++ b/update/version.txt @@ -1 +1 @@ -240221 +240424 From 62db26e70398b30b14649fa5f82c40ff960f96de Mon Sep 17 00:00:00 2001 From: tehn Date: Wed, 24 Apr 2024 15:33:25 -0400 Subject: [PATCH 20/33] releases.txt --- releases.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/releases.txt b/releases.txt index 90fdd8d93..40bd96a3f 100644 --- a/releases.txt +++ b/releases.txt @@ -5,8 +5,8 @@ releases = { sha="https://github.com/monome/norns/releases/download/v2.8.2/norns240221.sha256" }, beta = { - version="240221", - url="https://github.com/monome/norns/releases/download/v2.8.2/norns240221.tgz", - sha="https://github.com/monome/norns/releases/download/v2.8.2/norns240221.sha256" + version="240424", + url="https://github.com/monome/norns/releases/download/v2.8.3/norns240424.tgz", + sha="https://github.com/monome/norns/releases/download/v2.8.3/norns240424.sha256" } } From 6f52ef200680e869ec69c8e4f9dd50cf191a3057 Mon Sep 17 00:00:00 2001 From: tehn Date: Wed, 24 Apr 2024 15:47:13 -0400 Subject: [PATCH 21/33] releases.txt --- releases.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/releases.txt b/releases.txt index 40bd96a3f..ccf2b8381 100644 --- a/releases.txt +++ b/releases.txt @@ -1,8 +1,8 @@ releases = { stable = { - version="240221", - url="https://github.com/monome/norns/releases/download/v2.8.2/norns240221.tgz", - sha="https://github.com/monome/norns/releases/download/v2.8.2/norns240221.sha256" + version="240424", + url="https://github.com/monome/norns/releases/download/v2.8.3/norns240424.tgz", + sha="https://github.com/monome/norns/releases/download/v2.8.3/norns240424.sha256" }, beta = { version="240424", From 77f69b18d9336604898d42d8a817f3272df879f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hallmar=20Gauti=20Halld=C3=B3rsson?= <38192440+hallmar@users.noreply.github.com> Date: Sun, 5 May 2024 23:20:28 +0000 Subject: [PATCH 22/33] Keyboard stroke wakes up screen (#1778) --- lua/core/keyboard.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/core/keyboard.lua b/lua/core/keyboard.lua index 0894abee9..f59a40a34 100644 --- a/lua/core/keyboard.lua +++ b/lua/core/keyboard.lua @@ -131,7 +131,7 @@ function keyboard.process(type,code,value) if c == nil then return end - + screen.ping() -- textentry keycode if te_kbd_cb.code then te_kbd_cb.code(c,value) From 239956e658bc4a81651571657442e4f7fd10a73c Mon Sep 17 00:00:00 2001 From: brian crabtree Date: Tue, 7 May 2024 10:05:58 -0400 Subject: [PATCH 23/33] fix acceleration function switch (#1780) --- lua/core/norns.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/core/norns.lua b/lua/core/norns.lua index 87c6e49ac..11cc2845b 100644 --- a/lua/core/norns.lua +++ b/lua/core/norns.lua @@ -130,7 +130,7 @@ norns.script = require 'core/script' norns.state = require 'core/state' norns.encoders = require 'core/encoders' -_norns.enc = _norns.adc_rev() and norns.encoders.process or norns.encoders.process_with_accel +_norns.enc = _norns.adc_rev()==1 and norns.encoders.process or norns.encoders.process_with_accel --_norns.enc = norns.encoders.process_with_accel -- extend paths config table From 7a96b19456c7d578814346530fb408d588a757de Mon Sep 17 00:00:00 2001 From: dan derks Date: Tue, 14 May 2024 09:26:30 -0400 Subject: [PATCH 24/33] improve binary-style param set/get (#1781) --- lua/core/menu.lua | 1 + lua/core/menu/params.lua | 44 +++++++++++++++++++++++-------------- lua/core/params/binary.lua | 20 ++++++++++++----- lua/core/params/trigger.lua | 2 ++ 4 files changed, 44 insertions(+), 23 deletions(-) mode change 100644 => 100755 lua/core/menu.lua mode change 100644 => 100755 lua/core/params/binary.lua mode change 100644 => 100755 lua/core/params/trigger.lua diff --git a/lua/core/menu.lua b/lua/core/menu.lua old mode 100644 new mode 100755 index bbee81b3e..6ea585b89 --- a/lua/core/menu.lua +++ b/lua/core/menu.lua @@ -31,6 +31,7 @@ _menu.errormsg = "" _menu.shownav = false _menu.showstats = false _menu.previewfile = "" +_menu.binarystates = {triggered = {}, on = {}} -- menu pages local m = {} diff --git a/lua/core/menu/params.lua b/lua/core/menu/params.lua index 2464c3ffa..90f9f273c 100755 --- a/lua/core/menu/params.lua +++ b/lua/core/menu/params.lua @@ -121,6 +121,15 @@ local function write_pset(name) end end +local function delta_value(id,fine,d) + local prm = params:lookup_param(id) + if prm.t == params.tBINARY and prm.behavior == "toggle" then + prm:set(d) + elseif prm.t ~= params.tBINARY then + local dx = fine and (d / 20) or d + prm:delta(dx) + end +end m.key = function(n,z) if n==1 and z==1 then @@ -190,13 +199,13 @@ m.key = function(n,z) elseif t == params.tTRIGGER then if m.mode == mEDIT then params:set(i) - m.triggered[i] = 2 + _menu.binarystates.triggered[i] = 2 end elseif t == params.tBINARY and m.mode == mEDIT then params:delta(i,1) if params:lookup_param(i).behavior == 'trigger' then - m.triggered[i] = 2 - else m.on[i] = params:get(i) end + _menu.binarystates.triggered[i] = 2 + else _menu.binarystates.on[i] = params:get(i) end elseif m.mode == mMAP and params:get_allow_pmap(i) then local n = params:get_id(i) local pm = norns.pmap.data[n] @@ -225,7 +234,7 @@ m.key = function(n,z) if m.mode == mEDIT then params:delta(i, 0) if params:lookup_param(i).behavior ~= 'trigger' then - m.on[i] = params:get(i) + _menu.binarystates.on[i] = params:get(i) end end end @@ -329,8 +338,7 @@ m.enc = function(n,d) m.pos = i-1 -- adjust value elseif m.mode == mEDIT and n==3 and params.count > 0 then - local dx = m.fine and (d/20) or d - params:delta(page[m.pos+1],dx) + delta_value(page[m.pos + 1], m.fine, d) _menu.redraw() end -- MAPEDIT @@ -343,7 +351,7 @@ m.enc = function(n,d) local t = params:t(p) local pm = norns.pmap.data[n] if m.mpos==0 then - params:delta(page[m.pos+1],d) + delta_value(page[m.pos + 1], false, d) elseif m.mpos==3 then m.cc = util.clamp(m.cc+d,0,127) elseif m.mpos==4 then @@ -468,12 +476,12 @@ m.redraw = function() screen.text(params:get_name(p)) screen.move(127,10*i) if t == params.tTRIGGER then - if m.triggered[p] and m.triggered[p] > 0 then + if _menu.binarystates.triggered[p] and _menu.binarystates.triggered[p] > 0 then screen.rect(124, 10 * i - 4, 3, 3) screen.fill() end elseif t == params.tBINARY then - fill = m.on[p] or m.triggered[p] + fill = _menu.binarystates.on[p] or _menu.binarystates.triggered[p] if fill and fill > 0 then screen.rect(124, 10 * i - 4, 3, 3) screen.fill() @@ -660,19 +668,21 @@ m.init = function() if page == nil then build_page() end m.alt = false m.fine = false - m.triggered = {} + local trig = _menu.binarystates.triggered _menu.timer.event = function() - for k, v in pairs(m.triggered) do - if v > 0 then m.triggered[k] = v - 1 end + for k, v in pairs(trig) do + if v > 0 then + trig[k] = v - 1 + end end _menu.redraw() end - m.on = {} + local on = _menu.binarystates.on for i,param in ipairs(params.params) do if param.t == params.tBINARY then if params:lookup_param(i).behavior == 'trigger' then - m.triggered[i] = 2 - else m.on[i] = params:get(i) end + trig[i] = 2 + else on[i] = params:get(i) end end end _menu.timer.time = 0.2 @@ -735,8 +745,8 @@ norns.menu_midi_event = function(data, dev) for i,param in ipairs(params.params) do if params:lookup_param(i).behavior == params:lookup_param(r).behavior then if params:lookup_param(i).behavior == 'trigger' then - m.triggered[i] = 2 - else m.on[i] = params:get(i) end + _menu.binarystates.triggered[i] = 2 + else _menu.binarystates.on[i] = params:get(i) end end end end diff --git a/lua/core/params/binary.lua b/lua/core/params/binary.lua old mode 100644 new mode 100755 index 6c0c2e85d..4e830fdff --- a/lua/core/params/binary.lua +++ b/lua/core/params/binary.lua @@ -12,8 +12,8 @@ function Binary.new(id, name, behavior, default, allow_pmap) o.id = id o.name = name o.default = default or 0 - o.value = o.default o.behavior = behavior or 'trigger' + o.value = o.behavior ~= 'trigger' and o.default or 1 o.action = function() end if allow_pmap == nil then o.allow_pmap = true else o.allow_pmap = allow_pmap end return o @@ -25,10 +25,18 @@ end function Binary:set(v, silent) local silent = silent or false - v = (v > 0) and 1 or 0 - if self.value ~= v then - self.value = v - if silent==false then self:bang() end + local i = params.lookup[self.id] + v = v and v or 1 + if self.behavior == 'trigger' and v > 0 then + _menu.binarystates.triggered[i] = 2 + if silent == false then self:bang() end + elseif self.behavior ~= 'trigger' then + v = (v > 0) and 1 or 0 + if self.value ~= v then + self.value = v + _menu.binarystates.on[i] = v + if silent == false then self:bang() end + end end end @@ -47,7 +55,7 @@ function Binary:set_default() end function Binary:bang() - self.action(self.value) + self.action(self.behavior == 'trigger' and 1 or self.value) end function Binary:string() diff --git a/lua/core/params/trigger.lua b/lua/core/params/trigger.lua old mode 100644 new mode 100755 index 6216a3da9..72bb4104b --- a/lua/core/params/trigger.lua +++ b/lua/core/params/trigger.lua @@ -20,6 +20,8 @@ function Trigger:get() end function Trigger:set(v) + local i = params.lookup[self.id] + _menu.binarystates.triggered[i] = 2 self:bang() end From e11b68e1b931958f61e32c6220dd136a0fefe2ff Mon Sep 17 00:00:00 2001 From: dan derks Date: Thu, 30 May 2024 14:28:38 -0400 Subject: [PATCH 25/33] binary triggers: allow default of '1' (#1785) --- lua/core/params/binary.lua | 7 +++++-- lua/core/paramset.lua | 8 ++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/lua/core/params/binary.lua b/lua/core/params/binary.lua index 4e830fdff..1ce4f8036 100755 --- a/lua/core/params/binary.lua +++ b/lua/core/params/binary.lua @@ -11,9 +11,9 @@ function Binary.new(id, name, behavior, default, allow_pmap) o.t = tBINARY o.id = id o.name = name - o.default = default or 0 + o.default = default or (o.behavior ~= 'trigger' and 0 or 1) + o.value = o.default o.behavior = behavior or 'trigger' - o.value = o.behavior ~= 'trigger' and o.default or 1 o.action = function() end if allow_pmap == nil then o.allow_pmap = true else o.allow_pmap = allow_pmap end return o @@ -56,6 +56,9 @@ end function Binary:bang() self.action(self.behavior == 'trigger' and 1 or self.value) + if self.behavior == 'trigger' then + self.value = 0 + end end function Binary:string() diff --git a/lua/core/paramset.lua b/lua/core/paramset.lua index 44d8bba3c..7e39ca747 100755 --- a/lua/core/paramset.lua +++ b/lua/core/paramset.lua @@ -544,7 +544,11 @@ function ParamSet:read(filename, silent) if index and self.params[index] and not param_already_set[index] then if tonumber(value) ~= nil then - self.params[index]:set(tonumber(value), silent) + if self.params[index].t == self.tBINARY then + if self.params[index].behavior ~= "trigger" then + self.params[index]:set(tonumber(value), silent) + end + end elseif value == "-inf" then self.params[index]:set(-math.huge, silent) elseif value == "inf" then @@ -590,7 +594,7 @@ end --- bang all params. function ParamSet:bang() for _,v in pairs(self.params) do - if v.t ~= self.tTRIGGER and not (v.t == self.tBINARY and v.behavior == 'trigger') then + if v.t ~= self.tTRIGGER and not (v.t == self.tBINARY and v.behavior == 'trigger' and v.value == 0) then v:bang() end end From c0add2f3da5ebd28b7749ff5ba5630ea4779a7b5 Mon Sep 17 00:00:00 2001 From: Dan Stroud Date: Sun, 2 Jun 2024 19:50:47 -0500 Subject: [PATCH 26/33] Replace default font 04B_03__.TTF with norns.ttf containing 86 new glyphs (#1783) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * replace default font 04B_03__.TTF with norns.ttf - mv 04B_03__.TTF norns.ttf - update references to new font name - added Particle font to documentation - changes to font binary will occur on followup commit (preserving ability to Browse History back from norns.ttf) * update norns.ttf with 3 changes, 86 new glyphs Made changes to 3 existing glyphs: - Redesigned ♭ glyph to sit on baseline rather than extending 1 pixel below. - Remapped original glyph to U+E260 as a stylistic alternative. - Adjusted ~ glyph to be at a similar position as other operators (-+=). - Remapped original glyph to U+0303 as a stylistic alternative. - Redesigned ø glyph to be distinct from Ø - Original glyph is still available at U+00D8. Added 86 additional glyphs: - 4 arrows - 2 math - 10 media playback controls - 2 musical, full-size - 7 musical, superscript/superior - 14 roman numerals (1-7, for chords) - 10 superscript number - 27 superscript letters, lower - 1 superscript letter, upper (M, for chords) - 4 typographical including 3 space widths - 5 ui --- doc/modules/screen.html | 3 ++- lua/core/screen.lua | 5 +++-- matron/src/hardware/screen.c | 2 +- resources/04B_03__.TTF | Bin 21228 -> 0 bytes resources/norns.ttf | Bin 0 -> 28328 bytes 5 files changed, 6 insertions(+), 4 deletions(-) delete mode 100644 resources/04B_03__.TTF create mode 100644 resources/norns.ttf diff --git a/doc/modules/screen.html b/doc/modules/screen.html index a12899fd6..f6af96d51 100644 --- a/doc/modules/screen.html +++ b/doc/modules/screen.html @@ -997,7 +997,7 @@

Parameters:

  • index font face (see list, or Screen.font_face_names) -

    1 04B_03 (norns default) +

    1 norns (default) 2 ALEPH 3 Roboto Thin 4 Roboto Light @@ -1064,6 +1064,7 @@

    Parameters:

    65 unscii-8.pcf 66 unscii-8-tall.pcf 67 unscii-8-thin.pcf + 68 Particle
diff --git a/lua/core/screen.lua b/lua/core/screen.lua index ca5831fb6..a5bfe0c20 100644 --- a/lua/core/screen.lua +++ b/lua/core/screen.lua @@ -218,7 +218,7 @@ Screen.current_point = function() return _norns.screen_current_point() end --- select font face. -- @param index font face (see list, or Screen.font_face_names) -- --- 1 04B_03 (norns default) +-- 1 norns (default) -- 2 ALEPH -- 3 Roboto Thin -- 4 Roboto Light @@ -285,10 +285,11 @@ Screen.current_point = function() return _norns.screen_current_point() end -- 65 unscii-8.pcf -- 66 unscii-8-tall.pcf -- 67 unscii-8-thin.pcf +-- 68 Particle Screen.font_face = function(index) _norns.screen_font_face(index) end Screen.font_face_count = 68 Screen.font_face_names = { - "04B_03__", + "norns", "liquid", "Roboto-Thin", "Roboto-Light", diff --git a/matron/src/hardware/screen.c b/matron/src/hardware/screen.c index 486e0d12f..1bb47fdc2 100644 --- a/matron/src/hardware/screen.c +++ b/matron/src/hardware/screen.c @@ -159,7 +159,7 @@ void init_font_faces(void) { } int font_idx = 0; - strcpy(font_path[font_idx++], "04B_03__.TTF"); + strcpy(font_path[font_idx++], "norns.ttf"); strcpy(font_path[font_idx++], "liquid.ttf"); strcpy(font_path[font_idx++], "Roboto-Thin.ttf"); strcpy(font_path[font_idx++], "Roboto-Light.ttf"); diff --git a/resources/04B_03__.TTF b/resources/04B_03__.TTF deleted file mode 100644 index 1deb3b8ac24c07ecf620010edc918cc9aaf5d676..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21228 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 VSAMiU{b+qcEd6MG`hnM{e*ylZaQOfL literal 0 HcmV?d00001 From 4df821779e949d3efabb2d3ca61bf316713db752 Mon Sep 17 00:00:00 2001 From: Dan Stroud Date: Mon, 17 Jun 2024 19:46:49 -0500 Subject: [PATCH 27/33] =?UTF-8?q?Added=20=E2=96=A6=20glyph,=20adjusted=20s?= =?UTF-8?q?pacing=20on=203=20more=20(#1786)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * replace default font 04B_03__.TTF with norns.ttf - mv 04B_03__.TTF norns.ttf - update references to new font name - added Particle font to documentation - changes to font binary will occur on followup commit (preserving ability to Browse History back from norns.ttf) * update norns.ttf with 3 changes, 86 new glyphs Made changes to 3 existing glyphs: - Redesigned ♭ glyph to sit on baseline rather than extending 1 pixel below. - Remapped original glyph to U+E260 as a stylistic alternative. - Adjusted ~ glyph to be at a similar position as other operators (-+=). - Remapped original glyph to U+0303 as a stylistic alternative. - Redesigned ø glyph to be distinct from Ø - Original glyph is still available at U+00D8. Added 86 additional glyphs: - 4 arrows - 2 math - 10 media playback controls - 2 musical, full-size - 7 musical, superscript/superior - 14 roman numerals (1-7, for chords) - 10 superscript number - 27 superscript letters, lower - 1 superscript letter, upper (M, for chords) - 4 typographical including 3 space widths - 5 ui * Added ▦ glyph, realigned 3 others - Added ▦ U+25A6 Square with Orthogonal Crosshatch Fill - Removed leading space on • - Lowered ◢, ◣ to sit at baseline --- resources/norns.ttf | Bin 28328 -> 28640 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/resources/norns.ttf b/resources/norns.ttf index b764f6749adfaa732c8c282d94742dc4a9b6059d..464629bf9b8da9de94767ce226acbb7a0816471d 100644 GIT binary patch delta 2009 zcmeH{`)`v~7{|ZoZP)e2wo(b(G|*8t(4lGT(j{P~unSuShKn&v*kGkA>q2R_w%a-w zRtY3TW5PTML1TnOB>X@W?KFzS3~wl)VlakGj0WWrgy1g_ltlc#eGicR51y0nc|Paq zbKY}#&gsEl#BaZfU7p;j(RXb?^drE&urEHk;Y7{g2Y~erpnW114fnPk`t&ByRR$m! zqoYK#{>9%r*`FWVl*w)+@b^~0bTpofgyB7#1v*!=Ke;KK9l+lRFn)|do;0m0KK$ z1s?awptag@9ilKz05<80&CYMNMr*4%DKwb49Kcmo<|xp7`31J19)maH9*}0meMXg zN|BeB1+Zg0{rTwzPxmUia5;dP}?+2(x}o zc8YPu0(PxJv4#@OtJs9cG{0gqDz$Zri{R8o6fJ-%vc93e@?6{`&kg zVW*JE$a4-457}3chr_+n5h-&$s(f`=j3DKgXV-g8LE3-UA8$+`i4+n@!-Elo3pPSe zl$>GPOaBnP{fy}&uO?;bkE5k9vJX*tE^@q1zyDl4P-7ghDW&g)4d9wl`>7=PXJCQb5IF99k0D$F zE)P(HjJXV4qyJhj`3gkw+XVp^Abxm+s-^#Th#O{<=nZg@e{2>?j>jI7563P#^pV@~ z0`I{-Mb+ngyfu!&9hGOJTCE>vHYLqX<05-S^f`2O@2WD delta 1807 zcmd6m?@wD*7{|Zo-cm|iV1Nm1Q&;E!b+dyG#v}{FIev987GF5oaL|=PTU%P8SlEz~ zg+xir!g4j5B{Pd|aWBxA-NYEh$ow^bywDk6Rm~hhk;LI*oYPnOz1)LK{0H=$eENK! z=RD87=bq>E`>W!@cVfns9=OMI3+Ouw*sTN6vHtC^jNK2|#(~bNP|)AkHgo=I;BW}Q zjt~QRitQJ!@1(yu6ibfwLr@-Oz4}%(9`M6`q7gVaOMforA5GvEyv*-rl55Z(3!eV{ z=(|AAqd-=3B0ij(?7H#V-GFcc+4r8BP35mJ(;QUdnC=yqMDcMkE}jw-Vn_^&q!$3x0DM8 zRZe8{Wu>JB1;mI6{KYAiURiUxQ158TR~-TtWC8g=fi~c))aL7LTHd}wM=9&%)cj3u z#@6dgzT~=eFVJw7d<*O@A^h;&FOo%|F-mA3tRe~W2Dt(3p}&VU58X-50efA9eiLmI z{pQW&0?@LRu%_iVptYTR2(;}YQ{+p)*9h$Q%>euEAkUJofp!MlpCc^lU{^b4$sbIl z-al`2onOtf0Mc`>UhK)=brXt>0bt=+_q4vXyIoN&5Zdu0SF{5?OX+PqPouyn$%0>M zh39GB4Bi72BPQb(OIjM8dfOn*}qYQsa?Z76n(a>qW*h!~e zE)>Bny7)?A$>GWoF)p=$U1X$IkS7+UR^bu9N^QXg#U*tXoJzgaR>qs9w!x$HN}Ypo zrTV0F>?l#~QajL~mPzfTUMnaoxxl}dT4YCMsI zCq6WwedBi(*VcRM2IE76!>)&e10zxYkhi9))?2L?9(9WKT^Kn+!B$*P@=SsnaI>8?>u|Y_%3%Z8>l`*T@?rF$Ce#DuZpBH~7qU3r~yx0#umi zsP-G%2P{!qJ7E2oYfb{S(fH-qtFHv>l=SOBIl(2`izaxV_DvIfK>M}{ct6YMOz;uy zyb1X5atSU|e`unaGspe*F1#W;yd-=H-m>c$B1yrdJPll8L~C5#ty&4Te@H!0oU-K=hvp oHaa4+Zkt0e=k3S={Cnmbfwj?!R?Qb}D!Rt6{y%nd{J-qv-{^)}jsO4v From 0235b8f5c12d9fd9b23a6e623698fd4b61da3e83 Mon Sep 17 00:00:00 2001 From: Dan Stroud Date: Wed, 19 Jun 2024 09:29:31 -0500 Subject: [PATCH 28/33] fix for paramset:read() not setting values (#1787) Fixes issue introduced in #1785 which prevents paramset:read() from setting non-binary param values on .pset load. --- lua/core/paramset.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lua/core/paramset.lua b/lua/core/paramset.lua index 7e39ca747..289a60fe1 100755 --- a/lua/core/paramset.lua +++ b/lua/core/paramset.lua @@ -548,6 +548,8 @@ function ParamSet:read(filename, silent) if self.params[index].behavior ~= "trigger" then self.params[index]:set(tonumber(value), silent) end + else + self.params[index]:set(tonumber(value), silent) end elseif value == "-inf" then self.params[index]:set(-math.huge, silent) From 15c9cf9304d500b28c7ad04d6ddf4f85a4a6d095 Mon Sep 17 00:00:00 2001 From: dan derks Date: Wed, 10 Jul 2024 13:13:14 -0400 Subject: [PATCH 29/33] Update sleep.lua (#1790) --- lua/core/menu/sleep.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lua/core/menu/sleep.lua b/lua/core/menu/sleep.lua index 9a96c48c8..0acb5b08e 100644 --- a/lua/core/menu/sleep.lua +++ b/lua/core/menu/sleep.lua @@ -5,9 +5,10 @@ m.key = function(n,z) _menu.set_page("HOME") elseif n==3 and z==1 then m.sleep = true + if _menu.m.TAPE.rec.sel == 3 then + audio.tape_record_stop() + end _menu.redraw() - -- TODO - --if m.tape.rec.sel == TAPE_REC_STOP then audio.tape_record_stop() end norns.shutdown() end end From c6e5dfae714f58a5ba9308f789e3b041a371e204 Mon Sep 17 00:00:00 2001 From: Dan Stroud Date: Mon, 9 Sep 2024 13:13:26 -0500 Subject: [PATCH 30/33] fix text param val converting to number (#1796) - added check to prevent text param values from inadvertently being converted to numbers when reading pset file --- lua/core/paramset.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/core/paramset.lua b/lua/core/paramset.lua index 289a60fe1..5120e2af9 100755 --- a/lua/core/paramset.lua +++ b/lua/core/paramset.lua @@ -543,7 +543,7 @@ function ParamSet:read(filename, silent) local index = self.lookup[id] if index and self.params[index] and not param_already_set[index] then - if tonumber(value) ~= nil then + if self.params[index].t ~= self.tTEXT and tonumber(value) ~= nil then if self.params[index].t == self.tBINARY then if self.params[index].behavior ~= "trigger" then self.params[index]:set(tonumber(value), silent) From 42961b9cf7e986933663e8e084c924e6caee3132 Mon Sep 17 00:00:00 2001 From: tehn Date: Wed, 11 Sep 2024 10:03:09 -0400 Subject: [PATCH 31/33] 240911 --- update/changelog.txt | 10 ++++++++++ update/version.txt | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/update/changelog.txt b/update/changelog.txt index 2093a349c..76ed81265 100644 --- a/update/changelog.txt +++ b/update/changelog.txt @@ -1,3 +1,13 @@ +# 240911 + +# norns 2.8.4 + +- NEW norns font with 86 new glyphs #1783 @dstroud +- FIX paramset fixes #1787 #1796 @dstroud +- FIX binary params #1781 #1785 @dndrks +- FIX keyboard wakes up screen #1778 @hallmar + + # 240424 # norns 2.8.3 diff --git a/update/version.txt b/update/version.txt index 6b11c906b..e46207b3c 100644 --- a/update/version.txt +++ b/update/version.txt @@ -1 +1 @@ -240424 +240911 From a9297d046ccce468ddb2e51160257220b9a8d76b Mon Sep 17 00:00:00 2001 From: tehn Date: Wed, 11 Sep 2024 10:14:52 -0400 Subject: [PATCH 32/33] releases.txt --- releases.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/releases.txt b/releases.txt index ccf2b8381..f5514cc23 100644 --- a/releases.txt +++ b/releases.txt @@ -5,8 +5,8 @@ releases = { sha="https://github.com/monome/norns/releases/download/v2.8.3/norns240424.sha256" }, beta = { - version="240424", - url="https://github.com/monome/norns/releases/download/v2.8.3/norns240424.tgz", - sha="https://github.com/monome/norns/releases/download/v2.8.3/norns240424.sha256" + version="240911", + url="https://github.com/monome/norns/releases/download/v2.8.4/norns240911.tgz", + sha="https://github.com/monome/norns/releases/download/v2.8.4/norns240911.sha256" } } From 15578a14c03e7b543c16121b85c33a20b5907cfa Mon Sep 17 00:00:00 2001 From: tehn Date: Wed, 11 Sep 2024 10:29:03 -0400 Subject: [PATCH 33/33] releases.txt --- releases.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/releases.txt b/releases.txt index f5514cc23..28f2eac81 100644 --- a/releases.txt +++ b/releases.txt @@ -1,8 +1,8 @@ releases = { stable = { - version="240424", - url="https://github.com/monome/norns/releases/download/v2.8.3/norns240424.tgz", - sha="https://github.com/monome/norns/releases/download/v2.8.3/norns240424.sha256" + version="240911", + url="https://github.com/monome/norns/releases/download/v2.8.4/norns240911.tgz", + sha="https://github.com/monome/norns/releases/download/v2.8.4/norns240911.sha256" }, beta = { version="240911",