1
0
mirror of https://github.com/ElvishArtisan/rivendell.git synced 2025-04-24 17:37:53 +02:00

2014-10-25 Fred Gleason <fredg@paravelsystems.com>

* Implemented '--set-marker-end-*=' and '--set-marker-start-*='
	options for rdimport(1) in 'utils/rdimport/markerset.cpp',,
	'utils/rdimport/markerset.h', 'utils/rdimport/rdimport.cpp' and
	'utils/rdimport/rdimport.h'.
This commit is contained in:
Fred Gleason 2014-10-25 17:39:57 -04:00
parent 9cd612b1ed
commit 42d3bb430a
7 changed files with 342 additions and 72 deletions

@ -14577,3 +14577,8 @@
* Implemented post export commands in 'lib/rdreport.cpp'.
2014-10-25 Fred Gleason <fredg@paravelsystems.com>
* Created an rdimport(1) man page in 'docs/man/rdimport.1'.
2014-10-25 Fred Gleason <fredg@paravelsystems.com>
* Implemented '--set-marker-end-*=' and '--set-marker-start-*='
options for rdimport(1) in 'utils/rdimport/markerset.cpp',,
'utils/rdimport/markerset.h', 'utils/rdimport/rdimport.cpp' and
'utils/rdimport/rdimport.h'.

