PS-80 GrandComp Analyzer 1.2
Loading...
Searching...
No Matches
Widget Class Reference

The primary application window and signal processing controller. More...

#include <widget.h>

Inheritance diagram for Widget:

Public Member Functions

 Widget (QWidget *parent=nullptr)
 Initializes the UI and prepares the XYSeriesIODevice.
virtual ~Widget ()
 Virtual destructor for clean resource management.
 Widget (const Widget &)=delete
Widgetoperator= (const Widget &)=delete

Protected Member Functions

void paintEvent (QPaintEvent *event) override
 Renders the waveform visualizations and playheads.
void mousePressEvent (QMouseEvent *event) override
 Handles sample-precise selection within the waveform view.

Private Slots

File and Configuration Slots
void onOpenButtonClicked ()
 Slot: Handles the 'Open' button click event.
void onSaveButtonClicked ()
 Slot: Exports the currently captured waveform cycle to a CSV file.
void onBrowseFolderButtonClicked ()
 Slot: Handles the folder selection for waveform exports (the "Photo Shoot").
void onComboBoxFreqCurrentTextChanged (const QString &text)
 Slot: Updates the synthesis frequency based on UI selection.
Playback Control Slots
void onPlayWavButtonClicked ()
 Slot: Initiates full WAV file playback.
void onPauseWavButtonClicked ()
 Slot: Suspends audio playback by halting signal progression.
void onPlayClipButtonClicked ()
 Slot: Initiates playback of the captured single-cycle waveform.
void onPauseClipButtonClicked ()
 Slot: Halts the single-cycle waveform oscillator.
Signal Processing Slots
void onFloatingClipButtonClicked ()
 Slot: Toggles the sub-sample precision mode (Floating Clip).
void onMoveLeftButtonClicked ()
 Slot: Shifts the waveform data to the left within the viewing window.
void onMoveRightButtonClicked ()
 Slot: Shifts the waveform data to the right within the viewing window.
void onStretchButtonClicked ()
 Slot: Stretches the waveform by reducing the source window length.
void onShrinkedButtonClicked ()
 Slot: Shrinks the waveform by increasing the source window length.
void onFlipTimeButtonClicked ()
 Slot: Toggles the temporal mirroring (X-axis) of the captured waveform.
void onFlipPhaseButtonClicked ()
 Slot: Toggles the temporal mirroring (Y-axis) of the captured waveform.

Private Member Functions

Internal Rendering Methods
void drawWavFileContents (QPainter *painter, QWidget *target, const std::vector< float > &data)
 Renders the macro view of the entire WAV file.
void drawWaveformContents (QPainter *painter, QWidget *target, const std::vector< float > &data)
 Renders the detailed micro-view of the captured waveform cycle.
Core Signal Analysis Methods (The "Scientific" Wing)
void setupAudio ()
 Initializes the Qt Audio output stack and the custom XYSeriesIODevice.
void loadWavFile (const QString &fileName)
 Loads raw PCM data from a WAV file into m_fullWavData.
void updateButtonStates ()
 Manages the enabled/disabled state of UI elements based on engine state.
void normalizeCapturedCycle (std::vector< float > &capturedCycle)
 Peak-normalization algorithm. Scales the captured segment to utilize the full dynamic range [-1.0, 1.0].
void waveformBackup (const int centerSample)
 Creates a safety backup of the currently selected waveform segment.
void copyWaveform (std::vector< float > &dest, const std::vector< float > &source)
 Copies waveform data between buffers.
void stretchWaveform (std::vector< float > &dest, const std::vector< float > &source, const int waveformeLen)
 Mathematical resampling of the waveform. Maps the source segment into the target m_waveformLen using linear interpolation.
void flipTimeWaveform (std::vector< float > &dest)
 Reverses the time of the current captured cycle.
void flipPhaseWaveform (std::vector< float > &dest)
 Reverses the phase of the current captured cycle.

Private Attributes

Ui::Widget * ui
Qt::CheckState m_stateFloatingClip = Qt::CheckState::Unchecked
QAudioOutput * m_audioOutput {nullptr}
XYSeriesIODevicem_device {nullptr}
int m_lastClickSample {0}
QString m_folderPath {""}
std::vector< float > m_fullWavData
std::vector< float > m_capturedCycle
std::vector< float > m_copiedCapturedCycle
int m_waveformLen {AudioConfig::WAVESHAPE_LEN}
bool m_isWaveformFlipTime {false}
bool m_isWaveformFlipPhase {false}
float m_audioFreq

Detailed Description

The primary application window and signal processing controller.

  • Handles the extraction, transformation (stretch/mirror), and auditing of single-cycle waveforms from raw audio data.

