ardour
sfdb_ui.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2005-2006 Paul Davis
3 
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.
8 
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.
13 
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.
17 
18 */
19 
20 #ifdef WAF_BUILD
21 #include "gtk2ardour-config.h"
22 #endif
23 
24 #include "i18n.h"
25 
26 #include <map>
27 #include <cerrno>
28 #include <sstream>
29 
30 #include <unistd.h>
31 #include <limits.h>
32 #include <sys/stat.h>
33 
34 #include <gtkmm/box.h>
35 #include <gtkmm/stock.h>
36 
37 #include <glib/gstdio.h>
38 #include <glibmm/fileutils.h>
39 
40 #include "pbd/convert.h"
41 #include "pbd/tokenizer.h"
42 #include "pbd/enumwriter.h"
43 #include "pbd/pthread_utils.h"
44 #include "pbd/xml++.h"
45 
46 #include <gtkmm2ext/utils.h>
47 
48 #include "evoral/SMF.hpp"
49 
50 #include "ardour/audio_library.h"
51 #include "ardour/auditioner.h"
52 #include "ardour/audioregion.h"
53 #include "ardour/audiofilesource.h"
54 #include "ardour/midi_region.h"
55 #include "ardour/smf_source.h"
56 #include "ardour/region_factory.h"
57 #include "ardour/source_factory.h"
58 #include "ardour/session.h"
60 #include "ardour/srcfilesource.h"
61 
62 #include "ardour_ui.h"
63 #include "editing.h"
64 #include "gui_thread.h"
65 #include "prompter.h"
66 #include "sfdb_ui.h"
67 #include "editing.h"
68 #include "gain_meter.h"
69 #include "main_clock.h"
70 #include "public_editor.h"
71 #include "timers.h"
72 
74 
75 using namespace ARDOUR;
76 using namespace PBD;
77 using namespace std;
78 using namespace Gtk;
79 using namespace Gtkmm2ext;
80 using namespace Editing;
81 
82 using std::string;
83 
85 typedef TreeView::Selection::ListHandle_Path ListPath;
86 
87 static ImportMode
88 string2importmode (string str)
89 {
90  if (str == _("as new tracks")) {
91  return ImportAsTrack;
92  } else if (str == _("to selected tracks")) {
93  return ImportToTrack;
94  } else if (str == _("to region list")) {
95  return ImportAsRegion;
96  } else if (str == _("as new tape tracks")) {
97  return ImportAsTapeTrack;
98  }
99 
100  warning << string_compose (_("programming error: unknown import mode string %1"), str) << endmsg;
101 
102  return ImportAsTrack;
103 }
104 
105 static string
107 {
108  switch (mode) {
109  case ImportAsTrack:
110  return _("as new tracks");
111  case ImportToTrack:
112  return _("to selected tracks");
113  case ImportAsRegion:
114  return _("to region list");
115  case ImportAsTapeTrack:
116  return _("as new tape tracks");
117  }
118  abort(); /*NOTREACHED*/
119  return _("as new tracks");
120 }
121 
122 SoundFileBox::SoundFileBox (bool /*persistent*/)
123  : table (6, 2),
124  length_clock ("sfboxLengthClock", true, "", false, false, true, false),
125  timecode_clock ("sfboxTimecodeClock", true, "", false, false, false, false),
126  main_box (false, 6),
127  autoplay_btn (_("Auto-play")),
128  seek_slider(0,1000,1),
129  _seeking(false)
130 
131 {
132  set_name (X_("SoundFileBox"));
133  set_size_request (300, -1);
134 
135  preview_label.set_markup (_("<b>Sound File Information</b>"));
136 
137  border_frame.set_label_widget (preview_label);
138  border_frame.add (main_box);
139 
140  pack_start (border_frame, true, true);
141  set_border_width (6);
142 
143  main_box.set_border_width (6);
144 
145  length.set_text (_("Length:"));
146  length.set_alignment (1, 0.5);
147  timecode.set_text (_("Timestamp:"));
148  timecode.set_alignment (1, 0.5);
149  format.set_text (_("Format:"));
150  format.set_alignment (1, 0.5);
151  channels.set_text (_("Channels:"));
152  channels.set_alignment (1, 0.5);
153  samplerate.set_text (_("Sample rate:"));
154  samplerate.set_alignment (1, 0.5);
155 
156  preview_label.set_max_width_chars (50);
157  preview_label.set_ellipsize (Pango::ELLIPSIZE_END);
158 
159  format_text.set_max_width_chars (20);
160  format_text.set_ellipsize (Pango::ELLIPSIZE_END);
161  format_text.set_alignment (0, 1);
162 
163  table.set_col_spacings (6);
164  table.set_homogeneous (false);
165  table.set_row_spacings (6);
166 
167  table.attach (channels, 0, 1, 0, 1, FILL, FILL);
168  table.attach (samplerate, 0, 1, 1, 2, FILL, FILL);
169  table.attach (format, 0, 1, 2, 4, FILL, FILL);
170  table.attach (length, 0, 1, 4, 5, FILL, FILL);
171  table.attach (timecode, 0, 1, 5, 6, FILL, FILL);
172 
173  table.attach (channels_value, 1, 2, 0, 1, FILL, FILL);
174  table.attach (samplerate_value, 1, 2, 1, 2, FILL, FILL);
175  table.attach (format_text, 1, 2, 2, 4, FILL, FILL);
176  table.attach (length_clock, 1, 2, 4, 5, FILL, FILL);
177  table.attach (timecode_clock, 1, 2, 5, 6, FILL, FILL);
178 
179  length_clock.set_mode (ARDOUR_UI::instance()->secondary_clock->mode());
181 
182  main_box.pack_start (table, false, false);
183 
184  tags_entry.set_editable (true);
185  tags_entry.set_wrap_mode(Gtk::WRAP_WORD);
186  tags_entry.signal_focus_out_event().connect (sigc::mem_fun (*this, &SoundFileBox::tags_entry_left));
187 
188  Label* label = manage (new Label (_("Tags:")));
189  label->set_alignment (0.0f, 0.5f);
190  main_box.pack_start (*label, false, false);
191  main_box.pack_start (tags_entry, true, true);
192 
193  main_box.pack_start (bottom_box, false, false);
194 
195  play_btn.set_image (*(manage (new Image (Stock::MEDIA_PLAY, ICON_SIZE_BUTTON))));
196 // play_btn.set_label (_("Play"));
197 
198  stop_btn.set_image (*(manage (new Image (Stock::MEDIA_STOP, ICON_SIZE_BUTTON))));
199 // stop_btn.set_label (_("Stop"));
200 
201  bottom_box.set_homogeneous (false);
202  bottom_box.set_spacing (6);
203  bottom_box.pack_start(play_btn, true, true);
204  bottom_box.pack_start(stop_btn, true, true);
205  bottom_box.pack_start(autoplay_btn, false, false);
206 
207  seek_slider.set_draw_value(false);
208 
209  seek_slider.add_events(Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
210  seek_slider.signal_button_press_event().connect(sigc::mem_fun(*this, &SoundFileBox::seek_button_press), false);
211  seek_slider.signal_button_release_event().connect(sigc::mem_fun(*this, &SoundFileBox::seek_button_release), false);
212  main_box.pack_start (seek_slider, false, false);
213 
214  play_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::audition));
215  stop_btn.signal_clicked().connect (sigc::mem_fun (*this, &SoundFileBox::stop_audition));
216 
217  stop_btn.set_sensitive (false);
218 
219  channels_value.set_alignment (0.0f, 0.5f);
220  samplerate_value.set_alignment (0.0f, 0.5f);
221 }
222 
223 void
225 {
226  SessionHandlePtr::set_session (s);
227 
230 
231  if (!_session) {
232  play_btn.set_sensitive (false);
233  stop_btn.set_sensitive (false);
235  } else {
238  _session->the_auditioner()->AuditionProgress.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_progress, this, _1, _2), gui_context());
239  }
240 }
241 
242 void
244  stop_btn.set_sensitive (active);
245  seek_slider.set_sensitive (active);
246  if (!active) {
247  seek_slider.set_value(0);
248  }
249 }
250 
251 void
253  if (!_seeking) {
254  seek_slider.set_value( 1000.0 * pos / len);
255  seek_slider.set_sensitive (true);
256  }
257 }
258 
259 bool
261  _seeking = true;
262  return false; // pass on to slider
263 }
264 
265 bool
267  _seeking = false;
268  _session->the_auditioner()->seek_to_percent(seek_slider.get_value() / 10.0);
269  seek_slider.set_sensitive (false);
270  return false; // pass on to slider
271 }
272 
273 bool
274 SoundFileBox::setup_labels (const string& filename)
275 {
276  if (!path.empty()) {
277  // save existing tags
278  tags_changed ();
279  }
280 
281  path = filename;
282 
283  string error_msg;
284 
285  if (SMFSource::valid_midi_file (path)) {
286 
288  try {
290  SourceFactory::createExternal (DataType::MIDI, *_session,
291  path, 0, Source::Flag (0), false));
292  } catch (const std::exception& e) {
293  error << string_compose(_("Could not read file: %1 (%2)."),
294  path, e.what()) << endmsg;
295  }
296 
297  preview_label.set_markup (_("<b>Midi File Information</b>"));
298 
299  format_text.set_text ("MIDI");
300  samplerate_value.set_text ("-");
301  tags_entry.get_buffer()->set_text ("");
302  timecode_clock.set (0);
303  tags_entry.set_sensitive (false);
304 
305  if (ms) {
306  channels_value.set_text (to_string(ms->num_tracks(), std::dec));
308  } else {
309  channels_value.set_text ("");
310  length_clock.set (0);
311  }
312 
313  if (_session && ms) {
314  play_btn.set_sensitive (true);
315  } else {
316  play_btn.set_sensitive (false);
317  }
318 
319  return true;
320  }
321 
322  if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
323 
324  preview_label.set_markup (_("<b>Sound File Information</b>"));
325  format_text.set_text ("");
326  channels_value.set_text ("");
327  samplerate_value.set_text ("");
328  tags_entry.get_buffer()->set_text ("");
329 
330  length_clock.set (0);
331  timecode_clock.set (0);
332 
333  tags_entry.set_sensitive (false);
334  play_btn.set_sensitive (false);
335 
336  return false;
337  }
338 
339  preview_label.set_markup (string_compose ("<b>%1</b>", Glib::Markup::escape_text (Glib::path_get_basename (filename))));
340  std::string n = sf_info.format_name;
341  if (n.substr (0, 8) == X_("Format: ")) {
342  n = n.substr (8);
343  }
344  format_text.set_text (n);
345  channels_value.set_text (to_string (sf_info.channels, std::dec));
346 
348  samplerate.set_markup (string_compose ("<b>%1</b>", _("Sample rate:")));
349  samplerate_value.set_markup (string_compose (X_("<b>%1 Hz</b>"), sf_info.samplerate));
350  samplerate_value.set_name ("NewSessionSR1Label");
351  samplerate.set_name ("NewSessionSR1Label");
352  } else {
353  samplerate.set_text (_("Sample rate:"));
354  samplerate_value.set_text (string_compose (X_("%1 Hz"), sf_info.samplerate));
355  samplerate_value.set_name ("NewSessionSR2Label");
356  samplerate.set_name ("NewSessionSR2Label");
357  }
358 
359  framecnt_t const nfr = _session ? _session->nominal_frame_rate() : 25;
360  double src_coef = (double) nfr / sf_info.samplerate;
361 
362  length_clock.set (sf_info.length * src_coef + 0.5, true);
363  timecode_clock.set (sf_info.timecode * src_coef + 0.5, true);
364 
365  // this is a hack that is fixed in trunk, i think (august 26th, 2007)
366 
367  vector<string> tags = Library->get_tags (string ("//") + filename);
368 
369  stringstream tag_string;
370  for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
371  if (i != tags.begin()) {
372  tag_string << ", ";
373  }
374  tag_string << *i;
375  }
376  tags_entry.get_buffer()->set_text (tag_string.str());
377 
378  tags_entry.set_sensitive (true);
379  if (_session) {
380  play_btn.set_sensitive (true);
381  }
382 
383  return true;
384 }
385 
386 bool
388 {
389  return autoplay_btn.get_active();
390 }
391 
392 bool
394 {
395  audition ();
396  return false;
397 }
398 
399 void
401 {
402  if (!_session) {
403  return;
404  }
405 
407 
408  if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
409  warning << string_compose(_("Could not read file: %1 (%2)."), path, strerror(errno)) << endmsg;
410  return;
411  }
412 
414 
415  if (SMFSource::valid_midi_file (path)) {
416 
419  SourceFactory::createExternal (DataType::MIDI, *_session,
420  path, 0, Source::Flag (0), false));
421 
422  string rname = region_name_from_path (ms->path(), false);
423 
424  PropertyList plist;
425 
426  plist.add (ARDOUR::Properties::start, 0);
427  plist.add (ARDOUR::Properties::length, ms->length(ms->timeline_position()));
428  plist.add (ARDOUR::Properties::name, rname);
429  plist.add (ARDOUR::Properties::layer, 0);
430 
431  r = boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (boost::dynamic_pointer_cast<Source>(ms), plist, false));
432  assert(r);
433 
434  } else {
435 
436  SourceList srclist;
438  bool old_sbp = AudioSource::get_build_peakfiles ();
439 
440  /* don't even think of building peakfiles for these files */
441 
442  AudioSource::set_build_peakfiles (false);
443 
444  for (int n = 0; n < sf_info.channels; ++n) {
445  try {
447  SourceFactory::createExternal (DataType::AUDIO, *_session,
448  path, n,
450  if (afs->sample_rate() != _session->nominal_frame_rate()) {
452  srclist.push_back(sfs);
453  } else {
454  srclist.push_back(afs);
455  }
456 
457  } catch (failed_constructor& err) {
458  error << _("Could not access soundfile: ") << path << endmsg;
459  AudioSource::set_build_peakfiles (old_sbp);
460  return;
461  }
462  }
463 
464  AudioSource::set_build_peakfiles (old_sbp);
465 
466  if (srclist.empty()) {
467  return;
468  }
469 
470  afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
471  string rname = region_name_from_path (afs->path(), false);
472 
473  PropertyList plist;
474 
475  plist.add (ARDOUR::Properties::start, 0);
476  plist.add (ARDOUR::Properties::length, srclist[0]->length(srclist[0]->timeline_position()));
477  plist.add (ARDOUR::Properties::name, rname);
478  plist.add (ARDOUR::Properties::layer, 0);
479 
480  r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, plist, false));
481  }
482 
483  frameoffset_t audition_position = 0;
484  switch(_import_position) {
485  case ImportAtTimestamp:
486  audition_position = 0;
487  break;
488  case ImportAtPlayhead:
489  audition_position = _session->transport_frame();
490  break;
491  case ImportAtStart:
492  audition_position = _session->current_start_frame();
493  break;
494  case ImportAtEditPoint:
495  audition_position = PublicEditor::instance().get_preferred_edit_position ();
496  break;
497  }
498  r->set_position(audition_position);
499 
501 }
502 
503 void
505 {
506  if (_session) {
508  }
509 }
510 
511 bool
513 {
514  tags_changed ();
515  return false;
516 }
517 
518 void
520 {
521  string tag_string = tags_entry.get_buffer()->get_text ();
522 
523  if (tag_string.empty()) {
524  return;
525  }
526 
527  vector<string> tags;
528 
529  if (!PBD::tokenize (tag_string, string(",\n"), std::back_inserter (tags), true)) {
530  warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg;
531  return;
532  }
533 
534  save_tags (tags);
535 }
536 
537 void
538 SoundFileBox::save_tags (const vector<string>& tags)
539 {
540  Library->set_tags (string ("//") + path, tags);
541  Library->save_changes ();
542 }
543 
544 SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s, bool persistent)
545  : ArdourWindow (title)
546  , found_list (ListStore::create(found_list_columns))
547  , freesound_list (ListStore::create(freesound_list_columns))
548  , chooser (FILE_CHOOSER_ACTION_OPEN)
549  , preview (persistent)
550  , found_search_btn (_("Search"))
551  , found_list_view (found_list)
552  , freesound_search_btn (_("Search"))
553  , freesound_list_view (freesound_list)
554  , resetting_ourselves (false)
555  , matches (0)
556  , _status (0)
557  , _done (false)
558  , ok_button (Stock::OK)
559  , cancel_button (Stock::CANCEL)
560  , apply_button (Stock::APPLY)
561  , gm (0)
562 {
563 
564 #ifdef GTKOSX
565  chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops");
566  chooser.add_shortcut_folder_uri("file:///Library/Audio/Apple Loops");
567  chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files");
568  chooser.add_shortcut_folder_uri("file:///Volumes");
569 #endif
570 
571  //add the file chooser
572 
573  chooser.set_border_width (12);
574 
575  audio_and_midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun (*this, &SoundFileBrowser::on_audio_and_midi_filter));
576  audio_and_midi_filter.set_name (_("Audio and MIDI files"));
577 
578  audio_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_audio_filter));
579  audio_filter.set_name (_("Audio files"));
580 
581  midi_filter.add_custom (FILE_FILTER_FILENAME, sigc::mem_fun(*this, &SoundFileBrowser::on_midi_filter));
582  midi_filter.set_name (_("MIDI files"));
583 
584  matchall_filter.add_pattern ("*.*");
585  matchall_filter.set_name (_("All files"));
586 
587  chooser.add_filter (audio_and_midi_filter);
588  chooser.add_filter (audio_filter);
589  chooser.add_filter (midi_filter);
590  chooser.add_filter (matchall_filter);
591  chooser.set_select_multiple (true);
592  chooser.signal_update_preview().connect(sigc::mem_fun(*this, &SoundFileBrowser::update_preview));
593  chooser.signal_file_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
594 
595 #ifdef GTKOSX
596  /* some broken redraw behaviour - this is a bandaid */
597  chooser.signal_selection_changed().connect (mem_fun (chooser, &Widget::queue_draw));
598 #endif
599 
600  if (!persistent_folder.empty()) {
601  chooser.set_current_folder (persistent_folder);
602  }
603 
604  notebook.append_page (chooser, _("Browse Files"));
605 
606  hpacker.set_spacing (6);
607  hpacker.pack_start (notebook, true, true);
608  hpacker.pack_start (preview, false, false);
609 
610  vpacker.set_spacing (6);
611  vpacker.pack_start (hpacker, true, true);
612 
613  add (vpacker);
614 
615  //add tag search
616 
617  VBox* vbox;
618  HBox* hbox;
619 
620 
621  hbox = manage(new HBox);
622  hbox->pack_start (found_entry);
623  hbox->pack_start (found_search_btn);
624 
625  Gtk::ScrolledWindow *scroll = manage(new ScrolledWindow);
626  scroll->add(found_list_view);
627  scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
628 
629  vbox = manage(new VBox);
630  vbox->pack_start (*hbox, PACK_SHRINK);
631  vbox->pack_start (*scroll);
632 
633  found_list_view.append_column(_("Paths"), found_list_columns.pathname);
634 
635  found_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
636 
637  found_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::found_list_view_activated));
638 
639  found_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
640  found_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
641 
642  notebook.append_page (*vbox, _("Search Tags"));
643 
644  //add freesound search
645 
646  HBox* passbox;
647  Label* label;
648 
649  passbox = manage(new HBox);
650  passbox->set_spacing (6);
651 
652  label = manage (new Label);
653  label->set_text (_("Tags:"));
654  passbox->pack_start (*label, false, false);
655  passbox->pack_start (freesound_entry, true, true);
656 
657  label = manage (new Label);
658  label->set_text (_("Sort:"));
659  passbox->pack_start (*label, false, false);
660  passbox->pack_start (freesound_sort, false, false);
661  freesound_sort.clear_items();
662 
663  // Order of the following must correspond with enum sortMethod
664  // in sfdb_freesound_mootcher.h
665  freesound_sort.append_text(_("None"));
666  freesound_sort.append_text(_("Longest"));
667  freesound_sort.append_text(_("Shortest"));
668  freesound_sort.append_text(_("Newest"));
669  freesound_sort.append_text(_("Oldest"));
670  freesound_sort.append_text(_("Most downloaded"));
671  freesound_sort.append_text(_("Least downloaded"));
672  freesound_sort.append_text(_("Highest rated"));
673  freesound_sort.append_text(_("Lowest rated"));
674  freesound_sort.set_active(0);
675 
676  passbox->pack_start (freesound_search_btn, false, false);
677  passbox->pack_start (freesound_more_btn, false, false);
678  freesound_more_btn.set_label(_("More"));
679  freesound_more_btn.set_sensitive(false);
680 
681  passbox->pack_start (freesound_similar_btn, false, false);
682  freesound_similar_btn.set_label(_("Similar"));
683  freesound_similar_btn.set_sensitive(false);
684 
685  scroll = manage(new ScrolledWindow);
686  scroll->add(freesound_list_view);
687  scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
688 
689  vbox = manage(new VBox);
690  vbox->set_spacing (3);
691  vbox->pack_start (*passbox, PACK_SHRINK);
692  vbox->pack_start (*scroll);
693 
694  freesound_list_view.append_column(_("ID") , freesound_list_columns.id);
695  freesound_list_view.append_column(_("Filename"), freesound_list_columns.filename);
696  // freesound_list_view.append_column(_("URI") , freesound_list_columns.uri);
697  freesound_list_view.append_column(_("Duration"), freesound_list_columns.duration);
698  freesound_list_view.append_column(_("Size"), freesound_list_columns.filesize);
699  freesound_list_view.append_column(_("Samplerate"), freesound_list_columns.smplrate);
700  freesound_list_view.append_column(_("License"), freesound_list_columns.license);
701  freesound_list_view.get_column(0)->set_alignment(0.5);
702  freesound_list_view.get_column(1)->set_expand(true); // filename
703  freesound_list_view.get_column(1)->set_resizable(true); // filename
704  freesound_list_view.get_column(2)->set_alignment(0.5);
705  freesound_list_view.get_column(3)->set_alignment(0.5);
706  freesound_list_view.get_column(4)->set_alignment(0.5);
707  freesound_list_view.get_column(5)->set_alignment(0.5);
708 
709  freesound_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_list_view_selected));
710  freesound_list_view.set_tooltip_column(1);
711 
712  freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
713  freesound_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
714  freesound_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
715  freesound_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
716  freesound_more_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_more_clicked));
717  freesound_similar_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_similar_clicked));
718  notebook.append_page (*vbox, _("Search Freesound"));
719 
720  notebook.set_size_request (500, -1);
721  notebook.signal_switch_page().connect (sigc::hide_return (sigc::hide (sigc::hide (sigc::mem_fun (*this, &SoundFileBrowser::reset_options)))));
722 
723  set_session (s);
724 
725  Gtk::HButtonBox* button_box = manage (new HButtonBox);
726 
727  button_box->set_layout (BUTTONBOX_END);
728  button_box->pack_start (cancel_button, false, false);
729  cancel_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_CANCEL));
730  if (persistent) {
731  button_box->pack_start (apply_button, false, false);
732  apply_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_APPLY));
733  }
734 
735  button_box->pack_start (ok_button, false, false);
736  ok_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SoundFileBrowser::do_something), RESPONSE_OK));
737 
738  Gtkmm2ext::UI::instance()->set_tip (ok_button, _("Press to import selected files and close this window"));
739  Gtkmm2ext::UI::instance()->set_tip (apply_button, _("Press to import selected files and leave this window open"));
740  Gtkmm2ext::UI::instance()->set_tip (cancel_button, _("Press to close this window without importing any files"));
741 
742  vpacker.pack_end (*button_box, false, false);
743 
744  set_wmclass (X_("import"), PROGRAM_NAME);
745 }
746 
748 {
749  persistent_folder = chooser.get_current_folder();
750 }
751 
752 int
754 {
755  set_modal (true);
756  show_all ();
757  present ();
758 
759  _done = false;
760 
761  while (!_done) {
762  gtk_main_iteration ();
763  }
764 
765  return _status;
766 }
767 
768 void
770 {
771  ok_button.set_sensitive (yn);
772  apply_button.set_sensitive (yn);
773 }
774 
775 void
777 {
778  _done = true;
779  _status = action;
780 }
781 
782 void
784 {
785  ArdourWindow::on_show ();
786  start_metering ();
787 }
788 
789 void
791 {
792  chooser.unselect_all ();
793  found_list_view.get_selection()->unselect_all ();
794 }
795 
796 void
798 {
799  preview.audition ();
800 }
801 
802 void
803 SoundFileBrowser::found_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
804 {
805  preview.audition ();
806 }
807 
808 void
809 SoundFileBrowser::freesound_list_view_activated (const TreeModel::Path&, TreeViewColumn*)
810 {
811  preview.audition ();
812 }
813 
814 void
816 {
818  preview.set_session (s);
819 
820  if (_session) {
821  add_gain_meter ();
822  } else {
824  }
825 }
826 
827 void
829 {
830  delete gm;
831 
832  gm = new GainMeter (_session, 250);
833 
835 
836  gm->set_controls (r, r->shared_peak_meter(), r->amp());
837  gm->set_fader_name (X_("GainFader"));
838 
839  meter_packer.set_border_width (12);
840  meter_packer.pack_start (*gm, false, true);
841  hpacker.pack_end (meter_packer, false, false);
842  meter_packer.show_all ();
843  start_metering ();
844 }
845 
846 void
848 {
849  if (gm) {
850  meter_packer.remove (*gm);
851  hpacker.remove (meter_packer);
852  delete gm;
853  gm = 0;
854  }
855 }
856 
857 void
859 {
861 }
862 
863 void
865 {
866  metering_connection.disconnect();
867 }
868 
869 void
871 {
872  if (is_mapped () && _session && gm) {
873  gm->update_meters ();
874  }
875 }
876 
877 bool
878 SoundFileBrowser::on_audio_filter (const FileFilter::Info& filter_info)
879 {
880  return AudioFileSource::safe_audio_file_extension (filter_info.filename);
881 }
882 
883 bool
884 SoundFileBrowser::on_midi_filter (const FileFilter::Info& filter_info)
885 {
886  return SMFSource::safe_midi_file_extension (filter_info.filename);
887 }
888 
889 bool
890 SoundFileBrowser::on_audio_and_midi_filter (const FileFilter::Info& filter_info)
891 {
892  return on_audio_filter (filter_info) || on_midi_filter (filter_info);
893 }
894 
895 void
897 {
898  if (preview.setup_labels (chooser.get_preview_filename())) {
899  if (preview.autoplay()) {
900  Glib::signal_idle().connect (sigc::mem_fun (preview, &SoundFileBox::audition_oneshot));
901  }
902  }
903 }
904 
905 void
907 {
908  if (!reset_options ()) {
909  set_action_sensitive (false);
910  } else {
911  string file;
912 
913  ListPath rows = found_list_view.get_selection()->get_selected_rows ();
914 
915  if (!rows.empty()) {
916  TreeIter iter = found_list->get_iter(*rows.begin());
917  file = (*iter)[found_list_columns.pathname];
918  chooser.set_filename (file);
919  set_action_sensitive (true);
920  } else {
921  set_action_sensitive (false);
922  }
923 
924  preview.setup_labels (file);
925  }
926 }
927 
928 void
930 {
931  string tag_string = found_entry.get_text ();
932 
933  vector<string> tags;
934 
935  if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
936  warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
937  return;
938  }
939 
940  vector<string> results;
941  Library->search_members_and (results, tags);
942 
943  found_list->clear();
944  for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
945  TreeModel::iterator new_row = found_list->append();
946  TreeModel::Row row = *new_row;
947  string path = Glib::filename_from_uri (string ("file:") + *i);
948  row[found_list_columns.pathname] = path;
949  }
950 }
951 
952 
953 std::string
955 {
956 
957  Mootcher *mootcher = new Mootcher;
958  std::string file;
959 
960  string id = (*iter)[freesound_list_columns.id];
961  string uri = (*iter)[freesound_list_columns.uri];
962  string ofn = (*iter)[freesound_list_columns.filename];
963 
964  if (mootcher->checkAudioFile(ofn, id)) {
965  // file already exists, no need to download it again
966  file = mootcher->audioFileName;
967  delete mootcher;
968  (*iter)[freesound_list_columns.started] = false;
969  return file;
970  }
971  if (!(*iter)[freesound_list_columns.started]) {
972  // start downloading the sound file
973  (*iter)[freesound_list_columns.started] = true;
974  mootcher->fetchAudioFile(ofn, id, uri, this);
975  }
976  return "";
977 }
978 
979 void
981 {
982 
983  if (!reset_options ()) {
984  set_action_sensitive (false);
985  } else {
986  std::string file;
987  ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
988  for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
989  file = freesound_get_audio_file (freesound_list->get_iter(*i));
990  }
991 
992  switch (rows.size()) {
993  case 0:
994  // nothing selected
995  freesound_similar_btn.set_sensitive(false);
996  set_action_sensitive (false);
997  break;
998  case 1:
999  // exactly one item selected
1000  if (file != "") {
1001  // file exists on disk already
1002  chooser.set_filename (file);
1003  preview.setup_labels (file);
1004  set_action_sensitive (true);
1005  }
1006  freesound_similar_btn.set_sensitive(true);
1007  break;
1008  default:
1009  // multiple items selected
1010  preview.setup_labels ("");
1011  freesound_similar_btn.set_sensitive(false);
1012  break;
1013  }
1014 
1015  }
1016 }
1017 
1018 void
1019 SoundFileBrowser::refresh_display(std::string ID, std::string file)
1020 {
1021  // called when the mootcher has finished downloading a file
1022  ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1023  if (rows.size() == 1) {
1024  // there's a single item selected in the freesound list
1025  //XXX make a function to be used to construct the actual file name both here and in the mootcher
1026  Gtk::TreeIter row = freesound_list->get_iter(*rows.begin());
1027  std::string selected_ID = (*row)[freesound_list_columns.id];
1028  if (ID == selected_ID) {
1029  // the selected item in the freesound list is the item that has just finished downloading
1030  chooser.set_filename(file);
1031  preview.setup_labels (file);
1032  set_action_sensitive (true);
1033  }
1034  }
1035 }
1036 
1037 void
1039 {
1040  freesound_page = 1;
1041  freesound_list->clear();
1042  matches = 0;
1043  freesound_search();
1044 }
1045 
1046 void
1048 {
1049  char row_path[21];
1050  freesound_page++;
1051  freesound_search();
1052  snprintf(row_path, 21, "%d", (freesound_page - 1) * 100);
1053  freesound_list_view.scroll_to_row(Gtk::TreePath(row_path), 0);
1054 }
1055 
1056 void
1058 {
1059  ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1060  if (rows.size() == 1) {
1061  Mootcher mootcher;
1062  string id;
1063  Gtk::TreeIter iter = freesound_list->get_iter(*rows.begin());
1064  id = (*iter)[freesound_list_columns.id];
1065  freesound_list->clear();
1066 
1067  GdkCursor *prev_cursor;
1068  prev_cursor = gdk_window_get_cursor (get_window()->gobj());
1069  gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
1070  gdk_flush();
1071 
1072  std::string theString = mootcher.searchSimilar(id);
1073 
1074  gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
1075  handle_freesound_results(theString);
1076  }
1077 }
1078 
1079 void
1081 {
1082  Mootcher mootcher;
1083 
1084  string search_string = freesound_entry.get_text ();
1085  enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
1086 
1087  GdkCursor *prev_cursor;
1088  prev_cursor = gdk_window_get_cursor (get_window()->gobj());
1089  gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
1090  gdk_flush();
1091 
1092  std::string theString = mootcher.searchText(
1093  search_string,
1095 #ifdef GTKOSX
1096  "", // OSX eats anything incl mp3
1097 #else
1098  "type:wav OR type:aiff OR type:flac OR type:aif OR type:ogg OR type:oga",
1099 #endif
1100  sort_method
1101  );
1102 
1103  gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
1104  handle_freesound_results(theString);
1105 }
1106 
1107 void
1109  XMLTree doc;
1110  doc.read_buffer( theString );
1111  XMLNode *root = doc.root();
1112 
1113  if (!root) {
1114  error << "no root XML node!" << endmsg;
1115  return;
1116  }
1117 
1118  if ( strcmp(root->name().c_str(), "response") != 0) {
1119  error << string_compose ("root node name == %1 != \"response\"", root->name()) << endmsg;
1120  return;
1121  }
1122 
1123  // find out how many pages are available to search
1124  int freesound_n_pages = 1;
1125  XMLNode *res = root->child("num_pages");
1126  if (res) {
1127  string result = res->child("text")->content();
1128  freesound_n_pages = atoi(result);
1129  }
1130 
1131  int more_pages = freesound_n_pages - freesound_page;
1132 
1133  if (more_pages > 0) {
1134  freesound_more_btn.set_sensitive(true);
1135  freesound_more_btn.set_tooltip_text(string_compose(P_(
1136  "%1 more page of 100 results available",
1137  "%1 more pages of 100 results available",
1138  more_pages), more_pages));
1139  } else {
1140  freesound_more_btn.set_sensitive(false);
1141  freesound_more_btn.set_tooltip_text(_("No more results available"));
1142  }
1143 
1144  XMLNode *sounds_root = root->child("sounds");
1145  if (!sounds_root) {
1146  error << "no child node \"sounds\" found!" << endmsg;
1147  return;
1148  }
1149 
1150  XMLNodeList sounds = sounds_root->children();
1151  if (sounds.size() == 0) {
1152  /* nothing found */
1153  return;
1154  }
1155 
1156  XMLNodeConstIterator niter;
1157  XMLNode *node;
1158  for (niter = sounds.begin(); niter != sounds.end(); ++niter) {
1159  node = *niter;
1160  if( strcmp( node->name().c_str(), "resource") != 0 ) {
1161  error << string_compose ("node->name()=%1 != \"resource\"", node->name()) << endmsg;
1162  break;
1163  }
1164 
1165  // node->dump(cerr, "node:");
1166 
1167 
1168  XMLNode *id_node = node->child ("id");
1169  XMLNode *uri_node = node->child ("serve");
1170  XMLNode *ofn_node = node->child ("original_filename");
1171  XMLNode *dur_node = node->child ("duration");
1172  XMLNode *siz_node = node->child ("filesize");
1173  XMLNode *srt_node = node->child ("samplerate");
1174  XMLNode *lic_node = node->child ("license");
1175 
1176  if (id_node && uri_node && ofn_node && dur_node && siz_node && srt_node) {
1177 
1178  std::string id = id_node->child("text")->content();
1179  std::string uri = uri_node->child("text")->content();
1180  std::string ofn = ofn_node->child("text")->content();
1181  std::string dur = dur_node->child("text")->content();
1182  std::string siz = siz_node->child("text")->content();
1183  std::string srt = srt_node->child("text")->content();
1184  std::string lic = lic_node->child("text")->content();
1185 
1186  std::string r;
1187  // cerr << "id=" << id << ",uri=" << uri << ",ofn=" << ofn << ",dur=" << dur << endl;
1188 
1189  double duration_seconds = atof(dur);
1190  double h, m, s;
1191  char duration_hhmmss[16];
1192  if (duration_seconds >= 99 * 60 * 60) {
1193  strcpy(duration_hhmmss, ">99h");
1194  } else {
1195  s = modf(duration_seconds/60, &m) * 60;
1196  m = modf(m/60, &h) * 60;
1197  sprintf(duration_hhmmss, "%02.fh:%02.fm:%04.1fs",
1198  h, m, s
1199  );
1200  }
1201 
1202  double size_bytes = atof(siz);
1203  char bsize[32];
1204  if (size_bytes < 1000) {
1205  sprintf(bsize, "%.0f %s", size_bytes, _("B"));
1206  } else if (size_bytes < 1000000 ) {
1207  sprintf(bsize, "%.1f %s", size_bytes / 1000.0, _("kB"));
1208  } else if (size_bytes < 10000000) {
1209  sprintf(bsize, "%.1f %s", size_bytes / 1000000.0, _("MB"));
1210  } else if (size_bytes < 1000000000) {
1211  sprintf(bsize, "%.2f %s", size_bytes / 1000000.0, _("MB"));
1212  } else {
1213  sprintf(bsize, "%.2f %s", size_bytes / 1000000000.0, _("GB"));
1214  }
1215 
1216  /* see http://www.freesound.org/help/faq/#licenses */
1217  char shortlicense[64];
1218  if(!lic.compare(0, 42, "http://creativecommons.org/licenses/by-nc/")){
1219  sprintf(shortlicense, "CC-BY-NC");
1220  } else if(!lic.compare(0, 39, "http://creativecommons.org/licenses/by/")) {
1221  sprintf(shortlicense, "CC-BY");
1222  } else if(!lic.compare("http://creativecommons.org/licenses/sampling+/1.0/")) {
1223  sprintf(shortlicense, "sampling+");
1224  } else if(!lic.compare(0, 40, "http://creativecommons.org/publicdomain/")) {
1225  sprintf(shortlicense, "PD");
1226  } else {
1227  snprintf(shortlicense, 64, "%s", lic.c_str());
1228  shortlicense[63]= '\0';
1229  }
1230 
1231  TreeModel::iterator new_row = freesound_list->append();
1232  TreeModel::Row row = *new_row;
1233 
1234  row[freesound_list_columns.id ] = id;
1235  row[freesound_list_columns.uri ] = uri;
1236  row[freesound_list_columns.filename] = ofn;
1237  row[freesound_list_columns.duration] = duration_hhmmss;
1238  row[freesound_list_columns.filesize] = bsize;
1239  row[freesound_list_columns.smplrate] = srt;
1240  row[freesound_list_columns.license ] = shortlicense;
1241  matches++;
1242  }
1243  }
1244 }
1245 
1246 vector<string>
1248 {
1249  vector<string> results;
1250 
1251  int n = notebook.get_current_page ();
1252 
1253  if (n == 0) {
1254  vector<string> filenames = chooser.get_filenames();
1255  vector<string>::iterator i;
1256 
1257  for (i = filenames.begin(); i != filenames.end(); ++i) {
1258  struct stat buf;
1259  if ((!stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
1260  results.push_back (*i);
1261  }
1262  }
1263 
1264  } else if (n == 1) {
1265 
1266  ListPath rows = found_list_view.get_selection()->get_selected_rows ();
1267  for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1268  TreeIter iter = found_list->get_iter(*i);
1269  string str = (*iter)[found_list_columns.pathname];
1270 
1271  results.push_back (str);
1272  }
1273  } else {
1274  ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
1275  for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
1276  string str = freesound_get_audio_file (freesound_list->get_iter(*i));
1277  if (str != "") {
1278  results.push_back (str);
1279  }
1280  }
1281  }
1282 
1283  return results;
1284 }
1285 
1286 void
1288 {
1289  if (!resetting_ourselves) {
1290  (void) reset_options ();
1291  }
1292 }
1293 
1294 bool
1296 {
1297  vector<string> paths = get_paths ();
1298 
1299  if (paths.empty()) {
1300 
1301  channel_combo.set_sensitive (false);
1302  action_combo.set_sensitive (false);
1303  where_combo.set_sensitive (false);
1304  copy_files_btn.set_active (true);
1305  copy_files_btn.set_sensitive (false);
1306 
1307  return false;
1308 
1309  } else {
1310 
1311  channel_combo.set_sensitive (true);
1312  action_combo.set_sensitive (true);
1313  where_combo.set_sensitive (true);
1314 
1315  /* if we get through this function successfully, this may be
1316  reset at the end, once we know if we can use hard links
1317  to do embedding (or if we are importing a MIDI file).
1318  */
1319 
1320  if (ARDOUR_UI::config()->get_only_copy_imported_files()) {
1321  copy_files_btn.set_sensitive (false);
1322  } else {
1323  copy_files_btn.set_sensitive (false);
1324  }
1325  }
1326 
1327  bool same_size;
1328  bool src_needed;
1329  bool selection_includes_multichannel;
1330  bool selection_can_be_embedded_with_links = check_link_status (_session, paths);
1331  ImportMode mode;
1332 
1333  /* See if we are thinking about importing any MIDI files */
1334  vector<string>::iterator i = paths.begin ();
1335  while (i != paths.end() && SMFSource::valid_midi_file (*i) == false) {
1336  ++i;
1337  }
1338  bool const have_a_midi_file = (i != paths.end ());
1339 
1340  if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
1341  Glib::signal_idle().connect (sigc::mem_fun (*this, &SoundFileOmega::bad_file_message));
1342  return false;
1343  }
1344 
1345  string existing_choice;
1346  vector<string> action_strings;
1347 
1348  resetting_ourselves = true;
1349 
1350  if (chooser.get_filter() == &audio_filter) {
1351 
1352  /* AUDIO */
1353 
1354  if (selected_audio_track_cnt > 0) {
1355  if (channel_combo.get_active_text().length()) {
1357 
1358  switch (id) {
1359  case Editing::ImportDistinctFiles:
1360  if (selected_audio_track_cnt == paths.size()) {
1361  action_strings.push_back (importmode2string (ImportToTrack));
1362  }
1363  break;
1364 
1365  case Editing::ImportDistinctChannels:
1366  /* XXX it would be nice to allow channel-per-selected track
1367  but its too hard we don't want to deal with all the
1368  different per-file + per-track channel configurations.
1369  */
1370  break;
1371 
1372  default:
1373  action_strings.push_back (importmode2string (ImportToTrack));
1374  break;
1375  }
1376  }
1377  }
1378 
1379  } else {
1380 
1381  /* MIDI ONLY */
1382 
1383  if (selected_midi_track_cnt > 0) {
1384  action_strings.push_back (importmode2string (ImportToTrack));
1385  }
1386  }
1387 
1388  action_strings.push_back (importmode2string (ImportAsTrack));
1389  action_strings.push_back (importmode2string (ImportAsRegion));
1390  action_strings.push_back (importmode2string (ImportAsTapeTrack));
1391 
1392  existing_choice = action_combo.get_active_text();
1393 
1394  set_popdown_strings (action_combo, action_strings);
1395 
1396  /* preserve any existing choice, if possible */
1397 
1398 
1399  if (existing_choice.length()) {
1400  vector<string>::iterator x;
1401  for (x = action_strings.begin(); x != action_strings.end(); ++x) {
1402  if (*x == existing_choice) {
1403  action_combo.set_active_text (existing_choice);
1404  break;
1405  }
1406  }
1407  if (x == action_strings.end()) {
1408  action_combo.set_active_text (action_strings.front());
1409  }
1410  } else {
1411  action_combo.set_active_text (action_strings.front());
1412  }
1413 
1414  resetting_ourselves = false;
1415 
1416  if ((mode = get_mode()) == ImportAsRegion) {
1417  where_combo.set_sensitive (false);
1418  } else {
1419  where_combo.set_sensitive (true);
1420  }
1421 
1422  vector<string> channel_strings;
1423 
1424  if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
1425  channel_strings.push_back (_("one track per file"));
1426 
1427  if (selection_includes_multichannel) {
1428  channel_strings.push_back (_("one track per channel"));
1429  }
1430 
1431  if (paths.size() > 1) {
1432  /* tape tracks are a single region per track, so we cannot
1433  sequence multiple files.
1434  */
1435  if (mode != ImportAsTapeTrack) {
1436  channel_strings.push_back (_("sequence files"));
1437  }
1438  if (same_size) {
1439  channel_strings.push_back (_("all files in one track"));
1440  channel_strings.push_back (_("merge files"));
1441  }
1442 
1443  }
1444 
1445  } else {
1446  channel_strings.push_back (_("one region per file"));
1447 
1448  if (selection_includes_multichannel) {
1449  channel_strings.push_back (_("one region per channel"));
1450  }
1451 
1452  if (paths.size() > 1) {
1453  if (same_size) {
1454  channel_strings.push_back (_("all files in one region"));
1455  }
1456  }
1457  }
1458 
1459  resetting_ourselves = true;
1460 
1461  existing_choice = channel_combo.get_active_text();
1462 
1463  set_popdown_strings (channel_combo, channel_strings);
1464 
1465  /* preserve any existing choice, if possible */
1466 
1467  if (existing_choice.length()) {
1468  vector<string>::iterator x;
1469  for (x = channel_strings.begin(); x != channel_strings.end(); ++x) {
1470  if (*x == existing_choice) {
1471  channel_combo.set_active_text (existing_choice);
1472  break;
1473  }
1474  }
1475  if (x == channel_strings.end()) {
1476  channel_combo.set_active_text (channel_strings.front());
1477  }
1478  } else {
1479  channel_combo.set_active_text (channel_strings.front());
1480  }
1481 
1482  resetting_ourselves = false;
1483 
1484  if (src_needed) {
1485  src_combo.set_sensitive (true);
1486  } else {
1487  src_combo.set_sensitive (false);
1488  }
1489 
1490  /* We must copy MIDI files or those from Freesound
1491  * or any file if we are under nsm control */
1492  bool const must_copy = _session->get_nsm_state() || have_a_midi_file || notebook.get_current_page() == 2;
1493 
1494  if (ARDOUR_UI::config()->get_only_copy_imported_files()) {
1495 
1496  if (selection_can_be_embedded_with_links && !must_copy) {
1497  copy_files_btn.set_sensitive (true);
1498  } else {
1499  if (must_copy) {
1500  copy_files_btn.set_active (true);
1501  }
1502  copy_files_btn.set_sensitive (false);
1503  }
1504 
1505  } else {
1506 
1507  if (must_copy) {
1508  copy_files_btn.set_active (true);
1509  }
1510  copy_files_btn.set_sensitive (!must_copy);
1511  }
1512 
1513  return true;
1514 }
1515 
1516 
1517 bool
1519 {
1520  MessageDialog msg (*this,
1521  string_compose (_("One or more of the selected files\ncannot be used by %1"), PROGRAM_NAME),
1522  true,
1523  Gtk::MESSAGE_INFO,
1524  Gtk::BUTTONS_OK);
1525  msg.run ();
1526  resetting_ourselves = true;
1527  chooser.unselect_uri (chooser.get_preview_uri());
1528  resetting_ourselves = false;
1529 
1530  return false;
1531 }
1532 
1533 bool
1534 SoundFileOmega::check_info (const vector<string>& paths, bool& same_size, bool& src_needed, bool& multichannel)
1535 {
1537  framepos_t sz = 0;
1538  bool err = false;
1539  string errmsg;
1540 
1541  same_size = true;
1542  src_needed = false;
1543  multichannel = false;
1544 
1545  for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1546 
1547  if (AudioFileSource::get_soundfile_info (*i, info, errmsg)) {
1548  if (info.channels > 1) {
1549  multichannel = true;
1550  }
1551  if (sz == 0) {
1552  sz = info.length;
1553  } else {
1554  if (sz != info.length) {
1555  same_size = false;
1556  }
1557  }
1558 
1559  if (info.samplerate != _session->frame_rate()) {
1560  src_needed = true;
1561  }
1562 
1563  } else if (SMFSource::valid_midi_file (*i)) {
1564 
1565  Evoral::SMF reader;
1566  reader.open(*i);
1567  if (reader.num_tracks() > 1) {
1568  multichannel = true; // "channel" == track here...
1569  }
1570 
1571  /* XXX we need err = true handling here in case
1572  we can't check the file
1573  */
1574 
1575  } else {
1576  err = true;
1577  }
1578  }
1579 
1580  return err;
1581 }
1582 
1583 
1584 bool
1585 SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths)
1586 {
1587 #ifdef PLATFORM_WINDOWS
1588  return false;
1589 #else
1590  std::string tmpdir(Glib::build_filename (s->session_directory().sound_path(), "linktest"));
1591  bool ret = false;
1592 
1593  if (mkdir (tmpdir.c_str(), 0744)) {
1594  if (errno != EEXIST) {
1595  return false;
1596  }
1597  }
1598 
1599  for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1600 
1601  char tmpc[PATH_MAX+1];
1602 
1603  snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
1604 
1605  /* can we link ? */
1606 
1607  if (link ((*i).c_str(), tmpc)) {
1608  goto out;
1609  }
1610 
1611  ::g_unlink (tmpc);
1612  }
1613 
1614  ret = true;
1615 
1616  out:
1617  rmdir (tmpdir.c_str());
1618  return ret;
1619 #endif
1620 }
1621 
1623  : SoundFileBrowser (title, s, false)
1624 {
1625  chooser.set_select_multiple (false);
1626  found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1627  freesound_list_view.get_selection()->set_mode (SELECTION_SINGLE);
1628 }
1629 
1630 void
1632 {
1633  ArdourWindow::on_hide();
1634  stop_metering ();
1635 
1636  if (_session) {
1638  }
1639 }
1640 
1641 string
1643 {
1644  vector<string> paths;
1645 
1646  paths = get_paths ();
1647 
1648  if (paths.empty()) {
1649  return string ();
1650  }
1651 
1652  if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
1653  return string();
1654  }
1655 
1656  return paths.front();
1657 }
1658 
1660  uint32_t selected_audio_tracks,
1661  uint32_t selected_midi_tracks,
1662  bool persistent,
1663  Editing::ImportMode mode_hint)
1664  : SoundFileBrowser (title, s, persistent)
1665  , copy_files_btn ( _("Copy files to session"))
1666  , selected_audio_track_cnt (selected_audio_tracks)
1667  , selected_midi_track_cnt (selected_midi_tracks)
1668 {
1669  VBox* vbox;
1670  HBox* hbox;
1671  vector<string> str;
1672 
1673  set_size_request (-1, 450);
1674 
1675  block_two.set_border_width (12);
1676  block_three.set_border_width (12);
1677  block_four.set_border_width (12);
1678 
1679  options.set_spacing (12);
1680 
1681  str.clear ();
1682  str.push_back (_("file timestamp"));
1683  str.push_back (_("edit point"));
1684  str.push_back (_("playhead"));
1685  str.push_back (_("session start"));
1687  where_combo.set_active_text (str.front());
1688  where_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::where_combo_changed));
1689 
1690  Label* l = manage (new Label);
1691  l->set_markup (_("<b>Add files as ...</b>"));
1692 
1693  vbox = manage (new VBox);
1694  vbox->set_border_width (12);
1695  vbox->set_spacing (6);
1696  vbox->pack_start (*l, false, false);
1697  vbox->pack_start (action_combo, false, false);
1698  hbox = manage (new HBox);
1699  hbox->pack_start (*vbox, false, false);
1700  options.pack_start (*hbox, false, false);
1701 
1702  /* dummy entry for action combo so that it doesn't look odd if we
1703  come up with no tracks selected.
1704  */
1705 
1706  str.clear ();
1707  str.push_back (importmode2string (mode_hint));
1709  action_combo.set_active_text (str.front());
1710  action_combo.set_sensitive (false);
1711 
1712  l = manage (new Label);
1713  l->set_markup (_("<b>Insert at</b>"));
1714 
1715  vbox = manage (new VBox);
1716  vbox->set_border_width (12);
1717  vbox->set_spacing (6);
1718  vbox->pack_start (*l, false, false);
1719  vbox->pack_start (where_combo, false, false);
1720  hbox = manage (new HBox);
1721  hbox->pack_start (*vbox, false, false);
1722  options.pack_start (*hbox, false, false);
1723 
1724 
1725  l = manage (new Label);
1726  l->set_markup (_("<b>Mapping</b>"));
1727 
1728  vbox = manage (new VBox);
1729  vbox->set_border_width (12);
1730  vbox->set_spacing (6);
1731  vbox->pack_start (*l, false, false);
1732  vbox->pack_start (channel_combo, false, false);
1733  hbox = manage (new HBox);
1734  hbox->pack_start (*vbox, false, false);
1735  options.pack_start (*hbox, false, false);
1736 
1737  str.clear ();
1738  str.push_back (_("one track per file"));
1740  channel_combo.set_active_text (str.front());
1741  channel_combo.set_sensitive (false);
1742 
1743  l = manage (new Label);
1744  l->set_markup (_("<b>Conversion quality</b>"));
1745 
1746  vbox = manage (new VBox);
1747  vbox->set_border_width (12);
1748  vbox->set_spacing (6);
1749  vbox->pack_start (*l, false, false);
1750  vbox->pack_start (src_combo, false, false);
1751  hbox = manage (new HBox);
1752  hbox->pack_start (*vbox, false, false);
1753  options.pack_start (*hbox, false, false);
1754 
1755  l = manage (new Label);
1756  l->set_markup (_("<b>Instrument</b>"));
1757 
1758  vbox = manage (new VBox);
1759  vbox->set_border_width (12);
1760  vbox->set_spacing (6);
1761  vbox->pack_start (*l, false, false);
1762  vbox->pack_start (instrument_combo, false, false);
1763  hbox = manage (new HBox);
1764  hbox->pack_start (*vbox, false, false);
1765  options.pack_start (*hbox, false, false);
1766 
1767  str.clear ();
1768  str.push_back (_("Best"));
1769  str.push_back (_("Good"));
1770  str.push_back (_("Quick"));
1771  str.push_back (_("Fast"));
1772  str.push_back (_("Fastest"));
1773 
1775  src_combo.set_active_text (str.front());
1776  src_combo.set_sensitive (false);
1777  src_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::src_combo_changed));
1778 
1779  reset_options ();
1780 
1781  action_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1782  channel_combo.signal_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::reset_options_noret));
1783 
1784  copy_files_btn.set_active (true);
1785 
1786  Gtk::Label* copy_label = dynamic_cast<Gtk::Label*>(copy_files_btn.get_child());
1787 
1788  if (copy_label) {
1789  copy_label->set_size_request (175, -1);
1790  copy_label->set_line_wrap (true);
1791  }
1792 
1793  block_four.pack_start (copy_files_btn, false, false);
1794 
1795  options.pack_start (block_four, false, false);
1796 
1797  vpacker.pack_start (options, false, false);
1798 
1799  /* setup disposition map */
1800 
1801  disposition_map.insert (pair<string,ImportDisposition>(_("one track per file"), ImportDistinctFiles));
1802  disposition_map.insert (pair<string,ImportDisposition>(_("one track per channel"), ImportDistinctChannels));
1803  disposition_map.insert (pair<string,ImportDisposition>(_("merge files"), ImportMergeFiles));
1804  disposition_map.insert (pair<string,ImportDisposition>(_("sequence files"), ImportSerializeFiles));
1805 
1806  disposition_map.insert (pair<string,ImportDisposition>(_("one region per file"), ImportDistinctFiles));
1807  disposition_map.insert (pair<string,ImportDisposition>(_("one region per channel"), ImportDistinctChannels));
1808  disposition_map.insert (pair<string,ImportDisposition>(_("all files in one region"), ImportMergeFiles));
1809  disposition_map.insert (pair<string,ImportDisposition>(_("all files in one track"), ImportMergeFiles));
1810 
1811  chooser.signal_selection_changed().connect (sigc::mem_fun (*this, &SoundFileOmega::file_selection_changed));
1812 
1813  /* set size requests for a couple of combos to allow them to display the longest text
1814  they will ever be asked to display. This prevents them being resized when the user
1815  selects a file to import, which in turn prevents the size of the dialog from jumping
1816  around. */
1817 
1818  vector<string> t;
1819  t.push_back (_("one track per file"));
1820  t.push_back (_("one track per channel"));
1821  t.push_back (_("sequence files"));
1822  t.push_back (_("all files in one region"));
1824 
1825  t.clear ();
1826  t.push_back (importmode2string (ImportAsTrack));
1827  t.push_back (importmode2string (ImportToTrack));
1828  t.push_back (importmode2string (ImportAsRegion));
1829  t.push_back (importmode2string (ImportAsTapeTrack));
1831 }
1832 
1833 void
1835 {
1836  action_combo.set_active_text (importmode2string (mode));
1837 }
1838 
1839 ImportMode
1841 {
1842  return string2importmode (action_combo.get_active_text());
1843 }
1844 
1845 void
1847 {
1848  ArdourWindow::on_hide();
1849  if (_session) {
1851  }
1852 }
1853 
1856 {
1857  string str = where_combo.get_active_text();
1858 
1859  if (str == _("file timestamp")) {
1860  return ImportAtTimestamp;
1861  } else if (str == _("edit point")) {
1862  return ImportAtEditPoint;
1863  } else if (str == _("playhead")) {
1864  return ImportAtPlayhead;
1865  } else {
1866  return ImportAtStart;
1867  }
1868 }
1869 
1870 SrcQuality
1872 {
1873  string str = src_combo.get_active_text();
1874 
1875  if (str == _("Best")) {
1876  return SrcBest;
1877  } else if (str == _("Good")) {
1878  return SrcGood;
1879  } else if (str == _("Quick")) {
1880  return SrcQuick;
1881  } else if (str == _("Fast")) {
1882  return SrcFast;
1883  } else {
1884  return SrcFastest;
1885  }
1886 }
1887 
1888 void
1890 {
1892 }
1893 
1894 void
1896 {
1898 }
1899 
1902 {
1903  /* we use a map here because the channel combo can contain different strings
1904  depending on the state of the other combos. the map contains all possible strings
1905  and the ImportDisposition enum that corresponds to it.
1906  */
1907 
1908  string str = channel_combo.get_active_text();
1909  DispositionMap::const_iterator x = disposition_map.find (str);
1910 
1911  if (x == disposition_map.end()) {
1912  fatal << string_compose (_("programming error: %1 (%2)"), "unknown string for import disposition", str) << endmsg;
1913  abort(); /*NOTREACHED*/
1914  }
1915 
1916  return x->second;
1917 }
1918 
1919 void
1920 SoundFileOmega::reset (uint32_t selected_audio_tracks, uint32_t selected_midi_tracks)
1921 {
1922  selected_audio_track_cnt = selected_audio_tracks;
1923  selected_midi_track_cnt = selected_midi_tracks;
1924 
1926  chooser.set_filter (midi_filter);
1927  } else if (selected_midi_track_cnt == 0 && selected_audio_track_cnt > 0) {
1928  chooser.set_filter (audio_filter);
1929  } else {
1930  chooser.set_filter (audio_and_midi_filter);
1931  }
1932 
1933  reset_options ();
1934 }
1935 
1936 void
1938 {
1939  if (resetting_ourselves) {
1940  return;
1941  }
1942 
1943  if (!reset_options ()) {
1944  set_action_sensitive (false);
1945  } else {
1946  if (chooser.get_filenames().size() > 0) {
1947  set_action_sensitive (true);
1948  } else {
1949  set_action_sensitive (false);
1950  }
1951  }
1952 }
1953 
1954 void
1956 {
1958 
1959  if (action == RESPONSE_CANCEL) {
1960  hide ();
1961  return;
1962  }
1963 
1964  /* lets do it */
1965 
1966  vector<string> paths = get_paths ();
1967  ImportPosition pos = get_position ();
1968  ImportMode mode = get_mode ();
1971  framepos_t where;
1972 
1973  switch (pos) {
1974  case ImportAtEditPoint:
1976  break;
1977  case ImportAtTimestamp:
1978  where = -1;
1979  break;
1980  case ImportAtPlayhead:
1981  where = _session->transport_frame();
1982  break;
1983  case ImportAtStart:
1984  where = _session->current_start_frame();
1985  break;
1986  }
1987 
1988  SrcQuality quality = get_src_quality();
1989 
1990  if (copy_files_btn.get_active()) {
1991  PublicEditor::instance().do_import (paths, chns, mode, quality, where, instrument);
1992  } else {
1993  PublicEditor::instance().do_embed (paths, chns, mode, where, instrument);
1994  }
1995 
1996  if (action == RESPONSE_OK) {
1997  hide ();
1998  }
1999 }
2000 
Editing::ImportDisposition get_channel_disposition() const
Definition: sfdb_ui.cc:1901
void refresh_display(std::string ID, std::string file)
Definition: sfdb_ui.cc:1019
virtual float sample_rate() const =0
void set_src_quality(ARDOUR::SrcQuality q)
Definition: sfdb_ui.h:74
void file_selection_changed()
Definition: sfdb_ui.cc:1937
void handle_freesound_results(std::string theString)
Definition: sfdb_ui.cc:1108
framecnt_t nominal_frame_rate() const
Definition: session.h:367
Gtk::TreeView found_list_view
Definition: sfdb_ui.h:190
LIBPBD_API Transmitter fatal
Gtk::ComboBoxText action_combo
Definition: sfdb_ui.h:284
std::string to_string(T t, std::ios_base &(*f)(std::ios_base &))
Definition: convert.h:53
void freesound_similar_clicked()
Definition: sfdb_ui.cc:1057
Gtk::TreeModelColumn< std::string > filesize
Definition: sfdb_ui.h:145
void audition()
Definition: sfdb_ui.cc:400
int atoi(const string &s)
Definition: convert.cc:140
Gtk::ComboBoxText channel_combo
Definition: sfdb_ui.h:286
Gtk::HBox hpacker
Definition: sfdb_ui.h:213
void on_show()
Definition: sfdb_ui.cc:783
void freesound_list_view_activated(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *)
Definition: sfdb_ui.cc:809
void found_search_clicked()
Definition: sfdb_ui.cc:929
void set(framepos_t, bool force=false, ARDOUR::framecnt_t offset=0)
Definition: audio_clock.cc:956
const std::string & content() const
Definition: xml++.h:107
sigc::connection super_rapid_connect(const sigc::slot< void > &slot)
Definition: timers.cc:189
int freesound_page
Definition: sfdb_ui.h:243
Gtk::Frame border_frame
Definition: sfdb_ui.h:97
std::string get_filename()
Definition: sfdb_ui.cc:1642
void set_session(ARDOUR::Session *s)
bool tags_entry_left(GdkEventFocus *event)
Definition: sfdb_ui.cc:512
boost::shared_ptr< Amp > amp() const
Definition: route.h:194
Gtk::Label samplerate
Definition: sfdb_ui.h:87
std::string searchSimilar(std::string id)
void set_action_sensitive(bool)
Definition: sfdb_ui.cc:769
std::string path
Definition: sfdb_ui.h:78
void audition_progress(ARDOUR::framecnt_t, ARDOUR::framecnt_t)
Definition: sfdb_ui.cc:252
LIBARDOUR_API PBD::PropertyDescriptor< layer_t > layer
Definition: region.cc:67
FoundTagColumns found_list_columns
Definition: sfdb_ui.h:162
bool on_audio_filter(const Gtk::FileFilter::Info &filter_info)
Definition: sfdb_ui.cc:878
SoundFileChooser(std::string title, ARDOUR::Session *_s=0)
Definition: sfdb_ui.cc:1622
std::string freesound_get_audio_file(Gtk::TreeIter iter)
Definition: sfdb_ui.cc:954
Gtk::ComboBoxText freesound_sort
Definition: sfdb_ui.h:193
Gtk::ComboBoxText src_combo
Definition: sfdb_ui.h:287
void freesound_search_clicked()
Definition: sfdb_ui.cc:1038
static ImportMode string2importmode(string str)
Definition: sfdb_ui.cc:88
static bool check_link_status(const ARDOUR::Session *, const std::vector< std::string > &paths)
Definition: sfdb_ui.cc:1585
Glib::RefPtr< Gtk::ListStore > found_list
Definition: sfdb_ui.h:163
void freesound_more_clicked()
Definition: sfdb_ui.cc:1047
ImportPosition
Definition: editing.h:158
Gtk::Entry found_entry
Definition: sfdb_ui.h:188
Definition: ardour_ui.h:130
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
Definition: shared_ptr.hpp:396
static ARDOUR_UI * instance()
Definition: ardour_ui.h:187
LIBARDOUR_API PBD::PropertyDescriptor< std::string > name
const std::string & name() const
Definition: xml++.h:104
void set_fader_name(const char *name)
Definition: gain_meter.cc:583
static std::string persistent_folder
Definition: sfdb_ui.h:220
void reset_options_noret()
Definition: sfdb_ui.cc:1287
Gtk::VBox block_three
Definition: sfdb_ui.h:310
void save_tags(const std::vector< std::string > &)
Definition: sfdb_ui.cc:538
void audition_active(bool)
Definition: sfdb_ui.cc:243
void start_metering()
Definition: sfdb_ui.cc:858
void set_import_position(Editing::ImportPosition p)
Definition: sfdb_ui.h:75
uint32_t selected_audio_track_cnt
Definition: sfdb_ui.h:302
void src_combo_changed()
Definition: sfdb_ui.cc:1889
void chooser_file_activated()
Definition: sfdb_ui.cc:797
tuple f
Definition: signals.py:35
bool check_info(const std::vector< std::string > &paths, bool &same_size, bool &src_needed, bool &multichannel)
Definition: sfdb_ui.cc:1534
Definition: Beats.hpp:239
LIBPBD_API Transmitter error
unsigned int tokenize(const StringType &str, const StringType &delims, Iter it, bool strip_whitespace=false)
Definition: tokenizer.h:41
virtual void set_session(ARDOUR::Session *)
Definition: sfdb_ui.cc:815
LIBPBD_API Transmitter warning
bool fetchAudioFile(std::string originalFileName, std::string ID, std::string audioURL, SoundFileBrowser *caller)
const XMLNodeList & children(const std::string &str=std::string()) const
Definition: xml++.cc:329
void tags_changed()
Definition: sfdb_ui.cc:519
Gtk::FileFilter midi_filter
Definition: sfdb_ui.h:210
void found_list_view_activated(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *)
Definition: sfdb_ui.cc:803
virtual void do_embed(std::vector< std::string > paths, Editing::ImportDisposition, Editing::ImportMode mode, framepos_t &, boost::shared_ptr< ARDOUR::PluginInfo > instrument=boost::shared_ptr< ARDOUR::PluginInfo >())=0
SrcQuality
Definition: types.h:522
std::ostream & endmsg(std::ostream &ostr)
Definition: transmitter.h:71
LIBGTKMM2EXT_API void set_popdown_strings(Gtk::ComboBoxText &, const std::vector< std::string > &)
int open(const std::string &path) THROW_FILE_ERROR
Definition: OldSMF.cpp:60
boost::shared_ptr< PeakMeter > shared_peak_meter() const
Definition: route.h:198
#define P_(Singular, Plural, HowMany)
Definition: i18n.h:41
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
Definition: region.cc:63
Gtk::FileChooserWidget chooser
Definition: sfdb_ui.h:184
Gtk::Notebook notebook
Definition: sfdb_ui.h:197
framecnt_t frame_rate() const
Definition: session.h:365
Gtk::Entry freesound_entry
Definition: sfdb_ui.h:192
bool read_buffer(const std::string &)
Definition: xml++.cc:125
Gtk::FileFilter audio_and_midi_filter
Definition: sfdb_ui.h:208
#define invalidator(x)
Definition: gui_thread.h:40
Definition: xml++.h:55
void on_hide()
Definition: sfdb_ui.cc:1846
void cancel_audition()
Definition: session.cc:4160
void freesound_list_view_selected()
Definition: sfdb_ui.cc:980
boost::shared_ptr< Auditioner > the_auditioner()
Definition: session.h:673
Definition: id.h:32
static UI * instance()
Definition: gtk_ui.h:119
Gtk::Label channels
Definition: sfdb_ui.h:86
bool _seeking
Definition: sfdb_ui.h:122
Gtk::Label length
Definition: sfdb_ui.h:84
std::list< XMLNode * > XMLNodeList
Definition: xml++.h:44
Gtk::TreeModelColumn< std::string > duration
Definition: sfdb_ui.h:144
Gtk::VBox meter_packer
Definition: sfdb_ui.h:224
bool get_nsm_state() const
Definition: session.h:437
void freesound_search()
Definition: sfdb_ui.cc:1080
Gtk::CheckButton copy_files_btn
Definition: sfdb_ui.h:290
virtual bool reset_options()
Definition: sfdb_ui.h:254
#define _(Text)
Definition: i18n.h:11
Gtk::VBox block_four
Definition: sfdb_ui.h:311
bool reset_options()
Definition: sfdb_ui.cc:1295
Gtk::CheckButton autoplay_btn
Definition: sfdb_ui.h:108
Gtk::Label preview_label
Definition: sfdb_ui.h:98
Gtk::Button play_btn
Definition: sfdb_ui.h:106
void add_gain_meter()
Definition: sfdb_ui.cc:828
std::string searchText(std::string query, int page, std::string filter, enum sortMethod sort)
static string importmode2string(ImportMode mode)
Definition: sfdb_ui.cc:106
Gtk::Button freesound_search_btn
Definition: sfdb_ui.h:195
SoundFileBox preview
Definition: sfdb_ui.h:186
DispositionMap disposition_map
Definition: sfdb_ui.h:306
#define PATH_MAX
Definition: lv2_plugin.h:34
Editing::ImportPosition get_position() const
Definition: sfdb_ui.cc:1855
#define X_(Text)
Definition: i18n.h:13
void where_combo_changed()
Definition: sfdb_ui.cc:1895
InstrumentSelector instrument_combo
Definition: sfdb_ui.h:288
int64_t framecnt_t
Definition: types.h:76
void set_position(framepos_t)
Definition: region.cc:579
uint16_t num_tracks() const
Definition: SMF.cpp:44
std::vector< std::string > get_paths()
Definition: sfdb_ui.cc:1247
Gtk::TreeModelColumn< std::string > filename
Definition: sfdb_ui.h:143
Gtk::VBox vpacker
Definition: sfdb_ui.h:214
TreeView::Selection::ListHandle_Path ListPath
Definition: sfdb_ui.cc:85
Gtk::TextView tags_entry
Definition: sfdb_ui.h:100
bool seek_button_release(GdkEventButton *)
Definition: sfdb_ui.cc:266
Gtk::Label format
Definition: sfdb_ui.h:85
Gtk::TreeModelColumn< std::string > pathname
Definition: sfdb_ui.h:133
XMLNode * root() const
Definition: xml++.h:62
Gtk::HBox options
Definition: sfdb_ui.h:308
FreesoundColumns freesound_list_columns
Definition: sfdb_ui.h:165
SoundFileOmega(std::string title, ARDOUR::Session *_s, uint32_t selected_audio_tracks, uint32_t selected_midi_tracks, bool persistent, Editing::ImportMode mode_hint=Editing::ImportAsTrack)
Definition: sfdb_ui.cc:1659
framepos_t transport_frame() const
Definition: session.h:551
Definition: amp.h:29
bool audition_oneshot()
Definition: sfdb_ui.cc:393
virtual void set_controls(boost::shared_ptr< ARDOUR::Route > route, boost::shared_ptr< ARDOUR::PeakMeter > meter, boost::shared_ptr< ARDOUR::Amp > amp)
Definition: gain_meter.cc:1009
bool autoplay() const
Definition: sfdb_ui.cc:387
Gtk::Button found_search_btn
Definition: sfdb_ui.h:189
PBD::Signal1< void, bool > AuditionActive
Definition: session.h:679
#define gui_context()
Definition: gui_thread.h:36
Gtk::Button cancel_button
Definition: sfdb_ui.h:217
Gtk::FileFilter matchall_filter
Definition: sfdb_ui.h:212
ARDOUR::SoundFileInfo sf_info
Definition: sfdb_ui.h:80
Gtk::Button ok_button
Definition: sfdb_ui.h:216
Gtk::Label format_text
Definition: sfdb_ui.h:93
int64_t framepos_t
Definition: types.h:66
const std::string sound_path() const
bool on_audio_and_midi_filter(const Gtk::FileFilter::Info &filter_info)
Definition: sfdb_ui.cc:890
Gtk::TreeModelColumn< std::string > smplrate
Definition: sfdb_ui.h:146
ImportMode
Definition: editing.h:148
int64_t frameoffset_t
Definition: types.h:71
SoundFileBrowser(std::string title, ARDOUR::Session *_s, bool persistent)
Definition: sfdb_ui.cc:544
ARDOUR::PluginInfoPtr selected_instrument()
void set_mode(Mode)
void found_list_view_selected()
Definition: sfdb_ui.cc:906
LIBPBD_API Transmitter info
LIBARDOUR_API PBD::PropertyDescriptor< bool > active
Definition: route_group.cc:43
Gtk::TreeModelColumn< bool > started
Definition: sfdb_ui.h:148
void set_tags(std::string member, std::vector< std::string > tags)
void set_tip(Gtk::Widget &w, const gchar *tip)
void set_mode(Editing::ImportMode)
Definition: sfdb_ui.cc:1834
void clear_selection()
Definition: sfdb_ui.cc:790
Gtk::ComboBoxText where_combo
Definition: sfdb_ui.h:285
void audition_region(boost::shared_ptr< Region >)
Definition: session.cc:4152
static PublicEditor & instance()
GainMeter * gm
Definition: sfdb_ui.h:223
const std::string & path() const
Definition: file_source.h:49
void remove_gain_meter()
Definition: sfdb_ui.cc:847
Gtk::HBox bottom_box
Definition: sfdb_ui.h:104
virtual void do_import(std::vector< std::string > paths, Editing::ImportDisposition, Editing::ImportMode mode, ARDOUR::SrcQuality, framepos_t &, boost::shared_ptr< ARDOUR::PluginInfo > instrument=boost::shared_ptr< ARDOUR::PluginInfo >())=0
bool seek_button_press(GdkEventButton *)
Definition: sfdb_ui.cc:260
virtual void do_something(int action)
Definition: sfdb_ui.cc:776
Gtk::Button freesound_similar_btn
Definition: sfdb_ui.h:169
Gtk::FileFilter audio_filter
Definition: sfdb_ui.h:209
framepos_t current_start_frame() const
Definition: session.cc:5042
Definition: xml++.h:95
ImportDisposition
Definition: editing.h:168
Gtk::TreeModelColumn< std::string > id
Definition: sfdb_ui.h:141
Gtk::Label timecode
Definition: sfdb_ui.h:88
static UIConfiguration * config()
Definition: ardour_ui.h:188
virtual framepos_t get_preferred_edit_position(Editing::EditIgnoreOption=Editing::EDIT_IGNORE_NONE, bool from_context_menu=false, bool from_outside_canvas=false)=0
AudioClock timecode_clock
Definition: sfdb_ui.h:95
ARDOUR::SrcQuality get_src_quality() const
Definition: sfdb_ui.cc:1871
void search_members_and(std::vector< std::string > &results, const std::vector< std::string > &tags)
Gtk::TreeView freesound_list_view
Definition: sfdb_ui.h:196
Gtk::TreeModelColumn< std::string > uri
Definition: sfdb_ui.h:142
void update_meters()
Definition: gain_meter.cc:890
Definition: debug.h:30
Gtk::Label channels_value
Definition: sfdb_ui.h:90
Gtk::TreeModelColumn< std::string > license
Definition: sfdb_ui.h:147
Gtk::VBox main_box
Definition: sfdb_ui.h:102
framepos_t timeline_position() const
Definition: source.h:100
Gtk::Button freesound_more_btn
Definition: sfdb_ui.h:168
ARDOUR::SrcQuality _src_quality
Definition: sfdb_ui.h:123
Gtk::Table table
Definition: sfdb_ui.h:82
Gtk::HScale seek_slider
Definition: sfdb_ui.h:110
LIBARDOUR_API AudioLibrary * Library
Definition: globals.cc:121
void reset(uint32_t selected_audio_tracks, uint32_t selected_midi_tracks)
Definition: sfdb_ui.cc:1920
virtual framecnt_t length(framepos_t pos) const
Definition: midi_source.cc:164
Editing::ImportPosition _import_position
Definition: sfdb_ui.h:124
XMLNode * child(const char *) const
Definition: xml++.cc:309
Gtk::Label samplerate_value
Definition: sfdb_ui.h:91
Editing::ImportMode get_mode() const
Definition: sfdb_ui.cc:1840
void stop_metering()
Definition: sfdb_ui.cc:864
virtual ~SoundFileBrowser()
Definition: sfdb_ui.cc:747
virtual void set_session(ARDOUR::Session *)
Gtk::Button stop_btn
Definition: sfdb_ui.h:107
void update_preview()
Definition: sfdb_ui.cc:896
bool setup_labels(const std::string &filename)
Definition: sfdb_ui.cc:274
sigc::connection metering_connection
Definition: sfdb_ui.h:230
Glib::RefPtr< Gtk::ListStore > freesound_list
Definition: sfdb_ui.h:166
SoundFileBox(bool persistent)
Definition: sfdb_ui.cc:122
const SessionDirectory & session_directory() const
Definition: session.h:182
std::string audioFileName
bool resetting_ourselves
Definition: sfdb_ui.h:203
Gtk::Button apply_button
Definition: sfdb_ui.h:218
XMLNodeList::const_iterator XMLNodeConstIterator
Definition: xml++.h:49
bool checkAudioFile(std::string originalFileName, std::string ID)
void set_session(ARDOUR::Session *s)
Definition: sfdb_ui.cc:224
bool on_midi_filter(const Gtk::FileFilter::Info &filter_info)
Definition: sfdb_ui.cc:884
std::vector< boost::shared_ptr< Source > > SourceList
Definition: types.h:520
PBD::ScopedConnectionList auditioner_connections
Definition: sfdb_ui.h:112
LIBARDOUR_API std::string region_name_from_path(std::string path, bool strip_channels, bool add_channel_suffix=false, uint32_t total=0, uint32_t this_one=0)
bool add(PropertyBase *prop)
ARDOUR::Session * _session
bool bad_file_message()
Definition: sfdb_ui.cc:1518
Gtk::VBox block_two
Definition: sfdb_ui.h:309
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
uint32_t selected_midi_track_cnt
Definition: sfdb_ui.h:303
void do_something(int action)
Definition: sfdb_ui.cc:1955
AudioClock length_clock
Definition: sfdb_ui.h:94
double atof(const string &s)
Definition: convert.cc:158
void stop_audition()
Definition: sfdb_ui.cc:504
LIBARDOUR_API PBD::PropertyDescriptor< framecnt_t > length
Definition: region.cc:64
std::vector< std::string > get_tags(std::string member)