mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-22 14:46:34 +01:00
lots of details relating to MIDI file management; try to ignore ALSA sequencer MIDI ports named "Midi-Through"
git-svn-id: svn://localhost/ardour2/branches/3.0@7305 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
ecb0cd5d11
commit
37978aa214
17 changed files with 126 additions and 82 deletions
|
|
@ -423,6 +423,16 @@ PortGroupList::gather (ARDOUR::Session* session, bool inputs, bool allow_dups)
|
||||||
!ardour->has_port(p) &&
|
!ardour->has_port(p) &&
|
||||||
!other->has_port(p)) {
|
!other->has_port(p)) {
|
||||||
|
|
||||||
|
/* special hack: ignore MIDI ports labelled Midi-Through. these
|
||||||
|
are basically useless and mess things up for default
|
||||||
|
connections.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (p.find ("MIDI-Through") != string::npos) {
|
||||||
|
++n;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (port_has_prefix (p, "system:") ||
|
if (port_has_prefix (p, "system:") ||
|
||||||
port_has_prefix (p, "alsa_pcm") ||
|
port_has_prefix (p, "alsa_pcm") ||
|
||||||
port_has_prefix (p, "ardour:")) {
|
port_has_prefix (p, "ardour:")) {
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ public:
|
||||||
int move_to_trash (const Glib::ustring& trash_dir_name);
|
int move_to_trash (const Glib::ustring& trash_dir_name);
|
||||||
void mark_take (const Glib::ustring& id);
|
void mark_take (const Glib::ustring& id);
|
||||||
void mark_immutable ();
|
void mark_immutable ();
|
||||||
|
void mark_nonremovable ();
|
||||||
|
|
||||||
const Glib::ustring& take_id () const { return _take_id; }
|
const Glib::ustring& take_id () const { return _take_id; }
|
||||||
bool within_session () const { return _within_session; }
|
bool within_session () const { return _within_session; }
|
||||||
|
|
|
||||||
|
|
@ -353,7 +353,7 @@ class Region
|
||||||
|
|
||||||
void register_properties ();
|
void register_properties ();
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
void use_sources (SourceList const &);
|
void use_sources (SourceList const &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,15 +106,7 @@ class Source : public SessionObject
|
||||||
Flag flags() const { return _flags; }
|
Flag flags() const { return _flags; }
|
||||||
|
|
||||||
void inc_use_count () { g_atomic_int_inc (&_use_count); }
|
void inc_use_count () { g_atomic_int_inc (&_use_count); }
|
||||||
void dec_use_count () {
|
void dec_use_count ();
|
||||||
#ifndef NDEBUG
|
|
||||||
gint oldval = g_atomic_int_exchange_and_add (&_use_count, -1);
|
|
||||||
assert (oldval > 0);
|
|
||||||
#else
|
|
||||||
g_atomic_int_exchange_and_add (&_use_count, -1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int use_count() const { return g_atomic_int_get (&_use_count); }
|
int use_count() const { return g_atomic_int_get (&_use_count); }
|
||||||
bool used() const { return use_count() > 0; }
|
bool used() const { return use_count() > 0; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1917,8 +1917,6 @@ AudioDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
|
||||||
boost::shared_ptr<ChannelList> c = channels.reader();
|
boost::shared_ptr<ChannelList> c = channels.reader();
|
||||||
uint32_t n;
|
uint32_t n;
|
||||||
|
|
||||||
cerr << name() << " resetting write sources, recrodable " << recordable() << " chans = " << c->size() << endl;
|
|
||||||
|
|
||||||
if (!_session.writable() || !recordable()) {
|
if (!_session.writable() || !recordable()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1109,16 +1109,21 @@ AudioEngine::n_physical_outputs (DataType type) const
|
||||||
{
|
{
|
||||||
GET_PRIVATE_JACK_POINTER_RET (_jack,0);
|
GET_PRIVATE_JACK_POINTER_RET (_jack,0);
|
||||||
const char ** ports;
|
const char ** ports;
|
||||||
uint32_t i = 0;
|
uint32_t cnt = 0;
|
||||||
|
|
||||||
if ((ports = jack_get_ports (_priv_jack, NULL, type.to_jack_type(), JackPortIsPhysical|JackPortIsInput)) == 0) {
|
if ((ports = jack_get_ports (_priv_jack, NULL, type.to_jack_type(), JackPortIsPhysical|JackPortIsInput)) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; ports[i]; ++i) {}
|
for (uint32_t i = 0; ports[i]; ++i) {
|
||||||
|
if (!strstr (ports[i], "Midi-Through")) {
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free (ports);
|
free (ports);
|
||||||
|
|
||||||
return i;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
|
|
@ -1126,16 +1131,21 @@ AudioEngine::n_physical_inputs (DataType type) const
|
||||||
{
|
{
|
||||||
GET_PRIVATE_JACK_POINTER_RET (_jack,0);
|
GET_PRIVATE_JACK_POINTER_RET (_jack,0);
|
||||||
const char ** ports;
|
const char ** ports;
|
||||||
uint32_t i = 0;
|
uint32_t cnt = 0;
|
||||||
|
|
||||||
if ((ports = jack_get_ports (_priv_jack, NULL, type.to_jack_type(), JackPortIsPhysical|JackPortIsOutput)) == 0) {
|
if ((ports = jack_get_ports (_priv_jack, NULL, type.to_jack_type(), JackPortIsPhysical|JackPortIsOutput)) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; ports[i]; ++i) {}
|
for (uint32_t i = 0; ports[i]; ++i) {
|
||||||
|
if (!strstr (ports[i], "Midi-Through")) {
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free (ports);
|
free (ports);
|
||||||
|
|
||||||
return i;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1150,6 +1160,9 @@ AudioEngine::get_physical_inputs (DataType type, vector<string>& ins)
|
||||||
|
|
||||||
if (ports) {
|
if (ports) {
|
||||||
for (uint32_t i = 0; ports[i]; ++i) {
|
for (uint32_t i = 0; ports[i]; ++i) {
|
||||||
|
if (strstr (ports[i], "Midi-Through")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
ins.push_back (ports[i]);
|
ins.push_back (ports[i]);
|
||||||
}
|
}
|
||||||
free (ports);
|
free (ports);
|
||||||
|
|
@ -1168,6 +1181,9 @@ AudioEngine::get_physical_outputs (DataType type, vector<string>& outs)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; ports[i]; ++i) {
|
for (i = 0; ports[i]; ++i) {
|
||||||
|
if (strstr (ports[i], "Midi-Through")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
outs.push_back (ports[i]);
|
outs.push_back (ports[i]);
|
||||||
}
|
}
|
||||||
free (ports);
|
free (ports);
|
||||||
|
|
@ -1179,6 +1195,7 @@ AudioEngine::get_nth_physical (DataType type, uint32_t n, int flag)
|
||||||
GET_PRIVATE_JACK_POINTER_RET (_jack,"");
|
GET_PRIVATE_JACK_POINTER_RET (_jack,"");
|
||||||
const char ** ports;
|
const char ** ports;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
uint32_t idx;
|
||||||
string ret;
|
string ret;
|
||||||
|
|
||||||
assert(type != DataType::NIL);
|
assert(type != DataType::NIL);
|
||||||
|
|
@ -1187,10 +1204,14 @@ AudioEngine::get_nth_physical (DataType type, uint32_t n, int flag)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < n && ports[i]; ++i) {}
|
for (i = 0, idx = 0; idx < n && ports[i]; ++i) {
|
||||||
|
if (!strstr (ports[i], "Midi-Through")) {
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ports[i]) {
|
if (ports[idx]) {
|
||||||
ret = ports[i];
|
ret = ports[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
free ((const char **) ports);
|
free ((const char **) ports);
|
||||||
|
|
|
||||||
|
|
@ -417,6 +417,12 @@ FileSource::mark_immutable ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FileSource::mark_nonremovable ()
|
||||||
|
{
|
||||||
|
_flags = Flag (_flags & ~(Removable|RemovableIfEmpty|RemoveAtDestroy));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FileSource::set_within_session_from_path (const std::string& path)
|
FileSource::set_within_session_from_path (const std::string& path)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
#include "pbd/memento_command.h"
|
#include "pbd/memento_command.h"
|
||||||
#include "pbd/enumwriter.h"
|
#include "pbd/enumwriter.h"
|
||||||
#include "pbd/stateful_diff_command.h"
|
#include "pbd/stateful_diff_command.h"
|
||||||
|
#include "pbd/stacktrace.h"
|
||||||
|
|
||||||
#include "ardour/ardour.h"
|
#include "ardour/ardour.h"
|
||||||
#include "ardour/audioengine.h"
|
#include "ardour/audioengine.h"
|
||||||
|
|
@ -84,6 +85,7 @@ MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::F
|
||||||
|
|
||||||
init ();
|
init ();
|
||||||
use_new_playlist ();
|
use_new_playlist ();
|
||||||
|
use_new_write_source (0);
|
||||||
|
|
||||||
in_set_state = false;
|
in_set_state = false;
|
||||||
|
|
||||||
|
|
@ -101,6 +103,7 @@ MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node)
|
||||||
, _frames_read_from_ringbuffer(0)
|
, _frames_read_from_ringbuffer(0)
|
||||||
{
|
{
|
||||||
in_set_state = true;
|
in_set_state = true;
|
||||||
|
|
||||||
init ();
|
init ();
|
||||||
|
|
||||||
if (set_state (node, Stateful::loading_state_version)) {
|
if (set_state (node, Stateful::loading_state_version)) {
|
||||||
|
|
@ -108,11 +111,9 @@ MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node)
|
||||||
throw failed_constructor();
|
throw failed_constructor();
|
||||||
}
|
}
|
||||||
|
|
||||||
in_set_state = false;
|
use_new_write_source (0);
|
||||||
|
|
||||||
if (destructive()) {
|
in_set_state = false;
|
||||||
use_destructive_playlist ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -183,9 +184,10 @@ MidiDiskstream::non_realtime_input_change ()
|
||||||
/* implicit unlock */
|
/* implicit unlock */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reset capture files */
|
/* unlike with audio, there is never any need to reset write sources
|
||||||
|
based on input configuration changes because ... a MIDI track
|
||||||
reset_write_sources (false);
|
has just 1 MIDI port as input, always.
|
||||||
|
*/
|
||||||
|
|
||||||
/* now refill channel buffers */
|
/* now refill channel buffers */
|
||||||
|
|
||||||
|
|
@ -945,9 +947,24 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
|
||||||
/* figure out the name for this take */
|
/* figure out the name for this take */
|
||||||
|
|
||||||
srcs.push_back (_write_source);
|
srcs.push_back (_write_source);
|
||||||
|
|
||||||
_write_source->set_timeline_position (capture_info.front()->start);
|
_write_source->set_timeline_position (capture_info.front()->start);
|
||||||
_write_source->set_captured_for (_name);
|
_write_source->set_captured_for (_name);
|
||||||
|
|
||||||
|
/* flush to disk: this step differs from the audio path,
|
||||||
|
where all the data is already on disk.
|
||||||
|
*/
|
||||||
|
|
||||||
|
_write_source->mark_streaming_write_completed ();
|
||||||
|
|
||||||
|
/* we will want to be able to keep (over)writing the source
|
||||||
|
but we don't want it to be removable. this also differs
|
||||||
|
from the audio situation, where the source at this point
|
||||||
|
must be considered immutable
|
||||||
|
*/
|
||||||
|
|
||||||
|
_write_source->mark_nonremovable ();
|
||||||
|
|
||||||
string whole_file_region_name;
|
string whole_file_region_name;
|
||||||
whole_file_region_name = region_name_from_path (_write_source->name(), true);
|
whole_file_region_name = region_name_from_path (_write_source->name(), true);
|
||||||
|
|
||||||
|
|
@ -1021,11 +1038,11 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
|
||||||
_playlist->thaw ();
|
_playlist->thaw ();
|
||||||
_session.add_command (new StatefulDiffCommand(_playlist));
|
_session.add_command (new StatefulDiffCommand(_playlist));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
mark_write_completed = true;
|
mark_write_completed = true;
|
||||||
|
}
|
||||||
|
|
||||||
reset_write_sources (mark_write_completed);
|
use_new_write_source (0);
|
||||||
|
|
||||||
for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
|
for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
|
||||||
delete *ci;
|
delete *ci;
|
||||||
|
|
@ -1133,10 +1150,6 @@ MidiDiskstream::engage_record_enable ()
|
||||||
_source_port->request_monitor_input (!(_session.config.get_auto_input() && rolling));
|
_source_port->request_monitor_input (!(_session.config.get_auto_input() && rolling));
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Why is this necessary? Isn't needed for AudioDiskstream...
|
|
||||||
if (!_write_source)
|
|
||||||
use_new_write_source();
|
|
||||||
|
|
||||||
_write_source->mark_streaming_midi_write_started (_note_mode, _session.transport_frame());
|
_write_source->mark_streaming_midi_write_started (_note_mode, _session.transport_frame());
|
||||||
|
|
||||||
RecordEnableChanged (); /* EMIT SIGNAL */
|
RecordEnableChanged (); /* EMIT SIGNAL */
|
||||||
|
|
@ -1293,45 +1306,19 @@ MidiDiskstream::set_state (const XMLNode& node, int /*version*/)
|
||||||
|
|
||||||
in_set_state = false;
|
in_set_state = false;
|
||||||
|
|
||||||
/* make sure this is clear before we do anything else */
|
|
||||||
|
|
||||||
// FIXME?
|
|
||||||
//_capturing_source = 0;
|
|
||||||
|
|
||||||
/* write sources are handled when we handle the input set
|
|
||||||
up of the IO that owns this DS (::non_realtime_input_change())
|
|
||||||
*/
|
|
||||||
|
|
||||||
in_set_state = false;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
MidiDiskstream::use_new_write_source (uint32_t n)
|
MidiDiskstream::use_new_write_source (uint32_t n)
|
||||||
{
|
{
|
||||||
cerr << name() << " use new write source for n = " << n << " recordable ? " << recordable() << endl;
|
|
||||||
|
|
||||||
if (!recordable()) {
|
if (!recordable()) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(n == 0);
|
assert(n == 0);
|
||||||
|
|
||||||
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();
|
_write_source.reset();
|
||||||
} else {
|
|
||||||
_write_source.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
_write_source = boost::dynamic_pointer_cast<SMFSource>(_session.create_midi_source_for_session (0, name ()));
|
_write_source = boost::dynamic_pointer_cast<SMFSource>(_session.create_midi_source_for_session (0, name ()));
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ using namespace PBD;
|
||||||
MidiRegion::MidiRegion (const SourceList& srcs)
|
MidiRegion::MidiRegion (const SourceList& srcs)
|
||||||
: Region (srcs)
|
: Region (srcs)
|
||||||
{
|
{
|
||||||
midi_source(0)->Switched.connect_same_thread (*this, boost::bind (&MidiRegion::switch_source, this, _1));
|
// midi_source(0)->Switched.connect_same_thread (*this, boost::bind (&MidiRegion::switch_source, this, _1));
|
||||||
midi_source(0)->ModelChanged.connect_same_thread (_source_connection, boost::bind (&MidiRegion::model_changed, this));
|
midi_source(0)->ModelChanged.connect_same_thread (_source_connection, boost::bind (&MidiRegion::model_changed, this));
|
||||||
model_changed ();
|
model_changed ();
|
||||||
assert(_name.val().find("/") == string::npos);
|
assert(_name.val().find("/") == string::npos);
|
||||||
|
|
@ -63,7 +63,7 @@ MidiRegion::MidiRegion (boost::shared_ptr<const MidiRegion> other, frameoffset_t
|
||||||
: Region (other, offset, offset_relative)
|
: Region (other, offset, offset_relative)
|
||||||
{
|
{
|
||||||
assert(_name.val().find("/") == string::npos);
|
assert(_name.val().find("/") == string::npos);
|
||||||
midi_source(0)->Switched.connect_same_thread (*this, boost::bind (&MidiRegion::switch_source, this, _1));
|
// midi_source(0)->Switched.connect_same_thread (*this, boost::bind (&MidiRegion::switch_source, this, _1));
|
||||||
midi_source(0)->ModelChanged.connect_same_thread (_source_connection, boost::bind (&MidiRegion::model_changed, this));
|
midi_source(0)->ModelChanged.connect_same_thread (_source_connection, boost::bind (&MidiRegion::model_changed, this));
|
||||||
model_changed ();
|
model_changed ();
|
||||||
}
|
}
|
||||||
|
|
@ -258,8 +258,11 @@ MidiRegion::switch_source(boost::shared_ptr<Source> src)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MIDI regions have only one source
|
// MIDI regions have only one source
|
||||||
_sources.clear();
|
SourceList srcs;
|
||||||
_sources.push_back(msrc);
|
srcs.push_back (msrc);
|
||||||
|
|
||||||
|
drop_sources ();
|
||||||
|
use_sources (srcs);
|
||||||
|
|
||||||
set_name (msrc->name());
|
set_name (msrc->name());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -288,9 +288,19 @@ MidiSource::clone (Evoral::MusicalTime begin, Evoral::MusicalTime end)
|
||||||
void
|
void
|
||||||
MidiSource::session_saved()
|
MidiSource::session_saved()
|
||||||
{
|
{
|
||||||
|
/* this writes a copy of the data to disk.
|
||||||
|
XXX do we need to do this every time?
|
||||||
|
*/
|
||||||
|
|
||||||
flush_midi();
|
flush_midi();
|
||||||
|
cerr << name() << " @ " << this << " length at save = " << _length_beats << endl;
|
||||||
|
|
||||||
|
#if 0 // old style: clone the source if necessary on every session save
|
||||||
|
// and switch to the new source
|
||||||
|
|
||||||
if (_model && _model->edited()) {
|
if (_model && _model->edited()) {
|
||||||
|
cerr << "Model exists and is edited\n";
|
||||||
|
|
||||||
boost::shared_ptr<MidiSource> newsrc = clone ();
|
boost::shared_ptr<MidiSource> newsrc = clone ();
|
||||||
|
|
||||||
if (newsrc) {
|
if (newsrc) {
|
||||||
|
|
@ -298,6 +308,7 @@ MidiSource::session_saved()
|
||||||
Switched (newsrc); /* EMIT SIGNAL */
|
Switched (newsrc); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -1381,6 +1381,7 @@ void
|
||||||
Region::set_master_sources (const SourceList& srcs)
|
Region::set_master_sources (const SourceList& srcs)
|
||||||
{
|
{
|
||||||
for (SourceList::const_iterator i = _master_sources.begin (); i != _master_sources.end(); ++i) {
|
for (SourceList::const_iterator i = _master_sources.begin (); i != _master_sources.end(); ++i) {
|
||||||
|
cerr << name() << " " << id() << " DEC M SMS\n";
|
||||||
(*i)->dec_use_count ();
|
(*i)->dec_use_count ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1535,12 +1536,14 @@ void
|
||||||
Region::drop_sources ()
|
Region::drop_sources ()
|
||||||
{
|
{
|
||||||
for (SourceList::const_iterator i = _sources.begin (); i != _sources.end(); ++i) {
|
for (SourceList::const_iterator i = _sources.begin (); i != _sources.end(); ++i) {
|
||||||
|
cerr << name() << " " << id() << " DEC DS\n";
|
||||||
(*i)->dec_use_count ();
|
(*i)->dec_use_count ();
|
||||||
}
|
}
|
||||||
|
|
||||||
_sources.clear ();
|
_sources.clear ();
|
||||||
|
|
||||||
for (SourceList::const_iterator i = _master_sources.begin (); i != _master_sources.end(); ++i) {
|
for (SourceList::const_iterator i = _master_sources.begin (); i != _master_sources.end(); ++i) {
|
||||||
|
cerr << name() << " " << id() << " DEC MDS \n";
|
||||||
(*i)->dec_use_count ();
|
(*i)->dec_use_count ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,6 @@ RegionFactory::create (boost::shared_ptr<const Region> region)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
cerr << "Pure copy constructor region " << ret << " named " << ret->name() << endl;
|
|
||||||
map_add (ret);
|
map_add (ret);
|
||||||
|
|
||||||
/* pure copy constructor - no property list */
|
/* pure copy constructor - no property list */
|
||||||
|
|
@ -125,7 +124,6 @@ RegionFactory::create (boost::shared_ptr<Region> region, frameoffset_t offset, b
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret->set_properties (plist);
|
ret->set_properties (plist);
|
||||||
cerr << "Partial copy constructor region\n";
|
|
||||||
map_add (ret);
|
map_add (ret);
|
||||||
|
|
||||||
if (announce) {
|
if (announce) {
|
||||||
|
|
@ -165,7 +163,6 @@ RegionFactory::create (boost::shared_ptr<Region> region, const SourceList& srcs,
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|
||||||
ret->set_properties (plist);
|
ret->set_properties (plist);
|
||||||
cerr << "New sources copy constructor region\n";
|
|
||||||
map_add (ret);
|
map_add (ret);
|
||||||
|
|
||||||
if (announce) {
|
if (announce) {
|
||||||
|
|
@ -211,7 +208,6 @@ RegionFactory::create (const SourceList& srcs, const PropertyList& plist, bool a
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|
||||||
ret->set_properties (plist);
|
ret->set_properties (plist);
|
||||||
cerr << "de-novo constructor region " << ret << " named " << ret->name() << endl;
|
|
||||||
map_add (ret);
|
map_add (ret);
|
||||||
|
|
||||||
if (announce) {
|
if (announce) {
|
||||||
|
|
@ -285,8 +281,6 @@ RegionFactory::map_add (boost::shared_ptr<Region> r)
|
||||||
boost::bind (&RegionFactory::region_changed, _1, boost::weak_ptr<Region> (r))
|
boost::bind (&RegionFactory::region_changed, _1, boost::weak_ptr<Region> (r))
|
||||||
);
|
);
|
||||||
|
|
||||||
cerr << "Added region with ID = " << r->id() << " named " << r->name() << endl;
|
|
||||||
|
|
||||||
update_region_name_map (r);
|
update_region_name_map (r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -298,7 +292,6 @@ RegionFactory::map_remove (boost::shared_ptr<Region> r)
|
||||||
|
|
||||||
if (i != region_map.end()) {
|
if (i != region_map.end()) {
|
||||||
region_map.erase (i);
|
region_map.erase (i);
|
||||||
cerr << "Removed region with ID = " << r->id() << " named " << r->name() << endl;;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -313,10 +306,8 @@ RegionFactory::map_remove_with_equivalents (boost::shared_ptr<Region> r)
|
||||||
++tmp;
|
++tmp;
|
||||||
|
|
||||||
if (r->region_list_equivalent (i->second)) {
|
if (r->region_list_equivalent (i->second)) {
|
||||||
cerr << "Removed equivalent region " << i->second->name() << '/' << i->first << endl;
|
|
||||||
region_map.erase (i);
|
region_map.erase (i);
|
||||||
} else if (r == i->second) {
|
} else if (r == i->second) {
|
||||||
cerr << "Removed actual region " << i->second->name() << '/' << i->first << endl;
|
|
||||||
region_map.erase (i);
|
region_map.erase (i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,7 @@ SMFSource::SMFSource (Session& s, const XMLNode& node, bool must_exist)
|
||||||
SMFSource::~SMFSource ()
|
SMFSource::~SMFSource ()
|
||||||
{
|
{
|
||||||
if (removable()) {
|
if (removable()) {
|
||||||
|
cerr << name() << " is removable, empty ? " << empty() << " UC " << use_count() << endl;
|
||||||
unlink (_path.c_str());
|
unlink (_path.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -383,6 +384,7 @@ SMFSource::mark_streaming_write_completed ()
|
||||||
MidiSource::mark_streaming_write_completed();
|
MidiSource::mark_streaming_write_completed();
|
||||||
|
|
||||||
if (!writable()) {
|
if (!writable()) {
|
||||||
|
cerr << "\n\n\n[[[[[[[[[ This SMFS is not writable! ]]]]]]]]]]]\n\n\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -495,6 +497,11 @@ SMFSource::destroy_model ()
|
||||||
void
|
void
|
||||||
SMFSource::flush_midi ()
|
SMFSource::flush_midi ()
|
||||||
{
|
{
|
||||||
|
if (!writable()) {
|
||||||
|
cerr << "\n\n\n\n " << name() << " CANNOT FLUSH - not writable\n\n\n\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Evoral::SMF::end_write();
|
Evoral::SMF::end_write();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -272,3 +272,17 @@ Source::set_allow_remove_if_empty (bool yn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Source::dec_use_count ()
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
gint oldval = g_atomic_int_exchange_and_add (&_use_count, -1);
|
||||||
|
cerr << "Bad use dec for " << name() << endl;
|
||||||
|
if (oldval <= 0) {
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
assert (oldval > 0);
|
||||||
|
#else
|
||||||
|
g_atomic_int_exchange_and_add (&_use_count, -1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -285,8 +285,8 @@ SourceFactory::createWritable (DataType type, Session& s, const std::string& pat
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
} else if (type == DataType::MIDI) {
|
} else if (type == DataType::MIDI) {
|
||||||
|
// XXX writable flags should belong to MidiSource too
|
||||||
Source* src = new SMFSource (s, path, Source::Flag(0));
|
Source* src = new SMFSource (s, path, SndFileSource::default_writable_flags);
|
||||||
// boost_debug_shared_ptr_mark_interesting (src, "Source");
|
// boost_debug_shared_ptr_mark_interesting (src, "Source");
|
||||||
boost::shared_ptr<Source> ret (src);
|
boost::shared_ptr<Source> ret (src);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -275,7 +275,6 @@ SMF::begin_write()
|
||||||
void
|
void
|
||||||
SMF::end_write() THROW_FILE_ERROR
|
SMF::end_write() THROW_FILE_ERROR
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
/* don't create empty MIDI files
|
/* don't create empty MIDI files
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -283,7 +282,6 @@ SMF::end_write() THROW_FILE_ERROR
|
||||||
if (smf_peek_next_event (_smf) == 0) {
|
if (smf_peek_next_event (_smf) == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
PBD::StdioFileDescriptor d (_file_path, "w+");
|
PBD::StdioFileDescriptor d (_file_path, "w+");
|
||||||
FILE* f = d.allocate ();
|
FILE* f = d.allocate ();
|
||||||
|
|
@ -291,6 +289,8 @@ SMF::end_write() THROW_FILE_ERROR
|
||||||
throw FileError ();
|
throw FileError ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cerr << "\n\n\nSAVE SMF to " << _file_path << "\n\n";
|
||||||
|
|
||||||
if (smf_save(_smf, f) != 0) {
|
if (smf_save(_smf, f) != 0) {
|
||||||
throw FileError();
|
throw FileError();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue