Fix broken audio scopes

BUG: 351101
parent 56573c12
......@@ -282,7 +282,7 @@ MainWindow::MainWindow(const QString &MltPath, const QUrl &Url, const QString &
new LayoutManagement(this);
new HideTitleBars(this);
new TimelineSearch(this);
new ScopeManager(this);
ScopeManager *scmanager = new ScopeManager(this);
// Add shortcut to action tooltips
QList< KActionCollection * > collections = KActionCollection::allCollections();
......@@ -471,6 +471,7 @@ MainWindow::MainWindow(const QString &MltPath, const QUrl &Url, const QString &
#ifdef USE_JOGSHUTTLE
new JogManager(this);
#endif
scmanager->slotCheckActiveScopes();
//KMessageBox::information(this, "Warning, development version for testing only. we are currently working on core functionnalities,\ndo not save any project or your project files might be corrupted.");
}
......
......@@ -45,7 +45,7 @@ Q_OBJECT public:
: QObject(parent),
sendFrameForAnalysis(false),
analyseAudio(false),
m_name(name)
m_id(name)
{
}
......@@ -58,13 +58,13 @@ Q_OBJECT public:
/** @brief This property is used to decide if the renderer should send audio data for monitoring. */
bool analyseAudio;
const QString &name() const {return m_name;}
Kdenlive::MonitorId id() const {return m_id;}
/** @brief Someone needs us to send again a frame. */
virtual void sendFrameUpdate() = 0;
private:
QString m_name;
Kdenlive::MonitorId m_id;
signals:
/** @brief The renderer refreshed the current frame. */
......
......@@ -123,6 +123,12 @@ GLWidget::~GLWidget()
delete m_shader;
}
void GLWidget::updateAudioForAnalysis()
{
if (m_frameRenderer)
m_frameRenderer->sendAudioForAnalysis = KdenliveSettings::monitor_audio();
}
void GLWidget::initializeGL()
{
if (m_isInitialized) return;
......@@ -159,10 +165,11 @@ void GLWidget::initializeGL()
m_shareContext->create();
}
m_frameRenderer = new FrameRenderer(openglContext(), &m_offscreenSurface);
m_frameRenderer->sendAudioForAnalysis = KdenliveSettings::monitor_audio();
openglContext()->makeCurrent(this);
//openglContext()->blockSignals(false);
connect(m_frameRenderer, SIGNAL(frameDisplayed(const SharedFrame&)), this, SIGNAL(frameDisplayed(const SharedFrame&)), Qt::QueuedConnection);
connect(m_frameRenderer, SIGNAL(analyseFrame(QImage)), this, SIGNAL(analyseFrame(QImage)), Qt::QueuedConnection);
connect(m_frameRenderer, SIGNAL(audioSamplesSignal(const audioShortVector&,int,int,int)), this, SIGNAL(audioSamplesSignal(const audioShortVector&,int,int,int)), Qt::QueuedConnection);
connect(m_frameRenderer, SIGNAL(textureReady(GLuint,GLuint,GLuint)), SLOT(updateTexture(GLuint,GLuint,GLuint)), Qt::DirectConnection);
connect(this, SIGNAL(textureUpdated()), SLOT(update()), Qt::QueuedConnection);
......@@ -1125,6 +1132,7 @@ FrameRenderer::FrameRenderer(QOpenGLContext* shareContext, QSurface *surface)
, m_context(0)
, m_surface(surface)
, m_gl32(0)
, sendAudioForAnalysis(false)
{
Q_ASSERT(shareContext);
m_renderTexture[0] = m_renderTexture[1] = m_renderTexture[2] = 0;
......@@ -1170,6 +1178,27 @@ void FrameRenderer::showFrame(Mlt::Frame frame)
// The frame is now done being modified and can be shared with the rest
// of the application.
emit frameDisplayed(m_frame);
if (sendAudioForAnalysis) {
qDebug()<<" - - -- SEND AUDIO DATA";
mlt_audio_format audio_format = mlt_audio_s16;
//FIXME: should not be hardcoded..
int freq = 48000;
int num_channels = 2;
int samples = 0;
qint16* data = (qint16*)frame.get_audio(audio_format, freq, num_channels, samples);
if (data) {
// Data format: [ c00 c10 c01 c11 c02 c12 c03 c13 ... c0{samples-1} c1{samples-1} for 2 channels.
// So the vector is of size samples*channels.
audioShortVector sampleVector(samples*num_channels);
memcpy(sampleVector.data(), data, samples*num_channels*sizeof(qint16));
if (samples > 0) {
emit audioSamplesSignal(sampleVector, freq, num_channels, samples);
}
}
}
}
m_semaphore.release();
}
......
......@@ -70,6 +70,8 @@ public:
void clearFrameRenderer();
int displayWidth() const { return m_rect.width(); }
void updateAudioForAnalysis();
int displayHeight() const { return m_rect.height(); }
QObject* videoWidget() { return this; }
......@@ -104,6 +106,7 @@ public slots:
void slotSwitchAudioOverlay(bool enable);
//void setCurrentFilter(QmlFilter* filter, QmlMetadata* meta);
void initializeGL();
signals:
void frameDisplayed(const SharedFrame& frame);
void textureUpdated();
......@@ -122,6 +125,7 @@ signals:
void startDrag();
void effectChanged(const QRect);
void analyseFrame(QImage);
void audioSamplesSignal(const audioShortVector&,int,int,int);
void showContextMenu(const QPoint);
private:
......@@ -209,7 +213,7 @@ public slots:
signals:
void textureReady(GLuint yName, GLuint uName = 0, GLuint vName = 0);
void frameDisplayed(const SharedFrame& frame);
void analyseFrame(QImage);
void audioSamplesSignal(const audioShortVector&,int,int,int);
private:
QSemaphore m_semaphore;
......@@ -221,6 +225,7 @@ public:
GLuint m_renderTexture[3];
GLuint m_displayTexture[3];
QOpenGLFunctions_3_2_Core* m_gl32;
bool sendAudioForAnalysis;
};
......
......@@ -206,6 +206,7 @@ Monitor::Monitor(Kdenlive::MonitorId id, MonitorManager *manager, QWidget *paren
connect(render, SIGNAL(durationChanged(int,int)), this, SLOT(adjustRulerSize(int,int)));
connect(render, SIGNAL(rendererStopped(int)), this, SLOT(rendererStopped(int)));
connect(m_glMonitor, SIGNAL(analyseFrame(QImage)), render, SLOT(emitFrameUpdated(QImage)));
connect(m_glMonitor, SIGNAL(audioSamplesSignal(const audioShortVector&,int,int,int)), render, SIGNAL(audioSamplesSignal(const audioShortVector&,int,int,int)));
if (id != Kdenlive::ClipMonitor) {
connect(render, SIGNAL(durationChanged(int)), this, SIGNAL(durationChanged(int)));
connect(m_ruler, SIGNAL(zoneChanged(QPoint)), this, SIGNAL(zoneUpdated(QPoint)));
......@@ -1285,6 +1286,10 @@ void Monitor::sendFrameForAnalysis(bool analyse)
m_glMonitor->sendFrameForAnalysis = analyse;
}
void Monitor::updateAudioForAnalysis()
{
m_glMonitor->updateAudioForAnalysis();
}
void Monitor::onFrameDisplayed(const SharedFrame& frame)
{
......
......@@ -96,6 +96,7 @@ public:
QRect effectRect() const;
void setEffectKeyframe(bool enable);
void sendFrameForAnalysis(bool analyse);
void updateAudioForAnalysis();
void switchMonitorInfo(bool show);
void switchDropFrames(bool drop);
void updateMonitorGamma();
......
......@@ -240,15 +240,11 @@ void MonitorManager::slotRefreshCurrentMonitor(const QString &id)
void MonitorManager::slotUpdateAudioMonitoring()
{
// if(...) added since they are 0x0 when the config wizard is running! --Granjow
/*if (m_clipMonitor) {
m_clipMonitor->render->analyseAudio = KdenliveSettings::monitor_audio();
if (m_clipMonitor) {
m_clipMonitor->updateAudioForAnalysis();
}
if (m_projectMonitor) {
m_projectMonitor->render->analyseAudio = KdenliveSettings::monitor_audio();
}*/
for (int i = 0; i < m_monitorsList.count(); ++i) {
if (m_monitorsList.at(i)->abstractRender()) m_monitorsList.at(i)->abstractRender()->analyseAudio = KdenliveSettings::monitor_audio();
m_projectMonitor->updateAudioForAnalysis();
}
}
......
......@@ -129,8 +129,6 @@ void ScopeManager::slotDistributeAudio(const audioShortVector &sampleData, int f
}
}
}
checkActiveAudioScopes();
}
void ScopeManager::slotDistributeFrame(const QImage &image)
{
......@@ -196,7 +194,7 @@ void ScopeManager::slotUpdateActiveRenderer()
// Disconnect old connections
if (m_lastConnectedRenderer != NULL) {
#ifdef DEBUG_SM
qDebug() << "Disconnected previous renderer: " << m_lastConnectedRenderer->name();
qDebug() << "Disconnected previous renderer: " << m_lastConnectedRenderer->id();
#endif
m_lastConnectedRenderer->disconnect(this);
}
......@@ -213,7 +211,7 @@ void ScopeManager::slotUpdateActiveRenderer()
this, &ScopeManager::slotDistributeAudio, Qt::UniqueConnection);
#ifdef DEBUG_SM
qDebug() << "Renderer connected to ScopeManager: " << m_lastConnectedRenderer->name();
qDebug() << "Renderer connected to ScopeManager: " << m_lastConnectedRenderer->id();
#endif
if (imagesAcceptedByScopes()) {
......@@ -231,8 +229,9 @@ void ScopeManager::slotCheckActiveScopes()
#ifdef DEBUG_SM
qDebug() << "Checking active scopes ...";
#endif
checkActiveAudioScopes();
checkActiveColourScopes();
// Leave a small delay to make sure that scope widget has been shown or hidden
QTimer::singleShot(500, this, SLOT(checkActiveAudioScopes()));
QTimer::singleShot(500, this, SLOT(checkActiveColourScopes()));
}
......@@ -240,7 +239,7 @@ bool ScopeManager::audioAcceptedByScopes() const
{
bool accepted = false;
for (int i = 0; i < m_audioScopes.size(); ++i) {
if (!m_audioScopes[i].scope->visibleRegion().isEmpty() && m_audioScopes[i].scope->autoRefreshEnabled()) {
if (m_audioScopes.at(i).scope->isVisible() && m_audioScopes.at(i).scope->autoRefreshEnabled()) {
accepted = true;
break;
}
......@@ -278,6 +277,7 @@ void ScopeManager::checkActiveAudioScopes()
KdenliveSettings::setMonitor_audio(audioStillRequested);
pCore->monitorManager()->slotUpdateAudioMonitoring();
}
void ScopeManager::checkActiveColourScopes()
{
bool imageStillRequested = imagesAcceptedByScopes();
......
......@@ -82,18 +82,6 @@ private:
*/
bool imagesAcceptedByScopes() const;
/**
Checks whether audio data is required, and notifies the renderer (enable or disable data sending).
\see checkActiveAudioScopes() for image data
*/
void checkActiveAudioScopes();
/**
Checks whether any scope accepts frames, and notifies the renderer.
\see checkActiveAudioScopes() for audio data
*/
void checkActiveColourScopes();
/**
Creates all the scopes in audioscopes/ and colorscopes/.
New scopes are not detected automatically but have to be added.
......@@ -107,6 +95,9 @@ private:
*/
template <class T> void createScopeDock(T *scopeWidget, const QString &title);
public slots:
void slotCheckActiveScopes();
private slots:
/**
Updates the signal/slot connection since the active renderer has changed.
......@@ -121,15 +112,23 @@ private slots:
\see checkActiveColourScopes()
*/
void slotCheckActiveScopes();
/**
Checks whether audio data is required, and notifies the renderer (enable or disable data sending).
\see checkActiveAudioScopes() for image data
*/
void checkActiveAudioScopes();
/**
Checks whether any scope accepts frames, and notifies the renderer.
\see checkActiveAudioScopes() for audio data
*/
void checkActiveColourScopes();
void slotDistributeFrame(const QImage &image);
void slotDistributeAudio(const audioShortVector &sampleData, int freq, int num_channels, int num_samples);
/**
Allows a scope to explicitly request a new frame, even if the scope's autoRefresh is disabled.
*/
void slotRequestFrame(const QString &widgetName);
};
#endif // SCOPEMANAGER_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment