Merged 04bd883b65b9922c35216b92b4da52245fdc7f5b from master

This commit is contained in:
Fred Gleason 2015-09-15 08:06:20 -04:00
commit c0446ea5f7
103 changed files with 1645 additions and 205 deletions

59
.gitignore vendored
View File

@ -13,13 +13,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,9 +40,56 @@ 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/audio_peaks_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/rdcleandirs/rdcleandirs
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

View File

@ -42,6 +42,9 @@ Alban Peignier <alban.peignier@free.fr>
Daniel Roviriego <danifernando@gmail.com>
Portuguese Translation (pt_BR).
Chris Smowton
MP4 imporatation support.
Scott Spillers <scotts@paravelsystems.com>
The Icon set

104
ChangeLog
View File

@ -14794,13 +14794,91 @@
2015-02-24 Fred Gleason <fredg@paravelsystems.com>
* Updated 'NEWS'.
* Incremented the package version to 2.10.3.
2015-02-25 Fred Gleason <fredg@paravelsystems.com>
* Updated 'conf/rlm_padpoint.conf' to reflect new 'standard' port
value.
2015-02-27 Fred Gleason <fredg@paravelsystems.com>
* 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'.
2015-03-04 Fred Gleason <fredg@paravelsystems.com>
* Added support for 'scp' and 'sftp' protocols in
'rdcatch/edit_upload.cpp'.
* Added support for 'scp' and 'sftp' protocols in
'rdcatch/edit_download.cpp'.
2015-03-04 Fred Gleason <fredg@paravelsystems.com>
* Incremented the package version to 2.10.3int00.
2015-03-05 Fred Gleason <fredg@paravelsystems.com>
* 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 <fredg@paravelsystems.com>
* Modified the 'SAS USI' driver in 'ripcd/sasusi.cpp' to support
four digit endpoint numbers.
2015-03-05 Fred Gleason <fredg@paravelsystems.com>
* Increased 'MAX_ENDPOINTS' in 'lib/rd.h' from 1024 to 2048.
2015-03-05 Fred Gleason <fredg@paravelsystems.com>
* Increased digit count on endpoints from 3 to 4 in
'rdadmin/list_endpoints.cpp'.
2015-03-06 Fred Gleason <fredg@paravelsystems.com>
* Incremented the package version to 2.10.3int01.
2015-03-09 Fred Gleason <fredg@paravelsystems.com>
* 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 <fredg@paravelsystems.com>
* 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'.
2015-03-10 Fred Gleason <fredg@paravelsystems.com>
* Fixed a bug in 'lib/rdcdplayer.cpp' that threw a segfault
when opening the ripper with no CD inserted under RHEL 7.
2015-03-16 Fred Gleason <fredg@paravelsystems.com>
* Added 'DESCRIPTION', 'OUTCUE', 'FILENAME' and '*_POINT' fields
to the 'Cart CSV Report' in 'rdlibrary/list_reports.cpp'.
2015-03-17 Fred Gleason <fredg@paravelsystems.com>
* Updated 'get_distro.sh' to detect RHEL 7 correctly.
2015-03-23 Fred Gleason <fredg@paravelsystems.com>
* 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 <fredg@paravelsystems.com>
* 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 <fredg@paravelsystems.com>
* 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 <fredg@paravelsystems.com>
* 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'.
2015-04-21 Fred Gleason <fredg@paravelsystems.com>
* Incremented the package version to 2.10.3int02.
2015-05-20 Fred Gleason <fredg@paravelsystems.com>
* Added default parameters to the 'PadPoint' RLM in 'rlm_padpoint.c'.
2015-05-28 Fred Gleason <fredg@paravelsystems.com>
* Added rdcleandirs(8) utility in 'utils/rdcleandirs/'.
2015-05-28 Fred Gleason <fredg@paravelsystems.com>
* 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'.
2015-06-10 Fred Gleason <fredg@paravelsystems.com>
* Refactored 'LogPlay' class to provide per-instance RDCae instances.
in 'rdairplay/log_play.cpp' and 'rdairplay/log_play.h'.
2015-06-10 Fred Gleason <fredg@paravelsystems.com>
* Incremented the package version to 2.10.3caefix00.
2015-06-22 Fred Gleason <fredg@paravelsystems.com>
* Incremented the package version to 2.10.3caefix01.
2015-07-02 Fred Gleason <fredg@paravelsystems.com>
* Fixed a bug in 'LogPlay::refresh()' that caused a segfault
in 'rdairplay/log_play.cpp'.
@ -14814,26 +14892,16 @@
* Instrumented 'LogPlay::graceTimerData()' in
'rdairplay/log_play.cpp'.
* Instrumented 'RLMHost::timerData()' in 'rdairplay/rlmhost.cpp'.
2015-07-14 Fred Gleason <fredg@paravelsystems.com>
* Incremented the package version to 2.10.3caefix02.
2015-07-14 Fred Gleason <fredg@paravelsystems.com>
* Incremented the package version to 2.10.3caefix03.
2015-08-12 Fred Gleason <fredg@paravelsystems.com>
* Instrumented the cleanup phase of the 'LogPlay::refresh()' method in
'rdairplay/log_play.cpp'.
2015-08-12 Fred Gleason <fredg@paravelsystems.com>
* Incremented the package version to 2.10.3caefix04.
2015-08-13 Fred Gleason <fredg@paravelsystems.com>
* Commented out the 'qApp->processEvents()' call in the
'refreshStatusChangedData()' method in 'rdairplay/rdairplay.cpp'.
2015-08-13 Fred Gleason <fredg@paravelsystems.com>
* Incremented the package version to 2.10.3caefix05.
2015-08-29 Fred Gleason <fredg@paravelsystems.com>
* Removed instrumentation code in 'rdairplay/hourselector.cpp'.
* Removed instrumentation code in 'rdairplay/log_play.cpp'.
* Removed instrumentation code in 'rdairplay/rlmhost.cpp'.
2015-08-29 Fred Gleason <fredg@paravelsystems.com>
* Incremented the package version to 2.10.3caefix06.
2015-08-30 Fred Gleason <fredg@paravelsystems.com>
* Added an 'RDAudioConvert::Stage3Pcm24()' method in
'lib/rdaudioconvert.cpp' and 'lib/rdaudioconvert.h'.
@ -14860,10 +14928,6 @@
2015-08-30 Fred Gleason <fredg@paravelsystems.com>
* Added PCM24 play-out and capture support for JACK in
'cae/cae_jack.cpp' and 'cae/cae.h'.
2015-08-30 Fred Gleason <fredg@paravelsystems.com>
* Incremented the package version to 2.10.3-pcm24.0.
2015-08-30 Fred Gleason <fredg@paravelsystems.com>
* Incremented the package version to 2.10.3pcm24.0.
2015-08-30 Fred Gleason <fredg@paravelsystems.com>
* Added a --frames=' parameter in 'tests/audio_peaks_test.cpp'.
* Fixed a fencepost bug in generating peak energy data in
@ -14876,10 +14940,6 @@
2015-09-07 Fred Gleason <fredg@paravelsystems.com>
* Added PCM24 play-out and capture support for ALSA in
'cae/cae_alsa.cpp' and 'cae/cae.h'.
2015-09-08 Fred Gleason <fredg@paravelsystems.com>
* Incremented the package version to 2.10.3pcm24.1.
2015-09-09 Fred Gleason <fredg@paravelsystems.com>
* Added 'src_float_to_int()' and 'src_int_to_float()' functions in
'cae/cae.cpp' and 'cae/cae.h'.
2015-09-09 Fred Gleason <fredg@paravelsystems.com>
* Incremented the package version to 2.10.3pcm24.2.

