2020-01-30 Fred Gleason <fredg@paravelsystems.com>

* Renamed the 'RDCddbRecord' class to 'RDDiscRecord'.
	* Removed support for CD-TEXT from the CD rippers.
	* Removed the icedax(1) dependency.
This commit is contained in:
Fred Gleason 2020-01-30 13:11:14 -05:00
parent 729fef66bc
commit cbe375adf0
30 changed files with 723 additions and 525 deletions

View File

@ -19443,3 +19443,7 @@
2020-01-29 Fred Gleason <fredg@paravelsystems.com>
* Refactored the 'RDCddbLookup' class into 'RDCddbLookup' and
'RDDiscLookup'.
2020-01-30 Fred Gleason <fredg@paravelsystems.com>
* Renamed the 'RDCddbRecord' class to 'RDDiscRecord'.
* Removed support for CD-TEXT from the CD rippers.
* Removed the icedax(1) dependency.

View File

@ -7,10 +7,6 @@ system before building Rivendell:
Apache Web Server
Included with most distros, or available from: http://www.apache.org/.
Cdda2Wav
A CD ripper engine. Included in most distributions, but also available from
http://www.cdda2wav.de/.
Expat
A stream-oriented XML parser library. Available at https://libexpat.github.io/.

View File

@ -172,18 +172,15 @@ else
AC_SUBST(USERMODE_PKG,"usermode usermode-gtk")
AC_SUBST(MYSQL_PKG,"mariadb")
AC_SUBST(QT4_MYSQL_PKG,"qt-mysql")
AC_SUBST(CDDA2WAV_PKG,"icedax")
else
if test $ar_distro_major -ge 6 ; then
AC_SUBST(USERMODE_PKG,"usermode")
AC_SUBST(MYSQL_PKG,"mysql")
AC_SUBST(QT4_MYSQL_PKG,"qt4-mysql")
AC_SUBST(CDDA2WAV_PKG,"icedax")
else
AC_SUBST(USERMODE_PKG,"usermode")
AC_SUBST(MYSQL_PKG,"mysql")
AC_SUBST(QT4_MYSQL_PKG,"qt-MySQL")
AC_SUBST(CDDA2WAV_PKG,"")
fi
fi
fi

View File

@ -45,7 +45,7 @@ panel_copy_LDADD = @LIB_RDLIBS@ @LIBVORBIS@ @QT4_LIBS@ @MUSICBRAINZ_LIBS@ -lQt3S
dist_rdcatch_copy_SOURCES = rdcatch_copy.cpp rdcatch_copy.h
nodist_rdcatch_copy_SOURCES = moc_rdcatch_copy.cpp
rdcatch_copy_LDADD = @LIB_RDLIBS@ @LIBVORBIS@ @QT4_LIBS@ -lQt3Support
rdcatch_copy_LDADD = @LIB_RDLIBS@ @LIBVORBIS@ @QT4_LIBS@ @MUSICBRAINZ_LIBS@ -lQt3Support
dist_rivendell_filter_SOURCES = rivendell_filter.cpp rivendell_filter.h
nodist_rivendell_filter_SOURCES = moc_rivendell_filter.cpp

View File

@ -84,7 +84,6 @@ dist_librd_la_SOURCES = dbversion.h\
rdcatch_conf.cpp rdcatch_conf.h\
rdcatch_connect.cpp rdcatch_connect.h\
rdcddblookup.cpp rdcddblookup.h\
rdcddbrecord.cpp rdcddbrecord.h\
rdcdplayer.cpp rdcdplayer.h\
rdcdripper.cpp rdcdripper.h\
rdcheck_version.cpp rdcheck_version.h\
@ -112,6 +111,7 @@ dist_librd_la_SOURCES = dbversion.h\
rddelete.cpp rddelete.h\
rddialog.cpp rddialog.h\
rddisclookup.cpp rddisclookup.h\
rddiscrecord.cpp rddiscrecord.h\
rddownload.cpp rddownload.h\
rddropbox.cpp rddropbox.h\
rdedit_audio.cpp rdedit_audio.h\

View File

@ -2,7 +2,7 @@
#
# The lib/ QMake project file for Rivendell.
#
# (C) Copyright 2003-2018 Fred Gleason <fredg@paravelsystems.com>
# (C) Copyright 2003-2020 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
@ -57,7 +57,7 @@ SOURCES += rdcartdrag.cpp
SOURCES += rdcatch_connect.cpp
SOURCES += rdcddblookup.cpp
SOURCES += rdcdplayer.cpp
SOURCES += rdcddbrecord.cpp
SOURCES += rddiscrecord.cpp
SOURCES += rdcheck_version.cpp
SOURCES += rdclock.cpp
SOURCES += rdcmd_cache.cpp
@ -75,6 +75,7 @@ SOURCES += rddatedecode.cpp
SOURCES += rddatepicker.cpp
SOURCES += rddatetime.cpp
SOURCES += rddb.cpp
SOURCES += rddisclookup.cpp
SOURCES += rddbheartbeat.cpp
SOURCES += rddebug.cpp
SOURCES += rddeck.cpp
@ -189,7 +190,8 @@ HEADERS += rdcartdrag.h
HEADERS += rdcatch_connect.h
HEADERS += rdcddblookup.h
HEADERS += rdcdplayer.h
HEADERS += rdcddbrecord.h
HEADERS += rddiscrecord.h
HEADERS += rddisclookup.h
HEADERS += rdcheck_version.h
HEADERS += rdclock.h
HEADERS += rdcmd_cache.h

View File

