mirror of
https://github.com/ElvishArtisan/rivendell.git
synced 2025-08-16 08:34:12 +02:00
2023-11-03 Fred Gleason <fredg@paravelsystems.com>
* Added 'RDCoreApplication::ExitInternalError' to the 'RDCoreApplication::ExitCode' enumeration. * Refactored the 'RDCae' class to use the native BSD sockets API instead of 'QTcpSocket'. Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
This commit is contained in:
parent
8bb5b3c9e4
commit
c9953bffe2
@ -24435,3 +24435,8 @@
|
|||||||
Operations Guide.
|
Operations Guide.
|
||||||
2023-10-26 Fred Gleason <fredg@paravelsystems.com>
|
2023-10-26 Fred Gleason <fredg@paravelsystems.com>
|
||||||
* Incremented the package version to 4.1.0int2.
|
* Incremented the package version to 4.1.0int2.
|
||||||
|
2023-11-03 Fred Gleason <fredg@paravelsystems.com>
|
||||||
|
* Added 'RDCoreApplication::ExitInternalError' to the
|
||||||
|
'RDCoreApplication::ExitCode' enumeration.
|
||||||
|
* Refactored the 'RDCae' class to use the native BSD sockets API
|
||||||
|
instead of 'QTcpSocket'.
|
||||||
|
215
lib/rdcae.cpp
215
lib/rdcae.cpp
@ -2,7 +2,7 @@
|
|||||||
//
|
//
|
||||||
// Connection to the Rivendell Core Audio Engine
|
// Connection to the Rivendell Core Audio Engine
|
||||||
//
|
//
|
||||||
// (C) Copyright 2002-2023 Fred Gleason <fredg@paravelsystems.com>
|
// (C) Copyright 2002-2019 Fred Gleason <fredg@paravelsystems.com>
|
||||||
//
|
//
|
||||||
// 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 version 2 as
|
// it under the terms of the GNU General Public License version 2 as
|
||||||
@ -18,30 +18,30 @@
|
|||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/socket.h>
|
#include <netinet/ip.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
|
||||||
#include "rdapplication.h"
|
#include <ctype.h>
|
||||||
#include "rdcae.h"
|
|
||||||
#include "rddb.h"
|
|
||||||
#include "rddebug.h"
|
|
||||||
#include "rdescape_string.h"
|
|
||||||
|
|
||||||
//
|
#include <QStringList>
|
||||||
// Uncomment this to enable latency profiling in the syslog
|
#include <QTimer>
|
||||||
//
|
|
||||||
// #define DEBUG_LATENCY
|
#include <rdapplication.h>
|
||||||
|
#include <rddb.h>
|
||||||
|
#include <rdcae.h>
|
||||||
|
#include <rddebug.h>
|
||||||
|
#include <rdescape_string.h>
|
||||||
|
|
||||||
RDCae::RDCae(RDStation *station,RDConfig *config,QObject *parent)
|
RDCae::RDCae(RDStation *station,RDConfig *config,QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
int flags=-1;
|
int flags=0;
|
||||||
|
|
||||||
cae_station=station;
|
cae_station=station;
|
||||||
cae_config=config;
|
cae_config=config;
|
||||||
@ -50,32 +50,55 @@ RDCae::RDCae(RDStation *station,RDConfig *config,QObject *parent)
|
|||||||
argptr=0;
|
argptr=0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// TCP Connection
|
// Control Connection
|
||||||
//
|
//
|
||||||
if((cae_socket=socket(AF_INET,SOCK_STREAM,0))<0) {
|
if((cae_socket=socket(AF_INET,SOCK_STREAM,0))<0) {
|
||||||
rda->syslog(LOG_WARNING,"unable to allocate TCP socket [%s]",
|
rda->syslog(LOG_ERR,"failed to create socket [%s]",strerror(errno));
|
||||||
strerror(errno));
|
exit(RDCoreApplication::ExitInternalError);
|
||||||
}
|
}
|
||||||
if((flags=fcntl(cae_socket,F_GETFL,NULL))>=0) {
|
if((flags=fcntl(cae_socket,F_GETFL,NULL))<0) {
|
||||||
flags=flags|O_NONBLOCK;
|
rda->syslog(LOG_ERR,"failed to get control socket options [%s]",
|
||||||
if(fcntl(cae_socket,F_SETFL,flags)<0) {
|
strerror(errno));
|
||||||
rda->syslog(LOG_WARNING,"unable to set TCP socket to non-blocking [%s]",
|
exit(RDCoreApplication::ExitInternalError);
|
||||||
strerror(errno));
|
}
|
||||||
}
|
flags=flags|O_NONBLOCK;
|
||||||
|
if(fcntl(cae_socket,F_SETFL,flags)<0) {
|
||||||
|
rda->syslog(LOG_ERR,"failed to set control socket options [%s]",
|
||||||
|
strerror(errno));
|
||||||
|
exit(RDCoreApplication::ExitInternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Meter Connection
|
// Meter Connection
|
||||||
//
|
//
|
||||||
cae_meter_socket=new QUdpSocket(this);
|
if((cae_meter_socket=socket(AF_INET,SOCK_DGRAM,0))<0) {
|
||||||
|
rda->syslog(LOG_ERR,"failed to meter create socket [%s]",strerror(errno));
|
||||||
|
exit(RDCoreApplication::ExitInternalError);
|
||||||
|
}
|
||||||
|
if((flags=fcntl(cae_meter_socket,F_GETFL,NULL))<0) {
|
||||||
|
rda->syslog(LOG_ERR,"failed to get meter socket options [%s]",
|
||||||
|
strerror(errno));
|
||||||
|
exit(RDCoreApplication::ExitInternalError);
|
||||||
|
}
|
||||||
|
flags=flags|O_NONBLOCK;
|
||||||
|
if(fcntl(cae_meter_socket,F_SETFL,flags)<0) {
|
||||||
|
rda->syslog(LOG_ERR,"failed to set meter socket options [%s]",
|
||||||
|
strerror(errno));
|
||||||
|
exit(RDCoreApplication::ExitInternalError);
|
||||||
|
}
|
||||||
cae_meter_base_port=cae_config->meterBasePort();
|
cae_meter_base_port=cae_config->meterBasePort();
|
||||||
cae_meter_port_range=cae_config->meterPortRange();
|
cae_meter_port_range=cae_config->meterPortRange();
|
||||||
if(cae_meter_port_range>999) {
|
if(cae_meter_port_range>999) {
|
||||||
cae_meter_port_range=999;
|
cae_meter_port_range=999;
|
||||||
}
|
}
|
||||||
for(int16_t i=cae_meter_base_port;
|
for(int16_t i=cae_meter_base_port;i<(cae_meter_base_port+cae_meter_port_range);i++) {
|
||||||
i<(cae_meter_base_port+cae_meter_port_range);i++) {
|
struct sockaddr_in sa;
|
||||||
if(cae_meter_socket->bind(QHostAddress(),i)) {
|
memset(&sa,0,sizeof(sa));
|
||||||
|
sa.sin_family=AF_INET;
|
||||||
|
sa.sin_port=htons(i);
|
||||||
|
sa.sin_addr.s_addr=htonl(INADDR_ANY);
|
||||||
|
if(bind(cae_meter_socket,(struct sockaddr *)(&sa),sizeof(sa))==0) {
|
||||||
|
cae_meter_port=i;
|
||||||
i=(cae_meter_base_port+cae_meter_port_range)+1;
|
i=(cae_meter_base_port+cae_meter_port_range)+1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,42 +134,52 @@ RDCae::RDCae(RDStation *station,RDConfig *config,QObject *parent)
|
|||||||
|
|
||||||
|
|
||||||
RDCae::~RDCae() {
|
RDCae::~RDCae() {
|
||||||
close(cae_socket);
|
// delete cae_socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::connectHost()
|
bool RDCae::connectHost(QString *err_msg)
|
||||||
{
|
{
|
||||||
int count=10;
|
int count=10;
|
||||||
QTimer *timer=new QTimer(this);
|
|
||||||
struct sockaddr_in sa;
|
struct sockaddr_in sa;
|
||||||
|
QTimer *timer=new QTimer(this);
|
||||||
|
|
||||||
connect(timer,SIGNAL(timeout()),this,SLOT(readyData()));
|
connect(timer,SIGNAL(timeout()),this,SLOT(readyData()));
|
||||||
timer->start(CAE_POLL_INTERVAL);
|
timer->start(CAE_POLL_INTERVAL);
|
||||||
memset(&sa,0,sizeof(sa));
|
memset(&sa,0,sizeof(sa));
|
||||||
sa.sin_family=AF_INET;
|
sa.sin_family=AF_INET;
|
||||||
sa.sin_port=htons(CAED_TCP_PORT);
|
sa.sin_port=htons(CAED_TCP_PORT);
|
||||||
sa.sin_addr.s_addr=htonl(cae_station->caeAddress(cae_config).toIPv4Address());
|
sa.sin_addr.s_addr=
|
||||||
while((::connect(cae_socket,(struct sockaddr *)(&sa),sizeof(sa))!=0)&&
|
htonl(rda->station()->caeAddress(rda->config()).toIPv4Address());
|
||||||
|
while((::connect(cae_socket,(struct sockaddr *)(&sa),sizeof(sa))<0)&&
|
||||||
(--count>0)) {
|
(--count>0)) {
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
}
|
}
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
if(count>0) {
|
if(count>0) {
|
||||||
SendCommand("PW "+cae_config->password()+"!");
|
SendCommand(QString().sprintf("PW %s!",
|
||||||
|
cae_config->password().toUtf8().constData()));
|
||||||
for(int i=0;i<RD_MAX_CARDS;i++) {
|
for(int i=0;i<RD_MAX_CARDS;i++) {
|
||||||
SendCommand(QString::asprintf("TS %d!",i));
|
SendCommand(QString().sprintf("TS %d!",i));
|
||||||
for(int j=0;j<RD_MAX_PORTS;j++) {
|
for(int j=0;j<RD_MAX_PORTS;j++) {
|
||||||
SendCommand(QString::asprintf("IS %d %d!",i,j));
|
SendCommand(QString().sprintf("IS %d %d!",i,j));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
*err_msg=QString::asprintf("failed to connect to CAE service [%s]",
|
||||||
|
strerror(errno));
|
||||||
|
rda->syslog(LOG_ERR,"%s",err_msg->toUtf8().constData());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*err_msg="ok";
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::enableMetering(QList<int> *cards)
|
void RDCae::enableMetering(QList<int> *cards)
|
||||||
{
|
{
|
||||||
QString cmd=QString::asprintf("ME %u",cae_meter_socket->localPort());
|
QString cmd=QString().sprintf("ME %u",0xFFFF&cae_meter_port);
|
||||||
for(int i=0;i<cards->size();i++) {
|
for(int i=0;i<cards->size();i++) {
|
||||||
if(cards->at(i)>=0) {
|
if(cards->at(i)>=0) {
|
||||||
bool found=false;
|
bool found=false;
|
||||||
@ -156,7 +189,7 @@ void RDCae::enableMetering(QList<int> *cards)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!found) {
|
if(!found) {
|
||||||
cmd+=QString::asprintf(" %d",cards->at(i));
|
cmd+=QString().sprintf(" %d",cards->at(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,13 +199,10 @@ void RDCae::enableMetering(QList<int> *cards)
|
|||||||
|
|
||||||
bool RDCae::loadPlay(int card,QString name,int *stream,int *handle)
|
bool RDCae::loadPlay(int card,QString name,int *stream,int *handle)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_LATENCY
|
|
||||||
rda->syslog(LOG_NOTICE,"RDCae::loadPlay() starts",handle);
|
|
||||||
#endif // DEBUG_LATENCY
|
|
||||||
|
|
||||||
int count=0;
|
int count=0;
|
||||||
|
|
||||||
SendCommand("LP "+QString::asprintf(" %d ",card)+name+"!");
|
SendCommand(QString().sprintf("LP %d %s!",
|
||||||
|
card,name.toUtf8().constData()));
|
||||||
|
|
||||||
//
|
//
|
||||||
// This is really warty, but needed to make the method 'synchronous'
|
// This is really warty, but needed to make the method 'synchronous'
|
||||||
@ -199,54 +229,40 @@ bool RDCae::loadPlay(int card,QString name,int *stream,int *handle)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_LATENCY
|
|
||||||
rda->syslog(LOG_NOTICE,"RDCae::loadPlay(handle=%d) ends",*handle);
|
|
||||||
#endif // DEBUG_LATENCY
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::unloadPlay(int handle)
|
void RDCae::unloadPlay(int handle)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_LATENCY
|
SendCommand(QString().sprintf("UP %d!",handle));
|
||||||
rda->syslog(LOG_NOTICE,"RDCae::unloadPlay(handle=%d) starts",handle);
|
|
||||||
#endif // DEBUG_LATENCY
|
|
||||||
SendCommand(QString::asprintf("UP %d!",handle));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::positionPlay(int handle,int msec)
|
void RDCae::positionPlay(int handle,int pos)
|
||||||
{
|
{
|
||||||
if(msec<0) {
|
if(pos<0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SendCommand(QString::asprintf("PP %d %u!",handle,msec));
|
SendCommand(QString().sprintf("PP %d %u!",handle,pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::play(int handle,unsigned length,int speed,bool pitch)
|
void RDCae::play(int handle,unsigned length,int speed,bool pitch)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_LATENCY
|
|
||||||
rda->syslog(LOG_NOTICE,"RDCae::play(handle=%d) starts",handle);
|
|
||||||
#endif // DEBUG_LATENCY
|
|
||||||
|
|
||||||
int pitch_state=0;
|
int pitch_state=0;
|
||||||
|
|
||||||
if(pitch) {
|
if(pitch) {
|
||||||
pitch_state=1;
|
pitch_state=1;
|
||||||
}
|
}
|
||||||
SendCommand(QString::asprintf("PY %d %u %d %d!",
|
SendCommand(QString().sprintf("PY %d %u %d %d!",
|
||||||
handle,length,speed,pitch_state));
|
handle,length,speed,pitch_state));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::stopPlay(int handle)
|
void RDCae::stopPlay(int handle)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_LATENCY
|
SendCommand(QString().sprintf("SP %d!",handle));
|
||||||
rda->syslog(LOG_NOTICE,"RDCae::stopPlay(handle=%d) starts",handle);
|
|
||||||
#endif // DEBUG_LATENCY
|
|
||||||
SendCommand(QString::asprintf("SP %d!",handle));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -255,48 +271,47 @@ void RDCae::loadRecord(int card,int stream,QString name,
|
|||||||
int bit_rate)
|
int bit_rate)
|
||||||
{
|
{
|
||||||
// printf("RDCae::loadRecord(%d,%d,%s,%d,%d,%d,%d)\n",
|
// printf("RDCae::loadRecord(%d,%d,%s,%d,%d,%d,%d)\n",
|
||||||
// card,stream,(const char *)name,coding,chan,samp_rate,bit_rate);
|
// card,stream,(const char *)name,coding,chan,samp_rate,bit_rate);
|
||||||
SendCommand(QString::asprintf("LR %d %d %d %d %d %d %s!",
|
SendCommand(QString().sprintf("LR %d %d %d %d %d %d %s!",
|
||||||
card,stream,(int)coding,chan,samp_rate,
|
card,stream,(int)coding,chan,samp_rate,
|
||||||
bit_rate,name.toUtf8().constData()));
|
bit_rate,name.toUtf8().constData()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::unloadRecord(int card,int stream)
|
void RDCae::unloadRecord(int card,int stream)
|
||||||
|
|
||||||
{
|
{
|
||||||
SendCommand(QString::asprintf("UR %d %d!",card,stream));
|
SendCommand(QString().sprintf("UR %d %d!",card,stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::record(int card,int stream,unsigned length,int threshold)
|
void RDCae::record(int card,int stream,unsigned length,int threshold)
|
||||||
{
|
{
|
||||||
SendCommand(QString::asprintf("RD %d %d %u %d!",
|
SendCommand(QString().sprintf("RD %d %d %u %d!",
|
||||||
card,stream,length,threshold));
|
card,stream,length,threshold));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::stopRecord(int card,int stream)
|
void RDCae::stopRecord(int card,int stream)
|
||||||
{
|
{
|
||||||
SendCommand(QString::asprintf("SR %d %d!",card,stream));
|
SendCommand(QString().sprintf("SR %d %d!",card,stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::setClockSource(int card,RDCae::ClockSource src)
|
void RDCae::setClockSource(int card,RDCae::ClockSource src)
|
||||||
{
|
{
|
||||||
SendCommand(QString::asprintf("CS %d %d!",card,src));
|
SendCommand(QString().sprintf("CS %d %d!",card,src));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::setInputVolume(int card,int stream,int level)
|
void RDCae::setInputVolume(int card,int stream,int level)
|
||||||
{
|
{
|
||||||
SendCommand(QString::asprintf("IV %d %d %d!",card,stream,level));
|
SendCommand(QString().sprintf("IV %d %d %d!",card,stream,level));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::setOutputVolume(int card,int stream,int port,int level)
|
void RDCae::setOutputVolume(int card,int stream,int port,int level)
|
||||||
{
|
{
|
||||||
SendCommand(QString::asprintf("OV %d %d %d %d!",card,stream,port,level));
|
SendCommand(QString().sprintf("OV %d %d %d %d!",card,stream,port,level));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -308,44 +323,44 @@ void RDCae::setOutputPort(int card,int stream,int port)
|
|||||||
|
|
||||||
void RDCae::fadeOutputVolume(int card,int stream,int port,int level,int length)
|
void RDCae::fadeOutputVolume(int card,int stream,int port,int level,int length)
|
||||||
{
|
{
|
||||||
SendCommand(QString::asprintf("FV %d %d %d %d %d!",
|
SendCommand(QString().sprintf("FV %d %d %d %d %d!",
|
||||||
card,stream,port,level,length));
|
card,stream,port,level,length));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::setInputLevel(int card,int port,int level)
|
void RDCae::setInputLevel(int card,int port,int level)
|
||||||
{
|
{
|
||||||
SendCommand(QString::asprintf("IL %d %d %d!",card,port,level));
|
SendCommand(QString().sprintf("IL %d %d %d!",card,port,level));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::setOutputLevel(int card,int port,int level)
|
void RDCae::setOutputLevel(int card,int port,int level)
|
||||||
{
|
{
|
||||||
SendCommand(QString::asprintf("OL %d %d %d!",card,port,level));
|
SendCommand(QString().sprintf("OL %d %d %d!",card,port,level));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::setInputMode(int card,int stream,RDCae::ChannelMode mode)
|
void RDCae::setInputMode(int card,int stream,RDCae::ChannelMode mode)
|
||||||
{
|
{
|
||||||
SendCommand(QString::asprintf("IM %d %d %d!",card,stream,mode));
|
SendCommand(QString().sprintf("IM %d %d %d!",card,stream,mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::setOutputMode(int card,int stream,RDCae::ChannelMode mode)
|
void RDCae::setOutputMode(int card,int stream,RDCae::ChannelMode mode)
|
||||||
{
|
{
|
||||||
SendCommand(QString::asprintf("OM %d %d %d!",card,stream,mode));
|
SendCommand(QString().sprintf("OM %d %d %d!",card,stream,mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::setInputVOXLevel(int card,int stream,int level)
|
void RDCae::setInputVOXLevel(int card,int stream,int level)
|
||||||
{
|
{
|
||||||
SendCommand(QString::asprintf("IX %d %d %d!",card,stream,level));
|
SendCommand(QString().sprintf("IX %d %d %d!",card,stream,level));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RDCae::setInputType(int card,int port,RDCae::SourceType type)
|
void RDCae::setInputType(int card,int port,RDCae::SourceType type)
|
||||||
{
|
{
|
||||||
SendCommand(QString::asprintf("IT %d %d %d!",card,port,type));
|
SendCommand(QString().sprintf("IT %d %d %d!",card,port,type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -401,7 +416,7 @@ unsigned RDCae::playPosition(int handle)
|
|||||||
|
|
||||||
void RDCae::requestTimescale(int card)
|
void RDCae::requestTimescale(int card)
|
||||||
{
|
{
|
||||||
SendCommand(QString::asprintf("TS %d!",card));
|
SendCommand(QString().sprintf("TS %d!",card));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -441,6 +456,7 @@ void RDCae::readyData(int *stream,int *handle,QString name)
|
|||||||
delayed_cmds.clear();
|
delayed_cmds.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// while((c=cae_socket->readBlock(buf,256))>0) {
|
||||||
while((c=read(cae_socket,buf,256))>0) {
|
while((c=read(cae_socket,buf,256))>0) {
|
||||||
buf[c]=0;
|
buf[c]=0;
|
||||||
for(int i=0;i<c;i++) {
|
for(int i=0;i<c;i++) {
|
||||||
@ -460,15 +476,15 @@ void RDCae::readyData(int *stream,int *handle,QString name)
|
|||||||
args[argnum++][argptr]=0;
|
args[argnum++][argptr]=0;
|
||||||
if(stream==NULL) {
|
if(stream==NULL) {
|
||||||
cmd.load(args,argnum,argptr);
|
cmd.load(args,argnum,argptr);
|
||||||
/*
|
|
||||||
// ************************************
|
// ************************************
|
||||||
printf("DISPATCHING: ");
|
// printf("DISPATCHING: ");
|
||||||
for(int z=0;z<cmd.argNum();z++) {
|
// for(int z=0;z<cmd.argNum();z++) {
|
||||||
printf(" %s",cmd.arg(z));
|
// printf(" %s",cmd.arg(z));
|
||||||
}
|
// }
|
||||||
printf("\n");
|
// printf("\n");
|
||||||
// ************************************
|
// ************************************
|
||||||
*/
|
|
||||||
DispatchCommand(&cmd);
|
DispatchCommand(&cmd);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -485,7 +501,7 @@ void RDCae::readyData(int *stream,int *handle,QString name)
|
|||||||
}
|
}
|
||||||
argnum=0;
|
argnum=0;
|
||||||
argptr=0;
|
argptr=0;
|
||||||
if(cae_socket==-1) {
|
if(cae_socket<0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -523,12 +539,7 @@ void RDCae::clockData()
|
|||||||
|
|
||||||
void RDCae::SendCommand(QString cmd)
|
void RDCae::SendCommand(QString cmd)
|
||||||
{
|
{
|
||||||
int len=cmd.toUtf8().length();
|
write(cae_socket,cmd.toUtf8().constData(),cmd.toUtf8().length());
|
||||||
int n=write(cae_socket,cmd.toUtf8(),cmd.toUtf8().length());
|
|
||||||
if(n!=len) {
|
|
||||||
rda->syslog(LOG_WARNING,"RDCae lost %d bytes when sending \"%s\"",
|
|
||||||
len-n,cmd.toUtf8().constData());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -569,10 +580,6 @@ void RDCae::DispatchCommand(RDCmdCache *cmd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_LATENCY
|
|
||||||
rda->syslog(LOG_NOTICE,"RDCae::unloadPlay(handle=%d) ends ",
|
|
||||||
GetHandle(cmd->arg(1)));
|
|
||||||
#endif // DEBUG_LATENCY
|
|
||||||
emit playUnloaded(handle);
|
emit playUnloaded(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -594,20 +601,12 @@ void RDCae::DispatchCommand(RDCmdCache *cmd)
|
|||||||
|
|
||||||
if(!strcmp(cmd->arg(0),"PY")) { // Play
|
if(!strcmp(cmd->arg(0),"PY")) { // Play
|
||||||
if(cmd->arg(4)[0]=='+') {
|
if(cmd->arg(4)[0]=='+') {
|
||||||
#ifdef DEBUG_LATENCY
|
|
||||||
rda->syslog(LOG_NOTICE,"RDCae::play(handle=%d) ends",
|
|
||||||
GetHandle(cmd->arg(1)));
|
|
||||||
#endif // DEBUG_LATENCY
|
|
||||||
emit playing(GetHandle(cmd->arg(1)));
|
emit playing(GetHandle(cmd->arg(1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!strcmp(cmd->arg(0),"SP")) { // Stop Play
|
if(!strcmp(cmd->arg(0),"SP")) { // Stop Play
|
||||||
if(cmd->arg(2)[0]=='+') {
|
if(cmd->arg(2)[0]=='+') {
|
||||||
#ifdef DEBUG_LATENCY
|
|
||||||
rda->syslog(LOG_NOTICE,"RDCae::stopPlay(handle=%d) ends ",
|
|
||||||
GetHandle(cmd->arg(1)));
|
|
||||||
#endif // DEBUG_LATENCY
|
|
||||||
emit playStopped(GetHandle(cmd->arg(1)));
|
emit playStopped(GetHandle(cmd->arg(1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -704,7 +703,7 @@ void RDCae::UpdateMeters()
|
|||||||
int n;
|
int n;
|
||||||
QStringList args;
|
QStringList args;
|
||||||
|
|
||||||
while((n=cae_meter_socket->readDatagram(msg,1500))>0) {
|
while((n=read(cae_meter_socket,msg,1500))>0) {
|
||||||
msg[n]=0;
|
msg[n]=0;
|
||||||
args=QString(msg).split(" ");
|
args=QString(msg).split(" ");
|
||||||
if(args[0]=="ML") {
|
if(args[0]=="ML") {
|
||||||
|
17
lib/rdcae.h
17
lib/rdcae.h
@ -2,7 +2,7 @@
|
|||||||
//
|
//
|
||||||
// Connection to the Rivendell Core Audio Engine
|
// Connection to the Rivendell Core Audio Engine
|
||||||
//
|
//
|
||||||
// (C) Copyright 2002-2023 Fred Gleason <fredg@paravelsystems.com>
|
// (C) Copyright 2002-2016 Fred Gleason <fredg@paravelsystems.com>
|
||||||
//
|
//
|
||||||
// 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 version 2 as
|
// it under the terms of the GNU General Public License version 2 as
|
||||||
@ -21,9 +21,11 @@
|
|||||||
#ifndef RDCAE_H
|
#ifndef RDCAE_H
|
||||||
#define RDCAE_H
|
#define RDCAE_H
|
||||||
|
|
||||||
|
//#include <q3socketdevice.h>
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QUdpSocket>
|
|
||||||
|
|
||||||
#include <rd.h>
|
#include <rd.h>
|
||||||
#include <rdcmd_cache.h>
|
#include <rdcmd_cache.h>
|
||||||
@ -40,11 +42,11 @@ class RDCae : public QObject
|
|||||||
enum AudioCoding {Pcm16=0,MpegL1=1,MpegL2=2,MpegL3=3,Pcm24=4};
|
enum AudioCoding {Pcm16=0,MpegL1=1,MpegL2=2,MpegL3=3,Pcm24=4};
|
||||||
RDCae(RDStation *station,RDConfig *config,QObject *parent=0);
|
RDCae(RDStation *station,RDConfig *config,QObject *parent=0);
|
||||||
~RDCae();
|
~RDCae();
|
||||||
void connectHost();
|
bool connectHost(QString *err_msg);
|
||||||
void enableMetering(QList<int> *cards);
|
void enableMetering(QList<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 msec);
|
void positionPlay(int handle,int pos);
|
||||||
void play(int handle,unsigned length,int speed,bool pitch);
|
void play(int handle,unsigned length,int speed,bool pitch);
|
||||||
void stopPlay(int handle);
|
void stopPlay(int handle);
|
||||||
void loadRecord(int card,int stream,QString name,AudioCoding coding,
|
void loadRecord(int card,int stream,QString name,AudioCoding coding,
|
||||||
@ -76,7 +78,7 @@ class RDCae : public QObject
|
|||||||
signals:
|
signals:
|
||||||
void isConnected(bool state);
|
void isConnected(bool state);
|
||||||
void playLoaded(int handle);
|
void playLoaded(int handle);
|
||||||
void playPositioned(int handle,unsigned msec);
|
void playPositioned(int handle,unsigned pos);
|
||||||
void playing(int handle);
|
void playing(int handle);
|
||||||
void playStopped(int handle);
|
void playStopped(int handle);
|
||||||
void playUnloaded(int handle);
|
void playUnloaded(int handle);
|
||||||
@ -102,6 +104,7 @@ class RDCae : public QObject
|
|||||||
int StreamNumber(const char *arg);
|
int StreamNumber(const char *arg);
|
||||||
int GetHandle(const char *arg);
|
int GetHandle(const char *arg);
|
||||||
void UpdateMeters();
|
void UpdateMeters();
|
||||||
|
// Q3SocketDevice *cae_socket;
|
||||||
int cae_socket;
|
int cae_socket;
|
||||||
bool debug;
|
bool debug;
|
||||||
char args[CAE_MAX_ARGS][CAE_MAX_LENGTH];
|
char args[CAE_MAX_ARGS][CAE_MAX_LENGTH];
|
||||||
@ -111,7 +114,9 @@ class RDCae : public QObject
|
|||||||
bool input_status[RD_MAX_CARDS][RD_MAX_PORTS];
|
bool input_status[RD_MAX_CARDS][RD_MAX_PORTS];
|
||||||
int cae_handle[RD_MAX_CARDS][RD_MAX_STREAMS];
|
int cae_handle[RD_MAX_CARDS][RD_MAX_STREAMS];
|
||||||
unsigned cae_pos[RD_MAX_CARDS][RD_MAX_STREAMS];
|
unsigned cae_pos[RD_MAX_CARDS][RD_MAX_STREAMS];
|
||||||
QUdpSocket *cae_meter_socket;
|
// Q3SocketDevice *cae_meter_socket;
|
||||||
|
int cae_meter_socket;
|
||||||
|
uint16_t cae_meter_port;
|
||||||
int cae_meter_base_port;
|
int cae_meter_base_port;
|
||||||
int cae_meter_port_range;
|
int cae_meter_port_range;
|
||||||
short cae_input_levels[RD_MAX_CARDS][RD_MAX_PORTS][2];
|
short cae_input_levels[RD_MAX_CARDS][RD_MAX_PORTS][2];
|
||||||
|
@ -654,6 +654,10 @@ QString RDCoreApplication::exitCodeText(RDCoreApplication::ExitCode code)
|
|||||||
ret=tr("no such host");
|
ret=tr("no such host");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RDCoreApplication::ExitInternalError:
|
||||||
|
ret=tr("internal error");
|
||||||
|
break;
|
||||||
|
|
||||||
case RDCoreApplication::ExitLast:
|
case RDCoreApplication::ExitLast:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,8 @@ class RDCoreApplication : public QObject
|
|||||||
ExitLogLinkFailed=10,ExitNoPerms=11,ExitReportFailed=12,
|
ExitLogLinkFailed=10,ExitNoPerms=11,ExitReportFailed=12,
|
||||||
ExitImportFailed=13,ExitNoDropbox=14,ExitNoGroup=15,
|
ExitImportFailed=13,ExitNoDropbox=14,ExitNoGroup=15,
|
||||||
ExitInvalidCart=16,ExitNoSchedCode=17,
|
ExitInvalidCart=16,ExitNoSchedCode=17,
|
||||||
ExitBadTicket=18,ExitNoStation=19,ExitLast=20};
|
ExitBadTicket=18,ExitNoStation=19,ExitInternalError=20,
|
||||||
|
ExitLast=21};
|
||||||
RDCoreApplication(const QString &module_name,const QString &cmdname,
|
RDCoreApplication(const QString &module_name,const QString &cmdname,
|
||||||
const QString &usage,bool use_translations,QObject *parent);
|
const QString &usage,bool use_translations,QObject *parent);
|
||||||
~RDCoreApplication();
|
~RDCoreApplication();
|
||||||
|
@ -82,8 +82,9 @@ RDLogPlay::RDLogPlay(int id,RDEventPlayer *player,bool enable_cue,QObject *paren
|
|||||||
//
|
//
|
||||||
// CAE Connection
|
// CAE Connection
|
||||||
//
|
//
|
||||||
play_cae=new RDCae(rda->station(),rda->config(),parent);
|
// play_cae=new RDCae(rda->station(),rda->config(),parent);
|
||||||
play_cae->connectHost();
|
// play_cae->connectHost();
|
||||||
|
play_cae=rda->cae();
|
||||||
|
|
||||||
for(int i=0;i<2;i++) {
|
for(int i=0;i<2;i++) {
|
||||||
play_card[i]=0;
|
play_card[i]=0;
|
||||||
|
@ -243,7 +243,10 @@ MainWidget::MainWidget(RDConfig *config,QWidget *parent)
|
|||||||
//
|
//
|
||||||
connect(rda->cae(),SIGNAL(isConnected(bool)),
|
connect(rda->cae(),SIGNAL(isConnected(bool)),
|
||||||
this,SLOT(caeConnectedData(bool)));
|
this,SLOT(caeConnectedData(bool)));
|
||||||
rda->cae()->connectHost();
|
if(!rda->cae()->connectHost(&err_msg)) {
|
||||||
|
QMessageBox::warning(this,"RDAirPlay - "+tr("Error"),err_msg);
|
||||||
|
exit(RDCoreApplication::ExitInternalError);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set Audio Assignments
|
// Set Audio Assignments
|
||||||
|
@ -63,7 +63,10 @@ MainWidget::MainWidget(RDConfig *c,QWidget *parent)
|
|||||||
//
|
//
|
||||||
connect(rda->cae(),SIGNAL(isConnected(bool)),
|
connect(rda->cae(),SIGNAL(isConnected(bool)),
|
||||||
this,SLOT(caeConnectedData(bool)));
|
this,SLOT(caeConnectedData(bool)));
|
||||||
rda->cae()->connectHost();
|
if(!rda->cae()->connectHost(&err_msg)) {
|
||||||
|
QMessageBox::warning(this,"RDCartSlots - "+tr("Error"),err_msg);
|
||||||
|
exit(RDCoreApplication::ExitInternalError);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// RIPC Connection
|
// RIPC Connection
|
||||||
|
@ -149,7 +149,10 @@ MainWidget::MainWidget(RDConfig *c,QWidget *parent)
|
|||||||
connect(rda->cae(),SIGNAL(playing(int)),this,SLOT(playedData(int)));
|
connect(rda->cae(),SIGNAL(playing(int)),this,SLOT(playedData(int)));
|
||||||
connect(rda->cae(),SIGNAL(playStopped(int)),
|
connect(rda->cae(),SIGNAL(playStopped(int)),
|
||||||
this,SLOT(playStoppedData(int)));
|
this,SLOT(playStoppedData(int)));
|
||||||
rda->cae()->connectHost();
|
if(!rda->cae()->connectHost(&err_msg)) {
|
||||||
|
QMessageBox::warning(this,"RDCatch - "+tr("Error"),err_msg);
|
||||||
|
exit(RDCoreApplication::ExitInternalError);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Deck Monitors
|
// Deck Monitors
|
||||||
|
@ -225,7 +225,10 @@ MainObject::MainObject(QObject *parent)
|
|||||||
this,SLOT(playStoppedData(int)));
|
this,SLOT(playStoppedData(int)));
|
||||||
connect(rda->cae(),SIGNAL(playUnloaded(int)),
|
connect(rda->cae(),SIGNAL(playUnloaded(int)),
|
||||||
this,SLOT(playUnloadedData(int)));
|
this,SLOT(playUnloadedData(int)));
|
||||||
rda->cae()->connectHost();
|
if(!rda->cae()->connectHost(&err_msg)) {
|
||||||
|
rda->syslog(LOG_ERR,"failed to start [%s]",err_msg.toUtf8().constData());
|
||||||
|
exit(RDCoreApplication::ExitInternalError);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Sound Initialization
|
// Sound Initialization
|
||||||
|
@ -132,7 +132,10 @@ MainWidget::MainWidget(RDConfig *c,QWidget *parent)
|
|||||||
//
|
//
|
||||||
connect(rda->cae(),SIGNAL(isConnected(bool)),
|
connect(rda->cae(),SIGNAL(isConnected(bool)),
|
||||||
this,SLOT(caeConnectedData(bool)));
|
this,SLOT(caeConnectedData(bool)));
|
||||||
rda->cae()->connectHost();
|
if(!rda->cae()->connectHost(&err_msg)) {
|
||||||
|
QMessageBox::warning(this,"RDLibrary - "+tr("Error"),err_msg);
|
||||||
|
exit(RDCoreApplication::ExitInternalError);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Filter
|
// Filter
|
||||||
|
@ -86,7 +86,10 @@ MainWidget::MainWidget(RDConfig *c,QWidget *parent)
|
|||||||
//
|
//
|
||||||
connect(rda->cae(),SIGNAL(isConnected(bool)),
|
connect(rda->cae(),SIGNAL(isConnected(bool)),
|
||||||
this,SLOT(caeConnectedData(bool)));
|
this,SLOT(caeConnectedData(bool)));
|
||||||
rda->cae()->connectHost();
|
if(!rda->cae()->connectHost(&err_msg)) {
|
||||||
|
QMessageBox::warning(this,"RDLogEdit - "+tr("Error"),err_msg);
|
||||||
|
exit(RDCoreApplication::ExitInternalError);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// RIPC Connection
|
// RIPC Connection
|
||||||
|
@ -65,7 +65,10 @@ MainWidget::MainWidget(RDConfig *c,QWidget *parent)
|
|||||||
//
|
//
|
||||||
// CAE Connection
|
// CAE Connection
|
||||||
//
|
//
|
||||||
rda->cae()->connectHost();
|
if(!rda->cae()->connectHost(&err_msg)) {
|
||||||
|
QMessageBox::warning(this,"RDLogManager - "+tr("Error"),err_msg);
|
||||||
|
exit(RDCoreApplication::ExitInternalError);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// RIPC Connection
|
// RIPC Connection
|
||||||
|
@ -93,7 +93,10 @@ MainWidget::MainWidget(RDConfig *c,QWidget *parent)
|
|||||||
//
|
//
|
||||||
connect(rda->cae(),SIGNAL(isConnected(bool)),
|
connect(rda->cae(),SIGNAL(isConnected(bool)),
|
||||||
this,SLOT(caeConnectedData(bool)));
|
this,SLOT(caeConnectedData(bool)));
|
||||||
rda->cae()->connectHost();
|
if(!rda->cae()->connectHost(&err_msg)) {
|
||||||
|
QMessageBox::warning(this,"RDPanel - "+tr("Error"),err_msg);
|
||||||
|
exit(RDCoreApplication::ExitInternalError);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// RIPC Connection
|
// RIPC Connection
|
||||||
|
@ -88,7 +88,10 @@ MainObject::MainObject(QObject *parent)
|
|||||||
//
|
//
|
||||||
// CAE Connection
|
// CAE Connection
|
||||||
//
|
//
|
||||||
rda->cae()->connectHost();
|
if(!rda->cae()->connectHost(&err_msg)) {
|
||||||
|
rda->syslog(LOG_ERR,"failed to start [%s]",err_msg.toUtf8().constData());
|
||||||
|
exit(RDCoreApplication::ExitInternalError);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set Audio Assignments
|
// Set Audio Assignments
|
||||||
|
@ -131,7 +131,10 @@ MainObject::MainObject(QObject *parent)
|
|||||||
//
|
//
|
||||||
// CAE Connection
|
// CAE Connection
|
||||||
//
|
//
|
||||||
rda->cae()->connectHost();
|
if(!rda->cae()->connectHost(&err_msg)) {
|
||||||
|
rda->syslog(LOG_ERR,"failed to start [%s]",err_msg.toUtf8().constData());
|
||||||
|
exit(RDCoreApplication::ExitInternalError);
|
||||||
|
}
|
||||||
|
|
||||||
if(qApp->arguments().size()!=1) {
|
if(qApp->arguments().size()!=1) {
|
||||||
debug=true;
|
debug=true;
|
||||||
|
@ -123,7 +123,10 @@ MainWidget::MainWidget(QWidget *parent)
|
|||||||
//
|
//
|
||||||
connect(rda->cae(),SIGNAL(isConnected(bool)),
|
connect(rda->cae(),SIGNAL(isConnected(bool)),
|
||||||
this,SLOT(caeConnectedData(bool)));
|
this,SLOT(caeConnectedData(bool)));
|
||||||
rda->cae()->connectHost();
|
if(!rda->cae()->connectHost(&err_msg)) {
|
||||||
|
fprintf(stderr,"meterstrip_test: %s\n",err_msg.toUtf8().constData());
|
||||||
|
exit(RDCoreApplication::ExitInternalError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -520,6 +520,7 @@ void MainObject::PutAudio()
|
|||||||
case RDApplication::ExitNoSchedCode:
|
case RDApplication::ExitNoSchedCode:
|
||||||
case RDApplication::ExitBadTicket:
|
case RDApplication::ExitBadTicket:
|
||||||
case RDApplication::ExitNoStation:
|
case RDApplication::ExitNoStation:
|
||||||
|
case RDApplication::ExitInternalError:
|
||||||
rda->syslog(LOG_WARNING,
|
rda->syslog(LOG_WARNING,
|
||||||
"importer process returned exit code %d [cmdline: %s, client addr: %s]",
|
"importer process returned exit code %d [cmdline: %s, client addr: %s]",
|
||||||
proc->exitCode(),
|
proc->exitCode(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user