View File

@ -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/.

View File

@ -1 +1 @@
2.10.3pcm24.2
2.10.3int02

1
cae/.gitignore vendored
View File

@ -1 +0,0 @@
caed

View File

@ -2006,6 +2006,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
@ -2062,6 +2067,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

View File

@ -358,6 +358,7 @@ class MainObject : public QObject
#endif // ALSA
bool CheckLame();
bool CheckMp4Decode();
//
// TwoLAME Encoder

1
conf/.gitignore vendored
View File

@ -1 +0,0 @@
rd-bin.conf

View File

@ -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
;

View File

@ -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
@ -208,6 +210,19 @@ 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_HEADER(neaacdec.h,[MP4V2_FOUND=yes],[])
if test $MP4V2_FOUND ; then
AC_DEFINE(HAVE_MP4_LIBS)
fi
fi
fi
#
# Set Hard Library Dependencies
#
@ -427,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 \
@ -534,6 +550,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

View File

@ -22,10 +22,12 @@ 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
Sierra Automated Systems 64000 Audio Router
Sierra Automated Systems Universal Serial Interface (USI)
Sierra Automated Systems User Serial Interface (USI)
Sine Systems ACU-1 (Prophet version)
Software Authority Protocol
StarGuide III Satellite Receiver
@ -510,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
@ -535,6 +553,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
@ -591,9 +629,9 @@ outputs as well as audio crosspoints.
----------------------------------------------------------------------------
SIERRA AUTOMATED SYSTEMS Universal Serial Interface (USI)
SIERRA AUTOMATED SYSTEMS User Serial Interface (USI)
Driver Name: SAS User Serial Interface
Driver Name: SAS USI
Supported RML Commands:
Switch Take ('ST')

