CHANGE LOG

####################################################################################################

2.1.0:

New Features / Changes:

[spectrogram~]:
    - Added keyboard shortcuts for undo/redo: Cmd-Z / Cmd-Shift-Z on macOS, Ctrl-Z /
      Ctrl-Shift-Z on Windows. The spectrogram~ object must have keyboard focus (click into
      it first); otherwise Max routes the shortcut to patcher-level undo/redo. The
      right-click menu's Undo/Redo entries display these shortcuts.
    - Added clear_history message: drops both undo and redo stacks. Useful when a control
      patch swaps the contents of the reference buffer~ in place (without changing
      @buffer_name), or to free snapshot memory once a series of edits is considered final.
      Changing @buffer_name continues to clear history automatically.

Bug Fixes:

- No bugs found or reported.

####################################################################################################

2.0.0:

New Features / Changes:

[spectrogram~]:
    - Replaced kiss_fft with pffft for SIMD-accelerated FFT (SSE on x86, NEON on ARM).
    - Added @freq_reassign attribute to provide frequency reassignment functionality.
    - Added @time_format attribute to control time axis label format (H:MM:SS, Milliseconds,
      Seconds, Min:Sec, Min:Sec.ms, Samples). Default: Seconds.
    - Updated [spectrogram~] write message to save PNG using current object dimensions if width
      and height are not specified.
    - Updated help patches, snippets, and xml reference docs to align with latest changes.

    New Draw mouse mode (@mouse_mode 2):
        - Added Draw mouse mode (@mouse_mode 2) for drawing closed shapes on the spectrogram.
            - Click-and-drag to draw shapes. Shift-click inside a shape to remove it.
            - Up to 64 shapes, 4096 total points.
        - Added @draw_linewidth attribute: line width for drawn shapes (range 1-20, default 2).
        - Added @draw_linecolor attribute: line color for drawn shapes (default white).

    New in-place buffer~ editing functionality:
        - Added the following new messages:
            edit_selection_isolate message:
                keeps audio inside the selection rectangle, zeros everything else, and writes
                result to the reference buffer.
            edit_selection_delete message:
                zeros audio inside the selection rectangle, keeps everything else, and writes
                result to the reference buffer.
            edit_selection_gain message:
                applies dB gain to bins inside (and optionally outside) the selection rectangle.
                    - One argument applies gain inside only.
                    - Two arguments apply gain inside and outside independently.
            edit_selection_freq_shift message:
                shifts bins inside the selection rectangle by a constant Hz offset (additive).
                    - Takes one float argument (Hz). 
                    - Optional second argument sets gain in dB applied to the shifted content 
                      (default 0 = no change). 
                    - Optional third argument sets the mode (int or symbol): 
                        0/move-mix (default), 1/move-replace, 2/copy-mix, 3/copy-replace.
            edit_selection_pitch_shift message:
                shifts bins inside the selection rectangle by a musical interval (semitone-based,
                ratio = 2^(semitones/12), preserves harmonic relationships). 
                    - Takes one float argument (semitones). 
                    - Optional second argument sets gain in dB applied to the shifted content 
                      (default 0 = no change). 
                    - Optional third argument sets the mode (int or symbol): 
                        0/move-mix (default), 1/move-replace, 2/copy-mix, 3/copy-replace.
            edit_shapes_isolate message:
                keeps audio inside drawn shapes, zeros everything else, and writes result to
                the reference buffer.
            edit_shapes_delete message:
                zeros audio inside drawn shapes, keeps everything else, and writes result to
                the reference buffer.
            edit_shapes_gain message:
                applies dB gain to bins inside (and optionally outside) drawn shapes.
                    - One argument applies gain inside only.
                    - Two arguments apply gain inside and outside independently.
            edit_shapes_freq_shift message:
                shifts bins inside drawn shapes by a constant Hz offset (additive). 
                    - Takes one float argument (Hz). 
                    - Optional second argument sets gain in dB applied to the shifted content 
                      (default 0 = no change). 
                    - Optional third argument sets the mode (int or symbol): 
                        0/move-mix (default), 1/move-replace, 2/copy-mix, 3/copy-replace.
            edit_shapes_pitch_shift message:
                shifts bins inside drawn shapes by a musical interval (semitone-based,
                ratio = 2^(semitones/12), preserves harmonic relationships). 
                    - Takes one float argument (semitones). 
                    - Optional second argument sets gain in dB applied to the shifted content 
                      (default 0 = no change). 
                    - Optional third argument sets the mode (int or symbol): 
                        0/move-mix (default), 1/move-replace, 2/copy-mix, 3/copy-replace.
            edit_shapes_clear message:
                removes all drawn shapes.
            edit_shapes_clearlast message:
                removes the most recently drawn shape (undo one at a time).
            NOTE: When @buffer_chan is 0 (mixdown), edit messages process each channel of the
                  reference buffer independently rather than writing the mixdown to all channels.
        - Shift modes:
            0 = Move (mix) — zero source, add to destination (default)
            1 = Move (replace) — zero source, clear destination, write
            2 = Copy (mix) — keep source, add to destination
            3 = Copy (replace) — keep source, clear destination, write
        - Added undo message: restores the reference buffer to the state before the last edit
          operation (up to 20 levels).
        - Added redo message: re-applies the most recently undone edit operation (up to 20
          levels).
        - Added @edit_win_size attribute: STFT window size for analysis-synthesis (range
          32-8192, default 2048).
        - Added @edit_inverted attribute (0/1, default 0): when enabled, all edit operations
          (isolate, delete, gain, frequency shift, pitch shift) apply to bins OUTSIDE the
          selection or shapes instead of inside. When active, closed drawn shapes and/or 
          selection rectangle display a cross-hatch pattern (diagonal lines at ~12px spacing,
          35% opacity in the respective color) to indicate exclusion. The right-click context 
          menu reflects the inverted state in menu item names.
        - Added right-click context menu (available in all mouse modes) with quick access to
          undo/redo, selection edit operations, shape edit operations, frequency shift, pitch
          shift, and shape management.
            - Menu items are enabled/disabled based on current state.
            - Gain items prompt for dB values via dialog.
            - Frequency shift and pitch shift items prompt for values and mode via dialog,
              with a legend showing all mode options.
            - Undo/redo items display the action name (e.g. "Undo Gain Selection").

    Color Scheme Updates:
        - Added 5 new perceptually uniform, colorblind-friendly color schemes: Viridis, Magma,
          Inferno, Plasma, and Cividis (CC0 public domain). Removed Classic color scheme.
        - Added Turbo color scheme (Apache 2.0, Google LLC): high-contrast rainbow colormap,
          improved replacement for Jet with smoother gradation and better colorblind performance.
        - Added Hot color scheme: standard thermal colormap (black -> red -> yellow -> white),
          a classic spectrogram color scheme.
        - Reordered color_scheme attribute: Roseus (0), Viridis (1), Magma (2), Inferno (3),
          Plasma (4), Cividis (5), Turbo (6), Hot (7), Greyscale (8), Custom (9), plus inverted
          variants (10-19).
        - NOTE THE BREAKING CHANGE: saved color_scheme indices from previous versions will map
          to different schemes.

