Files
raDIYo/swplayercontrol.cpp
2025-08-05 22:36:00 +02:00

200 lines
4.4 KiB
C++

/***************************************************************************
source::worx raDIYo
Copyright © 2020-2022 c.holzheuer
chris@sourceworx.org
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
***************************************************************************/
#include <QDebug>
#include <QPainter>
#include <stdlib.h>
#include <swplayercontrol.h>
SWPlayerControl::SWPlayerControl( QWidget* parent, QSettings* settings )
: SWControl( parent, settings )
{
setupUi( this );
_pauseLabel->hide();
setAcceptDial( false );
_audioProbe.setSource( &_player );
// man weiss ja nie, default ist die maximale Lautstärke
_value = 0;
_player.setVolume( _value );
#ifdef Q_OS_LINUX
// unter linux kriegt der _interne_ player 100%, weil die
// Lautstärke über das globale Volume via 'amixer' geregelt wird.
// Dadurch können auch eingehende BT-Stream geregelt werden.
_player.setVolume( 100 );
#endif
// weiterreichen
connect( &_player, &QMediaPlayer::stateChanged, this,
[=]( QMediaPlayer::State newState )
{
emit stateChanged( newState );
});
_FFTCalc.moveToThread( &_workerThread );
qRegisterMetaType<SWValVec>("SWValVec");
connect( &_audioProbe, SIGNAL( audioBufferProbed(QAudioBuffer) ), &_FFTCalc, SLOT(onAudioProbed(QAudioBuffer) ) );
//connect( &_audioProbe, SIGNAL( audioBufferProbed(QAudioBuffer) ), this, SLOT(onAudioProbed(QAudioBuffer) ) );
connect( &_FFTCalc, SIGNAL( spectrumReady(SWValVec) ), this, SLOT( onSpectrumReady(SWValVec) ) );
_workerThread.start();
}
SWPlayerControl::~SWPlayerControl()
{
//_audioProbe.setSource( nullptr );
_workerThread.quit();
_workerThread.wait();
}
/**
* @brief Wird aufgerufen, wenn das (externe) Dial gedreht wurde.
*/
void SWPlayerControl::onDialDeltaChanged( int delta )
{
setValue( _value += 2*delta );
}
/**
* @brief Überschreibt SWRangeValue::setValue: es wird nicht
* nur _value neu gesetzt, sondern auch das player Volume
* angepasst
*/
void SWPlayerControl::setValue( int value )
{
if( _value != value )
_value = qBound( _rangeFrom, value, _rangeTo );
#ifdef Q_OS_WIN
_player.setVolume( _value );
#endif
#ifdef Q_OS_LINUX
QString cmd = _volCmd.arg( _value );
::system( cmd.toLocal8Bit().data() );
#endif
}
void SWPlayerControl::onAudioProbed( const QAudioBuffer& audiobuffer )
{
_FFTCalc.onAudioProbed( audiobuffer );
}
void SWPlayerControl::onSpectrumReady( const SWValVec& spectrum )
{
if( _player.state() != QMediaPlayer::PlayingState )
return;
// hier verteilen wir das gesamtspectrum
// auf die xx balken des Displays
int numbins = _spectrumWidget->numBars();
//int numvals = spectrum.size();
int numvals = spectrum.size() / 4 * 2;
//int numvals = spectrum.size() / 3 * 2;
int divider = numvals / numbins;
QVector<int> bins( numbins );
SWValVec vals( numbins );
for( int i=0; i<numvals; ++i )
{
bins[ i/divider ]++;
vals[ i/divider ] += spectrum[i];
// oder max: bar.value = qMax(bar.value, e.amplitude);
}
// durchschnitt bilden
for( int i=0; i<numbins; ++i )
{
if( bins[i] )
vals[i] /= bins[i];
}
_spectrumWidget->onValueListChanged( vals );
}
/**
* @brief SWPlayerControl::setUrl
* @param urlText
*/
void SWPlayerControl::setUrl( const QString& urlText )
{
_mediaUrl = urlText;
_player.setMedia( _mediaUrl );
}
/**
* @brief SWPlayerControl::togglePlaying
* @param playIt
*/
void SWPlayerControl::togglePlaying( bool playIt )
{
playIt ? startPlaying() : pausePlaying() ;
}
/**
* @brief SWPlayerControl::startPlaying: Erwartet eine _ordentliche_ URL als String
* @param urlText
*/
void SWPlayerControl::startPlaying()
{
//_player.setVolume( _value );
_pauseLabel->hide();
_player.play();
}
/**
* @brief Pausiert den Player an und löscht die Anzeige.
*/
void SWPlayerControl::pausePlaying()
{
_player.pause();
_pauseLabel->show();
}
/**
* @brief Hält den Player an und löscht die Anzeige.
*/
void SWPlayerControl::stopPlaying()
{
_player.stop();
_pauseLabel->hide();
_spectrumWidget->clearValueList();
}