View File

@ -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

View File

@ -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)

View File

@ -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

2
helpers/.gitignore vendored
View File

@ -1,2 +0,0 @@
cwrap
jsmin

View File

@ -1,6 +0,0 @@
nexgen_filter
panel_copy
rdcatch_copy
rivendell_filter
sas_filter
wings_filter

1
lib/.gitignore vendored
View File

@ -1 +0,0 @@
rdpaths.h

View File

@ -177,6 +177,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\

View File

@ -26,7 +26,7 @@
/*
* Current Database Version
*/
#define RD_VERSION_DATABASE 242
#define RD_VERSION_DATABASE 245
#endif // DBVERSION_H

View File

@ -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

View File

@ -22,11 +22,13 @@
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#include <math.h>
#include <dlfcn.h>
#include <errno.h>
#include <unistd.h>
#include <sndfile.h>
#include <samplerate.h>
@ -39,6 +41,10 @@
#include <FLAC++/encoder.h>
#include <rdflacdecode.h>
#endif // HAVE_FLAC
#ifdef HAVE_MP4_LIBS
#include <mp4v2/mp4v2.h>
#include <neaacdec.h>
#endif // HAVE_MP4_LIBS
#include <id3/tag.h>
#include <qfile.h>
@ -306,6 +312,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;
@ -672,6 +683,165 @@ 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)
{
#ifdef HAVE_MP4_LIBS
SNDFILE *sf_dst=NULL;
SF_INFO sf_dst_info;
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(!dlmp4.load()) {
return RDAudioConvert::ErrorFormatNotSupported;
}
//
// Open source
//
f = dlmp4.MP4Read(wave->getName());
if(f == MP4_INVALID_FILE_HANDLE)
return RDAudioConvert::ErrorNoSource;
audioTrack = dlmp4.getMP4AACTrack(f);
firstSample = 1;
lastSample = dlmp4.MP4GetTrackNumberOfSamples(f, audioTrack);
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;
}
}
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;
}
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
//
hDecoder = dlmp4.NeAACDecOpen();
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;
}
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: %u/%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((const float*)sample_buffer, frameInfo.samples);
if(sf_write_float(sf_dst, (const float*)sample_buffer, frameInfo.samples) != (sf_count_t)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,
SNDFILE *sf_src,

View File

@ -31,6 +31,9 @@
#ifdef HAVE_MAD
#include <mad.h>
#endif // HAVE_MAD
#include <rdmp4.h>
#include <qobject.h>
#include <rdwavedata.h>
@ -68,6 +71,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);
@ -150,6 +155,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
};

View File

@ -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;i<cdrom_track_count;i++) {
rec->setTrackOffset(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;i<cdrom_track_count;i++) {
rec->setTrackOffset(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;

View File

@ -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").

View File

@ -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;

View File

@ -64,7 +64,9 @@ 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 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]=
{
@ -103,7 +105,9 @@ 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 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]=
@ -143,7 +147,9 @@ 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 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)
@ -603,8 +609,12 @@ QString RDMatrix::typeString(RDMatrix::Type type)
return QString("BroadcastTools ACS 8.2");
break;
case RDMatrix::Sas16000:
return QString("SAS 16000(D)");
break;
case RDMatrix::SasUsi:
return QString("SAS User Serial Interface");
return QString("SAS USI");
break;
case RDMatrix::Bt16x2:
@ -691,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;

View File

@ -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,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,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,LastType=34};
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,

