From 4704ca52c0da802c89763391768eafa69f8a2f6e Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 22 Sep 2014 00:11:16 +0100 Subject: [PATCH 01/34] Add M4A import support using MP4V2 and faad. --- configure.ac | 23 ++++++++- lib/rdaudioconvert.cpp | 74 ++++++++++++++++++++++++++++ lib/rdaudioconvert.h | 2 + lib/rdwavefile.cpp | 107 +++++++++++++++++++++++++++++++++++++++++ lib/rdwavefile.h | 4 +- 5 files changed, 208 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 04b39930..5c20fb9c 100644 --- a/configure.ac +++ b/configure.ac @@ -78,6 +78,8 @@ AC_ARG_ENABLE(lame,[ --disable-lame disable MPEG Layer 3 encode suppor [LAME_DISABLED=yes],[]) AC_ARG_ENABLE(flac,[ --disable-flac disable FLAC encode/decode support], [FLAC_DISABLED=yes],[]) +AC_ARG_ENABLE(mp4v2,[ --disable-mp4 disable M4A decode support], + [MP4V2_DISABLED=yes],[]) # # Check for Qt @@ -206,10 +208,24 @@ if test -z $FLAC_DISABLED ; then AC_CHECK_LIB(FLAC,FLAC__metadata_get_tags,[FLAC_METADATA_FOUND=yes],[]) fi +# +# Check for MP4V2 +# +if test -z $MP4V2_DISABLED ; then + AC_CHECK_HEADER(mp4v2/mp4v2.h,[MP4V2_HEADER_FOUND=yes],[]) + if test $MP4V2_HEADER_FOUND ; then + AC_CHECK_LIB(mp4v2,MP4Read,[MP4V2_FOUND=yes],[]) + fi + if test $MP4V2_FOUND ; then + MP4V2_LIBS="-lmp4v2" + AC_DEFINE(HAVE_MP4V2) + fi +fi + # # Set Hard Library Dependencies # -AC_SUBST(LIB_RDLIBS,"-lm -lpthread -lqui -lrd -lcurl -lid3 $FLAC_LIBS -lsndfile -lsamplerate -lcdda_interface -lcdda_paranoia -lcrypt -ldl -lpam -lSoundTouch") +AC_SUBST(LIB_RDLIBS,"-lm -lpthread -lqui -lrd -lcurl -lid3 $FLAC_LIBS $MP4V2_LIBS -lsndfile -lsamplerate -lcdda_interface -lcdda_paranoia -lcrypt -ldl -lpam -lSoundTouch") # # Setup MPEG Dependencies @@ -531,6 +547,11 @@ AC_MSG_NOTICE("| OggVorbis Encoding/Decoding Support ... No |") else AC_MSG_NOTICE("| OggVorbis Encoding/Decoding Support ... Yes |") fi +if test -z $MP4V2_FOUND ; then +AC_MSG_NOTICE("| M4A Decoding Support ... No |") +else +AC_MSG_NOTICE("| M4A Decoding Support ... Yes |") +fi AC_MSG_NOTICE("| |") AC_MSG_NOTICE("| Optional Components: |") if test -z $USING_PAM ; then diff --git a/lib/rdaudioconvert.cpp b/lib/rdaudioconvert.cpp index a9767ca2..edd9bbbb 100644 --- a/lib/rdaudioconvert.cpp +++ b/lib/rdaudioconvert.cpp @@ -23,11 +23,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -307,6 +309,11 @@ RDAudioConvert::ErrorCode RDAudioConvert::Stage1Convert(const QString &srcfile, delete wave; return err; + case RDWaveFile::M4A: + err=Stage1M4A(dstfile,wave); + delete wave; + return err; + case RDWaveFile::Aiff: case RDWaveFile::Unknown: break; @@ -673,6 +680,73 @@ RDAudioConvert::ErrorCode RDAudioConvert::Stage1Mpeg(const QString &dstfile, #endif // HAVE_MAD } +RDAudioConvert::ErrorCode RDAudioConvert::Stage1M4A(const QString &dstfile, + RDWaveFile *wave) { + + const char* args[7]; + int childstatus = 0; + + pid_t child = fork(); + + QString tmpname = dstfile + ".m4a_temp.wav"; + + if(child == 0) { + + freopen("/dev/null", "w", stdout); + freopen("/dev/null", "w", stderr); + + args[0] = "faad"; + args[1] = wave->getName(); + args[2] = "-o"; + args[3] = tmpname; + args[4] = "-b"; + args[5] = "4"; // Emit a Float32 format wave file, like the other stage 1s. + args[6] = 0; + execvp("faad", (char* const*)args); + exit(109); + + } + else { + + waitpid(child, &childstatus, 0); + + // Killed by a signal (e.g. OOM?) + if(!WIFEXITED(childstatus)) { + unlink(tmpname); + return RDAudioConvert::ErrorInternal; + } + + // Returned 109, probably because we could't find faad? + if(WEXITSTATUS(childstatus) == 109) + return RDAudioConvert::ErrorFormatNotSupported; + + // Two elements are missing: + // 1. need to measure the peak amplitude; + // 2. need to trim if a subrange was requested. + // For now just use the sndfile import path to accomplish both tasks. + + { + + SF_INFO sf_src_info; + SNDFILE* sf_src; + + memset(&sf_src_info, 0, sizeof(sf_src_info)); + // If this fails it is likely because faad could not decode. + if((sf_src = sf_open(tmpname, SFM_READ, &sf_src_info)) == NULL) + return RDAudioConvert::ErrorFormatError; + + RDAudioConvert::ErrorCode err = Stage1SndFile(dstfile, sf_src, &sf_src_info); + + sf_close(sf_src); + unlink(tmpname); + + return err; + + } + + } + +} RDAudioConvert::ErrorCode RDAudioConvert::Stage1SndFile(const QString &dstfile, SNDFILE *sf_src, diff --git a/lib/rdaudioconvert.h b/lib/rdaudioconvert.h index 3b833c9a..14eeb976 100644 --- a/lib/rdaudioconvert.h +++ b/lib/rdaudioconvert.h @@ -70,6 +70,8 @@ class RDAudioConvert : public QObject RDWaveFile *wave); RDAudioConvert::ErrorCode Stage1Mpeg(const QString &dstfile, RDWaveFile *wave); + RDAudioConvert::ErrorCode Stage1M4A(const QString &dstfile, + RDWaveFile *wave); RDAudioConvert::ErrorCode Stage1SndFile(const QString &dstfile, SNDFILE *sf_src, SF_INFO *sf_src_info); diff --git a/lib/rdwavefile.cpp b/lib/rdwavefile.cpp index c09f9985..5c2408de 100644 --- a/lib/rdwavefile.cpp +++ b/lib/rdwavefile.cpp @@ -48,6 +48,10 @@ #include #include +#ifdef HAVE_MP4V2 +#include +#endif + RDWaveFile::RDWaveFile(QString file_name) { // @@ -322,6 +326,94 @@ bool RDWaveFile::openWave(RDWaveData *data) ReadId3Metadata(); break; + case RDWaveFile::M4A: + { +#ifdef HAVE_MP4V2 + + format_tag=WAVE_FORMAT_M4A; + + MP4FileHandle f = MP4Read(getName()); + if(f == MP4_INVALID_FILE_HANDLE) + return false; + + // Find an audio track, and populate sample rate, bits/sample etc. + uint32_t nTracks = MP4GetNumberOfTracks(f); + + MP4TrackId audioTrack = MP4_INVALID_TRACK_ID; + for(uint32_t trackIndex = 0; trackIndex < nTracks && audioTrack == MP4_INVALID_TRACK_ID; ++trackIndex) { + + MP4TrackId thisTrack = MP4FindTrackId(f, trackIndex); + const char* trackType = MP4GetTrackType(f, thisTrack); + if(trackType && !strcmp(trackType, MP4_AUDIO_TRACK_TYPE)) { + + const char* dataName = MP4GetTrackMediaDataName(f, thisTrack); + // The M4A format is only currently useful for AAC in an M4A container: + if(dataName && + (!strcasecmp(dataName, "mp4a")) && + MP4GetTrackEsdsObjectTypeId(f, thisTrack) == MP4_MPEG4_AUDIO_TYPE) { + + audioTrack = thisTrack; + + } + + } + + } + + if(audioTrack == MP4_INVALID_TRACK_ID) { + MP4Close(f); + return false; + } + + // Found audio track. Get audio data: + avg_bytes_per_sec = MP4GetTrackBitRate(f, audioTrack); + channels = MP4GetTrackAudioChannels(f, audioTrack); + + MP4Duration trackDuration = MP4GetTrackDuration(f, audioTrack); + ext_time_length = (unsigned)MP4ConvertFromTrackDuration(f, audioTrack, trackDuration, + MP4_MSECS_TIME_SCALE); + time_length = ext_time_length / 1000; + samples_per_sec = MP4GetTrackTimeScale(f, audioTrack); + bits_per_sample = 16; + data_start = 0; + sample_length = MP4GetTrackNumberOfSamples(f, audioTrack); + data_length = sample_length * 2 * channels; + data_chunk = true; + format_chunk = true; + wave_type = RDWaveFile::M4A; + + // Now extract metadata (title, artist, etc) + + if(wave_data) { + + const MP4Tags* tags = MP4TagsAlloc(); + MP4TagsFetch(tags, f); + + wave_data->setMetadataFound(true); + + if(tags->name) + wave_data->setTitle(tags->name); + if(tags->artist) + wave_data->setArtist(tags->artist); + if(tags->composer) + wave_data->setComposer(tags->composer); + if(tags->album) + wave_data->setAlbum(tags->album); + + MP4TagsFree(tags); + + } + + MP4Close(f); + + return true; + +#else + return false; +#endif + break; + } + case RDWaveFile::Ogg: #ifdef HAVE_VORBIS format_tag=WAVE_FORMAT_VORBIS; @@ -2020,6 +2112,9 @@ RDWaveFile::Type RDWaveFile::GetType(int fd) if(IsOgg(fd)) { return RDWaveFile::Ogg; } + if(IsM4A(fd)) { + return RDWaveFile::M4A; + } if(IsMpeg(fd)) { return RDWaveFile::Mpeg; } @@ -2211,6 +2306,18 @@ bool RDWaveFile::IsAiff(int fd) return true; } +bool RDWaveFile::IsM4A(int fd) +{ +#ifdef HAVE_MP4V2 + MP4FileHandle f = MP4Read(getName()); + bool ret = f != MP4_INVALID_FILE_HANDLE; + if(ret) + MP4Close(f); + return ret; +#else + return false; +#endif +} off_t RDWaveFile::FindChunk(int fd,const char *chunk_name,unsigned *chunk_size, bool big_end) diff --git a/lib/rdwavefile.h b/lib/rdwavefile.h index fbe4cfc1..c4a632fc 100644 --- a/lib/rdwavefile.h +++ b/lib/rdwavefile.h @@ -116,7 +116,7 @@ class RDWaveFile enum Format {Pcm8=0,Pcm16=1,Float32=2,MpegL1=3,MpegL2=4,MpegL3=5, DolbyAc2=6,DolbyAc3=7,Vorbis=8}; enum Type {Unknown=0,Wave=1,Mpeg=2,Ogg=3,Atx=4,Tmc=5,Flac=6,Ambos=7, - Aiff=8}; + Aiff=8,M4A=9}; enum MpegID {NonMpeg=0,Mpeg1=1,Mpeg2=2}; /** @@ -1046,6 +1046,7 @@ class RDWaveFile bool IsTmc(int fd); bool IsFlac(int fd); bool IsAiff(int fd); + bool IsM4A(int fd); off_t FindChunk(int fd,const char *chunk_name,unsigned *chunk_size, bool big_end=false); bool GetChunk(int fd,const char *chunk_name,unsigned *chunk_size, @@ -1378,6 +1379,7 @@ class RDWaveFile */ #define WAVE_FORMAT_VORBIS 0xFFFF #define WAVE_FORMAT_FLAC 0xFFFE +#define WAVE_FORMAT_M4A 0xFFFD /* * Proprietary Format Categories From f63b14cca9b2a57c3ca5b6505736e32d555add56 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Sun, 21 Dec 2014 20:13:58 +0000 Subject: [PATCH 02/34] MP4 support v2 (undebugged). This replaces callouts to faad with use of libfaad (aka neaacdec) and loads all components dynamically, much like existing MP1/2/3 support. --- configure.ac | 13 ++- lib/Makefile.am | 1 + lib/rdaudioconvert.cpp | 206 +++++++++++++++++++++++++++++------------ lib/rdaudioconvert.h | 3 + lib/rdmp4.cpp | 106 +++++++++++++++++++++ lib/rdmp4.h | 95 +++++++++++++++++++ lib/rdwavefile.cpp | 64 +++++-------- lib/rdwavefile.h | 4 + 8 files changed, 388 insertions(+), 104 deletions(-) create mode 100644 lib/rdmp4.cpp create mode 100644 lib/rdmp4.h diff --git a/configure.ac b/configure.ac index 3f8f0344..9276b359 100644 --- a/configure.ac +++ b/configure.ac @@ -216,18 +216,17 @@ fi if test -z $MP4V2_DISABLED ; then AC_CHECK_HEADER(mp4v2/mp4v2.h,[MP4V2_HEADER_FOUND=yes],[]) if test $MP4V2_HEADER_FOUND ; then - AC_CHECK_LIB(mp4v2,MP4Read,[MP4V2_FOUND=yes],[]) - fi - if test $MP4V2_FOUND ; then - MP4V2_LIBS="-lmp4v2" - AC_DEFINE(HAVE_MP4V2) - fi + AC_CHECK_HEADER(neaacdec.h,[MP4V2_FOUND=yes],[]) + if test $MP4V2_FOUND ; then + AC_DEFINE(HAVE_MP4_LIBS) + fi + fi fi # # Set Hard Library Dependencies # -AC_SUBST(LIB_RDLIBS,"-lm -lpthread -lqui -lrd -lcurl -lid3 $FLAC_LIBS $MP4V2_LIBS -lsndfile -lsamplerate -lcdda_interface -lcdda_paranoia -lcrypt -ldl -lpam -lSoundTouch") +AC_SUBST(LIB_RDLIBS,"-lm -lpthread -lqui -lrd -lcurl -lid3 $FLAC_LIBS -lsndfile -lsamplerate -lcdda_interface -lcdda_paranoia -lcrypt -ldl -lpam -lSoundTouch") # # Setup MPEG Dependencies diff --git a/lib/Makefile.am b/lib/Makefile.am index e751d5b0..b4f08c72 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -176,6 +176,7 @@ dist_librd_la_SOURCES = dbversion.h\ rdmeteraverage.cpp rdmeteraverage.h\ rdmixer.cpp rdmixer.h\ rdmonitor_config.cpp rdmonitor_config.h\ + rdmp4.cpp rdmp4.h\ rdnownext.cpp rdnownext.h\ rdoneshot.cpp rdoneshot.h\ rdpam.cpp rdpam.h\ diff --git a/lib/rdaudioconvert.cpp b/lib/rdaudioconvert.cpp index 429b5450..98dd2324 100644 --- a/lib/rdaudioconvert.cpp +++ b/lib/rdaudioconvert.cpp @@ -42,6 +42,10 @@ #include #include #endif // HAVE_FLAC +#ifdef HAVE_MP4_LIBS +#include +#include +#endif // HAVE_MP4_LIBS #include #include @@ -680,72 +684,160 @@ RDAudioConvert::ErrorCode RDAudioConvert::Stage1Mpeg(const QString &dstfile, #endif // HAVE_MAD } +// Based on libfaad's frontend/main.c, but using libmp4v2 for MP4 access. RDAudioConvert::ErrorCode RDAudioConvert::Stage1M4A(const QString &dstfile, - RDWaveFile *wave) { - - const char* args[7]; - int childstatus = 0; - - pid_t child = fork(); - - QString tmpname = dstfile + ".m4a_temp.wav"; - - if(child == 0) { - - freopen("/dev/null", "w", stdout); - freopen("/dev/null", "w", stderr); - - args[0] = "faad"; - args[1] = wave->getName(); - args[2] = "-o"; - args[3] = tmpname; - args[4] = "-b"; - args[5] = "4"; // Emit a Float32 format wave file, like the other stage 1s. - args[6] = 0; - execvp("faad", (char* const*)args); - exit(109); + RDWaveFile *wave) +{ +#ifdef HAVE_MP4_LIBS + SNDFILE *sf_dst=NULL; + SF_INFO sf_dst_info; + int ret = RDAudioConvert::ErrorOk; + if(!LoadMP4Libs()) { + return RDAudioConvert::ErrorFormatNotSupported; } - else { - waitpid(child, &childstatus, 0); - - // Killed by a signal (e.g. OOM?) - if(!WIFEXITED(childstatus)) { - unlink(tmpname); - return RDAudioConvert::ErrorInternal; - } - - // Returned 109, probably because we could't find faad? - if(WEXITSTATUS(childstatus) == 109) - return RDAudioConvert::ErrorFormatNotSupported; - - // Two elements are missing: - // 1. need to measure the peak amplitude; - // 2. need to trim if a subrange was requested. - // For now just use the sndfile import path to accomplish both tasks. - - { - - SF_INFO sf_src_info; - SNDFILE* sf_src; - - memset(&sf_src_info, 0, sizeof(sf_src_info)); - // If this fails it is likely because faad could not decode. - if((sf_src = sf_open(tmpname, SFM_READ, &sf_src_info)) == NULL) - return RDAudioConvert::ErrorFormatError; - - RDAudioConvert::ErrorCode err = Stage1SndFile(dstfile, sf_src, &sf_src_info); - - sf_close(sf_src); - unlink(tmpname); - - return err; + // + // Open source + // + MP4FileHandle f = dlmp4.MP4Read(getName()); + if(f == MP4_INVALID_FILE_HANDLE) + return RDAudioConvert::ErrorNoSource; + MP4TrackId audioTrack = dlmp4.getMP4AACTrack(f); + MP4SampleId firstSample = 0; + MP4SampleId lastSample = dlmp4.MP4GetTrackNumberOfSamples(f, audioTrack) - 1; + if(conv_start_point > 0) { + + double startsecs = ((double)conv_start_point) / 1000; + MP4Timestamp startts = (MP4Timestamp)(startsecs * wave->getSamplesPerSec()); + firstSample = dlmp4.MP4GetSampleIdFromTime(f, audioTrack, startts, /*need_sync=*/false); + if(firstSample == MP4_INVALID_SAMPLE_ID) { + ret = RDAudioConvert::ErrorInvalidSource; + goto out_mp4; } } + if(conv_end_point > 0) { + + double stopsecs = ((double)conv_end_point) / 1000; + MP4Timestamp stopts = (MP4Timestamp)(stopsecs * wave->getSamplesPerSec()); + lastSample = dlmp4.MP4GetSampleIdFromTime(f, audioTrack, stopts, /*need_sync=*/false); + if(lastSample == MP4_INVALID_SAMPLE_ID) { + ret = RDAudioConvert::ErrorInvalidSource; + goto out_mp4; + } + + } + + uint32_t aacBufSize = dlmp4.MP4GetTrackMaxSampleSize(f, audioTrack); + uint8_t* aacBuf = malloc(aacBufSize); + if(!aacBufSize || !aacBuf) { + // Probably the source's fault for specifying a massive buffer. + ret = RDAudioConvert::ErrorInvalidSource; + goto out_mp4; + } + + uint8_t* aacConfigBuffer; + uint32_t* aacConfigSize; + + dlmp4.MP4GetTrackESConfiguration(f, audioTrack, &aacConfigBuffer, &aacConfigSize); + if(!aacConfigBuffer) { + ret = RDAudioConvert::ErrorInvalidSource; + goto out_mp4_buf; + } + + // + // Open Destination + // + + memset(&sf_dst_info,0,sizeof(sf_dst_info)); + sf_dst_info.format=SF_FORMAT_WAV|SF_FORMAT_FLOAT; + sf_dst_info.channels=wave->getChannels(); + sf_dst_info.samplerate=wave->getSamplesPerSec(); + if((sf_dst=sf_open(dstfile,SFM_WRITE,&sf_dst_info))==NULL) { + ret = RDAudioConvert::ErrorNoDestination; + goto out_mp4_configbuf; + } + sf_command(sf_dst,SFC_SET_NORM_DOUBLE,NULL,SF_FALSE); + + // + // Initialize Decoder + // + NeAACDecHandle hDecoder = dlmp4.NeAACDecOpen(); + + NeAACDecConfigurationPtr config = dlmp4.NeAACDecGetCurrentConfiguration(hDecoder); + config->outputFormat = FAAD_FMT_FLOAT; + config->downMatrix = 1; // Downmix >2 channels to stereo. + if(!dlmp4.NeAACDecSetConfiguration(hDecoder, config)) { + ret = RDAudioConvert::ErrorInvalidSource; + goto out_decoder; + } + + unsigned long foundSampleRate; + unsigned char foundChannels; + if(dlmp4.NeAACDecInit2(hDecoder, aacConfigBuffer, aacConfigSize, &foundSampleRate, &foundChannels) < 0) { + ret = RDAudioConvert::ErrorInvalidSource; + goto out_decoder; + } + + if(foundSampleRate != wave->getSamplesPerSec() || foundChannels != wave->getChannels()) { + fprintf(stderr, "M4A header information inconsistent with actual file? Header: %lu/%u; file: %lu/%u\n", + wave->getSamplesPerSec(), (unsigned)wave->getChannels(), foundSampleRate, (unsigned)foundChannels); + ret = RDAudioConvert::ErrorInvalidSource; + goto out_decoder; + } + + // + // Decode + // + for(MP4SampleId i = firstSample; i <= lastSample; ++i) { + + uint32_t aacBytes = aacBufSize; + if(!dlmp4.MP4ReadSample(f, audioTrack, i, &aacBuf, &aacBytes, 0, 0, 0, 0)) { + ret = RDAudioConvert::ErrorInvalidSource; + break; + } + + NeAACDecFrameInfo frameInfo; + // The library docs are not clear about the lifetime or cleanup of sample_buffer. + // I hope it lives until the next NeAACDecDecode call, and is cleaned up by NeAACDecClose + void* sample_buffer = dlmp4.NeAACDecDecode(hDecoder, &frameInfo, aacBuf, aacBytes); + if(!sample_buffer) { + ret = RDAudioConvert::ErrorInvalidSource; + break; + } + + UpdatePeak(sample_buffer, frameInfo.samples); + + if(sf_write_float(dst_sf, sample_buffer, frameInfo.samples) != frameInfo.samples) { + ret = RDAudioConvert::ErrorInternal; + break; + } + + } + + // + // Cleanup + // + + out_decoder: + dlmp4.NeAACDecClose(hDecoder); + out_sf: + sf_close(sf_dst); + out_mp4_configbuf: + free(aacConfigBuffer); + out_mp4_buf: + free(aacBuf); + out_mp4: + dlmp4.MP4Close(f, 0); + + return ret; + +#else + return RDAudioConvert::ErrorFormatNotSupported; +#endif } RDAudioConvert::ErrorCode RDAudioConvert::Stage1SndFile(const QString &dstfile, diff --git a/lib/rdaudioconvert.h b/lib/rdaudioconvert.h index 14eeb976..e01df514 100644 --- a/lib/rdaudioconvert.h +++ b/lib/rdaudioconvert.h @@ -152,6 +152,9 @@ class RDAudioConvert : public QObject int (*lame_encode_flush)(lame_global_flags *,unsigned char *,int); int (*lame_set_bWriteVbrTag)(lame_global_flags *, int); #endif // HAVE_LAME +#ifdef HAVE_MP4_LIBS + DLMP4 dlmp4; +#endif }; diff --git a/lib/rdmp4.cpp b/lib/rdmp4.cpp new file mode 100644 index 00000000..a1986472 --- /dev/null +++ b/lib/rdmp4.cpp @@ -0,0 +1,106 @@ +// rdmp4.cpp +// +// Helpers for dealing with MP4 files. +// +// (C) Copyright 2014 Christopher Smowton +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library 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. +// +// + +#ifdef HAVE_MP4_LIBS + +#include +#include + +MP4TrackId DLMP4::getMP4AACTrack(MP4FileHandle f) +{ + + uint32_t nTracks = this->MP4GetNumberOfTracks(f); + + for(uint32_t trackIndex = 0; trackIndex < nTracks; ++trackIndex) { + + MP4TrackId thisTrack = this->MP4FindTrackId(f, trackIndex); + const char* trackType = this->MP4GetTrackType(f, thisTrack); + if(trackType && !strcmp(trackType, MP4_AUDIO_TRACK_TYPE)) { + + const char* dataName = this->MP4GetTrackMediaDataName(f, thisTrack); + // The M4A format is only currently useful for AAC in an M4A container: + if(dataName && + (!strcasecmp(dataName, "mp4a")) && + this->MP4GetTrackEsdsObjectTypeId(f, thisTrack) == MP4_MPEG4_AUDIO_TYPE) { + + return thisTrack; + + } + + } + + } + + return MP4_INVALID_TRACK_ID; + +} + +#define check_dlsym(lval, libhandle, symname) \ + *(void**)(&lval) = dlsym(libhandle, symname); \ + if(!lval) return false; + +bool DLMP4::load() +{ + + if(loadSuccess) + return true; + + neaac_handle = dlopen("libfaad.so",RTLD_LAZY); + mp4_handle = dlopen("libmp4v2.so",RTLD_LAZY); + + if(!neaac_handle || !mp4_handle) + return false; + + check_dlsym(this->MP4Read, mp4_handle, "MP4Read"); + check_dlsym(this->MP4GetTrackNumberOfSamples, mp4_handle, "MP4GetTrackNumberOfSamples"); + check_dlsym(this->MP4GetSampleIdFromTime, mp4_handle, "MP4GetSampleIdFromTime"); + check_dlsym(this->MP4GetTrackMaxSampleSize, mp4_handle, "MP4GetTrackMaxSampleSize"); + check_dlsym(this->MP4GetTrackESConfiguration, mp4_handle, "MP4GetTrackESConfiguration"); + check_dlsym(this->MP4ReadSample, mp4_handle, "MP4ReadSample"); + check_dlsym(this->MP4GetTrackBitRate, mp4_handle, "MP4GetTrackBitRate"); + check_dlsym(this->MP4GetTrackAudioChannels, mp4_handle, "MP4GetTrackAudioChannels"); + check_dlsym(this->MP4GetTrackDuration, mp4_handle, "MP4GetTrackDuration"); + check_dlsym(this->MP4ConvertFromTrackDuration, mp4_handle, "MP4ConvertFromTrackDuration"); + check_dlsym(this->MP4GetTrackTimeScale, mp4_handle, "MP4GetTrackTimeScale"); + check_dlsym(this->MP4GetNumberOfTracks, mp4_handle, "MP4GetNumberOfTracks"); + check_dlsym(this->MP4FindTrackId, mp4_handle, "MP4FindTrackId"); + check_dlsym(this->MP4GetTrackType, mp4_handle, "MP4GetTrackType"); + check_dlsym(this->MP4GetTrackMediaDataName, mp4_handle, "MP4GetTrackMediaDataName"); + check_dlsym(this->MP4GetTrackEsdsObjectTypeId, mp4_handle, "MP4GetTrackEsdsObjectTypeId"); + check_dlsym(this->MP4TagsAlloc, mp4_handle, "MP4TagsAlloc"); + check_dlsym(this->MP4TagsFetch, mp4_handle, "MP4TagsFetch"); + check_dlsym(this->MP4TagsFree, mp4_handle, "MP4TagsFree"); + check_dlsym(this->MP4Close, mp4_handle, "MP4Close"); + + check_dlsym(this->NeAACDecOpen, neaac_handle, "NeAACDecOpen"); + check_dlsym(this->NeAACDecGetCurrentConfiguration, neaac_handle, "NeAACDecGetCurrentConfiguration"); + check_dlsym(this->NeAACDecSetConfiguration, neaac_handle, "NeAACDecSetConfiguration"); + check_dlsym(this->NeAACDecInit2, neaac_handle, "NeAACDecInit2"); + check_dlsym(this->NeAACDecDecode, neaac_handle, "NeAACDecDecode"); + check_dlsym(this->NeAACDecClose, neaac_handle, "NeAACDecClose"); + + loadSuccess = true; + +} + +#undef check_dlsym + +#endif // HAVE_MP4_LIBS diff --git a/lib/rdmp4.h b/lib/rdmp4.h new file mode 100644 index 00000000..ebdb3bdc --- /dev/null +++ b/lib/rdmp4.h @@ -0,0 +1,95 @@ +// rdmp4.h +// +// Helpers for dealing with MP4 files. +// +// (C) Copyright 2014 Christopher Smowton +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library 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 RDMP4_H +#define RDMP4_H +#ifdef HAVE_MP4_LIBS + +#include +#include + +struct DLMP4 { + +DLMP4() : loadSuccess(false) {} + + void *conv_neaac_handle; + void *conv_mp4_handle; + bool loadSuccess; + + // MP4v2 Functions + MP4FileHandle (*MP4Read) (const char* fileName); + MP4SampleId (*MP4GetTrackNumberOfSamples) (MP4FileHandle hFile, MP4TrackId trackId); + MP4SampleId (*MP4GetSampleIdFromTime) (MP4FileHandle hFile, MP4TrackId trackId, MP4Timestamp when, bool wantSyncSample); + uint32_t (*MP4GetTrackMaxSampleSize) (MP4FileHandle hFile, MP4TrackId trackId); + bool (*MP4GetTrackESConfiguration) (MP4FileHandle hFile, MP4TrackId trackId, uint8_t** ppConfig, uint32_t* pConfigSize); + bool (*MP4ReadSample) ( + MP4FileHandle hFile, + MP4TrackId trackId, + MP4SampleId sampleId, + uint8_t** ppBytes, + uint32_t* pNumBytes, + MP4Timestamp* pStartTime, + MP4Duration* pDuration, + MP4Duration* pRenderingOffset, + bool* pIsSyncSample); + uint32_t (*MP4GetTrackBitRate) (MP4FileHandle hFile, MP4TrackId trackId); + int (*MP4GetTrackAudioChannels) (MP4FileHandle hFile, MP4TrackId trackId); + MP4Duration (*MP4GetTrackDuration) (MP4FileHandle hFile, MP4TrackId trackId); + uint64_t (*MP4ConvertFromTrackDuration) ( + MP4FileHandle hFile, + MP4TrackId trackId, + MP4Duration duration, + uint32_t timeScale); + uint32_t (*MP4GetTrackTimeScale) (MP4FileHandle hFile, MP4TrackId trackId); + uint32_t (*MP4GetNumberOfTracks) (MP4FileHandle hFile); + MP4TrackId (*MP4FindTrackId) (MP4FileHandle hFile, uint32_t trackIdx); + const char* (*MP4GetTrackType) (MP4FileHandle hFile, MP4TrackId); + const char* (*MP4GetTrackMediaDataName) (MP4FileHandle hFile, MP4TrackId); + uint8_t (*MP4GetTrackEsdsObjectTypeId) (MP4FileHandle hFile, MP4TrackId); + const MP4Tags* (*MP4TagsAlloc) (void); + bool (*MP4TagsFetch) (const MP4Tags* tags, MP4FileHandle hFile); + void (*MP4TagsFree) (const MP4Tags* tags); + void (*MP4Close) (MP4FileHandle hFile, uint32_t flags); + + // libfaad / NeAACDec functions + NeAACDecHandle (*NeAACDecOpen) (void); + NeAACDecConfigurationPtr (*NeAACDecGetCurrentConfiguration) (NeAACDecHandle hDecoder); + unsigned char (*NeAACDecSetConfiguration) (NeAACDecHandle hDecoder, NeAACDecConfigurationPtr config); + char (*NeAACDecInit2)(NeAACDecHandle hDecoder, + unsigned char *pBuffer, + unsigned long SizeOfDecoderSpecificInfo, + unsigned long *samplerate, + unsigned char *channels); + void* (*NeAACDecDecode) (NeAACDecHandle hDecoder, + NeAACDecFrameInfo *hInfo, + unsigned char *buffer, + unsigned long buffer_size); + void (*NeAACDecClose) (NeAACDecHandle hDecoder); + + // Helper functions: + MP4TrackId getMP4AACTrack(MP4FileHandle f); + + bool load(); + +}; + +#endif // HAVE_MP4_LIBS +#endif // RDMP4_H diff --git a/lib/rdwavefile.cpp b/lib/rdwavefile.cpp index f825f0fb..d1c2c869 100644 --- a/lib/rdwavefile.cpp +++ b/lib/rdwavefile.cpp @@ -47,8 +47,9 @@ #include #include #include +#include -#ifdef HAVE_MP4V2 +#ifdef HAVE_MP4_LIBS #include #endif @@ -328,55 +329,36 @@ bool RDWaveFile::openWave(RDWaveData *data) case RDWaveFile::M4A: { -#ifdef HAVE_MP4V2 +#ifdef HAVE_MP4_LIBS + // MP4 libs must already be loaded by now for file to have that type. + assert(dlmp4.load()); format_tag=WAVE_FORMAT_M4A; - MP4FileHandle f = MP4Read(getName()); + MP4FileHandle f = dlmp4.MP4Read(getName()); if(f == MP4_INVALID_FILE_HANDLE) return false; // Find an audio track, and populate sample rate, bits/sample etc. - uint32_t nTracks = MP4GetNumberOfTracks(f); - - MP4TrackId audioTrack = MP4_INVALID_TRACK_ID; - for(uint32_t trackIndex = 0; trackIndex < nTracks && audioTrack == MP4_INVALID_TRACK_ID; ++trackIndex) { - - MP4TrackId thisTrack = MP4FindTrackId(f, trackIndex); - const char* trackType = MP4GetTrackType(f, thisTrack); - if(trackType && !strcmp(trackType, MP4_AUDIO_TRACK_TYPE)) { - - const char* dataName = MP4GetTrackMediaDataName(f, thisTrack); - // The M4A format is only currently useful for AAC in an M4A container: - if(dataName && - (!strcasecmp(dataName, "mp4a")) && - MP4GetTrackEsdsObjectTypeId(f, thisTrack) == MP4_MPEG4_AUDIO_TYPE) { - - audioTrack = thisTrack; - - } - - } - - } + MP4TrackId audioTrack = dlmp4.getMP4AACTrack(f); if(audioTrack == MP4_INVALID_TRACK_ID) { - MP4Close(f); + dlmp4.MP4Close(f, 0); return false; } // Found audio track. Get audio data: - avg_bytes_per_sec = MP4GetTrackBitRate(f, audioTrack); - channels = MP4GetTrackAudioChannels(f, audioTrack); + avg_bytes_per_sec = dlmp4.MP4GetTrackBitRate(f, audioTrack); + channels = dlmp4.MP4GetTrackAudioChannels(f, audioTrack); - MP4Duration trackDuration = MP4GetTrackDuration(f, audioTrack); - ext_time_length = (unsigned)MP4ConvertFromTrackDuration(f, audioTrack, trackDuration, - MP4_MSECS_TIME_SCALE); + MP4Duration trackDuration = dlmp4.MP4GetTrackDuration(f, audioTrack); + ext_time_length = (unsigned)dlmp4.MP4ConvertFromTrackDuration(f, audioTrack, trackDuration, + MP4_MSECS_TIME_SCALE); time_length = ext_time_length / 1000; - samples_per_sec = MP4GetTrackTimeScale(f, audioTrack); + samples_per_sec = dlmp4.MP4GetTrackTimeScale(f, audioTrack); bits_per_sample = 16; data_start = 0; - sample_length = MP4GetTrackNumberOfSamples(f, audioTrack); + sample_length = dlmp4.MP4GetTrackNumberOfSamples(f, audioTrack); data_length = sample_length * 2 * channels; data_chunk = true; format_chunk = true; @@ -386,8 +368,8 @@ bool RDWaveFile::openWave(RDWaveData *data) if(wave_data) { - const MP4Tags* tags = MP4TagsAlloc(); - MP4TagsFetch(tags, f); + const MP4Tags* tags = dlmp4.MP4TagsAlloc(); + dlmp4.MP4TagsFetch(tags, f); wave_data->setMetadataFound(true); @@ -400,11 +382,11 @@ bool RDWaveFile::openWave(RDWaveData *data) if(tags->album) wave_data->setAlbum(tags->album); - MP4TagsFree(tags); + dlmp4.MP4TagsFree(tags); } - MP4Close(f); + dlmp4.MP4Close(f, 0); return true; @@ -2308,11 +2290,13 @@ bool RDWaveFile::IsAiff(int fd) bool RDWaveFile::IsM4A(int fd) { -#ifdef HAVE_MP4V2 - MP4FileHandle f = MP4Read(getName()); +#ifdef HAVE_MP4_LIBS + if(!dlmp4.load()) + return false; + MP4FileHandle f = dlmp4.MP4Read(getName()); bool ret = f != MP4_INVALID_FILE_HANDLE; if(ret) - MP4Close(f); + dlmp4.MP4Close(f, 0); return ret; #else return false; diff --git a/lib/rdwavefile.h b/lib/rdwavefile.h index c4a632fc..1a67b194 100644 --- a/lib/rdwavefile.h +++ b/lib/rdwavefile.h @@ -1241,6 +1241,10 @@ class RDWaveFile ogg_page ogg_pg; ogg_packet ogg_pack; #endif // HAVE_VORBIS +#ifdef HAVE_MP4_LIBS + DLMP4 dlmp4; +#endif + }; From 988e9a73fe4ccce76a7b5e3f2a67a61861f775f7 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Sun, 21 Dec 2014 21:13:29 +0000 Subject: [PATCH 03/34] Fix compile bugs, and avoid defining "LC" (from neaacdec.h) since that clashes with a Rivendell internal symbol. --- lib/rdaudioconvert.cpp | 42 +++++++++++++++++++++++------------------- lib/rdaudioconvert.h | 3 +++ lib/rdmp4.cpp | 2 ++ lib/rdmp4.h | 6 ++++-- lib/rdwavefile.cpp | 3 ++- lib/rdwavefile.h | 2 ++ 6 files changed, 36 insertions(+), 22 deletions(-) diff --git a/lib/rdaudioconvert.cpp b/lib/rdaudioconvert.cpp index 98dd2324..b2a59a44 100644 --- a/lib/rdaudioconvert.cpp +++ b/lib/rdaudioconvert.cpp @@ -691,22 +691,31 @@ RDAudioConvert::ErrorCode RDAudioConvert::Stage1M4A(const QString &dstfile, #ifdef HAVE_MP4_LIBS SNDFILE *sf_dst=NULL; SF_INFO sf_dst_info; - int ret = RDAudioConvert::ErrorOk; + MP4FileHandle f; + MP4TrackId audioTrack; + MP4SampleId firstSample, lastSample; + uint32_t aacBufSize, aacConfigSize; + uint8_t *aacBuf, *aacConfigBuffer; + NeAACDecHandle hDecoder; + NeAACDecConfigurationPtr config; + unsigned long foundSampleRate; + unsigned char foundChannels; + RDAudioConvert::ErrorCode ret = RDAudioConvert::ErrorOk; - if(!LoadMP4Libs()) { + if(!dlmp4.load()) { return RDAudioConvert::ErrorFormatNotSupported; } // // Open source // - MP4FileHandle f = dlmp4.MP4Read(getName()); + f = dlmp4.MP4Read(wave->getName()); if(f == MP4_INVALID_FILE_HANDLE) return RDAudioConvert::ErrorNoSource; - MP4TrackId audioTrack = dlmp4.getMP4AACTrack(f); - MP4SampleId firstSample = 0; - MP4SampleId lastSample = dlmp4.MP4GetTrackNumberOfSamples(f, audioTrack) - 1; + audioTrack = dlmp4.getMP4AACTrack(f); + firstSample = 0; + lastSample = dlmp4.MP4GetTrackNumberOfSamples(f, audioTrack) - 1; if(conv_start_point > 0) { double startsecs = ((double)conv_start_point) / 1000; @@ -731,17 +740,14 @@ RDAudioConvert::ErrorCode RDAudioConvert::Stage1M4A(const QString &dstfile, } - uint32_t aacBufSize = dlmp4.MP4GetTrackMaxSampleSize(f, audioTrack); - uint8_t* aacBuf = malloc(aacBufSize); + aacBufSize = dlmp4.MP4GetTrackMaxSampleSize(f, audioTrack); + aacBuf = (uint8_t*)malloc(aacBufSize); if(!aacBufSize || !aacBuf) { // Probably the source's fault for specifying a massive buffer. ret = RDAudioConvert::ErrorInvalidSource; goto out_mp4; } - uint8_t* aacConfigBuffer; - uint32_t* aacConfigSize; - dlmp4.MP4GetTrackESConfiguration(f, audioTrack, &aacConfigBuffer, &aacConfigSize); if(!aacConfigBuffer) { ret = RDAudioConvert::ErrorInvalidSource; @@ -765,9 +771,9 @@ RDAudioConvert::ErrorCode RDAudioConvert::Stage1M4A(const QString &dstfile, // // Initialize Decoder // - NeAACDecHandle hDecoder = dlmp4.NeAACDecOpen(); + hDecoder = dlmp4.NeAACDecOpen(); - NeAACDecConfigurationPtr config = dlmp4.NeAACDecGetCurrentConfiguration(hDecoder); + config = dlmp4.NeAACDecGetCurrentConfiguration(hDecoder); config->outputFormat = FAAD_FMT_FLOAT; config->downMatrix = 1; // Downmix >2 channels to stereo. if(!dlmp4.NeAACDecSetConfiguration(hDecoder, config)) { @@ -775,15 +781,13 @@ RDAudioConvert::ErrorCode RDAudioConvert::Stage1M4A(const QString &dstfile, goto out_decoder; } - unsigned long foundSampleRate; - unsigned char foundChannels; if(dlmp4.NeAACDecInit2(hDecoder, aacConfigBuffer, aacConfigSize, &foundSampleRate, &foundChannels) < 0) { ret = RDAudioConvert::ErrorInvalidSource; goto out_decoder; } if(foundSampleRate != wave->getSamplesPerSec() || foundChannels != wave->getChannels()) { - fprintf(stderr, "M4A header information inconsistent with actual file? Header: %lu/%u; file: %lu/%u\n", + fprintf(stderr, "M4A header information inconsistent with actual file? Header: %u/%u; file: %lu/%u\n", wave->getSamplesPerSec(), (unsigned)wave->getChannels(), foundSampleRate, (unsigned)foundChannels); ret = RDAudioConvert::ErrorInvalidSource; goto out_decoder; @@ -809,9 +813,9 @@ RDAudioConvert::ErrorCode RDAudioConvert::Stage1M4A(const QString &dstfile, break; } - UpdatePeak(sample_buffer, frameInfo.samples); + UpdatePeak((const float*)sample_buffer, frameInfo.samples); - if(sf_write_float(dst_sf, sample_buffer, frameInfo.samples) != frameInfo.samples) { + if(sf_write_float(sf_dst, (const float*)sample_buffer, frameInfo.samples) != (sf_count_t)frameInfo.samples) { ret = RDAudioConvert::ErrorInternal; break; } @@ -824,7 +828,7 @@ RDAudioConvert::ErrorCode RDAudioConvert::Stage1M4A(const QString &dstfile, out_decoder: dlmp4.NeAACDecClose(hDecoder); - out_sf: + // out_sf: sf_close(sf_dst); out_mp4_configbuf: free(aacConfigBuffer); diff --git a/lib/rdaudioconvert.h b/lib/rdaudioconvert.h index e01df514..bce0a39d 100644 --- a/lib/rdaudioconvert.h +++ b/lib/rdaudioconvert.h @@ -33,6 +33,9 @@ #ifdef HAVE_MAD #include #endif // HAVE_MAD + +#include + #include #include diff --git a/lib/rdmp4.cpp b/lib/rdmp4.cpp index a1986472..5779de30 100644 --- a/lib/rdmp4.cpp +++ b/lib/rdmp4.cpp @@ -23,6 +23,7 @@ #include #include +#include MP4TrackId DLMP4::getMP4AACTrack(MP4FileHandle f) { @@ -98,6 +99,7 @@ bool DLMP4::load() check_dlsym(this->NeAACDecClose, neaac_handle, "NeAACDecClose"); loadSuccess = true; + return true; } diff --git a/lib/rdmp4.h b/lib/rdmp4.h index ebdb3bdc..7ebf1901 100644 --- a/lib/rdmp4.h +++ b/lib/rdmp4.h @@ -25,13 +25,15 @@ #include #include +// neaacdec.h defines "LC", as in "low-complexity AAC", which clashes with a Rivendell Command. +#undef LC struct DLMP4 { DLMP4() : loadSuccess(false) {} - void *conv_neaac_handle; - void *conv_mp4_handle; + void *neaac_handle; + void *mp4_handle; bool loadSuccess; // MP4v2 Functions diff --git a/lib/rdwavefile.cpp b/lib/rdwavefile.cpp index d1c2c869..6d5244d8 100644 --- a/lib/rdwavefile.cpp +++ b/lib/rdwavefile.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -3861,7 +3862,7 @@ bool RDWaveFile::GetFlacStreamInfo() void RDWaveFile::ReadFlacMetadata() { -#ifdef HAVE_FLAC_METADATA +#ifdef HAVE_FLAC QString artist; QString composer; FLAC__StreamMetadata* tags; diff --git a/lib/rdwavefile.h b/lib/rdwavefile.h index 1a67b194..046981d3 100644 --- a/lib/rdwavefile.h +++ b/lib/rdwavefile.h @@ -40,6 +40,8 @@ #include #endif // HAVE_VORBIS +#include + #include #include #include From 5d5f2e77ca41058d90a0cb14ccc11fe8b14b012c Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Sun, 21 Dec 2014 23:23:38 +0000 Subject: [PATCH 04/34] Fix: use full type for MP4GetNumberOfTracks (including optional params) --- lib/rdmp4.cpp | 2 +- lib/rdmp4.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rdmp4.cpp b/lib/rdmp4.cpp index 5779de30..b3fa97a1 100644 --- a/lib/rdmp4.cpp +++ b/lib/rdmp4.cpp @@ -28,7 +28,7 @@ MP4TrackId DLMP4::getMP4AACTrack(MP4FileHandle f) { - uint32_t nTracks = this->MP4GetNumberOfTracks(f); + uint32_t nTracks = this->MP4GetNumberOfTracks(f, NULL, 0); for(uint32_t trackIndex = 0; trackIndex < nTracks; ++trackIndex) { diff --git a/lib/rdmp4.h b/lib/rdmp4.h index 7ebf1901..abdf016d 100644 --- a/lib/rdmp4.h +++ b/lib/rdmp4.h @@ -61,7 +61,7 @@ DLMP4() : loadSuccess(false) {} MP4Duration duration, uint32_t timeScale); uint32_t (*MP4GetTrackTimeScale) (MP4FileHandle hFile, MP4TrackId trackId); - uint32_t (*MP4GetNumberOfTracks) (MP4FileHandle hFile); + uint32_t (*MP4GetNumberOfTracks) (MP4FileHandle hFile, const char* type, uint8_t subType); MP4TrackId (*MP4FindTrackId) (MP4FileHandle hFile, uint32_t trackIdx); const char* (*MP4GetTrackType) (MP4FileHandle hFile, MP4TrackId); const char* (*MP4GetTrackMediaDataName) (MP4FileHandle hFile, MP4TrackId); From b90670dd2ddb455ce1325bcdd9073af725bf2a7e Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Sun, 21 Dec 2014 23:46:45 +0000 Subject: [PATCH 05/34] Fix: mp4v2 samples start at 1, not 0 --- lib/rdaudioconvert.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rdaudioconvert.cpp b/lib/rdaudioconvert.cpp index b2a59a44..84719f7b 100644 --- a/lib/rdaudioconvert.cpp +++ b/lib/rdaudioconvert.cpp @@ -714,8 +714,8 @@ RDAudioConvert::ErrorCode RDAudioConvert::Stage1M4A(const QString &dstfile, return RDAudioConvert::ErrorNoSource; audioTrack = dlmp4.getMP4AACTrack(f); - firstSample = 0; - lastSample = dlmp4.MP4GetTrackNumberOfSamples(f, audioTrack) - 1; + firstSample = 1; + lastSample = dlmp4.MP4GetTrackNumberOfSamples(f, audioTrack); if(conv_start_point > 0) { double startsecs = ((double)conv_start_point) / 1000; From cff4c44815ae36e07e1c9c79e6000570c90af09b Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 22 Dec 2014 00:25:20 +0000 Subject: [PATCH 06/34] Back out unrelated FLAC fix --- lib/rdwavefile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rdwavefile.cpp b/lib/rdwavefile.cpp index 6d5244d8..2004c9f9 100644 --- a/lib/rdwavefile.cpp +++ b/lib/rdwavefile.cpp @@ -3862,7 +3862,7 @@ bool RDWaveFile::GetFlacStreamInfo() void RDWaveFile::ReadFlacMetadata() { -#ifdef HAVE_FLAC +#ifdef HAVE_FLAC_METADATA QString artist; QString composer; FLAC__StreamMetadata* tags; From 18ebe71246ec327523556b527687d618b8f74798 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Wed, 25 Feb 2015 10:51:27 -0500 Subject: [PATCH 07/34] 2015-02-25 Fred Gleason * Updated 'conf/rlm_padpoint.conf' to reflect new 'standard' port value. --- ChangeLog | 3 +++ conf/rlm_padpoint.conf | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 40d7694e..bb3ea2c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14794,3 +14794,6 @@ 2015-02-24 Fred Gleason * Updated 'NEWS'. * Incremented the package version to 2.10.3. +2015-02-25 Fred Gleason + * Updated 'conf/rlm_padpoint.conf' to reflect new 'standard' port + value. diff --git a/conf/rlm_padpoint.conf b/conf/rlm_padpoint.conf index df3007f3..375d7306 100644 --- a/conf/rlm_padpoint.conf +++ b/conf/rlm_padpoint.conf @@ -17,12 +17,12 @@ ; IP Address ; ; The IP address of the remote PadPoint UDP port, in dotted-quad notation. -IpAddress=192.168.10.30 +IpAddress=127.0.0.1 ; UDP Port ; ; The UDP port number of the remote PadPoint UDP port, in the range 0 - 65,535. -UdpPort=1234 +UdpPort=3355 ; Log Selection ; From d44a6686bcf9edabdf1d2ef6a70dd45ca8ac4e38 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Fri, 27 Feb 2015 14:31:36 -0500 Subject: [PATCH 08/34] Removed debugging printfs --- rdairplay/log_play.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rdairplay/log_play.cpp b/rdairplay/log_play.cpp index f9e31bb6..f2e5aab2 100644 --- a/rdairplay/log_play.cpp +++ b/rdairplay/log_play.cpp @@ -1445,9 +1445,9 @@ void LogPlay::graceTimerData() void LogPlay::playStateChangedData(int id,RDPlayDeck::State state) { - //#ifdef SHOW_SLOTS +#ifdef SHOW_SLOTS printf("playStateChangedData(%d,%d), log: %s\n",id,state,(const char *)logName()); - //#endif +#endif switch(state) { case RDPlayDeck::Playing: Playing(id); @@ -1842,11 +1842,11 @@ bool LogPlay::StartEvent(int line,RDLogLine::TransType trans_type, rdevent_player-> exec(logline->resolveWildcards(play_start_rml[aport])); } - + /* printf("channelStarted(%d,%d,%d,%d)\n", play_id,playdeck->channel(), playdeck->card(),playdeck->port()); - + */ emit channelStarted(play_id,playdeck->channel(), playdeck->card(),playdeck->port()); LogLine(RDConfig::LogInfo,QString().sprintf( @@ -2757,12 +2757,12 @@ void LogPlay::ClearChannel(int deckid) if(play_deck[deckid]->channel()>=0) { rdevent_player->exec(play_stop_rml[play_deck[deckid]->channel()]); - + /* printf("Deck: %d channelStopped(%d,%d,%d,%d\n",deckid, play_id,play_deck[deckid]->channel(), play_deck[deckid]->card(), play_deck[deckid]->port()); - + */ emit channelStopped(play_id,play_deck[deckid]->channel(), play_deck[deckid]->card(), play_deck[deckid]->port()); From d1962d1c4f3839be93445034e3d838682dbc9c93 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Fri, 27 Feb 2015 14:55:17 -0500 Subject: [PATCH 09/34] 2015-02-27 Fred Gleason * Renamed the 'SAS User Serial Interface' driver to 'SAS USI (3 digit)'. --- ChangeLog | 3 ++ docs/SWITCHERS.txt | 6 ++-- lib/rdmatrix.cpp | 4 +-- lib/rdmatrix.h | 8 ++--- rdadmin/list_endpoints.cpp | 2 +- ripcd/Makefile.am | 4 +-- ripcd/loaddrivers.cpp | 6 ++-- ripcd/{sasusi.cpp => sasusi3digit.cpp} | 50 +++++++++++++------------- ripcd/{sasusi.h => sasusi3digit.h} | 24 ++++++------- 9 files changed, 53 insertions(+), 54 deletions(-) rename ripcd/{sasusi.cpp => sasusi3digit.cpp} (93%) rename ripcd/{sasusi.h => sasusi3digit.h} (79%) diff --git a/ChangeLog b/ChangeLog index bb3ea2c3..6069db0c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14797,3 +14797,6 @@ 2015-02-25 Fred Gleason * Updated 'conf/rlm_padpoint.conf' to reflect new 'standard' port value. +2015-02-27 Fred Gleason + * Renamed the 'SAS User Serial Interface' driver to + 'SAS USI (3 digit)'. diff --git a/docs/SWITCHERS.txt b/docs/SWITCHERS.txt index 9538d4c8..ba7efebc 100644 --- a/docs/SWITCHERS.txt +++ b/docs/SWITCHERS.txt @@ -25,7 +25,7 @@ Quartz Electronics Type 1 Routing Protocol Serial Port Modem Control Lines Sierra Automated Systems 32000 Audio Router Sierra Automated Systems 64000 Audio Router -Sierra Automated Systems Universal Serial Interface (USI) +Sierra Automated Systems User Serial Interface (USI) (3 digit) Sine Systems ACU-1 (Prophet version) Software Authority Protocol StarGuide III Satellite Receiver @@ -591,9 +591,9 @@ outputs as well as audio crosspoints. ---------------------------------------------------------------------------- -SIERRA AUTOMATED SYSTEMS Universal Serial Interface (USI) +SIERRA AUTOMATED SYSTEMS User Serial Interface (USI) (3 digit) -Driver Name: SAS User Serial Interface +Driver Name: SAS USI (3 digit) Supported RML Commands: Switch Take ('ST') diff --git a/lib/rdmatrix.cpp b/lib/rdmatrix.cpp index 3b546f82..ab11d2db 100644 --- a/lib/rdmatrix.cpp +++ b/lib/rdmatrix.cpp @@ -603,8 +603,8 @@ QString RDMatrix::typeString(RDMatrix::Type type) return QString("BroadcastTools ACS 8.2"); break; - case RDMatrix::SasUsi: - return QString("SAS User Serial Interface"); + case RDMatrix::SasUsi3Digit: + return QString("SAS USI (3 digit)"); break; case RDMatrix::Bt16x2: diff --git a/lib/rdmatrix.h b/lib/rdmatrix.h index b9909cbb..7219dfe9 100644 --- a/lib/rdmatrix.h +++ b/lib/rdmatrix.h @@ -33,10 +33,10 @@ class RDMatrix enum PortType {TtyPort=0,TcpPort=1,NoPort=2}; enum Type {LocalGpio=0,GenericGpo=1,GenericSerial=2,Sas32000=3,Sas64000=4, Unity4000=5,BtSs82=6,Bt10x1=7,Sas64000Gpi=8,Bt16x1=9,Bt8x2=10, - BtAcs82=11,SasUsi=12,Bt16x2=13,BtSs124=14,LocalAudioAdapter=15, - LogitekVguest=16,BtSs164=17,StarGuideIII=18,BtSs42=19, - LiveWireLwrpAudio=20,Quartz1=21,BtSs44=22,BtSrc8III=23,BtSrc16=24, - Harlond=25,Acu1p=26,LiveWireMcastGpio=27,Am16=28, + BtAcs82=11,SasUsi3Digit=12,Bt16x2=13,BtSs124=14, + LocalAudioAdapter=15,LogitekVguest=16,BtSs164=17,StarGuideIII=18, + BtSs42=19,LiveWireLwrpAudio=20,Quartz1=21,BtSs44=22,BtSrc8III=23, + BtSrc16=24,Harlond=25,Acu1p=26,LiveWireMcastGpio=27,Am16=28, LiveWireLwrpGpio=29,BtSentinel4Web=30,BtGpi16=31,ModemLines=32, SoftwareAuthority=33,LastType=34}; enum Endpoint {Input=0,Output=1}; diff --git a/rdadmin/list_endpoints.cpp b/rdadmin/list_endpoints.cpp index e8bd12d4..b05f4796 100644 --- a/rdadmin/list_endpoints.cpp +++ b/rdadmin/list_endpoints.cpp @@ -138,7 +138,7 @@ ListEndpoints::ListEndpoints(RDMatrix *matrix,RDMatrix::Endpoint endpoint, list_list_view->setColumnAlignment(3,Qt::AlignHCenter); break; - case RDMatrix::SasUsi: + case RDMatrix::SasUsi3Digit: list_readonly=true; break; diff --git a/ripcd/Makefile.am b/ripcd/Makefile.am index 294912cd..ee2d1619 100644 --- a/ripcd/Makefile.am +++ b/ripcd/Makefile.am @@ -63,7 +63,7 @@ dist_ripcd_SOURCES = acu1p.cpp acu1p.h\ sas32000.cpp sas32000.h\ sas64000.cpp sas64000.h\ sas64000gpi.cpp sas64000gpi.h\ - sasusi.cpp sasusi.h\ + sasusi3digit.cpp sasusi3digit.h\ starguide3.cpp starguide3.h\ starguide_feed.cpp starguide_feed.h\ swauthority.cpp swauthority.h\ @@ -101,7 +101,7 @@ nodist_ripcd_SOURCES = moc_am16.cpp\ moc_sas32000.cpp\ moc_sas64000.cpp\ moc_sas64000gpi.cpp\ - moc_sasusi.cpp\ + moc_sasusi3digit.cpp\ moc_starguide3.cpp\ moc_swauthority.cpp\ moc_switcher.cpp\ diff --git a/ripcd/loaddrivers.cpp b/ripcd/loaddrivers.cpp index 407c88d8..6d60ba53 100644 --- a/ripcd/loaddrivers.cpp +++ b/ripcd/loaddrivers.cpp @@ -52,7 +52,7 @@ #include #include #include -#include +#include #include #include #include @@ -175,8 +175,8 @@ bool MainObject::LoadSwitchDriver(int matrix_num) ripcd_switcher[matrix_num]=new Sas64000Gpi(matrix,this); break; - case RDMatrix::SasUsi: - ripcd_switcher[matrix_num]=new SasUsi(matrix,this); + case RDMatrix::SasUsi3Digit: + ripcd_switcher[matrix_num]=new SasUsi3Digit(matrix,this); break; case RDMatrix::SoftwareAuthority: diff --git a/ripcd/sasusi.cpp b/ripcd/sasusi3digit.cpp similarity index 93% rename from ripcd/sasusi.cpp rename to ripcd/sasusi3digit.cpp index d5847463..b9f7aa30 100644 --- a/ripcd/sasusi.cpp +++ b/ripcd/sasusi3digit.cpp @@ -1,10 +1,8 @@ // sasusi.cpp // -// A Rivendell switcher driver for the SAS User Serial Interface Protocol +// A Rivendell switcher driver for the SAS USI Protocol (3 digit) // -// (C) Copyright 2002-2004 Fred Gleason -// -// $Id: sasusi.cpp,v 1.24 2011/12/28 18:59:19 cvs Exp $ +// (C) Copyright 2002-2015 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 @@ -23,9 +21,9 @@ #include #include #include -#include +#include -SasUsi::SasUsi(RDMatrix *matrix,QObject *parent,const char *name) +SasUsi3Digit::SasUsi3Digit(RDMatrix *matrix,QObject *parent,const char *name) : Switcher(matrix,parent,name) { QString sql; @@ -104,37 +102,37 @@ SasUsi::SasUsi(RDMatrix *matrix,QObject *parent,const char *name) } -RDMatrix::Type SasUsi::type() +RDMatrix::Type SasUsi3Digit::type() { - return RDMatrix::SasUsi; + return RDMatrix::SasUsi3Digit; } -unsigned SasUsi::gpiQuantity() +unsigned SasUsi3Digit::gpiQuantity() { return sas_gpis; } -unsigned SasUsi::gpoQuantity() +unsigned SasUsi3Digit::gpoQuantity() { return sas_gpos; } -bool SasUsi::primaryTtyActive() +bool SasUsi3Digit::primaryTtyActive() { return sas_porttype==RDMatrix::TtyPort; } -bool SasUsi::secondaryTtyActive() +bool SasUsi3Digit::secondaryTtyActive() { return false; } -void SasUsi::processCommand(RDMacro *cmd) +void SasUsi3Digit::processCommand(RDMacro *cmd) { char str[256]; char cmd_byte; @@ -326,13 +324,13 @@ void SasUsi::processCommand(RDMacro *cmd) } -void SasUsi::ipConnect() +void SasUsi3Digit::ipConnect() { sas_socket->connectToHost(sas_ipaddress.toString(),sas_ipport); } -void SasUsi::connectedData() +void SasUsi3Digit::connectedData() { LogLine(RDConfig::LogInfo,QString(). sprintf("Connection to SasUsi device at %s:%d established", @@ -344,7 +342,7 @@ void SasUsi::connectedData() } -void SasUsi::connectionClosedData() +void SasUsi3Digit::connectionClosedData() { LogLine(RDConfig::LogNotice,QString(). sprintf("Connection to SasUsi device at %s:%d closed unexpectedly, attempting reconnect", @@ -353,11 +351,11 @@ void SasUsi::connectionClosedData() if(sas_stop_cart>0) { ExecuteMacroCart(sas_stop_cart); } - sas_reconnect_timer->start(SASUSI_RECONNECT_INTERVAL,true); + sas_reconnect_timer->start(SASUSI3DIGIT_RECONNECT_INTERVAL,true); } -void SasUsi::readyReadData() +void SasUsi3Digit::readyReadData() { char buffer[256]; unsigned n; @@ -371,7 +369,7 @@ void SasUsi::readyReadData() sas_ptr=0; } else { - if(sas_ptr==SASUSI_MAX_LENGTH) { // Buffer overflow + if(sas_ptr==SASUSI3DIGIT_MAX_LENGTH) { // Buffer overflow sas_ptr=0; } sas_buffer[sas_ptr++]=buffer[i]; @@ -381,7 +379,7 @@ void SasUsi::readyReadData() } -void SasUsi::errorData(int err) +void SasUsi3Digit::errorData(int err) { switch((QSocket::Error)err) { case QSocket::ErrConnectionRefused: @@ -389,7 +387,7 @@ void SasUsi::errorData(int err) "Connection to SasUsi device at %s:%d refused, attempting reconnect", (const char *)sas_ipaddress.toString(), sas_ipport)); - sas_reconnect_timer->start(SASUSI_RECONNECT_INTERVAL,true); + sas_reconnect_timer->start(SASUSI3DIGIT_RECONNECT_INTERVAL,true); break; case QSocket::ErrHostNotFound: @@ -409,7 +407,7 @@ void SasUsi::errorData(int err) } -void SasUsi::SendCommand(char *str) +void SasUsi3Digit::SendCommand(char *str) { LogLine(RDConfig::LogDebug,QString().sprintf("sending USI cmd: %s",(const char *)PrettifyCommand(str))); switch(sas_porttype) { @@ -427,9 +425,9 @@ void SasUsi::SendCommand(char *str) } -void SasUsi::DispatchCommand() +void SasUsi3Digit::DispatchCommand() { - char buffer[SASUSI_MAX_LENGTH]; + char buffer[SASUSI3DIGIT_MAX_LENGTH]; unsigned input; unsigned output; int line; @@ -615,7 +613,7 @@ void SasUsi::DispatchCommand() } -void SasUsi::ExecuteMacroCart(unsigned cartnum) +void SasUsi3Digit::ExecuteMacroCart(unsigned cartnum) { RDMacro rml; rml.setRole(RDMacro::Cmd); @@ -628,7 +626,7 @@ void SasUsi::ExecuteMacroCart(unsigned cartnum) } -QString SasUsi::PrettifyCommand(const char *cmd) const +QString SasUsi3Digit::PrettifyCommand(const char *cmd) const { QString ret; if(cmd[0]<26) { diff --git a/ripcd/sasusi.h b/ripcd/sasusi3digit.h similarity index 79% rename from ripcd/sasusi.h rename to ripcd/sasusi3digit.h index 19362bac..413efb49 100644 --- a/ripcd/sasusi.h +++ b/ripcd/sasusi3digit.h @@ -1,10 +1,8 @@ -// sasusi.h +// sasusi3digit.h // -// A Rivendell switcher driver for the SAS User Serial Interface Protocol +// A Rivendell switcher driver for the SAS USI Protocol (3 digit) // -// (C) Copyright 2002-2004 Fred Gleason -// -// $Id: sasusi.h,v 1.16 2011/05/26 21:20:37 cvs Exp $ +// (C) Copyright 2002-2015 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 @@ -20,8 +18,8 @@ // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -#ifndef SASUSI_H -#define SASUSI_H +#ifndef SASUSI3DIGIT_H +#define SASUSI3DIGIT_H #include @@ -36,14 +34,14 @@ #include -#define SASUSI_RECONNECT_INTERVAL 10000 -#define SASUSI_MAX_LENGTH 256 +#define SASUSI3DIGIT_RECONNECT_INTERVAL 10000 +#define SASUSI3DIGIT_MAX_LENGTH 256 -class SasUsi : public Switcher +class SasUsi3Digit : public Switcher { Q_OBJECT public: - SasUsi(RDMatrix *matrix,QObject *parent=0,const char *name=0); + SasUsi3Digit(RDMatrix *matrix,QObject *parent=0,const char *name=0); RDMatrix::Type type(); unsigned gpiQuantity(); unsigned gpoQuantity(); @@ -65,7 +63,7 @@ class SasUsi : public Switcher QString PrettifyCommand(const char *cmd) const; RDTTYDevice *sas_device; QSocket *sas_socket; - char sas_buffer[SASUSI_MAX_LENGTH]; + char sas_buffer[SASUSI3DIGIT_MAX_LENGTH]; unsigned sas_ptr; QHostAddress sas_ipaddress; int sas_matrix; @@ -84,4 +82,4 @@ class SasUsi : public Switcher }; -#endif // SASUSI_H +#endif // SASUSI3DIGIT_H From f9022eb4a7177152899a46156e59b73843c6a071 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Fri, 27 Feb 2015 15:51:09 -0500 Subject: [PATCH 10/34] 2015-02-27 Fred Gleason * Renamed the 'SAS User Serial Interface' driver to 'SAS USI (3 digit)'. * Added an 'SAS USI (2 digit)' swticher driver in 'ripcd/sasusi2digit.cpp' and 'ripcd/sasusi2digit.h'. --- ChangeLog | 2 + docs/SWITCHERS.txt | 20 +++++++ lib/rdmatrix.cpp | 19 ++++-- lib/rdmatrix.h | 2 +- ripcd/Makefile.am | 2 + ripcd/loaddrivers.cpp | 5 ++ ripcd/sasusi2digit.cpp | 132 +++++++++++++++++++++++++++++++++++++++++ ripcd/sasusi2digit.h | 65 ++++++++++++++++++++ ripcd/sasusi3digit.cpp | 2 +- 9 files changed, 241 insertions(+), 8 deletions(-) create mode 100644 ripcd/sasusi2digit.cpp create mode 100644 ripcd/sasusi2digit.h diff --git a/ChangeLog b/ChangeLog index 6069db0c..bc196109 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14800,3 +14800,5 @@ 2015-02-27 Fred Gleason * Renamed the 'SAS User Serial Interface' driver to 'SAS USI (3 digit)'. + * Added an 'SAS USI (2 digit)' swticher driver in + 'ripcd/sasusi2digit.cpp' and 'ripcd/sasusi2digit.h'. diff --git a/docs/SWITCHERS.txt b/docs/SWITCHERS.txt index ba7efebc..ad829406 100644 --- a/docs/SWITCHERS.txt +++ b/docs/SWITCHERS.txt @@ -25,6 +25,7 @@ Quartz Electronics Type 1 Routing Protocol Serial Port Modem Control Lines Sierra Automated Systems 32000 Audio Router Sierra Automated Systems 64000 Audio Router +Sierra Automated Systems User Serial Interface (USI) (2 digit) Sierra Automated Systems User Serial Interface (USI) (3 digit) Sine Systems ACU-1 (Prophet version) Software Authority Protocol @@ -590,6 +591,25 @@ and no terminator. This driver allows control of the system's GPO outputs as well as audio crosspoints. +---------------------------------------------------------------------------- +SIERRA AUTOMATED SYSTEMS User Serial Interface (USI) (2 digit) + +Driver Name: SAS USI (2 digit) + +Supported RML Commands: + Switch Take ('ST') + +GENERAL NOTES: +Control can done by means of an RS-232C connection to the 'User Serial +Interface' port on the unit. Serial port parameters should be: + +Baud Rate: 9600 +Parity: None +Data Bits: 8 +Stop Bits: 1 +Terminator: None + + ---------------------------------------------------------------------------- SIERRA AUTOMATED SYSTEMS User Serial Interface (USI) (3 digit) diff --git a/lib/rdmatrix.cpp b/lib/rdmatrix.cpp index ab11d2db..4e33105c 100644 --- a/lib/rdmatrix.cpp +++ b/lib/rdmatrix.cpp @@ -43,7 +43,7 @@ bool __mx_primary_controls[RDMatrix::LastType][RDMatrix::LastControl]= {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0}, // BT 16x1 {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0}, // BT 8x2 {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0}, // BT ACS 8.2 - {1,1,1,1,0,0,1,1,0,0,0,1,1,1,1,0,1,1,1,1,0,0,0,1,1,0,0,0,0}, // SAS USI + {1,1,1,1,0,0,1,1,0,0,0,1,1,1,1,0,1,1,1,1,0,0,0,1,1,0,0,0,0}, // SAS USI 3 {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0}, // BT 16x2 {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0}, // BT SS 12.4 {0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0}, // Local Adapter @@ -64,7 +64,8 @@ bool __mx_primary_controls[RDMatrix::LastType][RDMatrix::LastControl]= {0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0}, // BT Sentinel 4 Web {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}, // BT GPI-16 {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}, // Modem Lines - {0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0} // Software Authority + {0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0}, // Software Authority + {0,1,1,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,1,0,0,0,0} // SAS USI 2 }; bool __mx_backup_controls[RDMatrix::LastType][RDMatrix::LastControl]= { @@ -82,7 +83,7 @@ bool __mx_backup_controls[RDMatrix::LastType][RDMatrix::LastControl]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT 16x1 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT 8x2 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT ACS 8.2 - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // SAS USI + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // SAS USI 3 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT 16x2 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT SS 12.4 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Local Adapter @@ -103,7 +104,8 @@ bool __mx_backup_controls[RDMatrix::LastType][RDMatrix::LastControl]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT Sentinel 4 Web {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT GPI-16 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Modem Lines - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // Software Authority + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Software Authority + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // SAS USI 2 }; int __mx_default_values[RDMatrix::LastType][RDMatrix::LastControl]= @@ -122,7 +124,7 @@ int __mx_default_values[RDMatrix::LastType][RDMatrix::LastControl]= {0,0,0,0,0,0,0,0,0,0,0,16,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT 16x1 {0,0,0,0,0,0,0,0,0,0,0,8,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT 8x2 {0,0,0,0,0,0,0,0,0,0,0,8,2,16,16,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT ACS 8.2 - {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // SAS USI + {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // SAS USI 3 {0,0,0,0,0,0,0,0,0,0,0,16,2,16,16,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT 16x2 {0,0,0,0,0,0,0,0,0,0,0,12,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT SS 12.4 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // Local Adapter @@ -143,7 +145,8 @@ int __mx_default_values[RDMatrix::LastType][RDMatrix::LastControl]= {1,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT Sentinel 4 Web {0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT GPI-16 {0,0,0,0,0,0,0,0,0,0,0,0,0,4,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // Modem Lines - {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0} // Software Authority + {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // Software Authority + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0} // SAS USI 2 }; RDMatrix::RDMatrix(const QString &station,int matrix) @@ -603,6 +606,10 @@ QString RDMatrix::typeString(RDMatrix::Type type) return QString("BroadcastTools ACS 8.2"); break; + case RDMatrix::SasUsi2Digit: + return QString("SAS USI (2 digit)"); + break; + case RDMatrix::SasUsi3Digit: return QString("SAS USI (3 digit)"); break; diff --git a/lib/rdmatrix.h b/lib/rdmatrix.h index 7219dfe9..d77c0306 100644 --- a/lib/rdmatrix.h +++ b/lib/rdmatrix.h @@ -38,7 +38,7 @@ class RDMatrix BtSs42=19,LiveWireLwrpAudio=20,Quartz1=21,BtSs44=22,BtSrc8III=23, BtSrc16=24,Harlond=25,Acu1p=26,LiveWireMcastGpio=27,Am16=28, LiveWireLwrpGpio=29,BtSentinel4Web=30,BtGpi16=31,ModemLines=32, - SoftwareAuthority=33,LastType=34}; + SoftwareAuthority=33,SasUsi2Digit=34,LastType=35}; enum Endpoint {Input=0,Output=1}; enum Mode {Stereo=0,Left=1,Right=2}; enum VguestAttribute {VguestEngine=0,VguestDevice=1,VguestSurface=2, diff --git a/ripcd/Makefile.am b/ripcd/Makefile.am index ee2d1619..c551c52a 100644 --- a/ripcd/Makefile.am +++ b/ripcd/Makefile.am @@ -63,6 +63,7 @@ dist_ripcd_SOURCES = acu1p.cpp acu1p.h\ sas32000.cpp sas32000.h\ sas64000.cpp sas64000.h\ sas64000gpi.cpp sas64000gpi.h\ + sasusi2digit.cpp sasusi2digit.h\ sasusi3digit.cpp sasusi3digit.h\ starguide3.cpp starguide3.h\ starguide_feed.cpp starguide_feed.h\ @@ -101,6 +102,7 @@ nodist_ripcd_SOURCES = moc_am16.cpp\ moc_sas32000.cpp\ moc_sas64000.cpp\ moc_sas64000gpi.cpp\ + moc_sasusi2digit.cpp\ moc_sasusi3digit.cpp\ moc_starguide3.cpp\ moc_swauthority.cpp\ diff --git a/ripcd/loaddrivers.cpp b/ripcd/loaddrivers.cpp index 6d60ba53..3b9b635e 100644 --- a/ripcd/loaddrivers.cpp +++ b/ripcd/loaddrivers.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -175,6 +176,10 @@ bool MainObject::LoadSwitchDriver(int matrix_num) ripcd_switcher[matrix_num]=new Sas64000Gpi(matrix,this); break; + case RDMatrix::SasUsi2Digit: + ripcd_switcher[matrix_num]=new SasUsi2Digit(matrix,this); + break; + case RDMatrix::SasUsi3Digit: ripcd_switcher[matrix_num]=new SasUsi3Digit(matrix,this); break; diff --git a/ripcd/sasusi2digit.cpp b/ripcd/sasusi2digit.cpp new file mode 100644 index 00000000..0289abe5 --- /dev/null +++ b/ripcd/sasusi2digit.cpp @@ -0,0 +1,132 @@ +// sasusi2digit.cpp +// +// A Rivendell switcher driver for the SAS USI Protocol (2 digit) +// +// (C) Copyright 2002-2015 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 + +SasUsi2Digit::SasUsi2Digit(RDMatrix *matrix,QObject *parent,const char *name) + : Switcher(matrix,parent,name) +{ + RDTty *tty; + sas_matrix=matrix->matrix(); + sas_ptr=0; + + // + // Get Matrix Parameters + // + sas_inputs=matrix->inputs(); + sas_outputs=matrix->outputs(); + sas_gpis=matrix->gpis(); + sas_gpos=matrix->gpos(); + + // + // Initialize the connection + // + tty=new RDTty(rdstation->name(),matrix->port(RDMatrix::Primary)); + sas_device=new RDTTYDevice(); + if(tty->active()) { + sas_device->setName(tty->port()); + sas_device->setSpeed(tty->baudRate()); + sas_device->setWordLength(tty->dataBits()); + sas_device->setParity(tty->parity()); + sas_device->open(IO_Raw|IO_ReadWrite); + } + delete tty; +} + + +RDMatrix::Type SasUsi2Digit::type() +{ + return RDMatrix::SasUsi2Digit; +} + + +unsigned SasUsi2Digit::gpiQuantity() +{ + return sas_gpis; +} + + +unsigned SasUsi2Digit::gpoQuantity() +{ + return sas_gpos; +} + + +bool SasUsi2Digit::primaryTtyActive() +{ + return true; +} + + +bool SasUsi2Digit::secondaryTtyActive() +{ + return false; +} + + +void SasUsi2Digit::processCommand(RDMacro *cmd) +{ + char str[256]; + + switch(cmd->command()) { + case RDMacro::ST: + if((cmd->arg(1).toInt()<0)||(cmd->arg(1).toInt()>sas_inputs)|| + (cmd->arg(2).toInt()<1)||(cmd->arg(2).toInt()>sas_outputs)) { + cmd->acknowledge(false); + emit rmlEcho(cmd); + return; + } + snprintf(str,256,"%c%02d%02d\x0D\x0A",20, + cmd->arg(1).toInt(),cmd->arg(2).toInt()); + SendCommand(str); + cmd->acknowledge(true); + emit rmlEcho(cmd); + break; + + default: + cmd->acknowledge(false); + emit rmlEcho(cmd); + break; + } +} + + +void SasUsi2Digit::SendCommand(char *str) +{ + LogLine(RDConfig::LogDebug,QString().sprintf("sending USI cmd: %s",(const char *)PrettifyCommand(str))); + + sas_device->writeBlock(str,strlen(str)); +} + + +QString SasUsi2Digit::PrettifyCommand(const char *cmd) const +{ + QString ret; + if(cmd[0]<26) { + ret=QString().sprintf("^%c%s",'@'+cmd[0],cmd+1); + } + else { + ret=cmd; + } + return ret; +} diff --git a/ripcd/sasusi2digit.h b/ripcd/sasusi2digit.h new file mode 100644 index 00000000..fc9cc879 --- /dev/null +++ b/ripcd/sasusi2digit.h @@ -0,0 +1,65 @@ +// sasusi2digit.h +// +// A Rivendell switcher driver for the SAS USI Protocol (2 digit) +// +// (C) Copyright 2002-2015 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 SASUSI2DIGIT_H +#define SASUSI2DIGIT_H + +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#define SASUSI2DIGIT_MAX_LENGTH 256 + +class SasUsi2Digit : public Switcher +{ + Q_OBJECT + public: + SasUsi2Digit(RDMatrix *matrix,QObject *parent=0,const char *name=0); + RDMatrix::Type type(); + unsigned gpiQuantity(); + unsigned gpoQuantity(); + bool primaryTtyActive(); + bool secondaryTtyActive(); + void processCommand(RDMacro *cmd); + + private: + void SendCommand(char *str); + QString PrettifyCommand(const char *cmd) const; + RDTTYDevice *sas_device; + char sas_buffer[SASUSI2DIGIT_MAX_LENGTH]; + unsigned sas_ptr; + int sas_matrix; + int sas_ipport; + int sas_inputs; + int sas_outputs; + int sas_gpis; + int sas_gpos; +}; + + +#endif // SASUSI2DIGIT_H diff --git a/ripcd/sasusi3digit.cpp b/ripcd/sasusi3digit.cpp index b9f7aa30..f8bd9103 100644 --- a/ripcd/sasusi3digit.cpp +++ b/ripcd/sasusi3digit.cpp @@ -1,4 +1,4 @@ -// sasusi.cpp +// sasusi3digit.cpp // // A Rivendell switcher driver for the SAS USI Protocol (3 digit) // From dc9375c1d531a3b2fb2ac2a3fee376ae99d404cb Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Wed, 4 Mar 2015 15:21:42 -0500 Subject: [PATCH 11/34] 2015-03-04 Fred Gleason * Added support for 'scp' and 'sftp' protocols in 'rdcatch/edit_upload.cpp'. * Added support for 'scp' and 'sftp' protocols in 'rdcatch/edit_download.cpp'. --- ChangeLog | 5 +++++ rdcatch/edit_download.cpp | 5 +++-- rdcatch/edit_upload.cpp | 6 ++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index bc196109..40ea8d15 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14802,3 +14802,8 @@ 'SAS USI (3 digit)'. * Added an 'SAS USI (2 digit)' swticher driver in 'ripcd/sasusi2digit.cpp' and 'ripcd/sasusi2digit.h'. +2015-03-04 Fred Gleason + * Added support for 'scp' and 'sftp' protocols in + 'rdcatch/edit_upload.cpp'. + * Added support for 'scp' and 'sftp' protocols in + 'rdcatch/edit_download.cpp'. diff --git a/rdcatch/edit_download.cpp b/rdcatch/edit_download.cpp index 2d5ea1a5..a478b779 100644 --- a/rdcatch/edit_download.cpp +++ b/rdcatch/edit_download.cpp @@ -481,7 +481,8 @@ void EditDownload::urlChangedData(const QString &str) { QUrl url(str); QString protocol=url.protocol(); - if((protocol=="ftp")||(protocol=="http")||(protocol=="file")) { + if((protocol=="ftp")||(protocol=="http")||(protocol=="file")|| + (protocol=="scp")||(protocol=="sftp")) { edit_username_label->setEnabled(true); edit_username_edit->setEnabled(true); edit_password_label->setEnabled(true); @@ -556,7 +557,7 @@ void EditDownload::okData() RDUrl url(edit_url_edit->text()); QString protocol=url.protocol(); if((protocol!="ftp")&&(protocol!="http")&&(protocol!="https")&& - (protocol!="file")) { + (protocol!="file")&&(protocol!="scp")&&(protocol!="sftp")) { QMessageBox::warning(this, tr("Invalid URL"),tr("Unsupported URL protocol!")); return; diff --git a/rdcatch/edit_upload.cpp b/rdcatch/edit_upload.cpp index 820a7336..b26c1a27 100644 --- a/rdcatch/edit_upload.cpp +++ b/rdcatch/edit_upload.cpp @@ -495,7 +495,8 @@ void EditUpload::urlChangedData(const QString &str) { QUrl url(str); QString protocol=url.protocol().lower(); - if((protocol=="ftp")||(protocol=="file")) { + if((protocol=="ftp")||(protocol=="file")|| + (protocol=="scp")||(protocol=="sftp")) { edit_username_label->setEnabled(true); edit_username_edit->setEnabled(true); edit_password_label->setEnabled(true); @@ -577,7 +578,8 @@ void EditUpload::okData() } RDUrl url(edit_url_edit->text()); QString protocol=url.protocol(); - if((protocol!="ftp")&&(protocol!="file")) { + if((protocol!="ftp")&&(protocol!="file")&& + (protocol!="scp")&&(protocol!="sftp")) { QMessageBox::warning(this, tr("Invalid URL"),tr("Unsupported URL protocol!")); return; From bec97fb02dc886631f33b78f1bee61aa11687340 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Wed, 4 Mar 2015 15:26:59 -0500 Subject: [PATCH 12/34] 2015-03-04 Fred Gleason * Incremented the package version to 2.10.3int00. --- ChangeLog | 2 ++ PACKAGE_VERSION | 2 +- rivendell.ism | Bin 499284 -> 499284 bytes 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 40ea8d15..78f0672e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14807,3 +14807,5 @@ 'rdcatch/edit_upload.cpp'. * Added support for 'scp' and 'sftp' protocols in 'rdcatch/edit_download.cpp'. +2015-03-04 Fred Gleason + * Incremented the package version to 2.10.3int00. diff --git a/PACKAGE_VERSION b/PACKAGE_VERSION index fe182499..16fef5c1 100644 --- a/PACKAGE_VERSION +++ b/PACKAGE_VERSION @@ -1 +1 @@ -2.10.3 \ No newline at end of file +2.10.3int00 \ No newline at end of file diff --git a/rivendell.ism b/rivendell.ism index df0880c4386de86428c15d5c50d7eeb259b0ed13..2c492d551fe815d1c88e95792170711ff10de354 100755 GIT binary patch delta 16972 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 hirQ`6Nf{vYR(htXBHgCv91)20#;O1 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 From a8b8e5e6c881f61f284176f652cba7e1b76e0129 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Thu, 5 Mar 2015 12:41:15 -0500 Subject: [PATCH 13/34] 2015-03-04 Fred Gleason * Renamed the 'SAS USI (3 digit)' driver to 'SAS User Serial Interface'. * Renamed the 'SAS USI (2 digit)' driver to 'SAS 16000(D)'. --- ripcd/{sasusi2digit.cpp => sas16000.cpp} | 0 ripcd/{sasusi2digit.h => sas16000.h} | 0 ripcd/{sasusi3digit.cpp => sasusi.cpp} | 0 ripcd/{sasusi3digit.h => sasusi.h} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename ripcd/{sasusi2digit.cpp => sas16000.cpp} (100%) rename ripcd/{sasusi2digit.h => sas16000.h} (100%) rename ripcd/{sasusi3digit.cpp => sasusi.cpp} (100%) rename ripcd/{sasusi3digit.h => sasusi.h} (100%) diff --git a/ripcd/sasusi2digit.cpp b/ripcd/sas16000.cpp similarity index 100% rename from ripcd/sasusi2digit.cpp rename to ripcd/sas16000.cpp diff --git a/ripcd/sasusi2digit.h b/ripcd/sas16000.h similarity index 100% rename from ripcd/sasusi2digit.h rename to ripcd/sas16000.h diff --git a/ripcd/sasusi3digit.cpp b/ripcd/sasusi.cpp similarity index 100% rename from ripcd/sasusi3digit.cpp rename to ripcd/sasusi.cpp diff --git a/ripcd/sasusi3digit.h b/ripcd/sasusi.h similarity index 100% rename from ripcd/sasusi3digit.h rename to ripcd/sasusi.h From 5656687db51efcf88a927e38788752e58e488a0a Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Thu, 5 Mar 2015 12:41:31 -0500 Subject: [PATCH 14/34] 2015-03-04 Fred Gleason * Renamed the 'SAS USI (3 digit)' driver to 'SAS User Serial Interface'. * Renamed the 'SAS USI (2 digit)' driver to 'SAS 16000(D)'. --- ChangeLog | 5 ++++ docs/SWITCHERS.txt | 47 +++++++++++++++++++------------------- lib/rdmatrix.cpp | 20 ++++++++-------- lib/rdmatrix.h | 4 ++-- rdadmin/list_endpoints.cpp | 2 +- ripcd/Makefile.am | 8 +++---- ripcd/loaddrivers.cpp | 16 ++++++------- ripcd/sas16000.cpp | 24 +++++++++---------- ripcd/sas16000.h | 18 +++++++-------- ripcd/sasusi.cpp | 46 ++++++++++++++++++------------------- ripcd/sasusi.h | 18 +++++++-------- 11 files changed, 107 insertions(+), 101 deletions(-) diff --git a/ChangeLog b/ChangeLog index 78f0672e..bd3402dc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14809,3 +14809,8 @@ 'rdcatch/edit_download.cpp'. 2015-03-04 Fred Gleason * Incremented the package version to 2.10.3int00. +2015-03-04 Fred Gleason + * Renamed the 'SAS USI (3 digit)' driver to + 'SAS User Serial Interface'. + * Renamed the 'SAS USI (2 digit)' driver to + 'SAS 16000(D)'. diff --git a/docs/SWITCHERS.txt b/docs/SWITCHERS.txt index ad829406..b7a1b8f8 100644 --- a/docs/SWITCHERS.txt +++ b/docs/SWITCHERS.txt @@ -23,10 +23,10 @@ Local Audio Adapter Logitek vGuest Quartz Electronics Type 1 Routing Protocol Serial Port Modem Control Lines +Sierra Automated Systems 16000(D) Audio Router Sierra Automated Systems 32000 Audio Router Sierra Automated Systems 64000 Audio Router -Sierra Automated Systems User Serial Interface (USI) (2 digit) -Sierra Automated Systems User Serial Interface (USI) (3 digit) +Sierra Automated Systems User Serial Interface (USI) Sine Systems ACU-1 (Prophet version) Software Authority Protocol StarGuide III Satellite Receiver @@ -536,6 +536,26 @@ device. The lines map as follows: 2 Ready To Send (RTS) +---------------------------------------------------------------------------- +SIERRA AUTOMATED SYSTEMS 16000(D) AUDIO ROUTER + +Driver Name: SAS 16000(D) + +Supported RML Commands: + Switch Take ('ST') + +GENERAL NOTES: +Both analog and AES3 digital (D) variants are supported. Control can done +by means of an RS-232C connection to the 'User Serial Interface' port on +the unit. Serial port parameters should be: + +Baud Rate: 9600 +Parity: None +Data Bits: 8 +Stop Bits: 1 +Terminator: None + + ---------------------------------------------------------------------------- SIERRA AUTOMATED SYSTEMS 32000 AUDIO ROUTER @@ -592,28 +612,9 @@ outputs as well as audio crosspoints. ---------------------------------------------------------------------------- -SIERRA AUTOMATED SYSTEMS User Serial Interface (USI) (2 digit) +SIERRA AUTOMATED SYSTEMS User Serial Interface (USI) -Driver Name: SAS USI (2 digit) - -Supported RML Commands: - Switch Take ('ST') - -GENERAL NOTES: -Control can done by means of an RS-232C connection to the 'User Serial -Interface' port on the unit. Serial port parameters should be: - -Baud Rate: 9600 -Parity: None -Data Bits: 8 -Stop Bits: 1 -Terminator: None - - ----------------------------------------------------------------------------- -SIERRA AUTOMATED SYSTEMS User Serial Interface (USI) (3 digit) - -Driver Name: SAS USI (3 digit) +Driver Name: SAS USI Supported RML Commands: Switch Take ('ST') diff --git a/lib/rdmatrix.cpp b/lib/rdmatrix.cpp index 4e33105c..71ec588b 100644 --- a/lib/rdmatrix.cpp +++ b/lib/rdmatrix.cpp @@ -43,7 +43,7 @@ bool __mx_primary_controls[RDMatrix::LastType][RDMatrix::LastControl]= {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0}, // BT 16x1 {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0}, // BT 8x2 {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0}, // BT ACS 8.2 - {1,1,1,1,0,0,1,1,0,0,0,1,1,1,1,0,1,1,1,1,0,0,0,1,1,0,0,0,0}, // SAS USI 3 + {1,1,1,1,0,0,1,1,0,0,0,1,1,1,1,0,1,1,1,1,0,0,0,1,1,0,0,0,0}, // SAS USI {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0}, // BT 16x2 {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0}, // BT SS 12.4 {0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0}, // Local Adapter @@ -65,7 +65,7 @@ bool __mx_primary_controls[RDMatrix::LastType][RDMatrix::LastControl]= {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}, // BT GPI-16 {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}, // Modem Lines {0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0}, // Software Authority - {0,1,1,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,1,0,0,0,0} // SAS USI 2 + {0,1,1,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,1,0,0,0,0} // SAS 16000 }; bool __mx_backup_controls[RDMatrix::LastType][RDMatrix::LastControl]= { @@ -83,7 +83,7 @@ bool __mx_backup_controls[RDMatrix::LastType][RDMatrix::LastControl]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT 16x1 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT 8x2 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT ACS 8.2 - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // SAS USI 3 + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // SAS USI {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT 16x2 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT SS 12.4 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Local Adapter @@ -105,7 +105,7 @@ bool __mx_backup_controls[RDMatrix::LastType][RDMatrix::LastControl]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT GPI-16 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Modem Lines {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Software Authority - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // SAS USI 2 + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // SAS 16000 }; int __mx_default_values[RDMatrix::LastType][RDMatrix::LastControl]= @@ -124,7 +124,7 @@ int __mx_default_values[RDMatrix::LastType][RDMatrix::LastControl]= {0,0,0,0,0,0,0,0,0,0,0,16,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT 16x1 {0,0,0,0,0,0,0,0,0,0,0,8,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT 8x2 {0,0,0,0,0,0,0,0,0,0,0,8,2,16,16,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT ACS 8.2 - {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // SAS USI 3 + {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // SAS USI {0,0,0,0,0,0,0,0,0,0,0,16,2,16,16,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT 16x2 {0,0,0,0,0,0,0,0,0,0,0,12,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT SS 12.4 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // Local Adapter @@ -146,7 +146,7 @@ int __mx_default_values[RDMatrix::LastType][RDMatrix::LastControl]= {0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT GPI-16 {0,0,0,0,0,0,0,0,0,0,0,0,0,4,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // Modem Lines {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // Software Authority - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0} // SAS USI 2 + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0} // SAS 16000 }; RDMatrix::RDMatrix(const QString &station,int matrix) @@ -606,12 +606,12 @@ QString RDMatrix::typeString(RDMatrix::Type type) return QString("BroadcastTools ACS 8.2"); break; - case RDMatrix::SasUsi2Digit: - return QString("SAS USI (2 digit)"); + case RDMatrix::Sas16000: + return QString("SAS 16000(D)"); break; - case RDMatrix::SasUsi3Digit: - return QString("SAS USI (3 digit)"); + case RDMatrix::SasUsi: + return QString("SAS USI"); break; case RDMatrix::Bt16x2: diff --git a/lib/rdmatrix.h b/lib/rdmatrix.h index d77c0306..4cce1d15 100644 --- a/lib/rdmatrix.h +++ b/lib/rdmatrix.h @@ -33,12 +33,12 @@ class RDMatrix enum PortType {TtyPort=0,TcpPort=1,NoPort=2}; enum Type {LocalGpio=0,GenericGpo=1,GenericSerial=2,Sas32000=3,Sas64000=4, Unity4000=5,BtSs82=6,Bt10x1=7,Sas64000Gpi=8,Bt16x1=9,Bt8x2=10, - BtAcs82=11,SasUsi3Digit=12,Bt16x2=13,BtSs124=14, + BtAcs82=11,SasUsi=12,Bt16x2=13,BtSs124=14, LocalAudioAdapter=15,LogitekVguest=16,BtSs164=17,StarGuideIII=18, BtSs42=19,LiveWireLwrpAudio=20,Quartz1=21,BtSs44=22,BtSrc8III=23, BtSrc16=24,Harlond=25,Acu1p=26,LiveWireMcastGpio=27,Am16=28, LiveWireLwrpGpio=29,BtSentinel4Web=30,BtGpi16=31,ModemLines=32, - SoftwareAuthority=33,SasUsi2Digit=34,LastType=35}; + SoftwareAuthority=33,Sas16000=34,LastType=35}; enum Endpoint {Input=0,Output=1}; enum Mode {Stereo=0,Left=1,Right=2}; enum VguestAttribute {VguestEngine=0,VguestDevice=1,VguestSurface=2, diff --git a/rdadmin/list_endpoints.cpp b/rdadmin/list_endpoints.cpp index b05f4796..e8bd12d4 100644 --- a/rdadmin/list_endpoints.cpp +++ b/rdadmin/list_endpoints.cpp @@ -138,7 +138,7 @@ ListEndpoints::ListEndpoints(RDMatrix *matrix,RDMatrix::Endpoint endpoint, list_list_view->setColumnAlignment(3,Qt::AlignHCenter); break; - case RDMatrix::SasUsi3Digit: + case RDMatrix::SasUsi: list_readonly=true; break; diff --git a/ripcd/Makefile.am b/ripcd/Makefile.am index c551c52a..14e6b972 100644 --- a/ripcd/Makefile.am +++ b/ripcd/Makefile.am @@ -63,8 +63,8 @@ dist_ripcd_SOURCES = acu1p.cpp acu1p.h\ sas32000.cpp sas32000.h\ sas64000.cpp sas64000.h\ sas64000gpi.cpp sas64000gpi.h\ - sasusi2digit.cpp sasusi2digit.h\ - sasusi3digit.cpp sasusi3digit.h\ + sas16000.cpp sas16000.h\ + sasusi.cpp sasusi.h\ starguide3.cpp starguide3.h\ starguide_feed.cpp starguide_feed.h\ swauthority.cpp swauthority.h\ @@ -102,8 +102,8 @@ nodist_ripcd_SOURCES = moc_am16.cpp\ moc_sas32000.cpp\ moc_sas64000.cpp\ moc_sas64000gpi.cpp\ - moc_sasusi2digit.cpp\ - moc_sasusi3digit.cpp\ + moc_sas16000.cpp\ + moc_sasusi.cpp\ moc_starguide3.cpp\ moc_swauthority.cpp\ moc_switcher.cpp\ diff --git a/ripcd/loaddrivers.cpp b/ripcd/loaddrivers.cpp index 3b9b635e..c2b85358 100644 --- a/ripcd/loaddrivers.cpp +++ b/ripcd/loaddrivers.cpp @@ -49,11 +49,11 @@ #include #include #include +#include #include #include #include -#include -#include +#include #include #include #include @@ -164,6 +164,10 @@ bool MainObject::LoadSwitchDriver(int matrix_num) ripcd_switcher[matrix_num]=new Quartz1(matrix,this); break; + case RDMatrix::Sas16000: + ripcd_switcher[matrix_num]=new Sas16000(matrix,this); + break; + case RDMatrix::Sas32000: ripcd_switcher[matrix_num]=new Sas32000(matrix,this); break; @@ -176,12 +180,8 @@ bool MainObject::LoadSwitchDriver(int matrix_num) ripcd_switcher[matrix_num]=new Sas64000Gpi(matrix,this); break; - case RDMatrix::SasUsi2Digit: - ripcd_switcher[matrix_num]=new SasUsi2Digit(matrix,this); - break; - - case RDMatrix::SasUsi3Digit: - ripcd_switcher[matrix_num]=new SasUsi3Digit(matrix,this); + case RDMatrix::SasUsi: + ripcd_switcher[matrix_num]=new SasUsi(matrix,this); break; case RDMatrix::SoftwareAuthority: diff --git a/ripcd/sas16000.cpp b/ripcd/sas16000.cpp index 0289abe5..b0d85180 100644 --- a/ripcd/sas16000.cpp +++ b/ripcd/sas16000.cpp @@ -1,4 +1,4 @@ -// sasusi2digit.cpp +// sas16000.cpp // // A Rivendell switcher driver for the SAS USI Protocol (2 digit) // @@ -21,9 +21,9 @@ #include #include #include -#include +#include -SasUsi2Digit::SasUsi2Digit(RDMatrix *matrix,QObject *parent,const char *name) +Sas16000::Sas16000(RDMatrix *matrix,QObject *parent,const char *name) : Switcher(matrix,parent,name) { RDTty *tty; @@ -54,37 +54,37 @@ SasUsi2Digit::SasUsi2Digit(RDMatrix *matrix,QObject *parent,const char *name) } -RDMatrix::Type SasUsi2Digit::type() +RDMatrix::Type Sas16000::type() { - return RDMatrix::SasUsi2Digit; + return RDMatrix::Sas16000; } -unsigned SasUsi2Digit::gpiQuantity() +unsigned Sas16000::gpiQuantity() { return sas_gpis; } -unsigned SasUsi2Digit::gpoQuantity() +unsigned Sas16000::gpoQuantity() { return sas_gpos; } -bool SasUsi2Digit::primaryTtyActive() +bool Sas16000::primaryTtyActive() { return true; } -bool SasUsi2Digit::secondaryTtyActive() +bool Sas16000::secondaryTtyActive() { return false; } -void SasUsi2Digit::processCommand(RDMacro *cmd) +void Sas16000::processCommand(RDMacro *cmd) { char str[256]; @@ -111,7 +111,7 @@ void SasUsi2Digit::processCommand(RDMacro *cmd) } -void SasUsi2Digit::SendCommand(char *str) +void Sas16000::SendCommand(char *str) { LogLine(RDConfig::LogDebug,QString().sprintf("sending USI cmd: %s",(const char *)PrettifyCommand(str))); @@ -119,7 +119,7 @@ void SasUsi2Digit::SendCommand(char *str) } -QString SasUsi2Digit::PrettifyCommand(const char *cmd) const +QString Sas16000::PrettifyCommand(const char *cmd) const { QString ret; if(cmd[0]<26) { diff --git a/ripcd/sas16000.h b/ripcd/sas16000.h index fc9cc879..49926135 100644 --- a/ripcd/sas16000.h +++ b/ripcd/sas16000.h @@ -1,6 +1,6 @@ -// sasusi2digit.h +// sas16000.h // -// A Rivendell switcher driver for the SAS USI Protocol (2 digit) +// A Rivendell switcher driver for the SAS 16000(D) Audio Switcher // // (C) Copyright 2002-2015 Fred Gleason // @@ -18,8 +18,8 @@ // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -#ifndef SASUSI2DIGIT_H -#define SASUSI2DIGIT_H +#ifndef SAS16000_H +#define SAS16000_H #include @@ -33,13 +33,13 @@ #include -#define SASUSI2DIGIT_MAX_LENGTH 256 +#define SAS16000_MAX_LENGTH 256 -class SasUsi2Digit : public Switcher +class Sas16000 : public Switcher { Q_OBJECT public: - SasUsi2Digit(RDMatrix *matrix,QObject *parent=0,const char *name=0); + Sas16000(RDMatrix *matrix,QObject *parent=0,const char *name=0); RDMatrix::Type type(); unsigned gpiQuantity(); unsigned gpoQuantity(); @@ -51,7 +51,7 @@ class SasUsi2Digit : public Switcher void SendCommand(char *str); QString PrettifyCommand(const char *cmd) const; RDTTYDevice *sas_device; - char sas_buffer[SASUSI2DIGIT_MAX_LENGTH]; + char sas_buffer[SAS16000_MAX_LENGTH]; unsigned sas_ptr; int sas_matrix; int sas_ipport; @@ -62,4 +62,4 @@ class SasUsi2Digit : public Switcher }; -#endif // SASUSI2DIGIT_H +#endif // SAS16000_H diff --git a/ripcd/sasusi.cpp b/ripcd/sasusi.cpp index f8bd9103..523f37f5 100644 --- a/ripcd/sasusi.cpp +++ b/ripcd/sasusi.cpp @@ -1,4 +1,4 @@ -// sasusi3digit.cpp +// sasusi.cpp // // A Rivendell switcher driver for the SAS USI Protocol (3 digit) // @@ -21,9 +21,9 @@ #include #include #include -#include +#include -SasUsi3Digit::SasUsi3Digit(RDMatrix *matrix,QObject *parent,const char *name) +SasUsi::SasUsi(RDMatrix *matrix,QObject *parent,const char *name) : Switcher(matrix,parent,name) { QString sql; @@ -102,37 +102,37 @@ SasUsi3Digit::SasUsi3Digit(RDMatrix *matrix,QObject *parent,const char *name) } -RDMatrix::Type SasUsi3Digit::type() +RDMatrix::Type SasUsi::type() { - return RDMatrix::SasUsi3Digit; + return RDMatrix::SasUsi; } -unsigned SasUsi3Digit::gpiQuantity() +unsigned SasUsi::gpiQuantity() { return sas_gpis; } -unsigned SasUsi3Digit::gpoQuantity() +unsigned SasUsi::gpoQuantity() { return sas_gpos; } -bool SasUsi3Digit::primaryTtyActive() +bool SasUsi::primaryTtyActive() { return sas_porttype==RDMatrix::TtyPort; } -bool SasUsi3Digit::secondaryTtyActive() +bool SasUsi::secondaryTtyActive() { return false; } -void SasUsi3Digit::processCommand(RDMacro *cmd) +void SasUsi::processCommand(RDMacro *cmd) { char str[256]; char cmd_byte; @@ -324,13 +324,13 @@ void SasUsi3Digit::processCommand(RDMacro *cmd) } -void SasUsi3Digit::ipConnect() +void SasUsi::ipConnect() { sas_socket->connectToHost(sas_ipaddress.toString(),sas_ipport); } -void SasUsi3Digit::connectedData() +void SasUsi::connectedData() { LogLine(RDConfig::LogInfo,QString(). sprintf("Connection to SasUsi device at %s:%d established", @@ -342,7 +342,7 @@ void SasUsi3Digit::connectedData() } -void SasUsi3Digit::connectionClosedData() +void SasUsi::connectionClosedData() { LogLine(RDConfig::LogNotice,QString(). sprintf("Connection to SasUsi device at %s:%d closed unexpectedly, attempting reconnect", @@ -351,11 +351,11 @@ void SasUsi3Digit::connectionClosedData() if(sas_stop_cart>0) { ExecuteMacroCart(sas_stop_cart); } - sas_reconnect_timer->start(SASUSI3DIGIT_RECONNECT_INTERVAL,true); + sas_reconnect_timer->start(SASUSI_RECONNECT_INTERVAL,true); } -void SasUsi3Digit::readyReadData() +void SasUsi::readyReadData() { char buffer[256]; unsigned n; @@ -369,7 +369,7 @@ void SasUsi3Digit::readyReadData() sas_ptr=0; } else { - if(sas_ptr==SASUSI3DIGIT_MAX_LENGTH) { // Buffer overflow + if(sas_ptr==SASUSI_MAX_LENGTH) { // Buffer overflow sas_ptr=0; } sas_buffer[sas_ptr++]=buffer[i]; @@ -379,7 +379,7 @@ void SasUsi3Digit::readyReadData() } -void SasUsi3Digit::errorData(int err) +void SasUsi::errorData(int err) { switch((QSocket::Error)err) { case QSocket::ErrConnectionRefused: @@ -387,7 +387,7 @@ void SasUsi3Digit::errorData(int err) "Connection to SasUsi device at %s:%d refused, attempting reconnect", (const char *)sas_ipaddress.toString(), sas_ipport)); - sas_reconnect_timer->start(SASUSI3DIGIT_RECONNECT_INTERVAL,true); + sas_reconnect_timer->start(SASUSI_RECONNECT_INTERVAL,true); break; case QSocket::ErrHostNotFound: @@ -407,7 +407,7 @@ void SasUsi3Digit::errorData(int err) } -void SasUsi3Digit::SendCommand(char *str) +void SasUsi::SendCommand(char *str) { LogLine(RDConfig::LogDebug,QString().sprintf("sending USI cmd: %s",(const char *)PrettifyCommand(str))); switch(sas_porttype) { @@ -425,9 +425,9 @@ void SasUsi3Digit::SendCommand(char *str) } -void SasUsi3Digit::DispatchCommand() +void SasUsi::DispatchCommand() { - char buffer[SASUSI3DIGIT_MAX_LENGTH]; + char buffer[SASUSI_MAX_LENGTH]; unsigned input; unsigned output; int line; @@ -613,7 +613,7 @@ void SasUsi3Digit::DispatchCommand() } -void SasUsi3Digit::ExecuteMacroCart(unsigned cartnum) +void SasUsi::ExecuteMacroCart(unsigned cartnum) { RDMacro rml; rml.setRole(RDMacro::Cmd); @@ -626,7 +626,7 @@ void SasUsi3Digit::ExecuteMacroCart(unsigned cartnum) } -QString SasUsi3Digit::PrettifyCommand(const char *cmd) const +QString SasUsi::PrettifyCommand(const char *cmd) const { QString ret; if(cmd[0]<26) { diff --git a/ripcd/sasusi.h b/ripcd/sasusi.h index 413efb49..c33199f7 100644 --- a/ripcd/sasusi.h +++ b/ripcd/sasusi.h @@ -1,4 +1,4 @@ -// sasusi3digit.h +// sasusi.h // // A Rivendell switcher driver for the SAS USI Protocol (3 digit) // @@ -18,8 +18,8 @@ // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -#ifndef SASUSI3DIGIT_H -#define SASUSI3DIGIT_H +#ifndef SASUSI_H +#define SASUSI_H #include @@ -34,14 +34,14 @@ #include -#define SASUSI3DIGIT_RECONNECT_INTERVAL 10000 -#define SASUSI3DIGIT_MAX_LENGTH 256 +#define SASUSI_RECONNECT_INTERVAL 10000 +#define SASUSI_MAX_LENGTH 256 -class SasUsi3Digit : public Switcher +class SasUsi : public Switcher { Q_OBJECT public: - SasUsi3Digit(RDMatrix *matrix,QObject *parent=0,const char *name=0); + SasUsi(RDMatrix *matrix,QObject *parent=0,const char *name=0); RDMatrix::Type type(); unsigned gpiQuantity(); unsigned gpoQuantity(); @@ -63,7 +63,7 @@ class SasUsi3Digit : public Switcher QString PrettifyCommand(const char *cmd) const; RDTTYDevice *sas_device; QSocket *sas_socket; - char sas_buffer[SASUSI3DIGIT_MAX_LENGTH]; + char sas_buffer[SASUSI_MAX_LENGTH]; unsigned sas_ptr; QHostAddress sas_ipaddress; int sas_matrix; @@ -82,4 +82,4 @@ class SasUsi3Digit : public Switcher }; -#endif // SASUSI3DIGIT_H +#endif // SASUSI_H From f6bf04c49f8952f277c58daebf4f184cc9c71a14 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Thu, 5 Mar 2015 12:48:57 -0500 Subject: [PATCH 15/34] 2015-03-05 Fred Gleason * Modified the 'SAS USI' driver in 'ripcd/sasusi.cpp' to support four digit endpoint numbers. --- ChangeLog | 5 ++++- ripcd/sasusi.cpp | 4 ++-- ripcd/sasusi.h | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index bd3402dc..c5da77c2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14809,8 +14809,11 @@ 'rdcatch/edit_download.cpp'. 2015-03-04 Fred Gleason * Incremented the package version to 2.10.3int00. -2015-03-04 Fred Gleason +2015-03-05 Fred Gleason * Renamed the 'SAS USI (3 digit)' driver to 'SAS User Serial Interface'. * Renamed the 'SAS USI (2 digit)' driver to 'SAS 16000(D)'. +2015-03-05 Fred Gleason + * Modified the 'SAS USI' driver in 'ripcd/sasusi.cpp' to support + four digit endpoint numbers. diff --git a/ripcd/sasusi.cpp b/ripcd/sasusi.cpp index 523f37f5..3eb52283 100644 --- a/ripcd/sasusi.cpp +++ b/ripcd/sasusi.cpp @@ -1,6 +1,6 @@ // sasusi.cpp // -// A Rivendell switcher driver for the SAS USI Protocol (3 digit) +// A Rivendell switcher driver for the SAS USI Protocol // // (C) Copyright 2002-2015 Fred Gleason // @@ -258,7 +258,7 @@ void SasUsi::processCommand(RDMacro *cmd) emit rmlEcho(cmd); return; } - snprintf(str,256,"%c%03d%03d\x0D\x0A",20, + snprintf(str,256,"%cT%04d%04d\x0D\x0A",5, cmd->arg(1).toInt(),cmd->arg(2).toInt()); SendCommand(str); cmd->acknowledge(true); diff --git a/ripcd/sasusi.h b/ripcd/sasusi.h index c33199f7..3a3f348e 100644 --- a/ripcd/sasusi.h +++ b/ripcd/sasusi.h @@ -1,6 +1,6 @@ // sasusi.h // -// A Rivendell switcher driver for the SAS USI Protocol (3 digit) +// A Rivendell switcher driver for the SAS USI Protocol // // (C) Copyright 2002-2015 Fred Gleason // From c87ea8cfba0a9ee1b971238321fabaa21e36de20 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Thu, 5 Mar 2015 21:04:52 -0500 Subject: [PATCH 16/34] 2015-03-05 Fred Gleason * Increased 'MAX_ENDPOINTS' in 'lib/rd.h' from 1024 to 2048. --- ChangeLog | 2 ++ lib/rd.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c5da77c2..6e3cf31c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14817,3 +14817,5 @@ 2015-03-05 Fred Gleason * Modified the 'SAS USI' driver in 'ripcd/sasusi.cpp' to support four digit endpoint numbers. +2015-03-05 Fred Gleason + * Increased 'MAX_ENDPOINTS' in 'lib/rd.h' from 1024 to 2048. diff --git a/lib/rd.h b/lib/rd.h index 42fa7913..d741d17c 100644 --- a/lib/rd.h +++ b/lib/rd.h @@ -157,7 +157,7 @@ /* * Max number of inputs or outputs in a switcher */ -#define MAX_ENDPOINTS 1024 +#define MAX_ENDPOINTS 2048 /* * Max number of attached switcher matrices per workstation From 0fbbfc5f19dba2410be6e4c3394f659123ba789b Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Thu, 5 Mar 2015 21:37:56 -0500 Subject: [PATCH 17/34] 2015-03-05 Fred Gleason * Increased digit count on endpoints from 3 to 4 in 'rdadmin/list_endpoints.cpp'. --- ChangeLog | 3 +++ rdadmin/list_endpoints.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6e3cf31c..a32ef55e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14819,3 +14819,6 @@ four digit endpoint numbers. 2015-03-05 Fred Gleason * Increased 'MAX_ENDPOINTS' in 'lib/rd.h' from 1024 to 2048. +2015-03-05 Fred Gleason + * Increased digit count on endpoints from 3 to 4 in + 'rdadmin/list_endpoints.cpp'. diff --git a/rdadmin/list_endpoints.cpp b/rdadmin/list_endpoints.cpp index e8bd12d4..a457b694 100644 --- a/rdadmin/list_endpoints.cpp +++ b/rdadmin/list_endpoints.cpp @@ -267,7 +267,7 @@ ListEndpoints::ListEndpoints(RDMatrix *matrix,RDMatrix::Endpoint endpoint, q->first(); for(int i=0;isetText(0,QString().sprintf("%03d",i+1)); + l->setText(0,QString().sprintf("%04d",i+1)); if(q->isValid()&&(q->value(0).toInt()==(i+1))){ l->setText(1,q->value(1).toString()); switch(list_matrix->type()) { @@ -539,7 +539,7 @@ void ListEndpoints::okData() modecol=4; } for(int i=0;ifindItem(QString().sprintf("%03d",i+1),0); + item=list_list_view->findItem(QString().sprintf("%04d",i+1),0); if(item->text(modecol).lower()==QString(tr("stereo"))) { mode=RDMatrix::Stereo; } From 7c2be3b74f413a37be99a682f893bc305a5e414d Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Fri, 6 Mar 2015 14:56:49 -0500 Subject: [PATCH 18/34] 2015-03-06 Fred Gleason * Incremented the package version to 2.10.3int01. --- ChangeLog | 2 ++ PACKAGE_VERSION | 2 +- rivendell.ism | Bin 499284 -> 499284 bytes 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a32ef55e..bbc29acd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14822,3 +14822,5 @@ 2015-03-05 Fred Gleason * Increased digit count on endpoints from 3 to 4 in 'rdadmin/list_endpoints.cpp'. +2015-03-06 Fred Gleason + * Incremented the package version to 2.10.3int01. diff --git a/PACKAGE_VERSION b/PACKAGE_VERSION index 16fef5c1..86b18e84 100644 --- a/PACKAGE_VERSION +++ b/PACKAGE_VERSION @@ -1 +1 @@ -2.10.3int00 \ No newline at end of file +2.10.3int01 \ No newline at end of file diff --git a/rivendell.ism b/rivendell.ism index 2c492d551fe815d1c88e95792170711ff10de354..c6644df65b5c40deeba96a39b147a498ee6ade67 100755 GIT binary patch delta 18479 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 YfgP?~gWTUd;}9!%X=}ynyR@7C5AKsv!T)6f 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 From fbc07bc9abf56021a98e8e78bcd6970bddafe58a Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Mon, 9 Mar 2015 20:41:14 -0400 Subject: [PATCH 19/34] 2015-03-09 Fred Gleason * Merged patch from Chris Smowton to enable importation of MP4 files [GitHub pull request #000029]. * Added prerequisites for MP4 importation in 'INSTALL'. --- AUTHORS | 3 +++ ChangeLog | 4 ++++ INSTALL | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/AUTHORS b/AUTHORS index a4da54f8..9fa1ff36 100644 --- a/AUTHORS +++ b/AUTHORS @@ -42,6 +42,9 @@ Alban Peignier Daniel Roviriego Portuguese Translation (pt_BR). +Chris Smowton + MP4 imporatation support. + Scott Spillers The Icon set diff --git a/ChangeLog b/ChangeLog index bbc29acd..891c1ecf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14824,3 +14824,7 @@ 'rdadmin/list_endpoints.cpp'. 2015-03-06 Fred Gleason * Incremented the package version to 2.10.3int01. +2015-03-09 Fred Gleason + * Merged patch from Chris Smowton to enable importation of + MP4 files [GitHub pull request #000029]. + * Added prerequisites for MP4 importation in 'INSTALL'. diff --git a/INSTALL b/INSTALL index 6e73c151..4b203217 100644 --- a/INSTALL +++ b/INSTALL @@ -84,6 +84,10 @@ GPIO Driver A kernel driver for the line of data-acquisition boards from MeasurementComputing. See http://www.rivendellaudio.org/. +FAAD2 / mp4v2 - AAC/MP4 Decoding Libraries. Needed for MP4 file importation. +Available at http://www.audiocoding.com/faad2.html and +https://code.google.com/p/mp4v2/ respectively. + LAME - MPEG Layer 3 Encoder Library. Needed for MPEG Layer 3 exporting. Available at http://lame.sourceforge.net/. From da8cf74df802216d368d3f1cf37e0485ff41b7e5 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Mon, 9 Mar 2015 21:37:10 -0400 Subject: [PATCH 20/34] 2015-03-09 Fred Gleason * Added a 'STATIONS.HAVE_MP4_DECODE' field to the database. * Incremented the database version to 243. * Added a 'Capability::HaveMp4Decode' value to the 'RDStation::Capability' enumeration in 'lib/rdstation.cpp' and 'lib/rdstation.h'. --- ChangeLog | 6 ++++++ cae/cae.cpp | 16 ++++++++++++++++ cae/cae.h | 1 + docs/tables/stations.txt | 1 + lib/dbversion.h | 2 +- lib/rdstation.cpp | 8 ++++++++ lib/rdstation.h | 2 +- rdadmin/createdb.cpp | 8 ++++++++ rdadmin/rdadmin_cs.ts | 5 +++++ rdadmin/rdadmin_de.ts | 5 +++++ rdadmin/rdadmin_es.ts | 5 +++++ rdadmin/rdadmin_fr.ts | 5 +++++ rdadmin/rdadmin_nb.ts | 5 +++++ rdadmin/rdadmin_nn.ts | 5 +++++ rdadmin/rdadmin_pt_BR.ts | 5 +++++ rdadmin/view_adapters.cpp | 3 +++ 16 files changed, 80 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 891c1ecf..e4bb9066 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14828,3 +14828,9 @@ * Merged patch from Chris Smowton to enable importation of MP4 files [GitHub pull request #000029]. * Added prerequisites for MP4 importation in 'INSTALL'. +2015-03-09 Fred Gleason + * Added a 'STATIONS.HAVE_MP4_DECODE' field to the database. + * Incremented the database version to 243. + * Added a 'Capability::HaveMp4Decode' value to the + 'RDStation::Capability' enumeration in 'lib/rdstation.cpp' and + 'lib/rdstation.h'. diff --git a/cae/cae.cpp b/cae/cae.cpp index a9854bba..5fb68d4d 100644 --- a/cae/cae.cpp +++ b/cae/cae.cpp @@ -1991,6 +1991,11 @@ void MainObject::ProbeCaps(RDStation *station) station->setHaveCapability(RDStation::HaveTwoLame,LoadTwoLame()); station->setHaveCapability(RDStation::HaveMpg321,LoadMad()); + // + // MP4 Decoder + // + station->setHaveCapability(RDStation::HaveMp4Decode,CheckMp4Decode()); + #ifdef HPI station->setDriverVersion(RDStation::Hpi,hpiVersion()); #else @@ -2047,6 +2052,17 @@ bool MainObject::CheckLame() } +bool MainObject::CheckMp4Decode() +{ +#ifdef HAVE_MP4_LIBS + return (dlopen("libfaad.so",RTLD_LAZY)!=NULL)&& + (dlopen("libmp4v2.so",RTLD_LAZY)!=NULL); +#else + return false; +#endif // HAVE_MP4_LIBS +} + + bool MainObject::LoadTwoLame() { #ifdef HAVE_TWOLAME diff --git a/cae/cae.h b/cae/cae.h index d84dd52a..99b3c288 100644 --- a/cae/cae.h +++ b/cae/cae.h @@ -352,6 +352,7 @@ class MainObject : public QObject #endif // ALSA bool CheckLame(); + bool CheckMp4Decode(); // // TwoLAME Encoder diff --git a/docs/tables/stations.txt b/docs/tables/stations.txt index f2c7441f..e4195475 100644 --- a/docs/tables/stations.txt +++ b/docs/tables/stations.txt @@ -40,6 +40,7 @@ HAVE_FLAC enum('N','Y') HAVE_TWOLAME enum('N','Y') HAVE_LAME enum('N','Y') HAVE_MPG321 enum('N','Y') +HAVE_MP4_DECODE enum('N','Y') HPI_VERSION char(16) JACK_VERSION char(16) ALSA_VERSION char(16) diff --git a/lib/dbversion.h b/lib/dbversion.h index f2da5961..2cf326ee 100644 --- a/lib/dbversion.h +++ b/lib/dbversion.h @@ -26,7 +26,7 @@ /* * Current Database Version */ -#define RD_VERSION_DATABASE 242 +#define RD_VERSION_DATABASE 243 #endif // DBVERSION_H diff --git a/lib/rdstation.cpp b/lib/rdstation.cpp index 4a1396f6..42bddbc3 100644 --- a/lib/rdstation.cpp +++ b/lib/rdstation.cpp @@ -487,6 +487,10 @@ bool RDStation::haveCapability(Capability cap) const "HAVE_LAME").toString()); break; + case RDStation::HaveMp4Decode: + return RDBool(RDGetSqlValue("STATIONS","NAME",station_name, + "HAVE_MP4_DECODE").toString()); + case RDStation::HaveMpg321: return RDBool(RDGetSqlValue("STATIONS","NAME",station_name, "HAVE_MPG321").toString()); @@ -519,6 +523,10 @@ void RDStation::setHaveCapability(Capability cap,bool state) const SetRow("HAVE_LAME",state); break; + case RDStation::HaveMp4Decode: + SetRow("HAVE_MP4_DECODE",state); + break; + case RDStation::HaveMpg321: SetRow("HAVE_MPG321",state); break; diff --git a/lib/rdstation.h b/lib/rdstation.h index 321f921f..f0f1e371 100644 --- a/lib/rdstation.h +++ b/lib/rdstation.h @@ -42,7 +42,7 @@ class RDStation UserSec=1 /**< UserSec - user based security. */ }; enum Capability {HaveOggenc=0,HaveOgg123=1,HaveFlac=2, - HaveLame=3,HaveMpg321=4,HaveTwoLame=5}; + HaveLame=3,HaveMpg321=4,HaveTwoLame=5,HaveMp4Decode=6}; enum FilterMode {FilterSynchronous=0,FilterAsynchronous=1}; RDStation(const QString &name,bool create=false); ~RDStation(); diff --git a/rdadmin/createdb.cpp b/rdadmin/createdb.cpp index 592c1545..27f1cdd4 100644 --- a/rdadmin/createdb.cpp +++ b/rdadmin/createdb.cpp @@ -644,6 +644,7 @@ bool CreateDb(QString name,QString pwd) HAVE_TWOLAME enum('N','Y') default 'N',\ HAVE_LAME enum('N','Y') default 'N',\ HAVE_MPG321 enum('N','Y') default 'N',\ + HAVE_MP4_DECODE enum('N','Y') default 'N',\ HPI_VERSION char(16),\ JACK_VERSION char(16),\ ALSA_VERSION char(16),\ @@ -8086,6 +8087,13 @@ int UpdateDb(int ver) delete q; } + if(ver<243) { + sql=QString("alter table STATIONS add column ")+ + "HAVE_MP4_DECODE enum('N','Y') default 'N' after HAVE_MPG321"; + q=new QSqlQuery(sql); + delete q; + } + // **** End of version updates **** diff --git a/rdadmin/rdadmin_cs.ts b/rdadmin/rdadmin_cs.ts index 25b28d7f..0997e1ac 100644 --- a/rdadmin/rdadmin_cs.ts +++ b/rdadmin/rdadmin_cs.ts @@ -5902,5 +5902,10 @@ pro naplnění databáze zdroji zvuku. &Close &Zavřít + + MP-4/AAC + + + diff --git a/rdadmin/rdadmin_de.ts b/rdadmin/rdadmin_de.ts index 6b7532b8..9751a577 100644 --- a/rdadmin/rdadmin_de.ts +++ b/rdadmin/rdadmin_de.ts @@ -5852,5 +5852,10 @@ eingeben um die Audioressourcendatenbank zu füllen. &Close &Schliessen + + MP-4/AAC + + + diff --git a/rdadmin/rdadmin_es.ts b/rdadmin/rdadmin_es.ts index 9901761a..d25df961 100644 --- a/rdadmin/rdadmin_es.ts +++ b/rdadmin/rdadmin_es.ts @@ -5854,5 +5854,10 @@ Revise los parámetros e intente de nuevo. &Close &Cerrar + + MP-4/AAC + + + diff --git a/rdadmin/rdadmin_fr.ts b/rdadmin/rdadmin_fr.ts index 06ec2d69..47bed8ce 100644 --- a/rdadmin/rdadmin_fr.ts +++ b/rdadmin/rdadmin_fr.ts @@ -5380,5 +5380,10 @@ please check your settings and try again. &Close + + MP-4/AAC + + + diff --git a/rdadmin/rdadmin_nb.ts b/rdadmin/rdadmin_nb.ts index 034c6ca9..32dd67a3 100644 --- a/rdadmin/rdadmin_nb.ts +++ b/rdadmin/rdadmin_nb.ts @@ -5839,5 +5839,10 @@ Sjekk oppsettet ditt og prøv att. &Close &Lukk + + MP-4/AAC + + + diff --git a/rdadmin/rdadmin_nn.ts b/rdadmin/rdadmin_nn.ts index 034c6ca9..32dd67a3 100644 --- a/rdadmin/rdadmin_nn.ts +++ b/rdadmin/rdadmin_nn.ts @@ -5839,5 +5839,10 @@ Sjekk oppsettet ditt og prøv att. &Close &Lukk + + MP-4/AAC + + + diff --git a/rdadmin/rdadmin_pt_BR.ts b/rdadmin/rdadmin_pt_BR.ts index 7db3fbb2..5c9c37db 100644 --- a/rdadmin/rdadmin_pt_BR.ts +++ b/rdadmin/rdadmin_pt_BR.ts @@ -5832,5 +5832,10 @@ por favor, cheque suas configurações e tente novamente &Close &Fechar + + MP-4/AAC + + + diff --git a/rdadmin/view_adapters.cpp b/rdadmin/view_adapters.cpp index 91d407bc..572f8edf 100644 --- a/rdadmin/view_adapters.cpp +++ b/rdadmin/view_adapters.cpp @@ -98,6 +98,9 @@ ViewAdapters::ViewAdapters(RDStation *rdstation, text+=tr(" MPEG Layer 2\n"); text+=tr(" MPEG Layer 3\n"); } + if(rdstation->haveCapability(RDStation::HaveMp4Decode)) { + text+=tr(" MP-4/AAC\n"); + } if(rdstation->haveCapability(RDStation::HaveOgg123)) { text+=tr(" OggVorbis\n"); } From 5e20febe5b1119c9f1bafa5a174dd83ed6b5f379 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Tue, 10 Mar 2015 16:08:04 -0400 Subject: [PATCH 21/34] 2015-03-10 Fred Gleason * Fixed a bug in 'lib/rdcdplayer.cpp' that threw a segfault when opening the ripper with no CD inserted under RHEL 7. --- ChangeLog | 3 +++ lib/rdcdplayer.cpp | 17 ++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index e4bb9066..ab5eb0cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14834,3 +14834,6 @@ * Added a 'Capability::HaveMp4Decode' value to the 'RDStation::Capability' enumeration in 'lib/rdstation.cpp' and 'lib/rdstation.h'. +2015-03-10 Fred Gleason + * Fixed a bug in 'lib/rdcdplayer.cpp' that threw a segfault + when opening the ripper with no CD inserted under RHEL 7. diff --git a/lib/rdcdplayer.cpp b/lib/rdcdplayer.cpp index be97848c..9a7dc18b 100644 --- a/lib/rdcdplayer.cpp +++ b/lib/rdcdplayer.cpp @@ -201,13 +201,15 @@ int RDCdPlayer::rightVolume() void RDCdPlayer::setCddbRecord(RDCddbRecord *rec) { - rec->setTracks(cdrom_track_count); - rec->setDiscId(cdrom_disc_id); - rec->setDiscLength(75*(60*cdrom_track_start[cdrom_track_count].msf.minute+ - cdrom_track_start[cdrom_track_count].msf.second)+ - cdrom_track_start[cdrom_track_count].msf.frame); - for(int i=0;isetTrackOffset(i,trackOffset(i)); + if(cdrom_track_count>0) { + rec->setTracks(cdrom_track_count); + rec->setDiscId(cdrom_disc_id); + rec->setDiscLength(75*(60*cdrom_track_start[cdrom_track_count].msf.minute+ + cdrom_track_start[cdrom_track_count].msf.second)+ + cdrom_track_start[cdrom_track_count].msf.frame); + for(int i=0;isetTrackOffset(i,trackOffset(i)); + } } } @@ -460,6 +462,7 @@ void RDCdPlayer::ReadToc() // if(ioctl(cdrom_fd,CDROMREADTOCHDR,&tochdr)<0) { cdrom_track_count=0; + return; } cdrom_track_count=tochdr.cdth_trk1-tochdr.cdth_trk0+1; From 032f7f0f5a40120e10c24850b7b94380c11fcbaa Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Mon, 16 Mar 2015 17:39:45 -0400 Subject: [PATCH 22/34] 2015-03-16 Fred Gleason * Added 'DESCRIPTION', 'OUTCUE', 'FILENAME' and '*_POINT' fields to the 'Cart CSV Report' in 'rdlibrary/list_reports.cpp'. --- ChangeLog | 3 ++ rdlibrary/list_reports.cpp | 93 ++++++++++++++++++++++++++++++-------- 2 files changed, 76 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index e4bb9066..e7635311 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14834,3 +14834,6 @@ * Added a 'Capability::HaveMp4Decode' value to the 'RDStation::Capability' enumeration in 'lib/rdstation.cpp' and 'lib/rdstation.h'. +2015-03-16 Fred Gleason + * Added 'DESCRIPTION', 'OUTCUE', 'FILENAME' and '*_POINT' fields + to the 'Cart CSV Report' in 'rdlibrary/list_reports.cpp'. diff --git a/rdlibrary/list_reports.cpp b/rdlibrary/list_reports.cpp index 8e1c9feb..e1d7071b 100644 --- a/rdlibrary/list_reports.cpp +++ b/rdlibrary/list_reports.cpp @@ -690,7 +690,7 @@ void ListReports::GenerateCartDumpCsv(QString *report,bool prepend_names) RDSqlQuery *q; QString schedcode=""; QStringList f0; - unsigned code_quan=0; + int code_quan=0; if(list_schedcode!=tr("ALL")) { schedcode=list_schedcode; @@ -702,20 +702,27 @@ void ListReports::GenerateCartDumpCsv(QString *report,bool prepend_names) if(list_type_filter.isEmpty()) { return; } - sql=QString("select CUTS.CUT_NAME,CART.GROUP_NAME,CART.TITLE,CART.ARTIST,")+ + sql=QString("select CART.NUMBER,CART.TYPE,CUTS.CUT_NAME,CART.GROUP_NAME,CART.TITLE,CART.ARTIST,")+ "CART.ALBUM,CART.YEAR,CUTS.ISRC,CUTS.ISCI,CART.LABEL,CART.CLIENT,"+ "CART.AGENCY,CART.PUBLISHER,CART.COMPOSER,CART.CONDUCTOR,CART.SONG_ID,"+ - "CART.USER_DEFINED,CUTS.LENGTH,SCHED_CODES from CART "+ - "join CUTS on CART.NUMBER=CUTS.CART_NUMBER"; + "CART.USER_DEFINED,CUTS.DESCRIPTION,CUTS.OUTCUE,"+ + "CUTS.LENGTH,"+ + "CUTS.START_POINT,CUTS.END_POINT,"+ + "CUTS.SEGUE_START_POINT,CUTS.SEGUE_END_POINT,"+ + "CUTS.HOOK_START_POINT,CUTS.HOOK_END_POINT,"+ + "CUTS.TALK_START_POINT,CUTS.TALK_END_POINT,"+ + "CUTS.FADEUP_POINT,CUTS.FADEDOWN_POINT,"+ + "SCHED_CODES from CART "+ + "left join CUTS on CART.NUMBER=CUTS.CART_NUMBER"; if(list_group==QString("ALL")) { sql+=QString(" where ")+ RDAllCartSearchText(list_filter,schedcode,lib_user->name(),true)+" && "+ - list_type_filter+" order by CUTS.CUT_NAME"; + list_type_filter+" order by CART.NUMBER,CUTS.CUT_NAME"; } else { sql+=QString(" where ")+ RDCartSearchText(list_filter,list_group,schedcode,true)+" && "+ - list_type_filter+" order by CUTS.CUT_NAME"; + list_type_filter+" order by CART.NUMBER,CUTS.CUT_NAME"; } q=new RDSqlQuery(sql); @@ -724,7 +731,7 @@ void ListReports::GenerateCartDumpCsv(QString *report,bool prepend_names) // while(q->next()) { f0=f0.split(" ",q->value(17).toString()); - if(f0.size()>code_quan) { + if((int)f0.size()>code_quan) { code_quan=f0.size(); } } @@ -734,10 +741,16 @@ void ListReports::GenerateCartDumpCsv(QString *report,bool prepend_names) // Prepend Field Names // if(prepend_names) { - *report="CART,CUT,GROUP_NAME,TITLE,ARTIST,ALBUM,YEAR,ISRC,ISCI,LABEL,"; + *report="CART,CUT,TYPE,GROUP_NAME,TITLE,ARTIST,ALBUM,YEAR,ISRC,ISCI,LABEL,"; *report+="CLIENT,AGENCY,PUBLISHER,COMPOSER,CONDUCTOR,SONG_ID,USER_DEFINED,"; - *report+="LENGTH,"; - for(unsigned i=0;ileft(report->length()-1); @@ -749,15 +762,20 @@ void ListReports::GenerateCartDumpCsv(QString *report,bool prepend_names) // q->seek(-1); while(q->next()) { - *report+=QString().sprintf("%u,",RDCut::cartNumber(q->value(0).toString())); - *report+=QString().sprintf("%u,",RDCut::cutNumber(q->value(0).toString())); - *report+="\""+q->value(1).toString()+"\","; - *report+="\""+q->value(2).toString()+"\","; + RDCart::Type type=(RDCart::Type)q->value(1).toInt(); + *report+=QString().sprintf("%u,",q->value(0).toUInt()); + if(type==RDCart::Macro) { + *report+="0,\"macro\","; + } + else { + *report+=QString().sprintf("%u,",RDCut::cutNumber(q->value(2).toString())); + *report+="\"audio\","; + } *report+="\""+q->value(3).toString()+"\","; *report+="\""+q->value(4).toString()+"\","; - *report+="\""+q->value(5).toDate().toString("yyyy")+"\","; + *report+="\""+q->value(5).toString()+"\","; *report+="\""+q->value(6).toString()+"\","; - *report+="\""+q->value(7).toString()+"\","; + *report+="\""+q->value(7).toDate().toString("yyyy")+"\","; *report+="\""+q->value(8).toString()+"\","; *report+="\""+q->value(9).toString()+"\","; *report+="\""+q->value(10).toString()+"\","; @@ -766,11 +784,46 @@ void ListReports::GenerateCartDumpCsv(QString *report,bool prepend_names) *report+="\""+q->value(13).toString()+"\","; *report+="\""+q->value(14).toString()+"\","; *report+="\""+q->value(15).toString()+"\","; + *report+="\""+q->value(16).toString()+"\","; + *report+="\""+q->value(17).toString()+"\","; + *report+="\""+q->value(18).toString()+"\","; + *report+="\""+q->value(19).toString()+"\","; + if(type==RDCart::Macro) { + *report+="\"\","; + } + else { + *report+="\""+q->value(2).toString()+".wav\","; + } *report+="\""+ - RDGetTimeLength(q->value(16).toInt(),false,false).stripWhiteSpace()+"\","; - f0=f0.split(" ",q->value(17).toString()); - for(unsigned i=0;ii)&&(f0[i]!=".")) { + RDGetTimeLength(q->value(20).toInt(),false,false).stripWhiteSpace()+"\","; + if(type==RDCart::Macro) { + *report+="-1,"; + *report+="-1,"; + *report+="-1,"; + *report+="-1,"; + *report+="-1,"; + *report+="-1,"; + *report+="-1,"; + *report+="-1,"; + *report+="-1,"; + *report+="-1,"; + } + else { + *report+=QString().sprintf("%d,",q->value(21).toInt()); + *report+=QString().sprintf("%d,",q->value(22).toInt()); + *report+=QString().sprintf("%d,",q->value(23).toInt()); + *report+=QString().sprintf("%d,",q->value(24).toInt()); + *report+=QString().sprintf("%d,",q->value(25).toInt()); + *report+=QString().sprintf("%d,",q->value(26).toInt()); + *report+=QString().sprintf("%d,",q->value(27).toInt()); + *report+=QString().sprintf("%d,",q->value(28).toInt()); + *report+=QString().sprintf("%d,",q->value(29).toInt()); + *report+=QString().sprintf("%d,",q->value(30).toInt()); + } + + f0=f0.split(" ",q->value(31).toString()); + for(int i=0;ii)&&(f0[i]!=".")) { *report+="\""+f0[i].stripWhiteSpace()+"\","; } else { From d9aef7b4ac25b171c60fcfbebf83816d1ec70530 Mon Sep 17 00:00:00 2001 From: Cloud User Date: Tue, 17 Mar 2015 19:38:07 -0400 Subject: [PATCH 23/34] Updated get_distro.sh for RHEL 7 --- ChangeLog | 2 ++ get_distro.sh | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index e7635311..107b23a8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14837,3 +14837,5 @@ 2015-03-16 Fred Gleason * Added 'DESCRIPTION', 'OUTCUE', 'FILENAME' and '*_POINT' fields to the 'Cart CSV Report' in 'rdlibrary/list_reports.cpp'. +2015-03-17 Fred Gleason + * Updated 'get_distro.sh' to detect RHEL 7 correctly. diff --git a/get_distro.sh b/get_distro.sh index fd15e45a..9ecbe2e6 100755 --- a/get_distro.sh +++ b/get_distro.sh @@ -58,6 +58,9 @@ case "$1" in if test $VER = "release" ; then VER=`awk '/release/ {print $4}' /etc/redhat-release` fi + if test $VER = "Enterprise" ; then + VER=`awk '/release/ {print $7}' /etc/redhat-release` + fi echo $VER exit 0 fi @@ -80,6 +83,9 @@ case "$1" in if test $VER = "release" ; then VER=`awk '/release/ {print $4}' /etc/redhat-release` fi + if test $VER = "Enterprise" ; then + VER=`awk '/release/ {print $7}' /etc/redhat-release` + fi echo $VER | awk -F '.' '{print $1}' exit 0 fi @@ -98,6 +104,9 @@ case "$1" in if test $VER = "release" ; then VER=`awk '/release/ {print $4}' /etc/redhat-release` fi + if test $VER = "Enterprise" ; then + VER=`awk '/release/ {print $7}' /etc/redhat-release` + fi echo $VER | awk -F '.' '{print $2}' exit 0 fi From 19c5ce93646c8e8a90298d7600b24cfd4a338ad4 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Mon, 23 Mar 2015 17:05:28 -0400 Subject: [PATCH 24/34] 2015-03-23 Fred Gleason * Fixed a fencepost bug in 'ripcd/sasusi.cpp' that caused the last relay in the list to fail to respond to a 'GO' RML. --- ChangeLog | 3 +++ ripcd/sasusi.cpp | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e7635311..dee2d902 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14837,3 +14837,6 @@ 2015-03-16 Fred Gleason * Added 'DESCRIPTION', 'OUTCUE', 'FILENAME' and '*_POINT' fields to the 'Cart CSV Report' in 'rdlibrary/list_reports.cpp'. +2015-03-23 Fred Gleason + * Fixed a fencepost bug in 'ripcd/sasusi.cpp' that caused the + last relay in the list to fail to respond to a 'GO' RML. diff --git a/ripcd/sasusi.cpp b/ripcd/sasusi.cpp index 3eb52283..6edd5cee 100644 --- a/ripcd/sasusi.cpp +++ b/ripcd/sasusi.cpp @@ -288,10 +288,11 @@ void SasUsi::processCommand(RDMacro *cmd) } cmd_byte=0x01; } - if(cmd->arg(2).toUInt()arg(2).toUInt()<=sas_relay_numbers.size()) { if(sas_relay_numbers[cmd->arg(2).toUInt()-1]>=0) { snprintf(str,256,"\x05R%d%04d\x0D\x0A",cmd_byte, sas_relay_numbers[cmd->arg(2).toUInt()-1]); + syslog(LOG_NOTICE,"USI: %s",(const char *)PrettifyCommand(str)); SendCommand(str); cmd->acknowledge(true); emit rmlEcho(cmd); From 12b8566af9fa1367b26853cbeb005247cceff79e Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Thu, 2 Apr 2015 10:48:37 -0400 Subject: [PATCH 25/34] 2015-04-02 Fred Gleason * Modified the definition of the 'JACK_CLIENTS.COMMAND_LINE' field from 'char(255)' to 'text' in the database. * Incremented the database version to 244. --- ChangeLog | 4 ++++ lib/dbversion.h | 2 +- rdadmin/createdb.cpp | 8 +++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d20e2aee..15e1cf8c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14842,3 +14842,7 @@ 2015-03-23 Fred Gleason * Fixed a fencepost bug in 'ripcd/sasusi.cpp' that caused the last relay in the list to fail to respond to a 'GO' RML. +2015-04-02 Fred Gleason + * Modified the definition of the 'JACK_CLIENTS.COMMAND_LINE' + field from 'char(255)' to 'text' in the database. + * Incremented the database version to 244. diff --git a/lib/dbversion.h b/lib/dbversion.h index 2cf326ee..bcc1497a 100644 --- a/lib/dbversion.h +++ b/lib/dbversion.h @@ -26,7 +26,7 @@ /* * Current Database Version */ -#define RD_VERSION_DATABASE 243 +#define RD_VERSION_DATABASE 244 #endif // DBVERSION_H diff --git a/rdadmin/createdb.cpp b/rdadmin/createdb.cpp index 27f1cdd4..ab3687aa 100644 --- a/rdadmin/createdb.cpp +++ b/rdadmin/createdb.cpp @@ -2237,7 +2237,7 @@ bool CreateDb(QString name,QString pwd) ID int unsigned auto_increment not null primary key, \ STATION_NAME char(64) not null,\ DESCRIPTION char(64),\ - COMMAND_LINE char(255) not null,\ + COMMAND_LINE text not null,\ index IDX_STATION_NAME (STATION_NAME))"); if(!RunQuery(sql)) { return false; @@ -8094,6 +8094,12 @@ int UpdateDb(int ver) delete q; } + if(ver<244) { + sql=QString("alter table JACK_CLIENTS modify column ")+ + "COMMAND_LINE text not null"; + q=new QSqlQuery(sql); + delete q; + } // **** End of version updates **** From bd47f50abfe3c543130fdd775d476c260eb6d70a Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Mon, 6 Apr 2015 16:56:27 -0400 Subject: [PATCH 26/34] 2015-04-06 Fred Gleason * Fixed a bug in 'rdlibrary/disk_ripper.cpp' that caused the tracks from discs with no CDDB data to received scrambled/incorrect cart titles. --- ChangeLog | 4 ++++ rdlibrary/disk_ripper.cpp | 12 ++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9e0fc277..5b1fc059 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14849,3 +14849,7 @@ * Modified the definition of the 'JACK_CLIENTS.COMMAND_LINE' field from 'char(255)' to 'text' in the database. * Incremented the database version to 244. +2015-04-06 Fred Gleason + * Fixed a bug in 'rdlibrary/disk_ripper.cpp' that caused the tracks + from discs with no CDDB data to received scrambled/incorrect cart + titles. diff --git a/rdlibrary/disk_ripper.cpp b/rdlibrary/disk_ripper.cpp index 6d1b1dba..96453228 100644 --- a/rdlibrary/disk_ripper.cpp +++ b/rdlibrary/disk_ripper.cpp @@ -792,7 +792,7 @@ void DiskRipper::mediaChangedData() rip_cutnames.push_back(QString()); rip_end_track.push_back(-1); rip_wave_datas.push_back(new RDWaveData()); - rip_wave_datas.back()->setTitle(tr("Track")+QString().sprintf(" %d",i+1)); + rip_wave_datas.back()->setTitle(tr("Track")+QString().sprintf(" %d",rip_cdrom->tracks()-i+1)); l=new RDListViewItem(rip_track_list); l->setText(0,QString().sprintf("%d",i)); if(rip_cdrom->isAudio(i)) { @@ -1131,11 +1131,19 @@ QString DiskRipper::BuildTrackName(int start_track,int end_track) const while(item!=NULL) { if(item->text(0).toInt()==start_track) { ret=item->text(2); + if(ret.isEmpty()) { + ret=tr("Track")+" "+item->text(0); + } } else { if((item->text(0).toInt()>start_track)&& (item->text(0).toInt()<=end_track)) { - ret+=" / "+item->text(2); + if(item->text(2).isEmpty()) { + ret+=" / "+tr("Track")+" "+item->text(0); + } + else { + ret+=" / "+item->text(2); + } } } item=(RDListViewItem *)item->nextSibling(); From 153c0b4b0b24a84d201bb8e9927618a8cc4acc67 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Tue, 7 Apr 2015 14:09:55 -0400 Subject: [PATCH 27/34] 2015-04-07 Fred Gleason * Added a 'RDLIBRARY.READ_ISRC' field to the database. * Incremented the database version to 245. * Added 'RDLibraryConf::readIsrc()' and 'RDLibraryConf::setReadIsrc()' methods in 'lib/rdlibrary_conf.cpp' and 'lib/rdlibrary_conf.h'. * Added a 'Read ISRCs from CD' control to the 'Edit RDLibrary' dialog in 'rdadmin/edit_rdlibrary.cpp' and 'rdadmin/edi_rdlibrary.h'. * Implemented the 'Read ISRCs from CD' option in the full disc ripper in 'rdlibrary/disk_ripper.cpp'. * Implemented the 'Read ISRCs from CD' option in the per-track disc ripper in 'rdlibrary/cdripper.cpp'. --- ChangeLog | 11 +++ docs/tables/rd_library.txt | 2 +- lib/dbversion.h | 2 +- lib/rdlibrary_conf.cpp | 13 +++ lib/rdlibrary_conf.h | 2 + rdadmin/createdb.cpp | 8 ++ rdadmin/edit_rdlibrary.cpp | 178 +++++++++++++++++++------------------ rdadmin/edit_rdlibrary.h | 4 +- rdadmin/rdadmin_cs.ts | 4 + rdadmin/rdadmin_de.ts | 4 + rdadmin/rdadmin_es.ts | 4 + rdadmin/rdadmin_fr.ts | 4 + rdadmin/rdadmin_nb.ts | 4 + rdadmin/rdadmin_nn.ts | 4 + rdadmin/rdadmin_pt_BR.ts | 4 + rdlibrary/cdripper.cpp | 4 +- rdlibrary/disk_ripper.cpp | 6 +- 17 files changed, 163 insertions(+), 95 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5b1fc059..59fc08cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14853,3 +14853,14 @@ * Fixed a bug in 'rdlibrary/disk_ripper.cpp' that caused the tracks from discs with no CDDB data to received scrambled/incorrect cart titles. +2015-04-07 Fred Gleason + * Added a 'RDLIBRARY.READ_ISRC' field to the database. + * Incremented the database version to 245. + * Added 'RDLibraryConf::readIsrc()' and 'RDLibraryConf::setReadIsrc()' + methods in 'lib/rdlibrary_conf.cpp' and 'lib/rdlibrary_conf.h'. + * Added a 'Read ISRCs from CD' control to the 'Edit RDLibrary' dialog + in 'rdadmin/edit_rdlibrary.cpp' and 'rdadmin/edi_rdlibrary.h'. + * Implemented the 'Read ISRCs from CD' option in the full disc + ripper in 'rdlibrary/disk_ripper.cpp'. + * Implemented the 'Read ISRCs from CD' option in the per-track disc + ripper in 'rdlibrary/cdripper.cpp'. diff --git a/docs/tables/rd_library.txt b/docs/tables/rd_library.txt index 4662182e..0a647c27 100644 --- a/docs/tables/rd_library.txt +++ b/docs/tables/rd_library.txt @@ -1,7 +1,6 @@ RDLIBRARY Table Layout for Rivendell The RDLIBRARY table holds configuration data for the RDLibrary widget. -Following is the layout of a record in the RDLIBRARY table: FIELD NAME TYPE REMARKS ------------------------------------------------------------------------------ @@ -32,6 +31,7 @@ RIPPER_DEVICE char(64) PARANOIA_LEVEL int(11) RIPPER_LEVEL int(11) CDDB_SERVER char(64) +READ_ISRC enum('N','Y') ENABLE_EDITOR enum('N','Y') SRC_CONVERTER int(11) LIMIT_SEARCH int(11) 0 = No, 1 = Yes, 2 = Previous diff --git a/lib/dbversion.h b/lib/dbversion.h index bcc1497a..e5e6a64e 100644 --- a/lib/dbversion.h +++ b/lib/dbversion.h @@ -26,7 +26,7 @@ /* * Current Database Version */ -#define RD_VERSION_DATABASE 244 +#define RD_VERSION_DATABASE 245 #endif // DBVERSION_H diff --git a/lib/rdlibrary_conf.cpp b/lib/rdlibrary_conf.cpp index ee77f749..378a8bd1 100644 --- a/lib/rdlibrary_conf.cpp +++ b/lib/rdlibrary_conf.cpp @@ -288,6 +288,19 @@ void RDLibraryConf::setCddbServer(QString server) const } +bool RDLibraryConf::readIsrc() const +{ + return RDBool(RDGetSqlValue("RDLIBRARY","ID",lib_id,"READ_ISRC"). + toString()); +} + + +void RDLibraryConf::setReadIsrc(bool state) const +{ + SetRow("READ_ISRC",RDYesNo(state)); +} + + bool RDLibraryConf::enableEditor() const { return RDBool(RDGetSqlValue("RDLIBRARY","ID",lib_id,"ENABLE_EDITOR"). diff --git a/lib/rdlibrary_conf.h b/lib/rdlibrary_conf.h index 01d5891f..895de7ba 100644 --- a/lib/rdlibrary_conf.h +++ b/lib/rdlibrary_conf.h @@ -71,6 +71,8 @@ class RDLibraryConf void setRipperLevel(int level) const; QString cddbServer() const; void setCddbServer(QString server) const; + bool readIsrc() const; + void setReadIsrc(bool state) const; bool enableEditor() const; void setEnableEditor(bool state) const; void getSettings(RDSettings *s) const; diff --git a/rdadmin/createdb.cpp b/rdadmin/createdb.cpp index ab3687aa..46bbf6b5 100644 --- a/rdadmin/createdb.cpp +++ b/rdadmin/createdb.cpp @@ -1008,6 +1008,7 @@ bool CreateDb(QString name,QString pwd) PARANOIA_LEVEL INT DEFAULT 0,\ RIPPER_LEVEL INT DEFAULT -1300,\ CDDB_SERVER CHAR(64) DEFAULT \"freedb.freedb.org\",\ + READ_ISRC enum('N','Y') default 'Y',\ ENABLE_EDITOR enum('N','Y') default 'N',\ SRC_CONVERTER int default 1,\ LIMIT_SEARCH int default 1,\ @@ -8101,6 +8102,13 @@ int UpdateDb(int ver) delete q; } + if(ver<245) { + sql=QString("alter table RDLIBRARY add column ")+ + "READ_ISRC enum('N','Y') default 'Y' after CDDB_SERVER"; + q=new QSqlQuery(sql); + delete q; + } + // **** End of version updates **** diff --git a/rdadmin/edit_rdlibrary.cpp b/rdadmin/edit_rdlibrary.cpp index 1747d3a6..84416121 100644 --- a/rdadmin/edit_rdlibrary.cpp +++ b/rdadmin/edit_rdlibrary.cpp @@ -41,8 +41,8 @@ EditRDLibrary::EditRDLibrary(RDStation *station,RDStation *cae_station, - QWidget *parent,const char *name) - : QDialog(parent,name,true) + QWidget *parent) + : QDialog(parent,"",true) { // // Fix the Window Size @@ -65,7 +65,7 @@ EditRDLibrary::EditRDLibrary(RDStation *station,RDStation *cae_station, // // Text Validator // - RDTextValidator *validator=new RDTextValidator(this,"validator"); + RDTextValidator *validator=new RDTextValidator(this); // // Dialog Name @@ -75,9 +75,9 @@ EditRDLibrary::EditRDLibrary(RDStation *station,RDStation *cae_station, // // Input Configuration // - lib_input_card=new RDCardSelector(this,"lib_input_card"); + lib_input_card=new RDCardSelector(this); lib_input_card->setGeometry(10,29,120,117); - QLabel *label=new QLabel(lib_input_card,tr("INPUT"),this,"lib_input_label"); + QLabel *label=new QLabel(lib_input_card,tr("INPUT"),this); label->setGeometry(10,10,110,19); label->setFont(big_font); label->setAlignment(AlignCenter); @@ -85,9 +85,9 @@ EditRDLibrary::EditRDLibrary(RDStation *station,RDStation *cae_station, // // Output Configuration // - lib_output_card=new RDCardSelector(this,"lib_output_card"); + lib_output_card=new RDCardSelector(this); lib_output_card->setGeometry(170,29,120,87); - label=new QLabel(lib_output_card,tr("OUTPUT"),this,"lib_output_label"); + label=new QLabel(lib_output_card,tr("OUTPUT"),this); label->setGeometry(170,10,110,19); label->setFont(big_font); label->setAlignment(AlignCenter); @@ -95,7 +95,7 @@ EditRDLibrary::EditRDLibrary(RDStation *station,RDStation *cae_station, // // Settings // - QLabel *setting_label=new QLabel(tr("Settings"),this,"setting_label"); + QLabel *setting_label=new QLabel(tr("Settings"),this); setting_label->setGeometry(25,79,120,19); setting_label->setFont(big_font); setting_label->setAlignment(AlignRight|ShowPrefix); @@ -103,33 +103,32 @@ EditRDLibrary::EditRDLibrary(RDStation *station,RDStation *cae_station, // // Maximum Record Length // - lib_maxlength_time=new QTimeEdit(this,"lib_maxlength_time"); + lib_maxlength_time=new QTimeEdit(this); lib_maxlength_time->setGeometry(160,100,85,19); - QLabel *lib_maxlength_label=new QLabel(lib_maxlength_time, - tr("&Max Record Time:"),this, - "lib_maxlength_label"); + QLabel *lib_maxlength_label= + new QLabel(lib_maxlength_time,tr("&Max Record Time:"),this); lib_maxlength_label->setGeometry(25,101,130,19); lib_maxlength_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); // // VOX threshold // - lib_vox_spin=new QSpinBox(this,"lib_vox_spin"); + lib_vox_spin=new QSpinBox(this); lib_vox_spin->setGeometry(160,122,40,19); lib_vox_spin->setMinValue(-99); lib_vox_spin->setMaxValue(0); - QLabel *lib_vox_spin_label=new QLabel(lib_vox_spin,tr("&VOX Threshold:"), - this,"lib_vox_spin_label"); + QLabel *lib_vox_spin_label= + new QLabel(lib_vox_spin,tr("&VOX Threshold:"),this); lib_vox_spin_label->setGeometry(25,122,130,19); lib_vox_spin_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); - QLabel *lib_vox_spin_unit=new QLabel(tr("dbFS"),this,"lib_vox_spin_unit"); + QLabel *lib_vox_spin_unit=new QLabel(tr("dbFS"),this); lib_vox_spin_unit->setGeometry(205,122,120,19); lib_vox_spin_unit->setAlignment(AlignLeft|AlignVCenter|ShowPrefix); // // AutoTrim threshold // - lib_trim_spin=new QSpinBox(this,"lib_trim_spin"); + lib_trim_spin=new QSpinBox(this); lib_trim_spin->setGeometry(160,144,40,19); lib_trim_spin->setMinValue(-99); lib_trim_spin->setMaxValue(0); @@ -138,182 +137,181 @@ EditRDLibrary::EditRDLibrary(RDStation *station,RDStation *cae_station, this,"lib_trim_spin_label"); lib_trim_spin_label->setGeometry(25,144,130,19); lib_trim_spin_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); - QLabel *lib_trim_spin_unit=new QLabel(tr("dbFS"),this,"lib_trim_spin_unit"); + QLabel *lib_trim_spin_unit=new QLabel(tr("dbFS"),this); lib_trim_spin_unit->setGeometry(205,144,120,19); lib_trim_spin_unit->setAlignment(AlignLeft|AlignVCenter|ShowPrefix); // // Tail Preroll // - lib_preroll_spin=new QSpinBox(this,"lib_preroll_spin"); + lib_preroll_spin=new QSpinBox(this); lib_preroll_spin->setGeometry(160,166,50,19); lib_preroll_spin->setMinValue(0); lib_preroll_spin->setMaxValue(10000); lib_preroll_spin->setLineStep(100); - QLabel *lib_preroll_spin_label=new QLabel(lib_preroll_spin, - tr("&Tail Preroll:"),this, - "lib_preroll_spin_label"); + QLabel *lib_preroll_spin_label= + new QLabel(lib_preroll_spin,tr("&Tail Preroll:"),this); lib_preroll_spin_label->setGeometry(25,166,130,19); lib_preroll_spin_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); - QLabel *lib_preroll_spin_unit=new QLabel(tr("milliseconds"),this, - "lib_preroll_spin_unit"); + QLabel *lib_preroll_spin_unit=new QLabel(tr("milliseconds"),this); lib_preroll_spin_unit->setGeometry(215,166,120,19); lib_preroll_spin_unit->setAlignment(AlignLeft|AlignVCenter|ShowPrefix); // // Ripper Device // - lib_ripdev_edit=new QLineEdit(this,"lib_ripper_device"); + lib_ripdev_edit=new QLineEdit(this); lib_ripdev_edit->setGeometry(160,188,100,19); lib_ripdev_edit->setValidator(validator); - QLabel *lib_ripdev_label=new QLabel(lib_ripdev_edit,tr("&Ripper Device:"), - this,"lib_format_label"); + QLabel *lib_ripdev_label= + new QLabel(lib_ripdev_edit,tr("&Ripper Device:"),this); lib_ripdev_label->setGeometry(25,188,130,19); lib_ripdev_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); // // Paranoia Level // - lib_paranoia_box=new QComboBox(this,"lib_paranoia_box"); + lib_paranoia_box=new QComboBox(this); lib_paranoia_box->setGeometry(160,210,100,19); QLabel *lib_paranoia_label= - new QLabel(lib_paranoia_box,tr("&Paranoia Level:"), - this,"lib_paranoia_label"); + new QLabel(lib_paranoia_box,tr("&Paranoia Level:"),this); lib_paranoia_label->setGeometry(25,210,130,19); lib_paranoia_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); + // + // Read ISRC + // + lib_isrc_box=new QComboBox(this); + lib_isrc_box->setGeometry(160,232,60,19); + QLabel *lib_isrc_label= + new QLabel(lib_isrc_box,tr("&Read ISRCs from CD:"),this); + lib_isrc_label->setGeometry(25,232,130,19); + lib_isrc_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); + // // Ripper Level // - lib_riplevel_spin=new QSpinBox(this,"lib_riplevel_spin"); - lib_riplevel_spin->setGeometry(160,232,40,19); + lib_riplevel_spin=new QSpinBox(this); + lib_riplevel_spin->setGeometry(160,254,40,19); lib_riplevel_spin->setMinValue(-99); lib_riplevel_spin->setMaxValue(0); - QLabel *lib_riplevel_spin_label=new QLabel(lib_riplevel_spin, - tr("Ripper Level:"),this, - "lib_riplevel_spin_label"); - lib_riplevel_spin_label->setGeometry(25,232,130,19); + QLabel *lib_riplevel_spin_label= + new QLabel(lib_riplevel_spin,tr("Ripper Level:"),this); + lib_riplevel_spin_label->setGeometry(25,254,130,19); lib_riplevel_spin_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); - QLabel *lib_riplevel_spin_unit=new QLabel(tr("dbFS"), - this,"lib_riplevel_spin_unit"); - lib_riplevel_spin_unit->setGeometry(205,232,120,19); + QLabel *lib_riplevel_spin_unit=new QLabel(tr("dbFS"),this); + lib_riplevel_spin_unit->setGeometry(205,254,120,19); lib_riplevel_spin_unit->setAlignment(AlignLeft|AlignVCenter|ShowPrefix); // // FreeDB Server // - lib_cddb_edit=new QLineEdit(this,"lib_cddb_edit"); - lib_cddb_edit->setGeometry(160,256,160,19); + lib_cddb_edit=new QLineEdit(this); + lib_cddb_edit->setGeometry(160,278,160,19); lib_cddb_edit->setValidator(validator); - QLabel *lib_cddb_label=new QLabel(lib_cddb_edit,tr("&FreeDB Server:"),this, - "lib_cddb_label"); - lib_cddb_label->setGeometry(25,256,130,19); + QLabel *lib_cddb_label=new QLabel(lib_cddb_edit,tr("&FreeDB Server:"),this); + lib_cddb_label->setGeometry(25,278,130,19); lib_cddb_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); // // Format // - lib_format_box=new QComboBox(this,"lib_format_box"); - lib_format_box->setGeometry(160,280,150,19); + lib_format_box=new QComboBox(this); + lib_format_box->setGeometry(160,302,150,19); connect(lib_format_box,SIGNAL(activated(int)),this,SLOT(formatData(int))); - QLabel *lib_format_label=new QLabel(lib_format_box,tr("&Format:"),this, - "lib_format_label"); - lib_format_label->setGeometry(25,280,130,19); + QLabel *lib_format_label=new QLabel(lib_format_box,tr("&Format:"),this); + + lib_format_label->setGeometry(25,302,130,19); lib_format_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); // // Bitrate // - lib_bitrate_box=new QComboBox(this,"lib_bitrate_box"); - lib_bitrate_box->setGeometry(160,304,130,19); - QLabel *lib_bitrate_label=new QLabel(lib_bitrate_box,tr("&Bitrate:"),this, - "lib_bitrate_label"); - lib_bitrate_label->setGeometry(25,304,130,19); + lib_bitrate_box=new QComboBox(this); + lib_bitrate_box->setGeometry(160,326,130,19); + QLabel *lib_bitrate_label=new QLabel(lib_bitrate_box,tr("&Bitrate:"),this); + lib_bitrate_label->setGeometry(25,326,130,19); lib_bitrate_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); // // Enable Editor // - lib_editor_box=new QComboBox(this,"lib_editor_box"); - lib_editor_box->setGeometry(160,328,60,19); + lib_editor_box=new QComboBox(this); + lib_editor_box->setGeometry(160,350,60,19); lib_editor_box->insertItem(tr("No")); lib_editor_box->insertItem(tr("Yes")); - QLabel *lib_editor_label=new QLabel(lib_editor_box, - tr("Allow E&xternal Editing:"),this, - "lib_editor_label"); - lib_editor_label->setGeometry(25,328,130,19); + QLabel *lib_editor_label= + new QLabel(lib_editor_box,tr("Allow E&xternal Editing:"),this); + lib_editor_label->setGeometry(25,350,130,19); lib_editor_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); // // Sample Rate Converter // - lib_converter_box=new QComboBox(this,"lib_converter_box"); - lib_converter_box->setGeometry(160,352,sizeHint().width()-170,19); + lib_converter_box=new QComboBox(this); + lib_converter_box->setGeometry(160,374,sizeHint().width()-170,19); int conv=0; while(src_get_name(conv)!=NULL) { lib_converter_box->insertItem(src_get_name(conv++)); } - QLabel *lib_converter_label=new QLabel(lib_converter_box, - tr("Sample Rate Converter:"),this, - "lib_converter_label"); - lib_converter_label->setGeometry(10,352,145,19); + QLabel *lib_converter_label= + new QLabel(lib_converter_box,tr("Sample Rate Converter:"),this); + lib_converter_label->setGeometry(10,374,145,19); lib_converter_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); // // Limit Searches at Startup // lib_limit_search_box=new QComboBox(this); - lib_limit_search_box->setGeometry(160,376,80,19); + lib_limit_search_box->setGeometry(160,398,80,19); lib_limit_search_box->insertItem(tr("No")); lib_limit_search_box->insertItem(tr("Yes")); lib_limit_search_box->insertItem(tr("Previous")); QLabel *lib_limit_search_label= new QLabel(lib_limit_search_box,tr("Limit Searches at Startup")+":",this); - lib_limit_search_label->setGeometry(10,376,145,19); + lib_limit_search_label->setGeometry(10,398,145,19); lib_limit_search_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); // // Defaults // - QLabel *default_label=new QLabel(tr("Defaults"),this,"default_label"); - default_label->setGeometry(25,415,120,19); + QLabel *default_label=new QLabel(tr("Defaults"),this); + default_label->setGeometry(25,437,120,19); default_label->setFont(big_font); default_label->setAlignment(AlignRight|ShowPrefix); // // Default Channels // - lib_channels_box=new QComboBox(this,"lib_channels_box"); - lib_channels_box->setGeometry(160,434,60,19); - QLabel *lib_channels_label=new QLabel(lib_channels_box,tr("&Channels:"),this, - "lib_channels_label"); - lib_channels_label->setGeometry(25,434,130,19); + lib_channels_box=new QComboBox(this); + lib_channels_box->setGeometry(160,456,60,19); + QLabel *lib_channels_label=new QLabel(lib_channels_box,tr("&Channels:"),this); + lib_channels_label->setGeometry(25,456,130,19); lib_channels_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); // // Default Record Mode // - lib_recmode_box=new QComboBox(this,"lib_recmode_box"); - lib_recmode_box->setGeometry(160,456,100,19); - QLabel *lib_recmode_label=new QLabel(lib_recmode_box,tr("Record Mode:"),this, - "lib_recmode_label"); - lib_recmode_label->setGeometry(25,456,130,19); + lib_recmode_box=new QComboBox(this); + lib_recmode_box->setGeometry(160,478,100,19); + QLabel *lib_recmode_label=new QLabel(lib_recmode_box,tr("Record Mode:"),this); + lib_recmode_label->setGeometry(25,478,130,19); lib_recmode_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); // // Default Trim State // - lib_trimstate_box=new QComboBox(this,"lib_trimstate_box"); - lib_trimstate_box->setGeometry(160,480,100,19); - QLabel *lib_trimstate_label=new QLabel(lib_trimstate_box,tr("AutoTrim:"), - this,"lib_trimstate_label"); - lib_trimstate_label->setGeometry(25,480,130,19); + lib_trimstate_box=new QComboBox(this); + lib_trimstate_box->setGeometry(160,502,100,19); + QLabel *lib_trimstate_label= + new QLabel(lib_trimstate_box,tr("AutoTrim:"),this); + lib_trimstate_label->setGeometry(25,502,130,19); lib_trimstate_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); // // Ok Button // - QPushButton *ok_button=new QPushButton(this,"ok_button"); + QPushButton *ok_button=new QPushButton(this); ok_button->setGeometry(sizeHint().width()-180,sizeHint().height()-60,80,50); ok_button->setDefault(true); ok_button->setFont(small_font); @@ -323,7 +321,7 @@ EditRDLibrary::EditRDLibrary(RDStation *station,RDStation *cae_station, // // Cancel Button // - QPushButton *cancel_button=new QPushButton(this,"cancel_button"); + QPushButton *cancel_button=new QPushButton(this); cancel_button->setGeometry(sizeHint().width()-90,sizeHint().height()-60, 80,50); cancel_button->setFont(small_font); @@ -360,6 +358,9 @@ EditRDLibrary::EditRDLibrary(RDStation *station,RDStation *cae_station, lib_paranoia_box->insertItem(tr("Low")); lib_paranoia_box->insertItem(tr("None")); lib_paranoia_box->setCurrentItem(lib_lib->paranoiaLevel()); + lib_isrc_box->insertItem(tr("No")); + lib_isrc_box->insertItem(tr("Yes")); + lib_isrc_box->setCurrentItem(lib_lib->readIsrc()); lib_riplevel_spin->setValue(lib_lib->ripperLevel()/100); lib_format_box->insertItem(tr("PCM16")); lib_format_box->insertItem(tr("MPEG Layer 2")); @@ -407,7 +408,7 @@ EditRDLibrary::~EditRDLibrary() QSize EditRDLibrary::sizeHint() const { - return QSize(375,584); + return QSize(375,606); } @@ -437,6 +438,7 @@ void EditRDLibrary::okData() lib_lib->setTailPreroll(lib_preroll_spin->value()); lib_lib->setRipperDevice(lib_ripdev_edit->text()); lib_lib->setParanoiaLevel(lib_paranoia_box->currentItem()); + lib_lib->setReadIsrc(lib_isrc_box->currentItem()); lib_lib->setRipperLevel(lib_riplevel_spin->value()*100); lib_lib->setDefaultFormat(lib_format_box->currentItem()); lib_lib->setDefaultChannels(lib_channels_box->currentItem()+1); diff --git a/rdadmin/edit_rdlibrary.h b/rdadmin/edit_rdlibrary.h index 121d851d..715896eb 100644 --- a/rdadmin/edit_rdlibrary.h +++ b/rdadmin/edit_rdlibrary.h @@ -39,8 +39,7 @@ class EditRDLibrary : public QDialog { Q_OBJECT public: - EditRDLibrary(RDStation *station,RDStation *cae_station, - QWidget *parent=0,const char *name=0); + EditRDLibrary(RDStation *station,RDStation *cae_station,QWidget *parent=0); ~EditRDLibrary(); QSize sizeHint() const; QSizePolicy sizePolicy() const; @@ -66,6 +65,7 @@ class EditRDLibrary : public QDialog QTimeEdit *lib_maxlength_time; QLineEdit *lib_ripdev_edit; QComboBox *lib_paranoia_box; + QComboBox *lib_isrc_box; QSpinBox *lib_riplevel_spin; QLineEdit *lib_cddb_edit; QComboBox *lib_editor_box; diff --git a/rdadmin/rdadmin_cs.ts b/rdadmin/rdadmin_cs.ts index 0997e1ac..4288d62b 100644 --- a/rdadmin/rdadmin_cs.ts +++ b/rdadmin/rdadmin_cs.ts @@ -2814,6 +2814,10 @@ nastaveném pro běh služby CAE pro naplnění databáze se zdroji zvuku.Previous Předchozí + + &Read ISRCs from CD: + + EditRDLogedit diff --git a/rdadmin/rdadmin_de.ts b/rdadmin/rdadmin_de.ts index 9751a577..f1fccca7 100644 --- a/rdadmin/rdadmin_de.ts +++ b/rdadmin/rdadmin_de.ts @@ -2785,6 +2785,10 @@ configured to run the CAE service in order to populate the audio resources datab Previous Vorherige + + &Read ISRCs from CD: + + EditRDLogedit diff --git a/rdadmin/rdadmin_es.ts b/rdadmin/rdadmin_es.ts index d25df961..4f02fa51 100644 --- a/rdadmin/rdadmin_es.ts +++ b/rdadmin/rdadmin_es.ts @@ -2794,6 +2794,10 @@ equipo configurado para ejecutar CAE para obtener la información de audio.Limit Searches at Startup + + &Read ISRCs from CD: + + EditRDLogedit diff --git a/rdadmin/rdadmin_fr.ts b/rdadmin/rdadmin_fr.ts index 47bed8ce..a6161080 100644 --- a/rdadmin/rdadmin_fr.ts +++ b/rdadmin/rdadmin_fr.ts @@ -2509,6 +2509,10 @@ configured to run the CAE service in order to populate the audio resources datab Previous + + &Read ISRCs from CD: + + EditRDLogedit diff --git a/rdadmin/rdadmin_nb.ts b/rdadmin/rdadmin_nb.ts index 32dd67a3..c3384f74 100644 --- a/rdadmin/rdadmin_nb.ts +++ b/rdadmin/rdadmin_nb.ts @@ -2781,6 +2781,10 @@ configured to run the CAE service in order to populate the audio resources datab Previous Førre + + &Read ISRCs from CD: + + EditRDLogedit diff --git a/rdadmin/rdadmin_nn.ts b/rdadmin/rdadmin_nn.ts index 32dd67a3..c3384f74 100644 --- a/rdadmin/rdadmin_nn.ts +++ b/rdadmin/rdadmin_nn.ts @@ -2781,6 +2781,10 @@ configured to run the CAE service in order to populate the audio resources datab Previous Førre + + &Read ISRCs from CD: + + EditRDLogedit diff --git a/rdadmin/rdadmin_pt_BR.ts b/rdadmin/rdadmin_pt_BR.ts index 5c9c37db..acd1e8c6 100644 --- a/rdadmin/rdadmin_pt_BR.ts +++ b/rdadmin/rdadmin_pt_BR.ts @@ -2773,6 +2773,10 @@ configured to run the CAE service in order to populate the audio resources datab Previous Anterior + + &Read ISRCs from CD: + + EditRDLogedit diff --git a/rdlibrary/cdripper.cpp b/rdlibrary/cdripper.cpp index df26f678..4b877985 100644 --- a/rdlibrary/cdripper.cpp +++ b/rdlibrary/cdripper.cpp @@ -461,7 +461,9 @@ void CdRipper::ripTrackButtonData() // Read ISRCs // if(!rip_isrc_read) { - rip_cddb_lookup->readIsrc(rip_cdda_dir.path(),rip_conf->ripperDevice()); + if(rdlibrary_conf->readIsrc()) { + rip_cddb_lookup->readIsrc(rip_cdda_dir.path(),rip_conf->ripperDevice()); + } rip_isrc_read=true; } diff --git a/rdlibrary/disk_ripper.cpp b/rdlibrary/disk_ripper.cpp index 96453228..4ba30e9a 100644 --- a/rdlibrary/disk_ripper.cpp +++ b/rdlibrary/disk_ripper.cpp @@ -433,8 +433,10 @@ void DiskRipper::ripDiskButtonData() // Read ISRCs // if(!rip_isrc_read) { - rip_cddb_lookup-> - readIsrc(rip_cdda_dir.path(),rdlibrary_conf->ripperDevice()); + if(rdlibrary_conf->readIsrc()) { + rip_cddb_lookup-> + readIsrc(rip_cdda_dir.path(),rdlibrary_conf->ripperDevice()); + } rip_isrc_read=true; } From d45219fc8ff41440dbc079015d65056a4542f927 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Tue, 21 Apr 2015 18:17:08 -0400 Subject: [PATCH 28/34] 2015-04-21 Fred Gleason * Incremented the package version to 2.10.3int02. --- ChangeLog | 2 ++ PACKAGE_VERSION | 2 +- rivendell.ism | Bin 499284 -> 499284 bytes 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 59fc08cc..07860e05 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14864,3 +14864,5 @@ ripper in 'rdlibrary/disk_ripper.cpp'. * Implemented the 'Read ISRCs from CD' option in the per-track disc ripper in 'rdlibrary/cdripper.cpp'. +2015-04-21 Fred Gleason + * Incremented the package version to 2.10.3int02. diff --git a/PACKAGE_VERSION b/PACKAGE_VERSION index 86b18e84..b5789805 100644 --- a/PACKAGE_VERSION +++ b/PACKAGE_VERSION @@ -1 +1 @@ -2.10.3int01 \ No newline at end of file +2.10.3int02 \ No newline at end of file diff --git a/rivendell.ism b/rivendell.ism index c6644df65b5c40deeba96a39b147a498ee6ade67..62cbeef2b53ca7bf090b4a67b6a19fed2901e4a2 100755 GIT binary patch delta 16877 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 Htd9Q&z>pnW delta 18416 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 From eb1294267173f416304cc84646388229889726b4 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Wed, 20 May 2015 13:05:03 -0400 Subject: [PATCH 29/34] 2015-05-20 Fred Gleason * Added default parameters to the 'PadPoint' RLM in 'rlm_padpoint.c'. --- ChangeLog | 3 ++ rlm/rlm_padpoint.c | 88 +++++++++++++++++++++++++++++++--------------- 2 files changed, 63 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index 07860e05..a26fb92d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14866,3 +14866,6 @@ ripper in 'rdlibrary/cdripper.cpp'. 2015-04-21 Fred Gleason * Incremented the package version to 2.10.3int02. +2015-05-20 Fred Gleason + * Added default parameters to the 'PadPoint' RLM in 'rlm_padpoint.c'. + diff --git a/rlm/rlm_padpoint.c b/rlm/rlm_padpoint.c index 1330d200..41db8ae0 100644 --- a/rlm/rlm_padpoint.c +++ b/rlm/rlm_padpoint.c @@ -29,6 +29,15 @@ #include #include #include +#include +#include +#include + +#define PADPOINT_DEFAULT_ADDRESS "127.0.0.1" +#define PADPOINT_DEFAULT_PORT 3355 +#define PADPOINT_DEFAULT_MAINLOG 1 +#define PADPOINT_DEFAULT_AUX1LOG 1 +#define PADPOINT_DEFAULT_AUX2LOG 1 int rlm_padpoint_devs; char *rlm_padpoint_addresses; @@ -71,6 +80,7 @@ void rlm_padpoint_RLMStart(void *ptr,const char *arg) char address[17]; char section[256]; char errtext[256]; + struct stat info; int i=1; rlm_padpoint_devs=0; @@ -80,37 +90,59 @@ void rlm_padpoint_RLMStart(void *ptr,const char *arg) rlm_padpoint_aux1s=NULL; rlm_padpoint_aux2s=NULL; - sprintf(section,"PadPoint%d",i++); - strncpy(address,RLMGetStringValue(ptr,arg,section,"IpAddress",""),15); - if(strlen(address)==0) { - RLMLog(ptr,LOG_WARNING,"rlm_padpoint: no padpoint destinations specified"); - return; + if(stat(arg,&info)<0) { + /* + * Use default settings + */ + rlm_padpoint_addresses=realloc(rlm_padpoint_addresses,16); + strcpy(rlm_padpoint_addresses,PADPOINT_DEFAULT_ADDRESS); + rlm_padpoint_ports=realloc(rlm_padpoint_ports,sizeof(uint16_t)); + rlm_padpoint_ports[0]=PADPOINT_DEFAULT_PORT; + rlm_padpoint_masters=realloc(rlm_padpoint_masters,sizeof(int)); + rlm_padpoint_masters[0]=PADPOINT_DEFAULT_MAINLOG; + rlm_padpoint_aux1s=realloc(rlm_padpoint_aux1s,sizeof(int)); + rlm_padpoint_aux1s[0]=PADPOINT_DEFAULT_AUX1LOG; + rlm_padpoint_aux2s=realloc(rlm_padpoint_aux2s,sizeof(int)); + rlm_padpoint_aux2s[0]=PADPOINT_DEFAULT_AUX2LOG; + rlm_padpoint_devs=1; + RLMLog(ptr,LOG_INFO,"loaded default settings"); } - while(strlen(address)>0) { - rlm_padpoint_addresses= - realloc(rlm_padpoint_addresses,(rlm_padpoint_devs+1)*(rlm_padpoint_devs+1)*16); - strcpy(rlm_padpoint_addresses+16*rlm_padpoint_devs,address); - rlm_padpoint_ports=realloc(rlm_padpoint_ports,(rlm_padpoint_devs+1)*sizeof(uint16_t)); - rlm_padpoint_ports[rlm_padpoint_devs]= - RLMGetIntegerValue(ptr,arg,section,"UdpPort",0); - rlm_padpoint_masters=realloc(rlm_padpoint_masters, - (rlm_padpoint_devs+1)*sizeof(int)); - rlm_padpoint_masters[rlm_padpoint_devs]= - rlm_padpoint_GetLogStatus(ptr,arg,section,"MasterLog"); - rlm_padpoint_aux1s=realloc(rlm_padpoint_aux1s, - (rlm_padpoint_devs+1)*sizeof(int)); - rlm_padpoint_aux1s[rlm_padpoint_devs]= - rlm_padpoint_GetLogStatus(ptr,arg,section,"Aux1Log"); - rlm_padpoint_aux2s=realloc(rlm_padpoint_aux2s, - (rlm_padpoint_devs+1)*sizeof(int)); - rlm_padpoint_aux2s[rlm_padpoint_devs]= - rlm_padpoint_GetLogStatus(ptr,arg,section,"Aux2Log"); - sprintf(errtext,"rlm_padpoint: configured destination \"%s:%d\"",address, - rlm_padpoint_ports[rlm_padpoint_devs]); - rlm_padpoint_devs++; - RLMLog(ptr,LOG_INFO,errtext); + else { + /* + * Load settings from a configuration file + */ sprintf(section,"PadPoint%d",i++); strncpy(address,RLMGetStringValue(ptr,arg,section,"IpAddress",""),15); + if(strlen(address)==0) { + RLMLog(ptr,LOG_WARNING,"rlm_padpoint: no padpoint destinations specified"); + return; + } + while(strlen(address)>0) { + rlm_padpoint_addresses= + realloc(rlm_padpoint_addresses,(rlm_padpoint_devs+1)*(rlm_padpoint_devs+1)*16); + strcpy(rlm_padpoint_addresses+16*rlm_padpoint_devs,address); + rlm_padpoint_ports=realloc(rlm_padpoint_ports,(rlm_padpoint_devs+1)*sizeof(uint16_t)); + rlm_padpoint_ports[rlm_padpoint_devs]= + RLMGetIntegerValue(ptr,arg,section,"UdpPort",0); + rlm_padpoint_masters=realloc(rlm_padpoint_masters, + (rlm_padpoint_devs+1)*sizeof(int)); + rlm_padpoint_masters[rlm_padpoint_devs]= + rlm_padpoint_GetLogStatus(ptr,arg,section,"MasterLog"); + rlm_padpoint_aux1s=realloc(rlm_padpoint_aux1s, + (rlm_padpoint_devs+1)*sizeof(int)); + rlm_padpoint_aux1s[rlm_padpoint_devs]= + rlm_padpoint_GetLogStatus(ptr,arg,section,"Aux1Log"); + rlm_padpoint_aux2s=realloc(rlm_padpoint_aux2s, + (rlm_padpoint_devs+1)*sizeof(int)); + rlm_padpoint_aux2s[rlm_padpoint_devs]= + rlm_padpoint_GetLogStatus(ptr,arg,section,"Aux2Log"); + sprintf(errtext,"rlm_padpoint: configured destination \"%s:%d\"",address, + rlm_padpoint_ports[rlm_padpoint_devs]); + rlm_padpoint_devs++; + RLMLog(ptr,LOG_INFO,errtext); + sprintf(section,"PadPoint%d",i++); + strncpy(address,RLMGetStringValue(ptr,arg,section,"IpAddress",""),15); + } } } From 5f77898a63f95b601e60e06a9987a15afa6973e8 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Fri, 22 May 2015 12:47:39 -0400 Subject: [PATCH 30/34] Updated .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 42e818d3..90d4e06c 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ rivendell-*.zip .libs aclocal.m4 autom4te.cache +compile config.guess config.log config.status From 988fe7f1ebdca39a1139e79edfc9c48d2e9bda5b Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Thu, 28 May 2015 11:37:24 -0400 Subject: [PATCH 31/34] 2015-05-28 Fred Gleason * Added rdcleandirs(8) utility in 'utils/rdcleandirs/'. --- ChangeLog | 3 +- configure.ac | 1 + rivendell-suse.in | 2 + utils/Makefile.am | 1 + utils/rdcleandirs/Makefile.am | 50 +++++++++++++++++ utils/rdcleandirs/rdcleandirs.cpp | 89 +++++++++++++++++++++++++++++++ utils/rdcleandirs/rdcleandirs.h | 38 +++++++++++++ 7 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 utils/rdcleandirs/Makefile.am create mode 100644 utils/rdcleandirs/rdcleandirs.cpp create mode 100644 utils/rdcleandirs/rdcleandirs.h diff --git a/ChangeLog b/ChangeLog index a26fb92d..7eda85be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14868,4 +14868,5 @@ * Incremented the package version to 2.10.3int02. 2015-05-20 Fred Gleason * Added default parameters to the 'PadPoint' RLM in 'rlm_padpoint.c'. - +2015-05-28 Fred Gleason + * Added rdcleandirs(8) utility in 'utils/rdcleandirs/'. diff --git a/configure.ac b/configure.ac index 9276b359..8a730114 100644 --- a/configure.ac +++ b/configure.ac @@ -442,6 +442,7 @@ AC_CONFIG_FILES([rivendell.spec \ utils/rdalsaconfig/Makefile \ utils/rdcheckcuts/Makefile \ utils/rdchunk/Makefile \ + utils/rdcleandirs/Makefile \ utils/rdcollect/Makefile \ utils/rddbcheck/Makefile \ utils/rddelete/Makefile \ diff --git a/rivendell-suse.in b/rivendell-suse.in index 8fd1c6d3..c263b22b 100755 --- a/rivendell-suse.in +++ b/rivendell-suse.in @@ -37,6 +37,7 @@ function StartDaemons { + rdcleandirs if test $GPIO_START = yes ; then if test -x /etc/init.d/gpio ; then /etc/init.d/gpio status > /dev/null @@ -101,6 +102,7 @@ function StopDaemons { fi fi sleep 2 + rdcleandirs } # Set path for script functions diff --git a/utils/Makefile.am b/utils/Makefile.am index 2c80f830..5532e87a 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -34,6 +34,7 @@ SUBDIRS = $(ALSACONFIG_RD_OPT)\ rddgimport\ rdcheckcuts\ rdchunk\ + rdcleandirs\ rdcollect\ rddelete\ rddiscimport\ diff --git a/utils/rdcleandirs/Makefile.am b/utils/rdcleandirs/Makefile.am new file mode 100644 index 00000000..0928010a --- /dev/null +++ b/utils/rdcleandirs/Makefile.am @@ -0,0 +1,50 @@ +## automake.am +## +## Automake.am for rivendell/utils/rdcleandirs +## +## (C) Copyright 2015 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. +## +## Use automake to process this into a Makefile.in + +AM_CPPFLAGS = -Wall -DPREFIX=\"$(prefix)\" -DQTDIR=\"@QT_DIR@\" @QT_CXXFLAGS@ -I$(top_srcdir)/lib +LIBS = @QT_LIBS@ -L$(top_srcdir)/lib +MOC = @QT_MOC@ + +# The dependency for qt's Meta Object Compiler (moc) +moc_%.cpp: %.h + $(MOC) $< -o $@ + +sbin_PROGRAMS = rdcleandirs + +dist_rdcleandirs_SOURCES = rdcleandirs.cpp rdcleandirs.h + +rdcleandirs_LDADD = @LIB_RDLIBS@ @LIBVORBIS@ + +CLEANFILES = *~\ + *.exe\ + *.idb\ + *ilk\ + *.obj\ + *.pdb\ + *.qm\ + moc_* + +MAINTAINERCLEANFILES = *~\ + *.tar.gz\ + aclocal.m4\ + configure\ + Makefile.in\ + moc_* diff --git a/utils/rdcleandirs/rdcleandirs.cpp b/utils/rdcleandirs/rdcleandirs.cpp new file mode 100644 index 00000000..43b640db --- /dev/null +++ b/utils/rdcleandirs/rdcleandirs.cpp @@ -0,0 +1,89 @@ +// rdcleandirs.cpp +// +// Remove stale lockfiles from user directories. +// +// (C) Copyright 2010 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 + +MainObject::MainObject(QObject *parent,const char *name) + :QObject(parent,name) +{ + struct passwd *pwd=NULL; + + // + // Read Command Options + // + RDCmdSwitch *cmd= + new RDCmdSwitch(qApp->argc(),qApp->argv(),"rdcleandirs",RDCLEANDIRS_USAGE); + for(unsigned i=0;ikeys();i++) { + } + if(!cmd->allProcessed()) { + fprintf(stderr,"rdcleandirs: unknown option\n"); + exit(256); + } + + // + // Verify that we have root permissions + // + if(getuid()!=0) { + fprintf(stderr,"rdcleandirs: this program requires root permissions\n"); + exit(256); + } + + // + // Iterate through the user database + // + while((pwd=getpwent())!=NULL) { + QString user=QString(pwd->pw_name); + QString base=RDGetBasePart(pwd->pw_shell); + QString home=QString(pwd->pw_dir); + if((user!="mysql")&& + (base!="nologin")&& + (base!="null")&& + (base!="false")&& + (base!="sync")&& + (base!="shutdown")&& + (base!="halt")&& + (base!="reboot")) { + QFile::remove(home+"/.rdairplaylock"); + } + } + endpwent(); + + exit(0); +} + + +int main(int argc,char *argv[]) +{ + QApplication a(argc,argv,false); + new MainObject(NULL,"main"); + return a.exec(); +} diff --git a/utils/rdcleandirs/rdcleandirs.h b/utils/rdcleandirs/rdcleandirs.h new file mode 100644 index 00000000..4bc0ec1b --- /dev/null +++ b/utils/rdcleandirs/rdcleandirs.h @@ -0,0 +1,38 @@ +// rdcleandirs.h +// +// Remove stale lockfiles from user directories. +// +// (C) Copyright 2015 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 RDCLEANDIRS_H +#define RDCLEANDIRS_H + +#include + +#define RDCLEANDIRS_USAGE "\n" + +class MainObject : public QObject +{ + public: + MainObject(QObject *parent=0,const char *name=0); + + private: +}; + + +#endif // RDCLEANDIRS_H From 16284179cc49e154c3b9e4e3edfbd589103d99b5 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Thu, 28 May 2015 12:05:07 -0400 Subject: [PATCH 32/34] Consolidated .gitignore files --- .gitignore | 57 +++++++++++++++++++++++++++++++++++ cae/.gitignore | 1 - conf/.gitignore | 1 - helpers/.gitignore | 2 -- importers/.gitignore | 6 ---- lib/.gitignore | 1 - rdadmin/.gitignore | 1 - rdairplay/.gitignore | 1 - rdcartslots/.gitignore | 1 - rdcastmanager/.gitignore | 1 - rdcatch/.gitignore | 1 - rdcatchd/.gitignore | 1 - rdlibrary/.gitignore | 1 - rdlogedit/.gitignore | 1 - rdlogin/.gitignore | 1 - rdlogmanager/.gitignore | 1 - rdmonitor/.gitignore | 1 - rdpanel/.gitignore | 1 - rdrepld/.gitignore | 1 - rdselect/.gitignore | 1 - ripcd/.gitignore | 1 - tests/.gitignore | 11 ------- utils/rdalsaconfig/.gitignore | 1 - utils/rdcheckcuts/.gitignore | 1 - utils/rdchunk/.gitignore | 1 - utils/rdcollect/.gitignore | 1 - utils/rddbcheck/.gitignore | 1 - utils/rddelete/.gitignore | 1 - utils/rddgimport/.gitignore | 1 - utils/rddiscimport/.gitignore | 1 - utils/rdgen/.gitignore | 1 - utils/rdgpimon/.gitignore | 1 - utils/rdhpiinfo/.gitignore | 1 - utils/rdimport/.gitignore | 1 - utils/rdmaint/.gitignore | 1 - utils/rdmarkerset/.gitignore | 1 - utils/rdpopup/.gitignore | 1 - utils/rdpurgecasts/.gitignore | 1 - utils/rdsoftkeys/.gitignore | 1 - utils/rmlsend/.gitignore | 1 - utils/sas_shim/.gitignore | 1 - web/rdfeed/.gitignore | 1 - 42 files changed, 57 insertions(+), 57 deletions(-) delete mode 100644 cae/.gitignore delete mode 100644 conf/.gitignore delete mode 100644 helpers/.gitignore delete mode 100644 importers/.gitignore delete mode 100644 lib/.gitignore delete mode 100644 rdadmin/.gitignore delete mode 100644 rdairplay/.gitignore delete mode 100644 rdcartslots/.gitignore delete mode 100644 rdcastmanager/.gitignore delete mode 100644 rdcatch/.gitignore delete mode 100644 rdcatchd/.gitignore delete mode 100644 rdlibrary/.gitignore delete mode 100644 rdlogedit/.gitignore delete mode 100644 rdlogin/.gitignore delete mode 100644 rdlogmanager/.gitignore delete mode 100644 rdmonitor/.gitignore delete mode 100644 rdpanel/.gitignore delete mode 100644 rdrepld/.gitignore delete mode 100644 rdselect/.gitignore delete mode 100644 ripcd/.gitignore delete mode 100644 tests/.gitignore delete mode 100644 utils/rdalsaconfig/.gitignore delete mode 100644 utils/rdcheckcuts/.gitignore delete mode 100644 utils/rdchunk/.gitignore delete mode 100644 utils/rdcollect/.gitignore delete mode 100644 utils/rddbcheck/.gitignore delete mode 100644 utils/rddelete/.gitignore delete mode 100644 utils/rddgimport/.gitignore delete mode 100644 utils/rddiscimport/.gitignore delete mode 100644 utils/rdgen/.gitignore delete mode 100644 utils/rdgpimon/.gitignore delete mode 100644 utils/rdhpiinfo/.gitignore delete mode 100644 utils/rdimport/.gitignore delete mode 100644 utils/rdmaint/.gitignore delete mode 100644 utils/rdmarkerset/.gitignore delete mode 100644 utils/rdpopup/.gitignore delete mode 100644 utils/rdpurgecasts/.gitignore delete mode 100644 utils/rdsoftkeys/.gitignore delete mode 100644 utils/rmlsend/.gitignore delete mode 100644 utils/sas_shim/.gitignore delete mode 100644 web/rdfeed/.gitignore diff --git a/.gitignore b/.gitignore index 90d4e06c..7d55c645 100644 --- a/.gitignore +++ b/.gitignore @@ -12,14 +12,25 @@ rivendell-*.zip .libs aclocal.m4 autom4te.cache +cae/caed compile +conf/rd-bin.conf config.guess config.log config.status config.sub configure depcomp +helpers/cwrap +helpers/jsmin +importers/nexgen_filter +importers/panel_copy +importers/rdcatch_copy +importers/rivendell_filter +importers/sas_filter +importers/wings_filter install-sh +lib/rdpaths.h libtool ltmain.sh m4 @@ -28,8 +39,54 @@ missing Makefile.in Makefile moc_* +rdadmin/rdadmin +rdairplay/rdairplay +rdcastmanager/rdcastmanager +rdcartslots/rdcartslots +rdcatch/rdcatch +rdcatchd/rdcatchd +rdlibrary/rdlibrary +rdlogedit/rdlogedit +rdlogin/rdlogin +rdlogmanager/rdlogmanager +rdmonitor/rdmonitor +rdpanel/rdpanel +rdrepld/rdrepld rdrepld-suse +rdselect/rdselect +ripcd/ripcd rivendell rivendell-suse rivendell.spec slack-desc +tests/audio_convert_test +tests/audio_export_test +tests/audio_import_test +tests/datedecode_test +tests/reserve_carts_test +tests/sas_switch_torture +tests/sas_torture +tests/stringcode_test +tests/test_pam +tests/timer_test +tests/upload_test +utils/rdhpiinfo/rdhpiinfo +utils/rddgimport/rddgimport +utils/rddiscimport/rddiscimport +utils/rdcheckcuts/rdcheckcuts +utils/rdmarkerset/rdmarkerset +utils/rmlsend/rmlsend +utils/rdpurgecasts/rdpurgecasts +utils/rdchunk/rdchunk +utils/rdsoftkeys/rdsoftkeys +utils/rddbcheck/rddbcheck +utils/rdalsaconfig/rdalsaconfig +utils/rdpopup/rdpopup +utils/rddelete/rddelete +utils/rdgpimon/rdgpimon +utils/rdimport/rdimport +utils/rdcollect/rdcollect +utils/rdmaint/rdmaint +utils/rdgen/rdgen +utils/sas_shim/sas_shim +web/rdfeed/rdfeed.xml diff --git a/cae/.gitignore b/cae/.gitignore deleted file mode 100644 index 9157954a..00000000 --- a/cae/.gitignore +++ /dev/null @@ -1 +0,0 @@ -caed diff --git a/conf/.gitignore b/conf/.gitignore deleted file mode 100644 index 11df79b6..00000000 --- a/conf/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rd-bin.conf diff --git a/helpers/.gitignore b/helpers/.gitignore deleted file mode 100644 index 376a8812..00000000 --- a/helpers/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -cwrap -jsmin diff --git a/importers/.gitignore b/importers/.gitignore deleted file mode 100644 index 2bc56fdc..00000000 --- a/importers/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -nexgen_filter -panel_copy -rdcatch_copy -rivendell_filter -sas_filter -wings_filter diff --git a/lib/.gitignore b/lib/.gitignore deleted file mode 100644 index 3b465b31..00000000 --- a/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdpaths.h diff --git a/rdadmin/.gitignore b/rdadmin/.gitignore deleted file mode 100644 index 05fabb76..00000000 --- a/rdadmin/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdadmin diff --git a/rdairplay/.gitignore b/rdairplay/.gitignore deleted file mode 100644 index 57c95a00..00000000 --- a/rdairplay/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdairplay diff --git a/rdcartslots/.gitignore b/rdcartslots/.gitignore deleted file mode 100644 index db7a05cb..00000000 --- a/rdcartslots/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdcartslots diff --git a/rdcastmanager/.gitignore b/rdcastmanager/.gitignore deleted file mode 100644 index 5a968570..00000000 --- a/rdcastmanager/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdcastmanager diff --git a/rdcatch/.gitignore b/rdcatch/.gitignore deleted file mode 100644 index 584bc63e..00000000 --- a/rdcatch/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdcatch diff --git a/rdcatchd/.gitignore b/rdcatchd/.gitignore deleted file mode 100644 index d1d30992..00000000 --- a/rdcatchd/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdcatchd diff --git a/rdlibrary/.gitignore b/rdlibrary/.gitignore deleted file mode 100644 index ac83bb12..00000000 --- a/rdlibrary/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdlibrary diff --git a/rdlogedit/.gitignore b/rdlogedit/.gitignore deleted file mode 100644 index 8b5638cb..00000000 --- a/rdlogedit/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdlogedit diff --git a/rdlogin/.gitignore b/rdlogin/.gitignore deleted file mode 100644 index 9ad30a7b..00000000 --- a/rdlogin/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdlogin diff --git a/rdlogmanager/.gitignore b/rdlogmanager/.gitignore deleted file mode 100644 index c6eca06e..00000000 --- a/rdlogmanager/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdlogmanager diff --git a/rdmonitor/.gitignore b/rdmonitor/.gitignore deleted file mode 100644 index da49517a..00000000 --- a/rdmonitor/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdmonitor diff --git a/rdpanel/.gitignore b/rdpanel/.gitignore deleted file mode 100644 index 12d3aa93..00000000 --- a/rdpanel/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdpanel diff --git a/rdrepld/.gitignore b/rdrepld/.gitignore deleted file mode 100644 index fc070956..00000000 --- a/rdrepld/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdrepld diff --git a/rdselect/.gitignore b/rdselect/.gitignore deleted file mode 100644 index f5771ac5..00000000 --- a/rdselect/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdselect diff --git a/ripcd/.gitignore b/ripcd/.gitignore deleted file mode 100644 index 68046cc4..00000000 --- a/ripcd/.gitignore +++ /dev/null @@ -1 +0,0 @@ -ripcd diff --git a/tests/.gitignore b/tests/.gitignore deleted file mode 100644 index 5a4f746f..00000000 --- a/tests/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -audio_convert_test -audio_export_test -audio_import_test -datedecode_test -reserve_carts_test -sas_switch_torture -sas_torture -stringcode_test -test_pam -timer_test -upload_test diff --git a/utils/rdalsaconfig/.gitignore b/utils/rdalsaconfig/.gitignore deleted file mode 100644 index cacc6f1f..00000000 --- a/utils/rdalsaconfig/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdalsaconfig diff --git a/utils/rdcheckcuts/.gitignore b/utils/rdcheckcuts/.gitignore deleted file mode 100644 index 530db39a..00000000 --- a/utils/rdcheckcuts/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdcheckcuts diff --git a/utils/rdchunk/.gitignore b/utils/rdchunk/.gitignore deleted file mode 100644 index a8479b88..00000000 --- a/utils/rdchunk/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdchunk diff --git a/utils/rdcollect/.gitignore b/utils/rdcollect/.gitignore deleted file mode 100644 index 8afa313d..00000000 --- a/utils/rdcollect/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdcollect diff --git a/utils/rddbcheck/.gitignore b/utils/rddbcheck/.gitignore deleted file mode 100644 index 0fab7ff9..00000000 --- a/utils/rddbcheck/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rddbcheck diff --git a/utils/rddelete/.gitignore b/utils/rddelete/.gitignore deleted file mode 100644 index fd4fa7ef..00000000 --- a/utils/rddelete/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rddelete diff --git a/utils/rddgimport/.gitignore b/utils/rddgimport/.gitignore deleted file mode 100644 index abd16b0b..00000000 --- a/utils/rddgimport/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rddgimport diff --git a/utils/rddiscimport/.gitignore b/utils/rddiscimport/.gitignore deleted file mode 100644 index 7597458a..00000000 --- a/utils/rddiscimport/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rddiscimport diff --git a/utils/rdgen/.gitignore b/utils/rdgen/.gitignore deleted file mode 100644 index 09ef4ae9..00000000 --- a/utils/rdgen/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdgen diff --git a/utils/rdgpimon/.gitignore b/utils/rdgpimon/.gitignore deleted file mode 100644 index 0b157008..00000000 --- a/utils/rdgpimon/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdgpimon diff --git a/utils/rdhpiinfo/.gitignore b/utils/rdhpiinfo/.gitignore deleted file mode 100644 index 3c944d4d..00000000 --- a/utils/rdhpiinfo/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdhpiinfo diff --git a/utils/rdimport/.gitignore b/utils/rdimport/.gitignore deleted file mode 100644 index 6f1b2383..00000000 --- a/utils/rdimport/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdimport diff --git a/utils/rdmaint/.gitignore b/utils/rdmaint/.gitignore deleted file mode 100644 index 2484a6ef..00000000 --- a/utils/rdmaint/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdmaint diff --git a/utils/rdmarkerset/.gitignore b/utils/rdmarkerset/.gitignore deleted file mode 100644 index ba3da460..00000000 --- a/utils/rdmarkerset/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdmarkerset diff --git a/utils/rdpopup/.gitignore b/utils/rdpopup/.gitignore deleted file mode 100644 index 05c8116e..00000000 --- a/utils/rdpopup/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdpopup diff --git a/utils/rdpurgecasts/.gitignore b/utils/rdpurgecasts/.gitignore deleted file mode 100644 index f8fe45f2..00000000 --- a/utils/rdpurgecasts/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdpurgecasts diff --git a/utils/rdsoftkeys/.gitignore b/utils/rdsoftkeys/.gitignore deleted file mode 100644 index fa8bb41d..00000000 --- a/utils/rdsoftkeys/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdsoftkeys diff --git a/utils/rmlsend/.gitignore b/utils/rmlsend/.gitignore deleted file mode 100644 index 5282d7fe..00000000 --- a/utils/rmlsend/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rmlsend diff --git a/utils/sas_shim/.gitignore b/utils/sas_shim/.gitignore deleted file mode 100644 index 7ae7dc2e..00000000 --- a/utils/sas_shim/.gitignore +++ /dev/null @@ -1 +0,0 @@ -sas_shim diff --git a/web/rdfeed/.gitignore b/web/rdfeed/.gitignore deleted file mode 100644 index 09bd30cd..00000000 --- a/web/rdfeed/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rdfeed.xml From 888711270d94f3acc1f5799d7a0b7d6e609cd616 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Fri, 29 May 2015 07:13:05 -0400 Subject: [PATCH 33/34] 2015-05-28 Fred Gleason * Added an 'RDMatrix::RossNkScp' value to the 'RDMatrix::Type' enumeration in 'lib/rdmatrix.cpp' and 'lib/rdmatrix.h'. * Implemented a switcher driver for the Ross NK line of video switchers via the SCP/A serial interface in 'ripcd/rossnkscp.cpp' and 'riptcd/rossnkscp.h'. --- ChangeLog | 6 +++ docs/SWITCHERS.txt | 17 +++++++ lib/rdmatrix.cpp | 13 +++-- lib/rdmatrix.h | 2 +- ripcd/Makefile.am | 2 + ripcd/loaddrivers.cpp | 5 ++ ripcd/rossnkscp.cpp | 114 ++++++++++++++++++++++++++++++++++++++++++ ripcd/rossnkscp.h | 55 ++++++++++++++++++++ 8 files changed, 210 insertions(+), 4 deletions(-) create mode 100644 ripcd/rossnkscp.cpp create mode 100644 ripcd/rossnkscp.h diff --git a/ChangeLog b/ChangeLog index 7eda85be..2de06438 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14870,3 +14870,9 @@ * Added default parameters to the 'PadPoint' RLM in 'rlm_padpoint.c'. 2015-05-28 Fred Gleason * Added rdcleandirs(8) utility in 'utils/rdcleandirs/'. +2015-05-28 Fred Gleason + * Added an 'RDMatrix::RossNkScp' value to the 'RDMatrix::Type' + enumeration in 'lib/rdmatrix.cpp' and 'lib/rdmatrix.h'. + * Implemented a switcher driver for the Ross NK line of video + switchers via the SCP/A serial interface in 'ripcd/rossnkscp.cpp' + and 'riptcd/rossnkscp.h'. diff --git a/docs/SWITCHERS.txt b/docs/SWITCHERS.txt index b7a1b8f8..956f9e14 100644 --- a/docs/SWITCHERS.txt +++ b/docs/SWITCHERS.txt @@ -22,6 +22,7 @@ LiveWire Multicast GPIO Local Audio Adapter Logitek vGuest Quartz Electronics Type 1 Routing Protocol +Ross NK Video Switchers (via SCP/A Serial Interface) Serial Port Modem Control Lines Sierra Automated Systems 16000(D) Audio Router Sierra Automated Systems 32000 Audio Router @@ -511,6 +512,22 @@ Control can done either by means of an RS-232C connection or by means of TCP/IP to TCP port 23. +---------------------------------------------------------------------------- +Ross NK Video Switchers (via SCP/A Serial Interface) + +Driver Name: Ross NK-SCP/A Interface + +Supported RML Commands: + Switch Take ('ST') + +GENERAL NOTES: +Control is done by means of an RS-232C connection to a NK-SCP/A serial +interface. Serial port parameters should be set to 9600 baud rate, no parity, +8 data bits, 1 stop bit, CR termination. The Breakaway to use is defined +by setting the 'Card' parameter in the driver configuration, with +Card 0 = Breakaway 1, Card 1 = Breakaway 2, etc. + + ---------------------------------------------------------------------------- SERIAL PORT MODEM CONTROL LINES diff --git a/lib/rdmatrix.cpp b/lib/rdmatrix.cpp index 71ec588b..d10b84a7 100644 --- a/lib/rdmatrix.cpp +++ b/lib/rdmatrix.cpp @@ -65,7 +65,8 @@ bool __mx_primary_controls[RDMatrix::LastType][RDMatrix::LastControl]= {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}, // BT GPI-16 {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}, // Modem Lines {0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0}, // Software Authority - {0,1,1,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,1,0,0,0,0} // SAS 16000 + {0,1,1,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,1,0,0,0,0}, // SAS 16000 + {0,1,0,0,0,0,0,0,1,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0} // Ross NK/SCP }; bool __mx_backup_controls[RDMatrix::LastType][RDMatrix::LastControl]= { @@ -105,7 +106,8 @@ bool __mx_backup_controls[RDMatrix::LastType][RDMatrix::LastControl]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT GPI-16 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Modem Lines {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Software Authority - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // SAS 16000 + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // SAS 16000 + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // ROSS NK/SCP }; int __mx_default_values[RDMatrix::LastType][RDMatrix::LastControl]= @@ -146,7 +148,8 @@ int __mx_default_values[RDMatrix::LastType][RDMatrix::LastControl]= {0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT GPI-16 {0,0,0,0,0,0,0,0,0,0,0,0,0,4,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // Modem Lines {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // Software Authority - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0} // SAS 16000 + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // SAS 16000 + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0} // Ross NK/SCP }; RDMatrix::RDMatrix(const QString &station,int matrix) @@ -698,6 +701,10 @@ QString RDMatrix::typeString(RDMatrix::Type type) return QString("Software Authority Protocol"); break; + case RDMatrix::RossNkScp: + return QString("Ross NK-SCP/A Interface"); + break; + default: return QString("Unknown Type"); break; diff --git a/lib/rdmatrix.h b/lib/rdmatrix.h index 4cce1d15..a66b75d4 100644 --- a/lib/rdmatrix.h +++ b/lib/rdmatrix.h @@ -38,7 +38,7 @@ class RDMatrix BtSs42=19,LiveWireLwrpAudio=20,Quartz1=21,BtSs44=22,BtSrc8III=23, BtSrc16=24,Harlond=25,Acu1p=26,LiveWireMcastGpio=27,Am16=28, LiveWireLwrpGpio=29,BtSentinel4Web=30,BtGpi16=31,ModemLines=32, - SoftwareAuthority=33,Sas16000=34,LastType=35}; + SoftwareAuthority=33,Sas16000=34,RossNkScp=35,LastType=36}; enum Endpoint {Input=0,Output=1}; enum Mode {Stereo=0,Left=1,Right=2}; enum VguestAttribute {VguestEngine=0,VguestDevice=1,VguestSurface=2, diff --git a/ripcd/Makefile.am b/ripcd/Makefile.am index 14e6b972..2eb6944d 100644 --- a/ripcd/Makefile.am +++ b/ripcd/Makefile.am @@ -60,6 +60,7 @@ dist_ripcd_SOURCES = acu1p.cpp acu1p.h\ ripcd.cpp ripcd.h globals.h\ ripcd_connection.cpp ripcd_connection.h\ ripcd_socket.cpp ripcd_socket.h\ + rossnkscp.cpp rossnkscp.h\ sas32000.cpp sas32000.h\ sas64000.cpp sas64000.h\ sas64000gpi.cpp sas64000gpi.h\ @@ -99,6 +100,7 @@ nodist_ripcd_SOURCES = moc_am16.cpp\ moc_quartz1.cpp\ moc_ripcd.cpp\ moc_ripcd_socket.cpp\ + moc_rossnkscp.cpp\ moc_sas32000.cpp\ moc_sas64000.cpp\ moc_sas64000gpi.cpp\ diff --git a/ripcd/loaddrivers.cpp b/ripcd/loaddrivers.cpp index c2b85358..4ec8be4c 100644 --- a/ripcd/loaddrivers.cpp +++ b/ripcd/loaddrivers.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -164,6 +165,10 @@ bool MainObject::LoadSwitchDriver(int matrix_num) ripcd_switcher[matrix_num]=new Quartz1(matrix,this); break; + case RDMatrix::RossNkScp: + ripcd_switcher[matrix_num]=new RossNkScp(matrix,this); + break; + case RDMatrix::Sas16000: ripcd_switcher[matrix_num]=new Sas16000(matrix,this); break; diff --git a/ripcd/rossnkscp.cpp b/ripcd/rossnkscp.cpp new file mode 100644 index 00000000..da0267ae --- /dev/null +++ b/ripcd/rossnkscp.cpp @@ -0,0 +1,114 @@ +// rossnkscp.cpp +// +// A Rivendell switcher driver for the Ross NK switchers via the SCP/A +// +// (C) Copyright 2002-2015 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 + + +RossNkScp::RossNkScp(RDMatrix *matrix,QObject *parent,const char *name) + : Switcher(matrix,parent,name) +{ + // + // Get Matrix Parameters + // + ross_inputs=matrix->inputs(); + ross_outputs=matrix->outputs(); + ross_breakaway=matrix->card()+1; + + // + // Initialize the TTY Port + // + RDTty *tty=new RDTty(rdstation->name(),matrix->port(RDMatrix::Primary)); + ross_device=new RDTTYDevice(); + if(tty->active()) { + ross_device->setName(tty->port()); + ross_device->setSpeed(tty->baudRate()); + ross_device->setWordLength(tty->dataBits()); + ross_device->setParity(tty->parity()); + ross_device->open(IO_Raw|IO_ReadWrite); + } + delete tty; +} + + +RossNkScp::~RossNkScp() +{ + delete ross_device; +} + + +RDMatrix::Type RossNkScp::type() +{ + return RDMatrix::RossNkScp; +} + + +unsigned RossNkScp::gpiQuantity() +{ + return 0; +} + + +unsigned RossNkScp::gpoQuantity() +{ + return 0; +} + + +bool RossNkScp::primaryTtyActive() +{ + return true; +} + + +bool RossNkScp::secondaryTtyActive() +{ + return false; +} + + +void RossNkScp::processCommand(RDMacro *cmd) +{ + char str[11]; + + switch(cmd->command()) { + case RDMacro::ST: + if((cmd->arg(1).toInt()<=0)||(cmd->arg(1).toInt()>ross_inputs)|| + (cmd->arg(2).toInt()<1)||(cmd->arg(2).toInt()>ross_outputs)) { + cmd->acknowledge(false); + emit rmlEcho(cmd); + return; + } + sprintf(str,"X%03d,%03d,%d\x0d",cmd->arg(2).toInt()-1, + cmd->arg(1).toInt()-1,ross_breakaway); + syslog(LOG_WARNING,"sent: %s\n",str); + ross_device->writeBlock(str,11); + cmd->acknowledge(true); + emit rmlEcho(cmd); + break; + + default: + cmd->acknowledge(false); + emit rmlEcho(cmd); + break; + } +} diff --git a/ripcd/rossnkscp.h b/ripcd/rossnkscp.h new file mode 100644 index 00000000..ad3dce86 --- /dev/null +++ b/ripcd/rossnkscp.h @@ -0,0 +1,55 @@ +// rossnkscp.h +// +// A Rivendell switcher driver for the Ross NK switchers via the SCP/A +// +// (C) Copyright 2015 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 ROSSNKSCP_H +#define ROSSNKSCP_H + +#include +#include +#include +#include + +#include + +#define ROSSNKSCP_MIN_GAIN -99 +#define ROSSNKSCP_MAX_GAIN 28 + +class RossNkScp : public Switcher +{ + Q_OBJECT + public: + RossNkScp(RDMatrix *matrix,QObject *parent=0,const char *name=0); + ~RossNkScp(); + RDMatrix::Type type(); + unsigned gpiQuantity(); + unsigned gpoQuantity(); + bool primaryTtyActive(); + bool secondaryTtyActive(); + void processCommand(RDMacro *cmd); + + private: + RDTTYDevice *ross_device; + int ross_inputs; + int ross_outputs; + int ross_breakaway; +}; + + +#endif // ROSSNKSCP_H From 04bd883b65b9922c35216b92b4da52245fdc7f5b Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Fri, 29 May 2015 07:14:16 -0400 Subject: [PATCH 34/34] Updated .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 7d55c645..fc0e4ba1 100644 --- a/.gitignore +++ b/.gitignore @@ -78,6 +78,7 @@ utils/rdmarkerset/rdmarkerset utils/rmlsend/rmlsend utils/rdpurgecasts/rdpurgecasts utils/rdchunk/rdchunk +utils/rdcleandirs/rdcleandirs utils/rdsoftkeys/rdsoftkeys utils/rddbcheck/rddbcheck utils/rdalsaconfig/rdalsaconfig