@ -1418,6 +1418,29 @@ vozík</translation>
<translation>Ne</translation>
</message>
</context>
<context>
<name>RDDiscLookup</name>
<message>
<source>Multiple Matches Found!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>OK</source>
<translation type="unfinished">OK</translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished">Zrušit</translation>
</message>
<message>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to read CD.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDEditAudio</name>
<message>

View File

@ -1408,6 +1408,29 @@ Cart</source>
<translation>So</translation>
</message>
</context>
<context>
<name>RDDiscLookup</name>
<message>
<source>Multiple Matches Found!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>OK</source>
<translation type="unfinished">OK</translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished">Abbrechen</translation>
</message>
<message>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to read CD.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDEditAudio</name>
<message>

View File

@ -1405,6 +1405,29 @@ Cartucho</translation>
<translation>Do</translation>
</message>
</context>
<context>
<name>RDDiscLookup</name>
<message>
<source>Multiple Matches Found!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>OK</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished">Cancelar</translation>
</message>
<message>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to read CD.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDEditAudio</name>
<message>

View File

@ -1242,6 +1242,29 @@ Cart</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDDiscLookup</name>
<message>
<source>Multiple Matches Found!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>OK</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to read CD.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDEditAudio</name>
<message>

View File

@ -1403,6 +1403,29 @@ Cart</source>
<translation>Su</translation>
</message>
</context>
<context>
<name>RDDiscLookup</name>
<message>
<source>Multiple Matches Found!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>OK</source>
<translation type="unfinished">OK</translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to read CD.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDEditAudio</name>
<message>

View File

@ -1403,6 +1403,29 @@ Cart</source>
<translation>Su</translation>
</message>
</context>
<context>
<name>RDDiscLookup</name>
<message>
<source>Multiple Matches Found!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>OK</source>
<translation type="unfinished">OK</translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to read CD.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDEditAudio</name>
<message>

View File

@ -1409,6 +1409,29 @@ Cartão</translation>
<translation>Dom</translation>
</message>
</context>
<context>
<name>RDDiscLookup</name>
<message>
<source>Multiple Matches Found!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>OK</source>
<translation type="unfinished">OK</translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished">Cancelar</translation>
</message>
<message>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to read CD.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDEditAudio</name>
<message>

View File

