#include "pbd/error.h"
#include "ardour/amp.h"
-#include "ardour/audio_diskstream.h"
#include "ardour/audio_port.h"
#include "ardour/audioengine.h"
#include "ardour/audioplaylist.h"
#include "ardour/auditioner.h"
#include "ardour/data_type.h"
#include "ardour/delivery.h"
-#include "ardour/midi_diskstream.h"
+#include "ardour/disk_reader.h"
+#include "ardour/midi_playlist.h"
#include "ardour/midi_region.h"
#include "ardour/plugin.h"
#include "ardour/plugin_insert.h"
Auditioner::Auditioner (Session& s)
: Track (s, "auditioner", PresentationInfo::Auditioner)
- , current_frame (0)
+ , current_sample (0)
, _auditioning (0)
, length (0)
- , _seek_frame (-1)
+ , _seek_sample (-1)
, _seeking (false)
, _seek_complete (false)
, via_monitor (false)
}
_output->add_port ("", this, DataType::MIDI);
+ use_new_playlist (DataType::MIDI);
lookup_synth();
{
string plugin_id = Config->get_midi_audition_synth_uri();
asynth.reset ();
- if (!plugin_id.empty()) {
+ if (!plugin_id.empty() || plugin_id == X_("@default@")) {
boost::shared_ptr<Plugin> p;
p = find_plugin (_session, plugin_id, ARDOUR::LV2);
if (!p) {
- p = find_plugin (_session, "https://community.ardour.org/node/7596", ARDOUR::LV2);
+ p = find_plugin (_session, "http://gareus.org/oss/lv2/gmsynth", ARDOUR::LV2);
+ if (!p) {
+ p = find_plugin (_session, "https://community.ardour.org/node/7596", ARDOUR::LV2);
+ }
if (p) {
warning << _("Falling back to Reasonable Synth for Midi Audition") << endmsg;
} else {
}
}
if (p) {
+ if (plugin_id == X_("@default@")) {
+ Config->set_midi_audition_synth_uri (p->get_info()->unique_id);
+ }
asynth = boost::shared_ptr<Processor> (new PluginInsert (_session, p));
}
}
via_monitor = false;
if (left.empty() || left == "default") {
- if (_session.monitor_out()) {
- left = _session.monitor_out()->input()->audio (0)->name();
- via_monitor = true;
- } else {
+ if (_session.monitor_out() && _session.monitor_out()->input()->audio (0)) {
+ left = _session.monitor_out()->input()->audio (0)->name();
+ } else {
if (outputs.size() > 0) {
left = outputs[0];
}
- }
+ }
}
if (right.empty() || right == "default") {
- if (_session.monitor_out()) {
- right = _session.monitor_out()->input()->audio (1)->name();
- via_monitor = true;
- } else {
+ if (_session.monitor_out() && _session.monitor_out()->input()->audio (1)) {
+ right = _session.monitor_out()->input()->audio (1)->name();
+ } else {
if (outputs.size() > 1) {
right = outputs[1];
}
- }
+ }
}
_output->disconnect (this);
}
+ if (_session.monitor_out () && _output->connected_to (_session.monitor_out ()->input())) {
+ via_monitor = true;
+ }
+
return 0;
}
}
}
-boost::shared_ptr<Diskstream>
-Auditioner::create_diskstream () {
-
- {
- AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0);
- dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Hidden);
- _diskstream_audio = boost::shared_ptr<AudioDiskstream> (new AudioDiskstream (_session, name(), dflags));
- }
-
- {
- MidiDiskstream::Flag dflags = MidiDiskstream::Flag (0);
- dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Hidden);
- _diskstream_midi = boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, name(), dflags));
- _diskstream_midi->do_refill_with_alloc ();
- _diskstream_midi->playlist()->set_orig_track_id (id());
- }
-
- return _diskstream_audio;
-}
-
-int
-Auditioner::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler) {
- if (_midi_audition) {
- return roll_midi(nframes, start_frame, end_frame, declick, need_butler);
- } else {
- return roll_audio(nframes, start_frame, end_frame, declick, need_butler);
- }
-}
-
int
-Auditioner::roll_midi (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
+Auditioner::roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, int declick, bool& need_butler)
{
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
if (!lm.locked()) {
assert(_active);
- framecnt_t playback_distance = nframes;
- boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
- MidiBuffer& mbuf (bufs.get_midi (0));
- _silent = false;
-
- ChanCount cnt (DataType::MIDI, 1);
- cnt.set (DataType::AUDIO, bufs.count().n_audio());
- bufs.set_count (cnt);
if (_queue_panic) {
+ MidiBuffer& mbuf (bufs.get_midi (0));
_queue_panic = false;
for (uint8_t chn = 0; chn < 0xf; ++chn) {
uint8_t buf[3] = { ((uint8_t) (MIDI_CMD_CONTROL | chn)), ((uint8_t) MIDI_CTL_SUSTAIN), 0 };
buf[1] = MIDI_CTL_RESET_CONTROLLERS;
mbuf.push_back(0, 3, buf);
}
- process_output_buffers (bufs, start_frame, start_frame+1, 1, false, false);
-
- for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
- boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
- if (d) {
- d->flush_buffers (nframes);
- }
- }
}
- diskstream->get_playback (mbuf, nframes);
+ process_output_buffers (bufs, start_sample, end_sample, nframes, declick, !_session.transport_stopped(), true);
- process_output_buffers (bufs, start_frame, end_frame, nframes,
- declick, (!diskstream->record_enabled() && !_session.transport_stopped()));
+ /* note: auditioner never writes to disk, so we don't care about the
+ * disk writer status (it's buffers will always have no data in them).
+ */
+
+ if (_disk_reader->need_butler()) {
+ need_butler = true;
+ }
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
}
}
- need_butler = diskstream->commit (playback_distance);
- return 0;
-}
-
-
-int
-Auditioner::roll_audio (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler) {
- Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
- if (!lm.locked()) {
- return 0;
- }
-
- assert(n_outputs().n_total() > 0);
- assert(_active);
-
- int dret;
- framecnt_t playback_distance;
- framepos_t transport_frame = _session.transport_frame();
- boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
- BufferSet& bufs = _session.get_route_buffers (n_process_buffers ());
-
- _silent = false;
- _amp->apply_gain_automation(false);
-
- if ((dret = diskstream->process (bufs, transport_frame, nframes, playback_distance, (monitoring_state() == MonitoringDisk))) != 0) {
- need_butler = diskstream->commit (playback_distance);
- silence (nframes);
- return dret;
- }
-
- process_output_buffers (bufs, start_frame, end_frame, nframes, declick, (!diskstream->record_enabled() && _session.transport_rolling()));
- need_butler = diskstream->commit (playback_distance);
return 0;
}
-void
-Auditioner::set_diskstream (boost::shared_ptr<Diskstream> ds)
-{
- Track::set_diskstream (ds);
-
- _diskstream->set_track (this);
-#ifdef XXX_OLD_DESTRUCTIVE_API_XXX
- if (Profile->get_trx()) {
- _diskstream->set_destructive (false);
- } else {
- _diskstream->set_destructive (_mode == Destructive);
- }
- _diskstream->set_non_layered (_mode == NonLayered);
-#endif
- _diskstream->set_record_enabled (false);
- _diskstream->request_input_monitoring (false);
-
- DiskstreamChanged (); /* EMIT SIGNAL */
-}
-
-AudioPlaylist&
-Auditioner::prepare_playlist ()
-{
- // used by CrossfadeEditor::audition()
-
- _midi_audition = false;
- set_diskstream(_diskstream_audio);
- if (_synth_added) {
- remove_processor(asynth);
- _synth_added = false;
- }
-
- // FIXME auditioner is still audio-only
- boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(_diskstream->playlist());
- assert(apl);
-
- apl->clear ();
- return *apl;
-}
-
void
Auditioner::audition_region (boost::shared_ptr<Region> region)
{
if (boost::dynamic_pointer_cast<AudioRegion>(region) != 0) {
_midi_audition = false;
- set_diskstream(_diskstream_audio);
+
if (_synth_added) {
remove_processor(asynth);
_synth_added = false;
the_region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region));
the_region->set_position (0);
- _diskstream->playlist()->drop_regions ();
- _diskstream->playlist()->add_region (the_region, 0, 1);
+ _disk_reader->midi_playlist()->drop_regions ();
- if (_diskstream->n_channels().n_audio() < the_region->n_channels()) {
- audio_diskstream()->add_channel (the_region->n_channels() - _diskstream->n_channels().n_audio());
- } else if (_diskstream->n_channels().n_audio() > the_region->n_channels()) {
- audio_diskstream()->remove_channel (_diskstream->n_channels().n_audio() - the_region->n_channels());
- }
+ _disk_reader->audio_playlist()->drop_regions ();
+ _disk_reader->audio_playlist()->add_region (the_region, 0, 1);
ProcessorStreams ps;
{
if (configure_processors (&ps)) {
error << string_compose (_("Cannot setup auditioner processing flow for %1 channels"),
- _diskstream->n_channels()) << endmsg;
+ region->n_channels()) << endmsg;
return;
}
}
} else if (boost::dynamic_pointer_cast<MidiRegion>(region)) {
_midi_audition = true;
- set_diskstream(_diskstream_midi);
+
the_region.reset();
_import_position = region->position();
midi_region = (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (region)));
midi_region->set_position (_import_position);
- _diskstream->playlist()->drop_regions ();
- _diskstream->playlist()->add_region (midi_region, _import_position, 1);
- midi_diskstream()->reset_tracker();
+ _disk_reader->audio_playlist()->drop_regions();
+
+ _disk_reader->midi_playlist()->drop_regions ();
+ _disk_reader->midi_playlist()->add_region (midi_region, _import_position, 1);
+ _disk_reader->reset_tracker();
ProcessorStreams ps;
lookup_synth();
}
-
if (!_synth_added && asynth) {
int rv = add_processor (asynth, PreFader, &ps, true);
if (rv) {
if (configure_processors (&ps)) {
error << string_compose (_("Cannot setup auditioner processing flow for %1 channels"),
- _diskstream->n_channels()) << endmsg;
+ region->n_channels()) << endmsg;
return;
}
}
/* force a panner reset now that we have all channels */
_main_outs->reset_panner();
- _seek_frame = -1;
+ _seek_sample = -1;
_seeking = false;
int dir;
- framecnt_t offset;
+ samplecnt_t offset;
if (_midi_audition) {
length = midi_region->length();
offset = 0;
}
- _diskstream->seek (offset, true);
- current_frame = offset;
+ _disk_reader->seek (offset, true);
+ current_sample = offset;
g_atomic_int_set (&_auditioning, 1);
}
int
-Auditioner::play_audition (framecnt_t nframes)
+Auditioner::play_audition (samplecnt_t nframes)
{
bool need_butler = false;
- framecnt_t this_nframes;
+ samplecnt_t this_nframes;
int ret;
if (g_atomic_int_get (&_auditioning) == 0) {
#if 0 // TODO
if (_seeking && _seek_complete) {
// set FADE-IN
- } else if (_seek_frame >= 0 && _seek_frame < length && !_seeking) {
+ } else if (_seek_sample >= 0 && _seek_sample < length && !_seeking) {
// set FADE-OUT -- use/override amp? || use region-gain ?
}
#endif
if (_seeking && _seek_complete) {
_seek_complete = false;
_seeking = false;
- _seek_frame = -1;
- if (_midi_audition && midi_diskstream()) {
- midi_diskstream()->reset_tracker();
- }
+ _seek_sample = -1;
+ _disk_reader->reset_tracker();
}
if(!_seeking) {
/* process audio */
- this_nframes = min (nframes, length - current_frame + _import_position);
+ this_nframes = min (nframes, length - current_sample + _import_position);
- if ((ret = roll (this_nframes, current_frame, current_frame + nframes, false, need_butler)) != 0) {
+ if ((ret = roll (this_nframes, current_sample, current_sample + nframes, false, need_butler)) != 0) {
silence (nframes);
return ret;
}
- current_frame += this_nframes;
+ current_sample += this_nframes;
} else {
silence (nframes);
}
- if (_seek_frame >= 0 && _seek_frame < length && !_seeking) {
+ if (_seek_sample >= 0 && _seek_sample < length && !_seeking) {
_queue_panic = true;
_seek_complete = false;
_seeking = true;
}
if (!_seeking) {
- AuditionProgress(current_frame - _import_position, length); /* emit */
+ AuditionProgress(current_sample - _import_position, length); /* emit */
}
- if (current_frame >= length + _import_position) {
+ if (current_sample >= length + _import_position) {
_session.cancel_audition ();
return 0;
} else {
vector<string> connections;
vector<string> outputs;
_session.engine().get_physical_outputs (DataType::AUDIO, outputs);
+
+ if (_session.monitor_out () && _output->connected_to (_session.monitor_out ()->input ())) {
+ Config->set_auditioner_output_left ("default");
+ Config->set_auditioner_output_right ("default");
+ via_monitor = true;
+ return;
+ }
+
if (_output->nth (0)->get_connections (connections)) {
if (outputs.size() > 0) {
phys = outputs[0];
Auditioner::input_streams () const
{
/* auditioner never has any inputs - its channel configuration
- depends solely on the region we are auditioning.
- */
+ depends solely on the region we are auditioning.
+ */
- if (!_midi_audition && audio_diskstream()) {
- return audio_diskstream()->n_channels();
- }
- if (_midi_audition && midi_diskstream()) {
- ChanCount cnt (DataType::MIDI, 1);
- return cnt;
+ if (_midi_audition) {
+ return ChanCount (DataType::MIDI, 1);
+ } else {
+ if (the_region) {
+ return ChanCount (DataType::AUDIO, the_region->n_channels ());
+ }
}
- return ChanCount ();
+ return ChanCount (DataType::AUDIO, 1);
}
MonitorState
return MonitoringDisk;
}
-boost::shared_ptr<AudioDiskstream>
-Auditioner::audio_diskstream() const
-{
- return boost::dynamic_pointer_cast<AudioDiskstream> (_diskstream);
-}
-
-boost::shared_ptr<MidiDiskstream>
-Auditioner::midi_diskstream() const
-{
- return boost::dynamic_pointer_cast<MidiDiskstream> (_diskstream);
-}