108
lib/rdmp4.cpp Normal file
View File

@ -0,0 +1,108 @@
// rdmp4.cpp
//
// Helpers for dealing with MP4 files.
//
// (C) Copyright 2014 Christopher Smowton <chris@smowton.net>
//
// 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 <rdmp4.h>
#include <string.h>
#include <dlfcn.h>
MP4TrackId DLMP4::getMP4AACTrack(MP4FileHandle f)
{
uint32_t nTracks = this->MP4GetNumberOfTracks(f, NULL, 0);
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;
return true;
}
#undef check_dlsym
#endif // HAVE_MP4_LIBS

97
lib/rdmp4.h Normal file
View File

@ -0,0 +1,97 @@
// rdmp4.h
//
// Helpers for dealing with MP4 files.
//
// (C) Copyright 2014 Christopher Smowton <chris@smowton.net>
//
// 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 <mp4v2/mp4v2.h>
#include <neaacdec.h>
// neaacdec.h defines "LC", as in "low-complexity AAC", which clashes with a Rivendell Command.
#undef LC
struct DLMP4 {
DLMP4() : loadSuccess(false) {}
void *neaac_handle;
void *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, 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);
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

View File

@ -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;

View File

@ -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();

View File

@ -31,6 +31,7 @@
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>
#include <id3/tag.h>
#include <id3/misc_support.h>
@ -45,6 +46,11 @@
#include <rd.h>
#include <rdwavefile.h>
#include <rdconf.h>
#include <rdmp4.h>
#ifdef HAVE_MP4_LIBS
#include <mp4v2/mp4v2.h>
#endif
RDWaveFile::RDWaveFile(QString file_name)
{
@ -319,6 +325,75 @@ bool RDWaveFile::openWave(RDWaveData *data)
ReadId3Metadata();
break;
case RDWaveFile::M4A:
{
#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 = dlmp4.MP4Read(getName());
if(f == MP4_INVALID_FILE_HANDLE)
return false;
// Find an audio track, and populate sample rate, bits/sample etc.
MP4TrackId audioTrack = dlmp4.getMP4AACTrack(f);
if(audioTrack == MP4_INVALID_TRACK_ID) {
dlmp4.MP4Close(f, 0);
return false;
}
// Found audio track. Get audio data:
avg_bytes_per_sec = dlmp4.MP4GetTrackBitRate(f, audioTrack);
channels = dlmp4.MP4GetTrackAudioChannels(f, audioTrack);
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 = dlmp4.MP4GetTrackTimeScale(f, audioTrack);
bits_per_sample = 16;
data_start = 0;
sample_length = dlmp4.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 = dlmp4.MP4TagsAlloc();
dlmp4.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);
dlmp4.MP4TagsFree(tags);
}
dlmp4.MP4Close(f, 0);
return true;
#else
return false;
#endif
break;
}
case RDWaveFile::Ogg:
#ifdef HAVE_VORBIS
format_tag=WAVE_FORMAT_VORBIS;
@ -2071,6 +2146,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;
}
@ -2262,6 +2340,20 @@ bool RDWaveFile::IsAiff(int fd)
return true;
}
bool RDWaveFile::IsM4A(int fd)
{
#ifdef HAVE_MP4_LIBS
if(!dlmp4.load())
return false;
MP4FileHandle f = dlmp4.MP4Read(getName());
bool ret = f != MP4_INVALID_FILE_HANDLE;
if(ret)
dlmp4.MP4Close(f, 0);
return ret;
#else
return false;
#endif
}
off_t RDWaveFile::FindChunk(int fd,const char *chunk_name,unsigned *chunk_size,
bool big_end)

View File