@ -16,71 +16,58 @@ list of filespecs to be read from standard input.
.SH OPTIONS
.TP
.B --verbose
Print progress messages during processing.
.TP
.B --help
Print a short usage message and exit.
.TP
.B --version
Output version information and exit.
.TP
.B --log-mode
Prepend date/time information to each line of printed status (implies
the '--verbose' option).
.TP
.B --normalization-level=<\fIlevel\fP>
Specify the level to use for peak normalizing the audio, in dBFS.
Specifying '0' will turn off normalization.
.B --add-scheduler-code=<\fIstr\fP>
Add Scheduler Code <\fIstr\fP> to the target cart. The specified
code must exist in RDAdmin->SchedulerCodes. This option may be
specified multiple times.
.TP
.B --autotrim-level=<level>
Specify the threshold level to use for autotrimming the audio, in dBFS.
Specifying '0' will turn off autotrimming.
.TP
.B --single-cart
If more than one file is imported, place them within multiple cuts within a
single cart, rather than creating separate carts for each file.
.TP
.B --segue-level=<\fIlevel\fP>
Specify the threshold level to use for setting the segue markers, in dBFS.
Default action is not to create segue markers.
.TP
.B --segue-length=<\fIlength\fP>
Length of the added segue in msecs. See \fB--segue-level\fP above.
.TP
.B --to-cart=<\fIcartnum\fP>
Specify the cart to import the audio into, rather than using the next
available cart number for the group. If the cart does not exist, it will
be created. Each file will be imported into a separate new cut within the
cart. Use of this option implies the \fB--single-cart\fP option as well,
and is mutually exclusive with the \fB--use-cartchunk-cutid\fP option.
.TP
.B --use-cartchunk-cutid
Import the audio into the cart specified by the CartChunk CutID parameter
associated with the file. If the cart does not exist, it will be
created. Use of this option is mutually exclusive with the \fB--to-cart\fP
option.
.TP
.B --title-from-cartchunk-cutid
Set the cart title from CartChunk CutID.
.TP
.B --cart-number-offset=<\fIoffset\fP>
Add <\fIoffset\fP> to the cart number as determined from metadata pattern
or --use-cartchunk-cutid.
.TP
.B --delete-source
Delete each source file after successful import. Use with caution!
.B --create-enddate-offset=<\fIdays\fP>
If the imported file does not reference an end date, create with
end date offset by <\fIdays\fP> days relative to the current date.
Cannot be less than the value the value for \fB--create-startdate-offset\fP
(default = 0).
.TP
.B --create-startdate-offset=<\fIdays\fP>
If the imported file does not reference a start date, create with
startdate offset by <\fIdays\fP> days relative to the current date.
Cannot be greater than the value for \fB--create-enddate-offset\fP
(default = 0).
.TP
.B --delete-cuts
Delete all cuts within the destination cart before importing. Use
with caution!
.TP
.B --delete-source
Delete each source file after successful import. Use with caution!
.TP
.B --drop-box
Operate in DropBox mode, causing \fIrdimport(1)\fP to run continuously,
periodically scanning for files matching the specified <\fIfilespec\fP>,
importing and then deleting them when found. WARNING: use of this option
also implies the \fB--delete-source\fP option!
.TP
.B --enddate-offset=<days>
If the imported file references an end date, offset the value by <\fIdays\fP>
days.
.TP
.B --fix-broken-formats
Attempt to work around malformed audio input data.
.TP
.B --help
Print a short usage message and exit.
.TP
.B --log-mode
Prepend date/time information to each line of printed status (implies
the '--verbose' option).
.TP
.B --metadata-pattern=<\fIpattern\fP>
Attempt to read metadata parameters from the source filename, using
the pattern <\fIpattern\fP>. Patterns consist of a sequence of wildcards and
@ -154,41 +141,84 @@ when processing a filename of 'My Song_My Artist_TEMP_123456.mp3',
would extract 'My Song' as the title and 'My Artist' as the artist,
while importing it into cart 123456 in the TEMP group.
.TP
.B --startdate-offset=<\fIdays\fP>
If the imported file references a start date, offset the value by <\fIdays\fP>
days.
.B --normalization-level=<\fIlevel\fP>
Specify the level to use for peak normalizing the audio, in dBFS.
Specifying '0' will turn off normalization.
.TP
.B --enddate-offset=<days>
If the imported file references an end date, offset the value by <\fIdays\fP>
days.
.B --segue-length=<\fIlength\fP>
Length of the added segue in msecs. See \fB--segue-level\fP below.
.TP
.B --create-startdate-offset=<\fIdays\fP>
If the imported file does not reference a start date, create with
startdate offset by <\fIdays\fP> days relative to the current date.
Cannot be greater than the value for \fB--create-enddate-offset\fP
(default = 0).
.TP
.B --create-enddate-offset=<\fIdays\fP>
If the imported file does not reference an end date, create with
end date offset by <\fIdays\fP> days relative to the current date.
Cannot be less than the value the value for \fB--create-startdate-offset\fP
(default = 0).
.B --segue-level=<\fIlevel\fP>
Specify the threshold level to use for setting the segue markers, in dBFS.
Default action is not to create segue markers.
.TP
.B --set-daypart-times=<\fIstart-time\fP>,<\fIend-time\fP>
Set the start and end daypart times, in the format HHMMSS.
.TP
.B --fix-broken-formats
Attempt to work around malformed audio input data.
.B --set-marker-end-<\fImarker\fP>=<\fIoffset\fP>
Set an end marker to a given offset value. The <\fIoffset\fP> parameter is
specified in milliseconds. If positive, it is taken to indicate a marker
position relative to the absolute beginning of the audio cut, while if
negative, it is taken to indicate a marker position relative to the absolute
end of the audio cut.
The following <\fImarker\fP> types are recognized:
.RS
.TP
.B --add-scheduler-code=<\fIstr\fP>
Add Scheduler Code <\fIstr\fP> to the target cart. The specified
code must exist in RDAdmin->SchedulerCodes. This option may be
specified multiple times.
.B cut
The Cut markers.
.TP
.B hook
The Hook markers.
.TP
.B segue
The Segue markers
.TP
.B talk
The Talk markers.
.RE
.RE
.TP
.B --set-marker-start-<\fImarker\fP>=<\fIoffset\fP>
Set a start marker to a given offset value. See the discussion of the
\fB--set-marker-end-<marker>\fP option above for a description of the
<\fImarker\fP> and <\fIoffset\fP> parameters.
.TP
.B --set-user-defined=<\fIstr\fP>
Set the User Defined field for the target cart to <\fIstr\fP>. This will
override any value that might otherwise be set --e.g. by using the
\fB--metadata-pattern\fP option.
.TP
.B --single-cart
If more than one file is imported, place them within multiple cuts within a
single cart, rather than creating separate carts for each file.
.TP
.B --startdate-offset=<\fIdays\fP>
If the imported file references a start date, offset the value by <\fIdays\fP>
days.
.TP
.B --title-from-cartchunk-cutid
Set the cart title from CartChunk CutID.
.TP
.B --to-cart=<\fIcartnum\fP>
Specify the cart to import the audio into, rather than using the next
available cart number for the group. If the cart does not exist, it will
be created. Each file will be imported into a separate new cut within the
cart. Use of this option implies the \fB--single-cart\fP option as well,
and is mutually exclusive with the \fB--use-cartchunk-cutid\fP option.
.TP
.B --use-cartchunk-cutid
Import the audio into the cart specified by the CartChunk CutID parameter
associated with the file. If the cart does not exist, it will be
created. Use of this option is mutually exclusive with the \fB--to-cart\fP
option.
.TP
.B --verbose
Print progress messages during processing.
.TP
.B --version
Output version information and exit.
.SH NOTES
It may be necessary to enclose individual <\fIfilespec\fP> clauses in quotes
@ -197,8 +227,8 @@ indicator that this is necessary is the failure of \fBrdimport(1)\fP to process
newly added files when running in DropBox mode.
.SH BUGS
It could be argued that RMS rather peak normalization would be more appropriate
for use with the \fB--normalization-level\fP option.
It could be argued that RMS rather than peak normalization would be more
appropriate for use with the \fB--normalization-level\fP option.
.SH AUTHOR
Fred Gleason <fredg@paravelsystems.com>

