diff --git a/ChangeLog b/ChangeLog index 44b4c7c4..1718ca75 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22304,3 +22304,7 @@ 2021-08-17 Fred Gleason * Fixed a regression in rdlogmanager(1) that caused it to attempt to open an X11 connection even when invoked in CLI mode. +2021-08-18 Fred Gleason + * Refactored the HPI driver in caed(8) to use virtual inheritance. + * Disabled JACK driver support in caed(8). + * Disabled ALSA driver support in caed(8). diff --git a/cae/Makefile.am b/cae/Makefile.am index 08956fdd..77558f98 100644 --- a/cae/Makefile.am +++ b/cae/Makefile.am @@ -2,7 +2,7 @@ ## ## Core Audio Engine Makefile.am for Rivendell ## -## Copyright 2002-2020 Fred Gleason +## Copyright 2002-2021 Fred Gleason ## ## 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 @@ -33,10 +33,15 @@ dist_caed_SOURCES = cae.cpp cae.h\ cae_alsa.cpp\ cae_hpi.cpp\ cae_jack.cpp\ - cae_server.cpp cae_server.h + cae_server.cpp cae_server.h\ + caedriver.cpp caedriver.h\ + caedriverfactory.cpp caedriverfactory.h\ + hpidriver.cpp hpidriver.h nodist_caed_SOURCES = moc_cae.cpp\ - moc_cae_server.cpp + moc_cae_server.cpp\ + moc_caedriver.cpp\ + moc_hpidriver.cpp caed_LDADD = @LIB_RDLIBS@\ @LIBALSA@\ diff --git a/cae/cae.cpp b/cae/cae.cpp index 9a42be51..365b5567 100644 --- a/cae/cae.cpp +++ b/cae/cae.cpp @@ -45,10 +45,11 @@ #include #include -#include +#include "caedriverfactory.h" +#include "cae.h" volatile bool exiting=false; -RDConfig *rd_config; +//RDConfig *rd_config; #ifdef JACK extern jack_client_t *jack_client; #endif // JACK @@ -88,19 +89,19 @@ void SigHandler(int signum) MainObject::MainObject(QObject *parent) :QObject(parent) { - // - // Read Command Options - // - new RDCmdSwitch("caed",CAED_USAGE); + QString err_msg; + RDCoreApplication::ErrorType err_type=RDCoreApplication::ErrorOk; // - // LogLine references rd_config - // - rd_config=new RDConfig(RD_CONF_FILE); - rd_config->load(); - rd_config->setModuleName("caed"); - - RDApplication::syslog(rd_config,LOG_INFO,"cae starting"); + // Open Database + // + rda=static_cast(new RDCoreApplication("caed","caed",CAED_USAGE,this)); + if(!rda->open(&err_msg,&err_type,false)) { + fprintf(stderr,"caed: %s\n",err_msg.toUtf8().constData()); + exit(1); + } + rda->config()->setModuleName("caed"); + rda->syslog(LOG_INFO,"cae starting"); // // Initialize Data Structures @@ -147,10 +148,12 @@ MainObject::MainObject(QObject *parent) jack_client=NULL; #endif // JACK - cae_server=new CaeServer(rd_config,this); + // + // Server Front End + // + cae_server=new CaeServer(rda->config(),this); if(!cae_server->listen(QHostAddress::Any,CAED_TCP_PORT)) { - RDApplication::syslog(rd_config,LOG_ERR, - "caed: failed to bind port %d",CAED_TCP_PORT); + rda->syslog(LOG_ERR,"caed: failed to bind port %d",CAED_TCP_PORT); exit(1); } connect(cae_server,SIGNAL(connectionDropped(int)), @@ -233,47 +236,45 @@ MainObject::MainObject(QObject *parent) // meter_socket=new QUdpSocket(this); - // - // Open Database - // - QSqlDatabase db=QSqlDatabase::addDatabase(rd_config->mysqlDriver()); - db.setDatabaseName(rd_config->mysqlDbname()); - db.setUserName(rd_config->mysqlUsername()); - db.setPassword(rd_config->mysqlPassword()); - db.setHostName(rd_config->mysqlHostname()); - if(!db.open()) { - RDApplication::syslog(rd_config,LOG_ERR, - "unable to connect to mySQL Server"); - printf("caed: unable to connect to mySQL Server"); - exit(1); - } - // // Provisioning // InitProvisioning(); // - // Start Up the Drivers + // Audio Driver Backend // - cae_station=new RDStation(rd_config->stationName()); - RDSystem *sys=new RDSystem(); - system_sample_rate=sys->sampleRate(); - delete sys; - hpiInit(cae_station); - alsaInit(cae_station); - jackInit(cae_station); - ClearDriverEntries(cae_station); + system_sample_rate=rda->system()->sampleRate(); + // hpiInit(cae_station); + // alsaInit(cae_station); + // jackInit(cae_station); + ClearDriverEntries(rda->station()); + unsigned next_card=0; + + // + // HPI Devices (One driver instance handles them all) + // + CaeDriver *dvr=CaeDriverFactory(RDStation::Hpi,this); + if(dvr->initialize(&next_card)) { + connect(dvr,SIGNAL(playStateChanged(int,int,int)), + this,SLOT(statePlayUpdate(int,int,int))); + connect(dvr,SIGNAL(recordStateChanged(int,int,int)), + this,SLOT(stateRecordUpdate(int,int,int))); + d_drivers.push_back(dvr); + } + else { + delete dvr; + } // // Probe Capabilities // - ProbeCaps(cae_station); + ProbeCaps(rda->station()); // // Close Database Connection // - cae_station->setScanned(true); + rda->station()->setScanned(true); // // Initialize Mixers @@ -322,9 +323,9 @@ MainObject::MainObject(QObject *parent) jack_running=true; } #endif // JACK - if(rd_config->useRealtime()) { + if(rda->config()->useRealtime()) { if(!jack_running) { - sched_params.sched_priority=rd_config->realtimePriority(); + sched_params.sched_priority=rda->config()->realtimePriority(); } sched_policy=SCHED_FIFO; #ifdef ALSA @@ -356,12 +357,12 @@ MainObject::MainObject(QObject *parent) } mlockall(MCL_CURRENT|MCL_FUTURE); if(result) { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "unable to set realtime scheduling: %s", strerror(result)); } else { - RDApplication::syslog(rd_config,LOG_DEBUG, + rda->syslog(LOG_DEBUG, "using realtime scheduling, priority=%d", sched_params.sched_priority); } @@ -382,10 +383,10 @@ MainObject::MainObject(QObject *parent) // } } */ - if(rd_config->enableMixerLogging()) { - RDApplication::syslog(rd_config,LOG_INFO,"mixer logging enabled"); + if(rda->config()->enableMixerLogging()) { + rda->syslog(LOG_INFO,"mixer logging enabled"); } - RDApplication::syslog(rd_config,LOG_INFO,"cae started"); + rda->syslog(LOG_INFO,"cae started"); } @@ -394,50 +395,25 @@ void MainObject::loadPlaybackData(int id,unsigned card,const QString &name) QString wavename; int new_stream=-1; int handle; + CaeDriver *dvr=GetDriver(card); - wavename=rd_config->audioFileName(name); - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiLoadPlayback(card,wavename,&new_stream)) { - cae_server-> - sendCommand(id,QString().sprintf("LP %d %s -1 -1 -!",card, - (const char *)name.toUtf8())); - RDApplication::syslog(rd_config,LOG_WARNING, - "unable to allocate stream for card %d",card); - return; - } - break; - - case RDStation::Alsa: - if(!alsaLoadPlayback(card,wavename,&new_stream)) { - cae_server-> - sendCommand(id,QString().sprintf("LP %d %s -1 -1 -!",card, - (const char *)name.toUtf8())); - RDApplication::syslog(rd_config,LOG_WARNING, - "unable to allocate stream for card %d",card); - return; - } - break; - - case RDStation::Jack: - if(!jackLoadPlayback(card,wavename,&new_stream)) { - cae_server-> - sendCommand(id,QString().sprintf("LP %d %s -1 -1 -!",card, - (const char *)name.toUtf8())); - RDApplication::syslog(rd_config,LOG_WARNING, - "unable to allocate stream for card %d",card); - return; - } - break; - - default: + if(dvr==NULL) { cae_server-> sendCommand(id,QString().sprintf("LP %d %s -1 -1 -!",card, - (const char *)name.toUtf8())); + name.toUtf8().constData())); + return; + } + wavename=rda->config()->audioFileName(name); + if(!dvr->loadPlayback(card,wavename,&new_stream)) { + cae_server-> + sendCommand(id,QString().sprintf("LP %d %s -1 -1 -!",card, + name.toUtf8().constData())); + rda->syslog(LOG_WARNING, + "unable to allocate stream for card %d",card); return; } if((handle=GetHandle(card,new_stream))>=0) { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "*** clearing stale stream assignment, card=%d stream=%d ***", card,new_stream); play_handle[handle].card=-1; @@ -449,7 +425,7 @@ void MainObject::loadPlaybackData(int id,unsigned card,const QString &name) play_handle[handle].stream=new_stream; play_handle[handle].owner=id; play_owner[card][new_stream]=id; - RDApplication::syslog(rd_config,LOG_INFO, + rda->syslog(LOG_INFO, "LoadPlayback Card: %d Stream: %d Name: %s Handle: %d", card,new_stream,(const char *)wavename.toUtf8(),handle); cae_server-> @@ -463,51 +439,21 @@ void MainObject::unloadPlaybackData(int id,unsigned handle) { int card=play_handle[handle].card; int stream=play_handle[handle].stream; + CaeDriver *dvr=GetDriver(card); + if(dvr==NULL) { + cae_server->sendCommand(id,QString().sprintf("UP %d -!",handle)); + return; + } if((play_owner[card][stream]==-1)||(play_owner[card][stream]==id)) { - switch(cae_driver[card]) { - case RDStation::Hpi: - if(hpiUnloadPlayback(card,stream)) { - play_owner[card][stream]=-1; - RDApplication::syslog(rd_config,LOG_INFO, - "UnloadPlayback - Card: %d Stream: %d Handle: %d", - card,stream,handle); - cae_server->sendCommand(id,QString().sprintf("UP %d +!",handle)); - } - else { - cae_server->sendCommand(id,QString().sprintf("UP %d -!",handle)); - } - break; - - case RDStation::Alsa: - if(alsaUnloadPlayback(card,stream)) { - play_owner[card][stream]=-1; - RDApplication::syslog(rd_config,LOG_INFO, - "UnloadPlayback - Card: %d Stream: %d Handle: %d", - card,stream,handle); - cae_server->sendCommand(id,QString().sprintf("UP %d +!",handle)); - } - else { - cae_server->sendCommand(id,QString().sprintf("UP %d -!",handle)); - } - break; - - case RDStation::Jack: - if(jackUnloadPlayback(card,stream)) { - play_owner[card][stream]=-1; - RDApplication::syslog(rd_config,LOG_INFO, - "UnloadPlayback - Card: %d Stream: %d Handle: %d", - card,stream,handle); - cae_server->sendCommand(id,QString().sprintf("UP %d +!",handle)); - } - else { - cae_server->sendCommand(id,QString().sprintf("UP %d -!",handle)); - } - break; - - default: + if(dvr->unloadPlayback(card,stream)) { + play_owner[card][stream]=-1; + rda->syslog(LOG_INFO,"UnloadPlayback - Card: %d Stream: %d Handle: %d", + card,stream,handle); + cae_server->sendCommand(id,QString().sprintf("UP %d +!",handle)); + } + else { cae_server->sendCommand(id,QString().sprintf("UP %d -!",handle)); - return; } play_handle[handle].card=-1; play_handle[handle].stream=-1; @@ -524,48 +470,21 @@ void MainObject::playPositionData(int id,unsigned handle,unsigned pos) { int card=play_handle[handle].card; int stream=play_handle[handle].stream; + CaeDriver *dvr=GetDriver(card); + if(dvr==NULL) { + cae_server->sendCommand(id,QString().sprintf("PP %d %d -!",handle,pos)); + return; + } if(play_owner[card][stream]==id) { - switch(cae_driver[card]) { - case RDStation::Hpi: - if(hpiPlaybackPosition(card,stream,pos)) { - RDApplication::syslog(rd_config,LOG_INFO, - "PlaybackPosition - Card: %d Stream: %d Pos: %d Handle: %d", - card,stream,pos,handle); - cae_server->sendCommand(id,QString().sprintf("PP %d %d +!",handle,pos)); - } - else { - cae_server->sendCommand(id,QString().sprintf("PP %d %d -!",handle,pos)); - } - break; - - case RDStation::Alsa: - if(alsaPlaybackPosition(card,stream,pos)) { - RDApplication::syslog(rd_config,LOG_INFO, - "PlaybackPosition - Card: %d Stream: %d Pos: %d Handle: %d", - card,stream,pos,handle); - cae_server->sendCommand(id,QString().sprintf("PP %d %d +!",handle,pos)); - } - else { - cae_server->sendCommand(id,QString().sprintf("PP %d %d -!",handle,pos)); - } - break; - - case RDStation::Jack: - if(jackPlaybackPosition(card,stream,pos)) { - RDApplication::syslog(rd_config,LOG_INFO, - "PlaybackPosition - Card: %d Stream: %d Pos: %d Handle: %d", - card,stream,pos,handle); - cae_server->sendCommand(id,QString().sprintf("PP %d %d +!",handle,pos)); - } - else { - cae_server->sendCommand(id,QString().sprintf("PP %d %d -!",handle,pos)); - } - break; - - default: + if(dvr->playbackPosition(card,stream,pos)) { + rda->syslog(LOG_INFO, + "PlaybackPosition - Card: %d Stream: %d Pos: %d Handle: %d", + card,stream,pos,handle); + cae_server->sendCommand(id,QString().sprintf("PP %d %d +!",handle,pos)); + } + else { cae_server->sendCommand(id,QString().sprintf("PP %d %d -!",handle,pos)); - return; } return; } @@ -578,7 +497,14 @@ void MainObject::playData(int id,unsigned handle,unsigned length,unsigned speed, { int card=play_handle[handle].card; int stream=play_handle[handle].stream; + CaeDriver *dvr=GetDriver(card); + if(dvr==NULL) { + cae_server-> + sendCommand(id,QString().sprintf("PY %u %u %u %u -!", + handle,length,speed,pitch_flag)); + return; + } play_length[card][stream]=length; play_speed[card][stream]=speed; switch(pitch_flag) { @@ -597,50 +523,18 @@ void MainObject::playData(int id,unsigned handle,unsigned length,unsigned speed, return; } if(play_owner[card][stream]==id) { - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiPlay(card,stream,play_length[card][stream], + if(!dvr->play(card,stream,play_length[card][stream], play_speed[card][stream],play_pitch[card][stream], RD_ALLOW_NONSTANDARD_RATES)) { - cae_server-> - sendCommand(id,QString().sprintf("PY %u %u %u %u -!", - handle,length,speed,pitch_flag)); - return; - } - break; - - case RDStation::Alsa: - if(!alsaPlay(card,stream,play_length[card][stream], - play_speed[card][stream],play_pitch[card][stream], - RD_ALLOW_NONSTANDARD_RATES)) { - cae_server-> - sendCommand(id,QString().sprintf("PY %u %u %u %u -!", - handle,length,speed,pitch_flag)); - return; - } - break; - - case RDStation::Jack: - if(!jackPlay(card,stream,play_length[card][stream], - play_speed[card][stream],play_pitch[card][stream], - RD_ALLOW_NONSTANDARD_RATES)) { - cae_server-> - sendCommand(id,QString().sprintf("PY %u %u %u %u -!", - handle,length,speed,pitch_flag)); - return; - } - break; - - default: cae_server-> sendCommand(id,QString().sprintf("PY %u %u %u %u -!", handle,length,speed,pitch_flag)); return; } - RDApplication::syslog(rd_config,LOG_INFO, - "Play - Card: %d Stream: %d Handle: %d Length: %d Speed: %d Pitch: %d", - card,stream,handle,play_length[card][stream], - play_speed[card][stream],pitch_flag); + rda->syslog(LOG_INFO, + "Play - Card: %d Stream: %d Handle: %d Length: %d Speed: %d Pitch: %d", + card,stream,handle,play_length[card][stream], + play_speed[card][stream],pitch_flag); // No command echo for success -- statePlayUpdate() sends it! return; } @@ -654,34 +548,18 @@ void MainObject::stopPlaybackData(int id,unsigned handle) { int card=play_handle[handle].card; int stream=play_handle[handle].stream; + CaeDriver *dvr=GetDriver(card); + + if(dvr==NULL) { + cae_server->sendCommand(id,QString().sprintf("SP %u -!",handle)); + return; + } if(play_owner[card][stream]==id) { - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiStopPlayback(card,stream)) { - cae_server->sendCommand(id,QString().sprintf("SP %u -!",handle)); - return; - } - break; - - case RDStation::Alsa: - if(!alsaStopPlayback(card,stream)) { - cae_server->sendCommand(id,QString().sprintf("SP %u -!",handle)); - return; - } - break; - - case RDStation::Jack: - if(!jackStopPlayback(card,stream)) { - cae_server->sendCommand(id,QString().sprintf("SP %u -!",handle)); - return; - } - break; - - default: + if(!dvr->stopPlayback(card,stream)) { cae_server->sendCommand(id,QString().sprintf("SP %u -!",handle)); return; } - RDApplication::syslog(rd_config,LOG_INFO, + rda->syslog(LOG_INFO, "StopPlayback - Card: %d Stream: %d Handle: %d", card,stream,handle); return; @@ -693,23 +571,12 @@ void MainObject::stopPlaybackData(int id,unsigned handle) void MainObject::timescalingSupportData(int id,unsigned card) { bool state=false; + CaeDriver *dvr=GetDriver(card); - switch(cae_driver[card]) { - case RDStation::Hpi: - state=hpiTimescaleSupported(card); - break; - - case RDStation::Jack: - state=jackTimescaleSupported(card); - break; - - case RDStation::Alsa: - state=alsaTimescaleSupported(card); - break; - - case RDStation::None: - break; + if(dvr==NULL) { + return; } + state=dvr->timescaleSupported(card); if(state) { cae_server->sendCommand(id,QString().sprintf("TS %u +!",card)); } @@ -725,53 +592,27 @@ void MainObject::loadRecordingData(int id,unsigned card,unsigned port, const QString &name) { QString wavename; + CaeDriver *dvr=GetDriver(card); + if(dvr==NULL) { + cae_server-> + sendCommand(id,QString().sprintf("LR %u %u %u %u %u %u %s -!", + card,port,coding,channels,samprate, + bitrate,(const char *)name.toUtf8())); + return; + } if(record_owner[card][port]==-1) { - wavename=rd_config->audioFileName(name); + wavename=rda->config()->audioFileName(name); unlink(wavename.toUtf8()); // So we don't trainwreck any current playouts! unlink((wavename+".energy").toUtf8()); - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiLoadRecord(card,port,coding,channels,samprate,bitrate, - wavename)) { - cae_server-> - sendCommand(id,QString().sprintf("LR %u %u %u %u %u %u %s -!", - card,port,coding,channels,samprate, - bitrate,(const char *)name.toUtf8())); - return; - } - break; - - case RDStation::Alsa: - if(!alsaLoadRecord(card,port,coding,channels,samprate, - bitrate,wavename)) { - cae_server-> - sendCommand(id,QString().sprintf("LR %u %u %u %u %u %u %s -!", - card,port,coding,channels,samprate, - bitrate,(const char *)name.toUtf8())); - return; - } - break; - - case RDStation::Jack: - if(!jackLoadRecord(card,port,coding,channels,samprate, - bitrate,wavename)) { - cae_server-> - sendCommand(id,QString().sprintf("LR %u %u %u %u %u %u %s -!", - card,port,coding,channels,samprate, - bitrate,(const char *)name.toUtf8())); - return; - } - break; - - default: + if(!dvr->loadRecord(card,port,coding,channels,samprate,bitrate,wavename)) { cae_server-> sendCommand(id,QString().sprintf("LR %u %u %u %u %u %u %s -!", card,port,coding,channels,samprate, bitrate,(const char *)name.toUtf8())); return; } - RDApplication::syslog(rd_config,LOG_INFO, + rda->syslog(LOG_INFO, "LoadRecord - Card: %d Stream: %d Coding: %d Chans: %d SampRate: %d BitRate: %d Name: %s", card,port,coding,channels,samprate,bitrate, (const char *)wavename.toUtf8()); @@ -792,36 +633,20 @@ void MainObject::loadRecordingData(int id,unsigned card,unsigned port, void MainObject::unloadRecordingData(int id,unsigned card,unsigned stream) { + CaeDriver *dvr=GetDriver(card); + + if(dvr==NULL) { + cae_server->sendCommand(id,QString().sprintf("UR %u %u -!",card,stream)); + return; + } if((record_owner[card][stream]==-1)||(record_owner[card][stream]==id)) { unsigned len=0; - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiUnloadRecord(card,stream,&len)) { - cae_server->sendCommand(id,QString().sprintf("UR %u %u -!",card,stream)); - return; - } - break; - - case RDStation::Alsa: - if(!alsaUnloadRecord(card,stream,&len)) { - cae_server->sendCommand(id,QString().sprintf("UR %u %u -!",card,stream)); - return; - } - break; - - case RDStation::Jack: - if(!jackUnloadRecord(card,stream,&len)) { - cae_server->sendCommand(id,QString().sprintf("UR %u %u -!",card,stream)); - return; - } - break; - - default: + if(!dvr->unloadRecord(card,stream,&len)) { cae_server->sendCommand(id,QString().sprintf("UR %u %u -!",card,stream)); return; } record_owner[card][stream]=-1; - RDApplication::syslog(rd_config,LOG_INFO, + rda->syslog(LOG_INFO, "UnloadRecord - Card: %d Stream: %d, Length: %u", card,stream,len); cae_server-> @@ -839,47 +664,25 @@ void MainObject::unloadRecordingData(int id,unsigned card,unsigned stream) void MainObject::recordData(int id,unsigned card,unsigned stream,unsigned len, int threshold_level) { + CaeDriver *dvr=GetDriver(card); + + if(dvr==NULL) { + cae_server-> + sendCommand(id,QString().sprintf("RD %u %u %u %d -!", + card,stream,len,threshold_level)); + return; + } record_length[card][stream]=len; record_threshold[card][stream]=threshold_level; if(record_owner[card][stream]==id) { - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiRecord(card,stream,record_length[card][stream], + if(!dvr->record(card,stream,record_length[card][stream], record_threshold[card][stream])) { - cae_server-> - sendCommand(id,QString().sprintf("RD %u %u %u %d -!", - card,stream,len,threshold_level)); - return; - } - break; - - case RDStation::Alsa: - if(!alsaRecord(card,stream,record_length[card][stream], - record_threshold[card][stream])) { - cae_server-> - sendCommand(id,QString().sprintf("RD %u %u %u %d -!", - card,stream,len,threshold_level)); - return; - } - break; - - case RDStation::Jack: - if(!jackRecord(card,stream,record_length[card][stream], - record_threshold[card][stream])) { - cae_server-> - sendCommand(id,QString().sprintf("RD %u %u %u %d -!", - card,stream,len,threshold_level)); - return; - } - break; - - default: cae_server-> sendCommand(id,QString().sprintf("RD %u %u %u %d -!", card,stream,len,threshold_level)); return; } - RDApplication::syslog(rd_config,LOG_INFO, + rda->syslog(LOG_INFO, "Record - Card: %d Stream: %d Length: %d Thres: %d", card,stream,record_length[card][stream], record_threshold[card][stream]); @@ -894,35 +697,17 @@ void MainObject::recordData(int id,unsigned card,unsigned stream,unsigned len, void MainObject::stopRecordingData(int id,unsigned card,unsigned stream) { - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiStopRecord(card,stream)) { - cae_server->sendCommand(id,QString().sprintf("SR %u %u -!",card,stream)); - return; - } - break; + CaeDriver *dvr=GetDriver(card); - case RDStation::Alsa: - if(!alsaStopRecord(card,stream)) { - cae_server->sendCommand(id,QString().sprintf("SR %u %u -!",card,stream)); - return; - } - cae_server->sendCommand(id,QString().sprintf("SR %u %u +!",card,stream)); - break; - - case RDStation::Jack: - if(!jackStopRecord(card,stream)) { - cae_server->sendCommand(id,QString().sprintf("SR %u %u -!",card,stream)); - return; - } - cae_server->sendCommand(id,QString().sprintf("SR %u %u +!",card,stream)); - break; - - default: + if(dvr==NULL) { cae_server->sendCommand(id,QString().sprintf("SR %u %u -!",card,stream)); return; } - RDApplication::syslog(rd_config,LOG_INFO, + if(!dvr->stopRecord(card,stream)) { + cae_server->sendCommand(id,QString().sprintf("SR %u %u -!",card,stream)); + return; + } + rda->syslog(LOG_INFO, "StopRecord - Card: %d Stream: %d",card,stream); } @@ -930,35 +715,20 @@ void MainObject::stopRecordingData(int id,unsigned card,unsigned stream) void MainObject::setInputVolumeData(int id,unsigned card,unsigned stream, int level) { - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiSetInputVolume(card,stream,level)) { - cae_server-> - sendCommand(id,QString().sprintf("IV %u %u %d -!",card,stream,level)); - return; - } + CaeDriver *dvr=GetDriver(card); - case RDStation::Alsa: - if(!alsaSetInputVolume(card,stream,level)) { - cae_server-> - sendCommand(id,QString().sprintf("IV %u %u %d -!",card,stream,level)); - return; - } - - case RDStation::Jack: - if(!jackSetInputVolume(card,stream,level)) { - cae_server-> - sendCommand(id,QString().sprintf("IV %u %u %d -!",card,stream,level)); - return; - } - - default: + if(dvr==NULL) { cae_server-> sendCommand(id,QString().sprintf("IV %u %u %d -!",card,stream,level)); return; } - if(rd_config->enableMixerLogging()) { - RDApplication::syslog(rd_config,LOG_INFO, + if(!dvr->setInputVolume(card,stream,level)) { + cae_server-> + sendCommand(id,QString().sprintf("IV %u %u %d -!",card,stream,level)); + return; + } + if(rda->config()->enableMixerLogging()) { + rda->syslog(LOG_INFO, "SetInputVolume - Card: %d Stream: %d Level: %d", card,stream,level); } @@ -970,38 +740,20 @@ void MainObject::setInputVolumeData(int id,unsigned card,unsigned stream, void MainObject::setOutputVolumeData(int id,unsigned card,unsigned stream, unsigned port,int level) { - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiSetOutputVolume(card,stream,port,level)) { - cae_server->sendCommand(id,QString().sprintf("OV %u %u %u %d -!", - card,stream,port,level)); - return; - } - break; + CaeDriver *dvr=GetDriver(card); - case RDStation::Alsa: - if(!alsaSetOutputVolume(card,stream,port,level)) { - cae_server->sendCommand(id,QString().sprintf("OV %u %u %u %d -!", - card,stream,port,level)); - return; - } - break; - - case RDStation::Jack: - if(!jackSetOutputVolume(card,stream,port,level)) { - cae_server->sendCommand(id,QString().sprintf("OV %u %u %u %d -!", - card,stream,port,level)); - return; - } - break; - - default: + if(dvr==NULL) { cae_server->sendCommand(id,QString().sprintf("OV %u %u %u %d -!", card,stream,port,level)); return; } - if(rd_config->enableMixerLogging()) { - RDApplication::syslog(rd_config,LOG_INFO, + if(!dvr->setOutputVolume(card,stream,port,level)) { + cae_server->sendCommand(id,QString().sprintf("OV %u %u %u %d -!", + card,stream,port,level)); + return; + } + if(rda->config()->enableMixerLogging()) { + rda->syslog(LOG_INFO, "SetOutputVolume - Card: %d Stream: %d Port: %d Level: %d", card,stream,port,level); } @@ -1013,42 +765,22 @@ void MainObject::setOutputVolumeData(int id,unsigned card,unsigned stream, void MainObject::fadeOutputVolumeData(int id,unsigned card,unsigned stream, unsigned port,int level,unsigned length) { - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiFadeOutputVolume(card,stream,port,level,length)) { - cae_server-> - sendCommand(id,QString().sprintf("FV %u %u %u %d %u -!", - card,stream,port,level,length)); - return; - } - break; + CaeDriver *dvr=GetDriver(card); - case RDStation::Alsa: - if(!alsaFadeOutputVolume(card,stream,port,level,length)) { - cae_server-> - sendCommand(id,QString().sprintf("FV %u %u %u %d %u -!", - card,stream,port,level,length)); - return; - } - break; - - case RDStation::Jack: - if(!jackFadeOutputVolume(card,stream,port,level,length)) { - cae_server-> - sendCommand(id,QString().sprintf("FV %u %u %u %d %u -!", - card,stream,port,level,length)); - return; - } - break; - - default: + if(dvr==NULL) { cae_server-> sendCommand(id,QString().sprintf("FV %u %u %u %d %u -!", card,stream,port,level,length)); return; } - if(rd_config->enableMixerLogging()) { - RDApplication::syslog(rd_config,LOG_INFO, + if(!dvr->fadeOutputVolume(card,stream,port,level,length)) { + cae_server-> + sendCommand(id,QString().sprintf("FV %u %u %u %d %u -!", + card,stream,port,level,length)); + return; + } + if(rda->config()->enableMixerLogging()) { + rda->syslog(LOG_INFO, "FadeOutputVolume - Card: %d Stream: %d Port: %d Level: %d Length: %d", card,stream,port,level,length); } @@ -1061,38 +793,21 @@ void MainObject::fadeOutputVolumeData(int id,unsigned card,unsigned stream, void MainObject::setInputLevelData(int id,unsigned card,unsigned port, int level) { - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiSetInputLevel(card,port,level)) { - cae_server->sendCommand(id,QString().sprintf("IL %u %u %d -!", - card,port,level)); - return; - } - break; + CaeDriver *dvr=GetDriver(card); - case RDStation::Alsa: - if(!alsaSetInputLevel(card,port,level)) { - cae_server->sendCommand(id,QString().sprintf("IL %u %u %d -!", - card,port,level)); - return; - } - break; - - case RDStation::Jack: - if(!jackSetInputLevel(card,port,level)) { - cae_server->sendCommand(id,QString().sprintf("IL %u %u %d -!", - card,port,level)); - return; - } - break; - - default: + if(dvr==NULL) { cae_server->sendCommand(id,QString().sprintf("IL %u %u %d -!", card,port,level)); return; } - if(rd_config->enableMixerLogging()) { - RDApplication::syslog(rd_config,LOG_INFO, + + if(!dvr->setInputLevel(card,port,level)) { + cae_server->sendCommand(id,QString().sprintf("IL %u %u %d -!", + card,port,level)); + return; + } + if(rda->config()->enableMixerLogging()) { + rda->syslog(LOG_INFO, "SetInputLevel - Card: %d Port: %d Level: %d", card,port,level); } @@ -1104,38 +819,20 @@ void MainObject::setInputLevelData(int id,unsigned card,unsigned port, void MainObject::setOutputLevelData(int id,unsigned card,unsigned port, int level) { - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiSetOutputLevel(card,port,level)) { - cae_server->sendCommand(id,QString().sprintf("OL %u %u %d -!", - card,port,level)); - return; - } - break; + CaeDriver *dvr=GetDriver(card); - case RDStation::Alsa: - if(!alsaSetOutputLevel(card,port,level)) { - cae_server->sendCommand(id,QString().sprintf("OL %u %u %d -!", - card,port,level)); - return; - } - break; - - case RDStation::Jack: - if(!jackSetOutputLevel(card,port,level)) { - cae_server->sendCommand(id,QString().sprintf("OL %u %u %d -!", - card,port,level)); - return; - } - break; - - default: + if(dvr==NULL) { cae_server->sendCommand(id,QString().sprintf("OL %u %u %d -!", card,port,level)); return; } - if(rd_config->enableMixerLogging()) { - RDApplication::syslog(rd_config,LOG_INFO, + if(!dvr->setOutputLevel(card,port,level)) { + cae_server->sendCommand(id,QString().sprintf("OL %u %u %d -!", + card,port,level)); + return; + } + if(rda->config()->enableMixerLogging()) { + rda->syslog(LOG_INFO, "SetOutputLevel - Card: %d Port: %d Level: %d", card,port,level); } @@ -1147,38 +844,20 @@ void MainObject::setOutputLevelData(int id,unsigned card,unsigned port, void MainObject::setInputModeData(int id,unsigned card,unsigned stream, unsigned mode) { - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiSetInputMode(card,stream,mode)) { - cae_server->sendCommand(id,QString().sprintf("IM %u %u %u -!", - card,stream,mode)); - return; - } - break; + CaeDriver *dvr=GetDriver(card); - case RDStation::Alsa: - if(!alsaSetInputMode(card,stream,mode)) { - cae_server->sendCommand(id,QString().sprintf("IM %u %u %u -!", - card,stream,mode)); - return; - } - break; - - case RDStation::Jack: - if(!jackSetInputMode(card,stream,mode)) { - cae_server->sendCommand(id,QString().sprintf("IM %u %u %u -!", - card,stream,mode)); - return; - } - break; - - default: + if(dvr==NULL) { cae_server->sendCommand(id,QString().sprintf("IM %u %u %u -!", card,stream,mode)); return; } - if(rd_config->enableMixerLogging()) { - RDApplication::syslog(rd_config,LOG_INFO, + if(!dvr->setInputMode(card,stream,mode)) { + cae_server->sendCommand(id,QString().sprintf("IM %u %u %u -!", + card,stream,mode)); + return; + } + if(rda->config()->enableMixerLogging()) { + rda->syslog(LOG_INFO, "SetInputMode - Card: %d Stream: %d Mode: %d", card,stream,mode); } @@ -1190,38 +869,20 @@ void MainObject::setInputModeData(int id,unsigned card,unsigned stream, void MainObject::setOutputModeData(int id,unsigned card,unsigned stream, unsigned mode) { - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiSetOutputMode(card,stream,mode)) { - cae_server->sendCommand(id,QString().sprintf("OM %u %u %u -!", - card,stream,mode)); - return; - } - break; + CaeDriver *dvr=GetDriver(card); - case RDStation::Alsa: - if(!alsaSetOutputMode(card,stream,mode)) { - cae_server->sendCommand(id,QString().sprintf("OM %u %u %u -!", - card,stream,mode)); - return; - } - break; - - case RDStation::Jack: - if(!jackSetOutputMode(card,stream,mode)) { - cae_server->sendCommand(id,QString().sprintf("OM %u %u %u -!", - card,stream,mode)); - return; - } - break; - - default: + if(dvr==NULL) { cae_server->sendCommand(id,QString().sprintf("OM %u %u %u -!", card,stream,mode)); return; } - if(rd_config->enableMixerLogging()) { - RDApplication::syslog(rd_config,LOG_INFO, + if(!dvr->setOutputMode(card,stream,mode)) { + cae_server->sendCommand(id,QString().sprintf("OM %u %u %u -!", + card,stream,mode)); + return; + } + if(rda->config()->enableMixerLogging()) { + rda->syslog(LOG_INFO, "SetOutputMode - Card: %d Stream: %d Mode: %d", card,stream,mode); } @@ -1233,38 +894,20 @@ void MainObject::setOutputModeData(int id,unsigned card,unsigned stream, void MainObject::setInputVoxLevelData(int id,unsigned card,unsigned stream, int level) { - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiSetInputVoxLevel(card,stream,level)) { - cae_server->sendCommand(id,QString().sprintf("IX %u %u %d -!", - card,stream,level)); - return; - } - break; + CaeDriver *dvr=GetDriver(card); - case RDStation::Alsa: - if(!alsaSetInputVoxLevel(card,stream,level)) { - cae_server->sendCommand(id,QString().sprintf("IX %u %u %d -!", - card,stream,level)); - return; - } - break; - - case RDStation::Jack: - if(!jackSetInputVoxLevel(card,stream,level)) { - cae_server->sendCommand(id,QString().sprintf("IX %u %u %d -!", - card,stream,level)); - return; - } - break; - - default: + if(dvr==NULL) { cae_server->sendCommand(id,QString().sprintf("IX %u %u %d -!", card,stream,level)); return; } - if(rd_config->enableMixerLogging()) { - RDApplication::syslog(rd_config,LOG_INFO, + if(!dvr->setInputVoxLevel(card,stream,level)) { + cae_server->sendCommand(id,QString().sprintf("IX %u %u %d -!", + card,stream,level)); + return; + } + if(rda->config()->enableMixerLogging()) { + rda->syslog(LOG_INFO, "SetInputVOXLevel - Card: %d Stream: %d Level: %d", card,stream,level); } @@ -1276,38 +919,20 @@ void MainObject::setInputVoxLevelData(int id,unsigned card,unsigned stream, void MainObject::setInputTypeData(int id,unsigned card,unsigned port, unsigned type) { - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiSetInputType(card,port,type)) { - cae_server->sendCommand(id,QString().sprintf("IT %u %u %u -!", - card,port,type)); - return; - } - break; + CaeDriver *dvr=GetDriver(card); - case RDStation::Alsa: - if(!alsaSetInputType(card,port,type)) { - cae_server->sendCommand(id,QString().sprintf("IT %u %u %u -!", - card,port,type)); - return; - } - break; - - case RDStation::Jack: - if(!jackSetInputType(card,port,type)) { - cae_server->sendCommand(id,QString().sprintf("IT %u %u %u -!", - card,port,type)); - return; - } - break; - - default: + if(dvr==NULL) { cae_server->sendCommand(id,QString().sprintf("IT %u %u %u -!", card,port,type)); return; } - if(rd_config->enableMixerLogging()) { - RDApplication::syslog(rd_config,LOG_INFO, + if(!dvr->setInputType(card,port,type)) { + cae_server->sendCommand(id,QString().sprintf("IT %u %u %u -!", + card,port,type)); + return; + } + if(rda->config()->enableMixerLogging()) { + rda->syslog(LOG_INFO, "SetInputType - Card: %d Port: %d Type: %d", card,port,type); } @@ -1318,11 +943,18 @@ void MainObject::setInputTypeData(int id,unsigned card,unsigned port, void MainObject::getInputStatusData(int id,unsigned card,unsigned port) { - if(hpiGetInputStatus(card,port)) { - cae_server->sendCommand(id,QString().sprintf("IS %d %d 0 +!",card,port)); + CaeDriver *dvr=GetDriver(card); + + if(dvr==NULL) { + return; } - else { - cae_server->sendCommand(id,QString().sprintf("IS %d %d 1 +!",card,port)); + if(dvr->driverType()==RDStation::Hpi) { + if(dvr->getInputStatus(card,port)) { + cae_server->sendCommand(id,QString().sprintf("IS %d %d 0 +!",card,port)); + } + else { + cae_server->sendCommand(id,QString().sprintf("IS %d %d 1 +!",card,port)); + } } } @@ -1331,38 +963,20 @@ void MainObject::setAudioPassthroughLevelData(int id,unsigned card, unsigned input,unsigned output, int level) { - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiSetPassthroughLevel(card,input,output,level)) { - cae_server->sendCommand(id,QString().sprintf("AL %u %u %u %d -!", - card,input,output,level)); - return; - } - break; + CaeDriver *dvr=GetDriver(card); - case RDStation::Alsa: - if(!alsaSetPassthroughLevel(card,input,output,level)) { - cae_server->sendCommand(id,QString().sprintf("AL %u %u %u %d -!", - card,input,output,level)); - return; - } - break; - - case RDStation::Jack: - if(!jackSetPassthroughLevel(card,input,output,level)) { - cae_server->sendCommand(id,QString().sprintf("AL %u %u %u %d -!", - card,input,output,level)); - return; - } - break; - - default: + if(dvr==NULL) { cae_server->sendCommand(id,QString().sprintf("AL %u %u %u %d -!", card,input,output,level)); return; } - if(rd_config->enableMixerLogging()) { - RDApplication::syslog(rd_config,LOG_INFO, + if(!dvr->setPassthroughLevel(card,input,output,level)) { + cae_server->sendCommand(id,QString().sprintf("AL %u %u %u %d -!", + card,input,output,level)); + return; + } + if(rda->config()->enableMixerLogging()) { + rda->syslog(LOG_INFO, "SetPassthroughLevel - Card: %d InPort: %d OutPort: %d Level: %d", card,input,output,level); } @@ -1377,19 +991,24 @@ void MainObject::setClockSourceData(int id,unsigned card,int input) cae_server->sendCommand(id,QString().sprintf("CS %u %u -!",card,input)); return; } - switch(cae_driver[card]) { - case RDStation::Hpi: - if(!hpiSetClockSource(card,input)) { - cae_server->sendCommand(id,QString().sprintf("CS %u %u -!",card,input)); - return; - } + CaeDriver *dvr=GetDriver(card); - default: + if(dvr==NULL) { cae_server->sendCommand(id,QString().sprintf("CS %u %u +!",card,input)); return; } - if(rd_config->enableMixerLogging()) { - RDApplication::syslog(rd_config,LOG_INFO, + if(dvr->driverType()==RDStation::Hpi) { + if(!dvr->setClockSource(card,input)) { + cae_server->sendCommand(id,QString().sprintf("CS %u %u -!",card,input)); + return; + } + } + else { + cae_server->sendCommand(id,QString().sprintf("CS %u %u +!",card,input)); + return; + } + if(rda->config()->enableMixerLogging()) { + rda->syslog(LOG_INFO, "SetClockSource - Card: %d Source: %d",card,input); } cae_server->sendCommand(id,QString().sprintf("CS %u %u +!",card,input)); @@ -1512,10 +1131,15 @@ void MainObject::updateMeters() unsigned positions[RD_MAX_STREAMS]; if(exiting) { + /* jackFree(); alsaFree(); hpiFree(); - RDApplication::syslog(rd_config,LOG_INFO,"cae exiting"); + */ + for(int i=0;isyslog(LOG_INFO,"cae exiting"); exit(0); } @@ -1523,6 +1147,34 @@ void MainObject::updateMeters() JackClock(); for(int i=0;igetInputStatus(i,j)!=port_status[i][j]) { + port_status[i][j]=dvr->getInputStatus(i,j); + if(port_status[i][j]) { + cae_server->sendCommand(QString().sprintf("IS %d %d 0!",i,j)); + } + else { + cae_server->sendCommand(QString().sprintf("IS %d %d 1!",i,j)); + } + } + if(dvr->getInputMeters(i,j,levels)) { + SendMeterLevelUpdate("I",i,j,levels); + } + if(dvr->getOutputMeters(i,j,levels)) { + SendMeterLevelUpdate("O",i,j,levels); + } + } + dvr->getOutputPosition(i,positions); + SendMeterPositionUpdate(i,positions); + for(int j=0;jgetStreamOutputMeters(i,j,levels)) { + SendStreamMeterLevelUpdate(i,j,levels); + } + } + } + /* switch(cae_driver[i]) { case RDStation::Hpi: for(int j=0;jprovisioningCreateHost()) { - if(!rd_config->provisioningHostTemplate().isEmpty()) { + if(rda->config()->provisioningCreateHost()) { + if(!rda->config()->provisioningHostTemplate().isEmpty()) { sql=QString("select `NAME` from `STATIONS` where ")+ - "`NAME`='"+RDEscapeString(rd_config->stationName())+"'"; + "`NAME`='"+RDEscapeString(rda->config()->stationName())+"'"; q=new RDSqlQuery(sql); if(!q->first()) { - if(RDStation::create(rd_config->stationName(),&err_msg,rd_config->provisioningHostTemplate(),rd_config->provisioningHostIpAddress())) { - RDApplication::syslog(rd_config,LOG_INFO, + if(RDStation::create(rda->config()->stationName(),&err_msg,rda->config()->provisioningHostTemplate(),rda->config()->provisioningHostIpAddress())) { + rda->syslog(LOG_INFO, "created new host entry \"%s\"", - rd_config->stationName().toUtf8().constData()); - if(!rd_config->provisioningHostShortName(rd_config->stationName()). + rda->config()->stationName().toUtf8().constData()); + if(!rda->config()->provisioningHostShortName(rda->config()->stationName()). isEmpty()) { - RDStation *station=new RDStation(rd_config->stationName()); - station->setShortName(rd_config-> - provisioningHostShortName(rd_config->stationName())); + RDStation *station=new RDStation(rda->config()->stationName()); + station->setShortName(rda->config()-> + provisioningHostShortName(rda->config()->stationName())); delete station; } } @@ -1644,17 +1297,17 @@ void MainObject::InitProvisioning() const // // Provision a Service // - if(rd_config->provisioningCreateService()) { - if(!rd_config->provisioningServiceTemplate().isEmpty()) { + if(rda->config()->provisioningCreateService()) { + if(!rda->config()->provisioningServiceTemplate().isEmpty()) { QString svcname= - rd_config->provisioningServiceName(rd_config->stationName()); + rda->config()->provisioningServiceName(rda->config()->stationName()); sql=QString("select `NAME` from `SERVICES` where ")+ "`NAME`='"+RDEscapeString(svcname)+"'"; q=new RDSqlQuery(sql); if(!q->first()) { if(RDSvc::create(svcname,&err_msg, - rd_config->provisioningServiceTemplate(),rd_config)) { - RDApplication::syslog(rd_config,LOG_INFO, + rda->config()->provisioningServiceTemplate(),rda->config())) { + rda->syslog(LOG_INFO, "created new service entry \"%s\"", svcname.toUtf8().constData()); } @@ -1673,62 +1326,25 @@ void MainObject::InitProvisioning() const void MainObject::InitMixers() { for(int i=0;istationName(),i); - switch(cae_driver[i]) { - case RDStation::Hpi: - hpiSetClockSource(i,port->clockSource()); + RDAudioPort *port=new RDAudioPort(rda->config()->stationName(),i); + CaeDriver *dvr=GetDriver(i); + + if(dvr!=NULL) { + dvr->setClockSource(i,port->clockSource()); for(int j=0;jsetPassthroughLevel(i,j,k,RD_MUTE_DEPTH); } if(port->inputPortType(j)==RDAudioPort::Analog) { - hpiSetInputType(i,j,RDCae::Analog); + dvr->setInputType(i,j,RDCae::Analog); } else { - hpiSetInputType(i,j,RDCae::AesEbu); + dvr->setInputType(i,j,RDCae::AesEbu); } - hpiSetInputLevel(i,j,RD_BASE_ANALOG+port->inputPortLevel(j)); - hpiSetOutputLevel(i,j,RD_BASE_ANALOG+port->outputPortLevel(j)); - hpiSetInputMode(i,j,port->inputPortMode(j)); + dvr->setInputLevel(i,j,RD_BASE_ANALOG+port->inputPortLevel(j)); + dvr->setOutputLevel(i,j,RD_BASE_ANALOG+port->outputPortLevel(j)); + dvr->setInputMode(i,j,port->inputPortMode(j)); } - break; - - case RDStation::Jack: - for(int j=0;jinputPortType(j)==RDAudioPort::Analog) { - jackSetInputType(i,j,RDCae::Analog); - } - else { - jackSetInputType(i,j,RDCae::AesEbu); - } - jackSetInputLevel(i,j,RD_BASE_ANALOG+port->inputPortLevel(j)); - jackSetOutputLevel(i,j,RD_BASE_ANALOG+port->outputPortLevel(j)); - jackSetInputMode(i,j,port->inputPortMode(j)); - } - break; - - case RDStation::Alsa: - for(int j=0;jinputPortType(j)==RDAudioPort::Analog) { - alsaSetInputType(i,j,RDCae::Analog); - } - else { - alsaSetInputType(i,j,RDCae::AesEbu); - } - alsaSetInputLevel(i,j,RD_BASE_ANALOG+port->inputPortLevel(j)); - alsaSetOutputLevel(i,j,RD_BASE_ANALOG+port->outputPortLevel(j)); - alsaSetInputMode(i,j,port->inputPortMode(j)); - } - break; - - case RDStation::None: - break; } delete port; } @@ -1738,56 +1354,29 @@ void MainObject::InitMixers() void MainObject::KillSocket(int ch) { for(int i=0;isyslog(LOG_DEBUG,"force unloading record context for connection %s:%u: Card: %d Stream: %d Handle: %d", cae_server->peerAddress(ch).toString().toUtf8().constData(), 0xFFFF&cae_server->peerPort(ch), i,j,GetHandle(i,j)); unsigned len=0; - switch(cae_driver[i]) { - case RDStation::Hpi: - hpiUnloadRecord(i,j,&len); - break; - - case RDStation::Jack: - jackUnloadRecord(i,j,&len); - break; - - case RDStation::Alsa: - alsaUnloadRecord(i,j,&len); - break; - - default: - RDApplication::syslog(rd_config,LOG_DEBUG, - "tried to kill unowned socket!"); - break; + if(dvr!=NULL) { + dvr->unloadRecord(i,j,&len); } record_length[i][j]=0; record_threshold[i][j]=-10000; record_owner[i][j]=-1; } if(play_owner[i][j]==ch) { - RDApplication::syslog(rd_config,LOG_DEBUG,"force unloading play context for connection %d [%s:%u]: Card: %d Stream: %d Handle: %d", + rda->syslog(LOG_DEBUG,"force unloading play context for connection %d [%s:%u]: Card: %d Stream: %d Handle: %d", ch, cae_server->peerAddress(ch).toString().toUtf8().constData(), 0xFFFF&cae_server->peerPort(ch), i,j,GetHandle(i,j)); - switch(cae_driver[i]) { - case RDStation::Hpi: - hpiUnloadPlayback(i,j); - break; - - case RDStation::Jack: - jackUnloadPlayback(i,j); - break; - - case RDStation::Alsa: - alsaUnloadPlayback(i,j); - break; - - case RDStation::None: - break; + if(dvr!=NULL) { + dvr->unloadPlayback(i,j); } play_owner[i][j]=-1; play_length[i][j]=0; @@ -1886,6 +1475,7 @@ void MainObject::ProbeCaps(RDStation *station) // station->setHaveCapability(RDStation::HaveMp4Decode,CheckMp4Decode()); + /* #ifdef HPI station->setDriverVersion(RDStation::Hpi,hpiVersion()); #else @@ -1908,6 +1498,7 @@ void MainObject::ProbeCaps(RDStation *station) #else station->setDriverVersion(RDStation::Alsa,""); #endif // ALSA + */ } @@ -1949,7 +1540,7 @@ bool MainObject::LoadTwoLame() { #ifdef HAVE_TWOLAME if((twolame_handle=dlopen("libtwolame.so.0",RTLD_NOW))==NULL) { - RDApplication::syslog(rd_config,LOG_INFO, + rda->syslog(LOG_INFO, "TwoLAME encoder library not found, MPEG L2 encoding not supported"); return false; } @@ -1974,11 +1565,11 @@ bool MainObject::LoadTwoLame() dlsym(twolame_handle,"twolame_encode_flush"); *(void **)(&twolame_set_energy_levels)= dlsym(twolame_handle,"twolame_set_energy_levels"); - RDApplication::syslog(rd_config,LOG_INFO, + rda->syslog(LOG_INFO, "Found TwoLAME encoder library, MPEG L2 encoding supported"); return true; #else - RDApplication::syslog(rd_config,LOG_INFO,"MPEG L2 encoding not enabled"); + rda->syslog(LOG_INFO,"MPEG L2 encoding not enabled"); return false; #endif // HAVE_TWOLAME @@ -2001,7 +1592,7 @@ bool MainObject::InitTwoLameEncoder(int card,int stream,int chans,int samprate, break; } if((twolame_lameopts[card][stream]=twolame_init())==NULL) { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "unable to initialize twolame instance, card=%d, stream=%d", card,stream); return false; @@ -2013,7 +1604,7 @@ bool MainObject::InitTwoLameEncoder(int card,int stream,int chans,int samprate, twolame_set_bitrate(twolame_lameopts[card][stream],bitrate/1000); twolame_set_energy_levels(twolame_lameopts[card][stream],1); if(twolame_init_params(twolame_lameopts[card][stream])!=0) { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "invalid twolame parameters, card=%d, stream=%d, chans=%d, samprate=%d bitrate=%d", card,stream,chans,samprate,bitrate); return false; @@ -2040,7 +1631,7 @@ bool MainObject::LoadMad() { #ifdef HAVE_MAD if((mad_handle=dlopen("libmad.so.0",RTLD_NOW))==NULL) { - RDApplication::syslog(rd_config,LOG_INFO, + rda->syslog(LOG_INFO, "MAD decoder library not found, MPEG L2 decoding not supported"); return false; } @@ -2060,11 +1651,11 @@ bool MainObject::LoadMad() dlsym(mad_handle,"mad_frame_finish"); *(void **)(&mad_stream_finish)= dlsym(mad_handle,"mad_stream_finish"); - RDApplication::syslog(rd_config,LOG_INFO, + rda->syslog(LOG_INFO, "Found MAD decoder library, MPEG L2 decoding supported"); return true; #else - RDApplication::syslog(rd_config,LOG_INFO,"MPEG L2 decoding not enabled"); + rda->syslog(LOG_INFO,"MPEG L2 decoding not enabled"); return false; #endif // HAVE_MAD } @@ -2192,12 +1783,23 @@ void MainObject::SendMeterUpdate(const QString &msg,int conn_id) } +CaeDriver *MainObject::GetDriver(unsigned card) const +{ + for(int i=0;ihasCard(card)) { + return d_drivers.at(i); + } + } + return NULL; +} + + int main(int argc,char *argv[]) { int rc; QCoreApplication a(argc,argv,false); new MainObject(); rc=a.exec(); - RDApplication::syslog(rd_config,LOG_DEBUG,"cae post a.exec() rc: %d",rc); + rda->syslog(LOG_DEBUG,"cae post a.exec() rc: %d",rc); return rc; } diff --git a/cae/cae.h b/cae/cae.h index 7fff9008..010e685c 100644 --- a/cae/cae.h +++ b/cae/cae.h @@ -74,6 +74,7 @@ struct alsa_format { #include #include +#include "caedriver.h" #include "cae_server.h" #ifndef HAVE_SRC_CONV @@ -96,7 +97,7 @@ void src_float_to_int_array (const float *in, int *out, int len); // Function Prototypes // void SigHandler(int signum); -extern RDConfig *rd_config; +//extern RDConfig *rd_config; class MainObject : public QObject { @@ -183,12 +184,19 @@ class MainObject : public QObject int owner; } play_handle[256]; int next_play_handle; - RDStation *cae_station; + // RDStation *cae_station; + + // + // New Stuff + // + CaeDriver *GetDriver(unsigned card) const; + QList d_drivers; // // HPI Driver // private: + /* void hpiInit(RDStation *station); void hpiFree(); QString hpiVersion(); @@ -225,6 +233,7 @@ class MainObject : public QObject RDHPIRecordStream *record[RD_MAX_CARDS][RD_MAX_STREAMS]; RDHPIPlayStream *play[RD_MAX_CARDS][RD_MAX_STREAMS]; #endif // HPI + */ // // JACK Driver diff --git a/cae/cae_alsa.cpp b/cae/cae_alsa.cpp index 8be6146d..059bf13d 100644 --- a/cae/cae_alsa.cpp +++ b/cae/cae_alsa.cpp @@ -69,14 +69,13 @@ void *AlsaCaptureCallback(void *ptr) while(!alsa_format->exiting) { int s=snd_pcm_readi(alsa_format->pcm,alsa_format->card_buffer, - rd_config->alsaPeriodSize()/(alsa_format->periods*2)); + rda->config()->alsaPeriodSize()/(alsa_format->periods*2)); if(((snd_pcm_state(alsa_format->pcm)!=SND_PCM_STATE_RUNNING)&& (!alsa_format->exiting))||(s<0)) { snd_pcm_drop (alsa_format->pcm); snd_pcm_prepare(alsa_format->pcm); - RDApplication::syslog(rd_config,LOG_DEBUG, - "****** ALSA Capture Xrun - Card: %d ******", - alsa_format->card); + rda->syslog(LOG_DEBUG,"****** ALSA Capture Xrun - Card: %d ******", + alsa_format->card); } else { switch(alsa_format->format) { @@ -512,11 +511,11 @@ void *AlsaPlayCallback(void *ptr) int s=snd_pcm_writei(alsa_format->pcm,alsa_format->card_buffer,n); if(s!=n) { if(s<0) { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "*** alsa error %d: %s",-s,snd_strerror(s)); } else { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "period size mismatch - wrote %d",s); } } @@ -524,7 +523,7 @@ void *AlsaPlayCallback(void *ptr) (!alsa_format->exiting)) { snd_pcm_drop (alsa_format->pcm); snd_pcm_prepare(alsa_format->pcm); - RDApplication::syslog(rd_config,LOG_DEBUG, + rda->syslog(LOG_DEBUG, "****** ALSA Playout Xrun - Card: %d ******", alsa_format->card); } @@ -537,7 +536,7 @@ void *AlsaPlayCallback(void *ptr) void MainObject::AlsaInitCallback() { int avg_periods= - (330*system_sample_rate)/(1000*rd_config->alsaPeriodSize()); + (330*system_sample_rate)/(1000*rda->config()->alsaPeriodSize()); for(int i=0;istop(); } } - RDApplication::syslog(rd_config,LOG_DEBUG,"FadeLevel: %d",level); + rda->syslog(LOG_DEBUG,"FadeLevel: %d",level); alsaSetOutputVolume(card,stream,alsa_fade_port[card][stream],level); #endif // ALSA } @@ -726,7 +725,7 @@ void MainObject::alsaInit(RDStation *station) if(cae_driver[i]==RDStation::Alsa) { station->setCardDriver(i,RDStation::Alsa); if(snd_ctl_open(&snd_ctl,dev.toUtf8(),0)<0) { - RDApplication::syslog(rd_config,LOG_INFO, + rda->syslog(LOG_INFO, "no control device found for %s", dev.toUtf8().constData()); station->setCardName(i,tr("ALSA Device")+" "+dev); @@ -784,14 +783,14 @@ bool MainObject::alsaLoadPlayback(int card,QString wavename,int *stream) { #ifdef ALSA if(alsa_play_format[card].exiting||((*stream=GetAlsaOutputStream(card))<0)) { - RDApplication::syslog(rd_config,LOG_DEBUG, + rda->syslog(LOG_DEBUG, "alsaLoadPlayback(%s) GetAlsaOutputStream():%d < 0", (const char *)wavename.toUtf8(),*stream); return false; } alsa_play_wave[card][*stream]=new RDWaveFile(wavename); if(!alsa_play_wave[card][*stream]->openWave()) { - RDApplication::syslog(rd_config,LOG_DEBUG, + rda->syslog(LOG_DEBUG, "alsaLoadPlayback(%s) openWave() failed to open file", (const char *)wavename.toUtf8()); delete alsa_play_wave[card][*stream]; @@ -810,7 +809,7 @@ bool MainObject::alsaLoadPlayback(int card,QString wavename,int *stream) break; default: - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "alsaLoadPlayback(%s) getFormatTag()%d || getBistsPerSample()%d failed", (const char *)wavename.toUtf8(), alsa_play_wave[card][*stream]->getFormatTag(), @@ -998,7 +997,7 @@ bool MainObject::alsaLoadRecord(int card,int stream,int coding,int chans, break; default: - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "requested unsupported channel count %d, card: %d, stream: %d", chans,card,stream); delete alsa_record_wave[card][stream]; @@ -1026,7 +1025,7 @@ bool MainObject::alsaLoadRecord(int card,int stream,int coding,int chans, break; default: - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "requested invalid audio encoding %d, card: %d, stream: %d", coding,card,stream); delete alsa_record_wave[card][stream]; @@ -1040,8 +1039,8 @@ bool MainObject::alsaLoadRecord(int card,int stream,int coding,int chans, alsa_record_wave[card][stream]=NULL; return false; } - RDCheckExitCode(rd_config,"alsaLoadRecord() chown", - chown(wavename.toUtf8(),rd_config->uid(),rd_config->gid())); + RDCheckExitCode(rda->config(),"alsaLoadRecord() chown", + chown(wavename.toUtf8(),rda->config()->uid(),rda->config()->gid())); alsa_input_channels[card][stream]=chans; alsa_record_ring[card][stream]=new RDRingBuffer(RINGBUFFER_SIZE); alsa_record_ring[card][stream]->reset(); @@ -1367,7 +1366,7 @@ bool MainObject::AlsaStartCaptureDevice(QString &dev,int card,snd_pcm_t *pcm) snd_pcm_hw_params_alloca(&hwparams); snd_pcm_hw_params_any(pcm,hwparams); - RDApplication::syslog(rd_config,LOG_INFO,"Starting ALSA Capture Device %s:", + rda->syslog(LOG_INFO,"Starting ALSA Capture Device %s:", (const char *)dev.toUtf8()); // @@ -1375,9 +1374,9 @@ bool MainObject::AlsaStartCaptureDevice(QString &dev,int card,snd_pcm_t *pcm) // if(snd_pcm_hw_params_test_access(pcm,hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)<0) { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, " Interleaved access not supported,"); - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, " aborting initialization of device."); return false; } @@ -1388,18 +1387,18 @@ bool MainObject::AlsaStartCaptureDevice(QString &dev,int card,snd_pcm_t *pcm) // if(snd_pcm_hw_params_test_format(pcm,hwparams,SND_PCM_FORMAT_S32_LE)==0) { alsa_capture_format[card].format=SND_PCM_FORMAT_S32_LE; - RDApplication::syslog(rd_config,LOG_INFO," Format = 32 bit little-endian"); + rda->syslog(LOG_INFO," Format = 32 bit little-endian"); } else { if(snd_pcm_hw_params_test_format(pcm,hwparams,SND_PCM_FORMAT_S16_LE)==0) { alsa_capture_format[card].format=SND_PCM_FORMAT_S16_LE; - RDApplication::syslog(rd_config,LOG_INFO, + rda->syslog(LOG_INFO, " Format = 16 bit little-endian"); } else { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, " Neither 16 nor 32 bit little-endian formats available,"); - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, " aborting initialization of device."); return false; } @@ -1418,57 +1417,57 @@ bool MainObject::AlsaStartCaptureDevice(QString &dev,int card,snd_pcm_t *pcm) snd_pcm_hw_params_set_rate_near(pcm,hwparams,&sr,&dir); if((sr<(system_sample_rate-RD_ALSA_SAMPLE_RATE_TOLERANCE))|| (sr>(system_sample_rate+RD_ALSA_SAMPLE_RATE_TOLERANCE))) { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, " Asked for sample rate %u, got %u", system_sample_rate,sr); - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, " Sample rate unsupported by device"); return false; } alsa_capture_format[card].sample_rate=sr; - RDApplication::syslog(rd_config,LOG_INFO," SampleRate = %u",sr); + rda->syslog(LOG_INFO," SampleRate = %u",sr); // // Channels // - if(rd_config->alsaChannelsPerPcm()<0) { + if(rda->config()->alsaChannelsPerPcm()<0) { alsa_capture_format[card].channels=RD_DEFAULT_CHANNELS*RD_MAX_PORTS; } else { - alsa_capture_format[card].channels=rd_config->alsaChannelsPerPcm(); + alsa_capture_format[card].channels=rda->config()->alsaChannelsPerPcm(); } snd_pcm_hw_params_set_channels_near(pcm,hwparams, &alsa_capture_format[card].channels); alsa_play_format[card].capture_channels=alsa_capture_format[card].channels; - RDApplication::syslog(rd_config,LOG_INFO," Aggregate Channels = %u", + rda->syslog(LOG_INFO," Aggregate Channels = %u", alsa_capture_format[card].channels); // // Buffer Size // - alsa_capture_format[card].periods=rd_config->alsaPeriodQuantity(); + alsa_capture_format[card].periods=rda->config()->alsaPeriodQuantity(); snd_pcm_hw_params_set_periods_near(pcm,hwparams, &alsa_capture_format[card].periods,&dir); - RDApplication::syslog(rd_config,LOG_INFO, + rda->syslog(LOG_INFO, " Periods = %u",alsa_capture_format[card].periods); alsa_capture_format[card].buffer_size= - alsa_capture_format[card].periods*rd_config->alsaPeriodSize(); + alsa_capture_format[card].periods*rda->config()->alsaPeriodSize(); snd_pcm_hw_params_set_buffer_size_near(pcm,hwparams, &alsa_capture_format[card].buffer_size); - RDApplication::syslog(rd_config,LOG_INFO," BufferSize = %u frames", + rda->syslog(LOG_INFO," BufferSize = %u frames", (unsigned)alsa_capture_format[card].buffer_size); // // Fire It Up // if((err=snd_pcm_hw_params(pcm,hwparams))<0) { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, " Device Error: %s,",snd_strerror(err)); - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, " aborting initialization of device."); return false; } - RDApplication::syslog(rd_config,LOG_INFO," Device started successfully"); + rda->syslog(LOG_INFO," Device started successfully"); switch(alsa_capture_format[card].format) { case SND_PCM_FORMAT_S16_LE: alsa_capture_format[card].card_buffer_size= @@ -1496,9 +1495,9 @@ bool MainObject::AlsaStartCaptureDevice(QString &dev,int card,snd_pcm_t *pcm) // snd_pcm_sw_params_alloca(&swparams); snd_pcm_sw_params_current(pcm,swparams); - snd_pcm_sw_params_set_avail_min(pcm,swparams,rd_config->alsaPeriodSize()); + snd_pcm_sw_params_set_avail_min(pcm,swparams,rda->config()->alsaPeriodSize()); if((err=snd_pcm_sw_params(pcm,swparams))<0) { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "ALSA Device %s: %s",(const char *)dev.toUtf8(), snd_strerror(err)); return false; @@ -1534,7 +1533,7 @@ bool MainObject::AlsaStartPlayDevice(QString &dev,int card,snd_pcm_t *pcm) snd_pcm_hw_params_alloca(&hwparams); snd_pcm_hw_params_any(pcm,hwparams); - RDApplication::syslog(rd_config,LOG_INFO,"Starting ALSA Play Device %s:", + rda->syslog(LOG_INFO,"Starting ALSA Play Device %s:", (const char *)dev.toUtf8()); // @@ -1542,9 +1541,9 @@ bool MainObject::AlsaStartPlayDevice(QString &dev,int card,snd_pcm_t *pcm) // if(snd_pcm_hw_params_test_access(pcm,hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)<0) { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, " Interleaved access not supported,"); - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, " aborting initialization of device."); return false; } @@ -1555,18 +1554,18 @@ bool MainObject::AlsaStartPlayDevice(QString &dev,int card,snd_pcm_t *pcm) // if(snd_pcm_hw_params_test_format(pcm,hwparams,SND_PCM_FORMAT_S32_LE)==0) { alsa_play_format[card].format=SND_PCM_FORMAT_S32_LE; - RDApplication::syslog(rd_config,LOG_INFO," Format = 32 bit little-endian"); + rda->syslog(LOG_INFO," Format = 32 bit little-endian"); } else { if(snd_pcm_hw_params_test_format(pcm,hwparams,SND_PCM_FORMAT_S16_LE)==0) { alsa_play_format[card].format=SND_PCM_FORMAT_S16_LE; - RDApplication::syslog(rd_config,LOG_INFO, + rda->syslog(LOG_INFO, " Format = 16 bit little-endian"); } else { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, " Neither 16 nor 32 bit little-endian formats available,"); - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, " aborting initialization of device."); return false; } @@ -1580,55 +1579,55 @@ bool MainObject::AlsaStartPlayDevice(QString &dev,int card,snd_pcm_t *pcm) snd_pcm_hw_params_set_rate_near(pcm,hwparams,&sr,&dir); if((sr<(system_sample_rate-RD_ALSA_SAMPLE_RATE_TOLERANCE))|| (sr>(system_sample_rate+RD_ALSA_SAMPLE_RATE_TOLERANCE))) { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, " Asked for sample rate %u, got %u", system_sample_rate,sr); - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, " Sample rate unsupported by device"); return false; } alsa_play_format[card].sample_rate=sr; - RDApplication::syslog(rd_config,LOG_INFO," SampleRate = %u",sr); + rda->syslog(LOG_INFO," SampleRate = %u",sr); // // Channels // - if(rd_config->alsaChannelsPerPcm()<0) { + if(rda->config()->alsaChannelsPerPcm()<0) { alsa_play_format[card].channels=RD_DEFAULT_CHANNELS*RD_MAX_PORTS; } else { - alsa_play_format[card].channels=rd_config->alsaChannelsPerPcm(); + alsa_play_format[card].channels=rda->config()->alsaChannelsPerPcm(); } snd_pcm_hw_params_set_channels_near(pcm,hwparams, &alsa_play_format[card].channels); - RDApplication::syslog(rd_config,LOG_INFO," Aggregate Channels = %u", + rda->syslog(LOG_INFO," Aggregate Channels = %u", alsa_play_format[card].channels); // // Buffer Size // - alsa_play_format[card].periods=rd_config->alsaPeriodQuantity(); + alsa_play_format[card].periods=rda->config()->alsaPeriodQuantity(); snd_pcm_hw_params_set_periods_near(pcm,hwparams, &alsa_play_format[card].periods,&dir); - RDApplication::syslog(rd_config,LOG_INFO, + rda->syslog(LOG_INFO, " Periods = %u",alsa_play_format[card].periods); alsa_play_format[card].buffer_size= - alsa_play_format[card].periods*rd_config->alsaPeriodSize(); + alsa_play_format[card].periods*rda->config()->alsaPeriodSize(); snd_pcm_hw_params_set_buffer_size_near(pcm,hwparams, &alsa_play_format[card].buffer_size); - RDApplication::syslog(rd_config,LOG_INFO," BufferSize = %u frames", + rda->syslog(LOG_INFO," BufferSize = %u frames", (unsigned)alsa_play_format[card].buffer_size); // // Fire It Up // if((err=snd_pcm_hw_params(pcm,hwparams))<0) { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, " Device Error: %s,",snd_strerror(err)); - RDApplication::syslog(rd_config,LOG_ERR, + rda->syslog(LOG_ERR, " aborting initialization of device."); return false; } - RDApplication::syslog(rd_config,LOG_INFO," Device started successfully"); + rda->syslog(LOG_INFO," Device started successfully"); switch(alsa_play_format[card].format) { case SND_PCM_FORMAT_S16_LE: alsa_play_format[card].card_buffer_size= @@ -1655,9 +1654,9 @@ bool MainObject::AlsaStartPlayDevice(QString &dev,int card,snd_pcm_t *pcm) // snd_pcm_sw_params_alloca(&swparams); snd_pcm_sw_params_current(pcm,swparams); - snd_pcm_sw_params_set_avail_min(pcm,swparams,rd_config->alsaPeriodSize()); + snd_pcm_sw_params_set_avail_min(pcm,swparams,rda->config()->alsaPeriodSize()); if((err=snd_pcm_sw_params(pcm,swparams))<0) { - RDApplication::syslog(rd_config,LOG_WARNING,"ALSA Device %s: %s", + rda->syslog(LOG_WARNING,"ALSA Device %s: %s", (const char *)dev.toUtf8(),snd_strerror(err)); return false; } @@ -1748,7 +1747,7 @@ void MainObject::WriteAlsaBuffer(int card,int stream,int16_t *buffer,unsigned le alsa_record_wave[card][stream]->writeWave(mpeg,s); } else { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "TwoLAME encode error, card: %d, stream: %d", card,stream); } diff --git a/cae/cae_hpi.cpp b/cae/cae_hpi.cpp index 6a5d4a36..aed467ba 100644 --- a/cae/cae_hpi.cpp +++ b/cae/cae_hpi.cpp @@ -25,7 +25,7 @@ #include #include "cae.h" - +/* void MainObject::hpiInit(RDStation *station) { #ifdef HPI @@ -529,3 +529,4 @@ bool MainObject::hpiSetPassthroughLevel(int card,int in_port,int out_port, return false; #endif // HPI } +*/ diff --git a/cae/cae_jack.cpp b/cae/cae_jack.cpp index 1dcfd3d0..96d37d5f 100644 --- a/cae/cae_jack.cpp +++ b/cae/cae_jack.cpp @@ -436,23 +436,23 @@ void MainObject::jackClientStartData() "`DESCRIPTION`,"+ // 00 "`COMMAND_LINE` "+ // 01 "from `JACK_CLIENTS` where "+ - "`STATION_NAME`='"+RDEscapeString(rd_config->stationName())+"'"; + "`STATION_NAME`='"+RDEscapeString(rda->config()->stationName())+"'"; RDSqlQuery *q=new RDSqlQuery(sql); while(q->next()) { QString cmd=RDDateDecode(q->value(1).toString(),QDate::currentDate(), - cae_station,rd_config, - rd_config->provisioningServiceName(rd_config->stationName())); + rda->station(),rda->config(), + rda->config()->provisioningServiceName(rda->config()->stationName())); QStringList args=cmd.split(" ",QString::SkipEmptyParts); QString program=args.at(0); args.removeFirst(); jack_clients.push_back(new QProcess(this)); jack_clients.back()->start(program,args); if(jack_clients.back()->waitForStarted()) { - RDApplication::syslog(rd_config,LOG_INFO,"started JACK Client \"%s\"", + rda->syslog(LOG_INFO,"started JACK Client \"%s\"", (const char *)q->value(0).toString().toUtf8()); } else { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "failed to start JACK Client \"%s\" [%s]", (const char *)q->value(0).toString().toUtf8(), (const char *)q->value(1).toString().toUtf8()); @@ -482,7 +482,7 @@ void MainObject::jackInit(RDStation *station) } } if(jack_card==RD_MAX_CARDS) { - RDApplication::syslog(rd_config,LOG_INFO,"no more RD cards available"); + rda->syslog(LOG_INFO,"no more RD cards available"); return; } QString name=QString().sprintf("rivendell_%d",jack_card); @@ -499,16 +499,16 @@ void MainObject::jackInit(RDStation *station) QProcess *proc=new QProcess(this); proc->start(program,args); if(proc->waitForStarted()) { - RDApplication::syslog(rd_config,LOG_INFO,"JACK server started"); + rda->syslog(LOG_INFO,"JACK server started"); } else { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "failed to start JACK server"); } sleep(1); } else { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "could not start JACK server: no command line specified"); } } @@ -528,70 +528,70 @@ void MainObject::jackInit(RDStation *station) if(jack_client==NULL) { if((jackstat&JackInvalidOption)!=0) { fprintf (stderr, "invalid or unsupported JACK option\n"); - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "invalid or unsupported JACK option"); } if((jackstat&JackServerError)!=0) { fprintf (stderr, "communication error with the JACK server\n"); - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "communication error with the JACK server"); } if((jackstat&JackNoSuchClient)!=0) { fprintf (stderr, "requested JACK client does not exist\n"); - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "requested JACK client does not exist"); } if((jackstat&JackLoadFailure)!=0) { fprintf (stderr, "unable to load internal JACK client\n"); - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "unable to load internal JACK client"); } if((jackstat&JackInitFailure)!=0) { fprintf (stderr, "unable to initialize JACK client\n"); - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "unable to initialize JACK client"); } if((jackstat&JackShmFailure)!=0) { fprintf (stderr, "unable to access JACK shared memory\n"); - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "unable to access JACK shared memory"); } if((jackstat&JackVersionError)!=0) { fprintf (stderr, "JACK protocol version mismatch\n"); - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "JACK protocol version mismatch"); } if((jackstat&JackServerStarted)!=0) { fprintf (stderr, "JACK server started\n"); - RDApplication::syslog(rd_config,LOG_WARNING,"JACK server started"); + rda->syslog(LOG_WARNING,"JACK server started"); } if((jackstat&JackServerFailed)!=0) { fprintf (stderr, "unable to communication with JACK server\n"); - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "unable to communicate with JACK server"); } if((jackstat&JackNameNotUnique)!=0) { fprintf (stderr, "JACK client name not unique\n"); - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "JACK client name not unique"); } if((jackstat&JackFailure)!=0) { fprintf (stderr, "JACK general failure\n"); - RDApplication::syslog(rd_config,LOG_WARNING,"JACK general failure"); + rda->syslog(LOG_WARNING,"JACK general failure"); } jack_card=-1; fprintf (stderr, "no connection to JACK server\n"); - RDApplication::syslog(rd_config,LOG_WARNING,"no connection to JACK server"); + rda->syslog(LOG_WARNING,"no connection to JACK server"); return; } jack_connected=true; @@ -603,7 +603,7 @@ void MainObject::jackInit(RDStation *station) #else jack_on_shutdown(jack_client,JackShutdown,0); #endif // HAVE_JACK_INFO_SHUTDOWN - RDApplication::syslog(rd_config,LOG_INFO,"connected to JACK server"); + rda->syslog(LOG_INFO,"connected to JACK server"); // // Start JACK Clients @@ -722,7 +722,7 @@ void MainObject::jackInit(RDStation *station) jack_sample_rate=jack_get_sample_rate(jack_client); if(jack_sample_rate!=system_sample_rate) { fprintf (stderr,"JACK sample rate mismatch!\n"); - RDApplication::syslog(rd_config,LOG_WARNING,"JACK sample rate mismatch!"); + rda->syslog(LOG_WARNING,"JACK sample rate mismatch!"); } jack_activated=true; cae_driver[jack_card]=RDStation::Jack; @@ -751,14 +751,14 @@ bool MainObject::jackLoadPlayback(int card,QString wavename,int *stream) { #ifdef JACK if((*stream=GetJackOutputStream())<0) { - RDApplication::syslog(rd_config,LOG_DEBUG, + rda->syslog(LOG_DEBUG, "jackLoadPlayback(%s) GetJackOutputStream():%d <0", (const char *)wavename.toUtf8(),*stream); return false; } jack_play_wave[*stream]=new RDWaveFile(wavename); if(!jack_play_wave[*stream]->openWave()) { - RDApplication::syslog(rd_config,LOG_DEBUG, + rda->syslog(LOG_DEBUG, "jackLoadPlayback(%s) openWave() failed to open file", (const char *)wavename.toUtf8()); delete jack_play_wave[*stream]; @@ -777,7 +777,7 @@ bool MainObject::jackLoadPlayback(int card,QString wavename,int *stream) break; default: - RDApplication::syslog(rd_config,LOG_DEBUG, + rda->syslog(LOG_DEBUG, "jackLoadPlayback(%s) getFormatTag()%d || getBistsPerSample()%d failed", (const char *) wavename.toUtf8(), jack_play_wave[*stream]->getFormatTag(), @@ -972,7 +972,7 @@ bool MainObject::jackLoadRecord(int card,int stream,int coding,int chans, break; default: - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "requested unsupported channel count %d, card: %d, stream: %d", chans,card,stream); delete jack_record_wave[stream]; @@ -1000,7 +1000,7 @@ bool MainObject::jackLoadRecord(int card,int stream,int coding,int chans, break; default: - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "requested invalid audio encoding %d, card: %d, stream: %d", coding,card,stream); delete jack_record_wave[stream]; @@ -1014,8 +1014,8 @@ bool MainObject::jackLoadRecord(int card,int stream,int coding,int chans, jack_record_wave[stream]=NULL; return false; } - RDCheckExitCode(rd_config,"jackLoadRecord() chown", - chown(wavename.toUtf8(),rd_config->uid(),rd_config->gid())); + RDCheckExitCode(rda->config(),"jackLoadRecord() chown", + chown(wavename.toUtf8(),rda->config()->uid(),rda->config()->gid())); jack_input_channels[stream]=chans; jack_record_ring[stream]=new RDRingBuffer(RINGBUFFER_SIZE); jack_record_ring[stream]->reset(); @@ -1477,7 +1477,7 @@ void MainObject::WriteJackBuffer(int stream,jack_default_audio_sample_t *buffer, jack_record_wave[stream]->writeWave(mpeg,s); } else { - RDApplication::syslog(rd_config,LOG_WARNING, + rda->syslog(LOG_WARNING, "TwoLAME encode error, card: %d, stream: %d",jack_card,stream); } } @@ -1681,7 +1681,7 @@ void MainObject::JackSessionSetup() QString dest=profile->stringValue("JackSession",dest_tag,"",&dest_ok); while(src_ok&&dest_ok) { if(jack_connect(jack_client,src.toUtf8(),dest.toUtf8())!=0) { - RDApplication::syslog(rd_config,LOG_WARNING,"unable to connect %s to %s", + rda->syslog(LOG_WARNING,"unable to connect %s to %s", (const char *)src.toUtf8(),(const char *)dest.toUtf8()); } count++; diff --git a/cae/cae_server.cpp b/cae/cae_server.cpp index 9140a812..b93cbd65 100644 --- a/cae/cae_server.cpp +++ b/cae/cae_server.cpp @@ -217,6 +217,7 @@ void CaeServer::connectionClosedData(int id) bool CaeServer::ProcessCommand(int id,const QString &cmd) { + printf("CaeServer::ProcessCommand(%d,'%s')\n",id,cmd.toUtf8().constData()); CaeServerConnection *conn=cae_connections.value(id); bool ok=false; QString cmdstr=cmd; diff --git a/cae/caedriver.cpp b/cae/caedriver.cpp new file mode 100644 index 00000000..0757930d --- /dev/null +++ b/cae/caedriver.cpp @@ -0,0 +1,65 @@ +// caedriver.cpp +// +// Abstract base class for caed(8) audio driver implementations. +// +// (C) Copyright 2021 Fred Gleason +// +// 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 +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public +// License along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#include "caedriver.h" + +CaeDriver::CaeDriver(RDStation::AudioDriver type,QObject *parent) + : QObject(parent) +{ + d_driver_type=type; +} + + +RDStation::AudioDriver CaeDriver::driverType() const +{ + return d_driver_type; +} + + +bool CaeDriver::hasCard(int cardnum) const +{ + return d_cards.contains(cardnum); +} + + +void CaeDriver::statePlayUpdate(int card,int stream,int state) +{ + emit playStateChanged(card,stream,state); +} + + +void CaeDriver::stateRecordUpdate(int card,int stream,int state) +{ + emit recordStateChanged(card,stream,state); +} + + +void CaeDriver::addCard(unsigned cardnum) +{ + if(d_cards.contains(cardnum)) { + rda->syslog(LOG_WARNING, + "%s driver attempted to register card %u multiple times", + RDStation::audioDriverText(d_driver_type).toUtf8().constData(), + cardnum); + } + else { + d_cards.push_back(cardnum); + } +} diff --git a/cae/caedriver.h b/cae/caedriver.h new file mode 100644 index 00000000..e587a636 --- /dev/null +++ b/cae/caedriver.h @@ -0,0 +1,90 @@ +// caedriver.h +// +// Abstract base class for caed(8) audio driver implementations. +// +// (C) Copyright 2021 Fred Gleason +// +// 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 +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public +// License along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#ifndef CAEDRIVER_H +#define CAEDRIVER_H + +#include +#include + +#include + +class CaeDriver : public QObject +{ + Q_OBJECT + public: + CaeDriver(RDStation::AudioDriver type,QObject *parent=0); + RDStation::AudioDriver driverType() const; + bool hasCard(int cardnum) const; + virtual QString version() const=0; + virtual bool initialize(unsigned *next_cardnum)=0;; + virtual void updateMeters()=0; + + public: + virtual bool loadPlayback(int card,QString wavename,int *stream)=0; + virtual bool unloadPlayback(int card,int stream)=0; + virtual bool playbackPosition(int card,int stream,unsigned pos)=0; + virtual bool play(int card,int stream,int length,int speed,bool pitch, + bool rates)=0; + virtual bool stopPlayback(int card,int stream)=0; + virtual bool timescaleSupported(int card)=0; + virtual bool loadRecord(int card,int port,int coding,int chans,int samprate, + int bitrate,QString wavename)=0; + virtual bool unloadRecord(int card,int stream,unsigned *len)=0; + virtual bool record(int card,int stream,int length,int thres)=0; + virtual bool stopRecord(int card,int stream)=0; + virtual bool setClockSource(int card,int src)=0; + virtual bool setInputVolume(int card,int stream,int level)=0; + virtual bool setOutputVolume(int card,int stream,int port,int level)=0; + virtual bool fadeOutputVolume(int card,int stream,int port,int level, + int length)=0; + virtual bool setInputLevel(int card,int port,int level)=0; + virtual bool setOutputLevel(int card,int port,int level)=0; + virtual bool setInputMode(int card,int stream,int mode)=0; + virtual bool setOutputMode(int card,int stream,int mode)=0; + virtual bool setInputVoxLevel(int card,int stream,int level)=0; + virtual bool setInputType(int card,int port,int type)=0; + virtual bool getInputStatus(int card,int port)=0; + virtual bool getInputMeters(int card,int port,short levels[2])=0; + virtual bool getOutputMeters(int card,int port,short levels[2])=0; + virtual bool getStreamOutputMeters(int card,int stream,short levels[2])=0; + virtual bool setPassthroughLevel(int card,int in_port,int out_port, + int level)=0; + virtual void getOutputPosition(int card,unsigned *pos)=0; + + signals: + void playStateChanged(int card,int stream,int state); + void recordStateChanged(int card,int stream,int state); + + protected slots: + void statePlayUpdate(int card,int stream,int state); + void stateRecordUpdate(int card,int stream,int state); + + protected: + void addCard(unsigned cardnum); + RDConfig *config() const; + + private: + RDStation::AudioDriver d_driver_type; + QList d_cards; +}; + + +#endif // CAEDRIVER_H diff --git a/cae/caedriverfactory.cpp b/cae/caedriverfactory.cpp new file mode 100644 index 00000000..96962d2e --- /dev/null +++ b/cae/caedriverfactory.cpp @@ -0,0 +1,43 @@ +// caedriverfactory.xpp +// +// Create CaeDriver instances. +// +// (C) Copyright 2021 Fred Gleason +// +// 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 +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public +// License along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#include "caedriverfactory.h" +#include "hpidriver.h" + +CaeDriver *CaeDriverFactory(RDStation::AudioDriver dvr,QObject *parent) +{ + CaeDriver *ret=NULL; + printf("HERE1\n"); + switch(dvr) { + case RDStation::Hpi: + printf("HERE2\n"); + ret=new HpiDriver(parent); + break; + + case RDStation::Jack: + case RDStation::Alsa: + case RDStation::None: + printf("HERE3\n"); + break; + } + printf("HERE4: %p\n",ret); + + return ret; +} diff --git a/cae/caedriverfactory.h b/cae/caedriverfactory.h new file mode 100644 index 00000000..3f25d0a4 --- /dev/null +++ b/cae/caedriverfactory.h @@ -0,0 +1,33 @@ +// caedriverfactory.h +// +// Create CaeDriver instances. +// +// (C) Copyright 2021 Fred Gleason +// +// 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 +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public +// License along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#ifndef CAEDRIVERFACTORY_H +#define CAEDRIVERFACTORY_H + +#include + +#include + +#include "caedriver.h" + +CaeDriver *CaeDriverFactory(RDStation::AudioDriver dvr,QObject *parent=0); + + +#endif // CAEDRIVERFACTORY_H diff --git a/cae/hpidriver.cpp b/cae/hpidriver.cpp new file mode 100644 index 00000000..40de751c --- /dev/null +++ b/cae/hpidriver.cpp @@ -0,0 +1,567 @@ +// hpidriver.cpp +// +// caed(8) driver for AudioScience HPI audio devices. +// +// (C) Copyright 2021 Fred Gleason +// +// 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 +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public +// License along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#include +#include "hpidriver.h" + +HpiDriver::HpiDriver(QObject *parent) + : CaeDriver(RDStation::Hpi,parent) +{ +#ifdef HPI + for(int i=0;iconfig(),this); +#endif // HPI +} + + +HpiDriver::~HpiDriver() +{ +#ifdef HPI + for(int i=0;ihpiInformation(0); + if(info->hpiVersion()==0) { + return tr("not active"); + } + return QString().sprintf("%d.%02d.%02d",info->hpiMajorVersion(), + info->hpiMinorVersion(),info->hpiPointVersion()); +#else + return tr("not enabled"); +#endif // HPI +} + + +bool HpiDriver::initialize(unsigned *next_cardnum) +{ +#ifdef HPI + d_sound_card->setFadeProfile(RD_FADE_TYPE); + for(int i=0;igetCardQuantity();i++) { + rda->station()->setCardDriver(i,RDStation::Hpi); + rda->station()->setCardName(i,d_sound_card->getCardDescription(i)); + rda->station()->setCardInputs(i,d_sound_card->getCardInputPorts(i)); + rda->station()->setCardOutputs(i,d_sound_card->getCardOutputPorts(i)); + addCard(*next_cardnum); + (*next_cardnum)++; + } + return d_sound_card->getCardQuantity()>0; +#else + return false; +#endif // HPI +} + + +void HpiDriver::updateMeters() +{ +#ifdef HPI + +#endif // HPI +} + + +bool HpiDriver::loadPlayback(int card,QString wavename,int *stream) +{ +#ifdef HPI + RDHPIPlayStream *playstream=new RDHPIPlayStream(d_sound_card); + playstream->setCard(card); + if(playstream->openWave(wavename)!=RDHPIPlayStream::Ok) { + rda->syslog(LOG_DEBUG,"hpiLoadPlayback(%s) openWave() failed to open file", + wavename.toUtf8().constData()); + delete playstream; + return false; + } + *stream=playstream->getStream(); + d_play_streams[card][*stream]=playstream; + connect(d_play_streams[card][*stream],SIGNAL(stateChanged(int,int,int)), + this,SLOT(statePlayUpdate(int,int,int))); + + return true; +#else + return false; +#endif // HPI +} + + +bool HpiDriver::unloadPlayback(int card,int stream) +{ +#ifdef HPI + if(d_play_streams[card][stream]==NULL) { + return false; + } + if(d_play_streams[card][stream]->getState()==RDHPIPlayStream::Playing) { + d_play_streams[card][stream]->pause(); + } + d_play_streams[card][stream]->disconnect(); + d_play_streams[card][stream]->closeWave(); + delete d_play_streams[card][stream]; + d_play_streams[card][stream]=NULL; + + return true; +#else + return false; +#endif // HPI +} + + +bool HpiDriver::playbackPosition(int card,int stream,unsigned pos) +{ +#ifdef HPI + if(d_play_streams[card][stream]==NULL) { + return false; + } + return d_play_streams[card][stream]-> + setPosition((unsigned)((double)d_play_streams[card][stream]-> + getSamplesPerSec()*(double)pos/1000.0)); +#else + return false; +#endif // HPI +} + + +bool HpiDriver::play(int card,int stream,int length,int speed,bool pitch, + bool rates) +{ +#ifdef HPI + if(d_play_streams[card][stream]==NULL) { + return false; + } + if(!d_play_streams[card][stream]->setSpeed(speed,pitch,rates)) { + return false; + } + d_play_streams[card][stream]->setPlayLength(length); + return d_play_streams[card][stream]->play(); +#else + return false; +#endif // HPI +} + + +bool HpiDriver::stopPlayback(int card,int stream) +{ +#ifdef HPI + if(d_play_streams[card][stream]==NULL) { + return false; + } + d_play_streams[card][stream]->pause(); + + return true; +#else + return false; +#endif // HPI +} + + +bool HpiDriver::timescaleSupported(int card) +{ +#ifdef HPI + return d_sound_card->haveTimescaling(card); +#else + return false; +#endif // HPI +} + + +bool HpiDriver::loadRecord(int card,int port,int coding,int chans,int samprate, + int bitrate,QString wavename) +{ +#ifdef HPI + d_record_streams[card][port]=new RDHPIRecordStream(d_sound_card); + connect(d_record_streams[card][port],SIGNAL(stateChanged(int,int,int)), + this,SLOT(stateRecordUpdate(int,int,int))); + d_record_streams[card][port]->setCard(card); + d_record_streams[card][port]->setStream(port); + d_record_streams[card][port]->nameWave(wavename); + d_record_streams[card][port]->setChannels(chans); + d_record_streams[card][port]->setSamplesPerSec(samprate); + if(coding==0) { // PCM16 + d_record_streams[card][port]->setFormatTag(WAVE_FORMAT_PCM); + d_record_streams[card][port]->setBitsPerSample(16); + } + if((coding==1)||(coding==2)) { // MPEG-1 + d_record_streams[card][port]->setFormatTag(WAVE_FORMAT_MPEG); + d_record_streams[card][port]->setHeadLayer(coding); + d_record_streams[card][port]->setHeadBitRate(bitrate); + d_record_streams[card][port]->setMextChunk(true); + switch(chans) { + case 1: + d_record_streams[card][port]->setHeadMode(ACM_MPEG_SINGLECHANNEL); + break; + + case 2: + d_record_streams[card][port]->setHeadMode(ACM_MPEG_STEREO); + break; + + default: + delete d_record_streams[card][port]; + d_record_streams[card][port]=NULL; + return false; + } + d_record_streams[card][port]->setHeadFlags(ACM_MPEG_ID_MPEG1); + } + if(coding==4) { // PCM24 + d_record_streams[card][port]->setFormatTag(WAVE_FORMAT_PCM); + d_record_streams[card][port]->setBitsPerSample(24); + } + if(coding>4) { + delete d_record_streams[card][port]; + d_record_streams[card][port]=NULL; + return false; + } + d_record_streams[card][port]->setBextChunk(true); + d_record_streams[card][port]->setCartChunk(true); + d_record_streams[card][port]->setLevlChunk(true); + if(d_record_streams[card][port]->createWave()!=RDHPIRecordStream::Ok) { + delete d_record_streams[card][port]; + d_record_streams[card][port]=NULL; + return false; + } + RDCheckExitCode(rda->config(),"hpiLoadRecord() chown", + chown(wavename.toUtf8(),rda->config()->uid(),rda->config()->gid())); + if(!d_record_streams[card][port]->recordReady()) { + delete d_record_streams[card][port]; + d_record_streams[card][port]=NULL; + return false; + } + + return true; +#else + return false; +#endif // HPI +} + + +bool HpiDriver::unloadRecord(int card,int port,unsigned *len) +{ +#ifdef HPI + if(d_record_streams[card][port]==NULL) { + return false; + } + if(d_record_streams[card][port]->getState()==RDHPIRecordStream::Recording) { + d_record_streams[card][port]->pause(); + } + d_record_streams[card][port]->disconnect(); + *len=d_record_streams[card][port]->samplesRecorded(); + d_record_streams[card][port]->closeWave(); + delete d_record_streams[card][port]; + d_record_streams[card][port]=NULL; + + return true; +#else + return false; +#endif // HPI +} + + +bool HpiDriver::record(int card,int port,int length,int thres) +{ +#ifdef HPI + if(d_record_streams[card][port]==NULL) { + return false; + } + if(thres!=0) { + if(d_record_streams[card][port]->haveInputVOX()) { + d_record_streams[card][port]->setInputVOX(thres); + } + else { + return false; + } + } + d_record_streams[card][port]->setRecordLength(length); + d_record_streams[card][port]->record(); + + return true; +#else + return false; +#endif // HPI +} + + +bool HpiDriver::stopRecord(int card,int port) +{ +#ifdef HPI + if(d_record_streams[card][port]==NULL) { + return false; + } + d_record_streams[card][port]->pause(); + d_record_streams[card][port]->setInputVOX(-10000); + + return true; +#else + return false; +#endif // HPI +} + + +bool HpiDriver::setClockSource(int card,int src) +{ +#ifdef HPI + return d_sound_card->setClockSource(card,(RDHPISoundCard::ClockSource)src); +#else + return false; +#endif // HPI +} + + +bool HpiDriver::setInputVolume(int card,int stream,int level) +{ +#ifdef HPI + d_sound_card->setInputVolume(card,stream,level); + + return true; +#else + return false; +#endif // HPI +} + + +bool HpiDriver::setOutputVolume(int card,int stream,int port,int level) +{ +#ifdef HPI + d_sound_card->setOutputVolume(card,stream,port,level); + + return true; +#else + return false; +#endif // HPI +} + + +bool HpiDriver::fadeOutputVolume(int card,int stream,int port,int level, + int length) +{ +#ifdef HPI + d_sound_card->fadeOutputVolume(card,stream,port,level,length); + + return true; +#else + return false; +#endif // HPI +} + + +bool HpiDriver::setInputLevel(int card,int port,int level) +{ +#ifdef HPI + d_sound_card->setInputLevel(card,port,level); + + return true; +#else + return false; +#endif // HPI +} + + +bool HpiDriver::setOutputLevel(int card,int port,int level) +{ +#ifdef HPI + d_sound_card->setOutputLevel(card,port,level); + + return true; +#else + return false; +#endif // HPI +} + + +bool HpiDriver::setInputMode(int card,int stream,int mode) +{ +#ifdef HPI + switch(mode) { + case 0: + d_sound_card->setInputMode(card,stream,RDHPISoundCard::Normal); + break; + + case 1: + d_sound_card->setInputMode(card,stream,RDHPISoundCard::Swap); + break; + + case 2: + d_sound_card->setInputMode(card,stream,RDHPISoundCard::LeftOnly); + break; + + case 3: + d_sound_card->setInputMode(card,stream,RDHPISoundCard::RightOnly); + break; + + default: + return false; + } + + return true; +#else + return false; +#endif // HPI +} + + +bool HpiDriver::setOutputMode(int card,int stream,int mode) +{ +#ifdef HPI + switch(mode) { + case 0: + d_sound_card->setOutputMode(card,stream,RDHPISoundCard::Normal); + break; + + case 1: + d_sound_card->setOutputMode(card,stream,RDHPISoundCard::Swap); + break; + + case 2: + d_sound_card->setOutputMode(card,stream,RDHPISoundCard::LeftOnly); + break; + + case 3: + d_sound_card->setOutputMode(card,stream,RDHPISoundCard::RightOnly); + break; + + default: + return false; + } + + return true; +#else + return false; +#endif // HPI +} + + +bool HpiDriver::setInputVoxLevel(int card,int stream,int level) +{ +#ifdef HPI + d_sound_card->setInputStreamVOX(card,stream,level); + + return true; +#else + return false; +#endif // HPI +} + + +bool HpiDriver::setInputType(int card,int port,int type) +{ +#ifdef HPI + switch(type) { + case 0: + d_sound_card->setInputPortMux(card,port,RDHPISoundCard::LineIn); + break; + + case 1: + d_sound_card->setInputPortMux(card,port,RDHPISoundCard::AesEbuIn); + break; + + default: + return false; + } + + return true; +#else + return false; +#endif // HPI +} + + +bool HpiDriver::getInputStatus(int card,int port) +{ +#ifdef HPI + return d_sound_card->getInputPortError(card,port)==0; +#else + return false; +#endif // HPI +} + + +bool HpiDriver::getInputMeters(int card,int port,short levels[2]) +{ +#ifdef HPI + return d_sound_card->inputStreamMeter(card,port,levels); +#else + return false; +#endif // HPI +} + + +bool HpiDriver::getOutputMeters(int card,int port,short levels[2]) +{ +#ifdef HPI + return d_sound_card->outputPortMeter(card,port,levels); +#else + return false; +#endif // HPI +} + + +bool HpiDriver::getStreamOutputMeters(int card,int stream,short levels[2]) +{ +#ifdef HPI + return d_sound_card->outputStreamMeter(card,stream,levels); +#else + return false; +#endif // HPI +} + + +bool HpiDriver::setPassthroughLevel(int card,int in_port,int out_port,int level) +{ +#ifdef HPI + return d_sound_card->setPassthroughVolume(card,in_port,out_port,level); +#else + return false; +#endif // HPI +} + + +void HpiDriver::getOutputPosition(int card,unsigned *pos) +{ +#ifdef HPI + for(int i=0;icurrentPosition()/ + d_play_streams[card][i]->getSamplesPerSec(); + } + } +#endif // HPI +} diff --git a/cae/hpidriver.h b/cae/hpidriver.h new file mode 100644 index 00000000..157390d8 --- /dev/null +++ b/cae/hpidriver.h @@ -0,0 +1,83 @@ +// hpidriver.h +// +// caed(8) driver for AudioScience HPI audio devices. +// +// (C) Copyright 2021 Fred Gleason +// +// 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 +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public +// License along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#ifndef HPIDRIVER_H +#define HPIDRIVER_H + +#include + +#include "caedriver.h" + +#ifdef HPI +#include +#include +#include +#endif // HPI + +class HpiDriver : public CaeDriver +{ + Q_OBJECT + public: + HpiDriver(QObject *parent=0); + ~HpiDriver(); + QString version() const; + bool initialize(unsigned *next_cardnum); + void updateMeters(); + bool loadPlayback(int card,QString wavename,int *stream); + bool unloadPlayback(int card,int stream); + bool playbackPosition(int card,int stream,unsigned pos); + bool play(int card,int stream,int length,int speed,bool pitch, + bool rates); + bool stopPlayback(int card,int stream); + bool timescaleSupported(int card); + bool loadRecord(int card,int port,int coding,int chans,int samprate, + int bitrate,QString wavename); + bool unloadRecord(int card,int port,unsigned *len); + bool record(int card,int port,int length,int thres); + bool stopRecord(int card,int port); + bool setClockSource(int card,int src); + bool setInputVolume(int card,int stream,int level); + bool setOutputVolume(int card,int stream,int port,int level); + bool fadeOutputVolume(int card,int stream,int port,int level, + int length); + bool setInputLevel(int card,int port,int level); + bool setOutputLevel(int card,int port,int level); + bool setInputMode(int card,int stream,int mode); + bool setOutputMode(int card,int stream,int mode); + bool setInputVoxLevel(int card,int stream,int level); + bool setInputType(int card,int port,int type); + bool getInputStatus(int card,int port); + bool getInputMeters(int card,int port,short levels[2]); + bool getOutputMeters(int card,int port,short levels[2]); + bool getStreamOutputMeters(int card,int stream,short levels[2]); + bool setPassthroughLevel(int card,int in_port,int out_port, + int level); + void getOutputPosition(int card,unsigned *pos); + + private: +#ifdef HPI + RDHPISoundCard *d_sound_card; + RDHPIRecordStream *d_record_streams[RD_MAX_CARDS][RD_MAX_STREAMS]; + RDHPIPlayStream *d_play_streams[RD_MAX_CARDS][RD_MAX_STREAMS]; +#endif // HPI +}; + + +#endif // HPIDRIVER_H diff --git a/lib/rdstation.cpp b/lib/rdstation.cpp index dbd20c44..bc1c6b73 100644 --- a/lib/rdstation.cpp +++ b/lib/rdstation.cpp @@ -1992,6 +1992,30 @@ void RDStation::remove(const QString &name) } +QString RDStation::audioDriverText(RDStation::AudioDriver dvr) +{ + QString ret=QObject::tr("Unknown"); + switch(dvr) { + case RDStation::None: + ret=QObject::tr("None"); + break; + + case RDStation::Hpi: + ret=QObject::tr("AudioScience HPI"); + break; + + case RDStation::Jack: + ret=QObject::tr("JACK Audio Connection Kit"); + break; + + case RDStation::Alsa: + ret=QObject::tr("Advance Linux Sound Architecture (ALSA)"); + break; + } + return ret; +} + + void RDStation::SetRow(const QString ¶m,const QString &value) const { QString sql; diff --git a/lib/rdstation.h b/lib/rdstation.h index 94dc15e3..c827b843 100644 --- a/lib/rdstation.h +++ b/lib/rdstation.h @@ -117,6 +117,7 @@ class RDStation const QString &exemplar="", const QHostAddress &hostaddr=QHostAddress()); static void remove(const QString &name); + static QString audioDriverText(AudioDriver dvr); private: void SetRow(const QString ¶m,const QString &value) const;