From 5a9f59ec627f1c62da8614f3766df50fa8b77bf0 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Fri, 20 Aug 2021 09:42:35 -0400 Subject: [PATCH] 2021-08-20 Fred Gleason * Cleaned up code in 'cae/'. Signed-off-by: Fred Gleason --- ChangeLog | 2 + cae/Makefile.am | 1 - cae/alsadriver.cpp | 12 +- cae/cae.cpp | 276 ++----- cae/cae.h | 232 +----- cae/cae_jack.cpp | 1695 -------------------------------------- cae/caedriverfactory.cpp | 48 -- cae/caedriverfactory.h | 33 - cae/jackdriver.cpp | 4 + 9 files changed, 83 insertions(+), 2220 deletions(-) delete mode 100644 cae/cae_jack.cpp delete mode 100644 cae/caedriverfactory.cpp delete mode 100644 cae/caedriverfactory.h diff --git a/ChangeLog b/ChangeLog index e0a896f8..783249a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22312,3 +22312,5 @@ * Refactored the ALSA driver in caed(8) to use virtual inheritance. 2021-08-19 Fred Gleason * Refactored the JACK driver in caed(8) to use virtual inheritance. +2021-08-20 Fred Gleason + * Cleaned up code in 'cae/'. diff --git a/cae/Makefile.am b/cae/Makefile.am index 62324cb2..3ba92e4f 100644 --- a/cae/Makefile.am +++ b/cae/Makefile.am @@ -33,7 +33,6 @@ dist_caed_SOURCES = alsadriver.cpp alsadriver.h\ cae.cpp cae.h\ cae_server.cpp cae_server.h\ caedriver.cpp caedriver.h\ - caedriverfactory.cpp caedriverfactory.h\ hpidriver.cpp hpidriver.h\ jackdriver.cpp jackdriver.h diff --git a/cae/alsadriver.cpp b/cae/alsadriver.cpp index 3d7881bb..c52bca6d 100644 --- a/cae/alsadriver.cpp +++ b/cae/alsadriver.cpp @@ -649,7 +649,12 @@ AlsaDriver::~AlsaDriver() QString AlsaDriver::version() const { +#ifdef ALSA + return + QString().sprintf("%d.%d.%d",SND_LIB_MAJOR,SND_LIB_MINOR,SND_LIB_SUBMINOR); +#else return QString(); +#endif // ALSA } @@ -660,7 +665,7 @@ bool AlsaDriver::initialize(unsigned *next_cardnum) snd_pcm_t *pcm_capture_handle; snd_ctl_t *snd_ctl; snd_ctl_card_info_t *card_info=NULL; - bool pcm_opened; + bool pcm_opened=false; int card=0; // @@ -685,6 +690,9 @@ bool AlsaDriver::initialize(unsigned *next_cardnum) snd_pcm_close(pcm_capture_handle); } } + if(!pcm_opened) { + return card>0; + } rda->station()->setCardDriver(*next_cardnum,RDStation::Alsa); if(snd_ctl_open(&snd_ctl,dev.toUtf8(),0)<0) { rda->syslog(LOG_INFO, @@ -1310,7 +1318,6 @@ void AlsaDriver::processBuffers() alsa_stopping[i][j]=false; alsa_eof[i][j]=false; alsa_playing[i][j]=false; - printf("stop card: %d stream: %d\n",i,j); statePlayUpdate(i,j,2); } if(alsa_playing[i][j]) { @@ -1907,7 +1914,6 @@ void AlsaDriver::AlsaClock() alsa_stopping[i][j]=false; alsa_eof[i][j]=false; alsa_playing[i][j]=false; - printf("stop card: %d stream: %d\n",i,j); statePlayUpdate(i,j,2); } if(alsa_playing[i][j]) { diff --git a/cae/cae.cpp b/cae/cae.cpp index 7d34fd55..de207b7a 100644 --- a/cae/cae.cpp +++ b/cae/cae.cpp @@ -45,8 +45,10 @@ #include #include -#include "caedriverfactory.h" +#include "alsadriver.h" #include "cae.h" +#include "hpidriver.h" +#include "jackdriver.h" volatile bool exiting=false; #ifdef JACK @@ -123,7 +125,6 @@ MainObject::MainObject(QObject *parent) next_play_handle=0; for(int i=0;isystem()->sampleRate(); - // hpiInit(cae_station); - // alsaInit(cae_station); - // jackInit(cae_station); - ClearDriverEntries(rda->station()); + ClearDriverEntries(); unsigned next_card=0; - - // - // HPI Devices - // - CaeDriver *dvr=CaeDriverFactory(RDStation::Hpi,this); - if(dvr->initialize(&next_card)) { - connect(dvr,SIGNAL(playStateChanged(int,int,int)), - this,SLOT(statePlayUpdate(int,int,int))); - connect(dvr,SIGNAL(recordStateChanged(int,int,int)), - this,SLOT(stateRecordUpdate(int,int,int))); - d_drivers.push_back(dvr); - } - else { - delete dvr; - } - - // - // ALSA Devices - // - dvr=CaeDriverFactory(RDStation::Alsa,this); - if(dvr->initialize(&next_card)) { - connect(dvr,SIGNAL(playStateChanged(int,int,int)), - this,SLOT(statePlayUpdate(int,int,int))); - connect(dvr,SIGNAL(recordStateChanged(int,int,int)), - this,SLOT(stateRecordUpdate(int,int,int))); - d_drivers.push_back(dvr); - } - else { - delete dvr; - } - - // - // JACK Devices - // - dvr=CaeDriverFactory(RDStation::Jack,this); - if(dvr->initialize(&next_card)) { - connect(dvr,SIGNAL(playStateChanged(int,int,int)), - this,SLOT(statePlayUpdate(int,int,int))); - connect(dvr,SIGNAL(recordStateChanged(int,int,int)), - this,SLOT(stateRecordUpdate(int,int,int))); - d_drivers.push_back(dvr); - } - else { - delete dvr; - } + MakeDriver(&next_card,RDStation::Hpi); + MakeDriver(&next_card,RDStation::Alsa); + MakeDriver(&next_card,RDStation::Jack); // // Probe Capabilities @@ -329,28 +286,6 @@ MainObject::MainObject(QObject *parent) if(jack_client!=NULL) { pthread_getschedparam(jack_client_thread_id(jack_client),&sched_policy, &sched_params); - /* -#ifdef ALSA - for(int i=0;iconfig()->realtimePriority(); } sched_policy=SCHED_FIFO; - /* -#ifdef ALSA - for(int i=0;isched_get_priority_min(sched_policy)) { sched_params.sched_priority--; } @@ -1165,11 +1078,6 @@ void MainObject::updateMeters() unsigned positions[RD_MAX_STREAMS]; if(exiting) { - /* - jackFree(); - alsaFree(); - hpiFree(); - */ for(int i=0;isendCommand(QString().sprintf("IS %d %d 0!",i,j)); - } - else { - cae_server->sendCommand(QString().sprintf("IS %d %d 1!",i,j)); - } - } - if(hpiGetInputMeters(i,j,levels)) { - SendMeterLevelUpdate("I",i,j,levels); - } - if(hpiGetOutputMeters(i,j,levels)) { - SendMeterLevelUpdate("O",i,j,levels); - } - } - hpiGetOutputPosition(i,positions); - SendMeterPositionUpdate(i,positions); - for(int j=0;jsendCommand(QString().sprintf("IS %d %d %d",i,j, - port_status[i][j])); - } - if(jackGetInputMeters(i,j,levels)) { - SendMeterLevelUpdate("I",i,j,levels); - } - if(jackGetOutputMeters(i,j,levels)) { - SendMeterLevelUpdate("O",i,j,levels); - } - } - jackGetOutputPosition(i,positions); - SendMeterPositionUpdate(i,positions); - for(int j=0;jsendCommand(QString().sprintf("IS %d %d %d",i,j, - port_status[i][j])); - } - if(alsaGetInputMeters(i,j,levels)) { - SendMeterLevelUpdate("I",i,j,levels); - } - if(alsaGetOutputMeters(i,j,levels)) { - SendMeterLevelUpdate("O",i,j,levels); - } - } - alsaGetOutputPosition(i,positions); - SendMeterPositionUpdate(i,positions); - for(int j=0;jsetHaveCapability(RDStation::HaveMp4Decode,CheckMp4Decode()); - - /* -#ifdef HPI - station->setDriverVersion(RDStation::Hpi,hpiVersion()); -#else - station->setDriverVersion(RDStation::Hpi,"[not enabled]"); -#endif // HPI -#ifdef JACK - // - // FIXME: How can we detect the current JACK version? - // - station->setDriverVersion(RDStation::Jack,"Generic"); -#else - station->setDriverVersion(RDStation::Jack,""); -#endif // JACK -#ifdef ALSA - station->setDriverVersion(RDStation::Alsa, - QString().sprintf("%d.%d.%d", - SND_LIB_MAJOR, - SND_LIB_MINOR, - SND_LIB_SUBMINOR)); -#else - station->setDriverVersion(RDStation::Alsa,""); -#endif // ALSA - */ } -void MainObject::ClearDriverEntries(RDStation *station) +void MainObject::ClearDriverEntries() const { for(int i=0;isetCardDriver(i,RDStation::None); - station->setCardName(i,""); - station->setCardInputs(i,-1); - station->setCardOutputs(i,-1); - } + rda->station()->setCardDriver(i,RDStation::None); + rda->station()->setCardName(i,""); + rda->station()->setCardInputs(i,-1); + rda->station()->setCardOutputs(i,-1); } } @@ -1784,7 +1586,7 @@ void MainObject::SendMeterOutputStatusUpdate() QList ids=cae_server->connectionIds(); for(unsigned i=0;istation()->setDriverVersion(RDStation::Hpi,"v"+dvr->version()); +#else + rda->station()->setDriverVersion(RDStation::Hpi,"[not enabled]"); +#endif // HPI + break; + + case RDStation::Alsa: +#ifdef ALSA + dvr=new AlsaDriver(this); + rda->station()->setDriverVersion(RDStation::Alsa,"v"+dvr->version()); +#else + rda->station()->setDriverVersion(RDStation::Alsa,"[not enabled]"); +#endif // ALSA + break; + + case RDStation::Jack: +#ifdef JACK + dvr=new JackDriver(this); + rda->station()->setDriverVersion(RDStation::Jack,"v"+dvr->version()); +#else + rda->station()->setDriverVersion(RDStation::Jack,"[not enabled]"); +#endif // JACK + break; + + case RDStation::None: + break; + } + if(dvr!=NULL) { + if(dvr->initialize(next_card)) { + connect(dvr,SIGNAL(playStateChanged(int,int,int)), + this,SLOT(statePlayUpdate(int,int,int))); + connect(dvr,SIGNAL(recordStateChanged(int,int,int)), + this,SLOT(stateRecordUpdate(int,int,int))); + d_drivers.push_back(dvr); + } + else { + delete dvr; + } + } +} + + int main(int argc,char *argv[]) { int rc; diff --git a/cae/cae.h b/cae/cae.h index 04d2fac7..60451e71 100644 --- a/cae/cae.h +++ b/cae/cae.h @@ -34,31 +34,6 @@ #include -#ifdef HPI -#include -#include -#include -#endif // HPI - -#ifdef ALSA -#include -struct alsa_format { - int card; - pthread_t thread; - snd_pcm_t *pcm; - unsigned channels; - unsigned capture_channels; - snd_pcm_uframes_t buffer_size; - snd_pcm_format_t format; - unsigned sample_rate; - char *card_buffer; - char *passthrough_buffer; - unsigned card_buffer_size; - unsigned periods; - bool exiting; -}; -#endif // ALSA - #ifdef JACK #include #endif // JACK @@ -90,14 +65,12 @@ void src_float_to_int_array (const float *in, int *out, int len); // // Global CAE Definitions // -//#define RINGBUFFER_SIZE 262144 #define CAED_USAGE "[-d]\n\nSupplying the '-d' flag will set 'debug' mode, causing caed(8) to stay\nin the foreground and print debugging info on standard output.\n" // // Function Prototypes // void SigHandler(int signum); -//extern RDConfig *rd_config; class MainObject : public QObject { @@ -155,7 +128,7 @@ class MainObject : public QObject int GetNextHandle(); int GetHandle(int card,int stream); void ProbeCaps(RDStation *station); - void ClearDriverEntries(RDStation *station); + void ClearDriverEntries() const; void SendMeterLevelUpdate(const QString &type,int cardnum,int portnum, short levels[]); void SendStreamMeterLevelUpdate(int cardnum,int streamnum,short levels[]); @@ -163,12 +136,14 @@ class MainObject : public QObject void SendMeterOutputStatusUpdate(); void SendMeterOutputStatusUpdate(int card,int port,int stream); void SendMeterUpdate(const QString &msg,int conn_id); + CaeDriver *GetDriver(unsigned card) const; + void MakeDriver(unsigned *next_card,RDStation::AudioDriver type); + QList d_drivers; bool debug; unsigned system_sample_rate; CaeServer *cae_server; int16_t tcp_port; QUdpSocket *meter_socket; - RDStation::AudioDriver cae_driver[RD_MAX_CARDS]; 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]; @@ -184,207 +159,8 @@ class MainObject : public QObject int owner; } play_handle[256]; int next_play_handle; - // RDStation *cae_station; - - // - // New Stuff - // - CaeDriver *GetDriver(unsigned card) const; - QList d_drivers; - - // - // HPI Driver - // - private: - /* - void hpiInit(RDStation *station); - void hpiFree(); - QString hpiVersion(); - bool hpiLoadPlayback(int card,QString wavename,int *stream); - bool hpiUnloadPlayback(int card,int stream); - bool hpiPlaybackPosition(int card,int stream,unsigned pos); - bool hpiPlay(int card,int stream,int length,int speed,bool pitch, - bool rates); - bool hpiStopPlayback(int card,int stream); - bool hpiTimescaleSupported(int card); - bool hpiLoadRecord(int card,int port,int coding,int chans,int samprate, - int bitrate,QString wavename); - bool hpiUnloadRecord(int card,int stream,unsigned *len); - bool hpiRecord(int card,int stream,int length,int thres); - bool hpiStopRecord(int card,int stream); - bool hpiSetClockSource(int card,int src); - bool hpiSetInputVolume(int card,int stream,int level); - bool hpiSetOutputVolume(int card,int stream,int port,int level); - bool hpiFadeOutputVolume(int card,int stream,int port,int level,int length); - bool hpiSetInputLevel(int card,int port,int level); - bool hpiSetOutputLevel(int card,int port,int level); - bool hpiSetInputMode(int card,int stream,int mode); - bool hpiSetOutputMode(int card,int stream,int mode); - bool hpiSetInputVoxLevel(int card,int stream,int level); - bool hpiSetInputType(int card,int port,int type); - bool hpiGetInputStatus(int card,int port); - bool hpiGetInputMeters(int card,int port,short levels[2]); - bool hpiGetOutputMeters(int card,int port,short levels[2]); - bool hpiGetStreamOutputMeters(int card,int stream,short levels[2]); - bool hpiSetPassthroughLevel(int card,int in_port,int out_port,int level); - void hpiGetOutputPosition(int card,unsigned *pos); -#ifdef HPI - RDHPISoundCard *sound_card; - RDHPIRecordStream *record[RD_MAX_CARDS][RD_MAX_STREAMS]; - RDHPIPlayStream *play[RD_MAX_CARDS][RD_MAX_STREAMS]; -#endif // HPI - */ - - /* - // - // JACK Driver - // - private slots: - void jackStopTimerData(int stream); - void jackFadeTimerData(int stream); - void jackRecordTimerData(int stream); - void jackClientStartData(); private: - void jackInit(RDStation *station); - void jackFree(); - bool jackLoadPlayback(int card,QString wavename,int *stream); - bool jackUnloadPlayback(int card,int stream); - bool jackPlaybackPosition(int card,int stream,unsigned pos); - bool jackPlay(int card,int stream,int length,int speed,bool pitch, - bool rates); - bool jackStopPlayback(int card,int stream); - bool jackTimescaleSupported(int card); - bool jackLoadRecord(int card,int port,int coding,int chans,int samprate, - int bitrate,QString wavename); - bool jackUnloadRecord(int card,int stream,unsigned *len); - bool jackRecord(int card,int stream,int length,int thres); - bool jackStopRecord(int card,int stream); - bool jackSetInputVolume(int card,int stream,int level); - bool jackSetOutputVolume(int card,int stream,int port,int level); - bool jackFadeOutputVolume(int card,int stream,int port,int level,int length); - bool jackSetInputLevel(int card,int port,int level); - bool jackSetOutputLevel(int card,int port,int level); - bool jackSetInputMode(int card,int stream,int mode); - bool jackSetOutputMode(int card,int stream,int mode); - bool jackSetInputVoxLevel(int card,int stream,int level); - bool jackSetInputType(int card,int port,int type); - bool jackGetInputStatus(int card,int port); - bool jackGetInputMeters(int card,int port,short levels[2]); - bool jackGetOutputMeters(int card,int port,short levels[2]); - bool jackGetStreamOutputMeters(int card,int stream,short levels[2]); - bool jackSetPassthroughLevel(int card,int in_port,int out_port,int level); - void jackGetOutputPosition(int card,unsigned *pos); - void jackConnectPorts(const QString &out,const QString &in); - void jackDisconnectPorts(const QString &out,const QString &in); - int GetJackOutputStream(); - void FreeJackOutputStream(int stream); - void EmptyJackInputStream(int stream,bool done); -#ifdef JACK - void WriteJackBuffer(int stream,jack_default_audio_sample_t *buffer, - unsigned len,bool done); -#endif // JACK - void FillJackOutputStream(int stream); - void JackClock(); - void JackSessionSetup(); - bool jack_connected; - bool jack_activated; -#ifdef JACK - int jack_card; - QList jack_clients; - RDWaveFile *jack_record_wave[RD_MAX_STREAMS]; - RDWaveFile *jack_play_wave[RD_MAX_STREAMS]; - short *jack_wave_buffer; - int *jack_wave32_buffer; - uint8_t *jack_wave24_buffer; - jack_default_audio_sample_t *jack_sample_buffer; - soundtouch::SoundTouch *jack_st_conv[RD_MAX_STREAMS]; - short jack_input_volume_db[RD_MAX_STREAMS]; - short jack_output_volume_db[RD_MAX_PORTS][RD_MAX_STREAMS]; - short jack_passthrough_volume_db[RD_MAX_PORTS][RD_MAX_PORTS]; - short jack_fade_volume_db[RD_MAX_STREAMS]; - short jack_fade_increment[RD_MAX_STREAMS]; - int jack_fade_port[RD_MAX_STREAMS]; - bool jack_fade_up[RD_MAX_STREAMS]; - QTimer *jack_fade_timer[RD_MAX_STREAMS]; - QTimer *jack_stop_timer[RD_MAX_STREAMS]; - QTimer *jack_record_timer[RD_MAX_PORTS]; - QTimer *jack_client_start_timer; - int jack_offset[RD_MAX_STREAMS]; - int jack_clock_phase; - unsigned jack_samples_recorded[RD_MAX_STREAMS]; -#endif // JACK - */ - // - // ALSA Driver - // - /* - private slots: - void alsaStopTimerData(int cardstream); - void alsaFadeTimerData(int cardstream); - void alsaRecordTimerData(int cardport); - - private: - void alsaInit(RDStation *station); - void alsaFree(); - bool alsaLoadPlayback(int card,QString wavename,int *stream); - bool alsaUnloadPlayback(int card,int stream); - bool alsaPlaybackPosition(int card,int stream,unsigned pos); - bool alsaPlay(int card,int stream,int length,int speed,bool pitch, - bool rates); - bool alsaStopPlayback(int card,int stream); - bool alsaTimescaleSupported(int card); - bool alsaLoadRecord(int card,int port,int coding,int chans,int samprate, - int bitrate,QString wavename); - bool alsaUnloadRecord(int card,int stream,unsigned *len); - bool alsaRecord(int card,int stream,int length,int thres); - bool alsaStopRecord(int card,int stream); - bool alsaSetInputVolume(int card,int stream,int level); - bool alsaSetOutputVolume(int card,int stream,int port,int level); - bool alsaFadeOutputVolume(int card,int stream,int port,int level,int length); - bool alsaSetInputLevel(int card,int port,int level); - bool alsaSetOutputLevel(int card,int port,int level); - bool alsaSetInputMode(int card,int stream,int mode); - bool alsaSetOutputMode(int card,int stream,int mode); - bool alsaSetInputVoxLevel(int card,int stream,int level); - bool alsaSetInputType(int card,int port,int type); - bool alsaGetInputStatus(int card,int port); - bool alsaGetInputMeters(int card,int port,short levels[2]); - bool alsaGetOutputMeters(int card,int port,short levels[2]); - bool alsaGetStreamOutputMeters(int card,int stream,short levels[2]); - bool alsaSetPassthroughLevel(int card,int in_port,int out_port,int level); - void alsaGetOutputPosition(int card,unsigned *pos); - void AlsaClock(); -#ifdef ALSA - bool AlsaStartCaptureDevice(QString &dev,int card,snd_pcm_t *pcm); - bool AlsaStartPlayDevice(QString &dev,int card,snd_pcm_t *pcm); - void AlsaInitCallback(); - int GetAlsaOutputStream(int card); - void FreeAlsaOutputStream(int card,int stream); - void EmptyAlsaInputStream(int card,int stream); - void WriteAlsaBuffer(int card,int stream,short *buffer,unsigned len); - void FillAlsaOutputStream(int card,int stream); - struct alsa_format alsa_play_format[RD_MAX_CARDS]; - struct alsa_format alsa_capture_format[RD_MAX_CARDS]; - short alsa_input_volume_db[RD_MAX_CARDS][RD_MAX_STREAMS]; - short alsa_output_volume_db[RD_MAX_CARDS][RD_MAX_PORTS][RD_MAX_STREAMS]; - short alsa_passthrough_volume_db[RD_MAX_CARDS][RD_MAX_PORTS][RD_MAX_PORTS]; - short *alsa_wave_buffer; - uint8_t *alsa_wave24_buffer; - RDWaveFile *alsa_record_wave[RD_MAX_CARDS][RD_MAX_STREAMS]; - RDWaveFile *alsa_play_wave[RD_MAX_CARDS][RD_MAX_STREAMS]; - int alsa_offset[RD_MAX_CARDS][RD_MAX_STREAMS]; - QTimer *alsa_fade_timer[RD_MAX_CARDS][RD_MAX_STREAMS]; - QTimer *alsa_stop_timer[RD_MAX_CARDS][RD_MAX_STREAMS]; - QTimer *alsa_record_timer[RD_MAX_CARDS][RD_MAX_PORTS]; - bool alsa_fade_up[RD_MAX_CARDS][RD_MAX_STREAMS]; - short alsa_fade_volume_db[RD_MAX_CARDS][RD_MAX_STREAMS]; - short alsa_fade_increment[RD_MAX_CARDS][RD_MAX_STREAMS]; - int alsa_fade_port[RD_MAX_CARDS][RD_MAX_STREAMS]; - unsigned alsa_samples_recorded[RD_MAX_CARDS][RD_MAX_STREAMS]; -#endif // ALSA - */ - bool CheckLame(); bool CheckMp4Decode(); diff --git a/cae/cae_jack.cpp b/cae/cae_jack.cpp deleted file mode 100644 index 96d37d5f..00000000 --- a/cae/cae_jack.cpp +++ /dev/null @@ -1,1695 +0,0 @@ -// cae_jack.cpp -// -// The JACK Driver for the Core Audio Engine component of Rivendell -// -// (C) Copyright 2002-2021 Fred Gleason -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as -// published by the Free Software Foundation. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef JACK -// -// Callback Variables -// -jack_client_t *jack_client; -RDMeterAverage *jack_input_meter[RD_MAX_PORTS][2]; -RDMeterAverage *jack_output_meter[RD_MAX_PORTS][2]; -RDMeterAverage *jack_stream_output_meter[RD_MAX_STREAMS][2]; -volatile jack_default_audio_sample_t - jack_input_volume[RD_MAX_PORTS]; -volatile jack_default_audio_sample_t - jack_output_volume[RD_MAX_PORTS][RD_MAX_STREAMS]; -volatile jack_default_audio_sample_t - jack_passthrough_volume[RD_MAX_PORTS][RD_MAX_PORTS]; -volatile jack_default_audio_sample_t jack_input_vox[RD_MAX_PORTS]; -jack_port_t *jack_input_port[RD_MAX_PORTS][2]; -jack_port_t *jack_output_port[RD_MAX_PORTS][2]; -volatile int jack_input_channels[RD_MAX_PORTS]; -volatile int jack_output_channels[RD_MAX_STREAMS]; -volatile jack_default_audio_sample_t *jack_input_buffer[RD_MAX_PORTS][2]; -volatile jack_default_audio_sample_t *jack_output_buffer[RD_MAX_PORTS][2]; -RDRingBuffer *jack_play_ring[RD_MAX_STREAMS]; -RDRingBuffer *jack_record_ring[RD_MAX_PORTS]; -volatile bool jack_playing[RD_MAX_STREAMS]; -volatile bool jack_stopping[RD_MAX_STREAMS]; -volatile bool jack_eof[RD_MAX_STREAMS]; -volatile bool jack_recording[RD_MAX_PORTS]; -volatile bool jack_ready[RD_MAX_PORTS]; -volatile int jack_output_pos[RD_MAX_STREAMS]; -volatile unsigned jack_output_sample_rate[RD_MAX_STREAMS]; -volatile unsigned jack_sample_rate; -int jack_input_mode[RD_MAX_CARDS][RD_MAX_PORTS]; -int jack_card_process; // local copy of object member jack_card, for use by the callback process. - - -// -// Callback Buffers -// -jack_default_audio_sample_t jack_callback_buffer[RINGBUFFER_SIZE]; - -int JackProcess(jack_nframes_t nframes, void *arg) -{ - unsigned n=0; - jack_default_audio_sample_t in_meter[2]; - jack_default_audio_sample_t out_meter[2]; - jack_default_audio_sample_t stream_out_meter; - - // - // Ensure Buffers are Valid - // - for(int i=0;i0.0) { - for(int k=0;k<2;k++) { - if((jack_output_port[j][k]!=NULL)&&(jack_input_port[i][k]!=NULL)) { - for(unsigned l=0;l - write((char *)jack_callback_buffer, - nframes*sizeof(jack_default_audio_sample_t))/ - sizeof(jack_default_audio_sample_t); - break; - - case 2: // stereo - for(unsigned j=0;j - write((char *)jack_callback_buffer, - 2*nframes*sizeof(jack_default_audio_sample_t))/ - (2*sizeof(jack_default_audio_sample_t)); - break; - } - } - } - } - - // - // Process Output Streams - // - for(int i=0;i - read((char *)jack_callback_buffer, - nframes*sizeof(jack_default_audio_sample_t))/ - sizeof(jack_default_audio_sample_t); - stream_out_meter=0.0; - for(unsigned j=0;jstream_out_meter) { - stream_out_meter=fabsf(jack_callback_buffer[j]); - } - } - jack_stream_output_meter[i][0]->addValue(stream_out_meter); - jack_stream_output_meter[i][1]->addValue(stream_out_meter); - break; - - case 2: - n=jack_play_ring[i]-> - read((char *)jack_callback_buffer, - 2*nframes*sizeof(jack_default_audio_sample_t))/ - (2*sizeof(jack_default_audio_sample_t)); - for(unsigned j=0;j<2;j++) { // Stream Output Meters - stream_out_meter=0.0; - for(unsigned k=0;kstream_out_meter) { - stream_out_meter=fabsf(jack_callback_buffer[k+j]); - } - } - jack_stream_output_meter[i][j]->addValue(stream_out_meter); - } - break; - } - for(int j=0;j0.0) { - switch(jack_output_channels[i]) { - case 1: - for(unsigned k=0;kin_meter[1]) - in_meter[1]=jack_input_buffer[i][1][k]; - break; - case 2: // L only - if(jack_input_buffer[i][0][k]>in_meter[0]) - in_meter[0]=jack_input_buffer[i][0][k]; - break; - case 1: // swap - if(jack_input_buffer[i][0][k]>in_meter[1]) - in_meter[1]=jack_input_buffer[i][0][k]; - if(jack_input_buffer[i][1][k]>in_meter[0]) - in_meter[0]=jack_input_buffer[i][1][k]; - break; - case 0: // normal - default: - if(jack_input_buffer[i][0][k]>in_meter[0]) - in_meter[0]=jack_input_buffer[i][0][k]; - if(jack_input_buffer[i][1][k]>in_meter[1]) - in_meter[1]=jack_input_buffer[i][1][k]; - break; - } - } // for nframes - jack_input_meter[i][0]->addValue(in_meter[0]); - jack_input_meter[i][1]->addValue(in_meter[1]); - } - if(jack_output_port[i][0]!=NULL) { - // output meters - for(int j=0;j<2;j++) { - out_meter[j]=0.0; - for(unsigned k=0;kout_meter[j]) - out_meter[j]=jack_output_buffer[i][j][k]; - } - jack_output_meter[i][j]->addValue(out_meter[j]); - } - } - } // for RD_MAX_PORTS - return 0; -} - - -int JackSampleRate(jack_nframes_t nframes, void *arg) -{ - jack_sample_rate=nframes; - - return 0; -} - - -void JackError(const char *desc) -{ - fprintf(stderr,"caed: Jack error: %s\n",desc); -} - - -void JackShutdown(void *arg) -{ -} - - -void JackInitCallback() -{ - int avg_periods=(int)(330.0*jack_get_sample_rate(jack_client)/ - (1000.0*jack_get_buffer_size(jack_client))); - for(int i=0;istop(); - } - } - else { - level=jack_output_volume_db[jack_fade_port[stream]][stream]+ - jack_fade_increment[stream]; - if(level>=jack_fade_volume_db[stream]) { - level=jack_fade_volume_db[stream]; - jack_fade_timer[stream]->stop(); - } - } - jackSetOutputVolume(jack_card,stream,jack_fade_port[stream],level); -#endif // JACK -} - - -void MainObject::jackRecordTimerData(int stream) -{ -#ifdef JACK - jackStopRecord(jack_card,stream); - stateRecordUpdate(jack_card,stream,2); -#endif // JACK -} - - -void MainObject::jackClientStartData() -{ -#ifdef JACK - QString sql=QString("select ")+ - "`DESCRIPTION`,"+ // 00 - "`COMMAND_LINE` "+ // 01 - "from `JACK_CLIENTS` where "+ - "`STATION_NAME`='"+RDEscapeString(rda->config()->stationName())+"'"; - RDSqlQuery *q=new RDSqlQuery(sql); - while(q->next()) { - QString cmd=RDDateDecode(q->value(1).toString(),QDate::currentDate(), - rda->station(),rda->config(), - rda->config()->provisioningServiceName(rda->config()->stationName())); - QStringList args=cmd.split(" ",QString::SkipEmptyParts); - QString program=args.at(0); - args.removeFirst(); - jack_clients.push_back(new QProcess(this)); - jack_clients.back()->start(program,args); - if(jack_clients.back()->waitForStarted()) { - rda->syslog(LOG_INFO,"started JACK Client \"%s\"", - (const char *)q->value(0).toString().toUtf8()); - } - else { - rda->syslog(LOG_WARNING, - "failed to start JACK Client \"%s\" [%s]", - (const char *)q->value(0).toString().toUtf8(), - (const char *)q->value(1).toString().toUtf8()); - } - sleep(1); - } - delete q; -#endif // JACK -} - - -void MainObject::jackInit(RDStation *station) -{ -#ifdef JACK - jack_options_t jackopts=JackNullOption; - jack_status_t jackstat=JackFailure; - - jack_connected=false; - jack_activated=false; - - // - // Get Next Available Card Number - // - for(jack_card=0;jack_cardsyslog(LOG_INFO,"no more RD cards available"); - return; - } - QString name=QString().sprintf("rivendell_%d",jack_card); - - // - // Start Jack Server - // - if(station->startJack()) { - QStringList args= - station->jackCommandLine().split(" ",QString::SkipEmptyParts); - if(args.size()) { - QString program=args.at(0); - args.removeFirst(); - QProcess *proc=new QProcess(this); - proc->start(program,args); - if(proc->waitForStarted()) { - rda->syslog(LOG_INFO,"JACK server started"); - } - else { - rda->syslog(LOG_WARNING, - "failed to start JACK server"); - } - sleep(1); - } - else { - rda->syslog(LOG_WARNING, - "could not start JACK server: no command line specified"); - } - } - - // - // Attempt to Connect to Jack Server - // - jackopts=JackNoStartServer; - if(station->jackServerName().isEmpty()) { - jack_client=jack_client_open(name.toUtf8(),jackopts,&jackstat); - } - else { - jack_client= - jack_client_open(name.toUtf8(),jackopts,&jackstat, - station->jackServerName().toUtf8().constData()); - } - if(jack_client==NULL) { - if((jackstat&JackInvalidOption)!=0) { - fprintf (stderr, "invalid or unsupported JACK option\n"); - rda->syslog(LOG_WARNING, - "invalid or unsupported JACK option"); - } - - if((jackstat&JackServerError)!=0) { - fprintf (stderr, "communication error with the JACK server\n"); - rda->syslog(LOG_WARNING, - "communication error with the JACK server"); - } - - if((jackstat&JackNoSuchClient)!=0) { - fprintf (stderr, "requested JACK client does not exist\n"); - rda->syslog(LOG_WARNING, - "requested JACK client does not exist"); - } - - if((jackstat&JackLoadFailure)!=0) { - fprintf (stderr, "unable to load internal JACK client\n"); - rda->syslog(LOG_WARNING, - "unable to load internal JACK client"); - } - - if((jackstat&JackInitFailure)!=0) { - fprintf (stderr, "unable to initialize JACK client\n"); - rda->syslog(LOG_WARNING, - "unable to initialize JACK client"); - } - - if((jackstat&JackShmFailure)!=0) { - fprintf (stderr, "unable to access JACK shared memory\n"); - rda->syslog(LOG_WARNING, - "unable to access JACK shared memory"); - } - - if((jackstat&JackVersionError)!=0) { - fprintf (stderr, "JACK protocol version mismatch\n"); - rda->syslog(LOG_WARNING, - "JACK protocol version mismatch"); - } - - if((jackstat&JackServerStarted)!=0) { - fprintf (stderr, "JACK server started\n"); - rda->syslog(LOG_WARNING,"JACK server started"); - } - - if((jackstat&JackServerFailed)!=0) { - fprintf (stderr, "unable to communication with JACK server\n"); - rda->syslog(LOG_WARNING, - "unable to communicate with JACK server"); - } - - if((jackstat&JackNameNotUnique)!=0) { - fprintf (stderr, "JACK client name not unique\n"); - rda->syslog(LOG_WARNING, - "JACK client name not unique"); - } - - if((jackstat&JackFailure)!=0) { - fprintf (stderr, "JACK general failure\n"); - rda->syslog(LOG_WARNING,"JACK general failure"); - } - jack_card=-1; - fprintf (stderr, "no connection to JACK server\n"); - rda->syslog(LOG_WARNING,"no connection to JACK server"); - return; - } - jack_connected=true; - jack_set_process_callback(jack_client,JackProcess,0); - jack_set_sample_rate_callback(jack_client,JackSampleRate,0); - //jack_set_port_connect_callback(jack_client,JackPortConnectCB,this); -#ifdef HAVE_JACK_INFO_SHUTDOWN - jack_on_info_shutdown(jack_client,JackInfoShutdown,0); -#else - jack_on_shutdown(jack_client,JackShutdown,0); -#endif // HAVE_JACK_INFO_SHUTDOWN - rda->syslog(LOG_INFO,"connected to JACK server"); - - // - // Start JACK Clients - // - jack_client_start_timer=new QTimer(this); - jack_client_start_timer->setSingleShot(true); - connect(jack_client_start_timer,SIGNAL(timeout()), - this,SLOT(jackClientStartData())); - jack_client_start_timer->start(6000); - - // - // Tell the database about us - // - if(jack_connected) { - station->setCardDriver(jack_card,RDStation::Jack); - station->setCardName(jack_card,"JACK Audio Connection Kit"); - station->setCardInputs(jack_card,RD_MAX_PORTS); - station->setCardOutputs(jack_card,RD_MAX_PORTS); - } - - // - // Initialize Data Structures - // - for(int i=0;isetSingleShot(true); - stop_mapper->setMapping(jack_stop_timer[i],i); - connect(jack_stop_timer[i],SIGNAL(timeout()),stop_mapper,SLOT(map())); - jack_fade_timer[i]=new QTimer(this); - fade_mapper->setMapping(jack_fade_timer[i],i); - connect(jack_fade_timer[i],SIGNAL(timeout()),fade_mapper,SLOT(map())); - } - for(int i=0;isetMapping(jack_record_timer[i],i); - connect(jack_record_timer[i],SIGNAL(timeout()),record_mapper,SLOT(map())); - } - - // - // Register Ports - // - for(int i=0;ijackPorts();i++) { - name=QString().sprintf("playout_%dL",i); - jack_output_port[i][0]= - jack_port_register(jack_client,name.toUtf8(), - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsOutput|JackPortIsTerminal,0); - name=QString().sprintf("playout_%dR",i); - jack_output_port[i][1]= - jack_port_register(jack_client,name.toUtf8(), - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsOutput|JackPortIsTerminal,0); - name=QString().sprintf("record_%dL",i); - jack_input_port[i][0]= - jack_port_register(jack_client,name.toUtf8(), - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsInput|JackPortIsTerminal,0); - name=QString().sprintf("record_%dR",i); - jack_input_port[i][1]= - jack_port_register(jack_client,name.toUtf8(), - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsInput|JackPortIsTerminal,0); - } - - // - // Allocate Temporary Buffers - // - JackInitCallback(); - jack_wave_buffer=new short[RINGBUFFER_SIZE]; - jack_wave32_buffer=new int[RINGBUFFER_SIZE]; - jack_wave24_buffer=new uint8_t[RINGBUFFER_SIZE]; - jack_sample_buffer=new jack_default_audio_sample_t[RINGBUFFER_SIZE]; - - // - // Join the Graph - // - if(jack_activate(jack_client)) { - return; - } - jack_sample_rate=jack_get_sample_rate(jack_client); - if(jack_sample_rate!=system_sample_rate) { - fprintf (stderr,"JACK sample rate mismatch!\n"); - rda->syslog(LOG_WARNING,"JACK sample rate mismatch!"); - } - jack_activated=true; - cae_driver[jack_card]=RDStation::Jack; - JackSessionSetup(); - -#endif // JACK -} - - -void MainObject::jackFree() -{ -#ifdef JACK - for(int i=0;ikill(); - delete jack_clients[i]; - } - jack_clients.clear(); - if(jack_activated) { - jack_deactivate(jack_client); - } -#endif // JACK -} - - -bool MainObject::jackLoadPlayback(int card,QString wavename,int *stream) -{ -#ifdef JACK - if((*stream=GetJackOutputStream())<0) { - rda->syslog(LOG_DEBUG, - "jackLoadPlayback(%s) GetJackOutputStream():%d <0", - (const char *)wavename.toUtf8(),*stream); - return false; - } - jack_play_wave[*stream]=new RDWaveFile(wavename); - if(!jack_play_wave[*stream]->openWave()) { - rda->syslog(LOG_DEBUG, - "jackLoadPlayback(%s) openWave() failed to open file", - (const char *)wavename.toUtf8()); - delete jack_play_wave[*stream]; - jack_play_wave[*stream]=NULL; - FreeJackOutputStream(*stream); - *stream=-1; - return false; - } - switch(jack_play_wave[*stream]->getFormatTag()) { - case WAVE_FORMAT_PCM: - case WAVE_FORMAT_VORBIS: - break; - - case WAVE_FORMAT_MPEG: - InitMadDecoder(card,*stream,jack_play_wave[*stream]); - break; - - default: - rda->syslog(LOG_DEBUG, - "jackLoadPlayback(%s) getFormatTag()%d || getBistsPerSample()%d failed", - (const char *) wavename.toUtf8(), - jack_play_wave[*stream]->getFormatTag(), - jack_play_wave[*stream]->getBitsPerSample()); - delete jack_play_wave[*stream]; - jack_play_wave[*stream]=NULL; - FreeJackOutputStream(*stream); - *stream=-1; - return false; - } - jack_output_channels[*stream]=jack_play_wave[*stream]->getChannels(); - jack_output_sample_rate[*stream]=jack_play_wave[*stream]->getSamplesPerSec(); - jack_stopping[*stream]=false; - jack_offset[*stream]=0; - jack_output_pos[*stream]=0; - jack_eof[*stream]=false; - FillJackOutputStream(*stream); - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackUnloadPlayback(int card,int stream) -{ -#ifdef JACK - if ((stream <0) || (stream >= RD_MAX_STREAMS)){ - return false; - } - if(jack_play_ring[stream]==NULL) { - return false; - } - jack_playing[stream]=false; - switch(jack_play_wave[stream]->getFormatTag()) { - case WAVE_FORMAT_MPEG: - FreeMadDecoder(card,stream); - break; - } - jack_play_wave[stream]->closeWave(); - delete jack_play_wave[stream]; - jack_play_wave[stream]=NULL; - FreeJackOutputStream(stream); - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackPlaybackPosition(int card,int stream,unsigned pos) -{ -#ifdef JACK - unsigned offset=0; - - if ((stream <0) || (stream >= RD_MAX_STREAMS)){ - return false; - } - jack_eof[stream]=false; - jack_play_ring[stream]->reset(); - - - switch(jack_play_wave[stream]->getFormatTag()) { - case WAVE_FORMAT_PCM: - case WAVE_FORMAT_VORBIS: - offset=(unsigned)((double)jack_play_wave[stream]->getSamplesPerSec()* - (double)jack_play_wave[stream]->getBlockAlign()* - (double)pos/1000); - jack_offset[stream]=offset/jack_play_wave[stream]->getBlockAlign(); - offset=jack_offset[stream]*jack_play_wave[stream]->getBlockAlign(); - break; - - case WAVE_FORMAT_MPEG: - offset=(unsigned)((double)jack_play_wave[stream]->getSamplesPerSec()* - (double)pos/1000); - jack_offset[stream]=offset/1152*1152; - offset=jack_offset[stream]/1152*jack_play_wave[stream]->getBlockAlign(); - FreeMadDecoder(jack_card,stream); - InitMadDecoder(jack_card,stream,jack_play_wave[stream]); - break; - } - if(jack_offset[stream]>(int)jack_play_wave[stream]->getSampleLength()) { - return false; - } - jack_output_pos[stream]=0; - jack_play_wave[stream]->seekWave(offset,SEEK_SET); - FillJackOutputStream(stream); - - if(jack_playing[stream]) { - jack_stop_timer[stream]->stop(); - jack_stop_timer[stream]-> - start(jack_play_wave[stream]->getExtTimeLength()-pos); - } - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackPlay(int card,int stream,int length,int speed,bool pitch, - bool rates) -{ -#ifdef JACK - if((stream <0) || (stream >= RD_MAX_STREAMS) || - (jack_play_ring[stream]==NULL)||jack_playing[stream]) { - return false; - } - if(speed!=RD_TIMESCALE_DIVISOR) { - jack_st_conv[stream]=new soundtouch::SoundTouch(); - jack_st_conv[stream]->setTempo((float)speed/RD_TIMESCALE_DIVISOR); - jack_st_conv[stream]->setSampleRate(jack_output_sample_rate[stream]); - jack_st_conv[stream]->setChannels(jack_output_channels[stream]); - } - jack_playing[stream]=true; - if(length>0) { - jack_stop_timer[stream]->start(length); - } - statePlayUpdate(card,stream,1); - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackStopPlayback(int card,int stream) -{ -#ifdef JACK - if((stream <0) || (stream>=RD_MAX_STREAMS) || - (jack_play_ring[stream]==NULL)||(!jack_playing[stream])) { - return false; - } - jack_playing[stream]=false; - jack_stop_timer[stream]->stop(); - statePlayUpdate(card,stream,2); - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackTimescaleSupported(int card) -{ -#ifdef JACK - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackLoadRecord(int card,int stream,int coding,int chans, - int samprate,int bitrate,QString wavename) -{ -#ifdef JACK - jack_record_wave[stream]=new RDWaveFile(wavename); - switch(coding) { - case 0: // PCM16 - jack_record_wave[stream]->setFormatTag(WAVE_FORMAT_PCM); - jack_record_wave[stream]->setChannels(chans); - jack_record_wave[stream]->setSamplesPerSec(samprate); - jack_record_wave[stream]->setBitsPerSample(16); - break; - - case 4: // PCM24 - jack_record_wave[stream]->setFormatTag(WAVE_FORMAT_PCM); - jack_record_wave[stream]->setChannels(chans); - jack_record_wave[stream]->setSamplesPerSec(samprate); - jack_record_wave[stream]->setBitsPerSample(24); - break; - - case 2: // MPEG Layer 2 - if(!InitTwoLameEncoder(card,stream,chans,samprate,bitrate)) { - delete jack_record_wave[stream]; - jack_record_wave[stream]=NULL; - return false; - } - jack_record_wave[stream]->setFormatTag(WAVE_FORMAT_MPEG); - jack_record_wave[stream]->setChannels(chans); - jack_record_wave[stream]->setSamplesPerSec(samprate); - jack_record_wave[stream]->setBitsPerSample(16); - jack_record_wave[stream]->setHeadLayer(ACM_MPEG_LAYER2); - switch(chans) { - case 1: - jack_record_wave[stream]->setHeadMode(ACM_MPEG_SINGLECHANNEL); - break; - - case 2: - jack_record_wave[stream]->setHeadMode(ACM_MPEG_STEREO); - break; - - default: - rda->syslog(LOG_WARNING, - "requested unsupported channel count %d, card: %d, stream: %d", - chans,card,stream); - delete jack_record_wave[stream]; - jack_record_wave[stream]=NULL; - return false; - } - jack_record_wave[stream]->setHeadBitRate(bitrate); - jack_record_wave[stream]->setMextChunk(true); - jack_record_wave[stream]->setMextHomogenous(true); - jack_record_wave[stream]->setMextPaddingUsed(false); - jack_record_wave[stream]->setMextHackedBitRate(true); - jack_record_wave[stream]->setMextFreeFormat(false); - jack_record_wave[stream]-> - setMextFrameSize(144*jack_record_wave[stream]->getHeadBitRate()/ - jack_record_wave[stream]->getSamplesPerSec()); - jack_record_wave[stream]->setMextAncillaryLength(5); - jack_record_wave[stream]->setMextLeftEnergyPresent(true); - if(chans>1) { - jack_record_wave[stream]->setMextRightEnergyPresent(true); - } - else { - jack_record_wave[stream]->setMextRightEnergyPresent(false); - } - jack_record_wave[stream]->setMextPrivateDataPresent(false); - break; - - default: - rda->syslog(LOG_WARNING, - "requested invalid audio encoding %d, card: %d, stream: %d", - coding,card,stream); - delete jack_record_wave[stream]; - jack_record_wave[stream]=NULL; - return false; - } - jack_record_wave[stream]->setBextChunk(true); - jack_record_wave[stream]->setLevlChunk(true); - if(!jack_record_wave[stream]->createWave()) { - delete jack_record_wave[stream]; - jack_record_wave[stream]=NULL; - return false; - } - RDCheckExitCode(rda->config(),"jackLoadRecord() chown", - chown(wavename.toUtf8(),rda->config()->uid(),rda->config()->gid())); - jack_input_channels[stream]=chans; - jack_record_ring[stream]=new RDRingBuffer(RINGBUFFER_SIZE); - jack_record_ring[stream]->reset(); - jack_ready[stream]=true; - return true; - - /* - if ((stream <0) || (stream >=RD_MAX_PORTS)){ - return false; - } - jack_record_wave[stream]=new RDWaveFile(wavename); - jack_record_wave[stream]->setFormatTag(WAVE_FORMAT_PCM); - jack_record_wave[stream]->setChannels(chans); - jack_record_wave[stream]->setSamplesPerSec(samprate); - jack_record_wave[stream]->setBitsPerSample(16); - jack_record_wave[stream]->setBextChunk(true); - jack_record_wave[stream]->setLevlChunk(true); - if(!jack_record_wave[stream]->createWave()) { - delete jack_record_wave[stream]; - jack_record_wave[stream]=NULL; - return false; - } - chown((const char *)wavename,rd_config->uid(),rd_config->gid()); - jack_input_channels[stream]=chans; - jack_record_ring[stream]=new RDRingBuffer(RINGBUFFER_SIZE); - jack_record_ring[stream]->reset(); - jack_ready[stream]=true; - return true; - */ -#else - return false; -#endif // JACK -} - - -bool MainObject::jackUnloadRecord(int card,int stream,unsigned *len) -{ -#ifdef JACK - if ((stream <0) || (stream >= RD_MAX_PORTS)){ - return false; - } - jack_recording[stream]=false; - jack_ready[stream]=false; - EmptyJackInputStream(stream,true); - *len=jack_samples_recorded[stream]; - jack_samples_recorded[stream]=0; - jack_record_wave[stream]->closeWave(*len); - delete jack_record_wave[stream]; - jack_record_wave[stream]=NULL; - delete jack_record_ring[stream]; - jack_record_ring[stream]=NULL; - FreeTwoLameEncoder(card,stream); - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackRecord(int card,int stream,int length,int thres) -{ -#ifdef JACK - if ((stream <0) || (stream >= RD_MAX_PORTS)){ - return false; - } - if(!jack_ready[stream]) { - return false; - } - jack_recording[stream]=true; - if(jack_input_vox[stream]==0.0) { - if(length>0) { - jack_record_timer[stream]->start(length); - } - stateRecordUpdate(card,stream,4); - } - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackStopRecord(int card,int stream) -{ -#ifdef JACK - if ((stream <0) || (stream >= RD_MAX_PORTS)){ - return false; - } - if(!jack_recording[stream]) { - return false; - } - jack_recording[stream]=false; - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackSetInputVolume(int card,int stream,int level) -{ -#ifdef JACK - if ((stream <0) || (stream >= RD_MAX_STREAMS)){ - return false; - } - if(level>-10000) { - jack_input_volume[stream]= - (jack_default_audio_sample_t)pow(10.0,(double)level/2000.0); - jack_input_volume_db[stream]=level; - } - else { - jack_input_volume[stream]=0.0; - jack_input_volume_db[stream]=-10000; - } - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackSetOutputVolume(int card,int stream,int port,int level) -{ -#ifdef JACK - if ((stream <0) ||(stream >= RD_MAX_STREAMS) || - (port <0) || (port >= RD_MAX_PORTS)){ - return false; - } - if(level>-10000) { - jack_output_volume[port][stream]= - (jack_default_audio_sample_t)pow(10.0,(double)level/2000.0); - jack_output_volume_db[port][stream]=level; - } - else { - jack_output_volume[port][stream]=0.0; - jack_output_volume_db[port][stream]=-10000; - } - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackFadeOutputVolume(int card,int stream,int port,int level, - int length) -{ -#ifdef JACK - int diff; - if ((stream <0) ||(stream >= RD_MAX_STREAMS) || - (port <0) || (port >= RD_MAX_PORTS)){ - return false; - } - if(jack_fade_timer[stream]->isActive()) { - jack_fade_timer[stream]->stop(); - } - if(level>jack_output_volume_db[port][stream]) { - jack_fade_up[stream]=true; - diff=level-jack_output_volume_db[port][stream]; - } - else { - jack_fade_up[stream]=false; - diff=jack_output_volume_db[port][stream]-level; - } - jack_fade_volume_db[stream]=level; - jack_fade_port[stream]=port; - jack_fade_increment[stream]=diff*RD_JACK_FADE_INTERVAL/length; - jack_fade_timer[stream]->start(RD_JACK_FADE_INTERVAL); - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackSetInputLevel(int card,int port,int level) -{ -#ifdef JACK - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackSetOutputLevel(int card,int port,int level) -{ -#ifdef JACK - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackSetInputMode(int card,int stream,int mode) -{ -#ifdef JACK - jack_input_mode[card][stream]=mode; - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackSetOutputMode(int card,int stream,int mode) -{ -#ifdef JACK - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackSetInputVoxLevel(int card,int stream,int level) -{ -#ifdef JACK - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackSetInputType(int card,int port,int type) -{ -#ifdef JACK - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackGetInputStatus(int card,int port) -{ -#ifdef JACK - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackGetInputMeters(int card,int port,short levels[2]) -{ -#ifdef JACK - jack_default_audio_sample_t meter; - if ((port <0) || (port >= RD_MAX_PORTS)){ - return false; - } - for(int i=0;i<2;i++) { - meter=jack_input_meter[port][i]->average(); - if(meter==0.0) { - levels[i]=-10000; - } - else { - levels[i]=(short)(2000.0*log10(meter)); - if(levels[i]<-10000) { - levels[i]=-10000; - } - } - } - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackGetOutputMeters(int card,int port,short levels[2]) -{ -#ifdef JACK - jack_default_audio_sample_t meter; - if ((port <0) || (port >= RD_MAX_PORTS)){ - return false; - } - - for(int i=0;i<2;i++) { - meter=jack_output_meter[port][i]->average(); - if(meter==0.0) { - levels[i]=-10000; - } - else { - levels[i]=(short)(2000.0*log10(meter)); - if(levels[i]<-10000) { - levels[i]=-10000; - } - } - } - return true; -#else - return false; -#endif // JACK -} - - -bool MainObject::jackGetStreamOutputMeters(int card,int stream,short levels[2]) -{ -#ifdef JACK - jack_default_audio_sample_t meter; - if ((stream<0) || (stream>=RD_MAX_STREAMS)){ - return false; - } - - for(int i=0;i<2;i++) { - meter=jack_stream_output_meter[stream][i]->average(); - if(meter==0.0) { - levels[i]=-10000; - } - else { - levels[i]=(short)(2000.0*log10(meter)); - if(levels[i]<-10000) { - levels[i]=-10000; - } - } - } - return true; -#else - return false; -#endif // JACK -} - - -void MainObject::jackGetOutputPosition(int card,unsigned *pos) -{ -#ifdef JACK - for(int i=0;igetSamplesPerSec(); - } - else { - pos[i]=0; - } - } -#endif // JACK -} - -bool MainObject::jackSetPassthroughLevel(int card,int in_port,int out_port, - int level) -{ -#ifdef JACK - if ((in_port <0) || (in_port >= RD_MAX_PORTS) || - (out_port <0) || (out_port >= RD_MAX_PORTS)){ - return false; - } - if(level>-10000) { - jack_passthrough_volume[in_port][out_port]= - (jack_default_audio_sample_t)pow(10.0,(double)level/2000.0); - jack_passthrough_volume_db[in_port][out_port]=level; - } - else { - jack_passthrough_volume[in_port][out_port]=0.0; - jack_passthrough_volume_db[in_port][out_port]=-10000; - } - return true; -#else - return false; -#endif // JACK -} - - -int MainObject::GetJackOutputStream() -{ -#ifdef JACK - for(int i=0;i= RD_MAX_STREAMS)){ - return; - } - delete jack_play_ring[stream]; - jack_play_ring[stream]=NULL; - if(jack_st_conv[stream]!=NULL) { - delete jack_st_conv[stream]; - jack_st_conv[stream]=NULL; - } -#else - return; -#endif -} - - -void MainObject::EmptyJackInputStream(int stream,bool done) -{ -#ifdef JACK - if ((stream <0) || (stream >= RD_MAX_STREAMS)){ - return; - } - unsigned n=jack_record_ring[stream]-> - read((char *)jack_sample_buffer,jack_record_ring[stream]->readSpace()); - WriteJackBuffer(stream,jack_sample_buffer,n,done); -#endif // JACK -} - -#ifdef JACK -void MainObject::WriteJackBuffer(int stream,jack_default_audio_sample_t *buffer, - unsigned len,bool done) -{ - ssize_t s; - unsigned char mpeg[2048]; - unsigned frames; - unsigned n; - - frames=len/(sizeof(jack_default_audio_sample_t)* - jack_record_wave[stream]->getChannels()); - jack_samples_recorded[stream]+=frames; - switch(jack_record_wave[stream]->getFormatTag()) { - case WAVE_FORMAT_PCM: - switch(jack_record_wave[stream]->getBitsPerSample()) { - case 16: // PCM16 - n=len/sizeof(jack_default_audio_sample_t); - src_float_to_short_array(buffer,jack_wave_buffer,n); - jack_record_wave[stream]->writeWave(jack_wave_buffer,n*sizeof(short)); - break; - - case 24: // PCM24 - n=len/sizeof(jack_default_audio_sample_t); - src_float_to_int_array(buffer,jack_wave32_buffer,n); - for(unsigned i=0;iwriteWave(jack_wave24_buffer,n*3); - break; - } - break; - - case WAVE_FORMAT_MPEG: -#ifdef HAVE_TWOLAME - for(unsigned i=0;iframes) { - n=frames-i; - } - else { - n=1152; - } - if((s=twolame_encode_buffer_float32_interleaved( - twolame_lameopts[jack_card][stream], - buffer+i*jack_record_wave[stream]->getChannels(), - n,mpeg,2048))>=0) { - jack_record_wave[stream]->writeWave(mpeg,s); - } - else { - rda->syslog(LOG_WARNING, - "TwoLAME encode error, card: %d, stream: %d",jack_card,stream); - } - } - if(done) { - if((s=twolame_encode_flush(twolame_lameopts[jack_card][stream], - mpeg,2048))>=0) { - jack_record_wave[stream]->writeWave(mpeg,s); - } - } -#endif // HAVE_TWOLAME - break; - } -} -#endif // JACK - -void MainObject::FillJackOutputStream(int stream) -{ -#ifdef JACK - int n=0; - unsigned mpeg_frames=0; - unsigned frame_offset=0; - int m=0; - - if ((stream <0) || (stream >= RD_MAX_STREAMS)){ - return; - } - int free= - jack_play_ring[stream]->writeSpace()/sizeof(jack_default_audio_sample_t)-1; - if((free<=0)||(jack_eof[stream]==true)) { - return; - } - switch(jack_play_wave[stream]->getFormatTag()) { - case WAVE_FORMAT_PCM: - switch(jack_play_wave[stream]->getBitsPerSample()) { - case 16: // PMC16 - free=(int)free/jack_output_channels[stream]*jack_output_channels[stream]; - n=jack_play_wave[stream]->readWave(jack_wave_buffer,sizeof(short)*free)/ - sizeof(short); - if((n!=free)&&(jack_st_conv[stream]==NULL)) { - jack_eof[stream]=true; - jack_stop_timer[stream]->stop(); - } - src_short_to_float_array(jack_wave_buffer,jack_sample_buffer,n); - break; - - case 24: // PMC24 - free=(int)free/jack_output_channels[stream]*jack_output_channels[stream]; - n=jack_play_wave[stream]->readWave(jack_wave24_buffer,3*free)/3; - if((n!=free)&&(jack_st_conv[stream]==NULL)) { - jack_eof[stream]=true; - jack_stop_timer[stream]->stop(); - } - for(int i=0;ireadWave(jack_wave_buffer,sizeof(short)*free)/ - sizeof(short); - if((n!=free)&&(jack_st_conv[stream]==NULL)) { - jack_eof[stream]=true; - jack_stop_timer[stream]->stop(); - } - src_short_to_float_array(jack_wave_buffer,jack_sample_buffer,n); - break; - - case WAVE_FORMAT_MPEG: -#ifdef HAVE_MAD - mpeg_frames=free/(1152*jack_output_channels[stream]); - free=mpeg_frames*1152*jack_output_channels[stream]; - for(unsigned i=0;i - readWave(mad_mpeg[jack_card][stream]+mad_left_over[jack_card][stream], - mad_frame_size[jack_card][stream]); - if(m==mad_frame_size[jack_card][stream]) { - mad_stream_buffer(&mad_stream[jack_card][stream], - mad_mpeg[jack_card][stream], - m+mad_left_over[jack_card][stream]); - while(mad_frame_decode(&mad_frame[jack_card][stream], - &mad_stream[jack_card][stream])==0) { - mad_synth_frame(&mad_synth[jack_card][stream], - &mad_frame[jack_card][stream]); - n+=(jack_output_channels[stream]* - mad_synth[jack_card][stream].pcm.length); - for(int j=0;jstop(); - continue; - } - mad_left_over[jack_card][stream]= - mad_stream[jack_card][stream].bufend- - mad_stream[jack_card][stream].next_frame; - memmove(mad_mpeg[jack_card][stream], - mad_stream[jack_card][stream].next_frame, - mad_left_over[jack_card][stream]); - } -#endif // HAVE_MAD - break; - } - if(jack_st_conv[stream]==NULL) { - jack_play_ring[stream]-> - write((char *)jack_sample_buffer,n*sizeof(jack_default_audio_sample_t)); - } - else { - jack_st_conv[stream]-> - putSamples(jack_sample_buffer,n/jack_output_channels[stream]); - free=jack_play_ring[stream]->writeSpace()/ - (sizeof(jack_default_audio_sample_t)*jack_output_channels[stream])-1; - while((n=jack_st_conv[stream]-> - receiveSamples(jack_sample_buffer,free))>0) { - jack_play_ring[stream]-> - write((char *)jack_sample_buffer,n* - sizeof(jack_default_audio_sample_t)* - jack_output_channels[stream]); - free=jack_play_ring[stream]->writeSpace()/ - (sizeof(jack_default_audio_sample_t)*jack_output_channels[stream])-1; - } - if((jack_st_conv[stream]->numSamples()==0)&& - (jack_st_conv[stream]->numUnprocessedSamples()==0)) { - jack_eof[stream]=true; - jack_stop_timer[stream]->stop(); - } - } -#endif // JACK -} - - -void MainObject::JackClock() -{ -#ifdef JACK - for(int i=0;isetSource(RD_CONF_FILE); - bool src_ok=false; - bool dest_ok=false; - QString src_tag="Source1"; - QString dest_tag="Destination1"; - QString src=profile->stringValue("JackSession",src_tag,"",&src_ok); - QString dest=profile->stringValue("JackSession",dest_tag,"",&dest_ok); - while(src_ok&&dest_ok) { - if(jack_connect(jack_client,src.toUtf8(),dest.toUtf8())!=0) { - rda->syslog(LOG_WARNING,"unable to connect %s to %s", - (const char *)src.toUtf8(),(const char *)dest.toUtf8()); - } - count++; - src_tag=QString().sprintf("Source%d",count+1); - dest_tag=QString().sprintf("Destination%d",count+1); - src=profile->stringValue("JackSession",src_tag,"",&src_ok); - dest=profile->stringValue("JackSession",dest_tag,"",&dest_ok); - } - delete profile; -#endif // JACK -} diff --git a/cae/caedriverfactory.cpp b/cae/caedriverfactory.cpp deleted file mode 100644 index 1b5cb3f5..00000000 --- a/cae/caedriverfactory.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// caedriverfactory.xpp -// -// Create CaeDriver instances. -// -// (C) Copyright 2021 Fred Gleason -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as -// published by the Free Software Foundation. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "alsadriver.h" -#include "caedriverfactory.h" -#include "hpidriver.h" -#include "jackdriver.h" - -CaeDriver *CaeDriverFactory(RDStation::AudioDriver dvr,QObject *parent) -{ - CaeDriver *ret=NULL; - - switch(dvr) { - case RDStation::Hpi: - ret=new HpiDriver(parent); - break; - - case RDStation::Jack: - ret=new JackDriver(parent); - break; - - case RDStation::Alsa: - ret=new AlsaDriver(parent); - break; - - case RDStation::None: - break; - } - - return ret; -} diff --git a/cae/caedriverfactory.h b/cae/caedriverfactory.h deleted file mode 100644 index 3f25d0a4..00000000 --- a/cae/caedriverfactory.h +++ /dev/null @@ -1,33 +0,0 @@ -// caedriverfactory.h -// -// Create CaeDriver instances. -// -// (C) Copyright 2021 Fred Gleason -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as -// published by the Free Software Foundation. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef CAEDRIVERFACTORY_H -#define CAEDRIVERFACTORY_H - -#include - -#include - -#include "caedriver.h" - -CaeDriver *CaeDriverFactory(RDStation::AudioDriver dvr,QObject *parent=0); - - -#endif // CAEDRIVERFACTORY_H diff --git a/cae/jackdriver.cpp b/cae/jackdriver.cpp index 7e12553f..0fec7885 100644 --- a/cae/jackdriver.cpp +++ b/cae/jackdriver.cpp @@ -438,7 +438,11 @@ JackDriver::~JackDriver() QString JackDriver::version() const { +#ifdef JACK + return QString(jack_get_version_string()); +#else return QString(); +#endif // JACK }