[JSUI Toolbar & Mode Objects]:
    - Added spectrogram.toolbar.js: 15-button JSUI toolbar with zoom (6), view (4), and
      select (5) buttons in 3 groups, separated by vertical dividers.
        - Procedurally-drawn icons.
        - Outputs messages (zoom_in, view_all, select_all, etc.) from outlet.
        - Accepts 0-indexed ints to trigger buttons.
        - Hover hints appear after 500ms of mouse stillness.
    - Added spectrogram.modes.js: 3-button radio-style JSUI for mouse mode selection (Select,
      Move, Draw).
        - Procedurally-drawn cursor arrow, hand, and pencil icons.
        - Active mode shown with accent color.
        - Outputs "mouse_mode <int>" from outlet.
        - Accepts ints and "set <int>" to update display without output.
        - Hover hints appear after 500ms of mouse stillness.
        - Changed mouse_modes.maxpat abstraction (which now uses this jsui file) to map keys
          1, 2, 3 to the jsui index 0, 1, 2 respectively, replacing the Cmd/Alt, etc. behavior
          of the old version.
    - Added javascript/spectrogram_jsui_examples.maxpat: example patcher demonstrating both
      JSUI objects.

Bug Fixes:

- Fixed 5 critical section imbalances where critical_enter was called but critical_exit was
  skipped on early-return paths (select_all_freq, select_all_time, select_window_freq,
  select_window_time, 9th inlet list handler). Max's recursive mutex prevented deadlocks but
  lock counts remained permanently elevated.
- Fixed custom color scheme out-of-bounds array access when the greyscale interpolation value
  reached exactly 1.0 (index could reach 5, past the 5-element custom color array).
- Fixed jgraphics context leak: two jgraphics_create calls in text rendering had no matching
  jgraphics_destroy.
- Fixed buffer channel clamp logic inversion: condition was inverted, preventing channel number
  clamping when a buffer reference was present.

####################################################################################################

1.1.1:

New Features / Changes:

- Added snippet for spectrogram.bandpass abstraction.
- Comment improvement in spectrogram~.maxhelp.
- Minor under-the-hood code cleanup.

Bug Fixes:

- No bugs found or reported.

####################################################################################################

1.1.0:

New Features / Changes:

- Selection region is no longer bound by the current window view (mirroring similar behavior
  for selection in [waveform~]).
- Added the following new messages:
    - select_all, select_all_freq, select_all_time
- Moved spectral bandpass patcher into an abstraction, with accompanying help patch.
- Other cleanup and improvements to help patches, snippets, reference xml, etc.

Bug Fixes:

- No bugs found or reported.

####################################################################################################

1.0.1:

New Features / Changes:

- Added spectrogram.colorbar external to package.
- Minor improvement to internal notification logic.

Bug Fixes:

- No bugs found or reported.

####################################################################################################
