[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Traverso-commit] traverso/src commands/AudioClipExternalProcessi...
From: |
Remon Sijrier |
Subject: |
[Traverso-commit] traverso/src commands/AudioClipExternalProcessi... |
Date: |
Wed, 20 Jun 2007 15:27:16 +0000 |
CVSROOT: /sources/traverso
Module name: traverso
Changes by: Remon Sijrier <r_sijrier> 07/06/20 15:27:16
Modified files:
src/commands : AudioClipExternalProcessing.cpp
AudioClipExternalProcessing.h
src/core : AudioSource.h
Added files:
src/commands/ui: ExternalProcessing.ui
Log message:
improved external clip processing dialog
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/traverso/src/commands/AudioClipExternalProcessing.cpp?cvsroot=traverso&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/traverso/src/commands/AudioClipExternalProcessing.h?cvsroot=traverso&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/traverso/src/commands/ui/ExternalProcessing.ui?cvsroot=traverso&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/AudioSource.h?cvsroot=traverso&r1=1.19&r2=1.20
Patches:
Index: commands/AudioClipExternalProcessing.cpp
===================================================================
RCS file:
/sources/traverso/traverso/src/commands/AudioClipExternalProcessing.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- commands/AudioClipExternalProcessing.cpp 30 May 2007 13:14:45 -0000
1.6
+++ commands/AudioClipExternalProcessing.cpp 20 Jun 2007 15:27:15 -0000
1.7
@@ -30,18 +30,89 @@
#include <Project.h>
#include <ResourcesManager.h>
#include <Utils.h>
+#include "Interface.h"
+#include "Export.h"
+#include "WriteSource.h"
-#include <QInputDialog>
+#include <QThread>
+#include <QFile>
// Always put me below _all_ includes, this is needed
// in case we run with memory leak detection enabled!
#include "Debugger.h"
+class MergeThread : public QThread
+{
+public:
+ MergeThread(ReadSource* source, QString outFileName) {
+ m_outFileName = outFileName;
+ m_readsource = source;
+ }
+
+ void run() {
+ uint buffersize = 4096;
+ audio_sample_t readbuffer[buffersize];
+ audio_sample_t mixdown[2 * buffersize];
+
+ ExportSpecification* spec = new ExportSpecification();
+ spec->start_frame = 0;
+ spec->end_frame = m_readsource->get_nframes();
+ spec->total_frames = spec->end_frame;
+ spec->pos = 0;
+ spec->isRecording = false;
+ spec->extension = "wav";
+
+ spec->exportdir = pm().get_project()->get_root_dir() +
"/audiosources/";
+ spec->format = SF_FORMAT_WAV;
+ spec->data_width = 16;
+ spec->format |= SF_FORMAT_PCM_16;
+ spec->channels = 2;
+ spec->sample_rate = m_readsource->get_rate();
+ spec->blocksize = buffersize;
+ spec->name = m_outFileName;
+ spec->dataF = new audio_sample_t[buffersize * 2];
+
+ WriteSource* writesource = new WriteSource(spec);
+
+ do {
+ nframes_t this_nframes =
std::min((nframes_t)(spec->end_frame - spec->pos), buffersize);
+ nframes_t nframes = this_nframes;
+
+ memset (spec->dataF, 0, sizeof (spec->dataF[0]) *
nframes * spec->channels);
+
+ for (int chan=0; chan < 2; ++chan) {
+
+ m_readsource->file_read(chan, mixdown,
spec->pos, nframes, readbuffer);
+
+ for (uint x = 0; x < nframes; ++x) {
+ spec->dataF[chan+(x*spec->channels)] =
mixdown[x];
+ }
+ }
+
+ writesource->process(buffersize);
+
+ spec->pos += nframes;
+
+ } while (spec->pos != spec->total_frames);
+
+ writesource->finish_export();
+ delete writesource;
+ delete [] spec->dataF;
+ delete spec;
+ }
+
+private:
+ QString m_outFileName;
+ ReadSource* m_readsource;
+};
+
+
AudioClipExternalProcessing::AudioClipExternalProcessing(AudioClip* clip)
: Command(clip, tr("Clip: External Processing"))
{
m_clip = clip;
+ m_resultingclip = 0;
m_track = m_clip->get_track();
}
@@ -52,106 +123,237 @@
int AudioClipExternalProcessing::prepare_actions()
{
- bool ok;
+ ExternalProcessingDialog epdialog(Interface::instance(), this);
+
+ epdialog.exec();
- QString command = QInputDialog::getText(
- 0,
- tr("Clip Processing"),
- tr("Enter sox command"),
- QLineEdit::Normal,
- "",
- &ok );
-
- if (! ok || command.isEmpty()) {
- // Nothing typed in, or used hit cancel
- printf("No input command, or cancel button clicked\n");
+ if (! m_resultingclip) {
return -1;
}
- printf("returned command: %s\n", QS_C(command));
+ return 1;
+}
+
+
+int AudioClipExternalProcessing::do_action()
+{
+ PENTER;
+ Command::process_command(m_track->remove_clip(m_clip, false));
+ Command::process_command(m_track->add_clip(m_resultingclip, false));
+
+ return 1;
+}
+
+int AudioClipExternalProcessing::undo_action()
+{
+ PENTER;
+ Command::process_command(m_track->remove_clip(m_resultingclip, false));
+ Command::process_command(m_track->add_clip(m_clip, false));
+ return 1;
+}
+
+
+
+/************************************************************************/
+/* DIALOG */
+/************************************************************************/
+ExternalProcessingDialog::ExternalProcessingDialog(QWidget * parent,
AudioClipExternalProcessing* acep)
+ : QDialog(parent)
+{
+ setupUi(this);
+ m_acep = acep;
+ m_queryOptions = false;
+ m_merger = 0;
+
m_processor = new QProcess(this);
m_processor->setProcessChannelMode(QProcess::MergedChannels);
- ReadSource* rs =
resources_manager()->get_readsource(m_clip->get_readsource_id());
-/* if (! rs) {
- // This should NOT be possible, but just in case....
- printf("resources manager didn't return a resource for the to
be processed audioclip (%lld) !!!!\n",
- m_clip->get_id());
- return -1;
- }*/
+ command_lineedit_text_changed("sox");
- QString name = rs->get_name();
+ connect(m_processor, SIGNAL(readyReadStandardOutput()), this,
SLOT(read_standard_output()));
+ connect(m_processor, SIGNAL(started()), this, SLOT(process_started()));
+ connect(m_processor, SIGNAL(finished(int, QProcess::ExitStatus)), this,
SLOT(process_finished(int, QProcess::ExitStatus)));
+ connect(m_processor, SIGNAL(error( QProcess::ProcessError)), this,
SLOT(process_error(QProcess::ProcessError)));
+ connect(argsComboBox, SIGNAL(activated(const QString&)), this,
SLOT(arg_combo_index_changed(const QString&)));
+ connect(programLineEdit, SIGNAL(textChanged(const QString&)), this,
SLOT(command_lineedit_text_changed(const QString&)));
+ connect(startButton, SIGNAL(clicked()), this,
SLOT(prepare_for_external_processing()));
+ connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
+}
- QString infilename = rs->get_filename();
- QString outfilename = pm().get_project()->get_audiosources_dir() +
name.remove(".wav").remove(".")
-
.append("-").append(command.simplified()).append(".wav");
+ExternalProcessingDialog::~ ExternalProcessingDialog()
+{
+ delete m_processor;
+}
- printf("infilename is %s\n", QS_C(infilename));
- printf("outfilename is %s\n", QS_C(outfilename));
- QStringList arguments;
- arguments.append(infilename);
- arguments.append(outfilename);
- arguments += command.split(QRegExp("\\s+"));
+void ExternalProcessingDialog::prepare_for_external_processing()
+{
+ m_commandargs = argumentsLineEdit->text();
- printf("Complete command is %s\n", QS_C( arguments.join(" ")));
+ ReadSource* rs =
resources_manager()->get_readsource(m_acep->m_clip->get_readsource_id());
- m_processor->start("sox", arguments);
+ //This should NOT be possible, but just in case....
+ if (! rs) {
+ printf("ExternalProcessing:: resources manager did NOT return a
resource for the to be processed audioclip (%lld) !!!!\n",
m_acep->m_clip->get_id());
+ return;
+ }
- QString result;
+ m_filename = rs->get_name();
- if (! m_processor->waitForFinished() ) {
- if (!result.isEmpty())
- result = m_processor->errorString();
- if (!result.isEmpty())
- printf("output: \n %s", QS_C(result));
- return -1;
+ m_infilename = rs->get_filename();
+ // remove the extension and any dots that might confuse the external
program, append the
+ // new name and again the extension.
+ m_outfilename = pm().get_project()->get_audiosources_dir() +
+
m_filename.remove(".wav").remove(".").append("-").append(m_commandargs.simplified()).append(".wav");
+
+ printf("infilename is %s\n", QS_C(m_infilename));
+ printf("outfilename is %s\n", QS_C(m_outfilename));
+ printf("Complete command is %s\n", QS_C(m_arguments.join(" ")));
+
+
+ if (rs->get_channel_count() == 2 && rs->get_file_count() == 2) {
+ m_merger = new MergeThread(rs, "merged.wav");
+ connect(m_merger, SIGNAL(finished()), this,
SLOT(start_external_processing()));
+ m_merger->start();
+ statusText->setHtml(tr("Preparing audio data to a format that
can be used by <b>%1</b>, this can take a while for large
files!").arg(m_program));
+ progressBar->setMaximum(0);
} else {
- result = m_processor->readAllStandardOutput();
- if (!result.isEmpty())
- printf("output: \n %s", QS_C(result));
+ start_external_processing();
+ }
+}
+
+void ExternalProcessingDialog::start_external_processing()
+{
+ m_arguments.append("-S");
+ if (m_merger) {
+ progressBar->setMaximum(100);
+ m_arguments.append(pm().get_project()->get_audiosources_dir() +
"merged.wav");
+ delete m_merger;
+ } else {
+ m_arguments.append(m_infilename);
+ }
+ m_arguments.append(m_outfilename);
+ m_arguments += m_commandargs.split(QRegExp("\\s+"));
+
+ m_processor->start(m_program, m_arguments);
+}
+
+void ExternalProcessingDialog::read_standard_output()
+{
+ if (m_queryOptions) {
+ QString result = m_processor->readAllStandardOutput();
+ if (m_program == "sox") {
+ QStringList list = result.split("\n");
+ foreach(QString string, list) {
+ if (string.contains("Supported effects:")) {
+ result = string.remove("Supported
effects:");
+ QStringList options =
string.split(QRegExp("\\s+"));
+ foreach(QString string, options) {
+ if (!string.isEmpty())
+
argsComboBox->addItem(string);
+ }
+ }
+ }
+ }
+ return;
+ }
+
+ QString result = m_processor->readAllStandardOutput();
+
+ if (result.contains("%")) {
+ QStringList tokens = result.split(QRegExp("\\s+"));
+ foreach(QString token, tokens) {
+ if (token.contains("%")) {
+ token = token.remove("%)");
+ int number = (int)token.toDouble();
+ progressBar->setValue(number);
+ return;
+ }
+ }
+ }
+
+ statusText->append(result);
+}
+
+void ExternalProcessingDialog::process_started()
+{
+ statusText->clear();
+}
+
+void ExternalProcessingDialog::process_finished(int exitcode,
QProcess::ExitStatus exitstatus)
+{
+ Q_UNUSED(exitcode);
+ Q_UNUSED(exitstatus);
+
+ if (m_queryOptions) {
+ m_queryOptions = false;
+ return;
+ }
QString dir = pm().get_project()->get_audiosources_dir();
- ReadSource* source = resources_manager()->import_source(dir,
name);
+ // In case we used the merger, remove the file...
+ QFile::remove(dir + "/merged.wav");
+
+ if (progressBar->value() != 100) {
+ // not sure if this is always valid, but it at least should be
100 all
+ // the time, that is, after succesfull operation....
+ // so if not 100 -> unsucesfull, and we bail out
+ return;
+ }
+
+ QString result = m_processor->readAllStandardOutput();
+ // print anything on command line we didn't catch
+ printf("output: \n %s", QS_C(result));
+
+ ReadSource* source = resources_manager()->import_source(dir,
m_filename);
if (!source) {
printf("ResourcesManager didn't return a ReadSource,
most likely sox didn't understand your command\n");
- return -1;
+ return rejected();
}
- m_resultingclip =
resources_manager()->new_audio_clip(name.remove(".wav"));
+ m_acep->m_resultingclip =
resources_manager()->new_audio_clip(m_filename.remove(".wav"));
+ resources_manager()->set_source_for_clip(m_acep->m_resultingclip,
source);
// Clips live at project level, we have to set its Song, Track
and ReadSource explicitely!!
- m_resultingclip->set_song(m_clip->get_song());
- m_resultingclip->set_track(m_clip->get_track());
- resources_manager()->set_source_for_clip(m_resultingclip,
source);
-
m_resultingclip->set_track_start_frame(m_clip->get_track_start_frame());
- }
+ m_acep->m_resultingclip->set_song(m_acep->m_clip->get_song());
+ m_acep->m_resultingclip->set_track(m_acep->m_clip->get_track());
+
m_acep->m_resultingclip->set_track_start_frame(m_acep->m_clip->get_track_start_frame());
+ close();
+}
- return 1;
+void ExternalProcessingDialog::query_options()
+{
+ m_queryOptions = true;
+ argsComboBox->clear();
+ m_processor->start(m_program, QStringList());
}
+void ExternalProcessingDialog::arg_combo_index_changed(const QString & text)
+{
+ argumentsLineEdit->setText(text);
+}
-int AudioClipExternalProcessing::do_action()
+void ExternalProcessingDialog::command_lineedit_text_changed(const QString &
text)
{
- PENTER;
- Command::process_command(m_track->remove_clip(m_clip, false));
- Command::process_command(m_track->add_clip(m_resultingclip, false));
+ m_program = text;
+ if (m_program == "sox") {
+ query_options();
+ argsComboBox->show();
+ argsComboBox->setToolTip(tr("Available arguments for the sox
program"));
+ return;
+ }
- return 1;
+ argsComboBox->hide();
}
-int AudioClipExternalProcessing::undo_action()
+void ExternalProcessingDialog::process_error(QProcess::ProcessError error)
{
- PENTER;
- Command::process_command(m_track->remove_clip(m_resultingclip, false));
- Command::process_command(m_track->add_clip(m_clip, false));
- return 1;
+ if (error == QProcess::FailedToStart) {
+ statusText->setHtml(tr("Program <b>%1</b> not installed, or
insufficient permissions to run!").arg(m_program));
+ }
}
-
-// eof
-
Index: commands/AudioClipExternalProcessing.h
===================================================================
RCS file:
/sources/traverso/traverso/src/commands/AudioClipExternalProcessing.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- commands/AudioClipExternalProcessing.h 16 Mar 2007 00:10:54 -0000
1.1
+++ commands/AudioClipExternalProcessing.h 20 Jun 2007 15:27:15 -0000
1.2
@@ -19,11 +19,54 @@
*/
+#ifndef AUDIOCLIP_EXTERNAL_PROCESSING_H
+#define AUDIOCLIP_EXTERNAL_PROCESSING_H
+
+#include <QDialog>
#include <QProcess>
#include <Command.h>
+#include "build/ui_ExternalProcessing.h"
+
class AudioClip;
class Track;
+class AudioClipExternalProcessing;
+class MergeThread;
+
+class ExternalProcessingDialog : public QDialog, protected
Ui::ExternalProcessing
+{
+ Q_OBJECT
+
+public:
+ ExternalProcessingDialog(QWidget* parent, AudioClipExternalProcessing*
acep);
+ ~ExternalProcessingDialog();
+
+
+private:
+ AudioClipExternalProcessing* m_acep;
+ QProcess* m_processor;
+ MergeThread* m_merger;
+ QString m_filename;
+ QString m_program;
+ bool m_queryOptions;
+ QStringList m_arguments;
+ QString m_commandargs;
+ QString m_infilename;
+ QString m_outfilename;
+
+ void query_options();
+
+private slots:
+ void read_standard_output();
+ void prepare_for_external_processing();
+ void process_started();
+ void process_finished(int exitcode, QProcess::ExitStatus exitstatus);
+ void arg_combo_index_changed ( const QString & text );
+ void start_external_processing();
+ void command_lineedit_text_changed(const QString & text);
+ void process_error(QProcess::ProcessError error);
+};
+
class AudioClipExternalProcessing : public Command
{
@@ -40,6 +83,11 @@
AudioClip* m_clip;
AudioClip* m_resultingclip;
QProcess* m_processor;
+
+ friend class ExternalProcessingDialog;
+
};
+#endif
+
//eof
Index: core/AudioSource.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/AudioSource.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- core/AudioSource.h 5 Jun 2007 12:47:09 -0000 1.19
+++ core/AudioSource.h 20 Jun 2007 15:27:16 -0000 1.20
@@ -56,6 +56,7 @@
qint64 get_orig_song_id() const {return m_origSongId;}
int get_rate() const;
uint get_channel_count() const;
+ uint get_file_count() const {return m_fileCount;}
int get_bit_depth() const;
protected:
Index: commands/ui/ExternalProcessing.ui
===================================================================
RCS file: commands/ui/ExternalProcessing.ui
diff -N commands/ui/ExternalProcessing.ui
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ commands/ui/ExternalProcessing.ui 20 Jun 2007 15:27:15 -0000 1.1
@@ -0,0 +1,186 @@
+<ui version="4.0" >
+ <class>ExternalProcessing</class>
+ <widget class="QDialog" name="ExternalProcessing" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>430</width>
+ <height>269</height>
+ </rect>
+ </property>
+ <property name="minimumSize" >
+ <size>
+ <width>380</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>460</width>
+ <height>400</height>
+ </size>
+ </property>
+ <property name="windowTitle" >
+ <string>External Processing</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Program</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Arguments</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>Progress</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="programLineEdit" >
+ <property name="text" >
+ <string>sox</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="argumentsLineEdit" />
+ </item>
+ <item>
+ <widget class="QComboBox" name="argsComboBox" >
+ <property name="minimumSize" >
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="progressBar" >
+ <property name="value" >
+ <number>0</number>
+ </property>
+ <property name="textVisible" >
+ <bool>true</bool>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="startButton" >
+ <property name="text" >
+ <string>Start</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>Program output</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTextEdit" name="statusText" >
+ <property name="acceptDrops" >
+ <bool>false</bool>
+ </property>
+ <property name="textInteractionFlags" >
+ <enum>Qt::TextSelectableByMouse</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Traverso-commit] traverso/src commands/AudioClipExternalProcessi...,
Remon Sijrier <=