Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Kdenlive
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
259
Issues
259
List
Boards
Labels
Service Desk
Milestones
Merge Requests
14
Merge Requests
14
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Multimedia
Kdenlive
Commits
9f3c1670
Commit
9f3c1670
authored
Oct 10, 2019
by
Jean-Baptiste Mardelle
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Audiomix merge
parent
0ce0f757
Changes
24
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
988 additions
and
15 deletions
+988
-15
src/CMakeLists.txt
src/CMakeLists.txt
+1
-0
src/audiomixer/CMakeLists.txt
src/audiomixer/CMakeLists.txt
+7
-0
src/audiomixer/audiolevelwidget.cpp
src/audiomixer/audiolevelwidget.cpp
+212
-0
src/audiomixer/audiolevelwidget.hpp
src/audiomixer/audiolevelwidget.hpp
+63
-0
src/audiomixer/mixermanager.cpp
src/audiomixer/mixermanager.cpp
+172
-0
src/audiomixer/mixermanager.hpp
src/audiomixer/mixermanager.hpp
+78
-0
src/audiomixer/mixerwidget.cpp
src/audiomixer/mixerwidget.cpp
+273
-0
src/audiomixer/mixerwidget.hpp
src/audiomixer/mixerwidget.hpp
+94
-0
src/core.cpp
src/core.cpp
+11
-2
src/core.h
src/core.h
+5
-1
src/mainwindow.cpp
src/mainwindow.cpp
+10
-0
src/monitor/glwidget.cpp
src/monitor/glwidget.cpp
+17
-0
src/monitor/glwidget.h
src/monitor/glwidget.h
+5
-0
src/monitor/monitor.cpp
src/monitor/monitor.cpp
+4
-0
src/monitor/monitormanager.h
src/monitor/monitormanager.h
+6
-0
src/monitor/scopes/monitoraudiolevel.cpp
src/monitor/scopes/monitoraudiolevel.cpp
+2
-3
src/monitor/scopes/monitoraudiolevel.h
src/monitor/scopes/monitoraudiolevel.h
+3
-2
src/monitor/scopes/sharedframe.cpp
src/monitor/scopes/sharedframe.cpp
+5
-0
src/monitor/scopes/sharedframe.h
src/monitor/scopes/sharedframe.h
+1
-0
src/project/projectmanager.cpp
src/project/projectmanager.cpp
+3
-0
src/timeline2/model/timelineitemmodel.cpp
src/timeline2/model/timelineitemmodel.cpp
+9
-6
src/timeline2/model/trackmodel.cpp
src/timeline2/model/trackmodel.cpp
+5
-0
src/timeline2/model/trackmodel.hpp
src/timeline2/model/trackmodel.hpp
+1
-0
src/transitions/view/transitionstackview.cpp
src/transitions/view/transitionstackview.cpp
+1
-1
No files found.
src/CMakeLists.txt
View file @
9f3c1670
...
...
@@ -41,6 +41,7 @@ endif()
### Find source files
add_subdirectory
(
abstractmodel
)
add_subdirectory
(
assets
)
add_subdirectory
(
audiomixer
)
add_subdirectory
(
bin
)
add_subdirectory
(
capture
)
add_subdirectory
(
dialogs
)
...
...
src/audiomixer/CMakeLists.txt
0 → 100644
View file @
9f3c1670
set
(
kdenlive_SRCS
${
kdenlive_SRCS
}
audiomixer/mixerwidget.cpp
audiomixer/audiolevelwidget.cpp
audiomixer/mixermanager.cpp PARENT_SCOPE
)
src/audiomixer/audiolevelwidget.cpp
0 → 100644
View file @
9f3c1670
/*
Copyright (C) 2016 Jean-Baptiste Mardelle <jb@kdenlive.org>
This file is part of Kdenlive. See www.kdenlive.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) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "audiolevelwidget.hpp"
#include "core.h"
#include "profiles/profilemodel.hpp"
#include "mlt++/Mlt.h"
#include <cmath>
#include <QFont>
#include <QPaintEvent>
#include <QPainter>
#include <QFontDatabase>
const
double
log_factor
=
1.0
/
log10
(
1.0
/
127
);
static
inline
double
levelToDB
(
double
level
)
{
if
(
level
<=
0
)
{
return
-
100
;
}
return
100
*
(
1.0
-
log10
(
level
)
*
log_factor
);
}
AudioLevelWidget
::
AudioLevelWidget
(
int
width
,
QWidget
*
parent
)
:
QWidget
(
parent
)
,
audioChannels
(
2
)
,
m_width
(
width
)
,
m_channelWidth
(
width
/
2
)
,
m_channelDistance
(
2
)
,
m_channelFillWidth
(
m_channelWidth
)
{
setSizePolicy
(
QSizePolicy
::
Preferred
,
QSizePolicy
::
MinimumExpanding
);
setFont
(
QFontDatabase
::
systemFont
(
QFontDatabase
::
SmallestReadableFont
));
QFont
ft
=
font
();
ft
.
setPointSizeF
(
font
().
pointSize
()
*
0.8
);
setFont
(
ft
);
setMinimumWidth
(
4
);
}
AudioLevelWidget
::~
AudioLevelWidget
()
{
}
void
AudioLevelWidget
::
resizeEvent
(
QResizeEvent
*
event
)
{
drawBackground
(
m_peaks
.
size
());
}
void
AudioLevelWidget
::
refreshPixmap
()
{
drawBackground
(
m_peaks
.
size
());
}
void
AudioLevelWidget
::
drawBackground
(
int
channels
)
{
if
(
height
()
==
0
)
{
return
;
}
QSize
newSize
=
QWidget
::
size
();
if
(
!
newSize
.
isValid
())
{
return
;
}
m_offset
=
fontMetrics
().
boundingRect
(
QStringLiteral
(
"-45"
)).
width
()
+
5
;
newSize
.
setWidth
(
newSize
.
width
()
-
m_offset
);
QLinearGradient
gradient
(
0
,
newSize
.
height
(),
0
,
0
);
gradient
.
setColorAt
(
0.0
,
Qt
::
darkGreen
);
gradient
.
setColorAt
(
0.379
,
Qt
::
darkGreen
);
gradient
.
setColorAt
(
0.38
,
Qt
::
green
);
// -20db
gradient
.
setColorAt
(
0.868
,
Qt
::
green
);
gradient
.
setColorAt
(
0.869
,
Qt
::
yellow
);
// -2db
gradient
.
setColorAt
(
0.95
,
Qt
::
yellow
);
gradient
.
setColorAt
(
0.951
,
Qt
::
red
);
// 0db
m_pixmap
=
QPixmap
(
QWidget
::
size
());
if
(
m_pixmap
.
isNull
())
{
return
;
}
m_pixmap
.
fill
(
Qt
::
transparent
);
int
totalWidth
;
if
(
channels
<
2
)
{
m_channelWidth
=
newSize
.
width
()
/
2
;
totalWidth
=
m_channelWidth
;
}
else
{
m_channelWidth
=
(
newSize
.
width
()
-
(
channels
-
1
))
/
channels
;
totalWidth
=
channels
*
m_channelWidth
+
(
channels
-
1
);
}
QRect
rect
(
m_offset
,
0
,
newSize
.
width
(),
newSize
.
height
());
QPainter
p
(
&
m_pixmap
);
p
.
setOpacity
(
0.4
);
p
.
setFont
(
font
());
p
.
fillRect
(
rect
,
QBrush
(
gradient
));
// Channel labels are vertical along the bottom.
QVector
<
int
>
dbscale
;
dbscale
<<
0
<<
-
2
<<
-
5
<<
-
10
<<
-
15
<<
-
20
<<
-
30
<<
-
45
;
int
dbLabelCount
=
dbscale
.
size
();
// dB scale is vertical along the bottom
int
labelHeight
=
fontMetrics
().
ascent
();
for
(
int
i
=
0
;
i
<
dbLabelCount
;
i
++
)
{
int
value
=
dbscale
.
at
(
i
);
QString
label
=
QString
().
sprintf
(
"%d"
,
value
);
//int labelWidth = fontMetrics().width(label);
double
xf
=
m_pixmap
.
height
()
-
pow
(
10.0
,
(
double
)
dbscale
.
at
(
i
)
/
50.0
)
*
m_pixmap
.
height
()
*
40.0
/
42
;
/*if (xf + labelWidth / 2 > m_pixmap.height()) {
xf = height() - labelWidth / 2;
}*/
p
.
setPen
(
palette
().
dark
().
color
());
p
.
drawLine
(
m_offset
,
xf
,
m_offset
+
totalWidth
-
1
,
xf
);
xf
-=
labelHeight
*
2
/
3
;
p
.
setPen
(
palette
().
text
().
color
().
rgb
());
p
.
drawText
(
QRectF
(
0
,
xf
,
m_offset
-
5
,
labelHeight
),
label
,
QTextOption
(
Qt
::
AlignRight
));
}
p
.
setOpacity
(
isEnabled
()
?
1
:
0.5
);
p
.
setPen
(
palette
().
dark
().
color
());
// Clear space between the 2 channels
p
.
setCompositionMode
(
QPainter
::
CompositionMode_Source
);
if
(
m_channelWidth
<
4
)
{
// too many audio channels, simple line between channels
m_channelDistance
=
1
;
m_channelFillWidth
=
m_channelWidth
;
for
(
int
i
=
0
;
i
<
channels
;
i
++
)
{
p
.
drawLine
(
m_offset
+
i
*
(
m_channelWidth
+
m_channelDistance
),
0
,
i
*
(
m_channelWidth
+
m_channelDistance
),
rect
.
height
()
-
1
);
}
}
else
{
m_channelDistance
=
2
;
m_channelFillWidth
=
m_channelWidth
-
2
;
for
(
int
i
=
0
;
i
<
channels
;
i
++
)
{
p
.
drawRect
(
m_offset
+
i
*
(
m_channelWidth
+
m_channelDistance
),
0
,
m_channelWidth
-
1
,
rect
.
height
()
-
1
);
if
(
i
>
0
)
{
p
.
fillRect
(
m_offset
+
i
*
(
m_channelWidth
+
m_channelDistance
)
-
2
,
0
,
2
,
rect
.
height
(),
Qt
::
transparent
);
}
}
}
p
.
end
();
}
// cppcheck-suppress unusedFunction
void
AudioLevelWidget
::
setAudioValues
(
const
QVector
<
int
>
&
values
)
{
m_values
=
values
;
if
(
m_peaks
.
size
()
!=
m_values
.
size
())
{
m_peaks
=
values
;
drawBackground
(
values
.
size
());
}
else
{
for
(
int
i
=
0
;
i
<
m_values
.
size
();
i
++
)
{
m_peaks
[
i
]
--
;
if
(
m_values
.
at
(
i
)
>
m_peaks
.
at
(
i
))
{
m_peaks
[
i
]
=
m_values
.
at
(
i
);
}
}
}
update
();
}
void
AudioLevelWidget
::
setVisibility
(
bool
enable
)
{
if
(
enable
)
{
setVisible
(
true
);
setFixedWidth
(
m_width
);
}
else
{
// set height to 0 so the toolbar layout is not affected
setFixedHeight
(
0
);
setVisible
(
false
);
}
}
void
AudioLevelWidget
::
paintEvent
(
QPaintEvent
*
pe
)
{
if
(
!
isVisible
())
{
return
;
}
QPainter
p
(
this
);
p
.
setClipRect
(
pe
->
rect
());
QRect
rect
(
0
,
0
,
width
(),
height
());
if
(
m_values
.
isEmpty
())
{
p
.
setOpacity
(
0.2
);
p
.
drawPixmap
(
rect
,
m_pixmap
);
return
;
}
p
.
drawPixmap
(
rect
,
m_pixmap
);
p
.
setPen
(
palette
().
dark
().
color
());
p
.
setOpacity
(
0.9
);
int
width
=
m_channelDistance
==
1
?
rect
.
width
()
:
rect
.
width
()
-
1
;
for
(
int
i
=
0
;
i
<
m_values
.
count
();
i
++
)
{
if
(
m_values
.
at
(
i
)
>=
100
)
{
continue
;
}
int
val
=
(
50
+
m_values
.
at
(
i
))
/
150.0
*
rect
.
height
();
p
.
fillRect
(
m_offset
+
i
*
(
m_channelWidth
+
m_channelDistance
)
+
1
,
0
,
m_channelFillWidth
,
height
()
-
val
,
palette
().
dark
());
p
.
fillRect
(
m_offset
+
i
*
(
m_channelWidth
+
m_channelDistance
)
+
1
,
height
()
-
(
50
+
m_peaks
.
at
(
i
))
/
150.0
*
rect
.
height
(),
m_channelFillWidth
,
1
,
palette
().
text
());
}
}
src/audiomixer/audiolevelwidget.hpp
0 → 100644
View file @
9f3c1670
/*
Copyright (C) 2016 Jean-Baptiste Mardelle <jb@kdenlive.org>
This file is part of Kdenlive. See www.kdenlive.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) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef AUDIOLEVELWIDGET_H
#define AUDIOLEVELWIDGET_H
#include <QWidget>
#include <memory>
namespace
Mlt
{
class
Filter
;
}
// namespace Mlt
class
AudioLevelWidget
:
public
QWidget
{
Q_OBJECT
public:
explicit
AudioLevelWidget
(
int
width
,
QWidget
*
parent
=
nullptr
);
~
AudioLevelWidget
()
override
;
void
refreshPixmap
();
int
audioChannels
;
bool
isValid
;
void
setVisibility
(
bool
enable
);
protected:
void
paintEvent
(
QPaintEvent
*
)
override
;
void
resizeEvent
(
QResizeEvent
*
event
)
override
;
private:
std
::
unique_ptr
<
Mlt
::
Filter
>
m_filter
;
int
m_width
;
int
m_offset
;
QPixmap
m_pixmap
;
QVector
<
int
>
m_peaks
;
QVector
<
int
>
m_values
;
int
m_channelWidth
;
int
m_channelDistance
;
int
m_channelFillWidth
;
void
drawBackground
(
int
channels
=
2
);
public
slots
:
void
setAudioValues
(
const
QVector
<
int
>
&
values
);
};
#endif
src/audiomixer/mixermanager.cpp
0 → 100644
View file @
9f3c1670
/***************************************************************************
* Copyright (C) 2019 by Jean-Baptiste Mardelle *
* This file is part of Kdenlive. See www.kdenlive.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) version 3 or any later version accepted by the *
* membership of KDE e.V. (or its successor approved by the membership *
* of KDE e.V.), which shall act as a proxy defined in Section 14 of *
* version 3 of the license. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "mixermanager.hpp"
#include "mixerwidget.hpp"
#include "timeline2/model/timelineitemmodel.hpp"
#include "mlt++/MltService.h"
#include "mlt++/MltTractor.h"
#include <klocalizedstring.h>
#include <QHBoxLayout>
#include <QModelIndex>
const
double
log_factor
=
1.0
/
log10
(
1.0
/
127
);
static
inline
double
levelToDB
(
double
level
)
{
if
(
level
<=
0
)
{
return
-
100
;
}
return
100
*
(
1.0
-
log10
(
level
)
*
log_factor
);
}
MixerManager
::
MixerManager
(
QWidget
*
parent
)
:
QWidget
(
parent
)
,
renderPosition
(
0
)
,
m_connectedWidgets
(
0
)
{
m_box
=
new
QHBoxLayout
;
m_box
->
addStretch
(
10
);
setLayout
(
m_box
);
m_timer
.
setSingleShot
(
true
);
m_timer
.
setInterval
(
100
);
connect
(
&
m_timer
,
&
QTimer
::
timeout
,
[
&
]
()
{
for
(
auto
w
:
m_mixers
)
{
w
.
second
->
updateAudioLevel
(
m_lastFrame
);
}
});
}
void
MixerManager
::
registerTrack
(
int
tid
,
std
::
shared_ptr
<
Mlt
::
Tractor
>
service
,
const
QString
&
trackTag
)
{
if
(
m_mixers
.
count
(
tid
)
>
0
)
{
// Track already registered
return
;
}
std
::
shared_ptr
<
MixerWidget
>
mixer
(
new
MixerWidget
(
tid
,
service
,
trackTag
,
this
));
connect
(
mixer
.
get
(),
&
MixerWidget
::
muteTrack
,
[
&
](
int
id
,
bool
mute
)
{
m_model
->
setTrackProperty
(
id
,
"hide"
,
mute
?
QStringLiteral
(
"1"
)
:
QStringLiteral
(
"3"
));
});
connect
(
this
,
&
MixerManager
::
updateLevels
,
mixer
.
get
(),
&
MixerWidget
::
updateAudioLevel
);
connect
(
mixer
.
get
(),
&
MixerWidget
::
updateConnection
,
[
&
](
int
id
,
bool
doConnect
)
{
//connect(this, &MixerManager::storeLevels, m_mixers[id].get(), &MixerWidget::storeAudioLevel, Qt::DirectConnection);
m_connectedWidgets
++
;
if
(
m_connectedWidgets
==
1
)
{
emit
connectMixerRenderer
(
true
);
}
});
connect
(
mixer
.
get
(),
&
MixerWidget
::
toggleSolo
,
[
&
](
int
trid
,
bool
solo
)
{
if
(
!
solo
)
{
// unmute
for
(
int
id
:
m_soloMuted
)
{
if
(
m_mixers
.
count
(
id
)
>
0
)
{
m_model
->
setTrackProperty
(
id
,
"hide"
,
QStringLiteral
(
"1"
));
}
}
m_soloMuted
.
clear
();
}
else
{
if
(
!
m_soloMuted
.
isEmpty
())
{
// Another track was solo, discard first
for
(
int
id
:
m_soloMuted
)
{
if
(
m_mixers
.
count
(
id
)
>
0
)
{
m_model
->
setTrackProperty
(
id
,
"hide"
,
QStringLiteral
(
"1"
));
}
}
m_soloMuted
.
clear
();
}
for
(
auto
item
:
m_mixers
)
{
if
(
item
.
first
>
-
1
&&
item
.
first
!=
trid
&&
!
item
.
second
->
isMute
())
{
m_model
->
setTrackProperty
(
item
.
first
,
"hide"
,
QStringLiteral
(
"3"
));
m_soloMuted
<<
item
.
first
;
item
.
second
->
unSolo
();
}
}
}
});
m_mixers
[
tid
]
=
mixer
;
m_box
->
insertWidget
(
0
,
mixer
.
get
());
}
void
MixerManager
::
deregisterTrack
(
int
tid
)
{
Q_ASSERT
(
m_mixers
.
count
(
tid
)
>
0
);
m_mixers
.
erase
(
tid
);
}
void
MixerManager
::
resetAudioValues
()
{
qDebug
()
<<
"======
\n\n
RESTTING AUDIO VALUES
\n\n
------------------_"
;
for
(
auto
item
:
m_mixers
)
{
item
.
second
.
get
()
->
clear
();
}
}
void
MixerManager
::
cleanup
()
{
for
(
auto
item
:
m_mixers
)
{
m_box
->
removeWidget
(
item
.
second
.
get
());
}
m_mixers
.
clear
();
m_connectedWidgets
=
0
;
}
void
MixerManager
::
setModel
(
std
::
shared_ptr
<
TimelineItemModel
>
model
)
{
// Insert master mixer
int
tid
=
-
1
;
m_model
=
model
;
connect
(
m_model
.
get
(),
&
TimelineItemModel
::
dataChanged
,
[
&
](
const
QModelIndex
&
topLeft
,
const
QModelIndex
&
bottomRight
,
const
QVector
<
int
>
&
roles
)
{
if
(
roles
.
contains
(
TimelineModel
::
IsDisabledRole
))
{
int
id
=
(
int
)
topLeft
.
internalId
();
if
(
m_mixers
.
count
(
id
)
>
0
)
{
m_mixers
[
id
]
->
setMute
(
m_model
->
data
(
topLeft
,
TimelineModel
::
IsDisabledRole
).
toBool
());
}
else
{
qDebug
()
<<
"=== MODEL DATA CHANGED: MUTE DONE TRACK NOT FOUND!!!"
;
}
}
});
Mlt
::
Tractor
*
service
=
model
->
tractor
();
if
(
m_mixers
.
count
(
tid
)
>
0
)
{
// delete previous master mixer
m_box
->
removeWidget
(
m_mixers
[
tid
].
get
());
m_mixers
.
erase
(
tid
);
}
std
::
shared_ptr
<
MixerWidget
>
mixer
(
new
MixerWidget
(
tid
,
service
,
i18n
(
"Master"
),
this
));
connect
(
mixer
.
get
(),
&
MixerWidget
::
muteTrack
,
[
&
](
int
/*id*/
,
bool
mute
)
{
qDebug
()
<<
"=== SETTING MUITE"
;
m_model
->
tractor
()
->
set
(
"hide"
,
mute
?
3
:
1
);
});
connect
(
this
,
&
MixerManager
::
updateLevels
,
mixer
.
get
(),
&
MixerWidget
::
updateAudioLevel
);
connect
(
mixer
.
get
(),
&
MixerWidget
::
updateConnection
,
[
&
](
int
id
,
bool
doConnect
)
{
//connect(this, &MixerManager::storeLevels, m_mixers[id].get(), &MixerWidget::storeAudioLevel, Qt::DirectConnection);
m_connectedWidgets
++
;
if
(
m_connectedWidgets
==
1
)
{
emit
connectMixerRenderer
(
true
);
}
});
m_mixers
[
tid
]
=
mixer
;
m_box
->
insertWidget
(
0
,
mixer
.
get
());
}
src/audiomixer/mixermanager.hpp
0 → 100644
View file @
9f3c1670
/***************************************************************************
* Copyright (C) 2019 by Jean-Baptiste Mardelle *
* This file is part of Kdenlive. See www.kdenlive.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) version 3 or any later version accepted by the *
* membership of KDE e.V. (or its successor approved by the membership *
* of KDE e.V.), which shall act as a proxy defined in Section 14 of *
* version 3 of the license. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef MIXERMANGER_H
#define MIXERMANGER_H
#include "definitions.h"
#include <memory>
#include <unordered_map>
#include <QWidget>
#include <QTimer>
namespace
Mlt
{
class
Tractor
;
}
class
MixerWidget
;
class
QHBoxLayout
;
class
TimelineItemModel
;
class
MixerManager
:
public
QWidget
{
Q_OBJECT
public:
MixerManager
(
QWidget
*
parent
);
/* @brief Shows the parameters of the given transition model */
void
registerTrack
(
int
tid
,
std
::
shared_ptr
<
Mlt
::
Tractor
>
service
,
const
QString
&
trackTag
);
void
deregisterTrack
(
int
tid
);
void
setModel
(
std
::
shared_ptr
<
TimelineItemModel
>
model
);
void
cleanup
();
public
slots
:
void
resetAudioValues
();
signals:
void
updateLevels
(
int
);
void
connectMixerRenderer
(
bool
);
void
triggerUpdate
();
public:
int
renderPosition
;
protected:
std
::
unordered_map
<
int
,
std
::
shared_ptr
<
MixerWidget
>>
m_mixers
;
private:
std
::
shared_ptr
<
Mlt
::
Tractor
>
m_masterService
;
std
::
shared_ptr
<
TimelineItemModel
>
m_model
;
QHBoxLayout
*
m_box
;
QTimer
m_timer
;
int
m_lastFrame
;
int
m_connectedWidgets
;
QVector
<
int
>
m_soloMuted
;
};
#endif
src/audiomixer/mixerwidget.cpp
0 → 100644
View file @
9f3c1670
/***************************************************************************
* Copyright (C) 2019 by Jean-Baptiste Mardelle *
* This file is part of Kdenlive. See www.kdenlive.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) version 3 or any later version accepted by the *
* membership of KDE e.V. (or its successor approved by the membership *
* of KDE e.V.), which shall act as a proxy defined in Section 14 of *
* version 3 of the license. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "mixerwidget.hpp"
#include "mlt++/MltFilter.h"
#include "mlt++/MltTractor.h"
#include "mlt++/MltProfile.h"
#include "mixerwidget.hpp"
#include "mixermanager.hpp"
#include "audiolevelwidget.hpp"
#include <klocalizedstring.h>
#include <KDualAction>
#include <QGridLayout>
#include <QToolButton>
#include <QCheckBox>
#include <QSlider>
#include <QSpinBox>
#include <QDial>
#include <QLabel>
#include <QFontDatabase>
const
double
log_factor
=
1.0
/
log10
(
1.0
/
127
);
static
inline
int
levelToDB
(
double
level
)
{
if
(
level
<=
0
)
{
return
-
100
;
}
return
100
*
(
1.0
-
log10
(
level
)
*
log_factor
);
}
void
MixerWidget
::
property_changed
(
mlt_service
,
MixerWidget
*
widget
,
char
*
/*name*/
)
{
if
(
!
widget
->
m_levels
.
contains
(
widget
->
m_manager
->
renderPosition
))
{
widget
->
m_levels
[
widget
->
m_manager
->
renderPosition
]
=
{
levelToDB
(
mlt_properties_get_double
(
MLT_FILTER_PROPERTIES
(
widget
->
m_monitorFilter
->
get_filter
()),
"_audio_level.0"
)),
levelToDB
(
mlt_properties_get_double
(
MLT_FILTER_PROPERTIES
(
widget
->
m_monitorFilter
->
get_filter
()),
"_audio_level.1"
))};
}
}
MixerWidget
::
MixerWidget
(
int
tid
,
std
::
shared_ptr
<
Mlt
::
Tractor
>
service
,
const
QString
&
trackTag
,
MixerManager
*
parent
)
:
QWidget
(
parent
)
,
m_manager
(
parent
)
,
m_tid
(
tid
)
,
m_levelFilter
(
nullptr
)
,
m_monitorFilter
(
nullptr
)
,
m_balanceFilter
(
nullptr
)
,
m_solo
(
nullptr
)
,
m_lastVolume
(
0
)
{
buildUI
(
service
.
get
(),
trackTag
);
}
MixerWidget
::
MixerWidget
(
int
tid
,
Mlt
::
Tractor
*
service
,
const
QString
&
trackTag
,
MixerManager
*
parent
)
:
QWidget
(
parent
)
,
m_manager
(
parent
)
,
m_tid
(
tid
)