TR123e - EMCT Computing Final Project Version 1.0
Research Project Translation from gen~ to embedded Moog synth
Loading...
Searching...
No Matches
PortamentoFilter Class Reference

Musical technique analyzer for intelligent portamento triggering. More...

#include <PortamentoFilter.h>

Public Member Functions

 PortamentoFilter ()
 Initialize portamento filter with default state.
bool checkPortamento (int newNote, bool noteOn, float currentTimeMs)
 Analyze note event and determine portamento requirement.

Private Attributes

int previousNote
 Previous MIDI note number for comparison analysis.
bool previousNoteActive
 Previous note activity state indicator.
float previousNoteOffTime
 Timestamp of most recent note-off event.

Detailed Description

Musical technique analyzer for intelligent portamento triggering.

The PortamentoFilter class implements real-time analysis of MIDI note patterns to determine when portamento should be applied based on legato playing technique detection. This provides musically intelligent behavior that responds appropriately to different performance styles without requiring explicit control messages.

@design_philosophy The implementation prioritizes musical accuracy over technical complexity, using simple but effective heuristics that match performer expectations from acoustic instruments. The algorithm errs toward conservative portamento triggering to avoid unwanted pitch slides during fast passages.

@state_machine_design

[IDLE] --note_on--> [NOTE_ACTIVE]
| |
| note_on(different) --> [PORTAMENTO_TRIGGER]
| |
+--note_off<------------+

@musical_applications

  • Lead synthesizer voices requiring expressive pitch slides
  • Bass lines with smooth frequency transitions
  • Vocal synthesis emulation with natural portamento
  • Educational software teaching legato technique

@usage_example

// In MIDI processing loop:
bool usePortamento = filter.checkPortamento(noteNumber, isNoteOn, timestamp);
if (usePortamento) {
player.noteOn(noteNumber, true); // Enable smooth transition
} else {
player.noteOn(noteNumber, false); // Immediate frequency jump
}
bool checkPortamento(int newNote, bool noteOn, float currentTimeMs)
Analyze note event and determine portamento requirement.
Definition PortamentoFilter.cpp:50
PortamentoFilter()
Initialize portamento filter with default state.
Definition PortamentoFilter.cpp:25

Constructor & Destructor Documentation

◆ PortamentoFilter()

PortamentoFilter::PortamentoFilter ( )

Initialize portamento filter with default state.

Initialize portamento filter to safe default state.

Constructs filter in idle state with no previous note information. All state variables are initialized to safe default values that prevent spurious portamento triggering on first note.

@complexity O(1) - Constant time initialization @memory 12 bytes total object size (platform dependent) @thread_safety Safe for concurrent construction

Sets all state variables to values that ensure proper behavior on first note event. The initialization prevents spurious portamento triggering when no valid previous note context exists.

@implementation_details

  • previousNote = -1: Indicates no valid previous note (outside MIDI range)
  • previousNoteActive = false: Ensures first note won't trigger portamento
  • previousNoteOffTime = 0.0f: Safe default timestamp value

Member Function Documentation

◆ checkPortamento()

bool PortamentoFilter::checkPortamento ( int newNote,
bool noteOn,
float currentTimeMs )

Analyze note event and determine portamento requirement.

Analyze note event and determine portamento application.

Processes incoming MIDI note events to determine whether portamento should be applied based on legato playing technique detection. The algorithm analyzes note overlap patterns and pitch relationships to provide musically intelligent portamento behavior.

Parameters
newNoteMIDI note number [0-127] for current note event
noteOnBoolean indicating note-on (true) or note-off (false)
currentTimeMsCurrent timestamp in milliseconds for temporal analysis
Returns
true if portamento should be applied for this note transition false if note should start immediately without pitch slide

@complexity O(1) - Constant time analysis @determinism Bounded execution time regardless of input values @realtime_safety Real-time safe (no blocking operations)

@algorithm_logic For note-on events:

  1. Check if previous note is still active (overlap condition)
  2. Verify new note differs from previous (pitch change requirement)
  3. Update internal state with new note information
  4. Return portamento decision based on overlap AND pitch change

For note-off events:

  1. Mark previous note as inactive
  2. Record note-off timestamp for future temporal analysis
  3. Return false (portamento not applicable to note-off)

@musical_considerations

  • Portamento only triggers for overlapping notes with different pitches
  • Same-note retriggering does not activate portamento (trill protection)
  • Note-off events update state but never trigger portamento
  • First note after silence never triggers portamento (no source pitch)

@edge_cases

  • Rapid note repetition: Prevented by pitch difference requirement
  • Simultaneous note-on/note-off: Handled by state precedence rules
  • Invalid MIDI note numbers: Processed without validation for performance
Parameters
newNoteMIDI note number for analysis
noteOnNote event type (true=on, false=off)
currentTimeMsCurrent system timestamp
Returns
Portamento decision for this note transition

@algorithm_implementation The algorithm implements a simple but musically effective state machine that tracks note overlap conditions and pitch relationships to determine when smooth pitch transitions are appropriate.

@performance_analysis

  • No loops or recursion: O(1) guaranteed execution time
  • Minimal branching: CPU branch predictor friendly
  • No function calls: Inline operations for maximum efficiency
  • Cache efficient: All data in single object instance

Local variable for portamento decision Initialized to false (conservative default)

Process note-on events for legato analysis

Check for legato condition: overlapping notes with different pitches

Conditions for portamento triggering:

  1. previousNoteActive: Previous note still sustaining (overlap)
  2. previousNote != newNote: Different pitch (slide required)

This logic ensures portamento only occurs for musically appropriate transitions where the performer intends smooth pitch connection.

Notes overlap and are different: trigger portamento This represents classic legato playing technique where the performer connects notes smoothly without gaps.

Either no overlap or same note: no portamento Cases covered:

  • First note (no previous active note)
  • Staccato playing (gap between notes)
  • Note retriggering (same pitch, no slide needed)

Update state for next iteration Mark new note as active and store its pitch for future comparison

Process note-off events: update state without triggering portamento

Note-off events never trigger portamento but update internal state to track note activity and timing for subsequent analysis.

Member Data Documentation

◆ previousNote

int PortamentoFilter::previousNote
private

Previous MIDI note number for comparison analysis.

Stores the MIDI note number of the most recently active note for pitch comparison with incoming notes. Used to determine if portamento should be applied based on pitch interval requirements.

@range [0-127] for valid MIDI notes, -1 for uninitialized state @initialization -1 (no previous note available) @update_policy Updated on every note-on event

◆ previousNoteActive

bool PortamentoFilter::previousNoteActive
private

Previous note activity state indicator.

Boolean flag indicating whether the previous note is still conceptually "active" from a musical perspective. This determines overlap conditions for legato detection and portamento triggering logic.

@states

  • true: Previous note still active (sustaining or in release phase)
  • false: No active previous note (idle or after note-off)

@musical_significance Represents the performer's intent regarding note connection. Active state indicates potential for legato playing and portamento application.

◆ previousNoteOffTime

float PortamentoFilter::previousNoteOffTime
private

Timestamp of most recent note-off event.

Records the precise timing of the last note-off event for potential future use in temporal analysis algorithms. Currently used for state tracking but provides foundation for advanced timing-based heuristics.

@units Milliseconds (float precision for sub-millisecond accuracy) @range [0.0, ∞) - Monotonically increasing timestamps @precision Limited by system timer resolution and float representation

@future_applications

  • Gap-based portamento decisions (short gaps = portamento)
  • Velocity-sensitive portamento intensity
  • Timing-based performance style analysis

The documentation for this class was generated from the following files: