From f21b52626388fd8df9d8c6589ad5e2842ed4fad4 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Thu, 14 Dec 2023 17:43:26 -0500 Subject: [PATCH] 2023-12-14 Fred Gleason * Fixed regressions in the CAE subsystem that broke play-out positing and active output port reporting. Signed-off-by: Fred Gleason --- ChangeLog | 3 + cae/Makefile.am | 5 +- cae/cae.cpp | 602 +++++++++++++++++++++------------------ cae/cae.h | 33 +-- cae/cae_server.cpp | 91 +++--- cae/cae_server.h | 22 +- cae/playsession.cpp | 124 ++++++++ cae/playsession.h | 58 ++++ docs/apis/cae.xml | 156 ++++------ lib/rdcae.cpp | 534 +++++++++++++++++----------------- lib/rdcae.h | 76 ++--- lib/rdcartslot.cpp | 2 + lib/rdcueedit.cpp | 6 +- lib/rdlogplay.cpp | 17 +- lib/rdmarkerplayer.cpp | 91 +++--- lib/rdmarkerplayer.h | 11 +- lib/rdplay_deck.cpp | 116 ++++---- lib/rdplay_deck.h | 9 +- lib/rdsimpleplayer.cpp | 49 ++-- lib/rdsimpleplayer.h | 8 +- lib/rdsound_panel.cpp | 3 +- rdcatch/rdcatch.cpp | 42 ++- rdcatch/rdcatch.h | 3 +- rdcatchd/rdcatchd.cpp | 59 ++-- rdcatchd/rdcatchd.h | 7 +- rdlibrary/record_cut.cpp | 30 +- rdlibrary/record_cut.h | 15 +- 27 files changed, 1148 insertions(+), 1024 deletions(-) create mode 100644 cae/playsession.cpp create mode 100644 cae/playsession.h diff --git a/ChangeLog b/ChangeLog index c2954036..55946b5e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24540,3 +24540,6 @@ CAE commands. 2023-12-14 Fred Gleason * Moved LINE_NUMBER macros to 'lib/rd.h'. +2023-12-14 Fred Gleason + * Fixed regressions in the CAE subsystem that broke play-out positing + and active output port reporting. diff --git a/cae/Makefile.am b/cae/Makefile.am index 0824f2fa..055c9daa 100644 --- a/cae/Makefile.am +++ b/cae/Makefile.am @@ -2,7 +2,7 @@ ## ## Core Audio Engine Makefile.am for Rivendell ## -## Copyright 2002-2021 Fred Gleason +## Copyright 2002-2023 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 @@ -34,7 +34,8 @@ dist_caed_SOURCES = cae.cpp cae.h\ driver.cpp driver.h\ driver_alsa.cpp driver_alsa.h\ driver_hpi.cpp driver_hpi.h\ - driver_jack.cpp driver_jack.h + driver_jack.cpp driver_jack.h\ + playsession.cpp play_session.h nodist_caed_SOURCES = moc_cae.cpp\ moc_cae_server.cpp\ diff --git a/cae/cae.cpp b/cae/cae.cpp index 0041222a..5963ce2c 100644 --- a/cae/cae.cpp +++ b/cae/cae.cpp @@ -114,19 +114,11 @@ MainObject::MainObject(QObject *parent) } } } - for(int i=0;i<256;i++) { - play_handle[i].card=-1; - play_handle[i].stream=-1; - play_handle[i].owner=-1; - } - next_play_handle=0; - for(int i=0;i - sendCommand(id,QString::asprintf("LP %d %s -1 -1 -!",card, - name.toUtf8().constData())); + sendCommand(phandle,QString::asprintf("LP %u %u %u %s -!", + serial,cardnum,portnum, + name.toUtf8().constData())); return; } wavename=rda->config()->audioFileName(name); - if(!dvr->loadPlayback(card,wavename,&new_stream)) { + if(dvr->loadPlayback(cardnum,wavename,&new_stream)) { + play_sessions[phandle]=new PlaySession(phandle,cardnum,portnum,new_stream); + } + else { cae_server-> - sendCommand(id,QString::asprintf("LP %d %s -1 -1 -!",card, - name.toUtf8().constData())); + sendCommand(phandle,QString::asprintf("LP %u %u %u %s -!", + serial,cardnum,portnum, + name.toUtf8().constData())); rda->syslog(LOG_WARNING, - "unable to allocate stream for card %d",card); + "unable to allocate stream for card %d",cardnum); return; } - if((handle=GetHandle(card,new_stream))>=0) { - rda->syslog(LOG_WARNING, - "*** clearing stale stream assignment, card=%d stream=%d ***", - card,new_stream); - play_handle[handle].card=-1; - play_handle[handle].stream=-1; - play_handle[handle].owner=-1; - } - handle=GetNextHandle(); - play_handle[handle].card=card; - play_handle[handle].stream=new_stream; - play_handle[handle].owner=id; - play_owner[card][new_stream]=id; // // Mute all volume controls for the stream // - for(int i=0;ioutputPortQuantity(card);i++) { - dvr->setOutputVolume(card,new_stream,i,RD_MUTE_DEPTH); + for(int i=0;ioutputPortQuantity(cardnum);i++) { + dvr->setOutputVolume(cardnum,new_stream,i,RD_MUTE_DEPTH); } - rda->syslog(LOG_INFO, - "LoadPlayback Card: %d Stream: %d Name: %s Handle: %d", - card,new_stream,(const char *)wavename.toUtf8(),handle); + rda-> + syslog(LOG_INFO,"LoadPlayback Card: %d Stream: %d Name: %s Serial: %u", + cardnum,new_stream,wavename.toUtf8().constData(),serial); cae_server-> - sendCommand(id,QString::asprintf("LP %d %s %d %d +!",card, - (const char *)name.toUtf8(), - new_stream,handle)); + sendCommand(phandle,QString::asprintf("LP %u %u %u %s +!", + serial,cardnum,portnum, + name.toUtf8().constData())); } -void MainObject::unloadPlaybackData(int id,unsigned handle) +void MainObject::unloadPlaybackData(uint64_t phandle) { - int card=play_handle[handle].card; - int stream=play_handle[handle].stream; - Driver *dvr=GetDriver(card); + PlaySession *psess=play_sessions.value(phandle); + unsigned serial=PlaySession::serialNumber(phandle); - if(dvr==NULL) { - cae_server->sendCommand(id,QString::asprintf("UP %d -!",handle)); - return; - } - if((play_owner[card][stream]==-1)||(play_owner[card][stream]==id)) { - if(dvr->unloadPlayback(card,stream)) { - if(!rda->config()->testOutputStreams()) { - for(int i=0;isetOutputVolume(card,stream,i,RD_MUTE_DEPTH); // Clear mixer - } - } - play_owner[card][stream]=-1; - rda->syslog(LOG_INFO,"UnloadPlayback - Card: %d Stream: %d Handle: %d", - card,stream,handle); - cae_server->sendCommand(id,QString::asprintf("UP %d +!",handle)); - } - else { - cae_server->sendCommand(id,QString::asprintf("UP %d -!",handle)); - } - play_handle[handle].card=-1; - play_handle[handle].stream=-1; - play_handle[handle].owner=-1; - return; + if(psess==NULL) { + cae_server->sendCommand(phandle,QString::asprintf("UP %u -!",serial)); + rda->syslog(LOG_WARNING, + "attempted to unload non-existent session, serial:%u",serial); } else { - cae_server->sendCommand(id,QString::asprintf("UP %d -!",handle)); - } -} - - -void MainObject::playPositionData(int id,unsigned handle,unsigned pos) -{ - int card=play_handle[handle].card; - int stream=play_handle[handle].stream; - Driver *dvr=GetDriver(card); - - if(dvr==NULL) { - cae_server->sendCommand(id,QString::asprintf("PP %d %d -!",handle,pos)); - return; - } - if(play_owner[card][stream]==id) { - 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::asprintf("PP %d %d +!",handle,pos)); + Driver *dvr=GetDriver(psess->cardNumber()); + if(dvr==NULL) { + cae_server->sendCommand(phandle,QString::asprintf("UP %u -!",serial)); + rda->syslog(LOG_WARNING, + "attempted to access non-existent card, serial: %u card: %u", + serial,psess->cardNumber()); } else { - cae_server->sendCommand(id,QString::asprintf("PP %d %d -!",handle,pos)); + if(dvr->unloadPlayback(psess->cardNumber(),psess->streamNumber())) { + if(!rda->config()->testOutputStreams()) { + for(int i=0;isetOutputVolume(psess->cardNumber(),psess->streamNumber(),i, + RD_MUTE_DEPTH); // Clear mixer + } + } + rda->syslog(LOG_INFO, + "UnloadPlayback - Card: %d Stream: %d Serial: %u", + psess->cardNumber(),psess->streamNumber(), + psess->serialNumber()); + cae_server->sendCommand(phandle,QString::asprintf("UP %u +!",serial)); + } + else { + cae_server->sendCommand(phandle,QString::asprintf("UP %d -!",serial)); + rda->syslog(LOG_WARNING, + "failed to unload play session, serial: %u, card: %u stream: %d", + serial,psess->cardNumber(),psess->streamNumber()); + } + play_sessions.remove(phandle); } - return; } - cae_server->sendCommand(id,QString::asprintf("PP %d %d -!",handle,pos)); } -void MainObject::playData(int id,unsigned handle,unsigned length,unsigned speed, +void MainObject::playPositionData(uint64_t phandle,unsigned pos) +{ + PlaySession *psess=play_sessions.value(phandle); + unsigned serial=PlaySession::serialNumber(phandle); + + if(psess==NULL) { + cae_server->sendCommand(phandle,QString::asprintf("PP %u %u -!", + serial,pos)); + rda->syslog(LOG_WARNING, + "attempted to unload non-existent session, serial: %u",serial); + } + else { + Driver *dvr=GetDriver(psess->cardNumber()); + if(dvr==NULL) { + cae_server->sendCommand(phandle,QString::asprintf("PP %u %u -!", + serial,pos)); + rda->syslog(LOG_WARNING, + "attempted to access non-existent card, serial: %u pos: %u", + serial,pos); + } + else { + if(dvr->playbackPosition(psess->cardNumber(),psess->streamNumber(),pos)) { + rda-> + syslog(LOG_DEBUG, + "PlaybackPosition - Card: %d Stream: %d Pos: %d Serial: %d", + psess->cardNumber(),psess->streamNumber(),pos,serial); + cae_server-> + sendCommand(phandle,QString::asprintf("PP %u %u +!",serial,pos)); + } + else { + cae_server-> + sendCommand(phandle,QString::asprintf("PP %u %u -!",serial,pos)); + rda->syslog(LOG_WARNING,"PlaybackPosition failed, serial: %u, pos: %u", + serial,pos); + } + } + } +} + + +void MainObject::playData(uint64_t phandle,unsigned length,unsigned speed, unsigned pitch_flag) { - int card=play_handle[handle].card; - int stream=play_handle[handle].stream; - Driver *dvr=GetDriver(card); + PlaySession *psess=play_sessions.value(phandle); + unsigned serial=PlaySession::serialNumber(phandle); - if(dvr==NULL) { + if(psess==NULL) { cae_server-> - sendCommand(id,QString::asprintf("PY %u %u %u %u -!", - handle,length,speed,pitch_flag)); - return; + sendCommand(phandle,QString::asprintf("PY %u %u %u %u -!", + serial,length,speed,pitch_flag)); + rda->syslog(LOG_WARNING, + "attempted to play non-existent session, serial:%u",serial); } - play_length[card][stream]=length; - play_speed[card][stream]=speed; - switch(pitch_flag) { - case 0: - play_pitch[card][stream]=false; - break; - - case 1: - play_pitch[card][stream]=true; - break; - - default: + else { + Driver *dvr=GetDriver(psess->cardNumber()); + if(dvr==NULL) { cae_server-> - sendCommand(id,QString::asprintf("PY %u %u %u %u -!", - handle,length,speed,pitch_flag)); - return; - } - if(play_owner[card][stream]==id) { - 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::asprintf("PY %u %u %u %u -!", - handle,length,speed,pitch_flag)); - return; + sendCommand(phandle,QString::asprintf("PY %u %u %u %u -!", + serial,length,speed,pitch_flag)); + rda->syslog(LOG_WARNING, + "attempted to access non-existent card, serial: %u card: %u", + serial,psess->cardNumber()); + } + else { + psess->setLength(length); + psess->setSpeed(speed); + if(!dvr->play(psess->cardNumber(),psess->streamNumber(),psess->length(), + psess->speed(),false,RD_ALLOW_NONSTANDARD_RATES)) { + cae_server-> + sendCommand(phandle,QString::asprintf("PY %u %u %u %u -!", + serial,length,speed, + pitch_flag)); + } + else { + rda->syslog(LOG_INFO, + "Play - Card: %d Stream: %d Serial: %d Length: %d Speed: %d Pitch: %d", + psess->cardNumber(),psess->streamNumber(),serial, + psess->length(),psess->speed(),pitch_flag); + // No command echo for success -- statePlayUpdate() sends it! + } } - 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; } - cae_server-> - sendCommand(id,QString::asprintf("PY %u %u %u %u -!", - handle,length,speed,pitch_flag)); } -void MainObject::stopPlaybackData(int id,unsigned handle) +void MainObject::stopPlaybackData(uint64_t phandle) { - int card=play_handle[handle].card; - int stream=play_handle[handle].stream; - Driver *dvr=GetDriver(card); + PlaySession *psess=play_sessions.value(phandle); + unsigned serial=PlaySession::serialNumber(phandle); - if(dvr==NULL) { - cae_server->sendCommand(id,QString::asprintf("SP %u -!",handle)); - return; + if(psess==NULL) { + cae_server->sendCommand(phandle,QString::asprintf("SP %u -!",serial)); + rda->syslog(LOG_WARNING, + "attempted to stop non-existent session, serial: %u",serial); } - if(play_owner[card][stream]==id) { - if(!dvr->stopPlayback(card,stream)) { - cae_server->sendCommand(id,QString::asprintf("SP %u -!",handle)); + else { + Driver *dvr=GetDriver(psess->cardNumber()); + if(dvr==NULL) { + cae_server->sendCommand(phandle,QString::asprintf("SP %u -!",serial)); + rda->syslog(LOG_WARNING, + "attempted to access non-existent card, serial: %u card: %u", + serial,psess->cardNumber()); + } + else { + if(!dvr->stopPlayback(psess->cardNumber(),psess->streamNumber())) { + cae_server->sendCommand(phandle,QString::asprintf("SP %u -!",serial)); + return; + } + rda->syslog(LOG_INFO,"StopPlayback - Card: %d Stream: %d Serial: %d", + psess->cardNumber(),psess->streamNumber(),serial); return; } - rda->syslog(LOG_INFO, - "StopPlayback - Card: %d Stream: %d Handle: %d", - card,stream,handle); - return; } - cae_server->sendCommand(id,QString::asprintf("SP %u -!",handle)); + cae_server->sendCommand(phandle,QString::asprintf("SP %u -!",serial)); } @@ -685,67 +691,97 @@ void MainObject::setInputVolumeData(int id,unsigned card,unsigned stream, } -void MainObject::setOutputVolumeData(int id,unsigned card,unsigned stream, - int port,int level) +void MainObject::setOutputVolumeData(uint64_t phandle,int level) { - Driver *dvr=GetDriver(card); + PlaySession *psess=play_sessions.value(phandle); + unsigned serial=PlaySession::serialNumber(phandle); - if(dvr==NULL) { - cae_server->sendCommand(id,QString::asprintf("OV %u %u %u %d -!", - card,stream,port,level)); - return; + if(psess==NULL) { + cae_server->sendCommand(phandle,QString::asprintf("SP %u -!",serial)); + rda->syslog(LOG_WARNING, + "attempted to operate non-existent session, serial: %u",serial); } - if(!rda->config()->testOutputStreams()) { - if(port>=0) { - if(!dvr->setOutputVolume(card,stream,port,level)) { - cae_server->sendCommand(id,QString::asprintf("OV %u %u %u %d -!", - card,stream,port,level)); - return; - } + else { + Driver *dvr=GetDriver(psess->cardNumber()); + if(dvr==NULL) { + cae_server->sendCommand(phandle,QString::asprintf("SP %u -!",serial)); + rda->syslog(LOG_WARNING, + "attempted to access non-existent card, serial: %u card: %u", + serial,psess->cardNumber()); } else { - for(int i=0;isetOutputVolume(card,stream,i,level); + if(!rda->config()->testOutputStreams()) { + if(psess->portNumber()>=0) { + if(!dvr->setOutputVolume(psess->cardNumber(),psess->streamNumber(), + psess->portNumber(),level)) { + cae_server->sendCommand(phandle,QString::asprintf("OV %u %d -!", + serial,level)); + return; + } + } + /* RESET SECTION? + else { + for(int i=0;isetOutputVolume(card,stream,i,level); + } + } + */ + if(rda->config()->enableMixerLogging()) { + rda->syslog(LOG_INFO, + "[mixer] SetOutputVolume - Serial: %u Card: %d Stream: %d Port: %d Level: %d", + serial,psess->cardNumber(),psess->streamNumber(), + psess->portNumber(),level); + } } - } - if(rda->config()->enableMixerLogging()) { - rda->syslog(LOG_INFO, - "[mixer] SetOutputVolume - Card: %d Stream: %d Port: %d Level: %d", - card,stream,port,level); + cae_server->sendCommand(phandle,QString::asprintf("OV %u %d +!", + serial,level)); } } - cae_server->sendCommand(id,QString::asprintf("OV %u %u %u %d +!", - card,stream,port,level)); } -void MainObject::fadeOutputVolumeData(int id,unsigned card,unsigned stream, - unsigned port,int level,unsigned length) +void MainObject::fadeOutputVolumeData(uint64_t phandle,int level, + unsigned length) { - Driver *dvr=GetDriver(card); + PlaySession *psess=play_sessions.value(phandle); + unsigned serial=PlaySession::serialNumber(phandle); - if(dvr==NULL) { - cae_server-> - sendCommand(id,QString::asprintf("FV %u %u %u %d %u -!", - card,stream,port,level,length)); - return; + if(psess==NULL) { + cae_server->sendCommand(phandle,QString::asprintf("FV %u %d %u -!", + serial,level,length)); + rda->syslog(LOG_WARNING, + "attempted to operate non-existent session, serial: %u",serial); } - if(!rda->config()->testOutputStreams()) { - if(!dvr->fadeOutputVolume(card,stream,port,level,length)) { + else { + Driver *dvr=GetDriver(psess->cardNumber()); + if(dvr==NULL) { + cae_server->sendCommand(phandle,QString::asprintf("FV %u %d %u -!", + serial,level,length)); + rda->syslog(LOG_WARNING, + "attempted to access non-existent card, serial: %u card: %u", + serial,psess->cardNumber()); + } + else { + if(!rda->config()->testOutputStreams()) { + if(!dvr->fadeOutputVolume(psess->cardNumber(),psess->streamNumber(), + psess->portNumber(),level,length)) { + cae_server-> + sendCommand(phandle,QString::asprintf("FV %u %d %u -!", + serial,level,length)); + return; + } + if(rda->config()->enableMixerLogging()) { + rda->syslog(LOG_INFO, + "[mixer] FadeOutputVolume - Serial: %u Card: %d Stream: %d Port: %d Level: %d Length: %d", + serial,psess->cardNumber(),psess->streamNumber(), + psess->portNumber(),level,length); + } + } cae_server-> - sendCommand(id,QString::asprintf("FV %u %u %u %d %u -!", - card,stream,port,level,length)); - return; - } - if(rda->config()->enableMixerLogging()) { - rda->syslog(LOG_INFO, - "[mixer] FadeOutputVolume - Card: %d Stream: %d Port: %d Level: %d Length: %d", - card,stream,port,level,length); + sendCommand(phandle,QString::asprintf("FV %u %d %u +!", + serial,level,length)); } } - cae_server-> - sendCommand(id,QString::asprintf("FV %u %u %u %d %u +!", - card,stream,port,level,length)); } @@ -1024,33 +1060,31 @@ void MainObject::connectionDroppedData(int id) void MainObject::statePlayUpdate(int card,int stream,int state) { - printf("statePlayUpdate(%d,%d,%d)\n",card,stream,state); - int handle=GetHandle(card,stream); + rda->syslog(LOG_NOTICE,"statePlayUpdate(%d,%d,%d)\n",card,stream,state); + uint64_t phandle=GetPlayHandle(card,stream); + unsigned serial=PlaySession::serialNumber(phandle); + PlaySession *psess=play_sessions.value(phandle); - if(handle<0) { + if(psess==NULL) { return; } - if(play_owner[card][stream]!=-1) { - switch(state) { - case 1: // Playing - cae_server->sendCommand(play_owner[card][stream], - QString::asprintf("PY %d %d %d +!",handle, - play_length[card][stream], - play_speed[card][stream]).toUtf8()); - break; + switch(state) { + case 1: // Playing + cae_server-> + sendCommand(phandle,QString::asprintf("PY %u %d %d 0 +!", + serial, + psess->length(), + psess->speed())); + break; - case 2: // Paused - cae_server-> - sendCommand(play_owner[card][stream], - QString::asprintf("SP %d +!",handle).toUtf8()); - break; + case 2: // Paused + cae_server->sendCommand(phandle,QString::asprintf("SP %d +!",serial)); + break; - case 0: // Stopped - cae_server-> - sendCommand(play_owner[card][stream], - QString::asprintf("SP %d +!",handle).toUtf8()); - break; - } + case 0: // Stopped + cae_server-> + sendCommand(phandle,QString::asprintf("SP %d +!",serial).toUtf8()); + break; } } @@ -1230,16 +1264,19 @@ void MainObject::InitMixers() } -void MainObject::KillSocket(int ch) +void MainObject::KillSocket(int sock) { 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)); + // + // Clear Active Record Events + // + if(record_owner[i][j]==sock) { + rda->syslog(LOG_DEBUG,"force unloading record context for connection %s:%u: Card: %d Stream: %d", + cae_server->peerAddress(sock).toString().toUtf8().constData(), + 0xFFFF&cae_server->peerPort(sock), + i,j); unsigned len=0; if(dvr!=NULL) { dvr->unloadRecord(i,j,&len); @@ -1248,26 +1285,25 @@ void MainObject::KillSocket(int ch) record_threshold[i][j]=-10000; record_owner[i][j]=-1; } - if(play_owner[i][j]==ch) { - 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)); - if(dvr!=NULL) { - dvr->unloadPlayback(i,j); + + // + // Clear Active Playout Events + // + QMap::iterator it=play_sessions.begin(); + while(it!=play_sessions.end()) { + if((it.value()!=NULL)&&(it.value()->socketDescriptor()==sock)) { + rda->syslog(LOG_DEBUG,"force unloading play context for connection [%s:%u]: Serial: %u Card: %d Stream: %d", + cae_server->peerAddress(sock).toString().toUtf8(). + constData(), + 0xFFFF&cae_server->peerPort(sock), + it.value()->serialNumber(),i,j); + dvr->unloadPlayback(it.value()->cardNumber(), + it.value()->streamNumber()); + it=play_sessions.erase(it); + } + else { + ++it; } - play_owner[i][j]=-1; - play_length[i][j]=0; - play_speed[i][j]=100; - play_pitch[i][j]=false; - } - } - for(int i=0;i<256;i++) { - if(play_handle[i].owner==ch) { - play_handle[i].card=-1; - play_handle[i].stream=-1; - play_handle[i].owner=-1; } } } @@ -1300,27 +1336,16 @@ bool MainObject::CheckDaemon(QString name) } -int MainObject::GetNextHandle() +uint64_t MainObject::GetPlayHandle(unsigned cardnum,unsigned streamnum) const { - while(play_handle[next_play_handle].card>=0) { - next_play_handle++; - next_play_handle&=0xFF; - } - int handle=next_play_handle; - next_play_handle++; - next_play_handle&=0xFF; - return handle; -} - - -int MainObject::GetHandle(int card,int stream) -{ - for(int i=0;i<256;i++) { - if((play_handle[i].card==card)&&(play_handle[i].stream==stream)) { - return i; + for(QMap::const_iterator it=play_sessions.begin(); + it!=play_sessions.end();it++) { + if((it.value()->cardNumber()==cardnum)&& + (it.value()->streamNumber()==streamnum)) { + return it.key(); } } - return -1; + return 0; } @@ -1579,14 +1604,18 @@ void MainObject::SendStreamMeterLevelUpdate(int cardnum,int streamnum, void MainObject::SendMeterPositionUpdate(int cardnum,unsigned pos[]) { + PlaySession *psess=NULL; QList ids=cae_server->connectionIds(); for(unsigned k=0;kmeterPort(ids.at(l))>0)&& - cae_server->metersEnabled(ids.at(l),cardnum)) { - SendMeterUpdate(QString::asprintf("MP %d %d %d",cardnum,k,pos[k]), - ids.at(l)); + if((psess=GetPlaySession(cardnum,k))!=NULL) { + for(int l=0;lmeterPort(ids.at(l))>0)&& + cae_server->metersEnabled(ids.at(l),cardnum)) { + SendMeterUpdate(QString::asprintf("MP %u %d", + psess->serialNumber(),pos[k]), + psess->socketDescriptor()); + } } } } @@ -1630,6 +1659,12 @@ void MainObject::SendMeterOutputStatusUpdate(int card,int port,int stream) void MainObject::SendMeterUpdate(const QString &msg,int conn_id) { + /* + rda->syslog(LOG_NOTICE,"writing %s to %s:%u", + msg.toUtf8().constData(), + cae_server->peerAddress(conn_id).toString().toUtf8().constData(), + 0xFFFF&cae_server->meterPort(conn_id)); + */ meter_socket->writeDatagram(msg.toUtf8(),cae_server->peerAddress(conn_id), cae_server->meterPort(conn_id)); } @@ -1708,6 +1743,19 @@ void MainObject::MakeDriver(unsigned *next_card,RDStation::AudioDriver type) } +PlaySession *MainObject::GetPlaySession(unsigned card,unsigned stream) const +{ + for(QMap::const_iterator it=play_sessions.begin(); + it!=play_sessions.end();it++) { + if((it.value()->cardNumber()==card)&& + (it.value()->streamNumber()==stream)) { + return it.value(); + } + } + return NULL; +} + + int main(int argc,char *argv[]) { int rc; diff --git a/cae/cae.h b/cae/cae.h index 1eb19326..6206d12c 100644 --- a/cae/cae.h +++ b/cae/cae.h @@ -2,7 +2,7 @@ // // The Core Audio Engine component of Rivendell // -// (C) Copyright 2002-2021 Fred Gleason +// (C) Copyright 2002-2023 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 @@ -47,6 +47,7 @@ #include "driver.h" #include "cae_server.h" +#include "playsession.h" #ifndef HAVE_SRC_CONV void src_int_to_float_array (const int *in, float *out, int len); @@ -70,12 +71,13 @@ class MainObject : public QObject MainObject(QObject *parent=0); private slots: - void loadPlaybackData(int id,unsigned card,const QString &name); - void unloadPlaybackData(int id,unsigned handle); - void playPositionData(int id,unsigned handle,unsigned pos); - void playData(int id,unsigned handle,unsigned length,unsigned speed, + void loadPlaybackData(uint64_t phandle,unsigned card,unsigned portnum, + const QString &name); + void unloadPlaybackData(uint64_t phandle); + void playPositionData(uint64_t phandle,unsigned pos); + void playData(uint64_t phandle,unsigned length,unsigned speed, unsigned pitch_flag); - void stopPlaybackData(int id,unsigned handle); + void stopPlaybackData(uint64_t phandle); void timescalingSupportData(int id,unsigned card); void loadRecordingData(int id,unsigned card,unsigned port,unsigned coding, unsigned channels,unsigned samprate,unsigned bitrate, @@ -85,10 +87,8 @@ class MainObject : public QObject int threshold_level); void stopRecordingData(int id,unsigned card,unsigned stream); void setInputVolumeData(int id,unsigned card,unsigned stream,int level); - void setOutputVolumeData(int id,unsigned card,unsigned stream,int port, - int level); - void fadeOutputVolumeData(int id,unsigned card,unsigned stream,unsigned port, - int level,unsigned length); + void setOutputVolumeData(uint64_t phandle,int level); + void fadeOutputVolumeData(uint64_t phandle,int level,unsigned length); void setInputLevelData(int id,unsigned card,unsigned stream,int level); void setOutputLevelData(int id,unsigned card,unsigned port,int level); void setInputModeData(int id,unsigned card,unsigned stream,unsigned mode); @@ -116,8 +116,8 @@ class MainObject : public QObject void KillSocket(int); bool CheckDaemon(QString); pid_t GetPid(QString pidfile); - int GetNextHandle(); - int GetHandle(int card,int stream); + PlaySession *GetPlaySession(unsigned card,unsigned stream) const; + uint64_t GetPlayHandle(unsigned cardnum,unsigned streamnum) const; void ProbeCaps(RDStation *station); void ClearDriverEntries() const; void SendMeterLevelUpdate(const QString &type,int cardnum,int portnum, @@ -138,19 +138,12 @@ class MainObject : public QObject int record_owner[RD_MAX_CARDS][RD_MAX_STREAMS]; int record_length[RD_MAX_CARDS][RD_MAX_STREAMS]; int record_threshold[RD_MAX_CARDS][RD_MAX_STREAMS]; - int play_owner[RD_MAX_CARDS][RD_MAX_STREAMS]; int play_length[RD_MAX_CARDS][RD_MAX_STREAMS]; int play_speed[RD_MAX_CARDS][RD_MAX_STREAMS]; bool play_pitch[RD_MAX_CARDS][RD_MAX_STREAMS]; bool port_status[RD_MAX_CARDS][RD_MAX_PORTS]; bool output_status_flag[RD_MAX_CARDS][RD_MAX_PORTS][RD_MAX_STREAMS]; - struct { - int card; - int stream; - int owner; - } play_handle[256]; - int next_play_handle; - + QMap play_sessions; private: bool CheckLame(); bool CheckMp4Decode(); diff --git a/cae/cae_server.cpp b/cae/cae_server.cpp index 6edddc73..4e74ca82 100644 --- a/cae/cae_server.cpp +++ b/cae/cae_server.cpp @@ -27,6 +27,7 @@ #include #include "cae_server.h" +#include "playsession.h" // // Uncomment this to send all protocol messages to syslog (DEBUG priority) @@ -137,6 +138,12 @@ void CaeServer::sendCommand(const QString &cmd) } +void CaeServer::sendCommand(uint64_t phandle,const QString &cmd) +{ + sendCommand(PlaySession::socketDescriptor(phandle),cmd); +} + + void CaeServer::sendCommand(int id,const QString &cmd) { #ifdef __CAE_SERVER_LOG_PROTOCOL_MESSAGES @@ -237,7 +244,7 @@ bool CaeServer::ProcessCommand(int id,const QString &cmd) // Unpriviledged Commands // if(f0.at(0)=="DC") { - connectionClosedData(id); + cae_connections.value(id)->socket->close(); return true; } @@ -281,32 +288,41 @@ bool CaeServer::ProcessCommand(int id,const QString &cmd) } bool was_processed=false; - if((f0.at(0)=="LP")&&(f0.size()==3)) { // Load Playback - unsigned card=f0.at(1).toUInt(&ok); - if(ok&&(card +// +// 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 "playsession.h" + +PlaySession::PlaySession(int sock,unsigned serial,unsigned cardnum, + unsigned portnum,unsigned streamnum) +{ + d_socket_descriptor=sock; + d_serial_number=serial; + d_card_number=cardnum; + d_port_number=portnum; + d_stream_number=streamnum; + d_length=0; + d_speed=100000; +} + + +PlaySession::PlaySession(uint64_t phandle,unsigned cardnum,unsigned portnum, + unsigned streamnum) +{ + d_socket_descriptor=PlaySession::socketDescriptor(phandle); + d_serial_number=PlaySession::serialNumber(phandle); + d_card_number=cardnum; + d_port_number=portnum; + d_stream_number=streamnum; + d_length=0; + d_speed=100000; +} + + +uint64_t PlaySession::handle() const +{ + return PlaySession::makeHandle(d_socket_descriptor,d_serial_number); +} + + +int PlaySession::socketDescriptor() const +{ + return d_socket_descriptor; +} + + +unsigned PlaySession::serialNumber() const +{ + return d_serial_number; +} + + +unsigned PlaySession::cardNumber() const +{ + return d_card_number; +} + + +unsigned PlaySession::portNumber() const +{ + return d_port_number; +} + + +unsigned PlaySession::streamNumber() const +{ + return d_stream_number; +} + + +unsigned PlaySession::length() const +{ + return d_length; +} + + +void PlaySession::setLength(unsigned msec) +{ + d_length=msec; +} + + +unsigned PlaySession::speed() const +{ + return d_speed; +} + + +void PlaySession::setSpeed(unsigned ratio) +{ + d_speed=ratio; +} + + +uint64_t PlaySession::makeHandle(int fd,unsigned serial) +{ + return (((uint64_t)fd)<<32)|(0xffffffff&serial); +} + + +int PlaySession::socketDescriptor(uint64_t phandle) +{ + return phandle>>32; +} + + +unsigned PlaySession::serialNumber(uint64_t phandle) +{ + return 0xffffffff&phandle; +} diff --git a/cae/playsession.h b/cae/playsession.h new file mode 100644 index 00000000..bc119e52 --- /dev/null +++ b/cae/playsession.h @@ -0,0 +1,58 @@ +// playsession.h +// +// Playout session class for caed(8) +// +// (C) Copyright 2023 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 PLAYSESSION_H +#define PLAYSESSION_H + +#include + +class PlaySession +{ + public: + PlaySession(int sock,unsigned serial,unsigned cardnum,unsigned portnum, + unsigned streamnum); + PlaySession(uint64_t phandle,unsigned cardnum,unsigned portnum, + unsigned streamnum); + uint64_t handle() const; + int socketDescriptor() const; + unsigned serialNumber() const; + unsigned cardNumber() const; + unsigned portNumber() const; + unsigned streamNumber() const; + unsigned length() const; + void setLength(unsigned msec); + unsigned speed() const; + void setSpeed(unsigned ratio); + static uint64_t makeHandle(int fd,unsigned serial); + static int socketDescriptor(uint64_t phandle); + static unsigned serialNumber(uint64_t phandle); + + private: + int d_socket_descriptor; + unsigned d_serial_number; + unsigned d_card_number; + unsigned d_port_number; + unsigned d_stream_number; + unsigned d_length; + unsigned d_speed; +}; + + +#endif // PLAYSESSION_H diff --git a/docs/apis/cae.xml b/docs/apis/cae.xml index 1be77444..4e88c712 100644 --- a/docs/apis/cae.xml +++ b/docs/apis/cae.xml @@ -118,10 +118,22 @@ stream-num. - LP card-num + LP serial + card-num + port-num name! + + + serial + + + 32 bit Unsigned integer, unique within the scope of the TCP + connection. + Used to refer to this playback session in subsequent calls to CAE. + + card-num @@ -130,6 +142,14 @@ The number of the audio adapter to use. + + + port-num + + + The output port number of the audio adapter to use. + + name @@ -141,35 +161,11 @@ Returns: LP + serial card-num - name - stream-num - conn-handle! + port-num + name! - - - - stream-num - - - - The stream number selected to be used, or a -1 in case of error. - This is relative to the audio adapter selected. - - - - - - conn-handle - - - - The connection handle. This will be used to refer to the playback - event in all subsequent calls to CAE. - - - - @@ -179,16 +175,16 @@ output stream->output port volume controls. - UP conn-handle! + UP serial! - conn-handle + serial - The connection handle of the playback event, from the + The serial number of the playback event, from the Load Playback call. @@ -202,17 +198,17 @@ Position the playback pointer. - PP conn-handle + PP serial position! - conn-handle + serial - The connection handle of the playback event, from the + The serial number of the playback event, from the Load Playback call. @@ -236,7 +232,7 @@ Play the loaded file from the current position. - PY conn-handle + PY serial length speed pitch-flag! @@ -244,11 +240,11 @@ - conn-handle + serial - The connection handle of the playback event, from the + The serial number of the playback event, from the Load Playback call. @@ -294,16 +290,16 @@ Stop playback of the specified playback interface. - SP conn-handle! + SP serial! - conn-handle + serial - The connection handle of the playback event, from the + The serial number of the playback event, from the Load Playback call. @@ -668,36 +664,25 @@ <command>Set Output Volume</command> - Set the volume of an output stream. + Set the volume of an output playback. - OV card-num - stream-num - port-num + OV serial level! - card-num + serial - The number of the audio adapter to use. - - - - - - stream-num - - - - The stream number to use. This is relative to the audio adapter - selected. + The serial number of the playback event, from the + Load Playback call. + level @@ -728,45 +715,22 @@ <command>Fade Output Volume</command> - Transition the volume of an output stream over time. + Transition the volume of an output playback over time. - FV card-num - stream-num - port-num + FV serial level length! - card-num + serial - The number of the audio adapter to use. - - - - - - stream-num - - - - The stream number to use. This is relative to the audio adapter - selected. - - - - - - port-num - - - - The port number to use. This is relative to the audio adapter - selected. + The serial number of the playback event, from the + Load Playback call. @@ -1614,34 +1578,24 @@ - <command>Output Stream Position</command> + <command>Output Play Position</command> Output play position. MP - card-num - stream-num + serial pos! - card-num + serial - The number of the audio adapter to use. - - - - - - stream-num - - - - The stream number on the audio adapter. + The serial number of the playback event, from the + Load Playback call. diff --git a/lib/rdcae.cpp b/lib/rdcae.cpp index d0530faa..446a9be3 100644 --- a/lib/rdcae.cpp +++ b/lib/rdcae.cpp @@ -2,7 +2,7 @@ // // Connection to the Rivendell Core Audio Engine // -// (C) Copyright 2002-2019 Fred Gleason +// (C) Copyright 2002-2023 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 @@ -38,6 +38,46 @@ #include #include +__RDCae_PlayChannel::__RDCae_PlayChannel(unsigned card,unsigned port) +{ + d_card=card; + d_port=port; + d_position=0; +} + + +unsigned __RDCae_PlayChannel::card() const +{ + return d_card; +} + + +unsigned __RDCae_PlayChannel::port() const +{ + return d_port; +} + + +unsigned __RDCae_PlayChannel::position() const +{ + return d_position; +} + + +void __RDCae_PlayChannel::setPosition(unsigned pos) +{ + d_position=pos; +} + + +bool __RDCae_PlayChannel::operator==(const __RDCae_PlayChannel &other) const +{ + return (d_card==other.d_card)&&(d_port==other.d_port); +} + + + + RDCae::RDCae(RDStation *station,RDConfig *config,QObject *parent) : QObject(parent) { @@ -46,8 +86,7 @@ RDCae::RDCae(RDStation *station,RDConfig *config,QObject *parent) cae_station=station; cae_config=config; cae_connected=false; - argnum=0; - argptr=0; + next_serial_number=1; // // Control Connection @@ -114,27 +153,18 @@ RDCae::RDCae(RDStation *station,RDConfig *config,QObject *parent) cae_output_levels[i][j][k]=-10000; cae_stream_output_levels[i][j][k]=-10000; } - for(int k=0;kstart(RD_METER_UPDATE_INTERVAL); } RDCae::~RDCae() { - // delete cae_socket; + if(cae_socket>=0) { + close(cae_socket); + } + if(cae_meter_socket>=0) { + close(cae_meter_socket); + } } @@ -197,72 +227,73 @@ void RDCae::enableMetering(QList *cards) } -bool RDCae::loadPlay(int card,QString name,int *stream,int *handle) +unsigned RDCae::loadPlay(unsigned card,unsigned port,const QString &name) { - int count=0; - - SendCommand(QString().sprintf("LP %d %s!", - card,name.toUtf8().constData())); - - // - // This is really warty, but needed to make the method 'synchronous' - // with respect to CAE. - // - *stream=-2; - *handle=-1; - while(*stream==-2) { - readyData(stream,handle,name); - usleep(1000); - count++; + /* + cae_serials[card][port]=next_serial_number++; + SendCommand(QString().sprintf("LP %u %u %u %s!", + cae_serials[card][port],card,port, + name.toUtf8().constData())); + __RDCae_PlayChannel chan(card,port); + for(QMap::const_iterator it=cae_play_channels.begin();it!=cae_play_channels.end();it++) { + if(it.value()==chan) { + emit playPortStatusChanged(card,port,true); + break; + } } - if(count>1000) { - rda->syslog(LOG_ERR, - "*** LoadPlay: CAE took %d mS to return stream for %s ***", - count,name.toUtf8().constData()); - } - cae_handle[card][*stream]=*handle; - cae_pos[card][*stream]=0xFFFFFFFF; + cae_play_channelscae_serials - // CAE Daemon sends back a stream of -1 if there is an issue with allocating it - // such as file missing, etc. - if(*stream < 0) { - return false; + return cae_serials[card][port]; + */ + unsigned serial=next_serial_number++; + SendCommand(QString().sprintf("LP %u %u %u %s!", + serial,card,port,name.toUtf8().constData())); + bool found=false; + for(QMap::const_iterator it=cae_play_channels.begin();it!=cae_play_channels.end();it++) { + if((it.value()->card()==card)&&(it.value()->port()==port)) { + found=true; + break; + } + } + cae_play_channels[serial]=new __RDCae_PlayChannel(card,port); + if(!found) { + emit playPortStatusChanged(card,port,true); } - return true; + return serial; } -void RDCae::unloadPlay(int handle) +void RDCae::unloadPlay(unsigned serial) { - SendCommand(QString().sprintf("UP %d!",handle)); + SendCommand(QString().sprintf("UP %u!",serial)); } -void RDCae::positionPlay(int handle,int pos) +void RDCae::positionPlay(unsigned serial,int pos) { if(pos<0) { return; } - SendCommand(QString().sprintf("PP %d %u!",handle,pos)); + SendCommand(QString().sprintf("PP %u %u!",serial,pos)); } -void RDCae::play(int handle,unsigned length,int speed,bool pitch) +void RDCae::play(unsigned serial,unsigned length,int speed,bool pitch) { int pitch_state=0; if(pitch) { pitch_state=1; } - SendCommand(QString().sprintf("PY %d %u %d %d!", - handle,length,speed,pitch_state)); + SendCommand(QString().sprintf("PY %u %u %d %d!", + serial,length,speed,pitch_state)); } -void RDCae::stopPlay(int handle) +void RDCae::stopPlay(unsigned serial) { - SendCommand(QString().sprintf("SP %d!",handle)); + SendCommand(QString().sprintf("SP %u!",serial)); } @@ -270,8 +301,6 @@ void RDCae::loadRecord(int card,int stream,QString name, AudioCoding coding,int chan,int samp_rate, int bit_rate) { - // printf("RDCae::loadRecord(%d,%d,%s,%d,%d,%d,%d)\n", - // card,stream,(const char *)name,coding,chan,samp_rate,bit_rate); SendCommand(QString().sprintf("LR %d %d %d %d %d %d %s!", card,stream,(int)coding,chan,samp_rate, bit_rate,name.toUtf8().constData())); @@ -309,16 +338,15 @@ void RDCae::setInputVolume(int card,int stream,int level) } -void RDCae::setOutputVolume(int card,int stream,int port,int level) +void RDCae::setOutputVolume(unsigned serial,int level) { - SendCommand(QString().sprintf("OV %d %d %d %d!",card,stream,port,level)); + SendCommand(QString().sprintf("OV %u %d!",serial,level)); } -void RDCae::fadeOutputVolume(int card,int stream,int port,int level,int length) +void RDCae::fadeOutputVolume(unsigned serial,int level,int length) { - SendCommand(QString().sprintf("FV %d %d %d %d %d!", - card,stream,port,level,length)); + SendCommand(QString().sprintf("FV %u %d %d!",serial,level,length)); } @@ -395,15 +423,14 @@ void RDCae::outputStreamMeterUpdate(int card,int stream,short levels[2]) } -unsigned RDCae::playPosition(int handle) +unsigned RDCae::playPosition(unsigned serial) { - for(int i=0;iposition(); } + return 0; } @@ -414,10 +441,13 @@ void RDCae::requestTimescale(int card) } -bool RDCae::playPortActive(int card,int port,int except_stream) +bool RDCae::playPortStatus(int card,int port,unsigned except_serial) const { - for(int i=0;i::const_iterator it= + cae_play_channels.begin();it!=cae_play_channels.end();it++) { + if((((int)it.value()->card())==card)&& + (((int)it.value()->port())==port)&& + (it.key()!=except_serial)) { return true; } } @@ -425,106 +455,26 @@ bool RDCae::playPortActive(int card,int port,int except_stream) } -void RDCae::setPlayPortActive(int card,int port,int stream) -{ - cae_output_status_flags[card][port][stream]=true; -} - - void RDCae::readyData() { - readyData(0,0,""); -} + char data[1501]; + int n; + if((n=read(cae_socket,data,1500))>0) { + for(int i=0;ireadBlock(buf,256))>0) { - while((c=read(cae_socket,buf,256))>0) { - buf[c]=0; - for(int i=0;i=0) { - if(cae_output_positions[i][j]!=cae_pos[i][j]) { - emit playPositionChanged(cae_handle[i][j], - cae_output_positions[i][j]); - cae_pos[i][j]=cae_output_positions[i][j]; - } + default: + cae_accum+=0xFF&data[i]; + break; } } } @@ -537,157 +487,165 @@ void RDCae::SendCommand(QString cmd) } -void RDCae::DispatchCommand(RDCmdCache *cmd) +void RDCae::DispatchCommand(const QString &cmd) { - int pos; - int card; + __RDCae_PlayChannel *chan=NULL; + QStringList cmds=cmd.split(" ",QString::SkipEmptyParts); + bool was_processed=false; + bool ok=false; - if(!strcmp(cmd->arg(0),"PW")) { // Password Response - if(cmd->arg(1)[0]=='+') { - emit isConnected(true); - } - else { - emit isConnected(false); - } + if((cmds.at(0)=="PW")&&(cmds.size()==2)) { // Password Response + emit isConnected(cmds.at(1)=="+"); + was_processed=true; } - if(!strcmp(cmd->arg(0),"LP")) { // Load Play - int handle=GetHandle(cmd->arg(4)); - int card=CardNumber(cmd->arg(1)); - int stream=StreamNumber(cmd->arg(3)); - rda->syslog(LOG_ERR,"*** RDCae::DispatchCommand: received unhandled play stream from CAE, handle=%d, card=%d, stream=%d, name=\"%s\" ***", - handle,card,stream,cmd->arg(2)); - - unloadPlay(handle); + if((cmds.at(0),"LP")&&(cmds.size()==5)) { // Load Play + // FIXME: What should go here? + was_processed=true; } - if(!strcmp(cmd->arg(0),"UP")) { // Unload Play - if(cmd->arg(2)[0]=='+') { - int handle=GetHandle(cmd->arg(1)); - for(int i=0;iarg(0),"PP")) { // Position Play - if(cmd->arg(3)[0]=='+') { - int handle=GetHandle(cmd->arg(1)); - sscanf(cmd->arg(2),"%u",&pos); - for(int i=0;iarg(0),"PY")) { // Play - if(cmd->arg(4)[0]=='+') { - emit playing(GetHandle(cmd->arg(1))); - } - } - - if(!strcmp(cmd->arg(0),"SP")) { // Stop Play - if(cmd->arg(2)[0]=='+') { - emit playStopped(GetHandle(cmd->arg(1))); - } - } - - if(!strcmp(cmd->arg(0),"TS")) { // Timescale Supported - if(sscanf(cmd->arg(1),"%d",&card)==1) { - if(cmd->arg(2)[0]=='+') { - emit timescalingSupported(card,true); - } - else { - emit timescalingSupported(card,false); + if((cmds.at(0)=="PY")&&(cmds.size()==6)) { // Play + if(cmds.at(5)=='+') { + unsigned serial=cmds.at(1).toUInt(&ok); + if(ok) { + if(SerialCheck(serial,LINE_NUMBER)) { + emit playing(serial); + } } } + was_processed=true; } - if(!strcmp(cmd->arg(0),"LR")) { // Load Record - if(cmd->arg(8)[0]=='+') { - emit recordLoaded(CardNumber(cmd->arg(1)),StreamNumber(cmd->arg(2))); + if((cmds.at(0)=="SP")&&(cmds.size()==3)) { // Stop Play + if(cmds.at(2)=='+') { + unsigned serial=cmds.at(1).toUInt(&ok); + if(ok) { + if(SerialCheck(serial,LINE_NUMBER)) { + emit playStopped(serial); + } + } } + was_processed=true; } - if(!strcmp(cmd->arg(0),"UR")) { // Unload Record - if(cmd->arg(4)[0]=='+') { - emit recordUnloaded(CardNumber(cmd->arg(1)),StreamNumber(cmd->arg(2)), - QString(cmd->arg(3)).toUInt()); + if((cmds.at(0)=="TS")&&(cmds.size()==3)) { // Timescaling Support + int card=cmds.at(1).toInt(&ok); + if(ok&&(card>=0)&&(cardarg(0),"RD")) { // Record - } - - if(!strcmp(cmd->arg(0),"RS")) { // Record Start - if(cmd->arg(3)[0]=='+') { - emit recording(CardNumber(cmd->arg(1)),StreamNumber(cmd->arg(2))); + if((cmds.at(0)=="LR")&&(cmds.size()==9)) { // Load Record + if(cmds.at(8)=='+') { + int card=cmds.at(1).toInt(&ok); + if(ok&&(card>=0)&&(card=0)&&(portarg(0),"SR")) { // Stop Record - if(cmd->arg(3)[0]=='+') { - emit recordStopped(CardNumber(cmd->arg(1)),StreamNumber(cmd->arg(2))); + if((cmds.at(0)=="UR")&&(cmds.size()==5)) { // Unload Record + if(cmds.at(3)=='+') { + int card=cmds.at(1).toInt(&ok); + if(ok&&(card>=0)&&(card=0)&&(portarg(0),"IS")) { // Input Status - switch(cmd->arg(3)[0]) { - case '0': - emit inputStatusChanged(CardNumber(cmd->arg(1)), - StreamNumber(cmd->arg(2)),true); - input_status[CardNumber(cmd->arg(1))][StreamNumber(cmd->arg(2))]= - true; - break; + if((cmds.at(0)=="RD")&&(cmds.size()==6)) { // Record + was_processed=true; + } - case '1': - emit inputStatusChanged(CardNumber(cmd->arg(1)), - StreamNumber(cmd->arg(2)),false); - input_status[CardNumber(cmd->arg(1))][StreamNumber(cmd->arg(2))]= - false; - break; + if((cmds.at(0)=="RS")&&(cmds.size()==4)) { // Record Start + if(cmds.at(3)=='+') { + int card=cmds.at(1).toInt(&ok); + if(ok&&(card>=0)&&(card=0)&&(port=0)&&(card=0)&&(port=0)&&(card=0)&&(portsyslog(LOG_WARNING,"CAE response command \"%s\" was not processed", + cmd.toUtf8().constData()); + } } @@ -697,6 +655,8 @@ void RDCae::UpdateMeters() int n; QStringList args; + bool ok=false; + while((n=read(cae_meter_socket,msg,1500))>0) { msg[n]=0; args=QString(msg).split(" "); @@ -723,9 +683,23 @@ void RDCae::UpdateMeters() } } if(args[0]=="MP") { - if(args.size()==4) { - cae_output_positions[args[1].toInt()][args[2].toInt()]=args[3].toUInt(); + if(args.size()==3) { + unsigned serial=args.at(1).toUInt(&ok); + if(ok) { + emit playPositionChanged(serial,args.at(2).toUInt()); + } } } } } + + +bool RDCae::SerialCheck(unsigned serial,int linenum) const +{ + if(serial==0) { + rda->syslog(LOG_WARNING, + "attempting to use null serial value at rdcae.cpp:%d",linenum); + return false; + } + return true; +} diff --git a/lib/rdcae.h b/lib/rdcae.h index 4f166627..0107d0b3 100644 --- a/lib/rdcae.h +++ b/lib/rdcae.h @@ -2,7 +2,7 @@ // // Connection to the Rivendell Core Audio Engine // -// (C) Copyright 2002-2016 Fred Gleason +// (C) Copyright 2002-2023 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 @@ -21,8 +21,6 @@ #ifndef RDCAE_H #define RDCAE_H -//#include - #include #include #include @@ -32,6 +30,25 @@ #include #include +class __RDCae_PlayChannel +{ + public: + __RDCae_PlayChannel(unsigned card,unsigned port); + unsigned card() const; + unsigned port() const; + unsigned position() const; + void setPosition(unsigned pos); + bool operator==(const __RDCae_PlayChannel &other) const; + + private: + unsigned d_card; + unsigned d_port; + unsigned d_position; +}; + + + + class RDCae : public QObject { Q_OBJECT @@ -44,11 +61,11 @@ class RDCae : public QObject ~RDCae(); bool connectHost(QString *err_msg); void enableMetering(QList *cards); - bool loadPlay(int card,QString name,int *stream,int *handle); - void unloadPlay(int handle); - void positionPlay(int handle,int pos); - void play(int handle,unsigned length,int speed,bool pitch); - void stopPlay(int handle); + unsigned loadPlay(unsigned card,unsigned port,const QString &name); + void unloadPlay(unsigned serial); + void positionPlay(unsigned serial,int pos); + void play(unsigned serial,unsigned length,int speed,bool pitch); + void stopPlay(unsigned serial); void loadRecord(int card,int stream,QString name,AudioCoding coding, int chan,int samp_rate,int bit_rate); void unloadRecord(int card,int stream); @@ -56,8 +73,8 @@ class RDCae : public QObject void stopRecord(int card,int stream); void setClockSource(int card,RDCae::ClockSource src); void setInputVolume(int card,int stream,int level); - void setOutputVolume(int card,int stream,int port,int level); - void fadeOutputVolume(int card,int stream,int port,int level,int length); + void setOutputVolume(unsigned serial,int level); + void fadeOutputVolume(unsigned serial,int level,int length); void setInputLevel(int card,int port,int level); void setOutputLevel(int card,int port,int level); void setInputMode(int card,int stream,RDCae::ChannelMode mode); @@ -69,18 +86,17 @@ class RDCae : public QObject void inputMeterUpdate(int card,int port,short levels[2]); void outputMeterUpdate(int card,int port,short levels[2]); void outputStreamMeterUpdate(int card,int stream,short levels[2]); - unsigned playPosition(int handle); + unsigned playPosition(unsigned serial); void requestTimescale(int card); - bool playPortActive(int card,int port,int except_stream=-1); - void setPlayPortActive(int card,int port,int stream); + bool playPortStatus(int card,int port,unsigned except_serial=0) const; signals: void isConnected(bool state); - void playLoaded(int handle); - void playPositioned(int handle,unsigned pos); - void playing(int handle); - void playStopped(int handle); - void playUnloaded(int handle); + void playLoaded(unsigned serial); + void playPositioned(unsigned serial,unsigned pos); + void playing(unsigned serial); + void playStopped(unsigned serial); + void playUnloaded(unsigned serial); void recordLoaded(int card,int stream); void recording(int card,int stream); void recordStopped(int card,int stream); @@ -88,32 +104,24 @@ class RDCae : public QObject void gpiInputChanged(int line,bool state); void connected(bool state); void inputStatusChanged(int card,int stream,bool state); - void playPositionChanged(int handle,unsigned sample); + void playPositionChanged(unsigned serial,unsigned sample); void timescalingSupported(int card,bool state); + void playPortStatusChanged(int card,int port,bool status); private slots: void readyData(); - void readyData(int *stream,int *handle,QString name); - void clockData(); private: void SendCommand(QString cmd); - void DispatchCommand(RDCmdCache *cmd); - int CardNumber(const char *arg); - int StreamNumber(const char *arg); - int GetHandle(const char *arg); + void DispatchCommand(const QString &cmd); + bool SerialCheck(unsigned serial,int linenum) const; void UpdateMeters(); - // Q3SocketDevice *cae_socket; + unsigned next_serial_number; int cae_socket; bool debug; - char args[CAE_MAX_ARGS][CAE_MAX_LENGTH]; - int argnum; - int argptr; + QByteArray cae_accum; bool cae_connected; bool input_status[RD_MAX_CARDS][RD_MAX_PORTS]; - int cae_handle[RD_MAX_CARDS][RD_MAX_STREAMS]; - unsigned cae_pos[RD_MAX_CARDS][RD_MAX_STREAMS]; - // Q3SocketDevice *cae_meter_socket; int cae_meter_socket; uint16_t cae_meter_port; int cae_meter_base_port; @@ -121,9 +129,7 @@ class RDCae : public QObject short cae_input_levels[RD_MAX_CARDS][RD_MAX_PORTS][2]; short cae_output_levels[RD_MAX_CARDS][RD_MAX_PORTS][2]; short cae_stream_output_levels[RD_MAX_CARDS][RD_MAX_PORTS][2]; - unsigned cae_output_positions[RD_MAX_CARDS][RD_MAX_STREAMS]; - bool cae_output_status_flags[RD_MAX_CARDS][RD_MAX_PORTS][RD_MAX_STREAMS]; - std::vector delayed_cmds; + QMap cae_play_channels; RDStation *cae_station; RDConfig *cae_config; }; diff --git a/lib/rdcartslot.cpp b/lib/rdcartslot.cpp index 81d85ad0..0511e298 100644 --- a/lib/rdcartslot.cpp +++ b/lib/rdcartslot.cpp @@ -373,6 +373,7 @@ void RDCartSlot::setPauseEnabled(bool state) void RDCartSlot::updateMeters() { + /* short lvls[2]; switch(slot_deck->state()) { @@ -388,6 +389,7 @@ void RDCartSlot::updateMeters() case RDPlayDeck::Finished: break; } + */ } diff --git a/lib/rdcueedit.cpp b/lib/rdcueedit.cpp index cb1b0609..e7204f35 100644 --- a/lib/rdcueedit.cpp +++ b/lib/rdcueedit.cpp @@ -2,7 +2,7 @@ // // Cueing Editor for RDLogLine-based Events // -// (C) Copyright 2013-2022 Fred Gleason +// (C) Copyright 2013-2023 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 @@ -622,8 +622,8 @@ void RDCueEdit::UpdateCounters() void RDCueEdit::ClearChannel() { - if(rda->cae()->playPortActive(edit_play_deck->card(),edit_play_deck->port(), - edit_play_deck->stream())) { + if(rda->cae()->playPortStatus(edit_play_deck->card(),edit_play_deck->port(), + edit_play_deck->serial())) { return; } if((!edit_stop_rml.isEmpty())&&(edit_event_player!=NULL)) { diff --git a/lib/rdlogplay.cpp b/lib/rdlogplay.cpp index ce848006..09027990 100644 --- a/lib/rdlogplay.cpp +++ b/lib/rdlogplay.cpp @@ -2058,8 +2058,7 @@ bool RDLogPlay::StartEvent(int line,RDLogLine::TransType trans_type, if(play_timescaling_available&&logline->enforceLength()) { logline->setTimescalingActive(true); } - play_cae->setOutputVolume(playdeck->card(),playdeck->stream(), - playdeck->port(),playdeck->cut()->playGain()); + play_cae->setOutputVolume(playdeck->serial(),playdeck->cut()->playGain()); if((int)logline->playPosition()>logline->effectiveLength()) { rda->syslog(LOG_DEBUG,"log engine: *** position out of bounds: Line: %d Cart: %d Pos: %d ***",line,logline->cartNumber(),logline->playPosition()); logline->setPlayPosition(0); @@ -2081,12 +2080,12 @@ bool RDLogPlay::StartEvent(int line,RDLogLine::TransType trans_type, } emit channelStarted(play_id,playdeck->channel(), playdeck->card(),playdeck->port()); - rda->syslog(LOG_INFO,"log engine: started audio cart: Line: %d Cart: %u Cut: %u Pos: %d Card: %d Stream: %d Port: %d", + rda->syslog(LOG_INFO,"log engine: started audio cart: Line: %d Cart: %u Cut: %u Pos: %d Serial: %u Card: %d Port: %d", line,logline->cartNumber(), playdeck->cut()->cutNumber(), logline->playPosition(), + playdeck->serial(), playdeck->card(), - playdeck->stream(), playdeck->port()); // @@ -2292,11 +2291,12 @@ void RDLogPlay::CleanupEvent(int id) logline->cartNumber()); } else { - rda->syslog(LOG_INFO,"log engine: finished event: Line: %d Cart: %u Cut: %u Card: %d Stream: %d Port: %d", + rda->syslog(LOG_INFO,"log engine: finished event: Line: %d Cart: %u Cut: %u Serial: %u Card: %d Port: %d", line,logline->cartNumber(), playdeck->cut()->cutNumber(), + playdeck->serial(), playdeck->card(), - playdeck->stream(),playdeck->port()); + playdeck->port()); } RDLogLine *prev_logline; if((prev_logline=logLine(line-1))==NULL) { @@ -2985,12 +2985,11 @@ void RDLogPlay::ClearChannel(int deckid) if(play_deck[deckid]->channel()<0) { return; } - if(play_cae->playPortActive(play_deck[deckid]->card(), + if(play_cae->playPortStatus(play_deck[deckid]->card(), play_deck[deckid]->port(), - play_deck[deckid]->stream())) { + play_deck[deckid]->serial())) { return; } - if(play_deck[deckid]->channel()>=0) { play_event_player->exec(play_stop_rml[play_deck[deckid]->channel()]); /* diff --git a/lib/rdmarkerplayer.cpp b/lib/rdmarkerplayer.cpp index 2bea299a..84202283 100644 --- a/lib/rdmarkerplayer.cpp +++ b/lib/rdmarkerplayer.cpp @@ -27,8 +27,7 @@ RDMarkerPlayer::RDMarkerPlayer(int card,int port,QWidget *parent) { d_cards.push_back(card); d_port=port; - d_cae_stream=-1; - d_cae_handle=-1; + d_cae_serial=0; d_is_playing=false; d_looping=false; @@ -36,10 +35,12 @@ RDMarkerPlayer::RDMarkerPlayer(int card,int port,QWidget *parent) // CAE // rda->cae()->enableMetering(&d_cards); - connect(rda->cae(),SIGNAL(playing(int)),this,SLOT(caePlayedData(int))); - connect(rda->cae(),SIGNAL(playStopped(int)),this,SLOT(caePausedData(int))); - connect(rda->cae(),SIGNAL(playPositionChanged(int,unsigned)), - this,SLOT(caePositionData(int,unsigned))); + connect(rda->cae(),SIGNAL(playing(unsigned)), + this,SLOT(caePlayedData(unsigned))); + connect(rda->cae(),SIGNAL(playStopped(unsigned)), + this,SLOT(caePausedData(unsigned))); + connect(rda->cae(),SIGNAL(playPositionChanged(unsigned,unsigned)), + this,SLOT(caePositionData(unsigned,unsigned))); // // Marker Readouts @@ -230,12 +231,9 @@ QSizePolicy RDMarkerPlayer::sizePolicy() const bool RDMarkerPlayer::setCut(unsigned cartnum,int cutnum) { clearCut(); - - if(!rda->cae()->loadPlay(d_cards.first(),RDCut::cutName(cartnum,cutnum), - &d_cae_stream,&d_cae_handle)) { - return false; - } - rda->cae()->positionPlay(d_cae_handle,0); + d_cae_serial= + rda->cae()->loadPlay(d_cards.first(),d_port,RDCut::cutName(cartnum,cutnum)); + rda->cae()->positionPlay(d_cae_serial,0); QString sql=QString("select ")+ "`START_POINT`,"+ // 00 @@ -276,11 +274,10 @@ bool RDMarkerPlayer::setCut(unsigned cartnum,int cutnum) void RDMarkerPlayer::clearCut() { - if(d_cae_handle>=0) { - rda->cae()->stopPlay(d_cae_handle); - rda->cae()->unloadPlay(d_cae_handle); - d_cae_stream=-1; - d_cae_handle=-1; + if(d_cae_serial>0) { + rda->cae()->stopPlay(d_cae_serial); + rda->cae()->unloadPlay(d_cae_serial); + d_cae_serial=0; d_is_playing=false; } for(int i=0;icae()->positionPlay(d_cae_handle,msec); + rda->cae()->positionPlay(d_cae_serial,msec); } @@ -369,17 +366,15 @@ void RDMarkerPlayer::buttonPlayData() { d_active_play_button=d_play_button; - if(d_cae_handle>=0) { + if(d_cae_serial>0) { if(d_is_playing) { - rda->cae()->stopPlay(d_cae_handle); + rda->cae()->stopPlay(d_cae_serial); } } d_loop_start_msec=d_cursor_position; d_loop_start_length=0; - rda->cae()->setOutputVolume(d_cards.first(),d_cae_stream, - d_port,0+100*d_play_gain_spin->value()); - rda->cae()->play(d_cae_handle,d_loop_start_length,100000,false); - rda->cae()->setPlayPortActive(d_cards.first(),d_port,d_cae_stream); + rda->cae()->setOutputVolume(d_cae_serial,0+100*d_play_gain_spin->value()); + rda->cae()->play(d_cae_serial,d_loop_start_length,100000,false); d_meter_timer->start(RD_METER_UPDATE_INTERVAL); } @@ -387,19 +382,17 @@ void RDMarkerPlayer::buttonPlayData() void RDMarkerPlayer::buttonPlayFromData() { d_active_play_button=d_play_from_button; - if(d_cae_handle>=0) { + if(d_cae_serial>0) { if(d_is_playing) { - rda->cae()->stopPlay(d_cae_handle); + rda->cae()->stopPlay(d_cae_serial); } } if(d_selected_markers[RDMarkerHandle::Start]!=RDMarkerHandle::LastRole) { d_loop_start_msec=d_pointers[d_selected_markers[0]]; - rda->cae()->positionPlay(d_cae_handle,d_loop_start_msec); + rda->cae()->positionPlay(d_cae_serial,d_loop_start_msec); d_loop_start_length=0; - rda->cae()->setOutputVolume(d_cards.first(),d_cae_stream,d_port, - 0+100*d_play_gain_spin->value()); - rda->cae()->play(d_cae_handle,d_loop_start_length,100000,false); - rda->cae()->setPlayPortActive(d_cards.first(),d_port,d_cae_stream); + rda->cae()->setOutputVolume(d_cae_serial,0+100*d_play_gain_spin->value()); + rda->cae()->play(d_cae_serial,d_loop_start_length,100000,false); d_meter_timer->start(RD_METER_UPDATE_INTERVAL); } } @@ -408,9 +401,9 @@ void RDMarkerPlayer::buttonPlayFromData() void RDMarkerPlayer::buttonPlayToData() { d_active_play_button=d_play_to_button; - if(d_cae_handle>=0) { + if(d_cae_serial>0) { if(d_is_playing) { - rda->cae()->stopPlay(d_cae_handle); + rda->cae()->stopPlay(d_cae_serial); } } if(d_selected_markers[RDMarkerHandle::End]!=RDMarkerHandle::LastRole) { @@ -420,11 +413,9 @@ void RDMarkerPlayer::buttonPlayToData() d_loop_start_msec=0; d_loop_start_length=d_pointers[d_selected_markers[1]]; } - rda->cae()->positionPlay(d_cae_handle,d_loop_start_msec); - rda->cae()->setOutputVolume(d_cards.first(),d_cae_stream,d_port, - 0+100*d_play_gain_spin->value()); - rda->cae()->play(d_cae_handle,d_loop_start_length,100000,false); - rda->cae()->setPlayPortActive(d_cards.first(),d_port,d_cae_stream); + rda->cae()->positionPlay(d_cae_serial,d_loop_start_msec); + rda->cae()->setOutputVolume(d_cae_serial,0+100*d_play_gain_spin->value()); + rda->cae()->play(d_cae_serial,d_loop_start_length,100000,false); d_meter_timer->start(RD_METER_UPDATE_INTERVAL); } } @@ -432,10 +423,10 @@ void RDMarkerPlayer::buttonPlayToData() void RDMarkerPlayer::buttonStopData() { - if(d_cae_handle>=0) { + if(d_cae_serial>0) { if(d_is_playing) { d_stopping=true; - rda->cae()->stopPlay(d_cae_handle); + rda->cae()->stopPlay(d_cae_serial); } } } @@ -525,9 +516,9 @@ void RDMarkerPlayer::meterData() } -void RDMarkerPlayer::caePlayedData(int handle) +void RDMarkerPlayer::caePlayedData(unsigned serial) { - if(handle==d_cae_handle) { + if(serial==d_cae_serial) { if(!d_is_playing) { d_active_play_button->setState(RDTransportButton::On); d_stop_button->setState(RDTransportButton::Off); @@ -537,13 +528,13 @@ void RDMarkerPlayer::caePlayedData(int handle) } -void RDMarkerPlayer::caePausedData(int handle) +void RDMarkerPlayer::caePausedData(unsigned serial) { - if(handle==d_cae_handle) { + if(serial==d_cae_serial) { if(d_is_playing) { if(d_looping&&(!d_stopping)) { - rda->cae()->positionPlay(d_cae_handle,d_loop_start_msec); - rda->cae()->play(d_cae_handle,d_loop_start_length,100000,false); + rda->cae()->positionPlay(d_cae_serial,d_loop_start_msec); + rda->cae()->play(d_cae_serial,d_loop_start_length,100000,false); } else { d_stopping=false; @@ -563,10 +554,12 @@ void RDMarkerPlayer::caePausedData(int handle) } -void RDMarkerPlayer::caePositionData(int handle,unsigned msec) +void RDMarkerPlayer::caePositionData(unsigned serial,unsigned msec) { - if(handle==d_cae_handle) { - d_position_edit->setText(RDGetTimeLength(msec-d_pointers[RDMarkerHandle::CutStart],true,true)); + if(serial==d_cae_serial) { + d_position_edit-> + setText(RDGetTimeLength(msec-d_pointers[RDMarkerHandle::CutStart], + true,true)); d_cursor_position=msec; emit cursorPositionChanged(msec); } diff --git a/lib/rdmarkerplayer.h b/lib/rdmarkerplayer.h index 0fa1ffa5..1152d1b2 100644 --- a/lib/rdmarkerplayer.h +++ b/lib/rdmarkerplayer.h @@ -2,7 +2,7 @@ // // Audio player for RDMarkerDialog // -// (C) Copyright 2021 Fred Gleason +// (C) Copyright 2021-2023 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 @@ -80,9 +80,9 @@ class RDMarkerPlayer : public RDWidget void buttonTrimEndData(); void readoutClickedData(int role); void meterData(); - void caePlayedData(int handle); - void caePausedData(int handle); - void caePositionData(int handle,unsigned pos); + void caePlayedData(unsigned serial); + void caePausedData(unsigned serial); + void caePositionData(unsigned serial,unsigned pos); void trimThresholdChanged(int dbfs); protected: @@ -122,8 +122,7 @@ class RDMarkerPlayer : public RDWidget QSpinBox *d_trim_spin; QList d_cards; int d_port; - int d_cae_stream; - int d_cae_handle; + unsigned d_cae_serial; bool d_is_playing; RDMarkerHandle::PointerRole d_selected_markers[2]; int d_pointers[RDMarkerHandle::LastRole]; diff --git a/lib/rdplay_deck.cpp b/lib/rdplay_deck.cpp index 27755fdd..e72ac02e 100644 --- a/lib/rdplay_deck.cpp +++ b/lib/rdplay_deck.cpp @@ -31,7 +31,7 @@ RDPlayDeck::RDPlayDeck(RDCae *cae,int id,QObject *parent) play_start_time=QTime(); play_owner=-1; play_last_start_position=0; - play_handle=-1; + play_serial=0; play_audio_length=0; play_channel=-1; play_hook_mode=false; @@ -50,12 +50,13 @@ RDPlayDeck::RDPlayDeck(RDCae *cae,int id,QObject *parent) // CAE Connection // play_cae=cae; - connect(play_cae,SIGNAL(playing(int)),this,SLOT(playingData(int))); - connect(play_cae,SIGNAL(playStopped(int)),this,SLOT(playStoppedData(int))); + connect(play_cae,SIGNAL(playing(unsigned)),this,SLOT(playingData(unsigned))); + connect(play_cae,SIGNAL(playStopped(unsigned)), + this,SLOT(playStoppedData(unsigned))); play_cart=NULL; play_cut=NULL; play_card=-1; - play_stream=-1; + play_serial=0; // // Timers @@ -86,8 +87,8 @@ RDPlayDeck::RDPlayDeck(RDCae *cae,int id,QObject *parent) RDPlayDeck::~RDPlayDeck() { if(play_state!=RDPlayDeck::Stopped) { - play_cae->stopPlay(play_handle); - play_cae->unloadPlay(play_handle); + play_cae->stopPlay(play_serial); + play_cae->unloadPlay(play_serial); } } @@ -237,10 +238,7 @@ bool RDPlayDeck::setCart(RDLogLine *logline,bool rotate) play_duck_gain[0]=logline->duckUpGain(); play_duck_gain[1]=logline->duckDownGain(); if(play_state!=RDPlayDeck::Paused) { - if(!play_cae->loadPlay(play_card,play_cut->cutName(), - &play_stream,&play_handle)) { - return false; - } + play_serial=play_cae->loadPlay(play_card,play_port,play_cut->cutName()); } play_state=RDPlayDeck::Stopped; return true; @@ -255,7 +253,7 @@ RDCut *RDPlayDeck::cut() const bool RDPlayDeck::playable() const { - if(play_handle<0) { + if(play_serial==0) { return false; } return true; @@ -274,9 +272,9 @@ void RDPlayDeck::setCard(int card_num) } -int RDPlayDeck::stream() const +unsigned RDPlayDeck::serial() const { - return play_stream; + return play_serial; } @@ -349,7 +347,7 @@ void RDPlayDeck::clear() break; case RDPlayDeck::Paused: - play_cae->unloadPlay(play_handle); + play_cae->unloadPlay(play_serial); emit stateChanged(play_id,RDPlayDeck::Stopped); break; @@ -366,10 +364,10 @@ void RDPlayDeck::reset() switch(play_state) { case RDPlayDeck::Playing: case RDPlayDeck::Stopping: - play_cae->stopPlay(play_handle); + play_cae->stopPlay(play_serial); case RDPlayDeck::Paused: - play_cae->unloadPlay(play_handle); + play_cae->unloadPlay(play_serial); break; default: @@ -450,7 +448,7 @@ void RDPlayDeck::play(unsigned pos,int segue_start,int segue_end, else play_ducked=play_duck_gain[0]; - if(play_handle<0) { + if(play_serial==0) { return; } if(segue_start>=0) { @@ -464,26 +462,23 @@ void RDPlayDeck::play(unsigned pos,int segue_start,int segue_end, play_last_start_position=play_start_position; stop_called=false; pause_called=false; - play_cae->positionPlay(play_handle,play_audio_point[0]+pos); - play_cae->setPlayPortActive(play_card,play_port,play_stream); - play_cae->setOutputVolume(play_card,play_stream,-1,RD_MUTE_DEPTH); + play_cae->positionPlay(play_serial,play_audio_point[0]+pos); if((play_fade_point[0]==-1)||(play_fade_point[0]==play_audio_point[0])|| ((fadeup=play_fade_point[0]-play_audio_point[0]-pos)<=0)|| (play_state==RDPlayDeck::Paused)) { if((play_fade_point[1]==-1)||((fadeup=pos-play_fade_point[1])<=0)|| (play_state==RDPlayDeck::Paused)) { - play_cae->setOutputVolume(play_card,play_stream,play_port, - play_ducked+play_cut_gain+play_duck_level); - play_cae->fadeOutputVolume(play_card,play_stream,play_port, + play_cae-> + setOutputVolume(play_serial,play_ducked+play_cut_gain+play_duck_level); + play_cae->fadeOutputVolume(play_serial, play_ducked+play_cut_gain+play_duck_level,10); } else { // Fadedown event in progress, interpolate the gain accordingly int level=play_fade_gain[1]*((int)pos-play_fade_point[1])/ (play_audio_point[1]-play_fade_point[1]); play_cae-> - setOutputVolume(play_card,play_stream,play_port, - level+play_cut_gain+play_duck_level); - play_cae->fadeOutputVolume(play_card,play_stream,play_port, + setOutputVolume(play_serial,level+play_cut_gain+play_duck_level); + play_cae->fadeOutputVolume(play_serial, play_fade_gain[1]+play_cut_gain+ play_duck_level, play_audio_point[1]-(int)pos); @@ -494,23 +489,21 @@ void RDPlayDeck::play(unsigned pos,int segue_start,int segue_end, (play_fade_point[0]-play_audio_point[0])); if (level>play_ducked) { play_cae-> - setOutputVolume(play_card,play_stream,play_port, - play_ducked+play_cut_gain+play_duck_level); - play_cae->fadeOutputVolume(play_card,play_stream,play_port, + setOutputVolume(play_serial,play_ducked+play_cut_gain+play_duck_level); + play_cae->fadeOutputVolume(play_serial, play_ducked+play_cut_gain+play_duck_level, fadeup); } else { play_cae-> - setOutputVolume(play_card,play_stream,play_port, - level+play_cut_gain+play_duck_level); - play_cae->fadeOutputVolume(play_card,play_stream,play_port, + setOutputVolume(play_serial,level+play_cut_gain+play_duck_level); + play_cae->fadeOutputVolume(play_serial, play_ducked+play_cut_gain+play_duck_level, fadeup); } } play_cae-> - play(play_handle, + play(play_serial, (int)(100000.0*(double)(play_audio_point[1]-play_audio_point[0]-pos)/ (double)play_timescale_speed), play_timescale_speed,false); @@ -531,7 +524,7 @@ void RDPlayDeck::pause() { pause_called=true; play_state=RDPlayDeck::Paused; - play_cae->stopPlay(play_handle); + play_cae->stopPlay(play_serial); } @@ -546,7 +539,7 @@ void RDPlayDeck::stop() else { stop_called=true; play_state=RDPlayDeck::Stopping; - play_cae->stopPlay(play_handle); + play_cae->stopPlay(play_serial); } } @@ -578,8 +571,9 @@ void RDPlayDeck::stop(int interval,int gain) level=0; } if(level>play_duck_gain[1]){ - play_cae->fadeOutputVolume(play_card,play_stream,play_port, - play_duck_gain[1]+play_cut_gain+play_duck_level,play_duck_down); + play_cae->fadeOutputVolume(play_serial, + play_duck_gain[1]+play_cut_gain+ + play_duck_level,play_duck_down); play_duck_timer->start(play_duck_down); play_duck_down_state=true; play_segue_interval=interval; @@ -587,8 +581,9 @@ void RDPlayDeck::stop(int interval,int gain) } else { if(play_point_gain!=0) { - play_cae->fadeOutputVolume(play_card,play_stream,play_port, - play_point_gain+play_cut_gain+play_duck_level,interval); + play_cae->fadeOutputVolume(play_serial, + play_point_gain+play_cut_gain+ + play_duck_level,interval); } } play_stop_timer->start(interval); @@ -603,8 +598,9 @@ void RDPlayDeck::stop(int interval,int gain) void RDPlayDeck::duckDown(int interval) { if(play_duck_gain[1]<0) { - play_cae->fadeOutputVolume(play_card,play_stream,play_port, - play_duck_gain[1]+play_cut_gain+play_duck_level,play_duck_down); + play_cae->fadeOutputVolume(play_serial, + play_duck_gain[1]+play_cut_gain+play_duck_level, + play_duck_down); play_duck_timer->start(play_duck_down); play_duck_down_state=true; play_segue_interval=interval; @@ -617,15 +613,16 @@ void RDPlayDeck::duckVolume(int level,int fade) { play_duck_level=level; if((state()==RDPlayDeck::Playing || state()==RDPlayDeck::Stopping) && fade>0) { - play_cae->fadeOutputVolume(play_card,play_stream,play_port,play_cut_gain+play_duck_level, - fade); + play_cae->fadeOutputVolume(play_serial, + play_cut_gain+play_duck_level, + fade); } } -void RDPlayDeck::playingData(int handle) +void RDPlayDeck::playingData(unsigned serial) { - if(handle!=play_handle) { + if(serial!=play_serial) { return; } play_position_timer->start(POSITION_INTERVAL); @@ -633,9 +630,9 @@ void RDPlayDeck::playingData(int handle) } -void RDPlayDeck::playStoppedData(int handle) +void RDPlayDeck::playStoppedData(unsigned serial) { - if(handle!=play_handle) { + if(serial!=play_serial) { return; } play_position_timer->stop(); @@ -646,9 +643,9 @@ void RDPlayDeck::playStoppedData(int handle) emit stateChanged(play_id,RDPlayDeck::Paused); } else { - play_cae->unloadPlay(play_handle); + play_cae->unloadPlay(play_serial); - play_handle=-1; + play_serial=0; play_state=RDPlayDeck::Stopped; play_current_position=0; play_duck_down_state=false; @@ -728,7 +725,8 @@ void RDPlayDeck::fadeTimerData() { if(!play_duck_down_state) { play_cae-> - fadeOutputVolume(play_card,play_stream,play_port,play_fade_gain[1]+play_cut_gain+play_duck_level, + fadeOutputVolume(play_serial, + play_fade_gain[1]+play_cut_gain+play_duck_level, play_fade_down); } play_fade_down_state=true; @@ -739,21 +737,23 @@ void RDPlayDeck::duckTimerData() { if (!play_duck_down_state) { //duck up play_cae-> - fadeOutputVolume(play_card,play_stream,play_port,0+play_cut_gain+play_duck_level,play_duck_up); + fadeOutputVolume(play_serial, + 0+play_cut_gain+play_duck_level,play_duck_up); play_ducked=0; } else { //duck down - if(play_point_gain!=0) { - play_cae->fadeOutputVolume(play_card,play_stream,play_port, - play_point_gain+play_cut_gain+play_duck_level, - play_segue_interval-play_duck_down); + if(play_point_gain!=0) { + play_cae->fadeOutputVolume(play_serial, + play_point_gain+play_cut_gain+play_duck_level, + play_segue_interval-play_duck_down); } else { if(play_fade_down_state && play_fade_gain[1]fadeOutputVolume(play_card,play_stream,play_port, - play_fade_gain[1]+play_cut_gain+play_duck_level, - play_segue_interval-play_duck_down); + play_cae->fadeOutputVolume(play_serial, + play_fade_gain[1]+play_cut_gain+ + play_duck_level, + play_segue_interval-play_duck_down); } } play_duck_down_state=false; diff --git a/lib/rdplay_deck.h b/lib/rdplay_deck.h index 054e0794..68faca81 100644 --- a/lib/rdplay_deck.h +++ b/lib/rdplay_deck.h @@ -53,7 +53,7 @@ class RDPlayDeck : public QObject bool playable() const; int card() const; void setCard(int card_num); - int stream() const; + unsigned serial() const; int port() const; void setPort(int port_num); int channel() const; @@ -86,8 +86,8 @@ class RDPlayDeck : public QObject void talkEnd(int id); private slots: - void playingData(int handle); - void playStoppedData(int handle); + void playingData(unsigned serial); + void playStoppedData(unsigned serial); void pointTimerData(int); void positionTimerData(); void fadeTimerData(); @@ -124,10 +124,9 @@ class RDPlayDeck : public QObject int play_ducked; int play_duck_up_point; int play_card; - int play_stream; + unsigned play_serial; int play_port; int play_channel; - int play_handle; unsigned play_forced_length; bool play_hook_mode; QTime play_start_time; diff --git a/lib/rdsimpleplayer.cpp b/lib/rdsimpleplayer.cpp index 9b29c47e..910867f3 100644 --- a/lib/rdsimpleplayer.cpp +++ b/lib/rdsimpleplayer.cpp @@ -2,7 +2,7 @@ // // A naively simple player for Rivendell Carts. // -// (C) Copyright 2002-2021 Fred Gleason +// (C) Copyright 2002-2023 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 @@ -42,8 +42,9 @@ RDSimplePlayer::RDSimplePlayer(RDCae *cae,RDRipc *ripc,int card,int port, // // RDCae Connections // - connect(play_cae,SIGNAL(playing(int)),this,SLOT(playingData(int))); - connect(play_cae,SIGNAL(playStopped(int)),this,SLOT(playStoppedData(int))); + connect(play_cae,SIGNAL(playing(unsigned)),this,SLOT(playingData(unsigned))); + connect(play_cae,SIGNAL(playStopped(unsigned)), + this,SLOT(playStoppedData(unsigned))); // // Event Player @@ -127,7 +128,7 @@ void RDSimplePlayer::play() void RDSimplePlayer::play(int start_pos) { - int handle=0; + unsigned serial=0; int play_cut_gain=0; QString sql; RDSqlQuery *q; @@ -145,13 +146,7 @@ void RDSimplePlayer::play(int start_pos) delete cart; } if(!play_cut.isEmpty()) { - play_cae-> - loadPlay(play_card,play_cut,&play_stream,&handle); - - if(play_stream<0) { - return; - } - + serial=play_cae->loadPlay(play_card,play_port,play_cut); sql=QString("select ")+ "`START_POINT`,"+ // 00 "`END_POINT`,"+ // 01 @@ -161,20 +156,14 @@ void RDSimplePlayer::play(int start_pos) q=new RDSqlQuery(sql); if(q->first()) { play_cut_gain=q->value(2).toInt(); - play_handles.push(handle); - /* - for(int i=0;isetOutputVolume(play_card,play_stream,i,RD_MUTE_DEPTH); - } - */ + play_serials.push(serial); play_cae-> - setOutputVolume(play_card,play_stream,play_port,0+play_cut_gain); + setOutputVolume(serial,0+play_cut_gain); play_cae-> - positionPlay(play_handles.back(),q->value(0).toUInt()+start_pos); - play_cae->play(play_handles.back(), + positionPlay(play_serials.back(),q->value(0).toUInt()+start_pos); + play_cae->play(play_serials.back(), q->value(1).toUInt()-(q->value(0).toUInt()+start_pos), RD_TIMESCALE_DIVISOR,false); - play_cae->setPlayPortActive(play_card,play_port,play_stream); } delete q; } @@ -186,16 +175,16 @@ void RDSimplePlayer::stop() if(!play_is_playing) { return; } - play_cae->stopPlay(play_handles.back()); + play_cae->stopPlay(play_serials.back()); } -void RDSimplePlayer::playingData(int handle) +void RDSimplePlayer::playingData(unsigned serial) { - if(play_handles.empty()) { + if(play_serials.empty()) { return; } - if(handle!=play_handles.back()) { + if(serial!=play_serials.back()) { return; } play_event_player->exec(play_start_cart); @@ -206,19 +195,19 @@ void RDSimplePlayer::playingData(int handle) } -void RDSimplePlayer::playStoppedData(int handle) +void RDSimplePlayer::playStoppedData(unsigned serial) { - if(play_handles.empty()) { + if(play_serials.empty()) { return; } - if(handle!=play_handles.front()) { + if(serial!=play_serials.front()) { return; } - play_cae->unloadPlay(play_handles.front()); + play_cae->unloadPlay(play_serials.front()); play_event_player->exec(play_end_cart); play_start_button->off(); play_stop_button->on(); - play_handles.pop(); + play_serials.pop(); play_is_playing=false; emit stopped(); } diff --git a/lib/rdsimpleplayer.h b/lib/rdsimpleplayer.h index 0f07fe3b..de279036 100644 --- a/lib/rdsimpleplayer.h +++ b/lib/rdsimpleplayer.h @@ -2,7 +2,7 @@ // // A naively simple player for Rivendell Carts. // -// (C) Copyright 2002-2006,2016 Fred Gleason +// (C) Copyright 2002-2023 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 @@ -54,8 +54,8 @@ class RDSimplePlayer : public QWidget void stopped(); private slots: - void playingData(int handle); - void playStoppedData(int handle); + void playingData(unsigned serial); + void playStoppedData(unsigned serial); private: RDCae *play_cae; @@ -63,7 +63,7 @@ class RDSimplePlayer : public QWidget int play_card; int play_stream; int play_port; - std::queue play_handles; + std::queue play_serials; unsigned play_cart; QString play_cut; unsigned play_start_cart; diff --git a/lib/rdsound_panel.cpp b/lib/rdsound_panel.cpp index 60074991..7ae8f3a5 100644 --- a/lib/rdsound_panel.cpp +++ b/lib/rdsound_panel.cpp @@ -1738,8 +1738,9 @@ void RDSoundPanel::Stopped(int id) void RDSoundPanel::ClearChannel(int id) { RDPlayDeck *playdeck=panel_active_buttons[id]->playDeck(); + if(rda->cae()-> - playPortActive(playdeck->card(),playdeck->port(),playdeck->stream())) { + playPortStatus(playdeck->card(),playdeck->port(),playdeck->serial())) { return; } panel_event_player->exec(panel_stop_rml[panel_active_buttons[id]->output()]); diff --git a/rdcatch/rdcatch.cpp b/rdcatch/rdcatch.cpp index 6a5bc6b5..f94370ba 100644 --- a/rdcatch/rdcatch.cpp +++ b/rdcatch/rdcatch.cpp @@ -58,7 +58,7 @@ MainWidget::MainWidget(RDConfig *c,QWidget *parent) QString err_msg; catch_host_warnings=false; - catch_audition_stream=-1; + catch_audition_serial=0; catch_scroll=false; @@ -708,18 +708,14 @@ void MainWidget::headButtonData() EnableScroll(false); if((!head_playing)&&(!tail_playing)) { // Start Head Play RDCut *cut=new RDCut(catch_recordings_model->cutName(rows.first())); - rda->cae()->loadPlay(catch_audition_card,cut->cutName(), - &catch_audition_stream,&catch_play_handle); - if(catch_audition_stream<0) { + catch_audition_serial=rda->cae()-> + loadPlay(catch_audition_card,catch_audition_port,cut->cutName()); + if(catch_audition_serial==0) { return; } - rda->cae()->positionPlay(catch_play_handle,cut->startPoint()); - rda->cae()->setPlayPortActive(catch_audition_card,catch_audition_port, - catch_audition_stream); - rda->cae()->setOutputVolume(catch_audition_card,catch_audition_stream, - catch_audition_port, - 0+cut->playGain()); - rda->cae()->play(catch_play_handle,RDCATCH_AUDITION_LENGTH, + rda->cae()->positionPlay(catch_audition_serial,cut->startPoint()); + rda->cae()->setOutputVolume(catch_audition_serial,0+cut->playGain()); + rda->cae()->play(catch_audition_serial,RDCATCH_AUDITION_LENGTH, RD_TIMESCALE_DIVISOR,false); head_playing=true; delete cut; @@ -737,23 +733,21 @@ void MainWidget::tailButtonData() EnableScroll(false); if((!head_playing)&&(!tail_playing)) { // Start Tail Play RDCut *cut=new RDCut(catch_recordings_model->cutName(rows.first())); - rda->cae()->loadPlay(catch_audition_card,cut->cutName(), - &catch_audition_stream,&catch_play_handle); - if(catch_audition_stream<0) { + catch_audition_serial=rda->cae()-> + loadPlay(catch_audition_card,catch_audition_port,cut->cutName()); + if(catch_audition_serial==0) { return; } if((cut->endPoint()-cut->startPoint()-RDCATCH_AUDITION_LENGTH)>0) { - rda->cae()->positionPlay(catch_play_handle, + rda->cae()->positionPlay(catch_audition_serial, cut->endPoint()-RDCATCH_AUDITION_LENGTH); } else { - rda->cae()->positionPlay(catch_play_handle,cut->startPoint()); + rda->cae()->positionPlay(catch_audition_serial,cut->startPoint()); } - rda->cae()->setPlayPortActive(catch_audition_card,catch_audition_port,catch_audition_stream); - rda->cae()->setOutputVolume(catch_audition_card,catch_audition_stream,catch_audition_port, - 0+cut->playGain()); - rda->cae()->play(catch_play_handle,RDCATCH_AUDITION_LENGTH, - RD_TIMESCALE_DIVISOR,false); + rda->cae()->setOutputVolume(catch_audition_serial,0+cut->playGain()); + rda->cae()->play(catch_audition_serial,RDCATCH_AUDITION_LENGTH, + RD_TIMESCALE_DIVISOR,false); tail_playing=true; delete cut; } @@ -763,8 +757,8 @@ void MainWidget::tailButtonData() void MainWidget::stopButtonData() { if(head_playing||tail_playing) { // Stop Play - rda->cae()->stopPlay(catch_play_handle); - rda->cae()->unloadPlay(catch_play_handle); + rda->cae()->stopPlay(catch_audition_serial); + rda->cae()->unloadPlay(catch_audition_serial); } } @@ -803,7 +797,7 @@ void MainWidget::playStoppedData(int handle) catch_head_button->off(); catch_tail_button->off(); catch_stop_button->on(); - rda->cae()->unloadPlay(catch_play_handle); + rda->cae()->unloadPlay(catch_audition_serial); } diff --git a/rdcatch/rdcatch.h b/rdcatch/rdcatch.h index fc7590e3..3f79c0e1 100644 --- a/rdcatch/rdcatch.h +++ b/rdcatch/rdcatch.h @@ -94,8 +94,7 @@ class MainWidget : public RDMainWindow QScrollArea *catch_monitor_area; VBox *catch_monitor_vbox; QSqlDatabase *catch_db; - int catch_audition_stream; - int catch_play_handle; + unsigned catch_audition_serial; CatchTableView *catch_recordings_view; RecordListModel *catch_recordings_model; RDTransportButton *catch_head_button; diff --git a/rdcatchd/rdcatchd.cpp b/rdcatchd/rdcatchd.cpp index 99a5a9f9..06ddd03a 100644 --- a/rdcatchd/rdcatchd.cpp +++ b/rdcatchd/rdcatchd.cpp @@ -142,7 +142,7 @@ MainObject::MainObject(QObject *parent) catch_playout_status[i]=false; catch_playout_event_id[i]=-1; catch_playout_id[i]=0; - catch_playout_handle[i]=-1; + catch_playout_serial[i]=0; catch_monitor_port[i]=-1; catch_monitor_state[i]=false; catch_record_pending_cartnum[i]=0; @@ -397,7 +397,7 @@ void MainObject::catchEventReceivedData(RDCatchEvent *evt) if((evt->deckChannel()>128)&&(evt->deckChannel()<(MAX_DECKS+129))) { switch(catch_playout_deck_status[evt->deckChannel()-129]) { case RDDeck::Recording: - rda->cae()->stopPlay(catch_playout_handle[evt->deckChannel()-129]); + rda->cae()->stopPlay(catch_playout_serial[evt->deckChannel()-129]); break; default: @@ -707,7 +707,6 @@ void MainObject::engineData(int id) return; } catch_playout_card[catch_events[event].channel()-129]=-1; - catch_playout_stream[catch_events[event].channel()-129]=-1; sql=QString("select ")+ "`CARD_NUMBER`,"+ // 00 "`PORT_NUMBER`,"+ // 01 @@ -720,8 +719,6 @@ void MainObject::engineData(int id) catch_playout_id[catch_events[event].channel()-129]=id; catch_playout_card[catch_events[event].channel()-129]= q->value(0).toInt(); - catch_playout_stream[catch_events[event].channel()-129]= - q->value(1).toInt(); catch_playout_port[catch_events[event].channel()-129]= q->value(2).toInt(); } @@ -951,9 +948,9 @@ void MainObject::playLoadedData(int handle) SendEventResponse(deck,catch_playout_deck_status[deck-129], catch_playout_id[deck-129],""); if(debug) { - printf("Play Loaded - Card: %d Stream: %d\n", - catch_playout_card[deck-129], - catch_playout_stream[deck-129]); + printf("Play Loaded - Serial: %u Card: %d\n", + catch_playout_serial[deck-129], + catch_playout_card[deck-129]); } } @@ -968,9 +965,9 @@ void MainObject::playingData(int handle) catch_playout_id[deck-129],""); catch_playout_status[GetPlayoutDeck(handle)]=true; if(debug) { - printf("Playing - Card: %d Stream: %d\n", - catch_playout_card[deck-129], - catch_playout_stream[deck-129]); + printf("Playing - Serial: %u Card: %d\n", + catch_playout_serial[deck-129], + catch_playout_card[deck-129]); } } @@ -984,9 +981,9 @@ void MainObject::playStoppedData(int handle) rda->syslog(LOG_INFO,"playout stopped: cut %s", (const char *)catch_playout_name[deck-129].toUtf8()); if(debug) { - printf("Playout stopped - Card: %d Stream: %d\n", - catch_playout_card[deck-129], - catch_playout_stream[deck-129]); + printf("Playout stopped - Serial: %u Card: %d\n", + catch_playout_serial[deck-129], + catch_playout_card[deck-129]); } rda->cae()->unloadPlay(handle); } @@ -1004,8 +1001,9 @@ void MainObject::playUnloadedData(int handle) SendEventResponse(deck,catch_playout_deck_status[deck-129], catch_playout_id[deck-129],""); if(debug) { - printf("Play unloaded - Card: %d Stream: %d\n", - catch_playout_card[deck-129],catch_playout_stream[deck-129]); + printf("Play unloaded - Serial: %u Card: %d\n", + catch_playout_serial[deck-129], + catch_playout_card[deck-129]); } if(catch_events[catch_playout_event_id[deck-129]].oneShot()) { PurgeEvent(catch_playout_event_id[deck-129]); @@ -1334,28 +1332,23 @@ void MainObject::StartPlayout(int event) // Start the playout // catch_playout_event_player[deck-129]->load(catch_events[event].cutName()); - rda->cae()->loadPlay(catch_playout_card[deck-129], - catch_events[event].cutName(), - &catch_playout_stream[deck-129], - &catch_playout_handle[deck-129]); - rda->cae()->setOutputVolume(catch_playout_card[deck-129], - catch_playout_stream[deck-129], - catch_playout_port[deck-129], + catch_playout_serial[deck-129]= + rda->cae()-> + loadPlay(catch_playout_card[deck-129],catch_playout_port[deck-129], + catch_events[event].cutName()); + rda->cae()->setOutputVolume(catch_playout_serial[deck-129], catch_events[event].playGain()); - rda->cae()->positionPlay(catch_playout_handle[deck-129],start); + rda->cae()->positionPlay(catch_playout_serial[deck-129],start); catch_playout_event_player[deck-129]->start(start); rda->cae()-> - play(catch_playout_handle[deck-129],end-start,RD_TIMESCALE_DIVISOR,0); - rda->cae()->setPlayPortActive(catch_playout_card[deck-129], - catch_playout_port[deck-129], - catch_playout_stream[deck-129]); + play(catch_playout_serial[deck-129],end-start,RD_TIMESCALE_DIVISOR,0); catch_events[event].setStatus(RDDeck::Recording); rda->syslog(LOG_INFO, - "playout started: deck: %d, event %d card %d, stream %d , cut=%s", + "playout started: deck: %d, event %d serial: %u card %d, stream %d , cut=%s", deck,catch_events[event].id(), + catch_playout_serial[deck-129], catch_playout_card[deck-129], - catch_playout_stream[deck-129], (const char *)catch_events[event].cutName().toUtf8()); // @@ -1782,7 +1775,7 @@ void MainObject::LoadDeckList() catch_playout_deck_status[i]=RDDeck::Recording; } else { - rda->cae()->stopPlay(catch_playout_handle[i]); + rda->cae()->stopPlay(catch_playout_serial[i]); catch_playout_deck_status[i]=RDDeck::Offline; } } @@ -1804,10 +1797,10 @@ int MainObject::GetRecordDeck(int card,int stream) } -int MainObject::GetPlayoutDeck(int handle) +int MainObject::GetPlayoutDeck(unsigned serial) { for(int i=0;i +// (C) Copyright 2002-2023 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 @@ -123,7 +123,7 @@ class MainObject : public QObject void LoadEvent(RDSqlQuery *q,CatchEvent *e,bool add); void LoadDeckList(); int GetRecordDeck(int card,int stream); - int GetPlayoutDeck(int handle); + int GetPlayoutDeck(unsigned serial); int GetFreeEvent(); bool AddEvent(int id); void RemoveEvent(int id); @@ -175,9 +175,8 @@ class MainObject : public QObject unsigned catch_record_pending_maxlen[MAX_DECKS]; bool catch_playout_status[MAX_DECKS]; int catch_playout_card[MAX_DECKS]; - int catch_playout_stream[MAX_DECKS]; int catch_playout_port[MAX_DECKS]; - int catch_playout_handle[MAX_DECKS]; + unsigned catch_playout_serial[MAX_DECKS]; RDDeck::Status catch_playout_deck_status[MAX_DECKS]; int catch_playout_event_id[MAX_DECKS]; int catch_playout_id[MAX_DECKS]; diff --git a/rdlibrary/record_cut.cpp b/rdlibrary/record_cut.cpp index 4e81b0ca..496bdfb3 100644 --- a/rdlibrary/record_cut.cpp +++ b/rdlibrary/record_cut.cpp @@ -56,14 +56,15 @@ RecordCut::RecordCut(RDCart *cart,QString cut,bool use_weight,QWidget *parent) rec_port_no[0]=rda->libraryConf()->inputPort(); rec_card_no[1]=rda->libraryConf()->outputCard(); rec_port_no[1]=rda->libraryConf()->outputPort(); - rec_play_handle=-1; + rec_play_serial=0; // // CAE Connection // connect(rda->cae(),SIGNAL(isConnected(bool)),this,SLOT(initData(bool))); - connect(rda->cae(),SIGNAL(playing(int)),this,SLOT(playedData(int))); - connect(rda->cae(),SIGNAL(playStopped(int)),this,SLOT(playStoppedData(int))); + connect(rda->cae(),SIGNAL(playing(unsigned)),this,SLOT(playedData(unsigned))); + connect(rda->cae(),SIGNAL(playStopped(unsigned)), + this,SLOT(playStoppedData(unsigned))); connect(rda->cae(),SIGNAL(recordLoaded(int,int)), this,SLOT(recordLoadedData(int,int))); connect(rda->cae(),SIGNAL(recordUnloaded(int,int,unsigned)), @@ -582,8 +583,6 @@ void RecordCut::channelsData(int id) void RecordCut::recordData() { - // QString filename; - if((!is_ready)&&(!is_recording)&&(!is_playing)) { if(rec_cut->length()>0) { if(QMessageBox::warning(this,tr("Audio Exists"), @@ -653,14 +652,11 @@ void RecordCut::playData() int end=rec_cut->endPoint(true); if((!is_recording)&&(!is_playing)&&(!is_ready)) { // Start Play - rda->cae()->loadPlay(rec_card_no[1],rec_cut->cutName(), - &rec_stream_no[1],&rec_play_handle); - rda->cae()->positionPlay(rec_play_handle,start); - rda->cae()-> - setPlayPortActive(rec_card_no[1],rec_port_no[1],rec_stream_no[1]); - rda->cae()->setOutputVolume(rec_card_no[1],rec_stream_no[1],rec_port_no[1], - 0+rec_cut->playGain()); - rda->cae()->play(rec_play_handle,end-start,RD_TIMESCALE_DIVISOR,false); + rec_play_serial=rda->cae()-> + loadPlay(rec_card_no[1],rec_port_no[1],rec_cut->cutName()); + rda->cae()->positionPlay(rec_play_serial,start); + rda->cae()->setOutputVolume(rec_play_serial,0+rec_cut->playGain()); + rda->cae()->play(rec_play_serial,end-start,RD_TIMESCALE_DIVISOR,false); } if(is_ready&&(!is_recording)) { if(rec_mode_box->currentIndex()==1) { @@ -679,7 +675,7 @@ void RecordCut::playData() void RecordCut::stopData() { if(is_playing) { - rda->cae()->stopPlay(rec_play_handle); + rda->cae()->stopPlay(rec_play_serial); return; } if(is_recording) { @@ -717,7 +713,7 @@ void RecordCut::recordedData(int card,int stream) } -void RecordCut::playedData(int handle) +void RecordCut::playedData(unsigned serial) { rec_play_button->on(); rec_stop_button->off(); @@ -729,9 +725,9 @@ void RecordCut::playedData(int handle) } -void RecordCut::playStoppedData(int handle) +void RecordCut::playStoppedData(unsigned serial) { - rda->cae()->unloadPlay(rec_play_handle); + rda->cae()->unloadPlay(rec_play_serial); rec_timer->stop(); rec_play_button->off(); rec_stop_button->on(); diff --git a/rdlibrary/record_cut.h b/rdlibrary/record_cut.h index 112169f5..3ee57ac9 100644 --- a/rdlibrary/record_cut.h +++ b/rdlibrary/record_cut.h @@ -2,7 +2,7 @@ // // Record a Rivendell cut. // -// (C) Copyright 2002-2021 Fred Gleason +// (C) Copyright 2002-2023 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 @@ -62,8 +62,8 @@ class RecordCut : public RDDialog void recordedData(int,int); void recordStoppedData(int,int); void recordUnloadedData(int,int,unsigned); - void playedData(int); - void playStoppedData(int); + void playedData(unsigned serial); + void playStoppedData(unsigned serial); void closeData(); void initData(bool); void recTimerData(); @@ -106,12 +106,8 @@ class RecordCut : public RDDialog QLabel *cut_startdatetime_label; QGroupBox *cut_startdatetime_groupbox; RDDateTimeEdit *cut_startdatetime_edit; - // RDDateEdit *cut_startdate_edit; - // RDTimeEdit *cut_starttime_edit; QLabel *cut_enddatetime_label; RDDateTimeEdit *cut_enddatetime_edit; - // RDDateEdit *cut_enddate_edit; - // RDTimeEdit *cut_endtime_edit; QGroupBox *cut_daypart_groupbox; QButtonGroup *cut_daypart_group; QRadioButton *cut_startdaypart_enable_button; @@ -145,7 +141,7 @@ class RecordCut : public RDDialog int rec_card_no[2]; int rec_stream_no[2]; int rec_port_no[2]; - int rec_play_handle; + unsigned rec_play_serial; RDCae::AudioCoding rec_format; unsigned rec_channels; unsigned rec_samprate; @@ -160,5 +156,4 @@ class RecordCut : public RDDialog }; -#endif - +#endif // RECORD_CUT_H