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
9c92a5d1
Commit
9c92a5d1
authored
Oct 15, 2019
by
Jean-Baptiste Mardelle
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Mixer: add record buttons (volume doesn't yet adjust mic level)
parent
df21bcce
Pipeline
#8998
passed with stage
in 17 minutes and 12 seconds
Changes
10
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
102 additions
and
24 deletions
+102
-24
src/audiomixer/mixermanager.cpp
src/audiomixer/mixermanager.cpp
+7
-1
src/audiomixer/mixermanager.hpp
src/audiomixer/mixermanager.hpp
+2
-0
src/audiomixer/mixerwidget.cpp
src/audiomixer/mixerwidget.cpp
+61
-2
src/audiomixer/mixerwidget.hpp
src/audiomixer/mixerwidget.hpp
+7
-1
src/capture/mediacapture.cpp
src/capture/mediacapture.cpp
+6
-5
src/capture/mediacapture.h
src/capture/mediacapture.h
+4
-3
src/core.cpp
src/core.cpp
+7
-6
src/core.h
src/core.h
+2
-2
src/monitor/recmanager.cpp
src/monitor/recmanager.cpp
+2
-2
src/timeline2/view/timelinecontroller.cpp
src/timeline2/view/timelinecontroller.cpp
+4
-2
No files found.
src/audiomixer/mixermanager.cpp
View file @
9c92a5d1
...
...
@@ -128,7 +128,7 @@ void MixerManager::setModel(std::shared_ptr<TimelineItemModel> model)
{
// Insert master mixer
m_model
=
model
;
connect
(
m_model
.
get
(),
&
TimelineItemModel
::
dataChanged
,
[
&
](
const
QModelIndex
&
topLeft
,
const
QModelIndex
&
bottomRight
,
const
QVector
<
int
>
&
roles
)
{
connect
(
m_model
.
get
(),
&
TimelineItemModel
::
dataChanged
,
[
&
](
const
QModelIndex
&
topLeft
,
const
QModelIndex
&
,
const
QVector
<
int
>
&
roles
)
{
if
(
roles
.
contains
(
TimelineModel
::
IsDisabledRole
))
{
int
id
=
(
int
)
topLeft
.
internalId
();
if
(
m_mixers
.
count
(
id
)
>
0
)
{
...
...
@@ -153,3 +153,9 @@ void MixerManager::setModel(std::shared_ptr<TimelineItemModel> model)
m_masterBox
->
addWidget
(
m_masterMixer
.
get
());
}
void
MixerManager
::
recordStateChanged
(
int
tid
,
bool
recording
)
{
if
(
m_mixers
.
count
(
tid
)
>
0
)
{
m_mixers
[
tid
]
->
setRecordState
(
recording
);
}
}
src/audiomixer/mixermanager.hpp
View file @
9c92a5d1
...
...
@@ -50,11 +50,13 @@ public:
public
slots
:
void
resetAudioValues
();
void
recordStateChanged
(
int
tid
,
bool
recording
);
signals:
void
updateLevels
(
int
);
void
connectMixerRenderer
(
bool
);
void
triggerUpdate
();
void
recordAudio
(
int
tid
);
public:
int
renderPosition
;
...
...
src/audiomixer/mixerwidget.cpp
View file @
9c92a5d1
...
...
@@ -25,9 +25,12 @@
#include "mlt++/MltTractor.h"
#include "mlt++/MltEvent.h"
#include "mlt++/MltProfile.h"
#include "core.h"
#include "kdenlivesettings.h"
#include "mixerwidget.hpp"
#include "mixermanager.hpp"
#include "audiolevelwidget.hpp"
#include "capture/mediacapture.h"
#include <klocalizedstring.h>
#include <KDualAction>
...
...
@@ -73,8 +76,10 @@ MixerWidget::MixerWidget(int tid, std::shared_ptr<Mlt::Tractor> service, const Q
,
m_monitorFilter
(
nullptr
)
,
m_balanceFilter
(
nullptr
)
,
m_solo
(
nullptr
)
,
m_record
(
nullptr
)
,
m_lastVolume
(
0
)
,
m_listener
(
nullptr
)
,
m_recording
(
false
)
{
buildUI
(
service
.
get
(),
trackTag
);
}
...
...
@@ -87,8 +92,10 @@ MixerWidget::MixerWidget(int tid, Mlt::Tractor *service, const QString &trackTag
,
m_monitorFilter
(
nullptr
)
,
m_balanceFilter
(
nullptr
)
,
m_solo
(
nullptr
)
,
m_record
(
nullptr
)
,
m_lastVolume
(
0
)
,
m_listener
(
nullptr
)
,
m_recording
(
false
)
{
buildUI
(
service
,
trackTag
);
}
...
...
@@ -209,7 +216,7 @@ void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackTag)
mute
->
setAutoRaise
(
true
);
if
(
m_tid
>
-
1
)
{
// No solo button on master
// No solo
/ rec
button on master
m_solo
=
new
QToolButton
(
this
);
m_solo
->
setCheckable
(
true
);
m_solo
->
setIcon
(
QIcon
::
fromTheme
(
"headphones"
));
...
...
@@ -217,12 +224,22 @@ void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackTag)
connect
(
m_solo
,
&
QToolButton
::
toggled
,
[
&
](
bool
toggled
)
{
emit
toggleSolo
(
m_tid
,
toggled
);
});
m_record
=
new
QToolButton
(
this
);
m_record
->
setCheckable
(
true
);
m_record
->
setIcon
(
QIcon
::
fromTheme
(
"media-record"
));
m_record
->
setAutoRaise
(
true
);
connect
(
m_record
,
&
QToolButton
::
toggled
,
[
&
](
bool
toggled
)
{
m_manager
->
recordAudio
(
m_tid
);
});
}
connect
(
m_volumeSlider
,
&
QSlider
::
valueChanged
,
[
&
](
int
value
)
{
QSignalBlocker
bk
(
m_volumeSpin
);
m_volumeSpin
->
setValue
(
value
);
if
(
m_levelFilter
!=
nullptr
)
{
if
(
m_recording
)
{
KdenliveSettings
::
setAudiocapturevolume
(
value
);
//TODO update capture volume
}
else
if
(
m_levelFilter
!=
nullptr
)
{
m_levelFilter
->
set
(
"level"
,
value
);
}
});
...
...
@@ -243,6 +260,9 @@ void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackTag)
if
(
m_solo
)
{
buttonslay
->
addWidget
(
m_solo
);
}
if
(
m_record
)
{
buttonslay
->
addWidget
(
m_record
);
}
lay
->
addLayout
(
buttonslay
);
lay
->
addWidget
(
m_balanceDial
);
lay
->
addWidget
(
m_balanceSpin
);
...
...
@@ -305,3 +325,42 @@ void MixerWidget::unSolo()
}
}
void
MixerWidget
::
gotRecLevels
(
QVector
<
qreal
>
levels
)
{
switch
(
levels
.
size
())
{
case
0
:
m_audioMeterWidget
->
setAudioValues
({
-
100
,
-
100
});
break
;
case
1
:
m_audioMeterWidget
->
setAudioValues
({
levelToDB
(
levels
[
0
]),
-
100
});
break
;
default:
m_audioMeterWidget
->
setAudioValues
({
levelToDB
(
levels
[
0
]),
levelToDB
(
levels
[
1
])});
break
;
}
}
void
MixerWidget
::
setRecordState
(
bool
recording
)
{
m_recording
=
recording
;
QSignalBlocker
bk
(
m_volumeSpin
);
QSignalBlocker
bk2
(
m_volumeSlider
);
if
(
m_recording
)
{
connect
(
pCore
->
getAudioDevice
(),
&
MediaCapture
::
audioLevels
,
this
,
&
MixerWidget
::
gotRecLevels
);
m_volumeSlider
->
setRange
(
0
,
100
);
m_volumeSpin
->
setRange
(
0
,
100
);
m_volumeSpin
->
setSuffix
(
QStringLiteral
(
"%"
));
m_volumeSpin
->
setValue
(
KdenliveSettings
::
audiocapturevolume
());
m_volumeSlider
->
setValue
(
KdenliveSettings
::
audiocapturevolume
());
}
else
{
int
level
=
m_levelFilter
->
get_int
(
"level"
);
disconnect
(
pCore
->
getAudioDevice
(),
&
MediaCapture
::
audioLevels
,
this
,
&
MixerWidget
::
gotRecLevels
);
m_volumeSlider
->
setRange
(
-
100
,
60
);
m_volumeSpin
->
setRange
(
-
100
,
60
);
m_volumeSpin
->
setSuffix
(
i18n
(
"dB"
));
m_volumeSpin
->
setValue
(
level
);
m_volumeSlider
->
setValue
(
level
);
}
QSignalBlocker
bk3
(
m_record
);
m_record
->
setChecked
(
recording
);
}
src/audiomixer/mixerwidget.hpp
View file @
9c92a5d1
...
...
@@ -66,6 +66,10 @@ public:
public
slots
:
void
updateAudioLevel
(
int
pos
);
void
setAudioLevel
(
const
QVector
<
int
>
vol
);
void
setRecordState
(
bool
recording
);
private
slots
:
void
gotRecLevels
(
QVector
<
qreal
>
levels
);
protected:
MixerManager
*
m_manager
;
...
...
@@ -83,14 +87,16 @@ private:
std
::
shared_ptr
<
AudioLevelWidget
>
m_audioMeterWidget
;
QSlider
*
m_volumeSlider
;
QToolButton
*
m_solo
;
QToolButton
*
m_record
;
QMutex
m_storeMutex
;
int
m_lastVolume
;
Mlt
::
Event
*
m_listener
;
bool
m_recording
;
signals:
void
gotLevels
(
QPair
<
double
,
double
>
);
void
muteTrack
(
int
tid
,
bool
mute
);
void
toggleSolo
(
int
m_
tid
,
bool
toggled
);
void
toggleSolo
(
int
tid
,
bool
toggled
);
};
#endif
...
...
src/capture/mediacapture.cpp
View file @
9c92a5d1
...
...
@@ -59,21 +59,22 @@ void MediaCapture::resetIfUnused()
}
}
void
MediaCapture
::
recordAudio
(
bool
record
)
void
MediaCapture
::
recordAudio
(
int
tid
,
bool
record
)
{
QMutexLocker
lk
(
&
m_recMutex
);
if
(
!
m_audioRecorder
)
{
m_audioRecorder
=
std
::
make_unique
<
QAudioRecorder
>
(
this
);
m_probe
->
setSource
(
m_audioRecorder
.
get
());
connect
(
m_audioRecorder
.
get
(),
&
QAudioRecorder
::
stateChanged
,
[
&
]
(
QMediaRecorder
::
State
state
)
{
connect
(
m_audioRecorder
.
get
(),
&
QAudioRecorder
::
stateChanged
,
[
&
,
tid
]
(
QMediaRecorder
::
State
state
)
{
m_recordState
=
state
;
if
(
m_recordState
==
QMediaRecorder
::
StoppedState
)
{
m_resetTimer
.
start
();
m_levels
.
clear
();
emit
audioLevels
(
m_levels
);
emit
levelsChanged
();
pCore
->
finalizeRecording
(
getCaptureOutputLocation
().
toLocalFile
());
}
emit
recordStateChanged
();
emit
recordStateChanged
(
tid
,
m_recordState
==
QMediaRecorder
::
RecordingState
);
});
}
...
...
@@ -101,7 +102,7 @@ void MediaCapture::recordAudio(bool record)
}
}
void
MediaCapture
::
recordVideo
(
bool
record
)
void
MediaCapture
::
recordVideo
(
int
tid
,
bool
record
)
{
// TO DO - fix video capture
if
(
!
m_videoRecorder
)
{
...
...
@@ -317,13 +318,13 @@ QVector<qreal> getBufferLevels(const QAudioBuffer &buffer)
}
break
;
}
return
values
;
}
void
MediaCapture
::
processBuffer
(
const
QAudioBuffer
&
buffer
)
{
m_levels
=
getBufferLevels
(
buffer
);
emit
audioLevels
(
m_levels
);
emit
levelsChanged
();
}
...
...
src/capture/mediacapture.h
View file @
9c92a5d1
...
...
@@ -44,8 +44,8 @@ class MediaCapture : public QObject
public:
MediaCapture
(
QObject
*
parent
);
~
MediaCapture
()
override
;
void
recordAudio
(
bool
/*record*/
);
void
recordVideo
(
bool
/*record*/
);
void
recordAudio
(
int
tid
,
bool
/*record*/
);
void
recordVideo
(
int
tid
,
bool
/*record*/
);
/** @brief Returns true if a recording is in progress **/
bool
isRecording
()
const
;
/** @brief Sets m_path to selected output location **/
...
...
@@ -86,8 +86,9 @@ private slots:
signals:
void
levelsChanged
();
void
recordStateChanged
();
void
recordStateChanged
(
int
tid
,
bool
recording
);
void
recordDone
();
void
audioLevels
(
QVector
<
qreal
>
levels
);
};
#endif
src/core.cpp
View file @
9c92a5d1
...
...
@@ -175,6 +175,7 @@ void Core::initGUI(const QUrl &Url)
m_mixerWidget
=
new
MixerManager
(
m_mainWindow
);
connect
(
m_library
,
SIGNAL
(
addProjectClips
(
QList
<
QUrl
>
)),
m_binWidget
,
SLOT
(
droppedUrls
(
QList
<
QUrl
>
)));
connect
(
this
,
&
Core
::
updateLibraryPath
,
m_library
,
&
LibraryWidget
::
slotUpdateLibraryPath
);
connect
(
m_capture
.
get
(),
&
MediaCapture
::
recordStateChanged
,
m_mixerWidget
,
&
MixerManager
::
recordStateChanged
);
m_monitorManager
=
new
MonitorManager
(
this
);
connect
(
m_monitorManager
,
&
MonitorManager
::
pauseTriggered
,
m_mixerWidget
,
&
MixerManager
::
resetAudioValues
);
// Producer queue, creating MLT::Producers on request
...
...
@@ -711,22 +712,22 @@ void Core::clean()
m_self
.
reset
();
}
void
Core
::
startMediaCapture
(
bool
checkAudio
,
bool
checkVideo
)
void
Core
::
startMediaCapture
(
int
tid
,
bool
checkAudio
,
bool
checkVideo
)
{
if
(
checkAudio
&&
checkVideo
)
{
m_capture
->
recordVideo
(
true
);
m_capture
->
recordVideo
(
t
id
,
t
rue
);
}
else
if
(
checkAudio
)
{
m_capture
->
recordAudio
(
true
);
m_capture
->
recordAudio
(
t
id
,
t
rue
);
}
m_mediaCaptureFile
=
m_capture
->
getCaptureOutputLocation
();
}
void
Core
::
stopMediaCapture
(
bool
checkAudio
,
bool
checkVideo
)
void
Core
::
stopMediaCapture
(
int
tid
,
bool
checkAudio
,
bool
checkVideo
)
{
if
(
checkAudio
&&
checkVideo
)
{
m_capture
->
recordVideo
(
false
);
m_capture
->
recordVideo
(
tid
,
false
);
}
else
if
(
checkAudio
)
{
m_capture
->
recordAudio
(
false
);
m_capture
->
recordAudio
(
tid
,
false
);
}
}
...
...
src/core.h
View file @
9c92a5d1
...
...
@@ -187,8 +187,8 @@ public:
/** @brief Returns current timeline cursor position */
int
getTimelinePosition
()
const
;
/** @brief Handles audio and video capture **/
void
startMediaCapture
(
bool
,
bool
);
void
stopMediaCapture
(
bool
,
bool
);
void
startMediaCapture
(
int
tid
,
bool
,
bool
);
void
stopMediaCapture
(
int
tid
,
bool
,
bool
);
QStringList
getAudioCaptureDevices
();
int
getMediaCaptureState
();
bool
isMediaCapturing
();
...
...
src/monitor/recmanager.cpp
View file @
9c92a5d1
...
...
@@ -151,7 +151,7 @@ void RecManager::stopCapture()
slotRecord
(
false
);
}
else
if
(
pCore
->
getMediaCaptureState
()
==
1
&&
(
m_checkAudio
||
m_checkVideo
))
{
// QMediaRecorder::RecordingState value is 1
pCore
->
stopMediaCapture
(
m_checkAudio
,
m_checkVideo
);
pCore
->
stopMediaCapture
(
-
1
,
m_checkAudio
,
m_checkVideo
);
m_monitor
->
slotOpenClip
(
nullptr
);
}
}
...
...
@@ -242,7 +242,7 @@ void RecManager::slotRecord(bool record)
params
.
replace
(
QLatin1String
(
"alsa"
),
QStringLiteral
(
"dshow"
));
// Remove vorbis codec
params
.
replace
(
QLatin1String
(
"-acodec libvorbis"
),
QString
());
// Find first audio device
QProcess
tst
;
tst
.
setProcessChannelMode
(
QProcess
::
MergedChannels
);
...
...
src/timeline2/view/timelinecontroller.cpp
View file @
9c92a5d1
...
...
@@ -48,6 +48,7 @@
#include "timeline2/view/dialogs/clipdurationdialog.h"
#include "timeline2/view/dialogs/trackdialog.h"
#include "transitions/transitionsrepository.hpp"
#include "audiomixer/mixermanager.hpp"
#include <KColorScheme>
#include <QApplication>
...
...
@@ -78,6 +79,7 @@ TimelineController::TimelineController(QObject *parent)
m_disablePreview
->
setEnabled
(
false
);
connect
(
pCore
.
get
(),
&
Core
::
finalizeRecording
,
this
,
&
TimelineController
::
finishRecording
);
connect
(
pCore
.
get
(),
&
Core
::
autoScrollChanged
,
this
,
&
TimelineController
::
autoScrollChanged
);
connect
(
pCore
->
mixer
(),
&
MixerManager
::
recordAudio
,
this
,
&
TimelineController
::
switchRecording
);
}
TimelineController
::~
TimelineController
()
...
...
@@ -2556,10 +2558,10 @@ void TimelineController::switchRecording(int trackId)
}
}
pCore
->
monitorManager
()
->
slotSwitchMonitors
(
false
);
pCore
->
startMediaCapture
(
true
,
false
);
pCore
->
startMediaCapture
(
tr
ackId
,
tr
ue
,
false
);
pCore
->
monitorManager
()
->
slotPlay
();
}
else
{
pCore
->
stopMediaCapture
(
true
,
false
);
pCore
->
stopMediaCapture
(
tr
ackId
,
tr
ue
,
false
);
pCore
->
monitorManager
()
->
slotPause
();
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment