root/trunk/src/gui/src/ExportSongDialog.cpp @ 2450

Revision 2450, 22.5 KB (checked in by wolke, 17 months ago)

remove unused bool

Line 
1/*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 *
5 * http://www.hydrogen-music.org
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY, without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 *
21 */
22
23#include <QFileDialog>
24#include <QProgressBar>
25#include <QLabel>
26#include <QPixmap>
27
28#include "ExportSongDialog.h"
29#include "Skin.h"
30#include "HydrogenApp.h"
31#include "Mixer/Mixer.h"
32
33#include <hydrogen/basics/note.h>
34#include <hydrogen/basics/pattern.h>
35#include <hydrogen/basics/pattern_list.h>
36#include <hydrogen/basics/instrument.h>
37#include <hydrogen/basics/instrument_list.h>
38#include <hydrogen/basics/instrument_layer.h>
39#include <hydrogen/basics/song.h>
40#include <hydrogen/hydrogen.h>
41#include <hydrogen/Preferences.h>
42#include <hydrogen/IO/AudioOutput.h>
43#include <hydrogen/audio_engine.h>
44#include <hydrogen/sampler/Sampler.h>
45#include <hydrogen/event_queue.h>
46
47#include <memory>
48
49using namespace H2Core;
50
51const char* ExportSongDialog::__class_name = "ExportSongDialog";
52
53ExportSongDialog::ExportSongDialog(QWidget* parent)
54 : QDialog(parent)
55 , Object( __class_name )
56 , m_bExporting( false )
57{
58        setupUi( this );
59        setModal( true );
60        setWindowTitle( trUtf8( "Export song" ) );
61
62        exportTypeCombo->addItem(trUtf8("Export to a single track"));
63        exportTypeCombo->addItem(trUtf8("Export to seperate tracks"));
64        exportTypeCombo->addItem(trUtf8("Both"));
65
66        HydrogenApp::get_instance()->addEventListener( this );
67
68        m_pProgressBar->setValue( 0 );
69        sampleRateCombo->setCurrentIndex(1);
70        sampleDepthCombo->setCurrentIndex(1);
71
72        QString defaultFilename( Hydrogen::get_instance()->getSong()->get_filename() );
73        if( Hydrogen::get_instance()->getSong()->get_filename().isEmpty() )
74                defaultFilename = Hydrogen::get_instance()->getSong()->__name;
75        defaultFilename.replace( '*', "_" );
76        defaultFilename.replace( ".h2song", "" );       
77        defaultFilename += ".wav";
78        exportNameTxt->setText(defaultFilename);
79        b_QfileDialog = false;
80        m_bExportTrackouts = false;
81        m_nInstrument = 0;
82        m_sExtension = ".wav";
83        m_bOverwriteFiles = false;
84
85        // use of rubberband batch
86        if(checkUseOfRubberband()){
87                b_oldRubberbandBatchMode = Preferences::get_instance()->getRubberBandBatchMode();
88                toggleRubberbandCheckBox->setChecked(Preferences::get_instance()->getRubberBandBatchMode());
89                connect(toggleRubberbandCheckBox, SIGNAL(toggled(bool)), this, SLOT(toggleRubberbandBatchMode( bool )));
90        }else
91        {
92                b_oldRubberbandBatchMode = Preferences::get_instance()->getRubberBandBatchMode();
93                toggleRubberbandCheckBox->setEnabled( false );
94        }
95
96
97        // use of timeline
98        if( Hydrogen::get_instance()->m_timelinevector.size() > 0 ){
99                toggleTimeLineBPMCheckBox->setChecked(Preferences::get_instance()->getUseTimelineBpm());
100                b_oldTimeLineBPMMode = Preferences::get_instance()->getUseTimelineBpm();
101                connect(toggleTimeLineBPMCheckBox, SIGNAL(toggled(bool)), this, SLOT(togglTimeLineBPMMode( bool )));
102        }else
103        {
104                b_oldTimeLineBPMMode = Preferences::get_instance()->getUseTimelineBpm();
105                toggleTimeLineBPMCheckBox->setEnabled( false );
106        }
107
108
109        // use of interpolation mode
110        m_oldInterpolation = AudioEngine::get_instance()->get_sampler()->getInterpolateMode();
111        resampleComboBox->setCurrentIndex( m_oldInterpolation );
112        connect(resampleComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(resampleComboBoIndexChanged(int)));
113
114        // if rubberbandBatch calculate time needed by lib rubberband to resample samples
115        if(b_oldRubberbandBatchMode){
116                calculateRubberbandTime();
117        }
118}
119
120
121
122ExportSongDialog::~ExportSongDialog()
123{
124        HydrogenApp::get_instance()->removeEventListener( this );
125}
126
127
128
129/// \todo: memorizzare l'ultima directory usata
130void ExportSongDialog::on_browseBtn_clicked()
131{
132        static QString lastUsedDir = QDir::homePath();
133
134
135        std::auto_ptr<QFileDialog> fd( new QFileDialog );
136        fd->setFileMode(QFileDialog::AnyFile);
137
138
139        if( templateCombo->currentIndex() <= 4 ) fd->setNameFilter("Microsoft WAV (*.wav *.WAV)");
140        if( templateCombo->currentIndex() > 4 && templateCombo->currentIndex() < 8  ) fd->setNameFilter( "Apple AIFF (*.aiff *.AIFF)");
141        if( templateCombo->currentIndex() == 8) fd->setNameFilter( "Lossless  Flac (*.flac *.FLAC)");
142        if( templateCombo->currentIndex() == 9) fd->setNameFilter( "Compressed Ogg (*.ogg *.OGG)");
143
144        fd->setDirectory( lastUsedDir );
145        fd->setAcceptMode( QFileDialog::AcceptSave );
146        fd->setWindowTitle( trUtf8( "Export song" ) );
147
148
149        QString defaultFilename = exportNameTxt->text();
150
151        fd->selectFile(defaultFilename);
152
153        QString filename = "";
154        if (fd->exec()) {
155                filename = fd->selectedFiles().first();
156                b_QfileDialog = true;
157        }
158
159        if ( ! filename.isEmpty() ) {
160                lastUsedDir = fd->directory().absolutePath();
161                QString sNewFilename = filename;
162
163                //this second extension check is mostly important if you leave a dot
164                //without a regular extionsion in a filename
165                if( !filename.endsWith( m_sExtension ) ){
166                    filename.append(m_sExtension);
167                }
168
169                exportNameTxt->setText(filename);
170        }
171
172        if( filename.endsWith( ".ogg" ) || filename.endsWith( ".OGG" ) ){
173                sampleRateCombo->hide();
174                sampleDepthCombo->hide();
175                label->hide();
176                label_2->hide();
177        }
178               
179}
180
181
182
183void ExportSongDialog::on_okBtn_clicked()
184{
185        if ( m_bExporting ) {
186                return;
187        }
188
189        m_bOverwriteFiles = false;
190
191        /* If the song has a tempo change, notify the user
192         *  that hydrogen is unable export songs with
193         *  tempo changes correctly
194         **/
195        Hydrogen* engine = Hydrogen::get_instance();
196       
197        bool warn =  Preferences::get_instance()->getShowExportWarning();
198       
199        std::vector<Hydrogen::HTimelineVector> timelineVector = engine->m_timelinevector;
200/*      if( timelineVector.size() > 0 ){
201                int res = QMessageBox::information( this, "Hydrogen", tr( "This version of hydrogen is not able to export songs with tempo changes. If you proceed, the song will be exported without tempo changes."), QMessageBox::Yes | QMessageBox::No | QMessageBox::YesToAll);
202                if (res == QMessageBox::No ) return;
203                if (res == QMessageBox::YesToAll ) Preferences::get_instance()->setShowExportWarning(true);
204        }
205*/
206        /* 0: Export to single track
207        *  1: Export to multiple tracks
208        *  2: Export to both
209        */
210
211        if( exportTypeCombo->currentIndex() == 0 || exportTypeCombo->currentIndex() == 2 ){
212                m_bExportTrackouts = false;
213
214                QString filename = exportNameTxt->text();
215                if ( QFile( filename ).exists() == true && b_QfileDialog == false ) {
216
217                    int res;
218                    if( exportTypeCombo->currentIndex() == 0 ){
219                        res = QMessageBox::information( this, "Hydrogen", tr( "The file %1 exists. \nOverwrite the existing file?").arg(filename), QMessageBox::Yes | QMessageBox::No );
220                    } else {
221                        res = QMessageBox::information( this, "Hydrogen", tr( "The file %1 exists. \nOverwrite the existing file?").arg(filename), QMessageBox::Yes | QMessageBox::No | QMessageBox::YesToAll);
222                    }
223
224                    if (res == QMessageBox::YesToAll ) m_bOverwriteFiles = true;
225                    if (res == QMessageBox::No ) return;
226
227                }
228
229                if( exportTypeCombo->currentIndex() == 2 ) m_bExportTrackouts = true;
230                Hydrogen::get_instance()->startExportSong( filename, sampleRateCombo->currentText().toInt(), sampleDepthCombo->currentText().toInt() );
231
232                return;
233        }
234
235        if( exportTypeCombo->currentIndex() == 1 ){
236                m_bExportTrackouts = true;
237                exportTracks();
238                return;
239        }
240
241}
242
243void ExportSongDialog::exportTracks()
244{
245        Song *pSong = Hydrogen::get_instance()->getSong();
246        if( m_nInstrument <= pSong->get_instrument_list()->size() -1 ){
247
248                bool instrumentexists = false;
249                //if a instrument contains no notes we jump to the next instrument
250                unsigned nPatterns = pSong->get_pattern_list()->size();
251                for ( unsigned i = 0; i < nPatterns; i++ ) {
252                        Pattern *pat = pSong->get_pattern_list()->get( i );
253                        const Pattern::notes_t* notes = pat->get_notes();
254                        FOREACH_NOTE_CST_IT_BEGIN_END(notes,it) {
255                                Note *pNote = it->second;
256                                assert( pNote );
257
258                                if( pNote->get_instrument()->get_name() == Hydrogen::get_instance()->getSong()->get_instrument_list()->get(m_nInstrument)->get_name() ){
259                                        instrumentexists = true;
260                                        break;
261                                }
262
263                        }
264                }
265
266                if( !instrumentexists ){
267                        if( m_nInstrument == Hydrogen::get_instance()->getSong()->get_instrument_list()->size() -1 ){
268                                m_bExportTrackouts = false;
269                                HydrogenApp::get_instance()->getMixer()->unmuteAll( true );
270                                m_nInstrument = 0;
271                                return;
272                        }else {
273                                m_nInstrument++;
274                                exportTracks();
275                                return;
276                        }
277                }
278
279                QStringList filenameList =  exportNameTxt->text().split( m_sExtension );
280
281                QString firstItem;
282                if( !filenameList.isEmpty() ){
283                        firstItem = filenameList.first();
284                }
285                QString newItem =  firstItem + "-" + Hydrogen::get_instance()->getSong()->get_instrument_list()->get(m_nInstrument)->get_name();
286
287                QString filename =  newItem.append(m_sExtension);
288
289                if ( QFile( filename ).exists() == true && b_QfileDialog == false && !m_bOverwriteFiles) {
290                        int res = QMessageBox::information( this, "Hydrogen", tr( "The file %1 exists. \nOverwrite the existing file?").arg(filename), QMessageBox::Yes | QMessageBox::No | QMessageBox::YesToAll );
291                        if (res == QMessageBox::No ) return;
292                        if (res == QMessageBox::YesToAll ) m_bOverwriteFiles = true;
293                }
294
295                //Hydrogen::get_instance()->stopExportSong();
296                Hydrogen::get_instance()->stopTempExportSong();
297                m_bExporting = false;
298                HydrogenApp::get_instance()->getMixer()->soloClicked( m_nInstrument );
299
300                Hydrogen::get_instance()->startExportSong( filename, sampleRateCombo->currentText().toInt(), sampleDepthCombo->currentText().toInt() );
301
302                if(! (m_nInstrument == Hydrogen::get_instance()->getSong()->get_instrument_list()->size() -1 )){
303                        m_nInstrument++;
304                }
305        }
306
307}
308
309void ExportSongDialog::on_closeBtn_clicked()
310{
311        Hydrogen::get_instance()->stopExportSong();
312        m_bExporting = false;
313        if(Preferences::get_instance()->getRubberBandBatchMode()){
314                EventQueue::get_instance()->push_event( EVENT_RECALCULATERUBBERBAND, -1);
315        }
316        Preferences::get_instance()->setRubberBandBatchMode( b_oldRubberbandBatchMode );
317        Preferences::get_instance()->setUseTimelineBpm( b_oldTimeLineBPMMode );
318        setResamplerMode(m_oldInterpolation);
319        accept();
320
321}
322
323
324void ExportSongDialog::on_templateCombo_currentIndexChanged(int index )
325{
326        /**index
327         * 0 = wav 44100 | 16
328         * 1 = wav 48000 | 16
329         * 2 = wav 48000 | 24
330         * 3 = wav 22050 | 8
331         * 4 = wav 96000 | 32
332         * 5 = aiff 44100 | 16
333         * 6 = aiff 48000 | 16
334         * 7 = aiff 48000 | 24
335         * 8 = flac 48000
336         * 9 = ogg VBR , disable comboboxes
337         **/
338
339        QString filename;
340        QStringList splitty;
341
342        filename = exportNameTxt->text();
343        splitty = filename.split(".");
344        splitty.removeLast();
345        filename = splitty.join( "." );
346
347        switch ( index ) {
348        case 0:
349                sampleRateCombo->show();
350                sampleDepthCombo->show();
351                sampleRateCombo->setCurrentIndex ( 1 ); //44100hz
352                sampleDepthCombo->setCurrentIndex ( 1 ); //16bit
353                filename += ".wav";
354                m_sExtension = ".wav";
355                break;
356        case 1:
357                sampleRateCombo->show();
358                sampleDepthCombo->show();
359                sampleRateCombo->setCurrentIndex ( 2 ); //48000hz
360                sampleDepthCombo->setCurrentIndex ( 1 ); //16bit
361                filename += ".wav";
362                m_sExtension = ".wav";
363                break;
364        case 2:
365                sampleRateCombo->show();
366                sampleDepthCombo->show();
367                sampleRateCombo->setCurrentIndex ( 2 ); //48000hz
368                sampleDepthCombo->setCurrentIndex ( 2 ); //24bit
369                filename += ".wav";
370                m_sExtension = ".wav";
371                break;
372        case 3:
373                sampleRateCombo->show();
374                sampleDepthCombo->show();
375                sampleRateCombo->setCurrentIndex ( 0 ); //22050hz
376                sampleDepthCombo->setCurrentIndex ( 0 ); //8bit
377                filename += ".wav";
378                m_sExtension = ".wav";
379                break;
380        case 4:
381                sampleRateCombo->show();
382                sampleDepthCombo->show();
383                sampleRateCombo->setCurrentIndex ( 3 ); //96000hz
384                sampleDepthCombo->setCurrentIndex ( 3 ); //32bit
385                filename += ".wav";
386                m_sExtension = ".wav";
387                break;
388        case 5:
389                sampleRateCombo->show();
390                sampleDepthCombo->show();
391                sampleRateCombo->setCurrentIndex ( 1 ); //44100hz
392                sampleDepthCombo->setCurrentIndex ( 1 ); //16bit
393                filename += ".aiff";
394                m_sExtension = ".aiff";
395                break;
396        case 6:
397                sampleRateCombo->show();
398                sampleDepthCombo->show();
399                sampleRateCombo->setCurrentIndex ( 2 ); //48000hz
400                sampleDepthCombo->setCurrentIndex ( 1 ); //16bit
401                filename += ".aiff";
402                m_sExtension = ".aiff";
403                break;
404        case 7:
405                sampleRateCombo->show();
406                sampleDepthCombo->show();
407                sampleRateCombo->setCurrentIndex ( 2 ); //48000hz
408                sampleDepthCombo->setCurrentIndex ( 2 ); //24bit
409                filename += ".aiff";
410                m_sExtension = ".aiff";
411                break;
412        case 8:
413                sampleRateCombo->show();
414                sampleDepthCombo->show();
415                sampleRateCombo->setCurrentIndex ( 2 ); //48000hz
416                sampleDepthCombo->setCurrentIndex ( 2 ); //24bit
417                filename += ".flac";
418                m_sExtension = ".flac";
419                break;
420        case 9:
421                sampleRateCombo->hide();
422                sampleDepthCombo->hide();
423                label->hide();
424                label_2->hide();
425                filename += ".ogg";
426                m_sExtension = ".ogg";
427                break;
428
429        default:
430                sampleRateCombo->show();
431                sampleDepthCombo->show();
432                sampleRateCombo->setCurrentIndex ( 1 ); //44100hz
433                sampleDepthCombo->setCurrentIndex ( 1 ); //16bit
434                filename += ".wav";
435                m_sExtension = ".wav";
436        }
437
438        exportNameTxt->setText(filename);
439
440
441}
442
443
444void ExportSongDialog::on_exportNameTxt_textChanged( const QString& )
445{
446        QString filename = exportNameTxt->text();
447        if ( ! filename.isEmpty() ) {
448                okBtn->setEnabled(true);
449        }
450        else {
451                okBtn->setEnabled(false);
452        }
453
454        if( filename.endsWith( ".ogg" ) || filename.endsWith( ".OGG" ) ){
455                templateCombo->setCurrentIndex( 9 );//ogg
456        }
457        else if( filename.endsWith( ".flac" ) || filename.endsWith( ".FLAC" ) ){
458                label->show();
459                label_2->show();
460                templateCombo->setCurrentIndex( 8 );//flac
461        }
462        else if( filename.endsWith( ".aiff" ) || filename.endsWith( ".AIFF" ) ){
463                label->show();
464                label_2->show();
465                templateCombo->setCurrentIndex( 5 );//aiff
466        }
467        else if( filename.endsWith( ".wav" ) || filename.endsWith( ".WAV" ) ){
468                label->show();
469                label_2->show();
470                templateCombo->setCurrentIndex( 0 );//wav
471        }
472}
473
474
475void ExportSongDialog::progressEvent( int nValue )
476{
477        m_pProgressBar->setValue( nValue );
478        if ( nValue == 100 ) {
479
480                m_bExporting = false;
481
482                if( m_nInstrument == Hydrogen::get_instance()->getSong()->get_instrument_list()->size() -1 ){
483                        HydrogenApp::get_instance()->getMixer()->unmuteAll( false );
484                        m_nInstrument = 0;
485                        m_bExportTrackouts = false;
486
487                }
488
489                if( m_bExportTrackouts ){
490                        exportTracks();
491                }
492        }
493
494        if ( nValue < 100 ) {
495                closeBtn->setEnabled(false);
496                resampleComboBox->setEnabled(false);
497
498        }else
499        {
500                closeBtn->setEnabled(true);
501                resampleComboBox->setEnabled(true);
502        }
503}
504
505void ExportSongDialog::toggleRubberbandBatchMode(bool toggled)
506{
507        Preferences::get_instance()->setRubberBandBatchMode(toggled);
508        if(toggled){
509                calculateRubberbandTime();
510        }
511}
512
513void ExportSongDialog::togglTimeLineBPMMode(bool toggled)
514{
515        Preferences::get_instance()->setUseTimelineBpm(toggled);
516}
517
518void ExportSongDialog::resampleComboBoIndexChanged(int index )
519{
520        setResamplerMode(index);
521}
522
523void ExportSongDialog::setResamplerMode(int index)
524{
525        switch ( index ){
526        case 0:
527               AudioEngine::get_instance()->get_sampler()->setInterpolateMode( Sampler::LINEAR );
528               break;
529        case 1:
530               AudioEngine::get_instance()->get_sampler()->setInterpolateMode( Sampler::COSINE );
531               break;
532        case 2:
533               AudioEngine::get_instance()->get_sampler()->setInterpolateMode( Sampler::THIRD );
534               break;
535        case 3:
536               AudioEngine::get_instance()->get_sampler()->setInterpolateMode( Sampler::CUBIC );
537               break;
538        case 4:
539               AudioEngine::get_instance()->get_sampler()->setInterpolateMode( Sampler::HERMITE );
540               break;
541        }
542}
543
544
545void ExportSongDialog::calculateRubberbandTime()
546{
547        QApplication::setOverrideCursor(Qt::WaitCursor);
548        closeBtn->setEnabled(false);
549        resampleComboBox->setEnabled(false);
550        okBtn->setEnabled(false);
551        Hydrogen* engine = Hydrogen::get_instance();
552        float oldBPM = engine->getSong()->__bpm;
553        float lowBPM = oldBPM;
554
555        if( engine->m_timelinevector.size() >= 1 ){
556                for ( int t = 0; t < engine->m_timelinevector.size(); t++){
557                        if(engine->m_timelinevector[t].m_htimelinebpm < lowBPM){
558                                lowBPM =  engine->m_timelinevector[t].m_htimelinebpm;
559                        }
560
561                }
562        }
563
564        engine->setBPM(lowBPM);
565        time_t sTime = time(NULL);
566        Hydrogen *pEngine = Hydrogen::get_instance();
567        Song *song = pEngine->getSong();
568        assert(song);
569        if(song){
570                InstrumentList *songInstrList = song->get_instrument_list();
571                assert(songInstrList);
572                for ( unsigned nInstr = 0; nInstr < songInstrList->size(); ++nInstr ) {
573                        Instrument *pInstr = songInstrList->get( nInstr );
574                        assert( pInstr );
575                        if ( pInstr ){
576                                for ( int nLayer = 0; nLayer < MAX_LAYERS; nLayer++ ) {
577                                        InstrumentLayer *pLayer = pInstr->get_layer( nLayer );
578                                        if ( pLayer ) {
579                                                Sample *pSample = pLayer->get_sample();
580                                                if ( pSample ) {
581                            if( pSample->get_rubberband().use ) {
582                                Sample *newSample = Sample::load(
583                                        pSample->get_filepath(),
584                                        pSample->get_loops(),
585                                        pSample->get_rubberband(),
586                                        *pSample->get_velocity_envelope(),
587                                        *pSample->get_pan_envelope()
588                                        );
589                                                                if( !newSample  ){
590                                                                        continue;
591                                                                }
592                                                                delete pSample;
593                                                                // insert new sample from newInstrument
594                                                                AudioEngine::get_instance()->lock( RIGHT_HERE );
595                                                                pLayer->set_sample( newSample );
596                                                                AudioEngine::get_instance()->unlock();
597
598                                                        }
599                                                }
600                                        }
601                                }
602                        }
603                }
604        }
605        Preferences::get_instance()->setRubberBandCalcTime(time(NULL) - sTime);
606        engine->setBPM(oldBPM);
607        closeBtn->setEnabled(true);
608        resampleComboBox->setEnabled(true);
609        okBtn->setEnabled(true);
610        QApplication::restoreOverrideCursor();
611
612}
613
614bool ExportSongDialog::checkUseOfRubberband()
615{
616        Hydrogen *pEngine = Hydrogen::get_instance();
617        Song *song = pEngine->getSong();
618        assert(song);
619        if(song){
620                InstrumentList *songInstrList = song->get_instrument_list();
621                assert(songInstrList);
622                for ( unsigned nInstr = 0; nInstr < songInstrList->size(); ++nInstr ) {
623                        Instrument *pInstr = songInstrList->get( nInstr );
624                        assert( pInstr );
625                        if ( pInstr ){
626                                for ( int nLayer = 0; nLayer < MAX_LAYERS; nLayer++ ) {
627                                        InstrumentLayer *pLayer = pInstr->get_layer( nLayer );
628                                        if ( pLayer ) {
629                                                Sample *pSample = pLayer->get_sample();
630                                                if ( pSample ) {
631                            if( pSample->get_rubberband().use ) {
632                                    return true;
633
634                                                        }
635                                                }
636                                        }
637                                }
638                        }
639                }
640        }
641        return false;
642}
Note: See TracBrowser for help on using the browser.