2 Copyright (C) 2005-2006 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gtk2ardour-config.h"
32 #include <gtkmm/box.h>
33 #include <gtkmm/stock.h>
34 #include <glibmm/fileutils.h>
36 #include "pbd/convert.h"
37 #include "pbd/tokenizer.h"
38 #include "pbd/enumwriter.h"
39 #include "pbd/pthread_utils.h"
40 #include "pbd/xml++.h"
42 #include <gtkmm2ext/utils.h>
44 #include "evoral/SMF.hpp"
46 #include "ardour/audio_library.h"
47 #include "ardour/auditioner.h"
48 #include "ardour/audioregion.h"
49 #include "ardour/audiofilesource.h"
50 #include "ardour/smf_source.h"
51 #include "ardour/region_factory.h"
52 #include "ardour/source_factory.h"
53 #include "ardour/session.h"
54 #include "ardour/session_directory.h"
55 #include "ardour/srcfilesource.h"
57 #include "ardour_ui.h"
59 #include "gui_thread.h"
64 #include "gain_meter.h"
65 #include "main_clock.h"
66 #include "public_editor.h"
68 #include "sfdb_freesound_mootcher.h"
72 using namespace ARDOUR;
76 using namespace Gtkmm2ext;
77 using namespace Editing;
81 string SoundFileBrowser::persistent_folder;
82 typedef TreeView::Selection::ListHandle_Path ListPath;
85 string2importmode (string str)
87 if (str == _("as new tracks")) {
89 } else if (str == _("to selected tracks")) {
91 } else if (str == _("to region list")) {
92 return ImportAsRegion;
93 } else if (str == _("as new tape tracks")) {
94 return ImportAsTapeTrack;
97 warning << string_compose (_("programming error: unknown import mode string %1"), str) << endmsg;
103 importmode2string (ImportMode mode)
107 return _("as new tracks");
109 return _("to selected tracks");
111 return _("to region list");
112 case ImportAsTapeTrack:
113 return _("as new tape tracks");
116 return _("as new tracks");
119 SoundFileBox::SoundFileBox (bool persistent)
121 length_clock ("sfboxLengthClock", true, "", false, false, true, false),
122 timecode_clock ("sfboxTimecodeClock", true, "", false, false, false, false),
124 autoplay_btn (_("Auto-play")),
125 seek_slider(0,1000,1),
129 set_name (X_("SoundFileBox"));
130 set_size_request (300, -1);
132 preview_label.set_markup (_("<b>Sound File Information</b>"));
134 border_frame.set_label_widget (preview_label);
135 border_frame.add (main_box);
137 pack_start (border_frame, true, true);
138 set_border_width (6);
140 main_box.set_border_width (6);
142 length.set_text (_("Length:"));
143 length.set_alignment (1, 0.5);
144 timecode.set_text (_("Timestamp:"));
145 timecode.set_alignment (1, 0.5);
146 format.set_text (_("Format:"));
147 format.set_alignment (1, 0.5);
148 channels.set_text (_("Channels:"));
149 channels.set_alignment (1, 0.5);
150 samplerate.set_text (_("Sample rate:"));
151 samplerate.set_alignment (1, 0.5);
153 preview_label.set_max_width_chars (50);
154 preview_label.set_ellipsize (Pango::ELLIPSIZE_END);
156 format_text.set_max_width_chars (20);
157 format_text.set_ellipsize (Pango::ELLIPSIZE_END);
158 format_text.set_alignment (0, 1);
160 table.set_col_spacings (6);
161 table.set_homogeneous (false);
162 table.set_row_spacings (6);
164 table.attach (channels, 0, 1, 0, 1, FILL, FILL);
165 table.attach (samplerate, 0, 1, 1, 2, FILL, FILL);
166 table.attach (format, 0, 1, 2, 4, FILL, FILL);
167 table.attach (length, 0, 1, 4, 5, FILL, FILL);
168 table.attach (timecode, 0, 1, 5, 6, FILL, FILL);
170 table.attach (channels_value, 1, 2, 0, 1, FILL, FILL);
171 table.attach (samplerate_value, 1, 2, 1, 2, FILL, FILL);
172 table.attach (format_text, 1, 2, 2, 4, FILL, FILL);
173 table.attach (length_clock, 1, 2, 4, 5, FILL, FILL);
174 table.attach (timecode_clock, 1, 2, 5, 6, FILL, FILL);
176 length_clock.set_mode (ARDOUR_UI::instance()->secondary_clock->mode());
177 timecode_clock.set_mode (AudioClock::Timecode);
179 main_box.pack_start (table, false, false);
181 tags_entry.set_editable (true);
182 tags_entry.set_wrap_mode(Gtk::WRAP_WORD);
183 tags_entry.signal_focus_out_event().connect (sigc::mem_fun (*this, &SoundFileBox::tags_entry_left));
185 Label* label = manage (new Label (_("Tags:")));
186 label->set_alignment (0.0f, 0.5f);
187 main_box.pack_start (*label, false, false);
188 main_box.pack_start (tags_entry, true, true);
190 main_box.pack_start (bottom_box, false, false);
192 play_btn.set_image (*(manage (new Image (Stock::MEDIA_PLAY, ICON_SIZE_BUTTON))));
193 // play_btn.set_label (_("Play"));
195 stop_btn.set_image (*(manage (new Image (Stock::MEDIA_STOP, ICON_SIZE_BUTTON))));
196 // stop_btn.set_label (_("Stop"));
198 bottom_box.set_homogeneous (false);
199 bottom_box.set_spacing (6);
200 bottom_box.pack_start(play_btn, true, true);
201 bottom_box.pack_start(stop_btn, true, true);
202 bottom_box.pack_start(autoplay_btn, false, false);
204 seek_slider.set_draw_value(false);
206 seek_slider.add_events(Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
207 seek_slider.signal_button_press_event().connect(sigc::mem_fun(*this, &SoundFileBox::seek_button_press), false);
208 seek_slider.signal_button_release_event().connect(sigc::mem_fun(*this, &SoundFileBox::seek_button_release), false);
209 main_box.pack_start (seek_slider, false, false);
211 play_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::audition));
212 stop_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::stop_audition));
214 stop_btn.set_sensitive (false);
216 channels_value.set_alignment (0.0f, 0.5f);
217 samplerate_value.set_alignment (0.0f, 0.5f);
221 SoundFileBox::set_session(Session* s)
223 SessionHandlePtr::set_session (s);
225 length_clock.set_session (s);
226 timecode_clock.set_session (s);
229 play_btn.set_sensitive (false);
230 stop_btn.set_sensitive (false);
231 auditioner_connections.drop_connections();
233 auditioner_connections.drop_connections();
234 _session->AuditionActive.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_active, this, _1), gui_context());
235 _session->the_auditioner()->AuditionProgress.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_progress, this, _1, _2), gui_context());
240 SoundFileBox::audition_active(bool active) {
241 stop_btn.set_sensitive (active);
242 seek_slider.set_sensitive (active);
244 seek_slider.set_value(0);
249 SoundFileBox::audition_progress(ARDOUR::framecnt_t pos, ARDOUR::framecnt_t len) {
251 seek_slider.set_value( 1000.0 * pos / len);
252 seek_slider.set_sensitive (true);
257 SoundFileBox::seek_button_press(GdkEventButton*) {
259 return false; // pass on to slider
263 SoundFileBox::seek_button_release(GdkEventButton*) {
265 _session->the_auditioner()->seek_to_percent(seek_slider.get_value() / 10.0);
266 seek_slider.set_sensitive (false);
267 return false; // pass on to slider
271 SoundFileBox::setup_labels (const string& filename)
274 // save existing tags
282 if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
284 preview_label.set_markup (_("<b>Sound File Information</b>"));
285 format_text.set_text ("");
286 channels_value.set_text ("");
287 samplerate_value.set_text ("");
288 tags_entry.get_buffer()->set_text ("");
290 length_clock.set (0);
291 timecode_clock.set (0);
293 tags_entry.set_sensitive (false);
294 play_btn.set_sensitive (false);
299 preview_label.set_markup (string_compose ("<b>%1</b>", Glib::Markup::escape_text (Glib::path_get_basename (filename))));
300 std::string n = sf_info.format_name;
301 if (n.substr (0, 8) == X_("Format: ")) {
304 format_text.set_text (n);
305 channels_value.set_text (to_string (sf_info.channels, std::dec));
307 if (_session && sf_info.samplerate != _session->frame_rate()) {
308 samplerate.set_markup (string_compose ("<b>%1</b>", _("Sample rate:")));
309 samplerate_value.set_markup (string_compose (X_("<b>%1 Hz</b>"), sf_info.samplerate));
310 samplerate_value.set_name ("NewSessionSR1Label");
311 samplerate.set_name ("NewSessionSR1Label");
313 samplerate.set_text (_("Sample rate:"));
314 samplerate_value.set_text (string_compose (X_("%1 Hz"), sf_info.samplerate));
315 samplerate_value.set_name ("NewSessionSR2Label");
316 samplerate.set_name ("NewSessionSR2Label");
319 framecnt_t const nfr = _session ? _session->nominal_frame_rate() : 25;
320 double src_coef = (double) nfr / sf_info.samplerate;
322 length_clock.set (sf_info.length * src_coef + 0.5, true);
323 timecode_clock.set (sf_info.timecode * src_coef + 0.5, true);
325 // this is a hack that is fixed in trunk, i think (august 26th, 2007)
327 vector<string> tags = Library->get_tags (string ("//") + filename);
329 stringstream tag_string;
330 for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
331 if (i != tags.begin()) {
336 tags_entry.get_buffer()->set_text (tag_string.str());
338 tags_entry.set_sensitive (true);
340 play_btn.set_sensitive (true);
347 SoundFileBox::autoplay() const
349 return autoplay_btn.get_active();
353 SoundFileBox::audition_oneshot()
360 SoundFileBox::audition ()
366 if (SMFSource::safe_midi_file_extension (path)) {
367 error << _("Auditioning of MIDI files is not yet supported") << endmsg;
371 _session->cancel_audition();
373 if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
374 warning << string_compose(_("Could not read file: %1 (%2)."), path, strerror(errno)) << endmsg;
378 boost::shared_ptr<Region> r;
380 boost::shared_ptr<AudioFileSource> afs;
381 bool old_sbp = AudioSource::get_build_peakfiles ();
383 /* don't even think of building peakfiles for these files */
385 AudioSource::set_build_peakfiles (false);
387 for (int n = 0; n < sf_info.channels; ++n) {
389 afs = boost::dynamic_pointer_cast<AudioFileSource> (
390 SourceFactory::createExternal (DataType::AUDIO, *_session,
392 Source::Flag (0), false));
393 if (afs->sample_rate() != _session->nominal_frame_rate()) {
394 boost::shared_ptr<SrcFileSource> sfs (new SrcFileSource(*_session, afs, _src_quality));
395 srclist.push_back(sfs);
397 srclist.push_back(afs);
400 } catch (failed_constructor& err) {
401 error << _("Could not access soundfile: ") << path << endmsg;
402 AudioSource::set_build_peakfiles (old_sbp);
407 AudioSource::set_build_peakfiles (old_sbp);
409 if (srclist.empty()) {
413 afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
414 string rname = region_name_from_path (afs->path(), false);
418 plist.add (ARDOUR::Properties::start, 0);
419 plist.add (ARDOUR::Properties::length, srclist[0]->length(srclist[0]->timeline_position()));
420 plist.add (ARDOUR::Properties::name, rname);
421 plist.add (ARDOUR::Properties::layer, 0);
423 r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, plist, false));
425 _session->audition_region(r);
429 SoundFileBox::stop_audition ()
432 _session->cancel_audition();
437 SoundFileBox::tags_entry_left (GdkEventFocus *)
444 SoundFileBox::tags_changed ()
446 string tag_string = tags_entry.get_buffer()->get_text ();
448 if (tag_string.empty()) {
454 if (!PBD::tokenize (tag_string, string(",\n"), std::back_inserter (tags), true)) {
455 warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg;
463 SoundFileBox::save_tags (const vector<string>& tags)
465 Library->set_tags (string ("//") + path, tags);
466 Library->save_changes ();
469 SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s, bool persistent)
470 : ArdourWindow (title)
471 , found_list (ListStore::create(found_list_columns))
472 , freesound_list (ListStore::create(freesound_list_columns))
473 , chooser (FILE_CHOOSER_ACTION_OPEN)
474 , preview (persistent)
475 , found_search_btn (_("Search"))
476 , found_list_view (found_list)
477 , freesound_search_btn (_("Search"))
478 , freesound_list_view (freesound_list)
479 , resetting_ourselves (false)
483 , ok_button (Stock::OK)
484 , cancel_button (Stock::CANCEL)
485 , apply_button (Stock::APPLY)
490 chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops");
491 chooser.add_shortcut_folder_uri("file:///Library/Audio/Apple Loops");
492 chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files");
493 chooser.add_shortcut_folder_uri("file:///Volumes");
496 //add the file chooser
498 chooser.set_border_width (12);
500 audio_and_midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun (*this, &SoundFileBrowser::on_audio_and_midi_filter));
501 audio_and_midi_filter.set_name (_("Audio and MIDI files"));
503 audio_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_audio_filter));
504 audio_filter.set_name (_("Audio files"));
506 midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_midi_filter));
507 midi_filter.set_name (_("MIDI files"));
509 matchall_filter.add_pattern ("*.*");
510 matchall_filter.set_name (_("All files"));
512 chooser.add_filter (audio_and_midi_filter);
513 chooser.add_filter (audio_filter);
514 chooser.add_filter (midi_filter);
515 chooser.add_filter (matchall_filter);
516 chooser.set_select_multiple (true);
517 chooser.signal_update_preview().connect(sigc::mem_fun(*this, &SoundFileBrowser::update_preview));
518 chooser.signal_file_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
521 /* some broken redraw behaviour - this is a bandaid */
522 chooser.signal_selection_changed().connect (mem_fun (chooser, &Widget::queue_draw));
525 if (!persistent_folder.empty()) {
526 chooser.set_current_folder (persistent_folder);
529 notebook.append_page (chooser, _("Browse Files"));
531 hpacker.set_spacing (6);
532 hpacker.pack_start (notebook, true, true);
533 hpacker.pack_start (preview, false, false);
535 vpacker.set_spacing (6);
536 vpacker.pack_start (hpacker, true, true);
546 hbox = manage(new HBox);
547 hbox->pack_start (found_entry);
548 hbox->pack_start (found_search_btn);
550 Gtk::ScrolledWindow *scroll = manage(new ScrolledWindow);
551 scroll->add(found_list_view);
552 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
554 vbox = manage(new VBox);
555 vbox->pack_start (*hbox, PACK_SHRINK);
556 vbox->pack_start (*scroll);
558 found_list_view.append_column(_("Paths"), found_list_columns.pathname);
560 found_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
562 found_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::found_list_view_activated));
564 found_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
565 found_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
567 notebook.append_page (*vbox, _("Search Tags"));
569 //add freesound search
574 passbox = manage(new HBox);
575 passbox->set_spacing (6);
577 label = manage (new Label);
578 label->set_text (_("Tags:"));
579 passbox->pack_start (*label, false, false);
580 passbox->pack_start (freesound_entry, true, true);
582 label = manage (new Label);
583 label->set_text (_("Sort:"));
584 passbox->pack_start (*label, false, false);
585 passbox->pack_start (freesound_sort, false, false);
586 freesound_sort.clear_items();
588 // Order of the following must correspond with enum sortMethod
589 // in sfdb_freesound_mootcher.h
590 freesound_sort.append_text(_("None"));
591 freesound_sort.append_text(_("Longest"));
592 freesound_sort.append_text(_("Shortest"));
593 freesound_sort.append_text(_("Newest"));
594 freesound_sort.append_text(_("Oldest"));
595 freesound_sort.append_text(_("Most downloaded"));
596 freesound_sort.append_text(_("Least downloaded"));
597 freesound_sort.append_text(_("Highest rated"));
598 freesound_sort.append_text(_("Lowest rated"));
599 freesound_sort.set_active(0);
601 passbox->pack_start (freesound_search_btn, false, false);
602 passbox->pack_start (freesound_more_btn, false, false);
603 freesound_more_btn.set_label(_("More"));
604 freesound_more_btn.set_sensitive(false);
606 passbox->pack_start (freesound_similar_btn, false, false);
607 freesound_similar_btn.set_label(_("Similar"));
608 freesound_similar_btn.set_sensitive(false);
610 scroll = manage(new ScrolledWindow);
611 scroll->add(freesound_list_view);
612 scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
614 vbox = manage(new VBox);
615 vbox->set_spacing (3);
616 vbox->pack_start (*passbox, PACK_SHRINK);
617 vbox->pack_start (*scroll);
619 freesound_list_view.append_column(_("ID") , freesound_list_columns.id);
620 freesound_list_view.append_column(_("Filename"), freesound_list_columns.filename);
621 // freesound_list_view.append_column(_("URI") , freesound_list_columns.uri);
622 freesound_list_view.append_column(_("Duration"), freesound_list_columns.duration);
623 freesound_list_view.append_column(_("Size"), freesound_list_columns.filesize);
624 freesound_list_view.append_column(_("Samplerate"), freesound_list_columns.smplrate);
625 freesound_list_view.append_column(_("License"), freesound_list_columns.license);
626 freesound_list_view.get_column(0)->set_alignment(0.5);
627 freesound_list_view.get_column(1)->set_expand(true); // filename
628 freesound_list_view.get_column(1)->set_resizable(true); // filename
629 freesound_list_view.get_column(2)->set_alignment(0.5);
630 freesound_list_view.get_column(3)->set_alignment(0.5);
631 freesound_list_view.get_column(4)->set_alignment(0.5);
632 freesound_list_view.get_column(5)->set_alignment(0.5);
634 freesound_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_list_view_selected));
635 freesound_list_view.set_tooltip_column(1);
637 freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
638 freesound_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
639 freesound_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
640 freesound_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
641 freesound_more_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_more_clicked));
642 freesound_similar_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_similar_clicked));
643 notebook.append_page (*vbox, _("Search Freesound"));
645 notebook.set_size_request (500, -1);
646 notebook.signal_switch_page().connect (sigc::hide_return (sigc::hide (sigc::hide (sigc::mem_fun (*this, &SoundFileBrowser::reset_options)))));
650 Gtk::HButtonBox* button_box = manage (new HButtonBox);
652 button_box->set_layout (BUTTONBOX_END);
653 button_box->pack_start (cancel_button, false, false);
654 cancel_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_CANCEL));
656 button_box->pack_start (apply_button, false, false);
657 apply_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_APPLY));
660 button_box->pack_start (ok_button, false, false);
661 ok_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_OK));
663 Gtkmm2ext::UI::instance()->set_tip (ok_button, _("Press to import selected files and close this window"));
664 Gtkmm2ext::UI::instance()->set_tip (apply_button, _("Press to import selected files and leave this window open"));
665 Gtkmm2ext::UI::instance()->set_tip (cancel_button, _("Press to close this window without importing any files"));
667 vpacker.pack_end (*button_box, false, false);
669 set_wmclass (X_("import"), PROGRAM_NAME);
672 SoundFileBrowser::~SoundFileBrowser ()
674 persistent_folder = chooser.get_current_folder();
678 SoundFileBrowser::run ()
687 gtk_main_iteration ();
694 SoundFileBrowser::set_action_sensitive (bool yn)
696 ok_button.set_sensitive (yn);
697 apply_button.set_sensitive (yn);
701 SoundFileBrowser::do_something (int action)
708 SoundFileBrowser::on_show ()
710 ArdourWindow::on_show ();
715 SoundFileBrowser::clear_selection ()
717 chooser.unselect_all ();
718 found_list_view.get_selection()->unselect_all ();
722 SoundFileBrowser::chooser_file_activated ()
728 SoundFileBrowser::found_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
734 SoundFileBrowser::freesound_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
740 SoundFileBrowser::set_session (Session* s)
742 ArdourWindow::set_session (s);
743 preview.set_session (s);
748 remove_gain_meter ();
753 SoundFileBrowser::add_gain_meter ()
757 gm = new GainMeter (_session, 250);
759 boost::shared_ptr<Route> r = _session->the_auditioner ();
761 gm->set_controls (r, r->shared_peak_meter(), r->amp());
762 gm->set_fader_name (X_("GainFader"));
764 meter_packer.set_border_width (12);
765 meter_packer.pack_start (*gm, false, true);
766 hpacker.pack_end (meter_packer, false, false);
767 meter_packer.show_all ();
772 SoundFileBrowser::remove_gain_meter ()
775 meter_packer.remove (*gm);
776 hpacker.remove (meter_packer);
783 SoundFileBrowser::start_metering ()
785 metering_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (sigc::mem_fun(*this, &SoundFileBrowser::meter));
789 SoundFileBrowser::stop_metering ()
791 metering_connection.disconnect();
795 SoundFileBrowser::meter ()
797 if (is_mapped () && _session && gm) {
798 gm->update_meters ();
803 SoundFileBrowser::on_audio_filter (const FileFilter::Info& filter_info)
805 return AudioFileSource::safe_audio_file_extension (filter_info.filename);
809 SoundFileBrowser::on_midi_filter (const FileFilter::Info& filter_info)
811 return SMFSource::safe_midi_file_extension (filter_info.filename);
815 SoundFileBrowser::on_audio_and_midi_filter (const FileFilter::Info& filter_info)
817 return on_audio_filter (filter_info) || on_midi_filter (filter_info);
821 SoundFileBrowser::update_preview ()
823 if (preview.setup_labels (chooser.get_preview_filename())) {
824 if (preview.autoplay()) {
825 Glib::signal_idle().connect (sigc::mem_fun (preview, &SoundFileBox::audition_oneshot));
831 SoundFileBrowser::found_list_view_selected ()
833 if (!reset_options ()) {
834 set_action_sensitive (false);
838 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
841 TreeIter iter = found_list->get_iter(*rows.begin());
842 file = (*iter)[found_list_columns.pathname];
843 chooser.set_filename (file);
844 set_action_sensitive (true);
846 set_action_sensitive (false);
849 preview.setup_labels (file);
854 SoundFileBrowser::found_search_clicked ()
856 string tag_string = found_entry.get_text ();
860 if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
861 warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
865 vector<string> results;
866 Library->search_members_and (results, tags);
869 for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
870 TreeModel::iterator new_row = found_list->append();
871 TreeModel::Row row = *new_row;
872 string path = Glib::filename_from_uri (string ("file:") + *i);
873 row[found_list_columns.pathname] = path;
879 SoundFileBrowser::freesound_get_audio_file(Gtk::TreeIter iter)
882 Mootcher *mootcher = new Mootcher;
885 string id = (*iter)[freesound_list_columns.id];
886 string uri = (*iter)[freesound_list_columns.uri];
887 string ofn = (*iter)[freesound_list_columns.filename];
889 if (mootcher->checkAudioFile(ofn, id)) {
890 // file already exists, no need to download it again
891 file = mootcher->audioFileName;
893 (*iter)[freesound_list_columns.started] = false;
896 if (!(*iter)[freesound_list_columns.started]) {
897 // start downloading the sound file
898 (*iter)[freesound_list_columns.started] = true;
899 mootcher->fetchAudioFile(ofn, id, uri, this);
905 SoundFileBrowser::freesound_list_view_selected ()
908 if (!reset_options ()) {
909 set_action_sensitive (false);
912 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
913 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
914 file = freesound_get_audio_file (freesound_list->get_iter(*i));
917 switch (rows.size()) {
920 freesound_similar_btn.set_sensitive(false);
921 set_action_sensitive (false);
924 // exactly one item selected
926 // file exists on disk already
927 chooser.set_filename (file);
928 preview.setup_labels (file);
929 set_action_sensitive (true);
931 freesound_similar_btn.set_sensitive(true);
934 // multiple items selected
935 preview.setup_labels ("");
936 freesound_similar_btn.set_sensitive(false);
944 SoundFileBrowser::refresh_display(std::string ID, std::string file)
946 // called when the mootcher has finished downloading a file
947 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
948 if (rows.size() == 1) {
949 // there's a single item selected in the freesound list
950 //XXX make a function to be used to construct the actual file name both here and in the mootcher
951 Gtk::TreeIter row = freesound_list->get_iter(*rows.begin());
952 std::string selected_ID = (*row)[freesound_list_columns.id];
953 if (ID == selected_ID) {
954 // the selected item in the freesound list is the item that has just finished downloading
955 chooser.set_filename(file);
956 preview.setup_labels (file);
957 set_action_sensitive (true);
963 SoundFileBrowser::freesound_search_clicked ()
966 freesound_list->clear();
972 SoundFileBrowser::freesound_more_clicked ()
977 snprintf(row_path, 21, "%d", (freesound_page - 1) * 100);
978 freesound_list_view.scroll_to_row(Gtk::TreePath(row_path), 0);
982 SoundFileBrowser::freesound_similar_clicked ()
984 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
985 if (rows.size() == 1) {
988 Gtk::TreeIter iter = freesound_list->get_iter(*rows.begin());
989 id = (*iter)[freesound_list_columns.id];
990 freesound_list->clear();
992 GdkCursor *prev_cursor;
993 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
994 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
997 std::string theString = mootcher.searchSimilar(id);
999 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
1000 handle_freesound_results(theString);
1005 SoundFileBrowser::freesound_search()
1009 string search_string = freesound_entry.get_text ();
1010 enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
1012 GdkCursor *prev_cursor;
1013 prev_cursor = gdk_window_get_cursor (get_window()->gobj());
1014 gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
1017 std::string theString = mootcher.searchText(
1021 "", // OSX eats anything incl mp3
1023 "type:wav OR type:aiff OR type:flac OR type:aif OR type:ogg OR type:oga",
1028 gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
1029 handle_freesound_results(theString);
1033 SoundFileBrowser::handle_freesound_results(std::string theString) {
1035 doc.read_buffer( theString );
1036 XMLNode *root = doc.root();
1039 error << "no root XML node!" << endmsg;
1043 if ( strcmp(root->name().c_str(), "response") != 0) {
1044 error << string_compose ("root node name == %1 != \"response\"", root->name()) << endmsg;
1048 // find out how many pages are available to search
1049 int freesound_n_pages = 1;
1050 XMLNode *res = root->child("num_pages");
1052 string result = res->child("text")->content();
1053 freesound_n_pages = atoi(result);
1056 int more_pages = freesound_n_pages - freesound_page;
1058 if (more_pages > 0) {
1059 freesound_more_btn.set_sensitive(true);
1060 freesound_more_btn.set_tooltip_text(string_compose(P_(
1061 "%1 more page of 100 results available",
1062 "%1 more pages of 100 results available",
1063 more_pages), more_pages));
1065 freesound_more_btn.set_sensitive(false);
1066 freesound_more_btn.set_tooltip_text(_("No more results available"));
1069 XMLNode *sounds_root = root->child("sounds");
1071 error << "no child node \"sounds\" found!" << endmsg;
1075 XMLNodeList sounds = sounds_root->children();
1076 if (sounds.size() == 0) {
1081 XMLNodeConstIterator niter;
1083 for (niter = sounds.begin(); niter != sounds.end(); ++niter) {
1085 if( strcmp( node->name().c_str(), "resource") != 0 ) {
1086 error << string_compose ("node->name()=%1 != \"resource\"", node->name()) << endmsg;
1090 // node->dump(cerr, "node:");
1093 XMLNode *id_node = node->child ("id");
1094 XMLNode *uri_node = node->child ("serve");
1095 XMLNode *ofn_node = node->child ("original_filename");
1096 XMLNode *dur_node = node->child ("duration");
1097 XMLNode *siz_node = node->child ("filesize");
1098 XMLNode *srt_node = node->child ("samplerate");
1099 XMLNode *lic_node = node->child ("license");
1101 if (id_node && uri_node && ofn_node && dur_node && siz_node && srt_node) {
1103 std::string id = id_node->child("text")->content();
1104 std::string uri = uri_node->child("text")->content();
1105 std::string ofn = ofn_node->child("text")->content();
1106 std::string dur = dur_node->child("text")->content();
1107 std::string siz = siz_node->child("text")->content();
1108 std::string srt = srt_node->child("text")->content();
1109 std::string lic = lic_node->child("text")->content();
1112 // cerr << "id=" << id << ",uri=" << uri << ",ofn=" << ofn << ",dur=" << dur << endl;
1114 double duration_seconds = atof(dur);
1116 char duration_hhmmss[16];
1117 if (duration_seconds >= 99 * 60 * 60) {
1118 strcpy(duration_hhmmss, ">99h");
1120 s = modf(duration_seconds/60, &m) * 60;
1121 m = modf(m/60, &h) * 60;
1122 sprintf(duration_hhmmss, "%02.fh:%02.fm:%04.1fs",
1127 double size_bytes = atof(siz);
1129 if (size_bytes < 1000) {
1130 sprintf(bsize, "%.0f %s", size_bytes, _("B"));
1131 } else if (size_bytes < 1000000 ) {
1132 sprintf(bsize, "%.1f %s", size_bytes / 1000.0, _("kB"));
1133 } else if (size_bytes < 10000000) {
1134 sprintf(bsize, "%.1f %s", size_bytes / 1000000.0, _("MB"));
1135 } else if (size_bytes < 1000000000) {
1136 sprintf(bsize, "%.2f %s", size_bytes / 1000000.0, _("MB"));
1138 sprintf(bsize, "%.2f %s", size_bytes / 1000000000.0, _("GB"));
1141 /* see http://www.freesound.org/help/faq/#licenses */
1142 char shortlicense[64];
1143 if(!lic.compare(0, 42, "http://creativecommons.org/licenses/by-nc/")){
1144 sprintf(shortlicense, "CC-BY-NC");
1145 } else if(!lic.compare(0, 39, "http://creativecommons.org/licenses/by/")) {
1146 sprintf(shortlicense, "CC-BY");
1147 } else if(!lic.compare("http://creativecommons.org/licenses/sampling+/1.0/")) {
1148 sprintf(shortlicense, "sampling+");
1149 } else if(!lic.compare(0, 40, "http://creativecommons.org/publicdomain/")) {
1150 sprintf(shortlicense, "PD");
1152 snprintf(shortlicense, 64, "%s", lic.c_str());
1153 shortlicense[63]= '\0';
1156 TreeModel::iterator new_row = freesound_list->append();
1157 TreeModel::Row row = *new_row;
1159 row[freesound_list_columns.id ] = id;
1160 row[freesound_list_columns.uri ] = uri;
1161 row[freesound_list_columns.filename] = ofn;
1162 row[freesound_list_columns.duration] = duration_hhmmss;
1163 row[freesound_list_columns.filesize] = bsize;
1164 row[freesound_list_columns.smplrate] = srt;
1165 row[freesound_list_columns.license ] = shortlicense;
1172 SoundFileBrowser::get_paths ()
1174 vector<string> results;
1176 int n = notebook.get_current_page ();
1179 vector<string> filenames = chooser.get_filenames();
1180 vector<string>::iterator i;
1182 for (i = filenames.begin(); i != filenames.end(); ++i) {
1184 if ((!stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
1185 results.push_back (*i);
1189 } else if (n == 1) {
1191 ListPath rows = found_list_view.get_selection()->get_selected_rows ();
1192 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1193 TreeIter iter = found_list->get_iter(*i);
1194 string str = (*iter)[found_list_columns.pathname];
1196 results.push_back (str);
1199 ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1200 for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1201 string str = freesound_get_audio_file (freesound_list->get_iter(*i));
1203 results.push_back (str);
1212 SoundFileOmega::reset_options_noret ()
1214 if (!resetting_ourselves) {
1215 (void) reset_options ();
1220 SoundFileOmega::reset_options ()
1222 vector<string> paths = get_paths ();
1224 if (paths.empty()) {
1226 channel_combo.set_sensitive (false);
1227 action_combo.set_sensitive (false);
1228 where_combo.set_sensitive (false);
1229 copy_files_btn.set_active (true);
1230 copy_files_btn.set_sensitive (false);
1236 channel_combo.set_sensitive (true);
1237 action_combo.set_sensitive (true);
1238 where_combo.set_sensitive (true);
1240 /* if we get through this function successfully, this may be
1241 reset at the end, once we know if we can use hard links
1242 to do embedding (or if we are importing a MIDI file).
1245 if (Config->get_only_copy_imported_files()) {
1246 copy_files_btn.set_sensitive (false);
1248 copy_files_btn.set_sensitive (false);
1254 bool selection_includes_multichannel;
1255 bool selection_can_be_embedded_with_links = check_link_status (_session, paths);
1258 /* See if we are thinking about importing any MIDI files */
1259 vector<string>::iterator i = paths.begin ();
1260 while (i != paths.end() && SMFSource::safe_midi_file_extension (*i) == false) {
1263 bool const have_a_midi_file = (i != paths.end ());
1265 if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
1266 Glib::signal_idle().connect (sigc::mem_fun (*this, &SoundFileOmega::bad_file_message));
1270 string existing_choice;
1271 vector<string> action_strings;
1273 resetting_ourselves = true;
1275 if (chooser.get_filter() == &audio_filter) {
1279 if (selected_audio_track_cnt > 0) {
1280 if (channel_combo.get_active_text().length()) {
1281 ImportDisposition id = get_channel_disposition();
1284 case Editing::ImportDistinctFiles:
1285 if (selected_audio_track_cnt == paths.size()) {
1286 action_strings.push_back (importmode2string (ImportToTrack));
1290 case Editing::ImportDistinctChannels:
1291 /* XXX it would be nice to allow channel-per-selected track
1292 but its too hard we don't want to deal with all the
1293 different per-file + per-track channel configurations.
1298 action_strings.push_back (importmode2string (ImportToTrack));
1308 if (selected_midi_track_cnt > 0) {
1309 action_strings.push_back (importmode2string (ImportToTrack));
1313 action_strings.push_back (importmode2string (ImportAsTrack));
1314 action_strings.push_back (importmode2string (ImportAsRegion));
1315 action_strings.push_back (importmode2string (ImportAsTapeTrack));
1317 existing_choice = action_combo.get_active_text();
1319 set_popdown_strings (action_combo, action_strings);
1321 /* preserve any existing choice, if possible */
1324 if (existing_choice.length()) {
1325 vector<string>::iterator x;
1326 for (x = action_strings.begin(); x != action_strings.end(); ++x) {
1327 if (*x == existing_choice) {
1328 action_combo.set_active_text (existing_choice);
1332 if (x == action_strings.end()) {
1333 action_combo.set_active_text (action_strings.front());
1336 action_combo.set_active_text (action_strings.front());
1339 resetting_ourselves = false;
1341 if ((mode = get_mode()) == ImportAsRegion) {
1342 where_combo.set_sensitive (false);
1344 where_combo.set_sensitive (true);
1347 vector<string> channel_strings;
1349 if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
1350 channel_strings.push_back (_("one track per file"));
1352 if (selection_includes_multichannel) {
1353 channel_strings.push_back (_("one track per channel"));
1356 if (paths.size() > 1) {
1357 /* tape tracks are a single region per track, so we cannot
1358 sequence multiple files.
1360 if (mode != ImportAsTapeTrack) {
1361 channel_strings.push_back (_("sequence files"));
1364 channel_strings.push_back (_("all files in one track"));
1365 channel_strings.push_back (_("merge files"));
1371 channel_strings.push_back (_("one region per file"));
1373 if (selection_includes_multichannel) {
1374 channel_strings.push_back (_("one region per channel"));
1377 if (paths.size() > 1) {
1379 channel_strings.push_back (_("all files in one region"));
1384 resetting_ourselves = true;
1386 existing_choice = channel_combo.get_active_text();
1388 set_popdown_strings (channel_combo, channel_strings);
1390 /* preserve any existing choice, if possible */
1392 if (existing_choice.length()) {
1393 vector<string>::iterator x;
1394 for (x = channel_strings.begin(); x != channel_strings.end(); ++x) {
1395 if (*x == existing_choice) {
1396 channel_combo.set_active_text (existing_choice);
1400 if (x == channel_strings.end()) {
1401 channel_combo.set_active_text (channel_strings.front());
1404 channel_combo.set_active_text (channel_strings.front());
1407 resetting_ourselves = false;
1410 src_combo.set_sensitive (true);
1412 src_combo.set_sensitive (false);
1415 /* We must copy MIDI files or those from Freesound
1416 * or any file if we are under nsm control */
1417 bool const must_copy = _session->get_nsm_state() || have_a_midi_file || notebook.get_current_page() == 2;
1419 if (Config->get_only_copy_imported_files()) {
1421 if (selection_can_be_embedded_with_links && !must_copy) {
1422 copy_files_btn.set_sensitive (true);
1425 copy_files_btn.set_active (true);
1427 copy_files_btn.set_sensitive (false);
1433 copy_files_btn.set_active (true);
1435 copy_files_btn.set_sensitive (!must_copy);
1443 SoundFileOmega::bad_file_message()
1445 MessageDialog msg (*this,
1446 string_compose (_("One or more of the selected files\ncannot be used by %1"), PROGRAM_NAME),
1451 resetting_ourselves = true;
1452 chooser.unselect_uri (chooser.get_preview_uri());
1453 resetting_ourselves = false;
1459 SoundFileOmega::check_info (const vector<string>& paths, bool& same_size, bool& src_needed, bool& multichannel)
1468 multichannel = false;
1470 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1472 if (AudioFileSource::get_soundfile_info (*i, info, errmsg)) {
1473 if (info.channels > 1) {
1474 multichannel = true;
1479 if (sz != info.length) {
1484 if (info.samplerate != _session->frame_rate()) {
1488 } else if (SMFSource::safe_midi_file_extension (*i)) {
1492 if (reader.num_tracks() > 1) {
1493 multichannel = true; // "channel" == track here...
1496 /* XXX we need err = true handling here in case
1497 we can't check the file
1510 SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths)
1512 std::string tmpdir(Glib::build_filename (s->session_directory().sound_path(), "linktest"));
1515 if (mkdir (tmpdir.c_str(), 0744)) {
1516 if (errno != EEXIST) {
1521 for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1523 char tmpc[PATH_MAX+1];
1525 snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
1529 if (link ((*i).c_str(), tmpc)) {
1539 rmdir (tmpdir.c_str());
1543 SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s)
1544 : SoundFileBrowser (title, s, false)
1546 chooser.set_select_multiple (false);
1547 found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1548 freesound_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1552 SoundFileChooser::on_hide ()
1554 ArdourWindow::on_hide();
1558 _session->cancel_audition();
1563 SoundFileChooser::get_filename ()
1565 vector<string> paths;
1567 paths = get_paths ();
1569 if (paths.empty()) {
1573 if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
1577 return paths.front();
1580 SoundFileOmega::SoundFileOmega (string title, ARDOUR::Session* s,
1581 uint32_t selected_audio_tracks,
1582 uint32_t selected_midi_tracks,
1584 Editing::ImportMode mode_hint)
1585 : SoundFileBrowser (title, s, persistent)
1586 , copy_files_btn ( _("Copy files to session"))
1587 , selected_audio_track_cnt (selected_audio_tracks)
1588 , selected_midi_track_cnt (selected_midi_tracks)
1594 set_size_request (-1, 450);
1596 block_two.set_border_width (12);
1597 block_three.set_border_width (12);
1598 block_four.set_border_width (12);
1600 options.set_spacing (12);
1603 str.push_back (_("file timestamp"));
1604 str.push_back (_("edit point"));
1605 str.push_back (_("playhead"));
1606 str.push_back (_("session start"));
1607 set_popdown_strings (where_combo, str);
1608 where_combo.set_active_text (str.front());
1610 Label* l = manage (new Label);
1611 l->set_markup (_("<b>Add files as ...</b>"));
1613 vbox = manage (new VBox);
1614 vbox->set_border_width (12);
1615 vbox->set_spacing (6);
1616 vbox->pack_start (*l, false, false);
1617 vbox->pack_start (action_combo, false, false);
1618 hbox = manage (new HBox);
1619 hbox->pack_start (*vbox, false, false);
1620 options.pack_start (*hbox, false, false);
1622 /* dummy entry for action combo so that it doesn't look odd if we
1623 come up with no tracks selected.
1627 str.push_back (importmode2string (mode_hint));
1628 set_popdown_strings (action_combo, str);
1629 action_combo.set_active_text (str.front());
1630 action_combo.set_sensitive (false);
1632 l = manage (new Label);
1633 l->set_markup (_("<b>Insert at</b>"));
1635 vbox = manage (new VBox);
1636 vbox->set_border_width (12);
1637 vbox->set_spacing (6);
1638 vbox->pack_start (*l, false, false);
1639 vbox->pack_start (where_combo, false, false);
1640 hbox = manage (new HBox);
1641 hbox->pack_start (*vbox, false, false);
1642 options.pack_start (*hbox, false, false);
1645 l = manage (new Label);
1646 l->set_markup (_("<b>Mapping</b>"));
1648 vbox = manage (new VBox);
1649 vbox->set_border_width (12);
1650 vbox->set_spacing (6);
1651 vbox->pack_start (*l, false, false);
1652 vbox->pack_start (channel_combo, false, false);
1653 hbox = manage (new HBox);
1654 hbox->pack_start (*vbox, false, false);
1655 options.pack_start (*hbox, false, false);
1658 str.push_back (_("one track per file"));
1659 set_popdown_strings (channel_combo, str);
1660 channel_combo.set_active_text (str.front());
1661 channel_combo.set_sensitive (false);
1663 l = manage (new Label);
1664 l->set_markup (_("<b>Conversion quality</b>"));
1666 vbox = manage (new VBox);
1667 vbox->set_border_width (12);
1668 vbox->set_spacing (6);
1669 vbox->pack_start (*l, false, false);
1670 vbox->pack_start (src_combo, false, false);
1671 hbox = manage (new HBox);
1672 hbox->pack_start (*vbox, false, false);
1673 options.pack_start (*hbox, false, false);
1676 str.push_back (_("Best"));
1677 str.push_back (_("Good"));
1678 str.push_back (_("Quick"));
1679 str.push_back (_("Fast"));
1680 str.push_back (_("Fastest"));
1682 set_popdown_strings (src_combo, str);
1683 src_combo.set_active_text (str.front());
1684 src_combo.set_sensitive (false);
1685 src_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::src_combo_changed));
1689 action_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1690 channel_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1692 copy_files_btn.set_active (true);
1694 Gtk::Label* copy_label = dynamic_cast<Gtk::Label*>(copy_files_btn.get_child());
1697 copy_label->set_size_request (175, -1);
1698 copy_label->set_line_wrap (true);
1701 block_four.pack_start (copy_files_btn, false, false);
1703 options.pack_start (block_four, false, false);
1705 vpacker.pack_start (options, false, false);
1707 /* setup disposition map */
1709 disposition_map.insert (pair<string,ImportDisposition>(_("one track per file"), ImportDistinctFiles));
1710 disposition_map.insert (pair<string,ImportDisposition>(_("one track per channel"), ImportDistinctChannels));
1711 disposition_map.insert (pair<string,ImportDisposition>(_("merge files"), ImportMergeFiles));
1712 disposition_map.insert (pair<string,ImportDisposition>(_("sequence files"), ImportSerializeFiles));
1714 disposition_map.insert (pair<string,ImportDisposition>(_("one region per file"), ImportDistinctFiles));
1715 disposition_map.insert (pair<string,ImportDisposition>(_("one region per channel"), ImportDistinctChannels));
1716 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one region"), ImportMergeFiles));
1717 disposition_map.insert (pair<string,ImportDisposition>(_("all files in one track"), ImportMergeFiles));
1719 chooser.signal_selection_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::file_selection_changed));
1721 /* set size requests for a couple of combos to allow them to display the longest text
1722 they will ever be asked to display. This prevents them being resized when the user
1723 selects a file to import, which in turn prevents the size of the dialog from jumping
1727 t.push_back (_("one track per file"));
1728 t.push_back (_("one track per channel"));
1729 t.push_back (_("sequence files"));
1730 t.push_back (_("all files in one region"));
1731 set_popdown_strings (channel_combo, t);
1734 t.push_back (importmode2string (ImportAsTrack));
1735 t.push_back (importmode2string (ImportToTrack));
1736 t.push_back (importmode2string (ImportAsRegion));
1737 t.push_back (importmode2string (ImportAsTapeTrack));
1738 set_popdown_strings (action_combo, t);
1742 SoundFileOmega::set_mode (ImportMode mode)
1744 action_combo.set_active_text (importmode2string (mode));
1748 SoundFileOmega::get_mode () const
1750 return string2importmode (action_combo.get_active_text());
1754 SoundFileOmega::on_hide ()
1756 ArdourWindow::on_hide();
1758 _session->cancel_audition();
1763 SoundFileOmega::get_position() const
1765 string str = where_combo.get_active_text();
1767 if (str == _("file timestamp")) {
1768 return ImportAtTimestamp;
1769 } else if (str == _("edit point")) {
1770 return ImportAtEditPoint;
1771 } else if (str == _("playhead")) {
1772 return ImportAtPlayhead;
1774 return ImportAtStart;
1779 SoundFileOmega::get_src_quality() const
1781 string str = src_combo.get_active_text();
1783 if (str == _("Best")) {
1785 } else if (str == _("Good")) {
1787 } else if (str == _("Quick")) {
1789 } else if (str == _("Fast")) {
1797 SoundFileOmega::src_combo_changed()
1799 preview.set_src_quality(get_src_quality());
1803 SoundFileOmega::get_channel_disposition () const
1805 /* we use a map here because the channel combo can contain different strings
1806 depending on the state of the other combos. the map contains all possible strings
1807 and the ImportDisposition enum that corresponds to it.
1810 string str = channel_combo.get_active_text();
1811 DispositionMap::const_iterator x = disposition_map.find (str);
1813 if (x == disposition_map.end()) {
1814 fatal << string_compose (_("programming error: %1 (%2)"), "unknown string for import disposition", str) << endmsg;
1822 SoundFileOmega::reset (uint32_t selected_audio_tracks, uint32_t selected_midi_tracks)
1824 selected_audio_track_cnt = selected_audio_tracks;
1825 selected_midi_track_cnt = selected_midi_tracks;
1827 if (selected_audio_track_cnt == 0 && selected_midi_track_cnt > 0) {
1828 chooser.set_filter (midi_filter);
1829 } else if (selected_midi_track_cnt == 0 && selected_audio_track_cnt > 0) {
1830 chooser.set_filter (audio_filter);
1832 chooser.set_filter (audio_and_midi_filter);
1839 SoundFileOmega::file_selection_changed ()
1841 if (resetting_ourselves) {
1845 if (!reset_options ()) {
1846 set_action_sensitive (false);
1848 if (chooser.get_filenames().size() > 0) {
1849 set_action_sensitive (true);
1851 set_action_sensitive (false);
1857 SoundFileOmega::do_something (int action)
1859 SoundFileBrowser::do_something (action);
1861 if (action == RESPONSE_CANCEL) {
1868 vector<string> paths = get_paths ();
1869 ImportPosition pos = get_position ();
1870 ImportMode mode = get_mode ();
1871 ImportDisposition chns = get_channel_disposition ();
1875 case ImportAtEditPoint:
1876 where = PublicEditor::instance().get_preferred_edit_position ();
1878 case ImportAtTimestamp:
1881 case ImportAtPlayhead:
1882 where = _session->transport_frame();
1885 where = _session->current_start_frame();
1889 SrcQuality quality = get_src_quality();
1891 if (copy_files_btn.get_active()) {
1892 PublicEditor::instance().do_import (paths, chns, mode, quality, where);
1894 PublicEditor::instance().do_embed (paths, chns, mode, where);
1897 if (action == RESPONSE_OK) {