2018-06-12 Fred Gleason <fredg@paravelsystems.com>

* Added a 'card-num' parameter to the 'Meter Enable' ['ME'] command
	in caed(8).
	* Added an 'RDCae::enableMetering()' method.
	* Modified rdairplay(1) to enable metering explicitly.
	* Modified rdcartslots(1) to enable metering explicitly.
	* Modified rdlibrary(1) to enable metering explicitly.
	* Modified rdpanel(1) to enable metering explicitly.
This commit is contained in:
Fred Gleason 2018-06-12 19:00:55 +00:00
parent ea11505dbe
commit bb60b722d1
14 changed files with 168 additions and 41 deletions

View File

@ -17048,3 +17048,11 @@
2018-06-12 Fred Gleason <fredg@paravelsystems.com> 2018-06-12 Fred Gleason <fredg@paravelsystems.com>
* Changed the name of the 'Initial Audio Ports' control to * Changed the name of the 'Initial Audio Ports' control to
'Active Audio Ports' in the 'Configure JACK' dialog in rdadmin(1). 'Active Audio Ports' in the 'Configure JACK' dialog in rdadmin(1).
2018-06-12 Fred Gleason <fredg@paravelsystems.com>
* Added a 'card-num' parameter to the 'Meter Enable' ['ME'] command
in caed(8).
* Added an 'RDCae::enableMetering()' method.
* Modified rdairplay(1) to enable metering explicitly.
* Modified rdcartslots(1) to enable metering explicitly.
* Modified rdlibrary(1) to enable metering explicitly.
* Modified rdpanel(1) to enable metering explicitly.

View File

