AudioSpectrum::AudioSpectrum(QWidget *parent) : AbstractAudioScopeWidget(true, parent) , m_fftTools() , m_lastFFT() , m_lastFFTLock(1) , m_peaks() #ifdef DEBUG_AUDIOSPEC , m_timeTotal(0) , m_showTotal(0) #endif , m_dBmin(-70) , m_dBmax(0) , m_freqMax(0) , m_customFreq(false) ,colorizeFactor(0) { ui = new Ui::AudioSpectrum_UI; ui->setupUi(this); m_aResetHz = new QAction(i18n("Reset maximum frequency to sampling rate"), this); m_aTrackMouse = new QAction(i18n("Track mouse"), this); m_aTrackMouse->setCheckable(true); m_aShowMax = new QAction(i18n("Show maximum"), this); m_aShowMax->setCheckable(true); m_menu->addSeparator(); m_menu->addAction(m_aResetHz); m_menu->addAction(m_aTrackMouse); m_menu->addAction(m_aShowMax); m_menu->removeAction(m_aRealtime); ui->windowSize->addItem("256", QVariant(256)); ui->windowSize->addItem("512", QVariant(512)); ui->windowSize->addItem("1024", QVariant(1024)); ui->windowSize->addItem("2048", QVariant(2048)); ui->windowFunction->addItem(i18n("Rectangular window"), FFTTools::Window_Rect); ui->windowFunction->addItem(i18n("Triangular window"), FFTTools::Window_Triangle); ui->windowFunction->addItem(i18n("Hamming window"), FFTTools::Window_Hamming); bool b = true; b &= connect(m_aResetHz, SIGNAL(triggered()), this, SLOT(slotResetMaxFreq())); b &= connect(ui->windowFunction, SIGNAL(currentIndexChanged(int)), this, SLOT(forceUpdate())); b &= connect(this, SIGNAL(signalMousePositionChanged()), this, SLOT(forceUpdateHUD())); Q_ASSERT(b); // Note: These strings are used in both Spectogram and AudioSpectrum. Ideally change both (if necessary) to reduce workload on translators ui->labelFFTSize->setToolTip(i18n("The maximum window size is limited by the number of samples per frame.")); ui->windowSize->setToolTip(i18n("A bigger window improves the accuracy at the cost of computational power.")); ui->windowFunction->setToolTip(i18n("The rectangular window function is good for signals with equal signal strength (narrow peak), but creates more smearing. See Window function on Wikipedia.")); AbstractScopeWidget::init(); }
void AbstractScopeWidget::mouseMoveEvent(QMouseEvent *event) { m_mousePos = event->pos(); m_mouseWithinWidget = true; emit signalMousePositionChanged(); QPoint movement = event->pos()-m_rescaleStartPoint; if (m_rescaleActive) { if (m_rescalePropertiesLocked) { // Direction is known, now adjust parameters // Reset the starting point to make the next moveEvent relative to the current one m_rescaleStartPoint = event->pos(); if (!m_rescaleFirstRescaleDone) { // We have just learned the desired direction; Normalize the movement to one pixel // to avoid a jump by m_rescaleMinDist if (movement.x() != 0) { movement.setX(movement.x() / abs(movement.x())); } if (movement.y() != 0) { movement.setY(movement.y() / abs(movement.y())); } m_rescaleFirstRescaleDone = true; } handleMouseDrag(movement, m_rescaleDirection, m_rescaleModifiers); } else { // Detect the movement direction here. // This algorithm relies on the aspect ratio of dy/dx (size and signum). if (movement.manhattanLength() > m_rescaleMinDist) { float diff = ((float) movement.y())/movement.x(); if (fabs(diff) > m_rescaleVerticalThreshold || movement.x() == 0) { m_rescaleDirection = North; } else if (fabs(diff) < 1/m_rescaleVerticalThreshold) { m_rescaleDirection = East; } else if (diff < 0) { m_rescaleDirection = Northeast; } else { m_rescaleDirection = Southeast; } #ifdef DEBUG_ASW qDebug() << "Diff is " << diff << "; chose " << directions[m_rescaleDirection] << " as direction"; #endif m_rescalePropertiesLocked = true; } } } }
void AbstractScopeWidget::leaveEvent(QEvent *) { m_mouseWithinWidget = false; emit signalMousePositionChanged(); }