Constructor & Destructor Documentation

◆ Widget() [1/2]

Widget::Widget ( QWidget * parent = nullptr)
explicit

Initializes the UI and prepares the XYSeriesIODevice.

Constructor - Initializes UI, internal buffers, and audio engine.

  • Sets up the signal-slot connections for the PS-80 analyzer interface and initializes the real-time UI refresh timer.
    Parameters
    parentOptional pointer to the parent QWidget (default is nullptr).

◆ ~Widget()

Widget::~Widget ( )
virtual

Virtual destructor for clean resource management.

Destructor - Ensures safe teardown of the audio output and device.

◆ Widget() [2/2]

Widget::Widget ( const Widget & )
delete

Member Function Documentation

◆ copyWaveform()

void Widget::copyWaveform ( std::vector< float > & dest,
const std::vector< float > & source )
private

Copies waveform data between buffers.

Performs a deep copy of a waveform buffer.

  • This method ensures a clean state by swapping the destination buffer with an empty vector (releasing memory) before resizing and performing a high-speed copy of the source data.
    Parameters
    destThe target vector (destination).
    sourceThe source vector containing the waveform to be copied.

◆ drawWaveformContents()

void Widget::drawWaveformContents ( QPainter * painter,
QWidget * target,
const std::vector< float > & data )
private

Renders the detailed micro-view of the captured waveform cycle.

  • Visualizes the specific 2048-sample segment (or stretched/shrunk version) currently held in m_capturedCycle. It includes reference lines for amplitude limits and handles selection markers if rendered within the primary graph context.
    Parameters
    painterShared painter context from the main paintEvent.
    targetThe UI widget providing the target geometry.
    dataThe waveform data vector to be visualized.

◆ drawWavFileContents()

void Widget::drawWavFileContents ( QPainter * painter,
QWidget * target,
const std::vector< float > & data )
private

Renders the macro view of the entire WAV file.

  • This method draws the full waveform overview, provides visual indicators for the current selection window (red), and tracks real-time playback position (yellow) by querying the audio engine's index.
    Parameters
    painterShared painter context from paintEvent.
    targetThe UI widget providing coordinates and dimensions.
    dataThe master buffer to be visualized.

◆ flipPhaseWaveform()

void Widget::flipPhaseWaveform ( std::vector< float > & dest)
private

Reverses the phase of the current captured cycle.

Inverts the waveform in the amplitude domain (Phase Inversion).

  • Negates each sample value within the buffer, effectively flipping the waveform vertically. This is critical for phase alignment analysis.
    Parameters
    destThe target vector to be inverted (must match WAVESHAPE_LEN).

◆ flipTimeWaveform()

void Widget::flipTimeWaveform ( std::vector< float > & dest)
private

Reverses the time of the current captured cycle.

Reverses the waveform in the time domain (Retrograde).

  • Flips the sample order within the buffer, effectively playing the waveform backwards. This is useful for analyzing temporal symmetry.
    Parameters
    destThe target vector to be reversed (must match WAVESHAPE_LEN).

◆ loadWavFile()

void Widget::loadWavFile ( const QString & fileName)
private

Loads raw PCM data from a WAV file into m_fullWavData.

Parses a WAV file and extracts PCM data into the master buffer.

  • This method handles the binary parsing of the WAV container. Currently, it is optimized for 32-bit float PCM data, matching the PS-80 analyzer's requirements.
  • Parameters
    fileNameAbsolute path to the .wav file.

◆ mousePressEvent()

void Widget::mousePressEvent ( QMouseEvent * event)
overrideprotected

Handles sample-precise selection within the waveform view.

Handles mouse interaction with the master waveform display.

  • Translates screen coordinates into sample indices. If 'Floating Clip' is disabled, it enforces a strict block-alignment (grid snapping) based on AudioConfig::WAVESHAPE_LEN. This serves as the primary entry point for waveform extraction.
    Parameters
    eventThe mouse event containing click coordinates.

◆ normalizeCapturedCycle()

void Widget::normalizeCapturedCycle ( std::vector< float > & capturedCycle)
private

Peak-normalization algorithm. Scales the captured segment to utilize the full dynamic range [-1.0, 1.0].

Normalizes the analysis buffer to the full dynamic range [-1.0, 1.0].

  • This method applies a linear transformation (y = a1*x + a0) to remap the input signal. It effectively removes any DC offset and scales the amplitude to utilize the maximum available bit depth for the PS-80 analyzer.
    Parameters
    capturedCycleReference to the vector to be normalized in-place.

◆ onBrowseFolderButtonClicked

void Widget::onBrowseFolderButtonClicked ( )
privateslot