@ -1,6 +1,6 @@
// rdcddblookup.cpp
//
// A Qt class for accessing the FreeDB CD Database.
// RDDiscLookup instance class for accessing the FreeDB CD Database.
//
// (C) Copyright 2003-2020 Fred Gleason <fredg@paravelsystems.com>
//
@ -54,12 +54,14 @@ RDCddbLookup::~RDCddbLookup()
}
QString RDCddbLookup::sourceName() const
{
return QString("FreeDB");
}
void RDCddbLookup::lookupRecord()
{
if(cddbRecord()->tracks()==0) {
return;
}
lookup_username=rda->user()->name();
lookup_hostname=rda->libraryConf()->cddbServer();
lookup_appname="rivendell";

View File

@ -1,8 +1,8 @@
// rdcddblookup.h
//
// A Qt class for accessing the FreeDB CD Database.
// RDDiscLookup instance class for accessing the FreeDB CD Database.
//
// (C) Copyright 2003-2019 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2003-2020 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License
@ -31,7 +31,7 @@
#include <qtcpsocket.h>
#include <rddisclookup.h>
#include <rdcddbrecord.h>
#include <rddiscrecord.h>
#include <rddialog.h>
//
@ -45,12 +45,15 @@ class RDCddbLookup : public RDDiscLookup
public:
RDCddbLookup(const QString &caption,FILE *profile_msgs,QWidget *parent=0);
~RDCddbLookup();
void lookupRecord();
QString sourceName() const;
private slots:
void readyReadData();
void errorData(QAbstractSocket::SocketError);
protected:
void lookupRecord();
private:
void FinishCddbLookup(RDCddbLookup::Result res);
QString DecodeString(QString &str);

View File

@ -1,278 +0,0 @@
// rdcddbrecord.cpp
//
// A Container Class for CDDB Data.
//
// (C) Copyright 2003,2016 Fred Gleason <fredg@paravelsystems.com>
//
// 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.
//
#include <rdcddbrecord.h>
RDCddbRecord::RDCddbRecord()
{
clear();
}
void RDCddbRecord::clear()
{
cddb_tracks=0;
cddb_disc_id=0;
cddb_disc_length=0;
cddb_disc_title="";
cddb_disc_artist="";
cddb_disc_album="";
cddb_disc_author="";
cddb_disc_year=0;
cddb_disc_genre="";
cddb_disc_extended="";
cddb_disc_playorder="";
for(int i=0;i<CDROM_LEADOUT;i++) {
cddb_track_title[i]="";
cddb_track_extended[i]="";
cddb_track_artist[i]="";
cddb_track_isrc[i]="";
cddb_track_offset[i]=0;
}
}
int RDCddbRecord::tracks() const
{
return cddb_tracks;
}
void RDCddbRecord::setTracks(int num)
{
cddb_tracks=num;
}
unsigned RDCddbRecord::discLength() const
{
return cddb_disc_length;
}
void RDCddbRecord::setDiscLength(unsigned len)
{
cddb_disc_length=len;
}
unsigned RDCddbRecord::discId() const
{
return cddb_disc_id;
}
void RDCddbRecord::setDiscId(unsigned id)
{
cddb_disc_id=id;
}
QString RDCddbRecord::discTitle() const
{
return cddb_disc_title;
}
void RDCddbRecord::setDiscTitle(QString title)
{
int n;
cddb_disc_title=title;
if((n=title.find(" / "))!=-1) {
cddb_disc_artist=title.left(n);
cddb_disc_album=title.right(title.length()-n-3);
cddb_disc_author="";
}
else {
cddb_disc_album=title;
cddb_disc_artist=title;
cddb_disc_author="";
}
}
QString RDCddbRecord::discArtist() const
{
return cddb_disc_artist;
}
void RDCddbRecord::setDiscArtist(QString artist)
{
cddb_disc_artist=artist;
}
QString RDCddbRecord::discAlbum() const
{
return cddb_disc_album;
}
void RDCddbRecord::setDiscAlbum(QString album)
{
cddb_disc_album=album;
}
QString RDCddbRecord::discAuthor() const
{
return cddb_disc_author;
}
void RDCddbRecord::setDiscAuthor(QString author)
{
cddb_disc_author=author;
}
unsigned RDCddbRecord::discYear() const
{
return cddb_disc_year;
}
void RDCddbRecord::setDiscYear(unsigned year)
{
cddb_disc_year=year;
}
QString RDCddbRecord::discGenre() const
{
return cddb_disc_genre;
}
void RDCddbRecord::setDiscGenre(QString genre)
{
cddb_disc_genre=genre;
}
QString RDCddbRecord::discExtended() const
{
return cddb_disc_extended;
}
void RDCddbRecord::setDiscExtended(QString text)
{
cddb_disc_extended=text;
}
QString RDCddbRecord::discPlayOrder() const
{
return cddb_disc_playorder;
}
void RDCddbRecord::setDiscPlayOrder(QString order)
{
cddb_disc_playorder=order;
}
unsigned RDCddbRecord::trackOffset(int track) const
{
if(track<CDROM_LEADOUT) {
return cddb_track_offset[track];
}
return 0;
}
void RDCddbRecord::setTrackOffset(int track,unsigned frames)
{
if(track<CDROM_LEADOUT) {
cddb_track_offset[track]=frames;
}
}
QString RDCddbRecord::trackTitle(int track) const
{
if(track<CDROM_LEADOUT) {
return cddb_track_title[track];
}
return QString();
}
void RDCddbRecord::setTrackTitle(int track,QString title)
{
if(track<CDROM_LEADOUT) {
cddb_track_title[track]=title;
}
}
QString RDCddbRecord::trackExtended(int track) const
{
if(track<CDROM_LEADOUT) {
return cddb_track_extended[track];
}
return QString();
}
void RDCddbRecord::setTrackExtended(int track,QString text)
{
if(track<CDROM_LEADOUT) {
cddb_track_extended[track]=text;
}
}
QString RDCddbRecord::trackArtist(int track) const
{
if(track<CDROM_LEADOUT) {
return cddb_track_artist[track];
}
return QString();
}
void RDCddbRecord::setTrackArtist(int track,QString artist)
{
if(track<CDROM_LEADOUT) {
cddb_track_artist[track]=artist;
}
}
QString RDCddbRecord::isrc(int track) const
{
if(track<CDROM_LEADOUT) {
return cddb_track_isrc[track];
}
return QString();
}
void RDCddbRecord::setIsrc(int track,QString isrc)
{
if(track<CDROM_LEADOUT) {
cddb_track_isrc[track]=isrc;
}
}

View File

@ -2,7 +2,7 @@
//
// Abstract a Linux CDROM Device.
//
// (C) Copyright 2002-2019 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2002-2020 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License
@ -197,7 +197,7 @@ int RDCdPlayer::rightVolume()
}
void RDCdPlayer::setCddbRecord(RDCddbRecord *rec)
void RDCdPlayer::setCddbRecord(RDDiscRecord *rec)
{
if(cdrom_track_count>0) {
rec->setTracks(cdrom_track_count);

View File

@ -2,7 +2,7 @@
//
// Abstract a Linux CDROM Device.
//
// (C) Copyright 2002-2003,2016 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2002-2020 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License
@ -28,7 +28,7 @@
#include <qdialog.h>
#include <qtimer.h>
#include <rdcddbrecord.h>
#include <rddiscrecord.h>
//
// Driver Settings
@ -65,7 +65,7 @@ class RDCdPlayer : public QObject
int rightVolume();
RDCdPlayer::PlayMode playMode() const;
void setPlayMode(RDCdPlayer::PlayMode mode);
void setCddbRecord(RDCddbRecord *);
void setCddbRecord(RDDiscRecord *);
public slots:
void lock();

View File

@ -24,22 +24,20 @@
#include <fcntl.h>
#include <qobject.h>
//Added by qt3to4:
#include <Q3Signal>
#include <rd.h>
#include <rdconf.h>
#include <rdwavefile.h>
#include <rdcut.h>
#include <rdtextvalidator.h>
#include <rdconfig.h>
#include <rddb.h>
#include <rdescape_string.h>
#include <rdgroup.h>
#include <rdweb.h>
#include <rdcopyaudio.h>
#include <rdtrimaudio.h>
#include "rd.h"
#include "rdconf.h"
#include "rdconfig.h"
#include "rdcopyaudio.h"
#include "rdcut.h"
#include "rddb.h"
#include "rddisclookup.h"
#include "rdescape_string.h"
#include "rdgroup.h"
#include "rdtextvalidator.h"
#include "rdtrimaudio.h"
#include "rdwavefile.h"
#include "rdweb.h"
//
// Global Classes
@ -222,13 +220,10 @@ QString RDCut::isrc(IsrcFormat fmt) const
{
QString str= RDGetSqlValue("CUTS","CUT_NAME",cut_name,"ISRC").
toString();
if((fmt==RDCut::RawIsrc)||(str.length()!=12)) {
if((fmt==RDCut::RawIsrc)||(!RDDiscLookup::isrcIsValid(str))) {
return str;
}
str.insert(2,"-");
str.insert(6,"-");
str.insert(9,"-");
return str;
return RDDiscLookup::formattedIsrc(str);
}

View File

@ -22,11 +22,13 @@
#include <stdlib.h>
#include <string.h>
#include <qmessagebox.h>
#include <qtimer.h>
#include <qregexp.h>
#include <qdatetime.h>
#include <qmessagebox.h>
#include <q3process.h>
#include <qregexp.h>
#include <qtimer.h>
#include <discid/discid.h>
#include "rdtempdirectory.h"
#include "rddisclookup.h"
@ -36,6 +38,7 @@ RDDiscLookup::RDDiscLookup(const QString &caption,FILE *profile_msgs,
QWidget *parent)
: RDDialog(parent)
{
lookup_caption=caption;
lookup_profile_msgs=profile_msgs;
lookup_titles_label=new QLabel(tr("Multiple Matches Found!"),this);
@ -51,34 +54,6 @@ RDDiscLookup::RDDiscLookup(const QString &caption,FILE *profile_msgs,
lookup_cancel_button=new QPushButton(tr("Cancel"),this);
lookup_cancel_button->setFont(buttonFont());
connect(lookup_cancel_button,SIGNAL(clicked()),this,SLOT(cancelData()));
//
// Create Temporary Directory
//
char path[PATH_MAX];
strncpy(path,RDTempDirectory::basePath(),PATH_MAX);
strcat(path,"/XXXXXX");
if(mkdtemp(path)==NULL) {
QMessageBox::warning(this,caption+" - "+tr("Ripper Error"),
tr("Unable to create temporary directory!"));
}
else {
lookup_cdda_dir.setPath(path);
}
profile("created temp directory \""+lookup_cdda_dir.path()+"\"");
}
RDDiscLookup::~RDDiscLookup()
{
QStringList files=lookup_cdda_dir.entryList();
for(int i=0;i<files.size();i++) {
if((files[i]!=".")&&(files[i]!="..")) {
lookup_cdda_dir.remove(files[i]);
}
}
rmdir(lookup_cdda_dir.path());
profile("deleted temp directory \""+lookup_cdda_dir.path()+"\"");
}
@ -88,7 +63,7 @@ QSize RDDiscLookup::sizeHint() const
}
void RDDiscLookup::setCddbRecord(RDCddbRecord *rec)
void RDDiscLookup::setCddbRecord(RDDiscRecord *rec)
{
lookup_record=rec;
}
@ -96,21 +71,59 @@ void RDDiscLookup::setCddbRecord(RDCddbRecord *rec)
void RDDiscLookup::lookup()
{
profile("starting CD-TEXT lookup");
if(ReadCdText(lookup_cdda_dir.path(),rda->libraryConf()->ripperDevice())) {
emit lookupDone(RDDiscLookup::ExactMatch);
profile("CD-TEXT lookup success");
if(cddbRecord()->tracks()==0) {
return;
}
profile("CD-TEXT lookup failure");
//
// Get some basic disc parameters (CDDB DiskID, MusicBrainz mbid and,
// if enabled in rdadmin(1), MCN and ISRCs).
//
DiscId *disc=discid_new();
if(rda->libraryConf()->readIsrc()) {
if(discid_read(disc,rda->libraryConf()->ripperDevice().toUtf8())==0) {
QMessageBox::warning(this,caption()+" - "+tr("Error"),
tr("Unable to read CD.")+
"\n["+QString(discid_get_error_msg(disc))+"]");
discid_free(disc);
return;
}
}
else {
if(discid_read_sparse(disc,rda->libraryConf()->ripperDevice().toUtf8(),0)==0) {
QMessageBox::warning(this,caption()+" - "+tr("Error"),
tr("Unable to read CD.")+
"\n["+QString(discid_get_error_msg(disc))+"]");
discid_free(disc);
return;
}
}
cddbRecord()->setDiscId(QString(discid_get_freedb_id(disc)).toUInt(NULL,16));
cddbRecord()->setMbId(discid_get_id(disc));
cddbRecord()->setMbSubmissionUrl(discid_get_submission_url(disc));
if(rda->libraryConf()->readIsrc()) {
cddbRecord()->setMcn(discid_get_mcn(disc));
int first=discid_get_first_track_num(disc);
int last=discid_get_last_track_num(disc);
for(int i=first;i<=last;i++) {
if((i-first)<lookup_record->tracks()) {
cddbRecord()->setIsrc(i-first,
RDDiscLookup::normalizedIsrc(discid_get_track_isrc(disc,i)));
}
}
}
discid_free(disc);
//
// Call the low-level driver to complete the lookup.
//
lookupRecord();
}
bool RDDiscLookup::readIsrc()
QString RDDiscLookup::caption()
{
return ReadIsrcs(lookup_cdda_dir.path(),rda->libraryConf()->ripperDevice());
return lookup_caption;
}
@ -140,7 +153,7 @@ void RDDiscLookup::resizeEvent(QResizeEvent *e)
}
RDCddbRecord *RDDiscLookup::cddbRecord()
RDDiscRecord *RDDiscLookup::cddbRecord()
{
return lookup_record;
}
@ -168,129 +181,93 @@ QStringList *RDDiscLookup::titlesKey()
}
bool RDDiscLookup::ReadCdText(const QString &cdda_dir,const QString &cdda_dev)
bool RDDiscLookup::isrcIsValid(const QString &isrc)
{
RDProfile *title_profile=new RDProfile();
bool ret=false;
QString str;
QString cmd;
//
// For formatting rules for International Standard Recording Codes,
// see https://en.wikipedia.org/wiki/International_Standard_Recording_Code
//
// NOTE: This makes no attempt to validate that the Country or Registrant
// codes actually exist in the IFPI registry!
//
QString str=isrc;
bool valid=false;
//
// Write the Track Title Data to a Temp File
//
QByteArray output;
Q3Process *proc=new Q3Process(this);
proc->addArgument("cdda2wav");
proc->addArgument("-D");
proc->addArgument(cdda_dev);
proc->addArgument("--info-only");
proc->addArgument("-v");
proc->addArgument("titles");
proc->setWorkingDirectory(cdda_dir);
if(!proc->start()) {
delete proc;
profile("cdda2wav failed to start!");
str.replace("-","");
if(str.length()!=12) {
return false;
}
while(proc->isRunning()) {
output=proc->readStderr();
if(output.size()>0) { // Work around icedax(1)'s idiotic user prompt
if(strncmp(output,"load cdrom please and press enter",33)==0) {
proc->kill();
delete proc;
profile("cdda2wav returned \""+output+"\", killing it!");
return false;
}
}
}
if(!proc->normalExit()) {
profile("cdda2wav crashed!");
delete proc;
return false;
}
if(proc->exitStatus()!=0) {
profile("cdda2wav return exit code "+
QString().sprintf("%d",proc->exitStatus()));
delete proc;
return false;
}
delete proc;
//
// Read the Track Title Data File
// This could probably be done much more compactly with a regex.
//
for(int i=0;i<lookup_record->tracks();i++) {
title_profile->setSource(cdda_dir+QString().sprintf("/audio_%02d.inf",i+1));
str=title_profile->stringValue("","Albumtitle","");
str.remove("'");
if((!str.isEmpty())&&(str!="''")) {
lookup_record->setDiscTitle(str);
profile("setting DiscTitle to \""+str+"\"");
ret=true;
}
for(int i=0;i<12;i++) {
QChar::Category category=str.at(i).category();
switch(i) {
case 0: // Country Code
case 1:
valid=(category==QChar::Letter_Uppercase)||
(category==QChar::Letter_Lowercase);
break;
str=title_profile->stringValue("","Albumperformer","");
str.remove("'");
if((!str.isEmpty())&&(str!="''")) {
lookup_record->setDiscArtist(str);
profile("setting DiscArtist to \""+str+"\"");
ret=true;
}
case 2: // Registrant Code
case 3:
case 4:
valid=(category==QChar::Letter_Uppercase)||
(category==QChar::Letter_Lowercase)||
(category==QChar::Number_DecimalDigit);
break;
str=title_profile->stringValue("","Tracktitle","");
str.remove("'");
if((!str.isEmpty())&&(str!="''")) {
lookup_record->setTrackTitle(i,str);
profile("setting TrackTitle "+QString().sprintf("%d",i+1)+" to \""+str+"\"");
ret=true;
case 5: // Designation Code
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
valid=(category==QChar::Number_DecimalDigit);
break;
}
str=title_profile->stringValue("","Performer","");
str.remove("'");
if((!str.isEmpty())&&(str!="''")) {
lookup_record->setTrackArtist(i,str);
profile("setting TrackArtist "+QString().sprintf("%d",i+1)+" to \""+str+"\"");
ret=true;
if(!valid) {
return false;
}
}
return ret;
return true;
}
bool RDDiscLookup::ReadIsrcs(const QString &cdda_dir,const QString &cdda_dev)
QString RDDiscLookup::formattedIsrc(const QString &isrc,bool *ok)
{
int err=0;
RDProfile *title_profile=new RDProfile();
RDProfile *isrc_profile=new RDProfile();
bool ret=false;
QString str;
QString cmd;
//
// Write the ISRC Data to a Temp File
//
cmd=QString("CURDIR=`pwd`;cd ")+
cdda_dir+";cdda2wav -D "+cdda_dev+
" --info-only -v trackid 2> /dev/null;cd $CURDIR";
if((err=system(cmd))!=0) {
return false;
}
//
// Read the ISRC Data File
//
for(int i=0;i<lookup_record->tracks();i++) {
isrc_profile->setSource(cdda_dir+QString().sprintf("/audio_%02d.inf",i+1));
str=isrc_profile->stringValue("","ISRC","");
str.remove("'");
str.remove("-");
if((!str.isEmpty())&&(str!="''")) {
lookup_record->setIsrc(i,str);
ret=true;
if(RDDiscLookup::isrcIsValid(isrc)) {
if(ok!=NULL) {
*ok=true;
}
QString str=isrc;
str.insert(2,"-");
str.insert(6,"-");
str.insert(9,"-");
return str.toUpper();
}
delete title_profile;
delete isrc_profile;
return ret;
if(ok!=NULL) {
*ok=false;
}
return QString();
}
QString RDDiscLookup::normalizedIsrc(const QString &isrc,bool *ok)
{
if(RDDiscLookup::isrcIsValid(isrc)) {
if(ok!=NULL) {
*ok=true;
}
QString str=isrc;
str.replace("-","");
return str.toUpper();
}
if(ok!=NULL) {
*ok=false;
}
return QString();
}

View File

@ -25,13 +25,12 @@
#include <stdio.h>
#include <qcombobox.h>
#include <qdir.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qstringlist.h>
#include <qtcpsocket.h>
#include <rdcddbrecord.h>
#include <rddiscrecord.h>
#include <rddialog.h>
class RDDiscLookup : public RDDialog
@ -41,44 +40,45 @@ class RDDiscLookup : public RDDialog
enum Result {ExactMatch=0,PartialMatch=1,NoMatch=2,
ProtocolError=3,NetworkError=4};
RDDiscLookup(const QString &caption,FILE *profile_msgs,QWidget *parent=0);
~RDDiscLookup();
QSize sizeHint() const;
void setCddbRecord(RDCddbRecord *);
virtual QString sourceName() const=0;
void setCddbRecord(RDDiscRecord *);
void lookup();
bool readIsrc();
static bool isrcIsValid(const QString &isrc);
static QString formattedIsrc(const QString &isrc,bool *ok=NULL);
static QString normalizedIsrc(const QString &isrc,bool *ok=NULL);
signals:
void lookupDone(RDDiscLookup::Result);
protected slots:
virtual void lookupRecord()=0;
QString caption();
void okData();
void cancelData();
protected:
virtual void lookupRecord()=0;
void resizeEvent(QResizeEvent *e);
RDCddbRecord *cddbRecord();
RDDiscRecord *cddbRecord();
void profile(const QString &msg);
QComboBox *titlesBox();
QStringList *titlesKey();
private:
bool ReadCdText(const QString &cdda_dir,const QString &cdda_dev);
bool ReadIsrcs(const QString &cdda_dir,const QString &cdda_dev);
QLabel *lookup_titles_label;
QComboBox *lookup_titles_box;
QStringList lookup_titles_key;
QPushButton *lookup_ok_button;
QPushButton *lookup_cancel_button;
RDCddbRecord *lookup_record;
RDDiscRecord *lookup_record;
QTcpSocket *lookup_socket;
int lookup_state;
QString lookup_username;
QString lookup_appname;
QString lookup_appver;
QString lookup_hostname;
QDir lookup_cdda_dir;
FILE *lookup_profile_msgs;
QString lookup_caption;
};
#endif // RDDISCLOOKUP_H

314
lib/rddiscrecord.cpp Normal file
View File

@ -0,0 +1,314 @@
// rddiscrecord.cpp
//
// Container Class for Compact Disc Metadata
//
// (C) Copyright 2003-2020 Fred Gleason <fredg@paravelsystems.com>
//
// 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.
//
#include "rddiscrecord.h"
RDDiscRecord::RDDiscRecord()
{
clear();
}
void RDDiscRecord::clear()
{
disc_tracks=0;
disc_disc_id=0;
disc_disc_length=0;
disc_disc_title="";
disc_disc_artist="";
disc_disc_album="";
disc_disc_author="";
disc_disc_year=0;
disc_disc_genre="";
disc_disc_extended="";
disc_disc_playorder="";
for(int i=0;i<CDROM_LEADOUT;i++) {
disc_track_title[i]="";
disc_track_extended[i]="";
disc_track_artist[i]="";
disc_track_isrc[i]="";
disc_track_offset[i]=0;
}
}
int RDDiscRecord::tracks() const
{
return disc_tracks;
}
void RDDiscRecord::setTracks(int num)
{
disc_tracks=num;
}
unsigned RDDiscRecord::discLength() const
{
return disc_disc_length;
}
void RDDiscRecord::setDiscLength(unsigned len)
{
disc_disc_length=len;
}
unsigned RDDiscRecord::discId() const
{
return disc_disc_id;
}
void RDDiscRecord::setDiscId(unsigned id)
{
disc_disc_id=id;
}
QString RDDiscRecord::mcn() const
{
return disc_mcn;
}
void RDDiscRecord::setMcn(const QString &mcn)
{
disc_mcn=mcn;
}
QString RDDiscRecord::mbID() const
{
return disc_mb_id;
}
void RDDiscRecord::setMbId(const QString &str)
{
disc_mb_id=str;
}
QString RDDiscRecord::mbSubmissionUrl() const
{
return disc_mb_submission_url;
}
void RDDiscRecord::setMbSubmissionUrl(const QString &url)
{
disc_mb_submission_url=url;
}
QString RDDiscRecord::discTitle() const
{
return disc_disc_title;
}
void RDDiscRecord::setDiscTitle(QString title)
{
int n;
disc_disc_title=title;
if((n=title.find(" / "))!=-1) {
disc_disc_artist=title.left(n);
disc_disc_album=title.right(title.length()-n-3);
disc_disc_author="";
}
else {
disc_disc_album=title;
disc_disc_artist=title;
disc_disc_author="";
}
}
QString RDDiscRecord::discArtist() const
{
return disc_disc_artist;
}
void RDDiscRecord::setDiscArtist(QString artist)
{
disc_disc_artist=artist;
}
QString RDDiscRecord::discAlbum() const
{
return disc_disc_album;
}
void RDDiscRecord::setDiscAlbum(QString album)
{
disc_disc_album=album;
}
QString RDDiscRecord::discAuthor() const
{
return disc_disc_author;
}
void RDDiscRecord::setDiscAuthor(QString author)
{
disc_disc_author=author;
}
unsigned RDDiscRecord::discYear() const
{
return disc_disc_year;
}
void RDDiscRecord::setDiscYear(unsigned year)
{
disc_disc_year=year;
}
QString RDDiscRecord::discGenre() const
{
return disc_disc_genre;
}
void RDDiscRecord::setDiscGenre(QString genre)
{
disc_disc_genre=genre;
}
QString RDDiscRecord::discExtended() const
{
return disc_disc_extended;
}
void RDDiscRecord::setDiscExtended(QString text)
{
disc_disc_extended=text;
}
QString RDDiscRecord::discPlayOrder() const
{
return disc_disc_playorder;
}
void RDDiscRecord::setDiscPlayOrder(QString order)
{
disc_disc_playorder=order;
}
unsigned RDDiscRecord::trackOffset(int track) const
{
if(track<CDROM_LEADOUT) {
return disc_track_offset[track];
}
return 0;
}
void RDDiscRecord::setTrackOffset(int track,unsigned frames)
{
if(track<CDROM_LEADOUT) {
disc_track_offset[track]=frames;
}
}
QString RDDiscRecord::trackTitle(int track) const
{
if(track<CDROM_LEADOUT) {
return disc_track_title[track];
}
return QString();
}
void RDDiscRecord::setTrackTitle(int track,QString title)
{
if(track<CDROM_LEADOUT) {
disc_track_title[track]=title;
}
}
QString RDDiscRecord::trackExtended(int track) const
{
if(track<CDROM_LEADOUT) {
return disc_track_extended[track];
}
return QString();
}
void RDDiscRecord::setTrackExtended(int track,QString text)
{
if(track<CDROM_LEADOUT) {
disc_track_extended[track]=text;
}
}
QString RDDiscRecord::trackArtist(int track) const
{
if(track<CDROM_LEADOUT) {
return disc_track_artist[track];
}
return QString();
}
void RDDiscRecord::setTrackArtist(int track,QString artist)
{
if(track<CDROM_LEADOUT) {
disc_track_artist[track]=artist;
}
}
QString RDDiscRecord::isrc(int track) const
{
if(track<CDROM_LEADOUT) {
return disc_track_isrc[track];
}
return QString();
}
void RDDiscRecord::setIsrc(int track,QString isrc)
{
if(track<CDROM_LEADOUT) {
disc_track_isrc[track]=isrc;
}
}

View File

@ -1,8 +1,8 @@
// rdcddbrecord.h
// rddiscrecord.h
//
// A Container Class for CDDB Data.
// Container Class for Compact Disc Metadata
//
// (C) Copyright 2003,2016 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2003-2020 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License
@ -19,8 +19,8 @@
//
//
#ifndef RDCDDBRECORD_H
#define RDCDDBRECORD_H
#ifndef RDDISCRECORD_H
#define RDDISCRECORD_H
#include <qstring.h>
#include <linux/cdrom.h>
@ -31,13 +31,13 @@
* @author Fred Gleason <fredg@paravelsystems.com>
**/
class RDCddbRecord
class RDDiscRecord
{
public:
/**
* Create an RDCddbRecord object
* Create an RDDiscRecord object
**/
RDCddbRecord();
RDDiscRecord();
void clear();
int tracks() const;
void setTracks(int num);
@ -45,6 +45,12 @@ class RDCddbRecord
void setDiscLength(unsigned len);
unsigned discId() const;
void setDiscId(unsigned id);
QString mcn() const;
void setMcn(const QString &mcn);
QString mbID() const;
void setMbId(const QString &str);
QString mbSubmissionUrl() const;
void setMbSubmissionUrl(const QString &url);
QString discTitle() const;
void setDiscTitle(QString title);
QString discArtist() const;
@ -71,27 +77,28 @@ class RDCddbRecord
void setTrackArtist(int track,QString artist);
QString isrc(int track) const;
void setIsrc(int track,QString isrc);
QString mcn(int track) const;
void setMcn(int track,QString mcn);
private:
int cddb_tracks;
unsigned cddb_disc_id;
unsigned cddb_disc_length;
QString cddb_disc_title;
QString cddb_disc_artist;
QString cddb_disc_album;
QString cddb_disc_author;
unsigned cddb_disc_year;
QString cddb_disc_genre;
QString cddb_disc_extended;
QString cddb_disc_playorder;
QString cddb_track_title[CDROM_LEADOUT];
QString cddb_track_extended[CDROM_LEADOUT];
QString cddb_track_artist[CDROM_LEADOUT];
QString cddb_track_isrc[CDROM_LEADOUT];
unsigned cddb_track_offset[CDROM_LEADOUT];
int disc_tracks;
unsigned disc_disc_id;
QString disc_mcn;
QString disc_mb_id;
QString disc_mb_submission_url;
unsigned disc_disc_length;
QString disc_disc_title;
QString disc_disc_artist;
QString disc_disc_album;
QString disc_disc_author;
unsigned disc_disc_year;
QString disc_disc_genre;
QString disc_disc_extended;
QString disc_disc_playorder;
QString disc_track_title[CDROM_LEADOUT];
QString disc_track_extended[CDROM_LEADOUT];
QString disc_track_artist[CDROM_LEADOUT];
QString disc_track_isrc[CDROM_LEADOUT];
unsigned disc_track_offset[CDROM_LEADOUT];
};
#endif // RDCDDBRECORD_H
#endif // RDDISCRECORD_H

View File

@ -553,7 +553,7 @@ void AudioCart::ripCutData()
return;
}
cutname=item->text(12);
RDCddbRecord *rec=new RDCddbRecord();
RDDiscRecord *rec=new RDDiscRecord();
CdRipper *ripper=new CdRipper(cutname,rec,rda->libraryConf(),rdcart_profile_rip);
if((track=ripper->exec(&title,&artist,&album))>=0) {
if((rdcart_controls->title_edit->text().isEmpty()||

View File

@ -2,7 +2,7 @@
//
// CD Track Ripper Dialog for Rivendell.
//
// (C) Copyright 2002-2019 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2002-2020 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
@ -34,12 +34,12 @@
//
bool ripper_running;
CdRipper::CdRipper(QString cutname,RDCddbRecord *rec,RDLibraryConf *conf,
CdRipper::CdRipper(QString cutname,RDDiscRecord *rec,RDLibraryConf *conf,
bool profile_rip,QWidget *parent)
: RDDialog(parent)
{
rip_profile_rip=profile_rip;
rip_isrc_read=false;
// rip_isrc_read=false;
rip_conf=conf;
rip_cddb_record=rec;
rip_track[0]=-1;
@ -410,12 +410,14 @@ void CdRipper::ripTrackButtonData()
//
// Read ISRCs
//
/*
if(!rip_isrc_read) {
if(rda->libraryConf()->readIsrc()) {
rip_cddb_lookup->readIsrc();
}
rip_isrc_read=true;
}
*/
//
// Rip from disc
@ -534,7 +536,7 @@ void CdRipper::mediaChangedData()
{
Q3ListViewItem *l;
rip_isrc_read=false;
// rip_isrc_read=false;
rip_track_list->clear();
rip_track[0]=-1;
rip_track[1]=-1;

View File

@ -38,7 +38,7 @@ class CdRipper : public RDDialog
{
Q_OBJECT
public:
CdRipper(QString cutname,RDCddbRecord *rec,RDLibraryConf *conf,
CdRipper(QString cutname,RDDiscRecord *rec,RDLibraryConf *conf,
bool profile_rip,QWidget *parent=0);
~CdRipper();
QSize sizeHint() const;
@ -70,8 +70,8 @@ class CdRipper : public RDDialog
void Profile(const QString &msg);
RDLibraryConf *rip_conf;
RDCdPlayer *rip_cdrom;
RDCddbRecord *rip_cddb_record;
RDCddbLookup *rip_cddb_lookup;
RDDiscRecord *rip_cddb_record;
RDDiscLookup *rip_cddb_lookup;
RDCut *rip_cut;
QLabel *rip_track_label;
RDListView *rip_track_list;
@ -110,7 +110,6 @@ class CdRipper : public RDDialog
QLabel *rip_autotrim_unit;
bool rip_done;
bool rip_profile_rip;
bool rip_isrc_read;
};

View File

@ -36,7 +36,7 @@ DiskRipper::DiskRipper(QString *filter,QString *group,QString *schedcode,
bool profile_rip,QWidget *parent)
: RDDialog(parent)
{
rip_isrc_read=false;
// rip_isrc_read=false;
rip_filter_text=filter;
rip_group_text=group;
rip_schedcode_text=schedcode;
@ -380,6 +380,7 @@ void DiskRipper::ripDiskButtonData()
}
rip_disk_bar->setMaximum(tracks);
/*
//
// Read ISRCs
//
@ -389,6 +390,7 @@ void DiskRipper::ripDiskButtonData()
}
rip_isrc_read=true;
}
*/
//
// Set Artist and Album
@ -732,7 +734,7 @@ void DiskRipper::mediaChangedData()
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
rip_isrc_read=false;
// rip_isrc_read=false;
rip_cutnames.clear();
rip_end_track.clear();
for(unsigned i=0;i<rip_wave_datas.size();i++) {

View File

@ -76,7 +76,7 @@ class DiskRipper : public RDDialog
void SetArtistAlbum();
void SendNotification(RDNotification::Action action,unsigned cartnum);
RDCdPlayer *rip_cdrom;
RDCddbRecord rip_cddb_record;
RDDiscRecord rip_cddb_record;
RDCddbLookup *rip_cddb_lookup;
QLabel *rip_track_label;
Q3ListView *rip_track_list;
@ -125,7 +125,7 @@ class DiskRipper : public RDDialog
std::vector<RDWaveData *> rip_wave_datas;
bool rip_aborting;
bool rip_profile_rip;
bool rip_isrc_read;
// bool rip_isrc_read;
RDWaveDataDialog *rip_wavedata_dialog;
};

View File

@ -28,7 +28,7 @@ Release: @RPM_RELEASE@
License: GPL
Packager: Fred Gleason <fredg@paravelsystems.com>
Source: rivendell-@VERSION@.tar.gz
Requires: @MYSQL_PKG@, @QT4_MYSQL_PKG@, @APACHE_PKG@, curl, @USERMODE_PKG@, @CDDA2WAV_PKG@, rivendell-pypad = @VERSION@, rsyslog
Requires: @MYSQL_PKG@, @QT4_MYSQL_PKG@, @APACHE_PKG@, curl, @USERMODE_PKG@, rivendell-pypad = @VERSION@, rsyslog
BuildRoot: /var/tmp/rivendell-@VERSION@
Obsoletes: rivendell-base rivendell-opsguide
Conflicts: rivendell-opsguide

View File

@ -26,6 +26,7 @@
#include <discid/discid.h>
#include <rdcmd_switch.h>
#include <rddisclookup.h>
#include "readcd_test.h"
@ -88,11 +89,25 @@ MainObject::MainObject(QObject *parent)
printf("MusicBrainz Submission URL: %s\n",discid_get_submission_url(disc));
if(extended) {
printf("Media Catalog Number (MCN): %s\n",discid_get_mcn(disc));
printf("ISRCs:\n");
int first=discid_get_first_track_num(disc);
int last=discid_get_last_track_num(disc);
for(int i=first;i<=last;i++) {
printf(" Track %02d ISRC: %s\n",i,
discid_get_track_isrc(disc,i));
QString isrc=discid_get_track_isrc(disc,i);
printf("%02d ",i);
printf("%s ",(const char *)isrc.toUtf8());
if(RDDiscLookup::isrcIsValid(isrc)) {
printf("ok: yes ");
}
else {
printf("ok: no ");
}
printf("formatted: %s ",
(const char *)RDDiscLookup::formattedIsrc(isrc).toUtf8());
printf("normalized: %s ",
(const char *)RDDiscLookup::normalizedIsrc(isrc).toUtf8());
printf("\n");
}
}