diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/.DS_Store differ
diff --git a/.gitignore b/.gitignore
index 07780f1..0d096af 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,3 +26,13 @@ libcontrol/controlsender_test
libgui/channelselector_test
libgui/midicontrolchannelassigner_test
libgui/slider_test
+*.dot
+*.tex
+*.png
+*.html
+*.sty
+*.svg
+*.js
+*.css
+*.tmp
+doxydoc/latex/Makefile
diff --git a/INSTALL b/INSTALL
index 41d3811..c1f31fc 100644
--- a/INSTALL
+++ b/INSTALL
@@ -18,3 +18,63 @@ If you run into any other problems don't hesitate to contact me at
arnold@arnoldarts.de or on linux-audio-user@lists.linuxaudio.org.
Problems involving the MIDI control of the mixer are almost certainly
Nick Bailey's fault: nick@n-ism.org is the place to contact him.
+
+Install Scons
+ $ python3 -m pip install scons
+
+Install Qt environment
+ $ sudo apt-get install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools
+
+Install the jack-audio-connection-kit and compile it.
+ $ git clone https://github.com/jackaudio/jack2.git
+ Or download the source code via the link below.
+ https://github.com/jackaudio/jack2/releases/tag/v1.9.21
+
+ Compile and install Jack2 , on linux, using './waf configure', './waf' and './waf install' as root.
+ On macosx, users can use the xcode project.
+ On Windows, users can use the Code::Blocks workspace (you also have a small script to make an all in one installer).
+
+ Editing the configuration file
+
+ If your system has no directory called /etc/security/limits.d then you will need to edit /etc/security/limits.conf.
+ If /etc/security/limits.d does exist on your machine, then you will need to create and edit a file called /etc/security/limits.d/audio.conf.
+ The file must contain (at least) the following two lines:
+ @audio - rtprio 95
+ @audio - memlock unlimited
+ Contrary to a lot of misinformation on the web, there is no reason to include a line here that provides enhanced “niceness” control,
+ which is completely irrelevant for realtime scheduling and low latency audio applications.
+
+ Creating an “audio” group
+ As the super-user (“root”) run the following commands from a terminal window:
+ $ sudo groupadd audio
+ $ sudo usermod -a -G audio yourUserID
+ Users should substitute their actual user id or “login” for “yourUserID”.
+
+ Users can carry out these two steps using the graphical tools available under the “System Administration” section of your desktop’s main menu. However, this text-based method is faster and much easier to explain.
+
+ Suppose users use a distribution that has already created the group and configured the “limits” file.
+ In that case, users will need to determine the name of the group (it is likely called “audio” or “jackuser”).
+ Then they can add themselves to the group with this command (run as the superuser inside a terminal window):
+ $ usermod -a -G theGroupName yourUserID
+
+ Logout and back in
+ None of the changes users have made above will affect users until they log out and back in.
+ If that does not work, try rebooting. In either case, users do not need to reinstall any software.
+
+Install alsa, libsound2-dev, linux-lowlatency, pulseaudio-module-jack, qjackctl
+ $ sudo apt-get install alsa
+ $ sudo apt-get install libasound2-dev
+ $ sudo apt-get install linux-lowlatency
+ $ sudo apt-get install pulseaudio-module-jack
+ $ sudo apt-get install qjackctl
+
+ After completing the above steps, run qjackctl. Qjackctl is the basis for Jackmix to run.
+ If qjackctl fails to run, Jackmix will not be available.
+
+
+Complie and run Jackmix
+ The Jackmix project provides the SConstruct compilation file, so users can compile the entire Jackmix project
+ by typing scons in the terminal and pressing enter. Once compiled, the executable jackmix file is generated in
+ the /jackmix directory, and the graphical user interface appears after running jackmix successfully.
+
+
diff --git a/backend/jack_backend.h b/backend/jack_backend.h
index ebf20ad..75bf425 100644
--- a/backend/jack_backend.h
+++ b/backend/jack_backend.h
@@ -55,17 +55,37 @@ class JackBackend : public BackendInterface {
JackBackend( GuiServer_Interface* );
/// Ends everything
~JackBackend();
-
+
+ /**
+ * @brief Adding an output channel and return ture on success.
+ * @param Qstring The name of the output channel that we want to add.
+ * @return true or false
+ */
bool addOutput( QString );
+ /**
+ * @brief Remove an input channel and return true on success.
+ * @param Qstring The name of the input channel that we want to remove.
+ * @return true or false
+ */
bool removeInput( QString );
+ /**
+ * @brief Adding an input channel and return ture on success.
+ * @param Qstring The name of the input channel that we want to add.
+ * @return true or false
+ */
bool addInput( QString );
+ /**
+ * @brief Remove an input channel and return true on success.
+ * @param Qstring The name of the input channel that we want to remove.
+ * @return true or false
+ */
bool removeOutput( QString );
/**
- * Rename a jack port
+ * @brief Rename a jack port
*
- * \param old_name current port name
- * \param new_name new port name
- * \returns whether a port was renamed
+ * @param old_name current port name
+ * @param new_name new port name
+ * @returns whether a port was renamed
*/
bool rename(const QString old_name, const QString new_name);
bool rename(const QString old_name, const char *new_name);
@@ -120,7 +140,7 @@ class JackBackend : public BackendInterface {
::jack_port_t *midi_port;
/**
- * Handle changes in jack server sample rate
+ * @brief Handle changes in jack server sample rate
*
* @param rate New sample rate
* @param args Client-supplied args (not used)
diff --git a/jackmix/1.jm-xml b/jackmix/1.jm-xml
new file mode 100644
index 0000000..060a0b3
--- /dev/null
+++ b/jackmix/1.jm-xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jackmix/mainwindow.cpp b/jackmix/mainwindow.cpp
index 3b17e7f..c0c2622 100644
--- a/jackmix/mainwindow.cpp
+++ b/jackmix/mainwindow.cpp
@@ -121,6 +121,7 @@ void MainWindow::init() {
_filemenu->addAction( "Save File...", this, SLOT( saveFile() ), Qt::CTRL+Qt::Key_S );
_filemenu->addSeparator();
_filemenu->addAction( "&Quit", this, SLOT( close() ), Qt::CTRL+Qt::Key_Q );
+
_editmenu = menuBar()->addMenu( "&Edit" );
_select_action = new QAction( "Select Mode", this );
@@ -130,24 +131,34 @@ void MainWindow::init() {
//_select_action->addTo( new QToolBar( this ) );
_editmenu->addAction( "&Fill empty spaces", this, SLOT( scheduleAutoFill() ) );
_editmenu->addSeparator();
+
_add_inchannel_action = new QAction( "Add &Input...", this );
connect( _add_inchannel_action, SIGNAL( triggered() ), this, SLOT( addInput() ) );
_editmenu->addAction( _add_inchannel_action );
+
_add_outchannel_action = new QAction( "Add &Output...", this );
connect( _add_outchannel_action, SIGNAL( triggered() ), this, SLOT( addOutput() ) );
_editmenu->addAction( _add_outchannel_action );
+
_rename_input_action = new QAction( "Re&name Inputs...", this);
connect( _rename_input_action, SIGNAL( triggered() ), this, SLOT(renameInput()) );
_editmenu->addAction( _rename_input_action );
+
_rename_output_action = new QAction( "Ren&ame Outputs...", this);
connect( _rename_output_action, SIGNAL( triggered() ), this, SLOT(renameOutput()) );
_editmenu->addAction( _rename_output_action );
+
_remove_inchannel_action = new QAction( "&Remove Input...", this );
connect( _remove_inchannel_action, SIGNAL( triggered() ), this, SLOT( removeInput() ) );
_editmenu->addAction( _remove_inchannel_action );
+
_remove_outchannel_action = new QAction( "R&emove Output...", this );
connect( _remove_outchannel_action, SIGNAL( triggered() ), this, SLOT( removeOutput() ) );
_editmenu->addAction( _remove_outchannel_action );
+
+ //_replace_action = new QAction( "Replace elements...", this );
+ //connect( _replace_action, SIGNAL( triggered() ), this, SLOT( slot_simple_select()));
+ //_editmenu->addAction(_replace_action);
_viewmenu = menuBar()->addMenu( "&View" );
_togglein_action = new QAction( "Hide &inputcontrols", this );
diff --git a/jackmix/mainwindow.h b/jackmix/mainwindow.h
index 02beea5..b678ca0 100644
--- a/jackmix/mainwindow.h
+++ b/jackmix/mainwindow.h
@@ -31,7 +31,7 @@
#include
#include
#include
-
+#include
#include "controlsender.h"
class QHBox;
@@ -100,6 +100,8 @@ private slots:
void removeOutput();
void removeOutput( QString );
+ //void slot_simple_replace();
+
void allAutoFill();
void scheduleAutoFill();
diff --git a/libelements/aux_elements.cpp b/libelements/aux_elements.cpp
index e713112..4b569bb 100644
--- a/libelements/aux_elements.cpp
+++ b/libelements/aux_elements.cpp
@@ -32,7 +32,9 @@
#include
#include
#include
-//#include
+#include
+#include
+#include
#include
#include
@@ -77,12 +79,19 @@ AuxElement::AuxElement( QStringList inchannel, QStringList outchannel, MixingMat
: Element( inchannel, outchannel, p, n )
, dB2VolCalc( -42, 6 )
{
+
if (p->mode() == Widget::Select) {
menu()->addAction( "Select", this, SLOT( slot_simple_select() ) );
- menu()->addAction( "Replace", this, SLOT( slot_simple_replace() ) );
+
+ menu()->addAction( "&Replace", this, SLOT( slot_simple_replace() ), Qt::Key_R );
+
+ _button = new QRadioButton(this);
+ connect(_button, SIGNAL(clicked()),this,SLOT(slot_simple_select()));
}
- menu()->addAction( "Assign MIDI Parameter", this, SLOT( slot_assign_midi_parameters() ) );
+
+ menu()->addAction( "&Assign MIDI Parameter", this, SLOT( slot_assign_midi_parameters() ) );
+
QVBoxLayout* _layout = new QVBoxLayout( this );
if ( _in[0] == _out[0] ) {
@@ -93,8 +102,12 @@ AuxElement::AuxElement( QStringList inchannel, QStringList outchannel, MixingMat
_poti = new JackMix::GUI::Knob(
amptodb( backend()->getVolume( _in[0], _out[0] ) ),
dbmin, dbmax, 2, 3, this );
- _layout->addWidget( _poti, 100 );
-
+
+ //_button = new QRadioButton(this);
+
+ _layout->addWidget( _poti, 2000 );
+
+ //connect(_button, SIGNAL(buttonClicked()),this,SLOT(slot_simple_select()));
connect( _poti, SIGNAL( valueChanged( double ) ), this, SLOT( emitvalue( double ) ) );
connect( _poti, SIGNAL( select() ), this, SLOT( slot_simple_select() ) );
connect( _poti, SIGNAL( replace() ), this, SLOT( slot_simple_replace() ) );
diff --git a/libelements/aux_elements.h b/libelements/aux_elements.h
index 8a00f92..2d3033a 100644
--- a/libelements/aux_elements.h
+++ b/libelements/aux_elements.h
@@ -29,7 +29,7 @@
#include
#include
#include
-
+#include
namespace JackMix {
namespace GUI {
@@ -53,12 +53,17 @@ Q_OBJECT
int outchannels() const { return 1; }
void setIndicator(const QColor& c);
-
+
+signals:
+
public slots:
+
+
void emitvalue( double );
private:
JackMix::GUI::Knob *_poti;
+ QRadioButton *_button;
};
void init_aux_elements();
diff --git a/libelements/stereo_elements.cpp b/libelements/stereo_elements.cpp
index f085611..3e07798 100644
--- a/libelements/stereo_elements.cpp
+++ b/libelements/stereo_elements.cpp
@@ -49,11 +49,12 @@ class StereoFactory : public JackMix::MixingMatrix::ElementFactory
~StereoFactory() {}
QStringList canCreate() const {
- return QStringList()<<"Mono2StereoElement"<<"Stereo2StereoElement";
+ return QStringList()<<"Mono2StereoElement"<<"Stereo2StereoElement"<<"Threeinput2outputElement";
}
QStringList canCreate( int in, int out ) const {
if ( in==1 && out==2 ) return QStringList()<<"Mono2StereoElement";
if ( in==2 && out==2 ) return QStringList()<<"Stereo2StereoElement";
+ if ( in==3 && out==2 ) return QStringList()<<"Threeinput2outputElement";
return QStringList();
}
@@ -62,6 +63,8 @@ class StereoFactory : public JackMix::MixingMatrix::ElementFactory
return new Mono2StereoElement( ins, outs, p, n );
if ( type=="Stereo2StereoElement" )
return new Stereo2StereoElement( ins, outs, p, n );
+ if ( type=="Threeinput2outputElement" )
+ return new Threeinput2outputElement( ins, outs, p, n );
return 0;
}
};
@@ -93,10 +96,7 @@ Mono2StereoElement::Mono2StereoElement( QStringList inchannel, QStringList outch
_layout->setMargin( 0 );
_layout->setSpacing( 0 );
- menu()->addAction( "Select", this, SLOT( slot_simple_select() ) );
- menu()->addAction( "Replace", this, SLOT( slot_simple_replace() ) );
- menu()->addAction( "Explode", this, SLOT( slot_simple_explode() ) );
- menu()->addAction( "Assign MIDI Parameter", this, SLOT( slot_assign_midi_parameters() ) );
+
_balance = new JackMix::GUI::Knob( _balance_value, -1, 1, 2, 0.1, this, "%1" );
_layout->addWidget( _balance, 10 );
@@ -109,6 +109,12 @@ Mono2StereoElement::Mono2StereoElement( QStringList inchannel, QStringList outch
connect( _volume, SIGNAL( select() ), this, SLOT( slot_simple_select() ) );
connect( _volume, SIGNAL( replace() ), this, SLOT( slot_simple_replace() ) );
+ menu()->addAction( "Select", this, SLOT( slot_simple_select() ) );
+ menu()->addAction( "&Replace", this, SLOT( slot_simple_replace() ) );
+ menu()->addAction( "&Explode", this, SLOT( slot_simple_explode() ) );
+ menu()->addAction( "&Assign MIDI Parameter", this, SLOT( slot_assign_midi_parameters() ) );
+
+
// WATCH OUT: Order of initialisation is really important!
// Make sure all the widgets are contructed before adding them to the delegates list
@@ -132,14 +138,14 @@ Mono2StereoElement::~Mono2StereoElement() {
}
void Mono2StereoElement::balance( double n ) {
- //qDebug( "Mono2StereoElement::balance( double %f )", n );
+ qDebug( "Mono2StereoElement::balance( double %f )", n );
_balance_value = n;
calculateVolumes();
_balance->value( n );
emit valueChanged( this, QString( "balance" ) );
}
void Mono2StereoElement::volume( double n ) {
- //qDebug( "Mono2StereoElement::volume( double %f )", n );
+ qDebug( "Mono2StereoElement::volume( double %f )", n );
_volume_value = n;
calculateVolumes();
_volume->value( n );
@@ -195,14 +201,18 @@ Stereo2StereoElement::Stereo2StereoElement( QStringList inchannels, QStringList
QAction *toggle = new QAction( "Toggle Selection", this );
connect( toggle, SIGNAL( triggered() ), this, SLOT( slot_simple_select() ) );
menu()->addAction( toggle );
- QAction *replace = new QAction( "Replace", this );
+
+ QAction *replace = new QAction( "&Replace", this );
connect( replace, SIGNAL( triggered() ), this, SLOT( slot_simple_replace() ) );
menu()->addAction( replace );
- QAction *explode = new QAction( "Explode", this );
+
+ QAction *explode = new QAction( "&Explode", this );
+ explode->setShortcut(Qt::CTRL+Qt::Key_E);
+ this->addAction(explode);
connect( explode, SIGNAL( triggered() ), this, SLOT( slot_simple_explode() ) );
menu()->addAction( explode );
- QAction *assign = new QAction( "Assign MIDI Parameter", this );
+ QAction *assign = new QAction( "&Assign MIDI Parameter", this );
connect( assign, SIGNAL( triggered() ), this, SLOT( slot_assign_midi_parameters() ) );
menu()->addAction( assign );
@@ -231,14 +241,14 @@ Stereo2StereoElement::~Stereo2StereoElement() {
}
void Stereo2StereoElement::balance( double n ) {
- //qDebug( "Mono2StereoElement::balance( double %f )", n );
+ qDebug( "Mono2StereoElement::balance( double %f )", n );
_balance_value = n;
_balance_widget->value( n );
calculateVolumes();
emit valueChanged( this, QString( "balance" ) );
}
void Stereo2StereoElement::volume( double n ) {
- //qDebug( "Mono2StereoElement::volume( double %f )", n );
+ qDebug( "Mono2StereoElement::volume( double %f )", n );
_volume_value = n;
_volume_widget->value( n );
calculateVolumes();
@@ -256,3 +266,192 @@ void Stereo2StereoElement::calculateVolumes() {
backend()->setVolume( _in[0], _out[0], left );
backend()->setVolume( _in[1], _out[1], right );
}
+
+
+
+
+
+
+Threeinput2outputElement::Threeinput2outputElement( QStringList inchannel, QStringList outchannels, MixingMatrix::Widget* p, const char* n )
+ : Element( inchannel, outchannels, p, n )
+ , dB2VolCalc(-42, 6 )
+ , _balance_value( 0 )
+ , _volume_value( 0 )
+ , _balance_value2( 0 )
+ , _volume_value2( 0 )
+ , _balance_value3( 0 )
+ , _volume_value3( 0 )
+{
+
+ double left = backend()->getVolume( _in[0], _out[0] );
+ double right = backend()->getVolume( _in[0], _out[1] );
+ //qDebug( " volumes: %f, %f", left, right );
+ if ( left>right ) {
+ _volume_value = left;
+ _balance_value = right-left;
+ } else {
+ _volume_value = right;
+ _balance_value = right-left;
+ }
+ double left2 = backend()->getVolume( _in[1], _out[0] );
+ double right2 = backend()->getVolume( _in[1], _out[1] );
+ //qDebug( " volumes: %f, %f", left, right );
+ if ( left2>right2 ) {
+ _volume_value2 = left2;
+ _balance_value2 = right2-left2;
+ } else {
+ _volume_value2 = right2;
+ _balance_value2 = right2-left2;
+ }
+ double left3 = backend()->getVolume( _in[2], _out[0] );
+ double right3 = backend()->getVolume( _in[2], _out[1] );
+ //qDebug( " volumes: %f, %f", left, right );
+ if ( left3>right3 ) {
+ _volume_value3 = left3;
+ _balance_value3 = right3-left3;
+ } else {
+ _volume_value3 = right3;
+ _balance_value3 = right3-left3;
+ }
+ //qDebug( " values: %f, %f", _volume_value, _balance_value );
+ QGridLayout* _layout = new QGridLayout( this );
+ _layout->setSpacing( 1 );
+ _layout->setMargin( 2 );
+
+ _balance = new JackMix::GUI::Knob( _balance_value, -1, 1, 2, 0.1, this, "%1" );
+ _layout->addWidget( _balance, 0,0,1,1 );
+ _layout->setRowStretch( 0, 255 );
+ connect( _balance, SIGNAL( valueChanged( double ) ), this, SLOT( balance( double ) ) );
+ connect( _balance, SIGNAL( select() ), this, SLOT( slot_simple_select() ) );
+ connect( _balance, SIGNAL( replace() ), this, SLOT( slot_simple_replace() ) );
+
+ _balance2 = new JackMix::GUI::Knob( _balance_value2, -1, 1, 2, 0.1, this, "%1" );
+ _layout->addWidget( _balance2, 0,1,1,1 );
+ _layout->setRowStretch( 0, 255 );
+ connect( _balance2, SIGNAL( valueChanged( double ) ), this, SLOT( balance2( double ) ) );
+ connect( _balance2, SIGNAL( select() ), this, SLOT( slot_simple_select() ) );
+ connect( _balance2, SIGNAL( replace() ), this, SLOT( slot_simple_replace() ) );
+
+ _balance3 = new JackMix::GUI::Knob( _balance_value3, -1, 1, 2, 0.1, this, "%1" );
+ _layout->addWidget( _balance3, 0,2,1,1 );
+ _layout->setRowStretch( 0, 255 );
+ connect( _balance3, SIGNAL( valueChanged( double ) ), this, SLOT( balance3( double ) ) );
+ connect( _balance3, SIGNAL( select() ), this, SLOT( slot_simple_select() ) );
+ connect( _balance3, SIGNAL( replace() ), this, SLOT( slot_simple_replace() ) );
+
+ _volume_widget = new JackMix::GUI::Slider( amptodb( _volume_value ), dbmin, dbmax, 1, 3, this );
+ _layout->addWidget( _volume_widget, 1,0,2,3 );
+ _layout->setRowStretch( 1, 255 );
+ connect( _volume_widget, SIGNAL( valueChanged( double ) ), this, SLOT( volume( double ) ) );
+ connect( _volume_widget, SIGNAL( select() ), this, SLOT( slot_simple_select() ) );
+ connect( _volume_widget, SIGNAL( replace() ), this, SLOT( slot_simple_replace() ) );
+
+ QAction *toggle = new QAction( "Toggle Selection", this );
+ connect( toggle, SIGNAL( triggered() ), this, SLOT( slot_simple_select() ) );
+ menu()->addAction( toggle );
+
+ QAction *replace = new QAction( "&Replace", this );
+ connect( replace, SIGNAL( triggered() ), this, SLOT( slot_simple_replace() ) );
+ menu()->addAction( replace );
+
+ QAction *explode = new QAction( "&Explode", this );
+ explode->setShortcut(Qt::CTRL+Qt::Key_E);
+ this->addAction(explode);
+ connect( explode, SIGNAL( triggered() ), this, SLOT( slot_simple_explode() ) );
+ menu()->addAction( explode );
+
+ QAction *assign = new QAction( "&Assign MIDI Parameter", this );
+ connect( assign, SIGNAL( triggered() ), this, SLOT( slot_assign_midi_parameters() ) );
+ menu()->addAction( assign );
+
+
+ midi_params.append(0);
+ midi_delegates.append(_volume_widget);
+ midi_params.append(0);
+ midi_delegates.append(_balance3);
+ midi_delegates.append(_balance2);
+ midi_delegates.append(_balance);
+
+
+
+
+
+ // Now construct the parameter setting menu
+ _cca = new JackMix::GUI::MidiControlChannelAssigner(QString("Set MIDI control parameter"),
+ "(" + _in[0] + "/" + _in[1] + "/" + _in[2] +
+ ") → (" + _out[0] + "/" + _out[1] + ")",
+ QStringList() << "Gain" << "Pan",
+ midi_params,
+ this
+ );
+ connect( _cca, SIGNAL(assignParameters(QList)), this, SLOT(update_midi_parameters(QList)) );
+
+}
+Threeinput2outputElement::~Threeinput2outputElement() {
+}
+
+void Threeinput2outputElement::balance( double n ) {
+
+ _balance_value = n;
+ calculateVolumes();
+ _balance->value( n );
+ emit valueChanged( this, QString( "balance" ) );
+}
+void Threeinput2outputElement::volume( double n ) {
+
+ _volume_value = n;
+ calculateVolumes();
+ _volume_widget->value( n );
+ emit valueChanged( this, QString( "volume" ) );
+}
+
+void Threeinput2outputElement::calculateVolumes() {
+ double left, right;
+ left = dbtoamp( _volume_value );
+ right = dbtoamp( _volume_value );
+ if ( _balance_value > 0 )
+ left = dbtoamp( _volume_value )*( 1-_balance_value );
+ if ( _balance_value < 0 )
+ right = dbtoamp( _volume_value )*( 1+_balance_value );
+ backend()->setVolume( _in[0], _out[0], left );
+ backend()->setVolume( _in[0], _out[1], right );
+}
+void Threeinput2outputElement::balance2( double n ) {
+
+ _balance_value2 = n;
+ calculateVolumes2();
+ _balance2->value( n );
+ emit valueChanged( this, QString( "balance2" ) );
+}
+
+void Threeinput2outputElement::calculateVolumes2() {
+ double left2, right2;
+ left2 = dbtoamp( _volume_value2 );
+ right2 = dbtoamp( _volume_value2 );
+ if ( _balance_value2 > 0 )
+ left2 = dbtoamp( _volume_value2 )*( 1-_balance_value2 );
+ if ( _balance_value2 < 0 )
+ right2 = dbtoamp( _volume_value2 )*( 1+_balance_value2 );
+ backend()->setVolume( _in[1], _out[0], left2 );
+ backend()->setVolume( _in[1], _out[1], right2 );
+}
+
+void Threeinput2outputElement::balance3( double n ) {
+
+ _balance_value3 = n;
+ calculateVolumes();
+ _balance3->value( n );
+ emit valueChanged( this, QString( "balance3" ) );
+}
+
+void Threeinput2outputElement::calculateVolumes3() {
+ double left3, right3;
+ left3 = dbtoamp( _volume_value3 );
+ right3 = dbtoamp( _volume_value3 );
+ if ( _balance_value3 > 0 )
+ left3 = dbtoamp( _volume_value3 )*( 1-_balance_value3 );
+ if ( _balance_value < 0 )
+ right3 = dbtoamp( _volume_value3 )*( 1+_balance_value3 );
+ backend()->setVolume( _in[2], _out[0], left3 );
+ backend()->setVolume( _in[2], _out[1], right3 );
+}
diff --git a/libelements/stereo_elements.h b/libelements/stereo_elements.h
index ba30e28..798e48c 100644
--- a/libelements/stereo_elements.h
+++ b/libelements/stereo_elements.h
@@ -40,7 +40,7 @@ namespace MixerElements {
class Mono2StereoElement;
class Stereo2StereoElement;
-
+class Mono2StereoElement2;
/**
* A MonotoStereo control.
*/
@@ -101,6 +101,59 @@ private slots:
JackMix::GUI::Slider *_volume_widget, *_balance_widget;
};
+
+class Mono2StereoElement2 : public JackMix::MixingMatrix::Element , public dB2VolCalc
+{
+Q_OBJECT
+Q_PROPERTY( double volume READ volume WRITE volume );
+Q_PROPERTY( double panorama READ panorama WRITE set_panorama );
+//Q_PROPERTY( double volume2 READ volume2 WRITE volume2 );
+Q_PROPERTY( double panorama2 READ panorama2 WRITE set_panorama2 );
+//Q_PROPERTY( double volume3 READ volume3 WRITE volume3 );
+Q_PROPERTY( double panorama3 READ panorama3 WRITE set_panorama3 );
+public:
+ Mono2StereoElement2( QStringList, QStringList, MixingMatrix::Widget*, const char* =0 );
+ ~Mono2StereoElement2();
+
+ int inchannels() const { return 3; }
+ int outchannels() const { return 2; }
+
+
+ double volume() const { return _volume_value; }
+ double panorama() const { return _balance_value; }
+ //double volume2() const { return _volume_value2; }
+ double panorama2() const { return _balance_value2; }
+ //double volume3() const { return _volume_value3; }
+ double panorama3() const { return _balance_value3; }
+
+signals:
+ void volume_changed( double );
+ void panorama_changed( double );
+ void volume_changed2( double );
+ void panorama_changed2( double );
+ void volume_changed3( double );
+ void panorama_changed3( double );
+public slots:
+ void set_panorama( double n ) { balance( n ); }
+ void balance( double );
+ void volume( double );
+ void set_panorama2( double n ) { balance2( n ); }
+ void balance2( double );
+ //void volume2( double );
+ void set_panorama3( double n ) { balance3( n ); }
+ void balance3( double );
+ //void volume3( double );
+private slots:
+ void calculateVolumes();
+ void calculateVolumes2();
+ void calculateVolumes3();
+private:
+ QString _inchannel1, _inchannel2, _inchannel3, _outchannel1, _outchannel2;
+ JackMix::GUI::Knob *_balance, *_balance2, *_balance3;
+ JackMix::GUI::Slider *_volume_widget;
+ double _balance_value, _volume_value, _balance_value2, _volume_value2, _balance_value3, _volume_value3;
+};
+
void init_stereo_elements();
}; // MixerElements
diff --git a/libgui/knob.cpp b/libgui/knob.cpp
index c72f9e2..ca6b08b 100644
--- a/libgui/knob.cpp
+++ b/libgui/knob.cpp
@@ -109,16 +109,21 @@ void Knob::paintEvent( QPaintEvent* ) {
p.setPen( Qt::NoPen );
{
QRadialGradient grad( QPointF( 0,0 ), radius, QPointF( 0, radius*0.7 ) );
- grad.setColorAt( 0, _indicator );
- grad.setColorAt( 1, _indicator.darker() );
+ //grad.setColorAt( 0, _indicator );
+ //grad.setColorAt( 1, _indicator.darker() );
+ grad.setColorAt( 0, Qt::darkGray );
+ //grad.setColorAt( 1, Qt::black );
+
grad.setSpread( QGradient::PadSpread );
p.setBrush( grad );
p.drawEllipse( QRectF( -radius*0.8, -radius*0.8, radius*1.6, radius*1.6 ) );
}
{
QRadialGradient grad( QPointF( 0,0 ), radius*0.60, QPointF( 0, radius*0.20 ) );
- grad.setColorAt( 1, palette().color( QPalette::Highlight ) );
- grad.setColorAt( 0, palette().color( QPalette::Highlight ).lighter() );
+ //grad.setColorAt( 1, palette().color( QPalette::Light ) );
+ //grad.setColorAt( 0, palette().color( QPalette::Light ).lighter() );
+ grad.setColorAt( 1, Qt::black );
+ grad.setColorAt( 0, Qt::gray );
grad.setSpread( QGradient::PadSpread );
p.setBrush( grad );
p.drawEllipse( QRectF( -radius*0.65, -radius*0.65, radius*1.3, radius*1.3 ) );
diff --git a/libgui/midicontrolchannelassigner.cpp b/libgui/midicontrolchannelassigner.cpp
index 35380ca..9cec5db 100644
--- a/libgui/midicontrolchannelassigner.cpp
+++ b/libgui/midicontrolchannelassigner.cpp
@@ -101,8 +101,10 @@ void MidiControlChannelAssigner::commitnquit() {
void MidiControlChannelAssigner::updateParameters(QList p) {
// The MIDI parameters of the parent widget might have changed since construction
+ qDebug() << "p.size() is :" << p.size();
if (p.size() != _num_controls)
qDebug() << "Update of MIDI dialogue data from wrong-size vector!";
+
for (int i = 0; i < _num_controls; i++ ) {
int ival;
diff --git a/libmatrix/mixingmatrix.cpp b/libmatrix/mixingmatrix.cpp
index fc4722e..444f035 100644
--- a/libmatrix/mixingmatrix.cpp
+++ b/libmatrix/mixingmatrix.cpp
@@ -43,6 +43,10 @@
#include
#include
+#include
+#include
+#include
+
namespace JackMix {
namespace MixingMatrix {
@@ -81,30 +85,34 @@ void Widget::addElement( Element* n ) {
connect( n, SIGNAL( explode( Element* ) ), this, SLOT( explode( Element* ) ) );
resizeEvent( 0 );
}
+
void Widget::removeElement( Element* n ) {
//qDebug("Removing element");
_elements.removeAll( n );
}
void Widget::replace( Element* n ) {
- //qDebug( "Widget::replace( Element* %p )", n );
- //qDebug( "This Element has %i selected neighbors.", n->neighbors() );
- //qDebug( " and %i selected followers.", n->followers( n->neighbors() ) );
+ qDebug( "Widget::replace --- ( Element* %p )", n );
+ qDebug( "Widget::replace --- This Element has %i selected neighbors.", n->neighbors() );
+ qDebug( "Widget::replace --- and %i selected followers.", n->followers( n->neighbors() ) );
QStringList in, out;
in = n->neighborsList();
- //qDebug( "Selected ins = %s", qPrintable( in.join( "," ) ) );
+ qDebug( "Widget::replace --- Selected ins = %s", qPrintable( in.join( "," ) ) );
out = n->followersList();
- //qDebug( "Selected outs = %s", qPrintable( out.join( "," ) ) );
+ qDebug( "Widget::replace --- Selected outs = %s", qPrintable( out.join( "," ) ) );
for ( QStringList::ConstIterator it=out.begin(); it!=out.end(); ++it ) {
for ( QStringList::ConstIterator jt=in.begin(); jt!=in.end(); ++jt ) {
Element* tmp = getResponsible( ( *jt ),( *it ) );
- //qDebug( "About to delete %p", tmp );
+ qDebug( "Widget::replace --- About to delete %p", tmp );
if ( tmp )
tmp->deleteLater();
}
}
+
createControl( in, out );
+
QTimer::singleShot( 1, this, SLOT( autoFill() ) );
+
}
void Widget::explode( Element* n ) {
@@ -126,6 +134,7 @@ bool Widget::createControl( QStringList inchannels, QStringList outchannels ) {
//qDebug( "Widget::createControl( QStringList '%s', QStringList '%s', %s)", qPrintable( inchannels.join( "," ) ), qPrintable( outchannels.join( "," ) ) );
QStringList controls = Global::the()->canCreate( inchannels.size(), outchannels.size() );
+ //QStringList controls = Global::the()->canCreate( 1, 2 );
if ( ! controls.isEmpty() ) {
//qDebug( "Found %s to control [%i,%i] channels", controls.front().toStdString().c_str(), inchannels.size(), outchannels.size() );
return Global::the()->create( controls.front(), inchannels, outchannels, this );
@@ -141,10 +150,10 @@ void Widget::autoFill() {
//qDebug( "Doing the Autofill-boogie..." );
for ( QStringList::Iterator init=_inchannels.begin(); init!=_inchannels.end(); ++init )
for ( QStringList::Iterator outit=_outchannels.begin(); outit!=_outchannels.end(); ++outit ) {
- if ( !getResponsible( *init, *outit ) ) // {
+ if ( !getResponsible( *init, *outit ) ) {
//qDebug( "...together with (%s|%s)", qPrintable( *init ), qPrintable( *outit ) );
createControl( QStringList()<<*init, QStringList()<<*outit );
- // }
+ }
//else
//qDebug( " (%s|%s) is allready occupied. :(", qPrintable( *init ), qPrintable( *outit ) );
}
@@ -163,7 +172,6 @@ void Widget::autoFill() {
//qDebug() << " No responsible element found, creating a new one";
createControl( QStringList()<<*init, QStringList()<<*init );
}
-
}
}
resizeEvent( 0 );
@@ -263,12 +271,35 @@ QSize Widget::smallestElement() const {
return QSize( w,h );
}
-QString Widget::nextIn( QString n ) const {
+
+QString Widget::previousIn( QString n) const {
//qDebug() << "Widget::nextIn(" << n << ")";
if ( n.isNull() )
return 0;
- int i = _inchannels.indexOf( n ) + 1;
+ int i = _inchannels.indexOf( n ) - 1;
//qDebug() << " i=" << i;
+ if ( i > -1)
+ return _inchannels.at( i );
+ return 0;
+}
+
+QString Widget::previousOut( QString n ) const {
+ if ( n.isNull() )
+ return 0;
+ int i = _outchannels.indexOf( n ) - 1;
+ if ( i > -1 )
+ return _outchannels.at( i );
+ return 0;
+}
+
+
+
+QString Widget::nextIn( QString n ) const {
+ qDebug() << "Widget::nextIn --- (" << n << ")";
+ if ( n.isNull() )
+ return 0;
+ int i = _inchannels.indexOf( n ) + 1;
+ qDebug() << "Widget::nextIn --- i=" << i;
if ( i < _inchannels.size() )
return _inchannels.at( i );
return 0;
@@ -394,6 +425,8 @@ bool Element::isResponsible( QString in, QString out ) {
return false;
}
+
+
void Element::select( bool n ) {
//qDebug( "MixingMatrix::Element::select( bool %i )", n );
if ( n != _selected ) {
@@ -401,6 +434,7 @@ void Element::select( bool n ) {
_selected = n;
QPalette pal;
if ( _selected ) {
+ //connect(pCheckbox, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(onButtonClicked(QAbstractButton*)));
setFrameShadow( QFrame::Sunken );
pal.setColor( QPalette::Window, pal.color( QPalette::Window ).darker() );
} else {
@@ -415,22 +449,48 @@ void Element::select( bool n ) {
}
}
+
+
int Element::neighbors() const {
- Element* neighbor = _parent->getResponsible( _parent->nextIn( _in[ _in.size()-1 ] ), _out[ 0 ] );
- if ( neighbor && neighbor->isSelected() )
- return neighbor->neighbors()+1;
+ Element* neighbor_r = _parent->getResponsible( _parent->nextIn( _in[ _in.size()-1 ] ), _out[ 0 ] );
+ //Element* neighbor_l = _parent->getResponsible( _parent->previousIn( _in[ _in.size()-1 ] ), _out[ 0 ] );
+ if ( neighbor_r && neighbor_r->isSelected() )
+ return neighbor_r->neighbors()+1;
+ //if ( neighbor_l && neighbor_l->isSelected() )
+ // return neighbor_l->neighbors()-1;
return 0;
}
+
QStringList Element::neighborsList() const {
- //qDebug( "self = [%s]", qPrintable( _in.join( "|" ) ) );
- //qDebug( "neighbor = %s", qPrintable( _parent->nextIn( _in[ _in.size()-1 ] ) ) );
- Element* neighbor = _parent->getResponsible( _parent->nextIn( _in[ _in.size()-1 ] ), _out[ 0 ] );
+ qDebug( "Element::neighborList --- self = [%s]", qPrintable( _in.join( "|" ) ) );
+ qDebug( "Element::neighborList --- neighbor_r = %s", qPrintable( _parent->nextIn( _in[ _in.size()-1 ] ) ) );
+ //qDebug( "neighbor_l = %s", qPrintable( _parent->previousIn( _in[ _in.size()-1 ] ) ) );
+ Element* neighbor_r = _parent->getResponsible( _parent->nextIn( _in[ _in.size()-1 ] ), _out[ 0 ] );
+ //Element* neighbor_l = _parent->getResponsible( _parent->previousIn( _in[ _in.size()-1 ] ), _out[ 0 ] );
QStringList tmp;
- if ( neighbor && neighbor->isSelected() )
- tmp = neighbor->neighborsList();
+ //QString neighbor = qPrintable( _parent->nextIn( _in[ _in.size()-1 ] ) );
+ //if ( neighbor_l && neighbor_l->isSelected()) {
+ // tmp = neighbor_l->neighborsList();
+ // tmp = tmp + _in;
+ //}
+ //qDebug( "Element::neighborList --- _in is %s", qPrintable(_in.join(",")));
+
+ if (neighbor_r && neighbor_r->isSelected())
+ tmp = neighbor_r->neighborsList();
tmp = _in + tmp;
+
+ qDebug( "Element::neighborList --- tmp is %s", qPrintable(tmp.join(",")));
+ qDebug( "Element::neighborList --- _in is %s", qPrintable(_in.join(",")));
+
return tmp;
+ //if ( neighbor_l && neighbor_l->isSelected() )
+ //tmp = neighbor_l->neighborsList();
+
+ //return _in;
}
+
+
+
int Element::followers( int n ) const {
if ( n==0 )
return 0;
@@ -446,7 +506,7 @@ QStringList Element::followersList() const {
QStringList tmp;
if ( follower && follower->isSelected() )
tmp = follower->followersList();
- tmp = _out + tmp;
+ tmp = _out + tmp;
return tmp;
}
@@ -497,6 +557,8 @@ void Element::renamechannels(QString old_name, QString new_name)
if (disp_name) disp_name->setText( QString("%1").arg(new_name) );
}
+
+
ElementFactory::ElementFactory() {
Global::the()->registerFactory( this );
}
@@ -517,20 +579,20 @@ Global* Global::the() {
}
void Global::registerFactory( ElementFactory* n ) {
- //qDebug( "Global::registerFactory( ElementFactory* %p )", n );
+ qDebug( "Global::registerFactory( ElementFactory* %p )", n );
_factories.push_back( n );
}
void Global::unregisterFactory( ElementFactory* n ) {
- //qDebug( "Global::unregisterFactory( ElementFactory* %p )", n );
+ qDebug( "Global::unregisterFactory( ElementFactory* %p )", n );
_factories.removeAll( n );
}
QStringList Global::canCreate( int in, int out ) {
- //qDebug() << "Global::canCreate(" << in << "," << out << ")";
+ qDebug() << "Global::canCreate(" << in << "," << out << ")";
QStringList tmp;
for ( int i=0; i<_factories.size(); i++ )
tmp += _factories[ i ]->canCreate( in, out );
- //qDebug() << " returning" << tmp;
+ qDebug() << " returning" << tmp;
return tmp;
}
diff --git a/libmatrix/mixingmatrix.h b/libmatrix/mixingmatrix.h
index 365d73d..400891e 100644
--- a/libmatrix/mixingmatrix.h
+++ b/libmatrix/mixingmatrix.h
@@ -68,6 +68,8 @@ Q_PROPERTY( Direction direction READ direction WRITE direction )
QStringList inchannels() const { return _inchannels; }
QStringList outchannels() const { return _outchannels; }
+ QString previousIn( QString ) const;
+ QString previousOut( QString ) const;
QString nextIn( QString ) const;
QString nextOut( QString ) const;
@@ -201,6 +203,7 @@ Q_PROPERTY( QString name READ name WRITE name )
/** Allow others to see our controlling midi parameters (but not change them) */
const QList& midiParameters() const;
+
/** Inform the Element the parent's dead so it doesn't try to deregister itself
* on destruction (otherwise there may be a segfault at closedown)
*/