Slot: Handles the folder selection for waveform exports (the "Photo Shoot").

  • Opens a directory dialog to set the target location for CSV exports. The selected path is persisted using QSettings to streamline future analysis sessions.

◆ onComboBoxFreqCurrentTextChanged

void Widget::onComboBoxFreqCurrentTextChanged ( const QString & text)
privateslot

Slot: Updates the synthesis frequency based on UI selection.

  • Parses the selected text to extract the fundamental frequency (Hz) and immediately updates the audio engine's oscillator. This allows for real-time pitch shifting during waveform auditing.
    Parameters
    textThe current text from the frequency selection combo box (e.g., "55 Hz (A1)").

◆ onFlipPhaseButtonClicked

void Widget::onFlipPhaseButtonClicked ( )
privateslot

Slot: Toggles the temporal mirroring (Y-axis) of the captured waveform.

  • Inverse the sample of the current m_capturedCycle. This allows for analysis of temporal symmetry and retrograde playback within the GrandComp process.

◆ onFlipTimeButtonClicked

void Widget::onFlipTimeButtonClicked ( )
privateslot

Slot: Toggles the temporal mirroring (X-axis) of the captured waveform.

  • Reverses the sample order of the current m_capturedCycle. This allows for analysis of temporal symmetry and retrograde playback within the GrandComp process.

◆ onFloatingClipButtonClicked

void Widget::onFloatingClipButtonClicked ( )
privateslot

Slot: Toggles the sub-sample precision mode (Floating Clip).

  • Synchronizes the internal state with the UI checkbox. When enabled, the analyzer allows for non-integer frame indices, enabling more granular alignment during the waveform extraction process.

◆ onMoveLeftButtonClicked

void Widget::onMoveLeftButtonClicked ( )
privateslot

Slot: Shifts the waveform data to the left within the viewing window.

  • To make the waveform appear to move left, the sampling index is incremented, effectively sliding the capture window forward in time. Supports variable step sizes via Shift/Ctrl modifiers.

◆ onMoveRightButtonClicked

void Widget::onMoveRightButtonClicked ( )
privateslot

Slot: Shifts the waveform data to the right within the viewing window.

  • To make the waveform appear to move right, the sampling index is decremented, effectively sliding the capture window backward in time. Supports variable step sizes via Shift/Ctrl modifiers.

◆ onOpenButtonClicked

void Widget::onOpenButtonClicked ( )
privateslot

Slot: Handles the 'Open' button click event.

  • Launches a file dialog to select a WAV file. It persists the last used directory across sessions using QSettings for improved user experience.

◆ onPauseClipButtonClicked

void Widget::onPauseClipButtonClicked ( )
privateslot

Slot: Halts the single-cycle waveform oscillator.

  • Pauses the periodic synthesis by setting the oscillator frequency to 0 Hz. This freezes the XYSeriesIODevice phase accumulator, allowing for a seamless resume without reset-induced transients.

◆ onPauseWavButtonClicked

void Widget::onPauseWavButtonClicked ( )
privateslot

Slot: Suspends audio playback by halting signal progression.

  • Effectively pauses the audio output by setting the fundamental frequency to 0 Hz. This stops the phase accumulator in the XYSeriesIODevice without terminating the hardware stream, allowing for near-instant resumption.

◆ onPlayClipButtonClicked

void Widget::onPlayClipButtonClicked ( )
privateslot

Slot: Initiates playback of the captured single-cycle waveform.

  • This method switches the engine to XYSeriesIODevice::PlayMode::Waveform, transforming the static capture into a periodic oscillator. It ensures the synthesis frequency is correctly mapped from the UI before starting the hardware stream.

◆ onPlayWavButtonClicked

void Widget::onPlayWavButtonClicked ( )
privateslot

Slot: Initiates full WAV file playback.

  • Updates the audio engine with the master buffer and switches the playback engine to XYSeriesIODevice::PlayMode::WavFile. This mode provides a 1:1 linear audit of the source material.

◆ onSaveButtonClicked

void Widget::onSaveButtonClicked ( )
privateslot

Slot: Exports the currently captured waveform cycle to a CSV file.

  • This method normalizes the captured signal and saves it as a column of high-precision floating-point values. The filename is automatically generated based on the source file and the frame index (supporting both integer and floating-point indices for granular analysis).

◆ onShrinkedButtonClicked

void Widget::onShrinkedButtonClicked ( )
privateslot

Slot: Shrinks the waveform by increasing the source window length.

  • Increments the source segment length (m_waveformLen), causing the resampling algorithm to squeeze more audio data into the fixed 2048-sample target buffer. Supports variable steps via Shift/Ctrl modifiers.

◆ onStretchButtonClicked

void Widget::onStretchButtonClicked ( )
privateslot

Slot: Stretches the waveform by reducing the source window length.

  • Decrements the source segment length (m_waveformLen), which causes the resampling algorithm to "stretch" a smaller portion of audio over the fixed 2048-sample target buffer. Supports variable steps via Shift/Ctrl.

◆ operator=()

Widget & Widget::operator= ( const Widget & )
delete

◆ paintEvent()

void Widget::paintEvent ( QPaintEvent * event)
overrideprotected

Renders the waveform visualizations and playheads.

Main paint event handler for the widget.

  • Orchestrates the rendering process by initializing a single QPainter context and delegating the drawing of specific waveform displays to dedicated sub-routines. This ensures synchronized rendering across different UI components.
    Parameters
    eventStandard Qt paint event (unused but preserved for signature).

◆ setupAudio()

void Widget::setupAudio ( )
private

Initializes the Qt Audio output stack and the custom XYSeriesIODevice.

Initializes the Qt Audio subsystem.

◆ stretchWaveform()

void Widget::stretchWaveform ( std::vector< float > & dest,
const std::vector< float > & source,
const int waveformeLen )
private

Mathematical resampling of the waveform. Maps the source segment into the target m_waveformLen using linear interpolation.

Resamples a source segment to the target wavetable length using linear interpolation.

  • This method performs a time-stretch or time-shrink transformation by mapping a source segment of variable length (waveformeLen) onto a fixed-size destination buffer (AudioConfig::WAVESHAPE_LEN).
  • The algorithm calculates a relative index for each target sample and applies linear interpolation between the two nearest source samples to ensure high-fidelity reconstruction of the waveform without staircase aliasing.
  • Parameters
    destThe target vector where the resampled waveform will be stored.
    sourceThe immutable source buffer (backup) containing the original captured data.
    waveformeLenThe active window length in the source buffer to stretch/shrink from.
  • Note
    If waveformeLen is smaller than the target size, the signal is "stretched" (upsampled). If it is larger, the signal is "shrunk" (downsampled).

◆ updateButtonStates()

void Widget::updateButtonStates ( )
private

Manages the enabled/disabled state of UI elements based on engine state.

Updates the enabled/disabled state of UI controls based on current data.

  • This method acts as a central logic gate, ensuring that actions like 'Save', 'Stretch', or 'Mirror' are only available when valid waveform data is resident in memory and a target directory is defined.

◆ waveformBackup()

void Widget::waveformBackup ( const int centerSample)
private

Creates a safety backup of the currently selected waveform segment.

Performs a safety backup of the selected waveform segment.

  • Extracts a raw data window from the master buffer starting at centerSample. Uses clamping to prevent out-of-bounds access at the file boundaries. This "Clean Copy" serves as the immutable source for all subsequent transformations (stretching, mirroring, etc.).
    Parameters
    centerSampleThe starting index in the master WAV buffer.

Field Documentation

◆ m_audioFreq

float Widget::m_audioFreq
private
Initial value:
{
constexpr float DEFAULT_FREQ
The reference frequency (A1) used for precise cycle extraction.
Definition audio_config.h:36

Base frequency for synthesis (default 55 Hz).

◆ m_audioOutput

QAudioOutput* Widget::m_audioOutput {nullptr}
private

Qt system audio output.

◆ m_capturedCycle

std::vector<float> Widget::m_capturedCycle
private

Current WAVESHAPE_LEN-sample analysis buffer.

◆ m_copiedCapturedCycle

std::vector<float> Widget::m_copiedCapturedCycle
private

Backup buffer for "Undo" or "Compare" logic.

◆ m_device

XYSeriesIODevice* Widget::m_device {nullptr}
private

Custom I/O device for signal synthesis.

◆ m_folderPath

QString Widget::m_folderPath {""}
private

Export path for analyzed wave shapes.

◆ m_fullWavData

std::vector<float> Widget::m_fullWavData
private

Raw source buffer (master file).

◆ m_isWaveformFlipPhase

bool Widget::m_isWaveformFlipPhase {false}
private

State flag for phase inversion.

◆ m_isWaveformFlipTime

bool Widget::m_isWaveformFlipTime {false}
private

State flag for time inversion.

◆ m_lastClickSample

int Widget::m_lastClickSample {0}
private

Tracks the user's focus point in the master file.

◆ m_stateFloatingClip

Qt::CheckState Widget::m_stateFloatingClip = Qt::CheckState::Unchecked
private

◆ m_waveformLen

int Widget::m_waveformLen {AudioConfig::WAVESHAPE_LEN}
private

Current working length of the waveform.

◆ ui

Ui::Widget* Widget::ui
private

Pointer to the auto-generated UI layout.


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