Merged rendering

This commit is contained in:
Fred Gleason 2017-09-21 07:40:22 -04:00
commit ac84b6879d
25 changed files with 748 additions and 74 deletions

View File

@ -16025,6 +16025,23 @@
2017-09-18 Fred Gleason <fredg@paravelsystems.com>
* Fixed a bug in rdrender that caused the the default start time
to be midnight.
2017-09-19 Fred Gleason <fredg@paravelsystems.com>
* Added a 'Render Log' dialog to rdlogedit(1).
2017-09-19 Fred Gleason <fredg@paravelsystems.com>
* Added support for cart/cut rendering to the 'Render Log' dialog
in rdlogedit(1).
* Added a length check when rendering to cart/cut in
'lib/rdrenderer.cpp'.
2017-09-19 Fred Gleason <fredg@paravelsystems.com>
* Removed redundant 'int chans' parameter from the
'RDRenderer::renderTo*()' methods in 'lib/rdrenderer.cpp' and
'lib/rdrenderer.h'.
* Fixed a bug in 'lib/rdrenderer.cpp' and 'lib/rdrenerer.h' that
caused logs rendered to cart/cut in stereo regardless of the number
of channels specified.
2017-09-20 Fred Gleason <fredg@paravelsystems.com>
* Fixed a bug in rdrender(1) that caused the --channels option
to be ignored.
2017-09-20 Fred Gleason <fredg@paravelsystems.com>
* Fixed a race in 'lib/rdformpost.cpp' that could cause POST data
to be truncated.
@ -16042,3 +16059,8 @@
2017-09-20 Fred Gleason <fredg@paravelsystems.com>
* Added a 'Reset' button to the 'Edit Dropbox' dialog
in rdadmin(1).
2017-09-21 Fred Gleason <fredg@paravelsystems.com>
* Fixed a bug in 'lib/rdrenderer.cpp' that caused audio corruption
when rendering logs longer than 44:30.
2017-09-21 Fred Gleason <fredg@paravelsystems.com>
* Updated the rdrender(1) man page.

View File

@ -30,9 +30,9 @@
<refsynopsisdiv id='synopsis'>
<cmdsynopsis>
<command>rdrender</command>
<arg choice='opt'><replaceable>OUTPUT OPTS</replaceable></arg>
<arg choice='opt'><replaceable>RENDERING OPTS</replaceable></arg>
<arg choice='opt'><replaceable>AUDIO OPTS</replaceable></arg>
<arg choice='opt'><replaceable>OUTPUT-OPTS</replaceable></arg>
<arg choice='opt'><replaceable>RENDERING-OPTS</replaceable></arg>
<arg choice='opt'><replaceable>AUDIO-OPTS</replaceable></arg>
<arg choice='req'><replaceable>logname</replaceable></arg>
<sbr/>
</cmdsynopsis>
@ -66,12 +66,8 @@
<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-file</option>
option must be specified.
<option>--to-file</option> option, below.
</para>
</listitem>
</varlistentry>
@ -83,12 +79,8 @@
<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-file</option>
option must be specified.
<option>--to-cart</option> option, above.
</para>
</listitem>
</varlistentry>
@ -105,8 +97,11 @@
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
Exactly one <option>--to-cart</option> or <option>--to-file</option>
option must be specified.
</para>
</refsect1>
<refsect1 id='rendering_options'><title>Rendering Options</title>
@ -205,8 +200,6 @@
<para>
Specify the bitrate to use, in <replaceable>rate</replaceable>
bits per second. Default value is 256000 bits/sec.
</para>
<para>
This setting is meaningful only when used with the
<userinput>MP2</userinput> or <userinput>MP3</userinput> formats.
</para>
@ -307,8 +300,6 @@
Specify the quality level to use, in the range
<userinput>-1</userinput> through <userinput>10</userinput>,
inclusive. Default value is <userinput>3</userinput>.
</para>
<para>
This setting is meaningful only when used with the
<userinput>VORBIS</userinput> format.
</para>
@ -341,8 +332,10 @@
options).
</para>
<para>
Maximum length of the rendered log is limited to appoximately two hours when
using <option>--to-cart</option>.
Due to limitations inherent in the 32 bit Broadcast Wave File format used in
Rivendell's audio store, the maximum length of the rendered log is limited
to appoximately three hours for stereo and six hours for mono when using
the <option>--to-cart</option> option.
</para>
</refsect1>

View File

@ -2230,6 +2230,10 @@ Zkuste to, prosím, znovu!</translation>
<source>failed to play (NO AUDIO AVAILABLE)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rendered log is too long!</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDReport</name>

View File

@ -2221,6 +2221,10 @@ bitte erneut versuchen!</translation>
<source>failed to play (NO AUDIO AVAILABLE)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rendered log is too long!</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDReport</name>

View File

