2017-08-29 Fred Gleason <fredg@paravelsystems.com>

* Added '--to-cart=' and '--to-file=' switches to rdrender(1).
This commit is contained in:
Fred Gleason 2017-08-29 13:21:17 -04:00
parent adece83242
commit c860c8b90d
5 changed files with 145 additions and 33 deletions

View File

@ -15982,3 +15982,5 @@
2017-08-29 Fred Gleason <fredg@paravelsystems.com> 2017-08-29 Fred Gleason <fredg@paravelsystems.com>
* Added '--bitrate=', '--format=', '--normalization-level=', * Added '--bitrate=', '--format=', '--normalization-level=',
'--quality=' and '--samplerate=' switches to rdrender(1). '--quality=' and '--samplerate=' switches to rdrender(1).
2017-08-29 Fred Gleason <fredg@paravelsystems.com>
* Added '--to-cart=' and '--to-file=' switches to rdrender(1).

View File

@ -30,11 +30,10 @@
<refsynopsisdiv id='synopsis'> <refsynopsisdiv id='synopsis'>
<cmdsynopsis> <cmdsynopsis>
<command>rdrender</command> <command>rdrender</command>
<arg choice='opt'><replaceable>GENERAL OPTS</replaceable></arg> <arg choice='opt'><replaceable>OUTPUT OPTS</replaceable></arg>
<arg choice='opt'><replaceable>RENDERING OPTS</replaceable></arg> <arg choice='opt'><replaceable>RENDERING OPTS</replaceable></arg>
<arg choice='opt'><replaceable>AUDIO OPTS</replaceable></arg> <arg choice='opt'><replaceable>AUDIO OPTS</replaceable></arg>
<arg choice='req'><replaceable>logname</replaceable></arg> <arg choice='req'><replaceable>logname</replaceable></arg>
<arg choice='req'><replaceable>output-file</replaceable></arg>
<sbr/> <sbr/>
</cmdsynopsis> </cmdsynopsis>
</refsynopsisdiv> </refsynopsisdiv>
@ -47,16 +46,53 @@
</para> </para>
<para> <para>
Three different types of options can be given to Three different types of options can be given to
<command>rdrender</command><manvolnum>1</manvolnum>: General, <command>rdrender</command><manvolnum>1</manvolnum>: Output,
which affect the operation of the program itself, Rendering, which affect the outputs of the program, Rendering,
which control how a log is virtually &quot;played&quot; and Audio, which control how a log is virtually &quot;played&quot; and Audio,
which control the format of the resulting audio file. Each group of which control the format of the resulting audio file. Each group of
options is documented separately below. options is documented separately below.
</para> </para>
</refsect1> </refsect1>
<refsect1 id='general;_options'><title>General Options</title> <refsect1 id='output_options'><title>Output Options</title>
<variablelist remap='TP'> <variablelist remap='TP'>
<varlistentry>
<term>
<option>--to-cart=</option><replaceable>cartnum</replaceable>:<replaceable>cutnum</replaceable>
</term>
<listitem>
<para>
Save the rendered log to cut number
<replaceable>cutnum</replaceable> in cart number
<replaceable>cartnum</replaceable>. Both cart and cut must already
exist.
</para>
<para>
This option is mutually exclusive with the
<option>--to-file</option> option, below. Exactly one
<option>--to-cart</option> or <option>--to-cart</option>
option must be specified.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--to-file=</option><replaceable>filename</replaceable>
</term>
<listitem>
<para>
Save the rendered log to the <replaceable>filename</replaceable> file.
</para>
<para>
This option is mutually exclusive with the
<option>--to-cart</option> option, above. Exactly one
<option>--to-cart</option> or <option>--to-cart</option>
option must be specified.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<option>--verbose</option> <option>--verbose</option>

View File