@ -31,7 +31,8 @@ moc_%.cpp: %.h
bin_PROGRAMS = rdimport
dist_rdimport_SOURCES = rdimport.cpp rdimport.h
dist_rdimport_SOURCES = markerset.cpp markerset.h\
rdimport.cpp rdimport.h
nodist_rdimport_SOURCES = moc_rdimport.cpp

@ -0,0 +1,143 @@
// markerset.cpp
//
// Abstract a set of marker parameters.
//
// (C) Copyright 2014 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 <stdio.h>
#include <stdlib.h>
#include "markerset.h"
MarkerSet::MarkerSet()
{
marker_start_valid=false;
marker_start_value=0;
marker_end_valid=false;
marker_end_value=0;
marker_audio_length=0;
}
bool MarkerSet::hasStartValue() const
{
return marker_start_valid;
}
int MarkerSet::startValue(int lo_limit,int hi_limit) const
{
return LimitCheck(marker_start_value,lo_limit,hi_limit);
}
bool MarkerSet::hasEndValue() const
{
return marker_end_valid;
}
int MarkerSet::endValue(int lo_limit,int hi_limit) const
{
return LimitCheck(marker_end_value,lo_limit,hi_limit);
}
void MarkerSet::load(RDCmdSwitch *cmd,const QString &marker)
{
QString start_key="--set-marker-start-"+marker;
QString end_key="--set-marker-end-"+marker;
marker_marker=marker;
for(unsigned i=0;i<cmd->keys();i++) {
if(cmd->key(i)==start_key) {
marker_start_value=cmd->value(i).toInt(&marker_start_valid);
if(!marker_start_valid) {
fprintf(stderr,"rdimport: invalid argment to %s\n",
(const char *)start_key);
exit(255);
}
cmd->setProcessed(i,true);
}
if(cmd->key(i)==end_key) {
marker_end_value=cmd->value(i).toInt(&marker_end_valid);
if(!marker_end_valid) {
fprintf(stderr,"rdimport: invalid argment to %s\n",
(const char *)end_key);
exit(255);
}
cmd->setProcessed(i,true);
}
}
if(marker_end_valid&&(!marker_start_valid)) {
marker_start_value=0;
marker_start_valid=true;
}
}
void MarkerSet::setAudioLength(int msecs)
{
if(marker_start_valid&&(!marker_end_valid)) {
marker_end_value=msecs;
marker_end_valid=true;
}
marker_audio_length=msecs;
}
void MarkerSet::dump()
{
if(marker_start_valid) {
printf(" Marker Start %s: ",(const char *)marker_marker);
printf("%d mS\n",marker_start_value);
}
if(marker_end_valid) {
printf(" Marker End %s: ",(const char *)marker_marker);
printf("%d mS\n",marker_end_value);
}
}
int MarkerSet::LimitCheck(int value,int lo_limit,int hi_limit) const
{
if(lo_limit!=-1) {
if(value<lo_limit) {
return lo_limit;
}
}
if(hi_limit!=-1) {
if(value>hi_limit) {
return hi_limit;
}
}
return value;
}
int MarkerSet::FrontReference(int value) const
{
if(value>=0) {
if(value>marker_audio_length) {
return marker_audio_length;
}
return value;
}
if((marker_audio_length+value)<0) {
return 0;
}
return marker_audio_length+value;
}

@ -0,0 +1,50 @@
// markerset.h
//
// Abstract a set of marker parameters.
//
// (C) Copyright 2014 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 MARKERSET_H
#define MARKERSET_H
#include <rdcmd_switch.h>
class MarkerSet
{
public:
MarkerSet();
bool hasStartValue() const;
int startValue(int lo_limit=-1,int hi_limit=-1) const;
bool hasEndValue() const;
int endValue(int lo_limit=-1,int hi_limit=-1) const;
void load(RDCmdSwitch *cmd,const QString &marker);
void setAudioLength(int msecs);
void dump();
private:
int LimitCheck(int value,int lo_limit,int hi_limit) const;
int FrontReference(int value) const;
QString marker_marker;
bool marker_start_valid;
int marker_start_value;
bool marker_end_valid;
int marker_end_value;
int marker_audio_length;
};
#endif // MARKERSET_H

@ -246,6 +246,14 @@ MainObject::MainObject(QObject *parent,const char *name)
import_create_dates=true;
}
}
import_cut_markers=new MarkerSet();
import_cut_markers->load(import_cmd,"cut");
import_talk_markers=new MarkerSet();
import_talk_markers->load(import_cmd,"talk");
import_hook_markers=new MarkerSet();
import_hook_markers->load(import_cmd,"hook");
import_segue_markers=new MarkerSet();
import_segue_markers->load(import_cmd,"segue");
//
// Read Configuration
@ -508,6 +516,10 @@ MainObject::MainObject(QObject *parent,const char *name)
if(import_persistent_dropbox_id>=0) {
printf(" Persistent DropBox ID = %d\n",import_persistent_dropbox_id);
}
import_cut_markers->dump();
import_talk_markers->dump();
import_hook_markers->dump();
import_segue_markers->dump();
printf(" Files to process:\n");
for(unsigned i=import_file_key;i<import_cmd->keys();i++) {
printf(" \"%s\"\n",(const char *)import_cmd->key(i));
@ -785,7 +797,6 @@ MainObject::Result MainObject::ImportFile(const QString &filename,
return MainObject::FileBad;
}
}
if(!import_metadata_pattern.isEmpty()) {
QString groupname=effective_group->name();
found_cart=RunPattern(import_metadata_pattern,RDGetBasePart(filename),
@ -1006,6 +1017,30 @@ MainObject::Result MainObject::ImportFile(const QString &filename,
cut->setStartDaypart(import_dayparts[0],true);
cut->setEndDaypart(import_dayparts[1],true);
}
import_cut_markers->setAudioLength(wavefile->getExtTimeLength());
if(import_cut_markers->hasStartValue()) {
cut->setStartPoint(import_cut_markers->startValue());
cut->setEndPoint(import_cut_markers->endValue());
cut->setLength(cut->endPoint()-cut->startPoint());
cart->updateLength();
}
int lo=cut->startPoint();
int hi=cut->endPoint();
import_talk_markers->setAudioLength(wavefile->getExtTimeLength());
if(import_talk_markers->hasStartValue()) {
cut->setTalkStartPoint(import_talk_markers->startValue(lo,hi));
cut->setTalkEndPoint(import_talk_markers->endValue(lo,hi));
}
import_hook_markers->setAudioLength(wavefile->getExtTimeLength());
if(import_hook_markers->hasStartValue()) {
cut->setHookStartPoint(import_hook_markers->startValue(lo,hi));
cut->setHookEndPoint(import_hook_markers->endValue(lo,hi));
}
import_segue_markers->setAudioLength(wavefile->getExtTimeLength());
if(import_segue_markers->hasStartValue()) {
cut->setSegueStartPoint(import_segue_markers->startValue(lo,hi));
cut->setSegueEndPoint(import_segue_markers->endValue(lo,hi));
}
delete settings;
delete conv;
delete cut;

@ -44,6 +44,8 @@
#include <rdsystem.h>
#include <rdstation.h>
#include "markerset.h"
#define RDIMPORT_TEMP_BASENAME "rdimp"
#define RDIMPORT_STDIN_BUFFER_LENGTH 1024
#define RDIMPORT_DROPBOX_SCAN_INTERVAL 5
@ -127,6 +129,10 @@ class MainObject : public QObject
QString import_temp_fix_filename;
RDSystem *import_system;
RDStation *import_station;
MarkerSet *import_cut_markers;
MarkerSet *import_talk_markers;
MarkerSet *import_hook_markers;
MarkerSet *import_segue_markers;
};