@ -2223,6 +2223,10 @@ please try again!</source>
<source>failed to play (NO AUDIO AVAILABLE)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rendered log is too long!</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDReport</name>

View File

@ -1882,6 +1882,10 @@ please try again!</source>
<source>failed to play (NO AUDIO AVAILABLE)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rendered log is too long!</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDSoundPanel</name>

View File

@ -2171,6 +2171,10 @@ prøv ein gong til!</translation>
<source>failed to play (NO AUDIO AVAILABLE)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rendered log is too long!</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDReport</name>

View File

@ -2171,6 +2171,10 @@ prøv ein gong til!</translation>
<source>failed to play (NO AUDIO AVAILABLE)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rendered log is too long!</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDReport</name>

View File

@ -2170,6 +2170,10 @@ por favor, tente novamente!</translation>
<source>failed to play (NO AUDIO AVAILABLE)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rendered log is too long!</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDReport</name>

View File

@ -239,6 +239,7 @@ RDRenderer::RDRenderer(RDUser *user,RDStation *station,RDSystem *system,
render_station=station;
render_system=system;
render_config=config;
render_total_passes=0;
}
@ -248,15 +249,16 @@ RDRenderer::~RDRenderer()
bool RDRenderer::renderToFile(const QString &outfile,RDLogEvent *log,
unsigned chans,RDSettings *s,
const QTime &start_time,bool ignore_stops,
QString *err_msg,int first_line,int last_line,
RDSettings *s,const QTime &start_time,
bool ignore_stops,QString *err_msg,
int first_line,int last_line,
const QTime &first_time,const QTime &last_time)
{
QString temp_output_filename;
char tempdir[PATH_MAX];
bool ok=false;
FILE *f=NULL;
bool ret;
//
// Verify Destination
@ -270,6 +272,8 @@ bool RDRenderer::renderToFile(const QString &outfile,RDLogEvent *log,
if(((s->format()!=RDSettings::Pcm16)&&(s->format()!=RDSettings::Pcm24))||
(s->normalizationLevel()!=0)) {
ProgressMessage("Pass 1 of 2");
render_total_passes=2;
//
// Get Temporary File
//
@ -280,7 +284,7 @@ bool RDRenderer::renderToFile(const QString &outfile,RDLogEvent *log,
//
// Render It
//
if(!Render(temp_output_filename,log,chans,s,start_time,ignore_stops,err_msg,
if(!Render(temp_output_filename,log,s,start_time,ignore_stops,err_msg,
first_line,last_line,first_time,last_time)) {
return false;
}
@ -292,30 +296,54 @@ bool RDRenderer::renderToFile(const QString &outfile,RDLogEvent *log,
ProgressMessage(tr("Writing output file"));
ok=ConvertAudio(temp_output_filename,outfile,s,err_msg);
DeleteTempFile(temp_output_filename);
emit lineStarted(log->size()+1,log->size()+1);
if(!ok) {
return false;
}
}
else {
ProgressMessage(tr("Pass 1 of 1"));
return Render(outfile,log,chans,s,start_time,ignore_stops,err_msg,
first_line,last_line,first_time,last_time);
render_total_passes=1;
ret=Render(outfile,log,s,start_time,ignore_stops,err_msg,
first_line,last_line,first_time,last_time);
emit lineStarted(log->size(),log->size());
return ret;
}
return true;
}
bool RDRenderer::renderToCart(unsigned cartnum,int cutnum,RDLogEvent *log,
unsigned chans,RDSettings *s,
const QTime &start_time,bool ignore_stops,
QString *err_msg,int first_line,int last_line,
RDSettings *s,const QTime &start_time,
bool ignore_stops,QString *err_msg,
int first_line,int last_line,
const QTime &first_time,const QTime &last_time)
{
QString temp_output_filename;
char tempdir[PATH_MAX];
bool ok=false;
if(first_line<0) {
first_line=0;
}
if(last_line<0) {
last_line=log->size();
}
//
// Check that we won't overflow the 32 bit BWF structures
// when we go to import the rendered log back into the audio store
//
if((double)log->length(first_line,last_line-1)/1000.0>=
(1073741824.0/((double)s->channels()*(double)s->sampleRate()))) {
*err_msg=tr("Rendered log is too long!");
return false;
}
ProgressMessage(tr("Pass 1 of 2"));
render_total_passes=2;
//
// Verify Destination
//
@ -338,7 +366,7 @@ bool RDRenderer::renderToCart(unsigned cartnum,int cutnum,RDLogEvent *log,
//
// Render It
//
if(!Render(temp_output_filename,log,chans,s,start_time,ignore_stops,err_msg,
if(!Render(temp_output_filename,log,s,start_time,ignore_stops,err_msg,
first_line,last_line,first_time,last_time)) {
return false;
}
@ -348,8 +376,9 @@ bool RDRenderer::renderToCart(unsigned cartnum,int cutnum,RDLogEvent *log,
//
ProgressMessage(tr("Pass 2 of 2"));
ProgressMessage(tr("Importing cart"));
ok=ImportCart(temp_output_filename,cartnum,cutnum,err_msg);
ok=ImportCart(temp_output_filename,cartnum,cutnum,s->channels(),err_msg);
DeleteTempFile(temp_output_filename);
emit lineStarted(log->size()+1,log->size()+1);
if(!ok) {
return false;
}
@ -364,8 +393,14 @@ QStringList RDRenderer::warnings() const
}
bool RDRenderer::Render(const QString &outfile,RDLogEvent *log,unsigned chans,
RDSettings *s,const QTime &start_time,bool ignore_stops,
void RDRenderer::abort()
{
render_abort=true;
}
bool RDRenderer::Render(const QString &outfile,RDLogEvent *log,RDSettings *s,
const QTime &start_time,bool ignore_stops,
QString *err_msg,int first_line,int last_line,
const QTime &first_time,const QTime &last_time)
{
@ -374,6 +409,7 @@ bool RDRenderer::Render(const QString &outfile,RDLogEvent *log,unsigned chans,
QString temp_output_filename;
render_warnings.clear();
render_abort=false;
//
// Open Output File
@ -383,7 +419,7 @@ bool RDRenderer::Render(const QString &outfile,RDLogEvent *log,unsigned chans,
memset(&sf_info,0,sizeof(sf_info));
sf_info.samplerate=render_system->sampleRate();
sf_info.channels=chans;
sf_info.channels=s->channels();
if(s->format()==RDSettings::Pcm16) {
sf_info.format=SF_FORMAT_WAV|SF_FORMAT_PCM_16;
}
@ -404,7 +440,7 @@ bool RDRenderer::Render(const QString &outfile,RDLogEvent *log,unsigned chans,
for(int i=0;i<log->size();i++) {
lls.push_back(new __RDRenderLogLine(log->logLine(i),render_user,
render_station,render_system,
render_config,chans));
render_config,s->channels()));
if(ignore_stops&&(lls.back()->transType()==RDLogLine::Stop)) {
lls.back()->setTransType(RDLogLine::Play);
}
@ -435,7 +471,7 @@ bool RDRenderer::Render(const QString &outfile,RDLogEvent *log,unsigned chans,
}
lls.push_back(new __RDRenderLogLine(new RDLogLine(),render_user,
render_station,render_system,
render_config,chans));
render_config,s->channels()));
lls.back()->setTransType(RDLogLine::Play);
if((!first_time.isNull())&&(first_line==-1)) {
first_line=log->size();
@ -445,6 +481,14 @@ bool RDRenderer::Render(const QString &outfile,RDLogEvent *log,unsigned chans,
// Iterate through it
//
for(unsigned i=0;i<lls.size();i++) {
if(render_abort) {
emit lineStarted(log->size()+render_total_passes-1,
log->size()+render_total_passes-1);
*err_msg+="Render aborted.\n";
sf_close(sf_out);
return false;
}
emit lineStarted(i,log->size()+render_total_passes-1);
if(((first_line==-1)||(first_line<=(int)i))&&
((last_line==-1)||(last_line>(int)i))) {
if(lls.at(i)->transType()==RDLogLine::Stop) {
@ -474,13 +518,13 @@ bool RDRenderer::Render(const QString &outfile,RDLogEvent *log,unsigned chans,
current_time=current_time.addMSecs(lls.at(i)->cut()->endPoint()-
lls.at(i)->cut()->startPoint());
}
pcm=new float[frames*chans];
memset(pcm,0,frames*chans);
pcm=new float[frames*s->channels()];
memset(pcm,0,frames*s->channels()*sizeof(float));
for(unsigned j=0;j<i;j++) {
Sum(pcm,lls.at(j),frames,chans);
Sum(pcm,lls.at(j),frames,s->channels());
}
Sum(pcm,lls.at(i),frames,chans);
Sum(pcm,lls.at(i),frames,s->channels());
sf_writef_float(sf_out,pcm,frames);
delete pcm;
pcm=NULL;
@ -554,12 +598,13 @@ bool RDRenderer::ConvertAudio(const QString &srcfile,const QString &dstfile,
bool RDRenderer::ImportCart(const QString &srcfile,unsigned cartnum,int cutnum,
QString *err_msg)
unsigned chans,QString *err_msg)
{
RDAudioImport::ErrorCode err_import_code;
RDAudioConvert::ErrorCode err_conv_code;
RDSettings settings;
settings.setChannels(chans);
settings.setNormalizationLevel(0);
RDAudioImport *conv=new RDAudioImport(render_station,render_config,this);

View File

@ -80,24 +80,28 @@ class RDRenderer : public QObject
RDRenderer(RDUser *user,RDStation *station,RDSystem *system,RDConfig *config,
QObject *parent=0);
~RDRenderer();
bool renderToFile(const QString &outfile,RDLogEvent *log,unsigned chans,
RDSettings *s,const QTime &start_time,bool ignore_stops,
bool renderToFile(const QString &outfile,RDLogEvent *log,RDSettings *s,
const QTime &start_time,bool ignore_stops,
QString *err_msg,int first_line,int last_line,
const QTime &first_time=QTime(),
const QTime &last_time=QTime());
bool renderToCart(unsigned cartnum,int cutnum,RDLogEvent *log,unsigned chans,
RDSettings *s,const QTime &start_time,bool ignore_stops,
bool renderToCart(unsigned cartnum,int cutnum,RDLogEvent *log,RDSettings *s,
const QTime &start_time,bool ignore_stops,
QString *err_msg,int first_line,int last_line,
const QTime &first_time=QTime(),
const QTime &last_time=QTime());
QStringList warnings() const;
public slots:
void abort();
signals:
void progressMessageSent(const QString &msg);
void lineStarted(int linno,int totallines);
private:
bool Render(const QString &outfile,RDLogEvent *log,unsigned chans,
RDSettings *s,const QTime &start_time,bool ignore_stops,
bool Render(const QString &outfile,RDLogEvent *log,RDSettings *s,
const QTime &start_time,bool ignore_stops,
QString *err_msg,int first_line,int last_line,
const QTime &first_time,const QTime &last_time);
void Sum(float *pcm_out,__RDRenderLogLine *ll,sf_count_t frames,
@ -105,7 +109,7 @@ class RDRenderer : public QObject
bool ConvertAudio(const QString &srcfile,const QString &dstfile,
RDSettings *s,QString *err_msg);
bool ImportCart(const QString &srcfile,unsigned cartnum,int cutnum,
QString *err_msg);
unsigned chans,QString *err_msg);
uint64_t FramesFromMsec(uint64_t msec) const;
void DeleteTempFile(const QString &filename) const;
void ProgressMessage(const QString &msg);
@ -116,6 +120,8 @@ class RDRenderer : public QObject
RDSystem *render_system;
RDConfig *render_config;
QStringList render_warnings;
bool render_abort;
int render_total_passes;
};

View File

@ -55,6 +55,7 @@ dist_rdlogedit_SOURCES = add_meta.cpp add_meta.h\
list_logs.cpp list_logs.h\
log_listview.cpp log_listview.h\
rdlogedit.cpp rdlogedit.h globals.h\
render_dialog.cpp render_dialog.h\
voice_tracker.cpp voice_tracker.h
nodist_rdlogedit_SOURCES = moc_add_meta.cpp\
@ -69,6 +70,7 @@ nodist_rdlogedit_SOURCES = moc_add_meta.cpp\
moc_list_reports.cpp\
moc_log_listview.cpp\
moc_rdlogedit.cpp\
moc_render_dialog.cpp\
moc_voice_tracker.cpp
rdlogedit_LDADD = @LIB_RDLIBS@ @LIBVORBIS@

View File

@ -129,6 +129,11 @@ EditLog::EditLog(QString logname,QString *filter,QString *group,
edit_mic16_map=new QPixmap(mic16_xpm);
edit_traffic_map=new QPixmap(traffic_xpm);
//
// Dialogs
//
edit_render_dialog=new RenderDialog(rdstation_conf,rdsystem,log_config,this);
//
// Text Validator
//
@ -453,13 +458,21 @@ EditLog::EditLog(QString logname,QString *filter,QString *group,
connect(edit_save_button,SIGNAL(clicked()),this,SLOT(saveData()));
//
// SaveAs Button
// Save As Button
//
edit_saveas_button=new QPushButton(this);
edit_saveas_button->setFont(button_font);
edit_saveas_button->setText(tr("Save\n&As"));
edit_saveas_button->setText(tr("Save")+"\n"+tr("As"));
connect(edit_saveas_button,SIGNAL(clicked()),this,SLOT(saveasData()));
//
// Render Button
//
edit_renderas_button=new QPushButton(this);
edit_renderas_button->setFont(button_font);
edit_renderas_button->setText(tr("Render"));
connect(edit_renderas_button,SIGNAL(clicked()),this,SLOT(renderasData()));
//
// Reports Button
//
@ -1127,6 +1140,32 @@ ORIGIN_DATETIME=NOW(),LINK_DATETIME=NOW(),SERVICE=\"%s\"",
}
void EditLog::renderasData()
{
int first_line=-1;
int last_line=-1;
QListViewItem *next=edit_log_list->firstChild();
while(next!=NULL) {
if(edit_log_list->isSelected(next)) {
if(next->text(13).toInt()!=END_MARKER_ID) {
if(first_line<0) {
first_line=next->text(14).toInt();
}
last_line=next->text(14).toInt();
}
}
next=next->nextSibling();
}
if(first_line<0) {
edit_render_dialog->exec(rduser,edit_log_event,0,0);
}
else {
edit_render_dialog->exec(rduser,edit_log_event,first_line,last_line+1);
}
}
void EditLog::reportsData()
{
QDate start_date;
@ -1260,10 +1299,11 @@ void EditLog::resizeEvent(QResizeEvent *e)
setGeometry(size().width()-100,size().height()-125,80,50);
edit_save_button->setGeometry(10,size().height()-60,80,50);
edit_saveas_button->setGeometry(100,size().height()-60,80,50);
edit_reports_button->setGeometry(250,size().height()-60,80,50);
edit_renderas_button->setGeometry(190,size().height()-60,80,50);
edit_reports_button->setGeometry(300,size().height()-60,80,50);
#ifndef WIN32
edit_player->playButton()->setGeometry(400,size().height()-60,80,50);
edit_player->stopButton()->setGeometry(490,size().height()-60,80,50);
edit_player->playButton()->setGeometry(410,size().height()-60,80,50);
edit_player->stopButton()->setGeometry(500,size().height()-60,80,50);
#endif // WIN32
edit_ok_button->
setGeometry(size().width()-180,size().height()-60,80,50);

View File

@ -40,8 +40,9 @@
#include <rdgroup_list.h>
#include <rdsimpleplayer.h>
#include <drop_listview.h>
#include <list_reports.h>
#include "drop_listview.h"
#include "list_reports.h"
#include "render_dialog.h"
//
// Widget Settings
@ -84,6 +85,7 @@ class EditLog : public QDialog
void cartDroppedData(int line,RDLogLine *ll);
void saveData();
void saveasData();
void renderasData();
void reportsData();
void okData();
void cancelData();
@ -162,6 +164,7 @@ class EditLog : public QDialog
QPushButton *edit_paste_button;
QPushButton *edit_save_button;
QPushButton *edit_saveas_button;
QPushButton *edit_renderas_button;
QPushButton *edit_reports_button;
RDTransportButton *edit_play_button;
RDTransportButton *edit_stop_button;
@ -183,6 +186,7 @@ class EditLog : public QDialog
QLabel *edit_purgedate_label;
QDateEdit *edit_purgedate_edit;
QPushButton *edit_purgedate_button;
RenderDialog *edit_render_dialog;
};

View File

@ -234,7 +234,7 @@ popisná data</translation>
<message>
<source>Save
&amp;As</source>
<translation>Uložit
<translation type="obsolete">Uložit
&amp;jako</translation>
</message>
<message>
@ -409,6 +409,18 @@ jež jsou pro vybranou službu zakázány!</translation>
<source>Len</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Save</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>As</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Render</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditLogLine</name>

View File

@ -234,7 +234,7 @@ einfügen</translation>
<message>
<source>Save
&amp;As</source>
<translation>Speichern
<translation type="obsolete">Speichern
&amp;Als</translation>
</message>
<message>
@ -409,6 +409,18 @@ die für den gewählten Service ungültig sind!</translation>
<source>Len</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Save</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>As</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Render</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditLogLine</name>

View File

@ -214,7 +214,7 @@ Meta</translation>
<message>
<source>Save
&amp;As</source>
<translation>Guardar
<translation type="obsolete">Guardar
&amp;como</translation>
</message>
<message>
@ -409,6 +409,18 @@ desactivados para el servicio actual!
<source>Len</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Save</source>
<translation type="unfinished">Guardar</translation>
</message>
<message>
<source>As</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Render</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditLogLine</name>

View File

@ -229,11 +229,6 @@ Meta</source>
<source>&amp;Save</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Save
&amp;As</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&amp;Reports</source>
<translation type="unfinished"></translation>
@ -400,6 +395,18 @@ for the selected service!</source>
<source>Len</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Save</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>As</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Render</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditLogLine</name>

View File

@ -238,7 +238,7 @@ meta</translation>
<message>
<source>Save
&amp;As</source>
<translation>Lagra &amp;som</translation>
<translation type="obsolete">Lagra &amp;som</translation>
</message>
<message>
<source>&amp;Reports</source>
@ -416,6 +416,18 @@ skrudd av for denne tenesta!</translation>
<source>Len</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Save</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>As</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Render</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditLogLine</name>

View File

@ -238,7 +238,7 @@ meta</translation>
<message>
<source>Save
&amp;As</source>
<translation>Lagra &amp;som</translation>
<translation type="obsolete">Lagra &amp;som</translation>
</message>
<message>
<source>&amp;Reports</source>
@ -416,6 +416,18 @@ skrudd av for denne tenesta!</translation>
<source>Len</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Save</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>As</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Render</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditLogLine</name>

View File

@ -256,7 +256,7 @@ Meta
<message>
<source>Save
&amp;As</source>
<translation>&amp;Salvar
<translation type="obsolete">&amp;Salvar
Como</translation>
</message>
<message>
@ -411,6 +411,18 @@ para o serviço selecionado!</translation>
<source>Len</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Save</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>As</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Render</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditLogLine</name>

351
rdlogedit/render_dialog.cpp Normal file
View File

@ -0,0 +1,351 @@
// render_dialog.cpp
//
// Render Log Dialog for Rivendell.
//
// (C) Copyright 2017 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 <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <qfiledialog.h>
#include <qlineedit.h>
#include <qmessagebox.h>
#include <qpushbutton.h>
#include <rd.h>
#include <rdconf.h>
#include <rdexport_settings_dialog.h>
#include <rdrenderer.h>
#include "render_dialog.h"
RenderDialog::RenderDialog(RDStation *station,RDSystem *system,RDConfig *config,
QWidget *parent)
: QDialog(parent)
{
render_station=station;
render_system=system;
render_config=config;
render_save_path=RDHomeDir();
render_first_line=0;
render_last_line=0;
setCaption("RDLogEdit - "+tr("Render Log"));
QFont button_font("helvetica",12,QFont::Bold);
button_font.setPixelSize(12);
//
// Fix the Window Size
//
setMinimumWidth(sizeHint().width());
setMaximumWidth(sizeHint().width());
setMinimumHeight(sizeHint().height());
setMaximumHeight(sizeHint().height());
//
// Dialogs
//
render_progress_dialog=
new QProgressDialog(tr("Rendering Log..."),tr("Cancel"),0,this,"",true);
render_progress_dialog->setCaption("RDLogEdit - "+tr("Render Progress"));
//
// Settings
//
render_settings=new RDSettings();
render_settings->setChannels(2);
render_settings->setSampleRate(render_system->sampleRate());
render_settings->setFormat(RDSettings::Pcm16);
render_settings->setLayer(2);
render_settings->setBitRate(256000);
render_settings->setQuality(3);
render_settings->setNormalizationLevel(0);
//
// Render To Type
//
render_to_box=new QComboBox(this);
render_to_box->insertItem(tr("Cart/Cut"));
render_to_box->insertItem(tr("File"));
connect(render_to_box,SIGNAL(activated(int)),this,SLOT(toChangedData(int)));
render_to_label=new QLabel(tr("Render To")+":",this);
render_to_label->setFont(button_font);
render_to_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
//
// Filename
//
render_filename_edit=new QLineEdit(this);
render_filename_edit->setReadOnly(true);
connect(render_filename_edit,SIGNAL(textChanged(const QString &)),
this,SLOT(filenameChangedData(const QString &)));
render_filename_label=new QLabel(tr("Cart/Cut")+":",this);
render_filename_label->setFont(button_font);
render_filename_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
render_filename_button=new QPushButton(tr("Select"),this);
connect(render_filename_button,SIGNAL(clicked()),this,SLOT(selectData()));
//
// Audio Settings
//
render_audiosettings_edit=new QLineEdit(this);
render_audiosettings_edit->setReadOnly(true);
render_audiosettings_edit->setText(render_settings->description());
render_audiosettings_label=new QLabel(tr("Audio Parameters")+":",this);
render_audiosettings_label->setFont(button_font);
render_audiosettings_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
render_audiosettings_button=new QPushButton(tr("Set"),this);
connect(render_audiosettings_button,SIGNAL(clicked()),
this,SLOT(audiosettingsData()));
//
// Start Time
//
render_starttime_box=new QComboBox(this);
render_starttime_box->insertItem(tr("[now]"));
render_starttime_box->insertItem(tr("As Specified"));
connect(render_starttime_box,SIGNAL(activated(int)),
this,SLOT(starttimeSourceData(int)));
render_starttime_label=new QLabel(tr("Virtual Start Time")+":",this);
render_starttime_label->setFont(button_font);
render_starttime_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
render_starttime_edit=new QTimeEdit(this);
render_starttime_edit->setDisabled(true);
//
// Include Events
//
render_events_box=new QComboBox(this);
render_events_box->insertItem(tr("All Events"));
render_events_box->insertItem(tr("Only Selected Events"));
render_events_label=new QLabel(tr("Include")+":",this);
render_events_label->setFont(button_font);
render_events_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
//
// Ignore STOP
//
render_ignorestop_box=new QComboBox(this);
render_ignorestop_box->insertItem(tr("Stop Rendering"));
render_ignorestop_box->insertItem(tr("Treat as PLAY"));
render_ignorestop_label=new QLabel(tr("At STOP transition")+":",this);
render_ignorestop_label->setFont(button_font);
render_ignorestop_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
//
// Render Button
//
render_render_button=new QPushButton(tr("&Render"),this);
render_render_button->
setGeometry(sizeHint().width()-90,sizeHint().height()-60,80,50);
render_render_button->setFont(button_font);
render_render_button->setDefault(true);
connect(render_render_button,SIGNAL(clicked()),this,SLOT(renderData()));
//
// Cancel Button
//
render_cancel_button=new QPushButton(tr("&Cancel"),this);
render_cancel_button->
setGeometry(sizeHint().width()-90,sizeHint().height()-60,80,50);
render_cancel_button->setFont(button_font);
render_cancel_button->setDefault(true);
connect(render_cancel_button,SIGNAL(clicked()),this,SLOT(cancelData()));
}
RenderDialog::~RenderDialog()
{
}
QSize RenderDialog::sizeHint() const
{
return QSize(500,230);
}
int RenderDialog::exec(RDUser *user,RDLogEvent *log,
int first_line,int last_line)
{
render_user=user;
render_log=log;
render_first_line=first_line;
render_last_line=last_line;
render_filename_edit->clear();
render_render_button->setDisabled(true);
return QDialog::exec();
}
void RenderDialog::toChangedData(int item)
{
if(item) {
render_filename_label->setText(tr("Filename")+":");
render_filename_edit->setReadOnly(false);
}
else {
render_filename_label->setText(tr("Cart/Cut")+":");
render_filename_edit->setReadOnly(true);
}
render_filename_edit->clear();
render_to_cartnum=0;
render_to_cutnum=-1;
render_render_button->setDisabled(true);
}
void RenderDialog::filenameChangedData(const QString &str)
{
render_render_button->setDisabled(str.isEmpty());
}
void RenderDialog::selectData()
{
if(render_to_box->currentItem()) {
QString filename=
QFileDialog::getSaveFileName(render_save_path,RD_AUDIO_FILE_FILTER,
this,"","RDLogEdit - "+tr("Render Log"));
if(!filename.isEmpty()) {
render_filename_edit->setText(filename);
filenameChangedData(filename);
render_save_path=RDGetPathPart(filename);
}
}
else {
QString cutname;
RDCutDialog *d=new RDCutDialog(&cutname,render_station,render_system,
NULL,NULL,NULL,"",false,true,true,this);
if(d->exec()==0) {
render_to_cartnum=RDCut::cartNumber(cutname);
render_to_cutnum=RDCut::cutNumber(cutname);
render_filename_edit->setText(QString().sprintf("%06u:%03d",
render_to_cartnum,render_to_cutnum));
}
delete d;
}
}
void RenderDialog::starttimeSourceData(int item)
{
render_starttime_edit->setEnabled(item);
}
void RenderDialog::audiosettingsData()
{
RDExportSettingsDialog *d=
new RDExportSettingsDialog(render_settings,render_station);
if(d->exec()==0) {
render_audiosettings_edit->setText(render_settings->description());
}
delete d;
}
void RenderDialog::renderData()
{
QString err_msg;
bool result;
int first_line=0;
int last_line=render_log->size();
if(render_events_box->currentItem()) {
first_line=render_first_line;
last_line=render_last_line;
}
QTime start_time=QTime::currentTime();
if(render_starttime_box->currentItem()) {
start_time=render_starttime_edit->time();
}
RDRenderer *r=
new RDRenderer(render_user,render_station,render_system,render_config,this);
connect(r,SIGNAL(lineStarted(int,int)),
render_progress_dialog,SLOT(setProgress(int,int)));
connect(render_progress_dialog,SIGNAL(cancelled()),r,SLOT(abort()));
if(render_to_box->currentItem()) {
result=
r->renderToFile(render_filename_edit->text(),render_log,render_settings,
start_time,render_ignorestop_box->currentItem(),
&err_msg,first_line,last_line);
}
else {
result=
r->renderToCart(render_to_cartnum,render_to_cutnum,render_log,
render_settings,start_time,
render_ignorestop_box->currentItem(),
&err_msg,first_line,last_line);
}
if(!result) {
QMessageBox::warning(this,"RDLogEdit - "+tr("Rendering Error"),
err_msg);
delete r;
return;
}
delete r;
done(true);
}
void RenderDialog::cancelData()
{
done(false);
}
void RenderDialog::closeEvent(QCloseEvent *e)
{
cancelData();
}
void RenderDialog::resizeEvent(QResizeEvent *e)
{
render_to_label->setGeometry(10,10,65,20);
render_to_box->setGeometry(80,10,100,20);
render_filename_label->setGeometry(10,40,95,20);
render_filename_edit->setGeometry(110,40,size().width()-190,20);
render_filename_button->setGeometry(size().width()-70,38,60,25);
render_audiosettings_label->setGeometry(10,70,135,20);
render_audiosettings_edit->setGeometry(150,70,size().width()-230,20);
render_audiosettings_button->setGeometry(size().width()-70,68,60,25);
render_starttime_label->setGeometry(10,95,135,20);
render_starttime_box->setGeometry(150,95,160,20);
render_starttime_edit->setGeometry(315,95,80,20);
render_events_label->setGeometry(10,117,135,20);
render_events_box->setGeometry(150,117,160,20);
render_ignorestop_label->setGeometry(10,139,135,20);
render_ignorestop_box->setGeometry(150,139,160,20);
render_render_button->
setGeometry(size().width()-180,size().height()-60,80,50);
render_cancel_button->setGeometry(size().width()-90,size().height()-60,80,50);
}

105
rdlogedit/render_dialog.h Normal file
View File

@ -0,0 +1,105 @@
// render_dialog.h
//
// Log Rendering Dialog for Rivendell.
//
// (C) Copyright 2017 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 RENDER_DIALOG_H
#define RENDER_DIALOG_H
#include <qcheckbox.h>
#include <qcombobox.h>
#include <qdatetimeedit.h>
#include <qdialog.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qprogressdialog.h>
#include <rdbusybar.h>
#include <rdconfig.h>
#include <rdcut_dialog.h>
#include <rdsettings.h>
#include <rdlog_event.h>
#include <rdsystem.h>
#include <rduser.h>
//
// Widget Settings
//
#define IMPORT_BAR_INTERVAL 500
#define IMPORT_TEMP_BASENAME "rdlib"
class RenderDialog : public QDialog
{
Q_OBJECT
public:
RenderDialog(RDStation *station,RDSystem *system,RDConfig *config,
QWidget *parent=0);
~RenderDialog();
QSize sizeHint() const;
public slots:
int exec(RDUser *user,RDLogEvent *log,int first_line,int last_line);
private slots:
void toChangedData(int item);
void filenameChangedData(const QString &str);
void selectData();
void starttimeSourceData(int item);
void audiosettingsData();
void renderData();
void cancelData();
protected:
void closeEvent(QCloseEvent *e);
void resizeEvent(QResizeEvent *e);
private:
RDStation *render_station;
RDSystem *render_system;
RDConfig *render_config;
RDUser *render_user;
RDLogEvent *render_log;
int render_first_line;
int render_last_line;
RDSettings *render_settings;
QProgressDialog *render_progress_dialog;
QLabel *render_to_label;
QComboBox *render_to_box;
QLabel *render_filename_label;
QLineEdit *render_filename_edit;
QLabel *render_starttime_label;
QComboBox *render_starttime_box;
QTimeEdit *render_starttime_edit;
QLabel *render_audiosettings_label;
QLineEdit *render_audiosettings_edit;
QPushButton *render_audiosettings_button;
QLabel *render_events_label;
QComboBox *render_events_box;
QLabel *render_ignorestop_label;
QComboBox *render_ignorestop_box;
QPushButton *render_filename_button;
QPushButton *render_render_button;
QPushButton *render_cancel_button;
QString render_save_path;
unsigned render_to_cartnum;
int render_to_cutnum;
};
#endif // RDRENDER_DIALOG_H

View File

@ -46,7 +46,6 @@ MainObject::MainObject(QObject *parent)
:QObject(parent)
{
render_verbose=false;
render_channels=RDRENDER_DEFAULT_CHANNELS;
render_first_line=-1;
render_last_line=-1;
render_ignore_stops=false;
@ -89,8 +88,9 @@ MainObject::MainObject(QObject *parent)
cmd->setProcessed(i,true);
}
if(cmd->key(i)=="--channels") {
render_channels=cmd->value(i).toUInt(&ok);
if((!ok)||(render_channels>2)) {
render_settings.setChannels(cmd->value(i).toUInt(&ok));
if((!ok)||
(render_settings.channels()>2)||(render_settings.channels()==0)) {
fprintf(stderr,"rdrender: invalid --channels argument\n");
exit(1);
}
@ -330,7 +330,7 @@ void MainObject::userData()
this,SLOT(printProgressMessage(const QString &)));
if(render_to_file.isEmpty()) {
if(!r->renderToCart(render_cart_number,render_cut_number,log_event,
render_channels,&render_settings,render_start_time,
&render_settings,render_start_time,
render_ignore_stops,&err_msg,render_first_line,
render_last_line,render_first_time,render_last_time)) {
fprintf(stderr,"rdrender: %s\n",(const char *)err_msg);
@ -338,8 +338,8 @@ void MainObject::userData()
}
}
else {
if(!r->renderToFile(render_to_file,log_event,render_channels,
&render_settings,render_start_time,render_ignore_stops,
if(!r->renderToFile(render_to_file,log_event,&render_settings,
render_start_time,render_ignore_stops,
&err_msg,render_first_line,render_last_line,
render_first_time,render_last_time)) {
fprintf(stderr,"rdrender: %s\n",(const char *)err_msg);

View File

@ -60,7 +60,6 @@ class MainObject : public QObject
unsigned render_cart_number;
int render_cut_number;
QString render_temp_output_filename;
unsigned render_channels;
QTime render_start_time;
int render_first_line;
int render_last_line;