#include "pbd/xml++.h"
#include "pbd/memento_command.h"
#include "pbd/enumwriter.h"
+#include "pbd/stateful_diff_command.h"
#include "ardour/ardour.h"
#include "ardour/audioengine.h"
#include "ardour/smf_source.h"
#include "ardour/utils.h"
#include "ardour/session_playlists.h"
+#include "ardour/route.h"
#include "midi++/types.h"
in_set_state = true;
- init(flag);
+ init ();
use_new_playlist ();
in_set_state = false;
, _frames_read_from_ringbuffer(0)
{
in_set_state = true;
- init (Recordable);
+ init ();
if (set_state (node, Stateful::loading_state_version)) {
in_set_state = false;
}
void
-MidiDiskstream::init (Diskstream::Flag f)
+MidiDiskstream::init ()
{
- Diskstream::init(f);
-
/* there are no channels at this point, so these
two calls just get speed_buffer_size and wrap_buffer
size setup without duplicating their code.
o << trace_prefix
<< "Channel "
<< (msg[0]&0xF)+1
- << " Program PropertyChange ProgNum "
+ << " Program Change ProgNum "
<< (int) msg[1]
<< endl;
break;
#endif
int
-MidiDiskstream::process (nframes_t transport_frame, nframes_t nframes, bool can_record, bool rec_monitors_input)
+MidiDiskstream::process (nframes_t transport_frame, nframes_t nframes, bool can_record, bool rec_monitors_input, bool& need_butler)
{
int ret = -1;
nframes_t rec_offset = 0;
bool nominally_recording;
bool re = record_enabled ();
- /* if we've already processed the frames corresponding to this call,
- just return. this allows multiple routes that are taking input
- from this diskstream to call our ::process() method, but have
- this stuff only happen once. more commonly, it allows both
- the AudioTrack that is using this AudioDiskstream *and* the Session
- to call process() without problems.
- */
-
- if (_processed) {
- return 0;
- }
-
- commit_should_unlock = false;
+ playback_distance = 0;
check_record_status (transport_frame, nframes, can_record);
nominally_recording = (can_record && re);
if (nframes == 0) {
- _processed = true;
return 0;
}
- /* This lock is held until the end of ::commit, so these two functions
- must always be called as a pair. The only exception is if this function
- returns a non-zero value, in which case, ::commit should not be called.
- */
+ Glib::Mutex::Lock sm (state_lock, Glib::TRY_LOCK);
- // If we can't take the state lock return.
- if (!state_lock.trylock()) {
+ if (!sm.locked()) {
return 1;
}
- commit_should_unlock = true;
+
adjust_capture_position = 0;
if (nominally_recording || (_session.get_record_enabled() && _session.config.get_punch_in())) {
ret = 0;
- _processed = true;
-
- if (ret) {
-
- /* we're exiting with failure, so ::commit will not
- be called. unlock the state lock.
- */
-
- commit_should_unlock = false;
- state_lock.unlock();
- }
+ if (commit (nframes)) {
+ need_butler = true;
+ }
return ret;
}
" = " << frames_written - frames_read
<< " + " << nframes << " < " << midi_readahead << " = " << need_butler << ")" << endl;*/
- if (commit_should_unlock) {
- state_lock.unlock();
- }
-
- _processed = false;
-
return need_butler;
}
{
/* called from audio thread, so we can use the read ptr and playback sample as we wish */
- pending_overwrite = yn;
+ _pending_overwrite = yn;
overwrite_frame = playback_sample;
}
{
//read(overwrite_frame, disk_io_chunk_frames, false);
overwrite_queued = false;
- pending_overwrite = false;
+ _pending_overwrite = false;
return 0;
}
}
void
-MidiDiskstream::transport_stopped (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
+MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
{
bool more_work = true;
int err = 0;
if (_write_source) {
_write_source->mark_for_remove ();
- _write_source->drop_references ();
_write_source.reset();
}
// cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
- XMLNode &before = _playlist->get_state();
+ _playlist->clear_history ();
_playlist->freeze ();
uint32_t buffer_position = 0;
string region_name;
- _session.region_name (region_name, _write_source->name(), false);
+ RegionFactory::region_name (region_name, _write_source->name(), false);
// cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
}
_playlist->thaw ();
- XMLNode &after = _playlist->get_state();
- _session.add_command (new MementoCommand<Playlist>(*_playlist, &before, &after));
+ _session.add_command (new StatefulDiffCommand(_playlist));
}
XMLNode&
MidiDiskstream::get_state ()
{
- XMLNode* node = new XMLNode ("MidiDiskstream");
+ XMLNode* node = new XMLNode ("Diskstream");
char buf[64];
LocaleGuard lg (X_("POSIX"));
}
if (!had_playlist) {
- _playlist->set_orig_diskstream_id (_id);
+ _playlist->set_orig_diskstream_id (id());
}
if (capture_pending_node) {
if (_write_source) {
if (_write_source->is_empty ()) {
+ /* remove any region that is using this empty source; they can result when MIDI recordings
+ are made, but no MIDI data is received.
+ */
+ _playlist->remove_region_by_source (_write_source);
_write_source->mark_for_remove ();
+ _write_source->drop_references ();
_write_source.reset();
} else {
_write_source.reset();
}
try {
- _write_source = boost::dynamic_pointer_cast<SMFSource>(_session.create_midi_source_for_session (*this));
+ _write_source = boost::dynamic_pointer_cast<SMFSource>(_session.create_midi_source_for_session (name ()));
if (!_write_source) {
throw failed_constructor();
}