WIP miniaudio working, some sigsev while playing...
This commit is contained in:
parent
78695b7976
commit
7aea8f6cf1
23 changed files with 469 additions and 299 deletions
|
@ -1,18 +1,14 @@
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
Libre Media Server Audio - An Open source Media Server for arts and performing.
|
Libre Media Server Audio - An Open source Media Server for arts and performing.
|
||||||
(c) Santiago Noreña 2012-2024 <lms@criptomart.net>
|
(c) Criptomart - Santiago Noreña 2012-2024 <lms@criptomart.net>
|
||||||
Code: https://git.criptomart.net/libremediaserver
|
https://git.criptomart.net/libremediaserver
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
|
|
||||||
Lbre Media Server ChangeLog
|
Lbre Media Server ChangeLog
|
||||||
|
|
||||||
v 0.1.3 (28/05/2024)
|
v 1.4
|
||||||
|
- change engine to miniaudio.
|
||||||
+ Ubuntu 22.04 jammy.
|
- Select sound device output.
|
||||||
+ Use SFML as audio engine.
|
|
||||||
+ Qt 5.15.3.
|
|
||||||
+ pitch.
|
|
||||||
+ loop.
|
|
||||||
- pan.
|
- pan.
|
||||||
- Show faders values.
|
- Show faders values.
|
||||||
--> Hacer UI por fader: mute/centrado, valor, visualizador:
|
--> Hacer UI por fader: mute/centrado, valor, visualizador:
|
||||||
|
@ -20,6 +16,14 @@ v 0.1.3 (28/05/2024)
|
||||||
- SettingsDialog.
|
- SettingsDialog.
|
||||||
- Load/save conf file.
|
- Load/save conf file.
|
||||||
|
|
||||||
|
v 0.1.3 (19/04/2024)
|
||||||
|
|
||||||
|
+ Ubuntu 22.04 jammy.
|
||||||
|
+ Use SFML as audio engine.
|
||||||
|
+ Qt 5.15.3.
|
||||||
|
+ pitch.
|
||||||
|
+ loop.
|
||||||
|
|
||||||
v 0.1.2 (12/08/2015)
|
v 0.1.2 (12/08/2015)
|
||||||
|
|
||||||
- GUI config
|
- GUI config
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
Libre Media Server Audio - An Open source Media Server.
|
Libre Media Server Audio - An Open source Media Server for arts and performing.
|
||||||
(c) Santiago Noreña 2014-2024 <libremediaserver@criptomart.net>
|
(c) Criptomart - Santiago Noreña 2012-2024 <lms@criptomart.net>
|
||||||
https://git.criptomart.net/libremediaserver
|
https://git.criptomart.net/libremediaserver
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
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 3 of the License, or (at your option) any later version.
|
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 3 of the License, or (at your option) any later version.
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<dmxSettings fileVersion="1" layersNumber="4" path="/path/to/medias" universeNumber="1">
|
<dmxSettings fileVersion="1" layersNumber="4" path="/home/snt/Documentos/lab/lms/media/sound" universeNumber="1">
|
||||||
|
<audioDevice id="3" />
|
||||||
<layer0 dmx="1" universe="1" />
|
<layer0 dmx="1" universe="1" />
|
||||||
<layer1 dmx="17" universe="1" />
|
<layer1 dmx="17" universe="1" />
|
||||||
<layer2 dmx="33" universe="1" />
|
<layer2 dmx="33" universe="1" />
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
Libre Media Server Audio - An Open source Media Server for arts and performing.
|
Libre Media Server Audio - An Open source Media Server for arts and performing.
|
||||||
(c) Santiago Noreña 2012-2024 <lms@criptomart.net>
|
(c) Criptomart - Santiago Noreña 2012-2024 <lms@criptomart.net>
|
||||||
Code: https://git.criptomart.net/libremediaserver
|
https://git.criptomart.net/libremediaserver
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
|
|
||||||
Libre Media Server Roadmap
|
Libre Media Server Roadmap
|
||||||
(or a whislist...)
|
(en continuo crecimiento...)
|
||||||
|
|
||||||
v 0.2.1
|
v 0.2.x
|
||||||
- skin, UI/UX
|
- skin, UI/UX
|
||||||
- live input.
|
- live input.
|
||||||
|
- insertar/bypass/eliminar audio procesadores sin reiniciar por capa y master. (compresor, equs).
|
||||||
|
- FX en capas master para que se puedan usar como envíos de auxiliar.
|
||||||
|
- Enroutado de masters en otros masters (retorno de efectos).
|
||||||
|
|
||||||
v 0.2.0
|
v 0.2.0
|
||||||
- Use sACN directly.
|
- Use sACN directly.
|
||||||
|
@ -17,15 +20,13 @@ v 0.2.0
|
||||||
+ hay que empaquetar OLA, incluirlo en el binario, o implementar sACN y linkarlo estáticamente.
|
+ hay que empaquetar OLA, incluirlo en el binario, o implementar sACN y linkarlo estáticamente.
|
||||||
+ https://github.com/ETCLabs/sACN
|
+ https://github.com/ETCLabs/sACN
|
||||||
- Qt6.
|
- Qt6.
|
||||||
- audio processing (eq, rev, compresor, ...).
|
- audio processing (eq, rev, compresor, ...) por master y capa.
|
||||||
- CIPT/MSex, send icons play-pause-stop.
|
- CIPT/MSex, send icons play-pause-stop.
|
||||||
- Rasp build.
|
- Rasp build.
|
||||||
- Octopus Sound Card support (6 outputs - 8 inputs).
|
- Octopus Sound Card support (6 outputs - 8 inputs).
|
||||||
|
|
||||||
v 1.5
|
v 1.5
|
||||||
- Select sound device output.
|
- Multi devices output.
|
||||||
- Multi device output, router layers to devices and audio outputs.
|
|
||||||
- Jack/pipewire integration?
|
|
||||||
- Rose noise and sine generator in menu to test system.
|
- Rose noise and sine generator in menu to test system.
|
||||||
- Play Mode:
|
- Play Mode:
|
||||||
- Play all medias found in folder consecutevily or random, with loop.
|
- Play all medias found in folder consecutevily or random, with loop.
|
||||||
|
@ -34,18 +35,19 @@ v 1.5
|
||||||
- loop points.
|
- loop points.
|
||||||
- play offset. ¿stop offset?
|
- play offset. ¿stop offset?
|
||||||
- number of layers configured in conf file, up to 256.
|
- number of layers configured in conf file, up to 256.
|
||||||
- Dar la opción clickeando en el widget de tiempo de poner una cuenta atrás en vez de hacia delante.
|
- Master Bus Layer:
|
||||||
- Master Layer:
|
- each layer will have one "Gain" prefader that acts in source, "Vol" in v 1.3.
|
||||||
- Mute.
|
- each layer will have one volume dmx channel for each bus layer. One aux "Send" prefader.
|
||||||
- Pan.
|
- mute/panic.
|
||||||
|
- fader + value
|
||||||
|
- pan.
|
||||||
|
- magicq .hed
|
||||||
|
- audio device linked, outputs will be redirected there.
|
||||||
|
- dmx address + universe settings.
|
||||||
- Keyboards strokes, select files from ui.
|
- Keyboards strokes, select files from ui.
|
||||||
|
- Dar la opción clickeando en el widget de tiempo de poner una cuenta atrás en vez de hacia delante.
|
||||||
- LOGs y entrada de comandos.
|
- LOGs y entrada de comandos.
|
||||||
- Bufgix: depurar errores cuando no carga la librería de medias, cambia el númmero de capas, cambia el universo, etc.
|
- Bufgix: depurar errores cuando no carga la librería de medias, cambia el númmero de capas, cambia el universo, etc.
|
||||||
|
- Refactor AudioMasterWidget to AudioDMXReceptionWidget. Master functions will be in AudioWidget.
|
||||||
v 1.4
|
- New control mode without pitch control, it saves resources. MA_SOUND_FLAG_NO_PITCH
|
||||||
- pan.
|
- Vumeter or indicator about audio output in layer and master.
|
||||||
- Show faders values.
|
|
||||||
--> Hacer UI por fader: mute/centrado, valor, visualizador:
|
|
||||||
--> Hacer UI con la visualización de tiempos.
|
|
||||||
- SettingsDialog.
|
|
||||||
- Load/save conf file.
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ TEMPLATE = app
|
||||||
TARGET = libremediaserver-audio
|
TARGET = libremediaserver-audio
|
||||||
QT += webkitwidgets widgets
|
QT += webkitwidgets widgets
|
||||||
HEADERS += src/libremediaserver-audio.h \
|
HEADERS += src/libremediaserver-audio.h \
|
||||||
|
src/miniaudio.h \
|
||||||
src/medialibrary.h \
|
src/medialibrary.h \
|
||||||
src/olathread.h \
|
src/olathread.h \
|
||||||
src/audiolayerwidget.h \
|
src/audiolayerwidget.h \
|
||||||
|
@ -13,6 +14,7 @@ HEADERS += src/libremediaserver-audio.h \
|
||||||
src/settingsdialog.h \
|
src/settingsdialog.h \
|
||||||
src/layersettingswidget.h
|
src/layersettingswidget.h
|
||||||
SOURCES += src/main.cpp \
|
SOURCES += src/main.cpp \
|
||||||
|
src/miniaudio.c \
|
||||||
src/libremediaserver-audio.cpp \
|
src/libremediaserver-audio.cpp \
|
||||||
src/medialibrary.cpp \
|
src/medialibrary.cpp \
|
||||||
src/olathread.cpp \
|
src/olathread.cpp \
|
||||||
|
@ -25,12 +27,13 @@ SOURCES += src/main.cpp \
|
||||||
FORMS += src/libremediaserver-audio.ui \
|
FORMS += src/libremediaserver-audio.ui \
|
||||||
src/settingsdialog.ui \
|
src/settingsdialog.ui \
|
||||||
src/layersettingswidget.ui
|
src/layersettingswidget.ui
|
||||||
LIBS += -lola -lolacommon
|
CCFLAG += -msse2 -mavx2 #-fsanitize=address -g -O0
|
||||||
|
QMAKE_CXXFLAGS += $$(CXXFLAG)
|
||||||
|
#QMAKE_CXXFLAGS += -fsanitize=address -g -O0
|
||||||
|
QMAKE_CFLAGS += $$(CCFLAG)
|
||||||
|
QMAKE_LFLAGS += $$(LDFLAG)
|
||||||
|
LIBS += -lola -lolacommon -ldl -lpthread -lm
|
||||||
# -lcitp
|
# -lcitp
|
||||||
LIBS += -L$$PWD/SFML/lib/ -lsfml-audio -lsfml-system
|
|
||||||
INCLUDEPATH += $$PWD/SFML/include
|
|
||||||
DEPENDPATH += $$PWD/SFML/include
|
|
||||||
PRE_TARGETDEPS += $$PWD/SFML/lib/libsfml-audio.so $$PWD/SFML/lib/libsfml-system.so
|
|
||||||
OTHER_FILES += \
|
OTHER_FILES += \
|
||||||
LICENSE.txt \
|
LICENSE.txt \
|
||||||
docs/compiling.txt \
|
docs/compiling.txt \
|
||||||
|
|
|
@ -1,31 +1,20 @@
|
||||||
#include "audiolayerwidget.h"
|
#include "audiolayerwidget.h"
|
||||||
|
|
||||||
#include<iostream>
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QTime>
|
|
||||||
|
|
||||||
AudioLayerWidget::AudioLayerWidget(QWidget *parent, QString name):
|
AudioLayerWidget::AudioLayerWidget(QWidget *parent, QString name):
|
||||||
QGroupBox(parent)
|
QGroupBox(parent)
|
||||||
, m_suspendResumeButton(0)
|
, m_suspendResumeButton(0)
|
||||||
, m_watchDMX(new QTimer(this))
|
, m_refreshGUI(new QTimer(this))
|
||||||
, m_currentMedia(" ")
|
, m_currentMedia("")
|
||||||
, m_running(false)
|
, m_mediaLoaded(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
this->setTitle(name);
|
this->setTitle(name);
|
||||||
|
|
||||||
QVBoxLayout *layout = new QVBoxLayout;
|
QVBoxLayout *layout = new QVBoxLayout;
|
||||||
|
|
||||||
QHBoxLayout *status = new QHBoxLayout;
|
QHBoxLayout *status = new QHBoxLayout;
|
||||||
m_statusLabel = new QLabel;
|
m_statusLabel = new QLabel;
|
||||||
m_statusLabel->setText(STATUS_LABEL);
|
m_statusLabel->setText(STATUS_LABEL);
|
||||||
m_statusValue = new QLabel;
|
m_statusValue = new QLabel;
|
||||||
// m_receiveDMX = new QCheckBox("Receiving DMX", this);
|
|
||||||
// m_receiveDMX->setChecked(false);
|
|
||||||
// status->addWidget(m_receiveDMX);
|
|
||||||
status->addWidget(m_statusLabel);
|
status->addWidget(m_statusLabel);
|
||||||
status->addWidget(m_statusValue);
|
status->addWidget(m_statusValue);
|
||||||
m_loopCheck = new QCheckBox();
|
m_loopCheck = new QCheckBox();
|
||||||
|
@ -58,8 +47,8 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, QString name):
|
||||||
m_volumeLabel = new QLabel;
|
m_volumeLabel = new QLabel;
|
||||||
m_volumeLabel->setText(tr(VOLUME_LABEL));
|
m_volumeLabel->setText(tr(VOLUME_LABEL));
|
||||||
m_volumeSlider = new QSlider(Qt::Horizontal);
|
m_volumeSlider = new QSlider(Qt::Horizontal);
|
||||||
m_volumeSlider->setMinimum(0);
|
m_volumeSlider->setMinimum(-100);
|
||||||
m_volumeSlider->setMaximum(90);
|
m_volumeSlider->setMaximum(100);
|
||||||
m_volumeSlider->setSingleStep(1);
|
m_volumeSlider->setSingleStep(1);
|
||||||
m_volumeIndicator = new QLabel;
|
m_volumeIndicator = new QLabel;
|
||||||
volumeBox->addWidget(m_volumeLabel, 0, 0);
|
volumeBox->addWidget(m_volumeLabel, 0, 0);
|
||||||
|
@ -111,13 +100,8 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, QString name):
|
||||||
progressTime->addWidget(m_totalTimeValue);
|
progressTime->addWidget(m_totalTimeValue);
|
||||||
layout->addLayout(progressTime);
|
layout->addLayout(progressTime);
|
||||||
|
|
||||||
QHBoxLayout *progressSlider = new QHBoxLayout;
|
|
||||||
m_progressLabel = new QLabel;
|
|
||||||
m_progressLabel->setText(PROGRESS_LABEL);
|
|
||||||
m_progressSlider = new QSlider(Qt::Horizontal);
|
m_progressSlider = new QSlider(Qt::Horizontal);
|
||||||
progressSlider->addWidget(m_progressLabel);
|
layout->addWidget(m_progressSlider);
|
||||||
progressSlider->addWidget(m_progressSlider);
|
|
||||||
layout->addLayout(progressSlider);
|
|
||||||
|
|
||||||
m_suspendResumeButton = new QPushButton(this);
|
m_suspendResumeButton = new QPushButton(this);
|
||||||
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
|
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
|
||||||
|
@ -125,12 +109,8 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, QString name):
|
||||||
layout->addWidget(m_suspendResumeButton);
|
layout->addWidget(m_suspendResumeButton);
|
||||||
|
|
||||||
this->setLayout(layout);
|
this->setLayout(layout);
|
||||||
|
connect(m_refreshGUI, SIGNAL(timeout()), this, SLOT(refreshGUI()));
|
||||||
connect(m_watchDMX, SIGNAL(timeout()),
|
m_refreshGUI->start(100);
|
||||||
this, SLOT(refreshGUI()));
|
|
||||||
m_watchDMX->start(100);
|
|
||||||
|
|
||||||
m_music.setAttenuation(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioLayerWidget::~AudioLayerWidget()
|
AudioLayerWidget::~AudioLayerWidget()
|
||||||
|
@ -140,36 +120,42 @@ AudioLayerWidget::~AudioLayerWidget()
|
||||||
|
|
||||||
void AudioLayerWidget::volumeChanged(int value)
|
void AudioLayerWidget::volumeChanged(int value)
|
||||||
{
|
{
|
||||||
m_music.setVolume(value);
|
float result;
|
||||||
|
|
||||||
|
if (m_mediaLoaded == false)
|
||||||
|
return;
|
||||||
|
result = ma_volume_linear_to_db(value);
|
||||||
|
ma_sound_group_set_volume(¤tSound, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::panChanged(int value)
|
void AudioLayerWidget::panChanged(int value)
|
||||||
{
|
{
|
||||||
m_music.setRelativeToListener(true);
|
float result;
|
||||||
sf::Vector3f pos = m_music.getPosition();
|
if (m_mediaLoaded == false)
|
||||||
//m_music.setSpati(0, 0, 0);
|
return;
|
||||||
qreal pan = (value - 128) / 64.0f;
|
result = (value / 128.0) - 128;
|
||||||
qWarning("change pan %f", pan);
|
ma_sound_group_set_pan(¤tSound, result);
|
||||||
//m_music.setPosition(pan, 0.0, sqrtf(1.0 + pan*pan));
|
|
||||||
m_music.setPosition(pan, 0.0f, -1.0f);
|
|
||||||
//pos = m_music.getPosition();
|
|
||||||
qWarning("%f %f %f", pos.x, pos.y, pos.z);
|
|
||||||
qWarning("is rel %i", m_music.isRelativeToListener());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::pitchChanged(int value)
|
void AudioLayerWidget::pitchChanged(int value)
|
||||||
{
|
{
|
||||||
m_music.setPitch(qreal(value / 128.0 ));
|
float result;
|
||||||
|
if (m_mediaLoaded == false)
|
||||||
|
return;
|
||||||
|
result = (value / 128.0) - 128;
|
||||||
|
ma_sound_group_set_pitch(¤tSound, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::loopChanged(int value)
|
void AudioLayerWidget::loopChanged(int value)
|
||||||
{
|
{
|
||||||
m_music.setLoop(value);
|
if (m_mediaLoaded == false)
|
||||||
|
return;
|
||||||
|
ma_sound_set_looping(¤tSound, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::setVol(qreal vol)
|
void AudioLayerWidget::setVol(qreal vol)
|
||||||
{
|
{
|
||||||
m_music.setVolume(vol);
|
this->volumeChanged(vol);
|
||||||
m_volumeSlider->blockSignals(true);
|
m_volumeSlider->blockSignals(true);
|
||||||
m_volumeSlider->setValue(vol);
|
m_volumeSlider->setValue(vol);
|
||||||
m_volumeIndicator->setText(QString::number(vol));
|
m_volumeIndicator->setText(QString::number(vol));
|
||||||
|
@ -186,7 +172,7 @@ void AudioLayerWidget::setPan(qreal pan)
|
||||||
|
|
||||||
void AudioLayerWidget::setPitch(qreal pitch)
|
void AudioLayerWidget::setPitch(qreal pitch)
|
||||||
{
|
{
|
||||||
m_music.setPitch(float(pitch / 128 ));
|
this->pitchChanged(pitch);
|
||||||
m_pitchSlider->blockSignals(true);
|
m_pitchSlider->blockSignals(true);
|
||||||
m_pitchSlider->setValue(pitch);
|
m_pitchSlider->setValue(pitch);
|
||||||
m_pitchSlider->blockSignals(false);
|
m_pitchSlider->blockSignals(false);
|
||||||
|
@ -194,6 +180,12 @@ void AudioLayerWidget::setPitch(qreal pitch)
|
||||||
|
|
||||||
void AudioLayerWidget::loadMedia(QString file)
|
void AudioLayerWidget::loadMedia(QString file)
|
||||||
{
|
{
|
||||||
|
ma_result result;
|
||||||
|
ma_format *format = 0;
|
||||||
|
ma_uint32 *channels = 0;
|
||||||
|
ma_uint32 *sampleRate = 0;
|
||||||
|
|
||||||
|
|
||||||
if (m_currentMedia.compare(file) == 0 ) {
|
if (m_currentMedia.compare(file) == 0 ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -201,21 +193,46 @@ void AudioLayerWidget::loadMedia(QString file)
|
||||||
qWarning("Can not access to file %s", file.toLatin1().constData());
|
qWarning("Can not access to file %s", file.toLatin1().constData());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Load an ogg music file
|
ma_engine engine = AudioWidget::getInstance()->getEngine();
|
||||||
if (!m_music.openFromFile(file.toStdString())) {
|
if (currentSound.ownsDataSource == true)
|
||||||
qWarning("Can not open file %s", file.toLatin1().constData());
|
{
|
||||||
|
ma_sound_uninit(¤tSound);
|
||||||
|
}
|
||||||
|
result = ma_sound_init_from_file(&engine, file.toLatin1(), MA_SOUND_FLAG_NO_SPATIALIZATION | MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_DECODE | MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC | MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM, NULL, NULL, ¤tSound);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
qWarning("WARNING: Failed to load sound %s", file.toLatin1().constData());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_currentMedia = file;
|
m_currentMedia = file;
|
||||||
durationChanged(m_music.getDuration().asMilliseconds());
|
float pLength = this->getDuration();
|
||||||
|
result = ma_sound_get_data_format(¤tSound, format, channels, sampleRate, NULL, 0);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
qWarning("WARNING: Failed to get data format %s", file.toLatin1().constData());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_mediaLoaded = true;
|
||||||
|
durationChanged(pLength * 1000);
|
||||||
fileLoaded(file);
|
fileLoaded(file);
|
||||||
|
|
||||||
// Display music informations
|
// Display music informations
|
||||||
std::cout << "File loaded: " << file.toLatin1().constData() << " : " << std::endl;
|
std::cout << "File loaded: " << file.toLatin1().constData() << " : " << std::endl;
|
||||||
std::cout << " " << m_music.getDuration().asSeconds() << " seconds";
|
std::cout << " " << pLength << " seconds";
|
||||||
std::cout << " " << m_music.getSampleRate() << " samples / sec";
|
std::cout << " -- " << sampleRate << " samples/sec";
|
||||||
std::cout << " " << m_music.getChannelCount() << " channels" << std::endl;
|
std::cout << " -- " << format << " format";
|
||||||
|
std::cout << " -- " << channels << " channels" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AudioLayerWidget::getDuration()
|
||||||
|
{
|
||||||
|
float pLength;
|
||||||
|
|
||||||
|
if (m_mediaLoaded == false)
|
||||||
|
return 0;
|
||||||
|
ma_result result = ma_sound_get_length_in_seconds(¤tSound, &pLength);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
qWarning("WARNING: Failed to get total duration %s", m_currentMedia.toLatin1().constData());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return pLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::fileLoaded(QString file)
|
void AudioLayerWidget::fileLoaded(QString file)
|
||||||
|
@ -236,56 +253,66 @@ void AudioLayerWidget::durationChanged(qint64 dur)
|
||||||
|
|
||||||
void AudioLayerWidget::play(bool loop)
|
void AudioLayerWidget::play(bool loop)
|
||||||
{
|
{
|
||||||
m_music.play();
|
if (m_mediaLoaded == false)
|
||||||
m_music.setLoop(loop);
|
return;
|
||||||
|
ma_sound_set_looping(¤tSound, loop);
|
||||||
|
ma_sound_start(¤tSound);
|
||||||
m_loopCheck->blockSignals(true);
|
m_loopCheck->blockSignals(true);
|
||||||
m_loopCheck->setChecked(m_music.getLoop());
|
m_loopCheck->setChecked(loop);
|
||||||
m_loopCheck->blockSignals(false);
|
m_loopCheck->blockSignals(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::pause()
|
void AudioLayerWidget::pause()
|
||||||
{
|
{
|
||||||
m_music.pause();
|
if (m_mediaLoaded == false)
|
||||||
|
return;
|
||||||
|
ma_sound_stop(¤tSound);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::stop()
|
void AudioLayerWidget::stop()
|
||||||
{
|
{
|
||||||
m_music.stop();
|
if (m_mediaLoaded == false)
|
||||||
|
return;
|
||||||
|
ma_sound_stop(¤tSound);
|
||||||
|
ma_sound_seek_to_pcm_frame(¤tSound, 0);
|
||||||
|
m_progressTime->setTime(QTime::fromMSecsSinceStartOfDay(0));
|
||||||
|
m_statusValue->setText(STOP_LABEL);
|
||||||
|
m_suspendResumeButton->setText(tr(STOP_LABEL));
|
||||||
|
m_progressSlider->setValue(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::refreshGUI() {
|
void AudioLayerWidget::refreshGUI() {
|
||||||
// m_receiveDMX->setChecked(false);
|
float progress;
|
||||||
int progress;
|
|
||||||
switch (m_music.getStatus()) {
|
if (m_mediaLoaded == false)
|
||||||
case sf::SoundSource::Playing:
|
return;
|
||||||
progress = m_music.getPlayingOffset().asMilliseconds();
|
if (currentSound.ownsDataSource == 0)
|
||||||
|
return;
|
||||||
|
switch (ma_sound_is_playing(¤tSound)) {
|
||||||
|
case true:
|
||||||
|
ma_sound_get_cursor_in_seconds(¤tSound, &progress);
|
||||||
|
progress *= 1000;
|
||||||
m_progressSlider->setValue(progress);
|
m_progressSlider->setValue(progress);
|
||||||
m_progressTime->setTime(QTime::fromMSecsSinceStartOfDay(progress));
|
m_progressTime->setTime(QTime::fromMSecsSinceStartOfDay(progress));
|
||||||
m_statusValue->setText(PLAY_LABEL);
|
m_statusValue->setText(PLAY_LABEL);
|
||||||
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
|
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
|
||||||
break;
|
break;
|
||||||
case sf::SoundSource::Paused:
|
case false:
|
||||||
m_statusValue->setText(PAUSE_LABEL);
|
m_statusValue->setText(PAUSE_LABEL);
|
||||||
m_suspendResumeButton->setText(tr(RESUME_LABEL));
|
m_suspendResumeButton->setText(tr(RESUME_LABEL));
|
||||||
break;
|
break;
|
||||||
case sf::SoundSource::Stopped:
|
|
||||||
m_progressTime->setTime(QTime::fromMSecsSinceStartOfDay(0));
|
|
||||||
m_statusValue->setText(STOP_LABEL);
|
|
||||||
m_suspendResumeButton->setText(tr(RESUME_LABEL));
|
|
||||||
m_progressSlider->setValue(0);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
//m_loopCheck->blockSignals(true);
|
|
||||||
//m_loopCheck->setChecked(m_music.getLoop());
|
|
||||||
//m_loopCheck->blockSignals(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::toggleSuspendResume()
|
void AudioLayerWidget::toggleSuspendResume()
|
||||||
{
|
{
|
||||||
if (m_music.getStatus() == sf::SoundSource::Playing) {
|
if (m_mediaLoaded == false)
|
||||||
m_music.pause();
|
return;
|
||||||
|
if (ma_sound_is_playing(¤tSound)) {
|
||||||
|
this->pause();
|
||||||
} else {
|
} else {
|
||||||
m_music.play();
|
if (ma_sound_at_end(¤tSound))
|
||||||
|
ma_sound_seek_to_pcm_frame(¤tSound, 0);
|
||||||
|
ma_sound_start(¤tSound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
#ifndef AUDIOLAYERWIDGET_H
|
#ifndef AUDIOLAYERWIDGET_H
|
||||||
#define AUDIOLAYERWIDGET_H
|
#define AUDIOLAYERWIDGET_H
|
||||||
|
|
||||||
#include <cmath>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QTime>
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QHBoxLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QTime>
|
|
||||||
#include <QTimeEdit>
|
#include <QTimeEdit>
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
|
|
||||||
#include <SFML/Audio.hpp>
|
|
||||||
#include <SFML/System.hpp>
|
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
#include "audiowidget.h"
|
||||||
|
#include "miniaudio.h"
|
||||||
|
|
||||||
class AudioLayerWidget : public QGroupBox
|
class AudioLayerWidget : public QGroupBox
|
||||||
{
|
{
|
||||||
|
@ -32,20 +35,8 @@ public:
|
||||||
* @param file name with full path
|
* @param file name with full path
|
||||||
*/
|
*/
|
||||||
void loadMedia(QString file);
|
void loadMedia(QString file);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief play
|
|
||||||
*/
|
|
||||||
void play(bool loop);
|
void play(bool loop);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief stop
|
|
||||||
*/
|
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief pause
|
|
||||||
*/
|
|
||||||
void pause();
|
void pause();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,20 +44,11 @@ public:
|
||||||
* @param vol volume range 0 -100
|
* @param vol volume range 0 -100
|
||||||
*/
|
*/
|
||||||
void setVol(qreal vol);
|
void setVol(qreal vol);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief resume
|
|
||||||
*/
|
|
||||||
void resume();
|
void resume();
|
||||||
|
|
||||||
void setPan(qreal pan);
|
void setPan(qreal pan);
|
||||||
|
|
||||||
void setPitch(qreal pitch);
|
void setPitch(qreal pitch);
|
||||||
|
|
||||||
void setLoop(bool on);
|
void setLoop(bool on);
|
||||||
|
|
||||||
//void setEntryPoint(qreal entry);
|
//void setEntryPoint(qreal entry);
|
||||||
|
|
||||||
//void setEndPoint(qreal end);
|
//void setEndPoint(qreal end);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -120,14 +102,12 @@ private:
|
||||||
QLabel * m_folderLabel;
|
QLabel * m_folderLabel;
|
||||||
QLabel * m_folderValue;
|
QLabel * m_folderValue;
|
||||||
|
|
||||||
//QCheckBox *m_receiveDMX;
|
QTimer *m_refreshGUI;
|
||||||
QTimer *m_watchDMX;
|
|
||||||
|
|
||||||
QString m_currentMedia;
|
QString m_currentMedia;
|
||||||
|
ma_sound currentSound;
|
||||||
|
ma_bool8 m_mediaLoaded;
|
||||||
|
|
||||||
bool m_running;
|
float getDuration();
|
||||||
|
|
||||||
sf::Music m_music;
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,12 @@
|
||||||
#include "audiomasterwidget.h"
|
#include "audiomasterwidget.h"
|
||||||
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
|
|
||||||
AudioMasterWidget::AudioMasterWidget(QWidget *parent) :
|
AudioMasterWidget::AudioMasterWidget(QWidget *parent) :
|
||||||
QGroupBox(parent)
|
QGroupBox(parent)
|
||||||
//, m_file(new QLabel)
|
|
||||||
//, m_folder(new QLabel)
|
|
||||||
//, m_vol(new QSlider)
|
|
||||||
//, m_mute(new QCheckBox)
|
|
||||||
//, m_status(new QLabel)
|
|
||||||
, m_receiveDMX(new QCheckBox)
|
, m_receiveDMX(new QCheckBox)
|
||||||
, m_watchDMX(new QTimer)
|
, m_watchDMX(new QTimer)
|
||||||
{
|
{
|
||||||
QVBoxLayout *vbox = new QVBoxLayout;
|
QVBoxLayout *vbox = new QVBoxLayout;
|
||||||
//vbox->addWidget(m_status);
|
m_receiveDMX->setText("DMX signal");
|
||||||
//vbox->addWidget(m_vol);
|
|
||||||
//vbox->addWidget(m_mute);
|
|
||||||
m_receiveDMX->setText("Receiving DMX");
|
|
||||||
vbox->addWidget(m_receiveDMX);
|
vbox->addWidget(m_receiveDMX);
|
||||||
this->setLayout(vbox);
|
this->setLayout(vbox);
|
||||||
connect(m_watchDMX, SIGNAL(timeout()),
|
connect(m_watchDMX, SIGNAL(timeout()),
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
//#include "ui_audiomasterwidget.h"
|
//#include "ui_audiomasterwidget.h"
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "audiowidget.h"
|
#include "audiowidget.h"
|
||||||
|
#include "miniaudio.c"
|
||||||
|
|
||||||
AudioWidget *AudioWidget::_instance = 0;
|
AudioWidget *AudioWidget::_instance = 0;
|
||||||
|
|
||||||
|
@ -11,30 +12,117 @@ AudioWidget *AudioWidget::getInstance() {
|
||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioWidget::AudioWidget()
|
AudioWidget::AudioWidget() :
|
||||||
|
engineCount(0)
|
||||||
{
|
{
|
||||||
|
this->startEngine();
|
||||||
layout = new QHBoxLayout();
|
layout = new QHBoxLayout();
|
||||||
for (int i= 0; i < Settings::getInstance()->getLayersNumber(); i++ ) {
|
for (int i= 0; i < Settings::getInstance()->getLayersNumber(); i++ ) {
|
||||||
layout->insertWidget(i, new AudioLayerWidget(this, tr("Layer %1").arg(i)));
|
layout->insertWidget(i, new AudioLayerWidget(this, tr("Layer %1").arg(i + 1)));
|
||||||
}
|
}
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
// qDebug( "Init AudioWidget");
|
}
|
||||||
|
|
||||||
|
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
|
||||||
|
{
|
||||||
|
(void)pInput;
|
||||||
|
//Do master audio processing before sending to device.
|
||||||
|
ma_engine_read_pcm_frames((ma_engine*)pDevice->pUserData, pOutput, frameCount, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioWidget::startEngine(int n)
|
||||||
|
{
|
||||||
|
this->startContext();
|
||||||
|
this->startDevice(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioWidget::startDevice(int id)
|
||||||
|
{
|
||||||
|
ma_result result;
|
||||||
|
ma_device_config deviceConfig;
|
||||||
|
ma_engine_config engineConfig;
|
||||||
|
|
||||||
|
deviceConfig = ma_device_config_init(ma_device_type_playback);
|
||||||
|
deviceConfig.playback.pDeviceID = &pPlaybackDeviceInfos[id].id;
|
||||||
|
deviceConfig.playback.format = resourceManager.config.decodedFormat;
|
||||||
|
deviceConfig.playback.channels = 0;
|
||||||
|
deviceConfig.sampleRate = resourceManager.config.decodedSampleRate;
|
||||||
|
deviceConfig.dataCallback = data_callback;
|
||||||
|
deviceConfig.pUserData = &engines[engineCount];
|
||||||
|
result = ma_device_init(&context, &deviceConfig, &devices[engineCount]);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
qCritical("Failed to initialize audio device %s.", pPlaybackDeviceInfos[id].name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
engineConfig = ma_engine_config_init();
|
||||||
|
engineConfig.pDevice = &devices[engineCount];
|
||||||
|
engineConfig.pResourceManager = &resourceManager;
|
||||||
|
engineConfig.noAutoStart = MA_TRUE;
|
||||||
|
result = ma_engine_init(NULL, &engines[engineCount]);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
qCritical("Failed to initialize audio engine.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
result = ma_engine_start(&engines[engineCount]);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
qCritical("Failed to start audio engine %d.", engineCount);
|
||||||
|
}
|
||||||
|
//engineCount +=1;
|
||||||
|
iChosenDevice = id;
|
||||||
|
qInfo("Initialized audio device %d: %s", id, pPlaybackDeviceInfos[id].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioWidget::startContext()
|
||||||
|
{
|
||||||
|
ma_result result;
|
||||||
|
|
||||||
|
resourceManagerConfig = ma_resource_manager_config_init();
|
||||||
|
resourceManagerConfig.decodedFormat = ma_format_f32; /* ma_format_f32 should almost always be used as that's what the engine (and most everything else) uses for mixing. */
|
||||||
|
resourceManagerConfig.decodedChannels = 0;
|
||||||
|
resourceManagerConfig.decodedSampleRate = 0;
|
||||||
|
resourceManagerConfig.jobThreadCount = 0;
|
||||||
|
result = ma_resource_manager_init(&resourceManagerConfig, &resourceManager);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
qCritical("Failed to initialize audio resource manager.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
result = ma_context_init(NULL, 0, NULL, &context);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
qCritical("Failed to initialize audio context.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioWidget::startEngine()
|
||||||
|
{
|
||||||
|
this->startContext();
|
||||||
|
this->getAllAudioDevices();
|
||||||
|
iChosenDevice = Settings::getInstance()->getAudioDeviceId();
|
||||||
|
this->startDevice(iChosenDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
ma_engine AudioWidget::getEngine()
|
||||||
|
{
|
||||||
|
return(engines[engineCount]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioWidget::stopEngine()
|
||||||
|
{
|
||||||
|
ma_engine_uninit(&engines[engineCount]);
|
||||||
|
ma_device_uninit(&devices[engineCount]);
|
||||||
|
ma_context_uninit(&context);
|
||||||
|
ma_resource_manager_uninit(&resourceManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioWidget::mediaLoaded(int layer, QString media)
|
void AudioWidget::mediaLoaded(int layer, QString media)
|
||||||
{
|
{
|
||||||
QLayoutItem * const item = layout->itemAt(layer);
|
QLayoutItem * const item = layout->itemAt(layer);
|
||||||
dynamic_cast<AudioLayerWidget *>(item->widget())->loadMedia(media);
|
dynamic_cast<AudioLayerWidget *>(item->widget())->loadMedia(media);
|
||||||
// qDebug() << "AudioWidget::mediaLoaded Received layer: " << layer
|
|
||||||
// << "Media: " << media;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioWidget::volChanged(int layer, qreal vol) {
|
void AudioWidget::volChanged(int layer, qreal vol) {
|
||||||
QLayoutItem * const item = layout->itemAt(layer);
|
QLayoutItem * const item = layout->itemAt(layer);
|
||||||
dynamic_cast<AudioLayerWidget *>(item->widget())->setVol(vol);
|
dynamic_cast<AudioLayerWidget *>(item->widget())->setVol(vol);
|
||||||
// qDebug() << "AudioWidget::volChanged Received layer: " << layer
|
|
||||||
// << "Vol : " << vol;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioWidget::panChanged(int layer, qreal vol) {
|
void AudioWidget::panChanged(int layer, qreal vol) {
|
||||||
|
@ -65,10 +153,20 @@ void AudioWidget::playbackChanged(int layer, Status status)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void AudioWidget::layerReceived(int layer)
|
|
||||||
{
|
|
||||||
QLayoutItem * const item = layout->itemAt(layer);
|
|
||||||
dynamic_cast<AudioLayerWidget *>(item->widget())->updateWatchDMX(true);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
// enum all audio devices in system
|
||||||
|
void AudioWidget::getAllAudioDevices()
|
||||||
|
{
|
||||||
|
ma_result result;
|
||||||
|
|
||||||
|
result = ma_context_get_devices(&context, &pPlaybackDeviceInfos, &playbackDeviceCount, NULL, NULL);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
qCritical("Failed to enumerate playback devices.");
|
||||||
|
ma_context_uninit(&context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (ma_uint32 iAvailableDevice = 0; iAvailableDevice < playbackDeviceCount; iAvailableDevice += 1) {
|
||||||
|
qInfo("%d: : %s", iAvailableDevice, pPlaybackDeviceInfos[iAvailableDevice].name);
|
||||||
|
}
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
|
@ -4,12 +4,14 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
#include "audiomasterwidget.h"
|
#include "audiomasterwidget.h"
|
||||||
#include "audiolayerwidget.h"
|
#include "audiolayerwidget.h"
|
||||||
#include "defines.h"
|
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "miniaudio.h"
|
||||||
|
#include "defines.h"
|
||||||
|
|
||||||
#include "SFML/Audio/SoundSource.hpp"
|
|
||||||
|
|
||||||
class AudioWidget : public QWidget
|
class AudioWidget : public QWidget
|
||||||
{
|
{
|
||||||
|
@ -19,20 +21,37 @@ class AudioWidget : public QWidget
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
static AudioWidget *getInstance();
|
||||||
|
ma_engine getEngine();
|
||||||
|
void stopEngine();
|
||||||
|
void startEngine(int id);
|
||||||
|
ma_device_info* pPlaybackDeviceInfos;
|
||||||
|
ma_uint32 playbackDeviceCount;
|
||||||
|
ma_uint32 iChosenDevice;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
static AudioWidget *getInstance();
|
|
||||||
void mediaLoaded(int layer, QString media );
|
void mediaLoaded(int layer, QString media );
|
||||||
void volChanged(int layer, qreal vol);
|
void volChanged(int layer, qreal vol);
|
||||||
void panChanged(int layer, qreal pan);
|
void panChanged(int layer, qreal pan);
|
||||||
void pitchChanged(int layer, qreal pitch);
|
void pitchChanged(int layer, qreal pitch);
|
||||||
void playbackChanged(int layer, Status status);
|
void playbackChanged(int layer, Status status);
|
||||||
|
void startEngine();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static AudioWidget *_instance;
|
static AudioWidget *_instance;
|
||||||
AudioWidget();
|
AudioWidget();
|
||||||
QHBoxLayout *layout;
|
QHBoxLayout *layout;
|
||||||
|
ma_engine engines[MAX_DEVICES];
|
||||||
|
ma_uint32 engineCount;
|
||||||
|
ma_device devices[MAX_DEVICES];
|
||||||
|
ma_context context;
|
||||||
|
ma_resource_manager_config resourceManagerConfig;
|
||||||
|
ma_resource_manager resourceManager;
|
||||||
|
void getAllAudioDevices();
|
||||||
|
void startDevice(int id);
|
||||||
|
void startContext();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef DEFINES_H
|
#ifndef DEFINES_H
|
||||||
#define DEFINES_H
|
#define DEFINES_H
|
||||||
|
|
||||||
#define VERSION "LibreMediaServer-Audio 0.1.3"
|
#define VERSION "LibreMediaServer-Audio 0.1.4"
|
||||||
#define COPYRIGHT "(C) 2014-2024 Santi Norena lms@criptomart.net"
|
#define COPYRIGHT "(C) 2014-2024 Santi Norena lms@criptomart.net"
|
||||||
#define LICENSE "GPL 3 License. See LICENSE.txt and credits.txt for details"
|
#define LICENSE "GPL 3 License. See LICENSE.txt and credits.txt for details"
|
||||||
|
|
||||||
|
@ -9,11 +9,6 @@
|
||||||
|
|
||||||
#define DEFAULT_FILE "lms-audio.xlm"
|
#define DEFAULT_FILE "lms-audio.xlm"
|
||||||
|
|
||||||
const int DurationSeconds = 1;
|
|
||||||
const int ToneSampleRateHz = 600;
|
|
||||||
const int DataSampleRateHz = 44100;
|
|
||||||
const int BufferSize = 262144;
|
|
||||||
|
|
||||||
#define SUSPEND_LABEL "Pause playback"
|
#define SUSPEND_LABEL "Pause playback"
|
||||||
#define RESUME_LABEL "Resume playback"
|
#define RESUME_LABEL "Resume playback"
|
||||||
|
|
||||||
|
@ -33,6 +28,8 @@ const int BufferSize = 262144;
|
||||||
|
|
||||||
#define NOTIFY_INTERVAL 150
|
#define NOTIFY_INTERVAL 150
|
||||||
#define PULL_TIMER_INTERVAL 10
|
#define PULL_TIMER_INTERVAL 10
|
||||||
|
#define MAX_DEVICES 16
|
||||||
|
#define MAX_SOUNDS 4096
|
||||||
|
|
||||||
// struct where save the DMX settings for each layer
|
// struct where save the DMX settings for each layer
|
||||||
struct dmxSetting {
|
struct dmxSetting {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
/*
|
/*
|
||||||
Libre Media Server - A Media Server Sotfware for stage and performing
|
|
||||||
|
|
||||||
Copyright (C) 2012-2024 Santi Noreña lms@criptomart.net
|
Libre Media Server Audio - An Open source Media Server for arts and performing.
|
||||||
|
(c) Criptomart - Santiago Noreña 2012-2024 <lms@criptomart.net>
|
||||||
|
https://git.criptomart.net/libremediaserver
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -19,21 +20,16 @@
|
||||||
|
|
||||||
#include "libremediaserver-audio.h"
|
#include "libremediaserver-audio.h"
|
||||||
|
|
||||||
// QTextEdit * libreMediaServerAudio::textEdit = 0;
|
|
||||||
|
|
||||||
libreMediaServerAudio::libreMediaServerAudio(QStringList args, QWidget *parent)
|
libreMediaServerAudio::libreMediaServerAudio(QStringList args, QWidget *parent)
|
||||||
: QMainWindow(parent)
|
: QMainWindow(parent)
|
||||||
{
|
{
|
||||||
Q_UNUSED(args);
|
Q_UNUSED(args);
|
||||||
ui.setupUi(this);
|
ui.setupUi(this);
|
||||||
this->setWindowTitle(VERSION);
|
this->setWindowTitle(VERSION);
|
||||||
|
|
||||||
// Lee la configuración por defecto
|
Settings *set = Settings::getInstance();
|
||||||
Settings::getInstance()->readFile();
|
set->readFile();
|
||||||
|
|
||||||
// Inicia el objeto de conexión a ola
|
|
||||||
ola = new olaThread();
|
|
||||||
Q_CHECK_PTR(ola);
|
|
||||||
/*
|
/*
|
||||||
if (args.contains("-log")) {
|
if (args.contains("-log")) {
|
||||||
// Inicia el widget Terminal
|
// Inicia el widget Terminal
|
||||||
|
@ -54,43 +50,35 @@ libreMediaServerAudio::libreMediaServerAudio(QStringList args, QWidget *parent)
|
||||||
textEdit, SLOT(append(QString)), Qt::QueuedConnection);
|
textEdit, SLOT(append(QString)), Qt::QueuedConnection);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
this->setWindowTitle(VERSION);
|
this->setWindowTitle(VERSION);
|
||||||
|
qDebug() << VERSION;
|
||||||
|
qDebug() << COPYRIGHT;
|
||||||
|
qDebug() << LICENSE;
|
||||||
|
|
||||||
// qDebug() << QDate::currentDate().toString() << " "<< QTime::currentTime().toString();
|
// start audio engine
|
||||||
qDebug() << VERSION;
|
MediaLibrary::getInstance()->initMediaLibrary();
|
||||||
qDebug() << COPYRIGHT;
|
setCentralWidget(AudioWidget::getInstance());
|
||||||
qDebug() << LICENSE;
|
amw = new AudioMasterWidget(this);
|
||||||
|
QDockWidget *topWidget = new QDockWidget(tr("Master"), this);
|
||||||
setCentralWidget(AudioWidget::getInstance());
|
topWidget->setAllowedAreas(Qt::TopDockWidgetArea);
|
||||||
|
topWidget->setWidget(amw);
|
||||||
// Inicia el widget Master.
|
addDockWidget(Qt::TopDockWidgetArea, topWidget);
|
||||||
amw = new AudioMasterWidget(this);
|
// ola setup
|
||||||
QDockWidget *topWidget = new QDockWidget(tr("Master"), this);
|
ola = new olaThread();
|
||||||
topWidget->setAllowedAreas(Qt::TopDockWidgetArea);
|
Q_CHECK_PTR(ola);
|
||||||
topWidget->setWidget(amw);
|
connect(set, SIGNAL(registerUniverse(int)), ola, SLOT(registerUniverse(int)));
|
||||||
addDockWidget(Qt::TopDockWidgetArea, topWidget);
|
ola->registerUniverse(); // register now all the universes
|
||||||
|
ola->blockSignals(true);
|
||||||
// Conectamos los menus
|
connect(ola, SIGNAL (layerReceived()), amw, SLOT(updateWatchDMX()));
|
||||||
|
connect(ola, SIGNAL(dmxOutput(int, int, int)), this, SLOT(dmxInput(int, int, int)));
|
||||||
|
connect(ui.actionLaunch_OLA_Setup, SIGNAL(triggered()), this, SLOT(olasetup()));
|
||||||
|
ola->start(QThread::TimeCriticalPriority );
|
||||||
|
ola->blockSignals(false);
|
||||||
|
// menus
|
||||||
connect(ui.actionOpen_conf, SIGNAL(triggered()), this, SLOT(openFile()));
|
connect(ui.actionOpen_conf, SIGNAL(triggered()), this, SLOT(openFile()));
|
||||||
connect(ui.actionSave_conf, SIGNAL(triggered()), this, SLOT(saveFile()));
|
connect(ui.actionSave_conf, SIGNAL(triggered()), this, SLOT(saveFile()));
|
||||||
connect(ui.action_Settings, SIGNAL(triggered()), this, SLOT(settings()));
|
connect(ui.action_Settings, SIGNAL(triggered()), this, SLOT(settings()));
|
||||||
connect(ui.actionLaunch_OLA_Setup, SIGNAL(triggered()), this, SLOT(olasetup()));
|
connect(set, SIGNAL(audioDeviceChanged(int)), this, SLOT(audioDeviceChanged(int)));
|
||||||
|
|
||||||
connect(Settings::getInstance(), SIGNAL( registerUniverse(int) ),
|
|
||||||
ola, SLOT( registerUniverse(int) ) );
|
|
||||||
ola->registerUniverse(); // register now all the universes
|
|
||||||
ola->blockSignals(true);
|
|
||||||
connect(ola, SIGNAL (layerReceived()),
|
|
||||||
amw, SLOT(updateWatchDMX()));
|
|
||||||
|
|
||||||
// Inicia la media Library
|
|
||||||
MediaLibrary::getInstance()->initMediaLibrary();
|
|
||||||
|
|
||||||
// Inicia la lectura de datos DMX
|
|
||||||
ola->start(QThread::TimeCriticalPriority );
|
|
||||||
ola->blockSignals(false);
|
|
||||||
connect(ola, SIGNAL( dmxOutput(int, int, int) ),
|
|
||||||
this, SLOT( dmxInput(int, int, int) ) );
|
|
||||||
qDebug("Init Complete");
|
qDebug("Init Complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,8 +89,7 @@ libreMediaServerAudio::libreMediaServerAudio(QStringList args, QWidget *parent)
|
||||||
libreMediaServerAudio::~libreMediaServerAudio()
|
libreMediaServerAudio::~libreMediaServerAudio()
|
||||||
{
|
{
|
||||||
ola->stop();
|
ola->stop();
|
||||||
// qDebug() << QDate::currentDate() << QTime::currentTime();
|
AudioWidget::getInstance()->stopEngine();
|
||||||
// qDebug() << "********************************************************************************";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
|
@ -174,11 +161,11 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value)
|
||||||
break;
|
break;
|
||||||
case VOLUME_COARSE:
|
case VOLUME_COARSE:
|
||||||
f = ( value * 0x100 ) + ola->getValue(layer, VOLUME_FINE);
|
f = ( value * 0x100 ) + ola->getValue(layer, VOLUME_FINE);
|
||||||
AudioWidget::getInstance()->volChanged(layer, f / 655.35);
|
AudioWidget::getInstance()->volChanged(layer, (f / 655.35));
|
||||||
break;
|
break;
|
||||||
case VOLUME_FINE:
|
case VOLUME_FINE:
|
||||||
f = ( ola->getValue(layer, VOLUME_COARSE) * 0x100 ) + value;
|
f = ( ola->getValue(layer, VOLUME_COARSE) * 0x100 ) + value;
|
||||||
AudioWidget::getInstance()->volChanged(layer, f / 655.35);
|
AudioWidget::getInstance()->volChanged(layer, (f / 655.35));
|
||||||
break;
|
break;
|
||||||
case PAN:
|
case PAN:
|
||||||
AudioWidget::getInstance()->panChanged(layer, value);
|
AudioWidget::getInstance()->panChanged(layer, value);
|
||||||
|
@ -208,3 +195,9 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void libreMediaServerAudio::audioDeviceChanged(int id)
|
||||||
|
{
|
||||||
|
AudioWidget::getInstance()->stopEngine();
|
||||||
|
AudioWidget::getInstance()->startEngine(id);
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Libre Media Server - A Media Server Sotfware for stage and performing
|
Libre Media Server Audio - An Open source Media Server for arts and performing.
|
||||||
Copyright (C) 2012-2014 Santiago Noreña libremediaserver@gmail.com
|
(c) Criptomart - Santiago Noreña 2012-2024 <lms@criptomart.net>
|
||||||
|
https://git.criptomart.net/libremediaserver
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -26,17 +27,17 @@
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QWebView>
|
#include <QWebView>
|
||||||
|
#include <QApplication>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QTextEdit>
|
#include <QTextEdit>
|
||||||
|
|
||||||
#include "medialibrary.h"
|
|
||||||
#include "audiowidget.h"
|
#include "audiowidget.h"
|
||||||
#include "settings.h"
|
#include "medialibrary.h"
|
||||||
#include "olathread.h"
|
#include "olathread.h"
|
||||||
|
#include "settings.h"
|
||||||
#include "audiomasterwidget.h"
|
#include "audiomasterwidget.h"
|
||||||
#include "defines.h"
|
|
||||||
#include "settingsdialog.h"
|
#include "settingsdialog.h"
|
||||||
|
#include "defines.h"
|
||||||
|
|
||||||
#include "ui_libremediaserver-audio.h"
|
#include "ui_libremediaserver-audio.h"
|
||||||
|
|
||||||
|
@ -70,7 +71,7 @@ private:
|
||||||
void save(QFile *file);
|
void save(QFile *file);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// inline void toTerminal(QString msg) { textEdit->append(msg); }
|
void audioDeviceChanged(int id);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>126</width>
|
<width>199</width>
|
||||||
<height>89</height>
|
<height>218</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -20,8 +20,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>126</width>
|
<width>199</width>
|
||||||
<height>29</height>
|
<height>22</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="menuFile">
|
<widget class="QMenu" name="menuFile">
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*
|
/*
|
||||||
Libre Media Server - A media server for audio playback in stage arts
|
|
||||||
controlled by lingting protocols (DMX, ArtNet, ACN,...)
|
|
||||||
|
|
||||||
Copyright (C) 2015-2024 Santi Noreña lms@criptomart.net
|
Libre Media Server Audio - An Open source Media Server for arts and performing.
|
||||||
|
(c) Criptomart - Santiago Noreña 2012-2024 <lms@criptomart.net>
|
||||||
|
https://git.criptomart.net/libremediaserver
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -18,9 +18,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
//#include <QMutex>
|
|
||||||
//#include <QMutexLocker>
|
|
||||||
#include "libremediaserver-audio.h"
|
#include "libremediaserver-audio.h"
|
||||||
|
|
||||||
// Handler for pipe the stderr to a log file and texEdit
|
// Handler for pipe the stderr to a log file and texEdit
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include "medialibrary.h"
|
#include "medialibrary.h"
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
MediaLibrary *MediaLibrary::_instance = 0;
|
MediaLibrary *MediaLibrary::_instance = 0;
|
||||||
|
|
||||||
MediaLibrary *MediaLibrary::getInstance() {
|
MediaLibrary *MediaLibrary::getInstance() {
|
||||||
|
@ -20,7 +18,6 @@ MediaLibrary::MediaLibrary(QObject *parent) :
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaLibrary::initMediaLibrary() {
|
void MediaLibrary::initMediaLibrary() {
|
||||||
qDebug("starting the media library");
|
|
||||||
QDir dir;
|
QDir dir;
|
||||||
if (!dir.cd(Settings::getInstance()->getPathMedia())) {
|
if (!dir.cd(Settings::getInstance()->getPathMedia())) {
|
||||||
qWarning("Can not cd to the path: %s", Settings::getInstance()->getPathMedia().toLatin1().constData());
|
qWarning("Can not cd to the path: %s", Settings::getInstance()->getPathMedia().toLatin1().constData());
|
||||||
|
@ -46,7 +43,7 @@ void MediaLibrary::initMediaLibrary() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This set every media file included in one library/folder
|
* fill the struct with all files in one library/folder
|
||||||
*/
|
*/
|
||||||
QList<MediaFile> MediaLibrary::getMediaInformation(QDir dir)
|
QList<MediaFile> MediaLibrary::getMediaInformation(QDir dir)
|
||||||
{
|
{
|
||||||
|
@ -60,31 +57,27 @@ QList<MediaFile> MediaLibrary::getMediaInformation(QDir dir)
|
||||||
// Update the data base with the new file
|
// Update the data base with the new file
|
||||||
mediainf.Number = i;
|
mediainf.Number = i;
|
||||||
mediainf.MediaName = fileInfo.absoluteFilePath();
|
mediainf.MediaName = fileInfo.absoluteFilePath();
|
||||||
mediainf.MediaLength = 1000; // ¿?¿?¿?¿?
|
mediainf.MediaLength = 1000;
|
||||||
mediaList.append(mediainf);
|
mediaList.append(mediainf);
|
||||||
}
|
}
|
||||||
return mediaList;
|
return mediaList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Selects one media path from the library
|
/**
|
||||||
*
|
* returns the path to a media file from the library.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
QString MediaLibrary::requestNewFile(int folder, int file){
|
QString MediaLibrary::requestNewFile(int folder, int file){
|
||||||
// Select one mediafile from the media library
|
|
||||||
if (!m_media) {
|
if (!m_media) {
|
||||||
qWarning("Media Library not init. Set a correct path to medias library");
|
qWarning("MediaLibrary is not init. Set a correct path to media library");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
QString newfile;
|
QString newfile;
|
||||||
if (folder < m_media->size()) {
|
if (folder < m_media->size()) {
|
||||||
if (file < m_media->at(folder).m_MediaInformation.size()) {
|
if (file < m_media->at(folder).m_MediaInformation.size()) {
|
||||||
newfile = m_media->at(folder).m_MediaInformation.at(file).MediaName;
|
newfile = m_media->at(folder).m_MediaInformation.at(file).MediaName;
|
||||||
} else {
|
} else
|
||||||
qDebug("MediaLibrary::requestNewFile(): Requested file is greater than files in library");
|
qInfo("requestNewFile: Requested file %i is greater than files in library %i", file, m_media->at(folder).m_MediaInformation.size());
|
||||||
}
|
} else
|
||||||
} else {
|
qInfo("requestNewFile: Requested folder %i is greater than media libraries %i", folder, m_media->size());
|
||||||
qDebug("MediaLibrary::requestNewFile(): Requested folder is greater than media libraries");
|
|
||||||
}
|
|
||||||
return newfile;
|
return newfile;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
|
@ -28,6 +28,7 @@ void Settings::setPathMedia(QString path)
|
||||||
// - The number of sources/layers controlled by DMX
|
// - The number of sources/layers controlled by DMX
|
||||||
// - The first DMX channel of each source/layer
|
// - The first DMX channel of each source/layer
|
||||||
// - The universe to bind in OLA
|
// - The universe to bind in OLA
|
||||||
|
// - Audio device id
|
||||||
void Settings::readFromFile(QString file) {
|
void Settings::readFromFile(QString file) {
|
||||||
QFile* xmlFile = new QFile(file);
|
QFile* xmlFile = new QFile(file);
|
||||||
if (!xmlFile->open(QIODevice::ReadOnly | QIODevice::Text)) {
|
if (!xmlFile->open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
@ -58,6 +59,10 @@ void Settings::readFromFile(QString file) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(xmlReader->name() == "audioDevice") {
|
||||||
|
m_audioDeviceId = xmlReader->attributes().value("id").toLocal8Bit().toInt();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
QString add = "layer";
|
QString add = "layer";
|
||||||
add.append(QString("%1").arg(counter));
|
add.append(QString("%1").arg(counter));
|
||||||
if((xmlReader->name() == add)) {
|
if((xmlReader->name() == add)) {
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
|
||||||
#include "medialibrary.h"
|
#include "medialibrary.h"
|
||||||
|
#include "audiowidget.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -96,6 +97,11 @@ public:
|
||||||
else
|
else
|
||||||
m_layersNumber = LAYERS_NUMBER;
|
m_layersNumber = LAYERS_NUMBER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int getAudioDeviceId() { return m_audioDeviceId; }
|
||||||
|
inline void setAudioDeviceId(int id) { m_audioDeviceId = id; }
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static Settings *_instance;
|
static Settings *_instance;
|
||||||
|
@ -106,6 +112,9 @@ private:
|
||||||
// The path to media library
|
// The path to media library
|
||||||
QString m_pathmedia;
|
QString m_pathmedia;
|
||||||
|
|
||||||
|
// The SO audio device id used
|
||||||
|
uint m_audioDeviceId;
|
||||||
|
|
||||||
/** Constructor
|
/** Constructor
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -153,8 +162,7 @@ signals:
|
||||||
*/
|
*/
|
||||||
void registerUniverse(int universe);
|
void registerUniverse(int universe);
|
||||||
|
|
||||||
public slots:
|
void audioDeviceChanged(int id);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SETTINGS_H
|
#endif // SETTINGS_H
|
||||||
|
|
|
@ -2,18 +2,20 @@
|
||||||
#include "ui_settingsdialog.h"
|
#include "ui_settingsdialog.h"
|
||||||
|
|
||||||
SettingsDialog::SettingsDialog(QWidget *parent) :
|
SettingsDialog::SettingsDialog(QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent)
|
||||||
ui(new Ui::SettingsDialog)
|
, ui(new Ui::SettingsDialog)
|
||||||
|
, m_deviceDialog(NULL)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
this->setWindowTitle("Settings");
|
this->setWindowTitle("Settings");
|
||||||
ui->layersNumber->setValue(Settings::getInstance()->getLayersNumber());
|
ui->layersNumber->setValue(Settings::getInstance()->getLayersNumber());
|
||||||
QString path("Path to root folder of the media tree: /n");
|
//QString path("Path to root folder of the media tree: /n");
|
||||||
path.append(Settings::getInstance()->getPathMedia());
|
//path.append(Settings::getInstance()->getPathMedia());
|
||||||
ui->mediaPath->setText(path);
|
//ui->mediaPath->setText(path);
|
||||||
|
connect(ui->mediaPathButton, SIGNAL(clicked()),
|
||||||
connect(ui->mediaPatchButton, SIGNAL(clicked()),
|
|
||||||
this, SLOT(changeMediaPath()));
|
this, SLOT(changeMediaPath()));
|
||||||
|
connect(ui->audioDeviceButton , SIGNAL(clicked()),
|
||||||
|
this, SLOT(changeAudioDevice()));
|
||||||
connect(ui->layersNumber, SIGNAL(valueChanged(int)),
|
connect(ui->layersNumber, SIGNAL(valueChanged(int)),
|
||||||
this, SLOT(layersChanged(int)));
|
this, SLOT(layersChanged(int)));
|
||||||
int layer = 0;
|
int layer = 0;
|
||||||
|
@ -42,7 +44,45 @@ void SettingsDialog::changeMediaPath()
|
||||||
QString file = fileNames.at(0);
|
QString file = fileNames.at(0);
|
||||||
Settings::getInstance()->setPathMedia(file);
|
Settings::getInstance()->setPathMedia(file);
|
||||||
QString desc = tr("Media Path Changed to: %1").arg(file);
|
QString desc = tr("Media Path Changed to: %1").arg(file);
|
||||||
qDebug("%s", desc.toLatin1().constData());
|
qInfo("%s", desc.toLatin1().constData());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsDialog::changeAudioDevice()
|
||||||
|
{
|
||||||
|
if (!m_deviceDialog)
|
||||||
|
{
|
||||||
|
m_deviceDialog = new QDialog( this );
|
||||||
|
}
|
||||||
|
QLabel *msgLabel = new QLabel;
|
||||||
|
AudioWidget *aw = AudioWidget::getInstance();
|
||||||
|
QString *msg = new QString;
|
||||||
|
for (uint iAvailableDevice = 0; iAvailableDevice < aw->playbackDeviceCount; iAvailableDevice += 1) {
|
||||||
|
msg->append(tr("%1 : %2\n").arg(iAvailableDevice).arg(aw->pPlaybackDeviceInfos[iAvailableDevice].name));
|
||||||
|
}
|
||||||
|
msgLabel->setText(msg->toLatin1());
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout;
|
||||||
|
layout->addWidget(msgLabel);
|
||||||
|
QSpinBox *res = new QSpinBox;
|
||||||
|
res->setRange(0, aw->playbackDeviceCount);
|
||||||
|
res->setValue(AudioWidget::getInstance()->iChosenDevice);
|
||||||
|
layout->addWidget(res);
|
||||||
|
QPushButton *closeButton = new QPushButton(tr("Close"));
|
||||||
|
connect(closeButton, SIGNAL(clicked()), this, SLOT(closeAudioDeviceDialog()));
|
||||||
|
closeButton->setDefault(true);
|
||||||
|
layout->addWidget(closeButton);
|
||||||
|
m_deviceDialog->setLayout(layout);
|
||||||
|
m_deviceDialog->setModal(true);
|
||||||
|
m_deviceDialog->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsDialog::closeAudioDeviceDialog()
|
||||||
|
{
|
||||||
|
QLayoutItem * const item = m_deviceDialog->layout()->itemAt(1);
|
||||||
|
int value = dynamic_cast<QSpinBox *>(item->widget())->value();
|
||||||
|
Settings::getInstance()->setAudioDeviceId(value);
|
||||||
|
qInfo("device selected: %i", value);
|
||||||
|
m_deviceDialog->close();
|
||||||
|
emit Settings::getInstance()->audioDeviceChanged(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::layersChanged(int val)
|
void SettingsDialog::layersChanged(int val)
|
||||||
|
|
|
@ -21,11 +21,16 @@ public:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void changeMediaPath();
|
void changeMediaPath();
|
||||||
|
void changeAudioDevice();
|
||||||
|
void closeAudioDeviceDialog();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::SettingsDialog *ui;
|
Ui::SettingsDialog *ui;
|
||||||
|
QDialog *m_deviceDialog;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void layersChanged(int val);
|
void layersChanged(int val);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SETTINGSDIALOG_H
|
#endif // SETTINGSDIALOG_H
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>400</width>
|
<width>400</width>
|
||||||
<height>429</height>
|
<height>563</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -16,9 +16,9 @@
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>290</x>
|
<x>10</x>
|
||||||
<y>390</y>
|
<y>530</y>
|
||||||
<width>101</width>
|
<width>381</width>
|
||||||
<height>32</height>
|
<height>32</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -26,14 +26,14 @@
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="standardButtons">
|
<property name="standardButtons">
|
||||||
<set>QDialogButtonBox::Close</set>
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QSpinBox" name="layersNumber">
|
<widget class="QSpinBox" name="layersNumber">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>10</x>
|
<x>10</x>
|
||||||
<y>40</y>
|
<y>50</y>
|
||||||
<width>52</width>
|
<width>52</width>
|
||||||
<height>31</height>
|
<height>31</height>
|
||||||
</rect>
|
</rect>
|
||||||
|
@ -63,8 +63,8 @@
|
||||||
<widget class="QLabel" name="layersNumber_label">
|
<widget class="QLabel" name="layersNumber_label">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>60</x>
|
<x>70</x>
|
||||||
<y>40</y>
|
<y>50</y>
|
||||||
<width>111</width>
|
<width>111</width>
|
||||||
<height>21</height>
|
<height>21</height>
|
||||||
</rect>
|
</rect>
|
||||||
|
@ -73,25 +73,12 @@
|
||||||
<string>Layers Number</string>
|
<string>Layers Number</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="mediaPath">
|
<widget class="QPushButton" name="mediaPathButton">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>10</x>
|
<x>10</x>
|
||||||
<y>10</y>
|
<y>10</y>
|
||||||
<width>371</width>
|
<width>171</width>
|
||||||
<height>21</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>TextLabel</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QPushButton" name="mediaPatchButton">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>200</x>
|
|
||||||
<y>40</y>
|
|
||||||
<width>191</width>
|
|
||||||
<height>31</height>
|
<height>31</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -108,14 +95,33 @@
|
||||||
<widget class="QWidget" name="verticalLayoutWidget">
|
<widget class="QWidget" name="verticalLayoutWidget">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>9</x>
|
<x>0</x>
|
||||||
<y>99</y>
|
<y>80</y>
|
||||||
<width>381</width>
|
<width>401</width>
|
||||||
<height>281</height>
|
<height>451</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="layersLayout"/>
|
<layout class="QVBoxLayout" name="layersLayout"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QPushButton" name="audioDeviceButton">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>210</x>
|
||||||
|
<y>10</y>
|
||||||
|
<width>181</width>
|
||||||
|
<height>31</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Change Audio Device</string>
|
||||||
|
</property>
|
||||||
|
<property name="default">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections>
|
<connections>
|
||||||
|
|
Loading…
Add table
Reference in a new issue