@ -66,18 +66,20 @@ int MainObject::MainLoop()
else { else {
sf_info.format=SF_FORMAT_WAV|SF_FORMAT_PCM_24; sf_info.format=SF_FORMAT_WAV|SF_FORMAT_PCM_24;
} }
if(render_settings_modified) { if(render_settings_modified||render_to_file.isEmpty()) {
// //
// 2nd pass will be needed, so just create a placeholder for now // 2nd pass will be needed, so just create a placeholder for now
// and then output to a temp file // and then output to a temp file
// //
Verbose("Pass 1 of 2"); Verbose("Pass 1 of 2");
if((f=fopen(render_output_filename,"w"))==NULL) { if(!render_to_file.isEmpty()) {
fprintf(stderr,"rdrender: unable to open output file [%s]\n", if((f=fopen(render_to_file,"w"))==NULL) {
strerror(errno)); fprintf(stderr,"rdrender: unable to open output file [%s]\n",
return 1; strerror(errno));
return 1;
}
fclose(f);
} }
fclose(f);
strncpy(tempdir,RDTempDir()+"/rdrenderXXXXXX",PATH_MAX); strncpy(tempdir,RDTempDir()+"/rdrenderXXXXXX",PATH_MAX);
render_temp_output_filename=QString(mkdtemp(tempdir))+"/log.wav"; render_temp_output_filename=QString(mkdtemp(tempdir))+"/log.wav";
sf_out=sf_open(render_temp_output_filename,SFM_WRITE,&sf_info); sf_out=sf_open(render_temp_output_filename,SFM_WRITE,&sf_info);
@ -91,7 +93,7 @@ int MainObject::MainLoop()
} }
else { else {
Verbose("Pass 1 of 1"); Verbose("Pass 1 of 1");
sf_out=sf_open(render_output_filename,SFM_WRITE,&sf_info); sf_out=sf_open(render_to_file,SFM_WRITE,&sf_info);
if(sf_out==NULL) { if(sf_out==NULL) {
fprintf(stderr,"rdrender: unable to open output file [%s]\n", fprintf(stderr,"rdrender: unable to open output file [%s]\n",
sf_strerror(sf_out)); sf_strerror(sf_out));
@ -209,23 +211,35 @@ int MainObject::MainLoop()
// //
// Process 2nd Pass // Process 2nd Pass
// //
if(render_settings_modified) { if(render_settings_modified||render_to_file.isEmpty()) {
QString err_msg; QString err_msg;
bool ok=false; bool ok=false;
Verbose("Pass 2 of 2"); Verbose("Pass 2 of 2");
ok=ConvertAudio(render_temp_output_filename,render_output_filename, if(!render_to_file.isEmpty()) {
&render_settings,&err_msg); Verbose("Writing output file");
DeleteCutFile(render_temp_output_filename); ok=ConvertAudio(render_temp_output_filename,render_to_file,
if(!ok) { &render_settings,&err_msg);
fprintf(stderr,"rdrender: unable to convert output [%s]\n", DeleteCutFile(render_temp_output_filename);
(const char *)err_msg); if(!ok) {
fprintf(stderr,"rdrender: unable to convert output [%s]\n",
(const char *)err_msg);
return 1;
}
}
else {
Verbose("Importing cart");
ok=ImportCart(render_temp_output_filename,render_cart_number,
render_cut_number,&err_msg);
DeleteCutFile(render_temp_output_filename);
if(!ok) {
fprintf(stderr,"rdrender: unable to import to cart [%s]\n",
(const char *)err_msg);
return 1;
}
} }
return 1;
} }
fprintf(stderr,"%s",(const char *)warnings); fprintf(stderr,"%s",(const char *)warnings);
fflush(stderr); fflush(stderr);
return 0; return 0;
} }

View File

@ -29,9 +29,11 @@
#include <rd.h> #include <rd.h>
#include <rdaudioconvert.h> #include <rdaudioconvert.h>
#include <rdaudioexport.h> #include <rdaudioexport.h>
#include <rdaudioimport.h>
#include <rdcart.h> #include <rdcart.h>
#include <rdcmd_switch.h> #include <rdcmd_switch.h>
#include <rdconf.h> #include <rdconf.h>
#include <rdcut.h>
#include <rdescape_string.h> #include <rdescape_string.h>
#include <rddbheartbeat.h> #include <rddbheartbeat.h>
#include <rdsettings.h> #include <rdsettings.h>
@ -46,6 +48,8 @@ MainObject::MainObject(QObject *parent)
render_first_line=-1; render_first_line=-1;
render_last_line=-1; render_last_line=-1;
render_ignore_stops=false; render_ignore_stops=false;
render_cart_number=0;
render_cut_number=-1;
// //
// Initialize Audio Settings // Initialize Audio Settings
@ -65,15 +69,10 @@ MainObject::MainObject(QObject *parent)
new RDCmdSwitch(qApp->argc(),qApp->argv(),"rdimport",RDRENDER_USAGE); new RDCmdSwitch(qApp->argc(),qApp->argv(),"rdimport",RDRENDER_USAGE);
if(cmd->keys()<1) { if(cmd->keys()<1) {
fprintf(stderr, fprintf(stderr,
"rdrender: you must specify a logname and output filename\n"); "rdrender: you must specify a logname\n");
exit(256); exit(256);
} }
if(cmd->keys()<2) { for(int i=0;i<(int)cmd->keys()-1;i++) {
fprintf(stderr,
"rdrender: you must specify an output filename\n");
exit(256);
}
for(int i=0;i<(int)cmd->keys()-2;i++) {
bool ok=false; bool ok=false;
if(cmd->key(i)=="--verbose") { if(cmd->key(i)=="--verbose") {
render_verbose=true; render_verbose=true;
@ -205,6 +204,28 @@ MainObject::MainObject(QObject *parent)
} }
cmd->setProcessed(i,true); cmd->setProcessed(i,true);
} }
if(cmd->key(i)=="--to-cart") {
QStringList f0=f0.split(":",cmd->value(i));
if(f0.size()!=2) {
fprintf(stderr,"rdrender: invalid --to-cart argument\n");
exit(1);
}
render_cart_number=f0[0].toUInt(&ok);
if((!ok)||(render_cart_number>RD_MAX_CART_NUMBER)) {
fprintf(stderr,"rdrender: invalid cart number in --to-cart argument\n");
exit(1);
}
render_cut_number=f0[1].toInt(&ok);
if((!ok)||(render_cut_number>RD_MAX_CUT_NUMBER)||(render_cut_number<1)) {
fprintf(stderr,"rdrender: invalid cut number in --to-cart argument\n");
exit(1);
}
cmd->setProcessed(i,true);
}
if(cmd->key(i)=="--to-file") {
render_to_file=cmd->value(i);
cmd->setProcessed(i,true);
}
if(!cmd->processed(i)) { if(!cmd->processed(i)) {
fprintf(stderr,"rdrender: unrecognized option\n"); fprintf(stderr,"rdrender: unrecognized option\n");
exit(256); exit(256);
@ -219,9 +240,12 @@ MainObject::MainObject(QObject *parent)
fprintf(stderr,"rdrender: invalid audio settings\n"); fprintf(stderr,"rdrender: invalid audio settings\n");
exit(1); exit(1);
} }
if(render_to_file.isEmpty()&&
render_logname=cmd->key(cmd->keys()-2); ((render_cart_number==0)||(render_cut_number==-1))) {
render_output_filename=cmd->key(cmd->keys()-1); fprintf(stderr,"rdrender: you must specify exactly one --to-cart or --to-file option\n");
exit(1);
}
render_logname=cmd->key(cmd->keys()-1);
if(render_start_time.isNull()) { if(render_start_time.isNull()) {
render_start_time=QTime(0,0,0,1); render_start_time=QTime(0,0,0,1);
} }
@ -266,6 +290,15 @@ MainObject::MainObject(QObject *parent)
if(render_settings.sampleRate()==0) { if(render_settings.sampleRate()==0) {
render_settings.setSampleRate(render_system->sampleRate()); render_settings.setSampleRate(render_system->sampleRate());
} }
if((render_cart_number>0)&&(!RDCart::exists(render_cart_number))) {
fprintf(stderr,"rdrender: no such cart\n");
exit(1);
}
if((render_cut_number>0)&&
(!RDCut::exists(render_cart_number,render_cut_number))) {
fprintf(stderr,"rdrender: no such cut\n");
exit(1);
}
// //
// Station Configuration // Station Configuration
@ -391,6 +424,29 @@ bool MainObject::ConvertAudio(const QString &srcfile,const QString &dstfile,
} }
bool MainObject::ImportCart(const QString &srcfile,unsigned cartnum,int cutnum,
QString *err_msg)
{
RDAudioImport::ErrorCode err_import_code;
RDAudioConvert::ErrorCode err_conv_code;
RDSettings settings;
settings.setNormalizationLevel(0);
RDAudioImport *conv=new RDAudioImport(render_station,render_config,this);
conv->setCartNumber(cartnum);
conv->setCutNumber(cutnum);
conv->setSourceFile(srcfile);
conv->setUseMetadata(false);
conv->setDestinationSettings(&settings);
err_import_code=
conv->runImport(render_user->name(),render_user->password(),&err_conv_code);
*err_msg=RDAudioImport::errorText(err_import_code,err_conv_code);
delete conv;
return err_import_code==RDAudioImport::ErrorOk;
}
int main(int argc,char *argv[]) int main(int argc,char *argv[])
{ {
QApplication a(argc,argv,false); QApplication a(argc,argv,false);

View File

@ -66,9 +66,13 @@ class MainObject : public QObject
void DeleteCutFile(const QString &dest_filename) const; void DeleteCutFile(const QString &dest_filename) const;
bool ConvertAudio(const QString &srcfile,const QString &dstfile, bool ConvertAudio(const QString &srcfile,const QString &dstfile,
RDSettings *s,QString *err_msg); RDSettings *s,QString *err_msg);
bool ImportCart(const QString &srcfile,unsigned cartnum,int cutnum,
QString *err_msg);
bool render_verbose; bool render_verbose;
QString render_logname; QString render_logname;
QString render_output_filename; QString render_to_file;
unsigned render_cart_number;
int render_cut_number;
QString render_temp_output_filename; QString render_temp_output_filename;
unsigned render_channels; unsigned render_channels;
QTime render_start_time; QTime render_start_time;