Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Preliminary support for projects with 4/6 audio channels

parent 40efcb54
Pipeline #20163 canceled with stage
......@@ -34,7 +34,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
AudioLevelWidget::AudioLevelWidget(int width, QWidget *parent)
: QWidget(parent)
, audioChannels(2)
, audioChannels(pCore->audioChannels())
, m_width(width)
, m_channelWidth(width / 2)
, m_channelDistance(2)
......@@ -80,7 +80,7 @@ void AudioLevelWidget::drawBackground(int channels)
return;
}
m_offset = fontMetrics().boundingRect(QStringLiteral("-45")).width() + 5;
newSize.setWidth(newSize.width() - m_offset);
newSize.setWidth(newSize.width() - m_offset - 1);
QLinearGradient gradient(0, newSize.height(), 0, 0);
gradient.setColorAt(0.0, Qt::darkGreen);
gradient.setColorAt(0.379, Qt::darkGreen);
......@@ -130,7 +130,7 @@ void AudioLevelWidget::drawBackground(int channels)
}
p.setOpacity(isEnabled() ? 1 : 0.5);
p.setPen(palette().dark().color());
// Clear space between the 2 channels
// Clear space between the channels
p.setCompositionMode(QPainter::CompositionMode_Source);
if (m_channelWidth < 4) {
// too many audio channels, simple line between channels
......
......@@ -86,7 +86,12 @@ void MixerWidget::property_changed( mlt_service , MixerWidget *widget, char *nam
mlt_properties filter_props = MLT_FILTER_PROPERTIES( widget->m_monitorFilter->get_filter());
int pos = mlt_properties_get_int(filter_props, "_position");
if (!widget->m_levels.contains(pos)) {
widget->m_levels[pos] = {IEC_Scale(mlt_properties_get_double(filter_props, "_audio_level.0")), IEC_Scale(mlt_properties_get_double(filter_props, "_audio_level.1"))};
QVector<double> levels;
for (int i = 0; i < widget->m_channels; i++) {
levels << IEC_Scale(mlt_properties_get_double(filter_props, QString("_audio_level.%1").arg(i).toUtf8().constData()));
}
widget->m_levels[pos] = std::move(levels);
//{IEC_Scale(mlt_properties_get_double(filter_props, "_audio_level.0")), IEC_Scale(mlt_properties_get_double(filter_props, "_audio_level.1"))};
if (widget->m_levels.size() > widget->m_maxLevels) {
widget->m_levels.erase(widget->m_levels.begin());
}
......@@ -101,6 +106,7 @@ MixerWidget::MixerWidget(int tid, std::shared_ptr<Mlt::Tractor> service, const Q
, m_levelFilter(nullptr)
, m_monitorFilter(nullptr)
, m_balanceFilter(nullptr)
, m_channels(pCore->audioChannels())
, m_maxLevels(qMax(30, (int)(service->get_fps() * 1.5)))
, m_solo(nullptr)
, m_record(nullptr)
......@@ -119,6 +125,7 @@ MixerWidget::MixerWidget(int tid, Mlt::Tractor *service, const QString &trackTag
, m_levelFilter(nullptr)
, m_monitorFilter(nullptr)
, m_balanceFilter(nullptr)
, m_channels(pCore->audioChannels())
, m_maxLevels(qMax(30, (int)(service->get_fps() * 1.5)))
, m_solo(nullptr)
, m_record(nullptr)
......@@ -404,7 +411,7 @@ void MixerWidget::updateAudioLevel(int pos)
{
QMutexLocker lk(&m_storeMutex);
if (m_levels.contains(pos)) {
m_audioMeterWidget->setAudioValues({m_levels.value(pos).first, m_levels.value(pos).second});
m_audioMeterWidget->setAudioValues(m_levels.value(pos));
//m_levels.remove(pos);
} else {
m_audioMeterWidget->setAudioValues({-100, -100});
......
......@@ -87,7 +87,8 @@ protected:
std::shared_ptr<Mlt::Filter> m_levelFilter;
std::shared_ptr<Mlt::Filter> m_monitorFilter;
std::shared_ptr<Mlt::Filter> m_balanceFilter;
QMap<int, QPair<double, double>> m_levels;
QMap<int, QVector<double>> m_levels;
int m_channels;
KDualAction *m_muteAction;
QSpinBox *m_balanceSpin;
QDial *m_balanceDial;
......
......@@ -917,3 +917,8 @@ bool Core::enableMultiTrack(bool enable)
}
return false;
}
int Core::audioChannels()
{
return currentDoc()->audioChannels();
}
......@@ -221,6 +221,8 @@ public:
int undoIndex() const;
/** @brief Enable / disable monitor multitrack view. Returns false if multitrack was not previously enabled */
bool enableMultiTrack(bool enable);
/** @brief Returns number of audio channels for this project. */
int audioChannels();
private:
explicit Core();
......
......@@ -1404,6 +1404,8 @@ void RenderWidget::generateRenderFiles(QDomDocument doc, const QString &playlist
consumer.setAttribute(QStringLiteral("in"), in);
consumer.setAttribute(QStringLiteral("out"), out);
}
// Audio Channels
consumer.setAttribute(QStringLiteral("channels"), pCore->audioChannels());
// Check if the rendering profile is different from project profile,
// in which case we need to use the producer_comsumer from MLT
......
......@@ -71,7 +71,7 @@
const double DOCUMENTVERSION = 0.99;
KdenliveDoc::KdenliveDoc(const QUrl &url, QString projectFolder, QUndoGroup *undoGroup, const QString &profileName, const QMap<QString, QString> &properties,
const QMap<QString, QString> &metadata, const QPoint &tracks, bool *openBackup, MainWindow *parent)
const QMap<QString, QString> &metadata, const QPair<int, int> &tracks, int audioChannels, bool *openBackup, MainWindow *parent)
: QObject(parent)
, m_autosave(nullptr)
, m_url(url)
......@@ -106,9 +106,10 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, QString projectFolder, QUndoGroup *und
m_documentProperties[QStringLiteral("generateimageproxy")] = QString::number((int)KdenliveSettings::generateimageproxy());
m_documentProperties[QStringLiteral("proxyimageminsize")] = QString::number(KdenliveSettings::proxyimageminsize());
m_documentProperties[QStringLiteral("proxyimagesize")] = QString::number(KdenliveSettings::proxyimagesize());
m_documentProperties[QStringLiteral("videoTarget")] = QString::number(tracks.y());
m_documentProperties[QStringLiteral("audioTarget")] = QString::number(tracks.y() - 1);
m_documentProperties[QStringLiteral("activeTrack")] = QString::number(tracks.y());
m_documentProperties[QStringLiteral("videoTarget")] = QString::number(tracks.second);
m_documentProperties[QStringLiteral("audioTarget")] = QString::number(tracks.second - 1);
m_documentProperties[QStringLiteral("activeTrack")] = QString::number(tracks.second);
m_documentProperties[QStringLiteral("audioChannels")] = QString::number(audioChannels);
m_documentProperties[QStringLiteral("enableTimelineZone")] = QLatin1Char('0');
m_documentProperties[QStringLiteral("zonein")] = QLatin1Char('0');
m_documentProperties[QStringLiteral("zoneout")] = QStringLiteral("75");
......@@ -250,7 +251,7 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, QString projectFolder, QUndoGroup *und
if (!success) {
m_url.clear();
pCore->setCurrentProfile(profileName);
m_document = createEmptyDocument(tracks.x(), tracks.y());
m_document = createEmptyDocument(tracks.first, tracks.second);
updateProjectProfile(false);
} else {
m_clipsCount = m_document.elementsByTagName(QLatin1String("entry")).size();
......@@ -1760,3 +1761,8 @@ QMap <QString, QString> KdenliveDoc::getProjectTags()
}
return tags;
}
int KdenliveDoc::audioChannels() const
{
return getDocumentProperty(QStringLiteral("audioChannels"), QStringLiteral("2")).toInt();
}
......@@ -58,7 +58,7 @@ class KdenliveDoc : public QObject
Q_OBJECT
public:
KdenliveDoc(const QUrl &url, QString projectFolder, QUndoGroup *undoGroup, const QString &profileName, const QMap<QString, QString> &properties,
const QMap<QString, QString> &metadata, const QPoint &tracks, bool *openBackup, MainWindow *parent = nullptr);
const QMap<QString, QString> &metadata, const QPair<int, int> &tracks, int audioChannels, bool *openBackup, MainWindow *parent = nullptr);
~KdenliveDoc() override;
friend class LoadJob;
/** @brief Get current document's producer. */
......@@ -157,6 +157,8 @@ public:
int clipsCount() const;
/** @brief Returns a list of project tags (color / description) */
QMap <QString, QString> getProjectTags();
/** @brief Returns the number of audio channels for this project */
int audioChannels() const;
private:
QUrl m_url;
......
......@@ -144,6 +144,11 @@
<default>2</default>
</entry>
<entry name="audio_channels" type="Int">
<label>Default number of audio channels per track.</label>
<default>0</default>
</entry>
<entry name="enableproxy" type="Bool">
<label>Enable proxy clips.</label>
<default>false</default>
......
......@@ -1825,8 +1825,8 @@ void MainWindow::slotEditProjectSettings()
{
KdenliveDoc *project = pCore->currentDoc();
QPair <int, int> p = getMainTimeline()->getTracksCount();
ProjectSettings *w = new ProjectSettings(project, project->metadata(), getMainTimeline()->controller()->extractCompositionLumas(), p.first, p.second,
int channels = qMin(project->getDocumentProperty(QStringLiteral("audioChannels"), QStringLiteral("2")).toInt(), 2);
ProjectSettings *w = new ProjectSettings(project, project->metadata(), getMainTimeline()->controller()->extractCompositionLumas(), p.first, p.second, channels,
project->projectTempFolder(), true, !project->isModified(), this);
connect(w, &ProjectSettings::disableProxies, this, &MainWindow::slotDisableProxies);
// connect(w, SIGNAL(disablePreview()), pCore->projectManager()->currentTimeline(), SLOT(invalidateRange()));
......
......@@ -1141,6 +1141,7 @@ int GLWidget::reconfigure()
dropFrames = -dropFrames;
}
m_consumer->set("real_time", dropFrames);
m_consumer->set("channels", pCore->audioChannels());
if (KdenliveSettings::previewScaling() > 1) {
m_consumer->set("scale", 1.0 / KdenliveSettings::previewScaling());
}
......
......@@ -149,7 +149,7 @@ protected:
void mouseDoubleClickEvent(QMouseEvent *event) override;
void wheelEvent(QWheelEvent *event) override;
/** @brief Update producer, should ONLY be called from monitor */
int setProducer(const std::shared_ptr<Mlt::Producer> &producer, bool isActive, int position = -1);
int setProducer(const std::shared_ptr<Mlt::Producer> &producer, bool isActive, int position);
int setProducer(const QString &file);
QString frameToTime(int frames) const;
......
......@@ -1545,7 +1545,7 @@ void Monitor::slotOpenClip(const std::shared_ptr<ProjectClip> &controller, int i
// hasEffects = controller->hasEffects();
} else {
loadQmlScene(MonitorSceneDefault);
m_glMonitor->setProducer(nullptr, isActive());
m_glMonitor->setProducer(nullptr, isActive(), -1);
m_glMonitor->getControllerProxy()->setAudioThumb();
m_audioMeterWidget->audioChannels = 0;
m_glMonitor->getControllerProxy()->setClipProperties(-1, ClipType::Unknown, false, QString());
......@@ -2255,6 +2255,7 @@ void Monitor::requestSeek(int pos)
void Monitor::setProducer(std::shared_ptr<Mlt::Producer> producer, int pos)
{
m_audioMeterWidget->audioChannels = pCore->audioChannels();
m_glMonitor->setProducer(std::move(producer), isActive(), pos);
}
......
......@@ -159,6 +159,7 @@ public:
/** @brief Returns true if monitor is currently fullscreen */
bool monitorIsFullScreen() const;
void reloadActiveStream();
protected:
void mousePressEvent(QMouseEvent *event) override;
......
......@@ -644,4 +644,3 @@ void MonitorManager::updateBgColor()
m_clipMonitor->updateBgColor();
}
}
......@@ -63,8 +63,7 @@ public:
}
};
ProjectSettings::ProjectSettings(KdenliveDoc *doc, QMap<QString, QString> metadata, QStringList lumas, int videotracks, int audiotracks,
const QString & /*projectPath*/, bool readOnlyTracks, bool savedProject, QWidget *parent)
ProjectSettings::ProjectSettings(KdenliveDoc *doc, QMap<QString, QString> metadata, QStringList lumas, int videotracks, int audiotracks, int audiochannels, const QString & /*projectPath*/, bool readOnlyTracks, bool savedProject, QWidget *parent)
: QDialog(parent)
, m_savedProject(savedProject)
, m_lumas(std::move(lumas))
......@@ -88,6 +87,11 @@ ProjectSettings::ProjectSettings(KdenliveDoc *doc, QMap<QString, QString> metada
video_thumbs->setChecked(KdenliveSettings::videothumbnails());
audio_tracks->setValue(audiotracks);
video_tracks->setValue(videotracks);
if (audiochannels == 4) {
audio_channels->setCurrentIndex(1);
} else if (audiochannels == 6) {
audio_channels->setCurrentIndex(2);
}
connect(generate_proxy, &QAbstractButton::toggled, proxy_minsize, &QWidget::setEnabled);
connect(generate_imageproxy, &QAbstractButton::toggled, proxy_imageminsize, &QWidget::setEnabled);
connect(generate_imageproxy, &QAbstractButton::toggled, image_label, &QWidget::setEnabled);
......@@ -187,6 +191,7 @@ ProjectSettings::ProjectSettings(KdenliveDoc *doc, QMap<QString, QString> metada
if (readOnlyTracks) {
video_tracks->setEnabled(false);
audio_tracks->setEnabled(false);
audio_channels->setEnabled(false);
}
metadata_list->setItemDelegateForColumn(0, new NoEditDelegate(this));
......@@ -472,12 +477,21 @@ QUrl ProjectSettings::selectedFolder() const
return project_folder->url();
}
QPoint ProjectSettings::tracks() const
QPair<int, int> ProjectSettings::tracks() const
{
return {video_tracks->value(), audio_tracks->value()};
}
int ProjectSettings::audioChannels() const
{
QPoint p;
p.setX(video_tracks->value());
p.setY(audio_tracks->value());
return p;
switch (audio_channels->currentIndex()) {
case 1:
return 4;
case 2:
return 6;
default:
return 2;
}
}
bool ProjectSettings::enableVideoThumbs() const
......
......@@ -33,11 +33,12 @@ class ProjectSettings : public QDialog, public Ui::ProjectSettings_UI
Q_OBJECT
public:
ProjectSettings(KdenliveDoc *doc, QMap<QString, QString> metadata, QStringList lumas, int videotracks, int audiotracks, const QString &projectPath,
ProjectSettings(KdenliveDoc *doc, QMap<QString, QString> metadata, QStringList lumas, int videotracks, int audiotracks, int audiochannels, const QString &projectPath,
bool readOnlyTracks, bool unsavedProject, QWidget *parent = nullptr);
QString selectedProfile() const;
QUrl selectedFolder() const;
QPoint tracks() const;
QPair<int, int> tracks() const;
int audioChannels() const;
bool enableVideoThumbs() const;
bool enableAudioThumbs() const;
bool useProxy() const;
......
......@@ -143,7 +143,13 @@ void ProjectManager::newFile(QString profileName, bool showProjectSettings)
QString projectFolder;
QMap<QString, QString> documentProperties;
QMap<QString, QString> documentMetadata;
QPoint projectTracks(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks());
QPair<int, int> projectTracks{KdenliveSettings::videotracks(), KdenliveSettings::audiotracks()};
int audioChannels = 2;
if (KdenliveSettings::audio_channels() == 1) {
audioChannels = 4;
} else if (KdenliveSettings::audio_channels() == 2) {
audioChannels = 6;
}
pCore->monitorManager()->resetDisplay();
QString documentId = QString::number(QDateTime::currentMSecsSinceEpoch());
documentProperties.insert(QStringLiteral("documentid"), documentId);
......@@ -159,8 +165,7 @@ void ProjectManager::newFile(QString profileName, bool showProjectSettings)
documentProperties.insert(QStringLiteral("storagefolder"), projectFolder + documentId);
}
} else {
QPointer<ProjectSettings> w = new ProjectSettings(nullptr, QMap<QString, QString>(), QStringList(), projectTracks.x(), projectTracks.y(),
KdenliveSettings::defaultprojectfolder(), false, true, pCore->window());
QPointer<ProjectSettings> w = new ProjectSettings(nullptr, QMap<QString, QString>(), QStringList(), projectTracks.first, projectTracks.second, audioChannels, KdenliveSettings::defaultprojectfolder(), false, true, pCore->window());
connect(w.data(), &ProjectSettings::refreshProfiles, pCore->window(), &MainWindow::slotRefreshProfiles);
if (w->exec() != QDialog::Accepted) {
delete w;
......@@ -179,11 +184,13 @@ void ProjectManager::newFile(QString profileName, bool showProjectSettings)
profileName = w->selectedProfile();
projectFolder = w->storageFolder();
projectTracks = w->tracks();
audioChannels = w->audioChannels();
documentProperties.insert(QStringLiteral("enableproxy"), QString::number((int)w->useProxy()));
documentProperties.insert(QStringLiteral("generateproxy"), QString::number((int)w->generateProxy()));
documentProperties.insert(QStringLiteral("proxyminsize"), QString::number(w->proxyMinSize()));
documentProperties.insert(QStringLiteral("proxyparams"), w->proxyParams());
documentProperties.insert(QStringLiteral("proxyextension"), w->proxyExtension());
documentProperties.insert(QStringLiteral("audioChannels"), QString::number(w->audioChannels()));
documentProperties.insert(QStringLiteral("generateimageproxy"), QString::number((int)w->generateImageProxy()));
QString preview = w->selectedPreview();
if (!preview.isEmpty()) {
......@@ -203,8 +210,7 @@ void ProjectManager::newFile(QString profileName, bool showProjectSettings)
bool openBackup;
m_notesPlugin->clear();
documentProperties.insert(QStringLiteral("decimalPoint"), QLocale().decimalPoint());
KdenliveDoc *doc = new KdenliveDoc(QUrl(), projectFolder, pCore->window()->m_commandStack, profileName, documentProperties, documentMetadata, projectTracks,
&openBackup, pCore->window());
KdenliveDoc *doc = new KdenliveDoc(QUrl(), projectFolder, pCore->window()->m_commandStack, profileName, documentProperties, documentMetadata, projectTracks, audioChannels, &openBackup, pCore->window());
doc->m_autosave = new KAutoSaveFile(startFile, doc);
ThumbnailCache::get()->clearCache();
pCore->bin()->setDocument(doc);
......@@ -516,10 +522,16 @@ void ProjectManager::doOpenFile(const QUrl &url, KAutoSaveFile *stale)
m_progressDialog->show();
bool openBackup;
m_notesPlugin->clear();
int audioChannels = 2;
if (KdenliveSettings::audio_channels() == 1) {
audioChannels = 4;
} else if (KdenliveSettings::audio_channels() == 2) {
audioChannels = 6;
}
KdenliveDoc *doc = new KdenliveDoc(stale ? QUrl::fromLocalFile(stale->fileName()) : url, QString(), pCore->window()->m_commandStack,
KdenliveSettings::default_profile().isEmpty() ? pCore->getCurrentProfile()->path() : KdenliveSettings::default_profile(),
QMap<QString, QString>(), QMap<QString, QString>(),
QPoint(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks()), &openBackup, pCore->window());
{KdenliveSettings::videotracks(), KdenliveSettings::audiotracks()}, audioChannels, &openBackup, pCore->window());
if (stale == nullptr) {
const QString projectId = QCryptographicHash::hash(url.fileName().toUtf8(), QCryptographicHash::Md5).toHex();
QUrl autosaveUrl = QUrl::fromLocalFile(QFileInfo(url.path()).absoluteDir().absoluteFilePath(projectId + QStringLiteral(".kdenlive")));
......
......@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>486</width>
<height>310</height>
<width>579</width>
<height>250</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
......@@ -17,7 +17,20 @@
<property name="topMargin">
<number>0</number>
</property>
<item row="5" column="0" colspan="5">
<item row="0" column="0" colspan="7">
<widget class="QGroupBox" name="profile_box">
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QSpinBox" name="kcfg_audiotracks"/>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="kcfg_videotracks"/>
</item>
<item row="5" column="0" colspan="7">
<widget class="QPlainTextEdit" name="previewparams">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
......@@ -30,27 +43,14 @@
</property>
</widget>
</item>
<item row="1" column="4">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>58</width>
<height>22</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" colspan="5">
<widget class="QGroupBox" name="profile_box">
<property name="flat">
<bool>true</bool>
<item row="1" column="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Audio tracks</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="5">
<item row="3" column="0" colspan="7">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="kcfg_customprojectfolder">
......@@ -60,7 +60,7 @@
</widget>
</item>
<item>
<widget class="KUrlRequester" name="projecturl">
<widget class="KUrlRequester" name="projecturl" native="true">
<property name="enabled">
<bool>false</bool>
</property>
......@@ -68,13 +68,7 @@
</item>
</layout>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="kcfg_videotracks"/>
</item>
<item row="1" column="3">
<widget class="QSpinBox" name="kcfg_audiotracks"/>
</item>
<item row="4" column="0" colspan="5">
<item row="4" column="0" colspan="7">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_25">
......@@ -118,13 +112,6 @@
</item>
</layout>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Audio tracks</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
......@@ -145,6 +132,38 @@
</property>
</spacer>
</item>
<item row="1" column="4">
<widget class="QLabel" name="label">
<property name="text">
<string>Audio channels</string>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QComboBox" name="kcfg_audio_channels">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>2 channels (stereo)</string>
</property>
</item>
<item>
<property name="text">
<string>4 channels</string>
</property>
</item>
<item>
<property name="text">
<string>6 channels</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
<customwidgets>
......
......@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>733</width>
<height>571</height>
<height>511</height>
</rect>
</property>
<property name="windowTitle">
......@@ -51,7 +51,7 @@
</widget>
</item>
<item>
<widget class="KUrlRequester" name="project_folder">
<widget class="KUrlRequester" name="project_folder" native="true">
<property name="enabled">
<bool>false</bool>
</property>
......@@ -95,17 +95,36 @@
<widget class="QSpinBox" name="audio_tracks"/>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<widget class="QLabel" name="label">
<property name="text">
<string>Audio channels</string>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>67</width>
<height>20</height>
</size>
</widget>
</item>
<item>
<widget class="QComboBox" name="audio_channels">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</spacer>
<item>
<property name="text">
<string>2 channels (stereo)</string>
</property>
</item>
<item>
<property name="text">
<string>4 channels</string>
</property>
</item>
<item>
<property name="text">
<string>6 channels</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
......
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