@ -171,6 +171,9 @@ MainObject::MainObject(QObject *parent,const char *name)
argnum[i]=0; argnum[i]=0;
argptr[i]=0; argptr[i]=0;
auth[i]=false; auth[i]=false;
for(int j=0;j<RD_MAX_CARDS;j++) {
update_meters[j][i]=false;
}
} }
for(int i=0;i<RD_MAX_CARDS;i++) { for(int i=0;i<RD_MAX_CARDS;i++) {
cae_driver[i]=RDStation::None; cae_driver[i]=RDStation::None;
@ -1808,6 +1811,15 @@ void MainObject::DispatchCommand(int ch)
return; return;
} }
meter_port[ch]=port; meter_port[ch]=port;
for(int i=2;i<argnum[ch];i++) {
sscanf(args[ch][i],"%d",&card);
if((card<0)||(card>=RD_MAX_CARDS)) {
EchoArgs(ch,'-');
return;
}
update_meters[card][ch]=true;
}
EchoArgs(ch,'+'); EchoArgs(ch,'+');
SendMeterOutputStatusUpdate(); SendMeterOutputStatusUpdate();
return; return;
@ -1885,6 +1897,7 @@ void MainObject::KillSocket(int ch)
auth[ch]=false; auth[ch]=false;
meter_port[ch]=0; meter_port[ch]=0;
for(int i=0;i<RD_MAX_CARDS;i++) { for(int i=0;i<RD_MAX_CARDS;i++) {
update_meters[i][ch]=false;
for(int j=0;j<RD_MAX_STREAMS;j++) { for(int j=0;j<RD_MAX_STREAMS;j++) {
if(record_owner[i][j]==ch) { if(record_owner[i][j]==ch) {
unsigned len=0; unsigned len=0;
@ -2307,30 +2320,35 @@ void MainObject::FreeMadDecoder(int card,int stream)
void MainObject::SendMeterLevelUpdate(const QString &type,int cardnum, void MainObject::SendMeterLevelUpdate(const QString &type,int cardnum,
int portnum,short levels[]) int portnum,short levels[])
{ {
char msg[1500]; for(int l=0;l<CAE_MAX_CONNECTIONS;l++) {
int n=snprintf(msg,1500,"ML %s %d %d %d %d", if((meter_port[l]>0)&&update_meters[cardnum][l]) {
(const char *)type,cardnum,portnum,levels[0],levels[1]); SendMeterUpdate(QString().sprintf("ML %s %d %d %d %d",
SendMeterUpdate(msg,n); (const char *)type,cardnum,portnum,levels[0],levels[1]),l);
}
}
} }
void MainObject::SendStreamMeterLevelUpdate(int cardnum,int streamnum, void MainObject::SendStreamMeterLevelUpdate(int cardnum,int streamnum,
short levels[]) short levels[])
{ {
char msg[1500]; for(int l=0;l<CAE_MAX_CONNECTIONS;l++) {
int n=snprintf(msg,1500,"MO %d %d %d %d", if((meter_port[l]>0)&&update_meters[cardnum][l]) {
cardnum,streamnum,levels[0],levels[1]); SendMeterUpdate(QString().sprintf("MO %d %d %d %d",
SendMeterUpdate(msg,n); cardnum,streamnum,levels[0],levels[1]),l);
}
}
} }
void MainObject::SendMeterPositionUpdate(int cardnum,unsigned pos[]) void MainObject::SendMeterPositionUpdate(int cardnum,unsigned pos[])
{ {
char msg[1500]; for(unsigned k=0;k<RD_MAX_STREAMS;k++) {
int n; for(int l=0;l<CAE_MAX_CONNECTIONS;l++) {
for(unsigned i=0;i<RD_MAX_STREAMS;i++) { if((meter_port[l]>0)&&update_meters[cardnum][l]) {
n=snprintf(msg,1500,"MP %d %d %d",cardnum,i,pos[i]); SendMeterUpdate(QString().sprintf("MP %d %d %d",cardnum,k,pos[k]),l);
SendMeterUpdate(msg,n); }
}
} }
} }
@ -2341,7 +2359,12 @@ void MainObject::SendMeterOutputStatusUpdate()
if(cae_driver[i]!=RDStation::None) { if(cae_driver[i]!=RDStation::None) {
for(unsigned j=0;j<RD_MAX_PORTS;j++) { for(unsigned j=0;j<RD_MAX_PORTS;j++) {
for(unsigned k=0;k<RD_MAX_STREAMS;k++) { for(unsigned k=0;k<RD_MAX_STREAMS;k++) {
SendMeterOutputStatusUpdate(i,j,k); for(unsigned l=0;l<CAE_MAX_CONNECTIONS;l++) {
if((meter_port[l]>0)&&update_meters[i][l]) {
SendMeterUpdate(QString().sprintf("MS %d %d %d %d",i,j,k,
output_status_flag[i][j][k]),l);
}
}
} }
} }
} }
@ -2351,23 +2374,20 @@ void MainObject::SendMeterOutputStatusUpdate()
void MainObject::SendMeterOutputStatusUpdate(int card,int port,int stream) void MainObject::SendMeterOutputStatusUpdate(int card,int port,int stream)
{ {
char msg[1500]; for(unsigned l=0;l<CAE_MAX_CONNECTIONS;l++) {
int n; if((meter_port[l]>0)&&update_meters[card][l]) {
n=snprintf(msg,1500,"MS %d %d %d %d",card,port,stream, SendMeterUpdate(QString().sprintf("MS %d %d %d %d",card,port,stream,
output_status_flag[card][port][stream]); output_status_flag[card][port][stream]),l);
SendMeterUpdate(msg,n);
}
void MainObject::SendMeterUpdate(const char *msg,unsigned len)
{
for(unsigned i=0;i<CAE_MAX_CONNECTIONS;i++) {
if(meter_port[i]>0) {
meter_socket->writeBlock(msg,len,socket[i]->peerAddress(),meter_port[i]);
} }
} }
} }
void MainObject::SendMeterUpdate(const QString &msg,int conn_id)
{
meter_socket->writeBlock(msg,msg.length(),socket[conn_id]->peerAddress(),
meter_port[conn_id]);
}
int main(int argc,char *argv[]) int main(int argc,char *argv[])
{ {

View File

@ -142,7 +142,7 @@ class MainObject : public QObject
void SendMeterPositionUpdate(int cardnum,unsigned pos[]); void SendMeterPositionUpdate(int cardnum,unsigned pos[]);
void SendMeterOutputStatusUpdate(); void SendMeterOutputStatusUpdate();
void SendMeterOutputStatusUpdate(int card,int port,int stream); void SendMeterOutputStatusUpdate(int card,int port,int stream);
void SendMeterUpdate(const char *msg,unsigned len); void SendMeterUpdate(const QString &msg,int conn_id);
bool debug; bool debug;
unsigned system_sample_rate; unsigned system_sample_rate;
Q_INT16 tcp_port; Q_INT16 tcp_port;
@ -165,6 +165,7 @@ class MainObject : public QObject
bool play_pitch[RD_MAX_CARDS][RD_MAX_STREAMS]; bool play_pitch[RD_MAX_CARDS][RD_MAX_STREAMS];
bool port_status[RD_MAX_CARDS][RD_MAX_PORTS]; bool port_status[RD_MAX_CARDS][RD_MAX_PORTS];
bool output_status_flag[RD_MAX_CARDS][RD_MAX_PORTS][RD_MAX_STREAMS]; bool output_status_flag[RD_MAX_CARDS][RD_MAX_PORTS][RD_MAX_STREAMS];
bool update_meters[RD_MAX_CARDS][CAE_MAX_CONNECTIONS];
struct { struct {
int card; int card;
int stream; int stream;

View File

@ -1459,11 +1459,14 @@
<sect2> <sect2>
<title><command>Meter Enable</command></title> <title><command>Meter Enable</command></title>
<para> <para>
Set UDP port to whcih to send meter update messages. Set UDP port to which to send meter update messages for the specified
card(s).
</para> </para>
<para> <para>
<userinput>ME <userinput>ME
<replaceable>udp-port</replaceable>!</userinput> <replaceable>udp-port</replaceable>
<replaceable>card0</replaceable>
<replaceable>..</replaceable>!</userinput>
</para> </para>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
@ -1476,6 +1479,16 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<replaceable>card0</replaceable>
</term>
<listitem>
<para>
Audio card number for which to send updates.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</sect2> </sect2>
</sect1> </sect1>

View File

@ -118,10 +118,30 @@ void RDCae::connectHost()
SendCommand(QString().sprintf("IS %d %d!",i,j)); SendCommand(QString().sprintf("IS %d %d!",i,j));
} }
} }
SendCommand(QString().sprintf("ME %u!",cae_meter_socket->port()));
} }
} }
void RDCae::enableMetering(std::vector<int> *cards)
{
QString cmd=QString().sprintf("ME %u",cae_meter_socket->port());
for(unsigned i=0;i<cards->size();i++) {
if(cards->at(i)>=0) {
bool found=false;
for(unsigned j=0;j<i;j++) {
if(cards->at(i)==cards->at(j)) {
found=true;
}
}
if(!found) {
cmd+=QString().sprintf(" %d",cards->at(i));
}
}
}
SendCommand(cmd+"!");
}
bool RDCae::loadPlay(int card,QString name,int *stream,int *handle) bool RDCae::loadPlay(int card,QString name,int *stream,int *handle)
{ {
int count=0; int count=0;

View File

@ -45,6 +45,7 @@ class RDCae : public QObject
RDCae(RDStation *station,RDConfig *config,QObject *parent=0); RDCae(RDStation *station,RDConfig *config,QObject *parent=0);
~RDCae(); ~RDCae();
void connectHost(); void connectHost();
void enableMetering(std::vector<int> *cards);
bool loadPlay(int card,QString name,int *stream,int *handle); bool loadPlay(int card,QString name,int *stream,int *handle);
void unloadPlay(int handle); void unloadPlay(int handle);
void positionPlay(int handle,int pos); void positionPlay(int handle,int pos);
@ -127,4 +128,4 @@ class RDCae : public QObject
}; };
#endif #endif // RDCAE_H

View File

@ -304,6 +304,8 @@ MainWidget::MainWidget(QWidget *parent)
// //
// CAE Connection // CAE Connection
// //
connect(rda->cae(),SIGNAL(isConnected(bool)),
this,SLOT(caeConnectedData(bool)));
rda->cae()->connectHost(); rda->cae()->connectHost();
// //
@ -315,7 +317,7 @@ MainWidget::MainWidget(QWidget *parent)
// //
// RIPC Connection // RIPC Connection
// //
connect(rda->ripc(),SIGNAL(connected(bool)),this,SLOT(ripcConnected(bool))); connect(rda->ripc(),SIGNAL(connected(bool)),this,SLOT(ripcConnectedData(bool)));
connect(rda,SIGNAL(userChanged()),this,SLOT(userData())); connect(rda,SIGNAL(userChanged()),this,SLOT(userData()));
connect(rda->ripc(),SIGNAL(rmlReceived(RDMacro *)), connect(rda->ripc(),SIGNAL(rmlReceived(RDMacro *)),
this,SLOT(rmlReceivedData(RDMacro *))); this,SLOT(rmlReceivedData(RDMacro *)));
@ -914,7 +916,24 @@ QSizePolicy MainWidget::sizePolicy() const
} }
void MainWidget::ripcConnected(bool state) void MainWidget::caeConnectedData(bool state)
{
std::vector<int> cards;
cards.push_back(rda->airplayConf()->card(RDAirPlayConf::MainLog1Channel));
cards.push_back(rda->airplayConf()->card(RDAirPlayConf::MainLog2Channel));
cards.push_back(rda->airplayConf()->card(RDAirPlayConf::AuxLog1Channel));
cards.push_back(rda->airplayConf()->card(RDAirPlayConf::AuxLog2Channel));
cards.push_back(rda->airplayConf()->card(RDAirPlayConf::SoundPanel1Channel));
cards.push_back(rda->airplayConf()->card(RDAirPlayConf::SoundPanel2Channel));
cards.push_back(rda->airplayConf()->card(RDAirPlayConf::SoundPanel3Channel));
cards.push_back(rda->airplayConf()->card(RDAirPlayConf::SoundPanel4Channel));
cards.push_back(rda->airplayConf()->card(RDAirPlayConf::SoundPanel5Channel));
rda->cae()->enableMetering(&cards);
}
void MainWidget::ripcConnectedData(bool state)
{ {
QString logname; QString logname;
QHostAddress addr; QHostAddress addr;

View File

@ -98,7 +98,8 @@ class MainWidget : public QWidget
private slots: private slots:
void logLine(RDConfig::LogPriority prio,const QString &msg); void logLine(RDConfig::LogPriority prio,const QString &msg);
void ripcConnected(bool state); void caeConnectedData(bool state);
void ripcConnectedData(bool state);
void rmlReceivedData(RDMacro *rml); void rmlReceivedData(RDMacro *rml);
void gpiStateChangedData(int matrix,int line,bool state); void gpiStateChangedData(int matrix,int line,bool state);
void logChannelStartedData(int id,int mport,int card,int port); void logChannelStartedData(int id,int mport,int card,int port);

View File

@ -37,6 +37,7 @@
#include <rdapplication.h> #include <rdapplication.h>
#include <rdcheck_daemons.h> #include <rdcheck_daemons.h>
#include <rddbheartbeat.h> #include <rddbheartbeat.h>
#include <rdescape_string.h>
#include "rdcartslots.h" #include "rdcartslots.h"
@ -92,6 +93,8 @@ MainWidget::MainWidget(QWidget *parent)
// //
// CAE Connection // CAE Connection
// //
connect(rda->cae(),SIGNAL(isConnected(bool)),
this,SLOT(caeConnectedData(bool)));
rda->cae()->connectHost(); rda->cae()->connectHost();
// //
@ -166,6 +169,22 @@ QSize MainWidget::sizeHint() const
} }
void MainWidget::caeConnectedData(bool state)
{
std::vector<int> cards;
QString sql=QString("select CARD from CARTSLOTS where ")+
"STATION_NAME=\""+RDEscapeString(rda->config()->stationName())+"\"";
RDSqlQuery *q=new RDSqlQuery(sql);
while(q->next()) {
cards.push_back(q->value(0).toInt());
}
delete q;
rda->cae()->enableMetering(&cards);
}
void MainWidget::rmlReceivedData(RDMacro *rml) void MainWidget::rmlReceivedData(RDMacro *rml)
{ {
RunLocalMacros(rml); RunLocalMacros(rml);

View File

@ -56,6 +56,7 @@ class MainWidget : public QWidget
QSizePolicy sizePolicy() const; QSizePolicy sizePolicy() const;
private slots: private slots:
void caeConnectedData(bool state);
void userData(); void userData();
void rmlReceivedData(RDMacro *rml); void rmlReceivedData(RDMacro *rml);
@ -66,12 +67,6 @@ class MainWidget : public QWidget
private: private:
void RunLocalMacros(RDMacro *rml); void RunLocalMacros(RDMacro *rml);
void SetCaption(); void SetCaption();
// RDConfig *panel_config;
// RDCae *panel_cae;
// RDRipc *panel_ripc;
// RDUser *panel_user;
// RDStation *panel_station;
// RDSystem *panel_system;
RDEventPlayer *panel_player; RDEventPlayer *panel_player;
QPixmap *lib_rivendell_map; QPixmap *lib_rivendell_map;
QString panel_filter; QString panel_filter;

View File

@ -190,6 +190,8 @@ MainWidget::MainWidget(QWidget *parent)
// //
// CAE Connection // CAE Connection
// //
connect(rda->cae(),SIGNAL(isConnected(bool)),
this,SLOT(caeConnectedData(bool)));
rda->cae()->connectHost(); rda->cae()->connectHost();
// //
@ -483,6 +485,17 @@ QSizePolicy MainWidget::sizePolicy() const
} }
void MainWidget::caeConnectedData(bool state)
{
if(state) {
std::vector<int> cards;
cards.push_back(rda->libraryConf()->inputCard());
cards.push_back(rda->libraryConf()->outputCard());
rda->cae()->enableMetering(&cards);
}
}
void MainWidget::userData() void MainWidget::userData()
{ {
QString sql; QString sql;

View File

@ -70,6 +70,7 @@ class MainWidget : public QWidget
QSizePolicy sizePolicy() const; QSizePolicy sizePolicy() const;
private slots: private slots:
void caeConnectedData(bool state);
void userData(); void userData();
void filterChangedData(const QString &str); void filterChangedData(const QString &str);
void searchClickedData(); void searchClickedData();

View File

@ -145,6 +145,8 @@ MainWidget::MainWidget(QWidget *parent)
// //
// CAE Connection // CAE Connection
// //
connect(rda->cae(),SIGNAL(isConnected(bool)),
this,SLOT(caeConnectedData(bool)));
rda->cae()->connectHost(); rda->cae()->connectHost();
// //
@ -342,6 +344,19 @@ QSizePolicy MainWidget::sizePolicy() const
} }
void MainWidget::caeConnectedData(bool state)
{
std::vector<int> cards;
cards.push_back(rda->airplayConf()->card(RDAirPlayConf::SoundPanel1Channel));
cards.push_back(rda->airplayConf()->card(RDAirPlayConf::SoundPanel2Channel));
cards.push_back(rda->airplayConf()->card(RDAirPlayConf::SoundPanel3Channel));
cards.push_back(rda->airplayConf()->card(RDAirPlayConf::SoundPanel4Channel));
cards.push_back(rda->airplayConf()->card(RDAirPlayConf::SoundPanel5Channel));
rda->cae()->enableMetering(&cards);
}
void MainWidget::userData() void MainWidget::userData()
{ {
SetCaption(); SetCaption();

View File

@ -49,6 +49,7 @@ class MainWidget : public QWidget
QSizePolicy sizePolicy() const; QSizePolicy sizePolicy() const;
private slots: private slots:
void caeConnectedData(bool state);
void userData(); void userData();
void masterTimerData(); void masterTimerData();
void meterData(); void meterData();