@ -40,6 +40,8 @@
#include <vorbis/vorbisenc.h>
#endif // HAVE_VORBIS
#include <rdmp4.h>
#include <rdwavedata.h>
#include <rdringbuffer.h>
#include <rdsettings.h>
@ -115,7 +117,7 @@ class RDWaveFile
enum Format {Pcm8=0,Pcm16=1,Float32=2,MpegL1=3,MpegL2=4,MpegL3=5,
DolbyAc2=6,DolbyAc3=7,Vorbis=8,Pcm24=9};
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};
/**
@ -1034,6 +1036,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,
@ -1228,6 +1231,10 @@ class RDWaveFile
ogg_page ogg_pg;
ogg_packet ogg_pack;
#endif // HAVE_VORBIS
#ifdef HAVE_MP4_LIBS
DLMP4 dlmp4;
#endif
};
@ -1366,6 +1373,7 @@ class RDWaveFile
*/
#define WAVE_FORMAT_VORBIS 0xFFFF
#define WAVE_FORMAT_FLAC 0xFFFE
#define WAVE_FORMAT_M4A 0xFFFD
/*
* Proprietary Format Categories

1
rdadmin/.gitignore vendored
View File

@ -1 +0,0 @@
rdadmin

View File

@ -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),\
@ -1007,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,\
@ -2236,7 +2238,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;
@ -8086,6 +8088,26 @@ 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;
}
if(ver<244) {
sql=QString("alter table JACK_CLIENTS modify column ")+
"COMMAND_LINE text not null";
q=new QSqlQuery(sql);
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 ****

View File

@ -175,94 +175,105 @@ EditRDLibrary::EditRDLibrary(RDStation *station,RDStation *cae_station,
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->setGeometry(160,232,40,19);
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->setGeometry(25,232,130,19);
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->setGeometry(205,232,120,19);
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->setGeometry(160,256,160,19);
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->setGeometry(25,256,130,19);
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->setGeometry(160,280,150,19);
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->setGeometry(25,280,130,19);
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->setGeometry(160,304,130,19);
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,304,130,19);
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->setGeometry(160,328,60,19);
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->setGeometry(25,328,130,19);
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->setGeometry(160,352,sizeHint().width()-170,19);
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->setGeometry(10,352,145,19);
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->setGeometry(25,415,120,19);
default_label->setGeometry(25,437,120,19);
default_label->setFont(big_font);
default_label->setAlignment(AlignRight|ShowPrefix);
@ -270,28 +281,28 @@ EditRDLibrary::EditRDLibrary(RDStation *station,RDStation *cae_station,
// Default Channels
//
lib_channels_box=new QComboBox(this);
lib_channels_box->setGeometry(160,434,60,19);
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,434,130,19);
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->setGeometry(160,456,100,19);
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,456,130,19);
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->setGeometry(160,480,100,19);
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,480,130,19);
lib_trimstate_label->setGeometry(25,502,130,19);
lib_trimstate_label->setAlignment(AlignRight|AlignVCenter|ShowPrefix);
//
@ -344,6 +355,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_channels_box->insertItem("1");
lib_channels_box->insertItem("2");
@ -406,7 +420,7 @@ EditRDLibrary::~EditRDLibrary()
QSize EditRDLibrary::sizeHint() const
{
return QSize(375,584);
return QSize(375,606);
}
@ -436,6 +450,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);
switch(lib_format_box->currentItem()) {
case 0: // PCM16

View File

@ -63,6 +63,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;

View File

@ -267,7 +267,7 @@ ListEndpoints::ListEndpoints(RDMatrix *matrix,RDMatrix::Endpoint endpoint,
q->first();
for(int i=0;i<list_size;i++) {
l=new QListViewItem(list_list_view);
l->setText(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;i<list_size;i++) {
item=list_list_view->findItem(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;
}

View File

@ -2822,6 +2822,10 @@ nastaveném pro běh služby CAE pro naplnění databáze se zdroji zvuku.</tran
<source>PCM24</source>
<translation type="unfinished">PCM24</translation>
</message>
<message>
<source>&amp;Read ISRCs from CD:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditRDLogedit</name>
@ -5914,5 +5918,10 @@ pro naplnění databáze zdroji zvuku.</translation>
<source>&amp;Close</source>
<translation>&amp;Zavřít</translation>
</message>
<message>
<source> MP-4/AAC
</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -2793,6 +2793,10 @@ configured to run the CAE service in order to populate the audio resources datab
<source>PCM24</source>
<translation type="unfinished">PCM24</translation>
</message>
<message>
<source>&amp;Read ISRCs from CD:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditRDLogedit</name>
@ -5864,5 +5868,10 @@ eingeben um die Audioressourcendatenbank zu füllen.</translation>
<source>&amp;Close</source>
<translation>&amp;Schliessen</translation>
</message>
<message>
<source> MP-4/AAC
</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -2802,6 +2802,10 @@ equipo configurado para ejecutar CAE para obtener la información de audio.</tra
<source>PCM24</source>
<translation type="unfinished">PCM24</translation>
</message>
<message>
<source>&amp;Read ISRCs from CD:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditRDLogedit</name>
@ -5866,5 +5870,10 @@ Revise los parámetros e intente de nuevo.</translation>
<source>&amp;Close</source>
<translation>&amp;Cerrar</translation>
</message>
<message>
<source> MP-4/AAC
</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -2501,6 +2501,10 @@ configured to run the CAE service in order to populate the audio resources datab
<source>PCM24</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&amp;Read ISRCs from CD:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditRDLogedit</name>
@ -5360,5 +5364,10 @@ please check your settings and try again.</source>
<source>&amp;Close</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> MP-4/AAC
</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -2789,6 +2789,10 @@ configured to run the CAE service in order to populate the audio resources datab
<source>PCM24</source>
<translation type="unfinished">PCM24</translation>
</message>
<message>
<source>&amp;Read ISRCs from CD:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditRDLogedit</name>
@ -5851,5 +5855,10 @@ Sjekk oppsettet ditt og prøv att.</translation>
<source>&amp;Close</source>
<translation>&amp;Lukk</translation>
</message>
<message>
<source> MP-4/AAC
</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -2789,6 +2789,10 @@ configured to run the CAE service in order to populate the audio resources datab
<source>PCM24</source>
<translation type="unfinished">PCM24</translation>
</message>
<message>
<source>&amp;Read ISRCs from CD:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditRDLogedit</name>
@ -5851,5 +5855,10 @@ Sjekk oppsettet ditt og prøv att.</translation>
<source>&amp;Close</source>
<translation>&amp;Lukk</translation>
</message>
<message>
<source> MP-4/AAC
</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -2781,6 +2781,10 @@ configured to run the CAE service in order to populate the audio resources datab
<source>PCM24</source>
<translation type="unfinished">PCM24</translation>
</message>
<message>
<source>&amp;Read ISRCs from CD:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditRDLogedit</name>
@ -5844,5 +5848,10 @@ por favor, cheque suas configurações e tente novamente</translation>
<source>&amp;Close</source>
<translation>&amp;Fechar</translation>
</message>
<message>
<source> MP-4/AAC
</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -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");
}

View File

@ -1 +0,0 @@
rdairplay

View File

@ -1460,9 +1460,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);
@ -1857,11 +1857,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(
@ -2772,12 +2772,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());

View File

@ -1 +0,0 @@
rdcartslots

View File

@ -1 +0,0 @@
rdcastmanager

1
rdcatch/.gitignore vendored
View File

@ -1 +0,0 @@
rdcatch

View File

@ -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;

View File

@ -493,7 +493,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);
@ -575,7 +576,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;

1
rdcatchd/.gitignore vendored
View File

@ -1 +0,0 @@
rdcatchd

View File

@ -1 +0,0 @@
rdlibrary

View File

@ -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;
}

View File

@ -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;
}
@ -792,7 +794,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 +1133,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();

View File

@ -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;i<code_quan;i++) {
*report+="DESCRIPTION,OUTCUE,";
*report+="FILENAME,LENGTH,";
*report+="START_POINT,END_POINT,";
*report+="SEGUE_START_POINT,SEGUE_END_POINT,";
*report+="HOOK_START_POINT,HOOK_END_POINT,";
*report+="TALK_START_POINT,TALK_END_POINT,";
*report+="FADEUP_POINT,FADEDOWN_POINT,";
for(int i=0;i<code_quan;i++) {
*report+=QString().sprintf("SCHED_CODE%u,",i+1);
}
*report=report->left(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;i<code_quan;i++) {
if((f0.size()>i)&&(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;i<code_quan;i++) {
if(((int)f0.size()>i)&&(f0[i]!=".")) {
*report+="\""+f0[i].stripWhiteSpace()+"\",";
}
else {

View File

@ -1 +0,0 @@
rdlogedit

1
rdlogin/.gitignore vendored
View File

@ -1 +0,0 @@
rdlogin

View File

@ -1 +0,0 @@
rdlogmanager

View File

@ -1 +0,0 @@
rdmonitor

1
rdpanel/.gitignore vendored
View File

@ -1 +0,0 @@
rdpanel

1
rdrepld/.gitignore vendored
View File

@ -1 +0,0 @@
rdrepld

1
rdselect/.gitignore vendored
View File

@ -1 +0,0 @@
rdselect

1
ripcd/.gitignore vendored
View File

@ -1 +0,0 @@
ripcd

View File

@ -60,9 +60,11 @@ 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\
sas16000.cpp sas16000.h\
sasusi.cpp sasusi.h\
starguide3.cpp starguide3.h\
starguide_feed.cpp starguide_feed.h\
@ -98,9 +100,11 @@ 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\
moc_sas16000.cpp\
moc_sasusi.cpp\
moc_starguide3.cpp\
moc_swauthority.cpp\

View File

@ -49,6 +49,8 @@
#include <local_gpio.h>
#include <modemlines.h>
#include <quartz1.h>
#include <rossnkscp.h>
#include <sas16000.h>
#include <sas32000.h>
#include <sas64000.h>
#include <sas64000gpi.h>
@ -163,6 +165,14 @@ 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;
case RDMatrix::Sas32000:
ripcd_switcher[matrix_num]=new Sas32000(matrix,this);
break;

114
ripcd/rossnkscp.cpp Normal file
View File

@ -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 <fredg@paravelsystems.com>
//
// 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 <stdlib.h>
#include <globals.h>
#include <rossnkscp.h>
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;
}
}

55
ripcd/rossnkscp.h Normal file
View File

@ -0,0 +1,55 @@
// rossnkscp.h
//
// A Rivendell switcher driver for the Ross NK switchers via the SCP/A
//
// (C) Copyright 2015 Fred Gleason <fredg@paravelsystems.com>
//
// 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 <rd.h>
#include <rdmatrix.h>
#include <rdmacro.h>
#include <rdtty.h>
#include <switcher.h>
#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

132
ripcd/sas16000.cpp Normal file
View File

@ -0,0 +1,132 @@
// sas16000.cpp
//
// A Rivendell switcher driver for the SAS USI Protocol (2 digit)
//
// (C) Copyright 2002-2015 Fred Gleason <fredg@paravelsystems.com>
//
// 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 <stdlib.h>
#include <rddb.h>
#include <globals.h>
#include <sas16000.h>
Sas16000::Sas16000(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 Sas16000::type()
{
return RDMatrix::Sas16000;
}
unsigned Sas16000::gpiQuantity()
{
return sas_gpis;
}
unsigned Sas16000::gpoQuantity()
{
return sas_gpos;
}
bool Sas16000::primaryTtyActive()
{
return true;
}
bool Sas16000::secondaryTtyActive()
{
return false;
}
void Sas16000::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 Sas16000::SendCommand(char *str)
{
LogLine(RDConfig::LogDebug,QString().sprintf("sending USI cmd: %s",(const char *)PrettifyCommand(str)));
sas_device->writeBlock(str,strlen(str));
}
QString Sas16000::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;
}

65
ripcd/sas16000.h Normal file
View File

@ -0,0 +1,65 @@
// sas16000.h
//
// A Rivendell switcher driver for the SAS 16000(D) Audio Switcher
//
// (C) Copyright 2002-2015 Fred Gleason <fredg@paravelsystems.com>
//
// 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 SAS16000_H
#define SAS16000_H
#include <vector>
#include <qsocket.h>
#include <qhostaddress.h>
#include <rd.h>
#include <rdmatrix.h>
#include <rdmacro.h>
#include <rdtty.h>
#include <switcher.h>
#define SAS16000_MAX_LENGTH 256
class Sas16000 : public Switcher
{
Q_OBJECT
public:
Sas16000(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[SAS16000_MAX_LENGTH];
unsigned sas_ptr;
int sas_matrix;
int sas_ipport;
int sas_inputs;
int sas_outputs;
int sas_gpis;
int sas_gpos;
};
#endif // SAS16000_H

View File

@ -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
//
// (C) Copyright 2002-2004 Fred Gleason <fredg@paravelsystems.com>
//
// $Id: sasusi.cpp,v 1.24 2011/12/28 18:59:19 cvs Exp $
// (C) Copyright 2002-2015 Fred Gleason <fredg@paravelsystems.com>
//
// 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
@ -260,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);
@ -290,10 +288,11 @@ void SasUsi::processCommand(RDMacro *cmd)
}
cmd_byte=0x01;
}
if(cmd->arg(2).toUInt()<sas_relay_numbers.size()) {
if(cmd->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);

View File

@ -1,10 +1,8 @@
// sasusi.h
//
// A Rivendell switcher driver for the SAS User Serial Interface Protocol
// A Rivendell switcher driver for the SAS USI Protocol
//
// (C) Copyright 2002-2004 Fred Gleason <fredg@paravelsystems.com>
//
// $Id: sasusi.h,v 1.16 2011/05/26 21:20:37 cvs Exp $
// (C) Copyright 2002-2015 Fred Gleason <fredg@paravelsystems.com>
//
// 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

View File

@ -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

Binary file not shown.

View File

@ -29,6 +29,15 @@
#include <string.h>
#include <strings.h>
#include <rlm/rlm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#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);
}
}
}

11
tests/.gitignore vendored
View File

@ -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

View File

@ -34,6 +34,7 @@ SUBDIRS = $(ALSACONFIG_RD_OPT)\
rddgimport\
rdcheckcuts\
rdchunk\
rdcleandirs\
rdcollect\
rddelete\
rddiscimport\

View File

@ -1 +0,0 @@
rdalsaconfig

View File

@ -1 +0,0 @@
rdcheckcuts

View File

@ -1 +0,0 @@
rdchunk

View File

@ -0,0 +1,50 @@
## automake.am
##
## Automake.am for rivendell/utils/rdcleandirs
##
## (C) Copyright 2015 Fred Gleason <fredg@paravelsystems.com>
##
## 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_*

View File

@ -0,0 +1,89 @@
// rdcleandirs.cpp
//
// Remove stale lockfiles from user directories.
//
// (C) Copyright 2010 Fred Gleason <fredg@paravelsystems.com>
//
// 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 <pwd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <qapplication.h>
#include <qdir.h>
#include <qfile.h>
#include <rdcmd_switch.h>
#include <rdconf.h>
#include <rdcleandirs.h>
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;i<cmd->keys();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();
}

View File

@ -0,0 +1,38 @@
// rdcleandirs.h
//
// Remove stale lockfiles from user directories.
//
// (C) Copyright 2015 Fred Gleason <fredg@paravelsystems.com>
//
// 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 <qobject.h>
#define RDCLEANDIRS_USAGE "\n"
class MainObject : public QObject
{
public:
MainObject(QObject *parent=0,const char *name=0);
private:
};
#endif // RDCLEANDIRS_H

View File

@ -1 +0,0 @@
rdcollect

View File

@ -1 +0,0 @@
rddbcheck

View File

@ -1 +0,0 @@
rddelete

View File

@ -1 +0,0 @@
rddgimport

View File

@ -1 +0,0 @@
rddiscimport

View File

@ -1 +0,0 @@
rdgen

View File

@ -1 +0,0 @@
rdgpimon

View File

@ -1 +0,0 @@
rdhpiinfo

View File

@ -1 +0,0 @@
rdimport

View File

@ -1 +0,0 @@
rdmaint

View File

@ -1 +0,0 @@
rdmarkerset

View File

@ -1 +0,0 @@
rdpopup

View File

@ -1 +0,0 @@
rdpurgecasts

View File

@ -1 +0,0 @@
rdsoftkeys

Some files were not shown because too many files have changed in this diff Show More