Route::set_meter_point() is now conceptually RT safe, although it still takes a write lock on the processor list. this allows it to be called when setting rec-enable status on a route. not thoroughly tested, and still incomplete - single route rec-enables should probably use this pathway, and there is still no cross-thread cleanup from an RT route op request
git-svn-id: svn://localhost/ardour2/branches/3.0@6320 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
1a44701643
commit
8dab33c609
@ -59,6 +59,19 @@ public:
|
|||||||
|
|
||||||
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
|
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
|
||||||
bool configure_io (ChanCount in, ChanCount out);
|
bool configure_io (ChanCount in, ChanCount out);
|
||||||
|
|
||||||
|
/* special method for meter, to ensure that it can always handle the maximum
|
||||||
|
number of streams in the route, no matter where we put it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void reset_max_channels (const ChanCount&);
|
||||||
|
|
||||||
|
/* tell the meter than no matter how many channels it can handle,
|
||||||
|
`in' is the number it is actually going be handling from
|
||||||
|
now on.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void reflect_inputs (const ChanCount& in);
|
||||||
|
|
||||||
/** Compute peaks */
|
/** Compute peaks */
|
||||||
void run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nframes_t nframes, bool);
|
void run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nframes_t nframes, bool);
|
||||||
@ -80,10 +93,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
XMLNode& state (bool full);
|
XMLNode& state (bool full);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class IO;
|
friend class IO;
|
||||||
|
|
||||||
|
uint32_t current_meters;
|
||||||
|
|
||||||
std::vector<float> _peak_power;
|
std::vector<float> _peak_power;
|
||||||
std::vector<float> _visible_peak_power;
|
std::vector<float> _visible_peak_power;
|
||||||
std::vector<float> _max_peak_power;
|
std::vector<float> _max_peak_power;
|
||||||
|
@ -153,7 +153,7 @@ class Route : public SessionObject, public AutomatableControls
|
|||||||
void drop_route_group (void *);
|
void drop_route_group (void *);
|
||||||
RouteGroup *route_group () const { return _route_group; }
|
RouteGroup *route_group () const { return _route_group; }
|
||||||
|
|
||||||
virtual void set_meter_point (MeterPoint, void *src);
|
void set_meter_point (MeterPoint, void *src);
|
||||||
MeterPoint meter_point() const { return _meter_point; }
|
MeterPoint meter_point() const { return _meter_point; }
|
||||||
void meter ();
|
void meter ();
|
||||||
|
|
||||||
|
@ -90,8 +90,6 @@ class Track : public Route
|
|||||||
bool record_enabled() const;
|
bool record_enabled() const;
|
||||||
void set_record_enable (bool yn, void *src);
|
void set_record_enable (bool yn, void *src);
|
||||||
|
|
||||||
void set_meter_point (MeterPoint, void* src);
|
|
||||||
|
|
||||||
sigc::signal<void> DiskstreamChanged;
|
sigc::signal<void> DiskstreamChanged;
|
||||||
sigc::signal<void> FreezeChange;
|
sigc::signal<void> FreezeChange;
|
||||||
|
|
||||||
|
@ -65,6 +65,12 @@ Metering::update_meters()
|
|||||||
Meter(); /* EMIT SIGNAL */
|
Meter(); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PeakMeter::PeakMeter (Session& s, const XMLNode& node)
|
||||||
|
: Processor (s, node)
|
||||||
|
{
|
||||||
|
current_meters = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** Get peaks from @a bufs
|
/** Get peaks from @a bufs
|
||||||
* Input acceptance is lenient - the first n buffers from @a bufs will
|
* Input acceptance is lenient - the first n buffers from @a bufs will
|
||||||
* be metered, where n was set by the last call to setup(), excess meters will
|
* be metered, where n was set by the last call to setup(), excess meters will
|
||||||
@ -115,11 +121,6 @@ PeakMeter::run (BufferSet& bufs, sframes_t /*start_frame*/, sframes_t /*end_fram
|
|||||||
_active = _pending_active;
|
_active = _pending_active;
|
||||||
}
|
}
|
||||||
|
|
||||||
PeakMeter::PeakMeter (Session& s, const XMLNode& node)
|
|
||||||
: Processor (s, node)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PeakMeter::reset ()
|
PeakMeter::reset ()
|
||||||
{
|
{
|
||||||
@ -150,7 +151,21 @@ PeakMeter::configure_io (ChanCount in, ChanCount out)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t limit = in.n_total();
|
current_meters = in.n_total ();
|
||||||
|
|
||||||
|
return Processor::configure_io (in, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PeakMeter::reflect_inputs (const ChanCount& in)
|
||||||
|
{
|
||||||
|
current_meters = in.n_total ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PeakMeter::reset_max_channels (const ChanCount& chn)
|
||||||
|
{
|
||||||
|
uint32_t limit = chn.n_total();
|
||||||
|
|
||||||
while (_peak_power.size() > limit) {
|
while (_peak_power.size() > limit) {
|
||||||
_peak_power.pop_back();
|
_peak_power.pop_back();
|
||||||
@ -167,8 +182,6 @@ PeakMeter::configure_io (ChanCount in, ChanCount out)
|
|||||||
assert(_peak_power.size() == limit);
|
assert(_peak_power.size() == limit);
|
||||||
assert(_visible_peak_power.size() == limit);
|
assert(_visible_peak_power.size() == limit);
|
||||||
assert(_max_peak_power.size() == limit);
|
assert(_max_peak_power.size() == limit);
|
||||||
|
|
||||||
return Processor::configure_io (in, out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** To be driven by the Meter signal from IO.
|
/** To be driven by the Meter signal from IO.
|
||||||
@ -185,7 +198,7 @@ PeakMeter::meter ()
|
|||||||
|
|
||||||
assert(_visible_peak_power.size() == _peak_power.size());
|
assert(_visible_peak_power.size() == _peak_power.size());
|
||||||
|
|
||||||
const size_t limit = _peak_power.size();
|
const size_t limit = min (_peak_power.size(), (size_t) current_meters);
|
||||||
|
|
||||||
for (size_t n = 0; n < limit; ++n) {
|
for (size_t n = 0; n < limit; ++n) {
|
||||||
|
|
||||||
|
@ -80,8 +80,8 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type)
|
|||||||
/* add standard processors other than amp (added by ::init()) */
|
/* add standard processors other than amp (added by ::init()) */
|
||||||
|
|
||||||
_meter.reset (new PeakMeter (_session));
|
_meter.reset (new PeakMeter (_session));
|
||||||
_meter->set_display_to_user (_meter_point == MeterCustom);
|
_meter->set_display_to_user (false);
|
||||||
add_processor (_meter, PreFader);
|
add_processor (_meter, PostFader);
|
||||||
|
|
||||||
if (_flags & ControlOut) {
|
if (_flags & ControlOut) {
|
||||||
/* where we listen to tracks */
|
/* where we listen to tracks */
|
||||||
@ -1479,6 +1479,10 @@ Route::configure_processors_unlocked (ProcessorStreams* err)
|
|||||||
out = c->second;
|
out = c->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_meter) {
|
||||||
|
_meter->reset_max_channels (processor_max_streams);
|
||||||
|
}
|
||||||
|
|
||||||
/* make sure we have sufficient scratch buffers to cope with the new processor
|
/* make sure we have sufficient scratch buffers to cope with the new processor
|
||||||
configuration */
|
configuration */
|
||||||
_session.ensure_buffers (n_process_buffers ());
|
_session.ensure_buffers (n_process_buffers ());
|
||||||
@ -2667,6 +2671,8 @@ Route::flush_processors ()
|
|||||||
void
|
void
|
||||||
Route::set_meter_point (MeterPoint p, void *src)
|
Route::set_meter_point (MeterPoint p, void *src)
|
||||||
{
|
{
|
||||||
|
/* CAN BE CALLED FROM PROCESS CONTEXT */
|
||||||
|
|
||||||
if (_meter_point == p) {
|
if (_meter_point == p) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2675,54 +2681,61 @@ Route::set_meter_point (MeterPoint p, void *src)
|
|||||||
|
|
||||||
{
|
{
|
||||||
Glib::RWLock::WriterLock lm (_processor_lock);
|
Glib::RWLock::WriterLock lm (_processor_lock);
|
||||||
ProcessorList as_it_was (_processors);
|
|
||||||
|
|
||||||
if (p != MeterCustom) {
|
if (p != MeterCustom) {
|
||||||
// Move meter in the processors list to reflect the new position
|
// Move meter in the processors list to reflect the new position
|
||||||
ProcessorList::iterator loc = find(_processors.begin(), _processors.end(), _meter);
|
ProcessorList::iterator loc = find (_processors.begin(), _processors.end(), _meter);
|
||||||
_processors.erase(loc);
|
_processors.erase(loc);
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case MeterInput:
|
case MeterInput:
|
||||||
loc = _processors.begin();
|
loc = _processors.begin();
|
||||||
break;
|
break;
|
||||||
case MeterPreFader:
|
case MeterPreFader:
|
||||||
loc = find(_processors.begin(), _processors.end(), _amp);
|
loc = find (_processors.begin(), _processors.end(), _amp);
|
||||||
break;
|
break;
|
||||||
case MeterPostFader:
|
case MeterPostFader:
|
||||||
loc = _processors.end();
|
loc = _processors.end();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_processors.insert(loc, _meter);
|
|
||||||
|
|
||||||
if (configure_processors_unlocked (0)) {
|
ChanCount m_in;
|
||||||
_processors = as_it_was;
|
|
||||||
configure_processors_unlocked (0); // it worked before we tried to add it ...
|
if (loc == _processors.begin()) {
|
||||||
return;
|
m_in = _input->n_ports();
|
||||||
|
} else {
|
||||||
|
ProcessorList::iterator before = loc;
|
||||||
|
--before;
|
||||||
|
m_in = (*before)->output_streams ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_meter->reflect_inputs (m_in);
|
||||||
|
|
||||||
|
_processors.insert (loc, _meter);
|
||||||
|
|
||||||
|
/* we do not need to reconfigure the processors, because the meter
|
||||||
|
(a) is always ready to handle processor_max_streams
|
||||||
|
(b) is always an N-in/N-out processor, and thus moving
|
||||||
|
it doesn't require any changes to the other processors.
|
||||||
|
*/
|
||||||
|
|
||||||
_meter->set_display_to_user (false);
|
_meter->set_display_to_user (false);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// just make it visible and let the user move it
|
// just make it visible and let the user move it
|
||||||
|
|
||||||
_meter->set_display_to_user (true);
|
_meter->set_display_to_user (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_meter_point = p;
|
_meter_point = p;
|
||||||
meter_change (src); /* EMIT SIGNAL */
|
meter_change (src); /* EMIT SIGNAL */
|
||||||
|
|
||||||
/* the meter has visibly changed if it is not visible to the user, or if it was and now isn't */
|
bool const meter_visibly_changed = (_meter->display_to_user() != meter_was_visible_to_user);
|
||||||
bool const meter_visibly_changed = _meter->display_to_user() || meter_was_visible_to_user;
|
|
||||||
|
|
||||||
processors_changed (RouteProcessorChange (RouteProcessorChange::MeterPointChange, meter_visibly_changed)); /* EMIT SIGNAL */
|
processors_changed (RouteProcessorChange (RouteProcessorChange::MeterPointChange, meter_visibly_changed)); /* EMIT SIGNAL */
|
||||||
|
|
||||||
_session.set_dirty ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1164,8 +1164,9 @@ Session::disable_record (bool rt_context, bool force)
|
|||||||
// FIXME: timestamp correct? [DR]
|
// FIXME: timestamp correct? [DR]
|
||||||
// FIXME FIXME FIXME: rt_context? this must be called in the process thread.
|
// FIXME FIXME FIXME: rt_context? this must be called in the process thread.
|
||||||
// does this /need/ to be sent in all cases?
|
// does this /need/ to be sent in all cases?
|
||||||
if (rt_context)
|
if (rt_context) {
|
||||||
deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
|
deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
|
||||||
|
}
|
||||||
|
|
||||||
if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
|
if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
|
||||||
boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
|
boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
|
||||||
@ -3647,13 +3648,21 @@ Session::record_enable_change_all (bool yn)
|
|||||||
void
|
void
|
||||||
Session::do_record_enable_change_all (RouteList* rl, bool yn)
|
Session::do_record_enable_change_all (RouteList* rl, bool yn)
|
||||||
{
|
{
|
||||||
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
|
for (RouteList::iterator i = rl->begin(); i != rl->end(); ) {
|
||||||
boost::shared_ptr<Track> t;
|
boost::shared_ptr<Track> t;
|
||||||
|
|
||||||
if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
|
if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
|
||||||
t->set_record_enable (yn, this);
|
t->set_record_enable (yn, this);
|
||||||
}
|
if (t->meter_point() == MeterCustom) {
|
||||||
|
/* don't change metering for this track */
|
||||||
|
i = rl->erase (i);
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_dirty ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -69,7 +69,7 @@ SessionEvent::operator delete (void *ptr, size_t /*size*/)
|
|||||||
{
|
{
|
||||||
Pool* p = pool->per_thread_pool ();
|
Pool* p = pool->per_thread_pool ();
|
||||||
SessionEvent* ev = static_cast<SessionEvent*> (ptr);
|
SessionEvent* ev = static_cast<SessionEvent*> (ptr);
|
||||||
|
|
||||||
if (p == ev->own_pool) {
|
if (p == ev->own_pool) {
|
||||||
p->release (ptr);
|
p->release (ptr);
|
||||||
} else {
|
} else {
|
||||||
@ -278,3 +278,10 @@ SessionEventManager::_clear_event_type (SessionEvent::Type type)
|
|||||||
set_next_event ();
|
set_next_event ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void
|
||||||
|
Session::process_rtop (SessionEvent* ev)
|
||||||
|
{
|
||||||
|
ev->rt_return (ev->rt_slot ());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -1082,6 +1082,227 @@ Session::_midi_thread_work (void* arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void
|
||||||
|
Session::midi_thread_work ()
|
||||||
|
{
|
||||||
|
MIDIRequest* request;
|
||||||
|
GPollFD pfd[4];
|
||||||
|
int nfds = 0;
|
||||||
|
int timeout;
|
||||||
|
int fds_ready;
|
||||||
|
struct sched_param rtparam;
|
||||||
|
int x;
|
||||||
|
bool restart;
|
||||||
|
vector<MIDI::Port*> ports;
|
||||||
|
|
||||||
|
PBD::notify_gui_about_thread_creation (pthread_self(), X_("MIDI"), 2048);
|
||||||
|
SessionEvent::create_per_thread_pool (X_("MIDI I/O"), 128);
|
||||||
|
|
||||||
|
memset (&rtparam, 0, sizeof (rtparam));
|
||||||
|
rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
|
||||||
|
|
||||||
|
if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
|
||||||
|
// do we care? not particularly.
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set up the port vector; 5 is the largest possible size for now */
|
||||||
|
|
||||||
|
ports.assign (5, (MIDI::Port*) 0);
|
||||||
|
|
||||||
|
GMainContext* main_context = g_main_context_new ();
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
nfds = 0;
|
||||||
|
|
||||||
|
gpfd[nfds].fd = midi_request_pipe[0];
|
||||||
|
gpfd[nfds].events = POLLIN|POLLHUP|POLLERR;
|
||||||
|
nfds++;
|
||||||
|
|
||||||
|
if (Config->get_mmc_control() && _mmc_port && _mmc_port->selectable() >= 0) {
|
||||||
|
gpfd[nfds].fd = _mmc_port->selectable();
|
||||||
|
gpfd[nfds].events = POLLIN|POLLHUP|POLLERR;
|
||||||
|
ports[nfds] = _mmc_port;
|
||||||
|
g_main_context_add_poll (&gpfd[nfds]);
|
||||||
|
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("set up port #%1 for mmc @ %2\n", nfds, _mmc_port));
|
||||||
|
nfds++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if MTC is being handled on a different port from MMC
|
||||||
|
or we are not handling MMC at all, poll
|
||||||
|
the relevant port.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (_mtc_port && (_mtc_port != _mmc_port || !Config->get_mmc_control()) && _mtc_port->selectable() >= 0) {
|
||||||
|
gpfd[nfds].fd = _mtc_port->selectable();
|
||||||
|
gpfd[nfds].events = POLLIN|POLLHUP|POLLERR;
|
||||||
|
ports[nfds] = _mtc_port;
|
||||||
|
g_main_context_add_poll (&gpfd[nfds]);
|
||||||
|
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("set up port #%1 for mtc @ %2\n", nfds, _mtc_port));
|
||||||
|
nfds++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_midi_clock_port && (_midi_clock_port != _mmc_port || !Config->get_mmc_control()) && _midi_clock_port->selectable() >= 0) {
|
||||||
|
gpfd[nfds].fd = _midi_clock_port->selectable();
|
||||||
|
gpfd[nfds].events = POLLIN|POLLHUP|POLLERR;
|
||||||
|
ports[nfds] = _midi_clock_port;
|
||||||
|
g_main_context_add_poll (&gpfd[nfds]);
|
||||||
|
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("set up port #%1 for midi clock @ %2\n", nfds, _midi_clock_port));
|
||||||
|
nfds++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we are using MMC control, we obviously have to listen
|
||||||
|
the relevant port.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (_midi_port && (_midi_port != _mmc_port || !Config->get_mmc_control()) && (_midi_port != _mtc_port) && _midi_port->selectable() >= 0) {
|
||||||
|
gpfd[nfds].fd = _midi_port->selectable();
|
||||||
|
gpfd[nfds].events = POLLIN|POLLHUP|POLLERR;
|
||||||
|
ports[nfds] = _midi_port;
|
||||||
|
g_main_context_add_poll (&gpfd[nfds]);
|
||||||
|
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("set up port #%1 for midi @ %2\n", nfds, _midi_port));
|
||||||
|
nfds++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!midi_timeouts.empty()) {
|
||||||
|
timeout = 100; /* 10msecs */
|
||||||
|
} else {
|
||||||
|
timeout = -1; /* if there is no data, we don't care */
|
||||||
|
}
|
||||||
|
|
||||||
|
again:
|
||||||
|
|
||||||
|
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("MIDI poll on %1 fds for %2\n", nfds, timeout));
|
||||||
|
if (g_poll (gpfd, nfds, timeout) < 0) {
|
||||||
|
if (errno == EINTR) {
|
||||||
|
/* gdb at work, perhaps */
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
|
||||||
|
error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nframes64_t now = engine().frame_time();
|
||||||
|
|
||||||
|
DEBUG_TRACE (DEBUG::MidiIO, "MIDI thread awake\n");
|
||||||
|
|
||||||
|
fds_ready = 0;
|
||||||
|
|
||||||
|
/* check the transport request pipe */
|
||||||
|
|
||||||
|
if (gpfd[0].revents & ~POLLIN) {
|
||||||
|
error << _("Error on transport thread request pipe") << endmsg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gpfd[0].revents & POLLIN) {
|
||||||
|
|
||||||
|
char foo[16];
|
||||||
|
|
||||||
|
DEBUG_TRACE (DEBUG::MidiIO, "MIDI request FIFO ready\n");
|
||||||
|
fds_ready++;
|
||||||
|
|
||||||
|
/* empty the pipe of all current requests */
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
size_t nread = read (midi_request_pipe[0], &foo, sizeof (foo));
|
||||||
|
|
||||||
|
if (nread > 0) {
|
||||||
|
if ((size_t) nread < sizeof (foo)) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (nread == 0) {
|
||||||
|
break;
|
||||||
|
} else if (errno == EAGAIN) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
fatal << _("Error reading from transport request pipe") << endmsg;
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (midi_requests.read (&request, 1) == 1) {
|
||||||
|
|
||||||
|
switch (request->type) {
|
||||||
|
case MIDIRequest::PortChange:
|
||||||
|
/* restart poll with new ports */
|
||||||
|
DEBUG_TRACE (DEBUG::MidiIO, "rebind\n");
|
||||||
|
restart = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MIDIRequest::Quit:
|
||||||
|
delete request;
|
||||||
|
DEBUG_TRACE (DEBUG::MidiIO, "thread quit\n");
|
||||||
|
pthread_exit_pbd (0);
|
||||||
|
/*NOTREACHED*/
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
delete request;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (restart) {
|
||||||
|
DEBUG_TRACE (DEBUG::MidiIO, "ports changed, restart poll\n");
|
||||||
|
restart = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now read the rest of the ports */
|
||||||
|
|
||||||
|
for (int p = 1; p < nfds; ++p) {
|
||||||
|
|
||||||
|
DEBUG_STR_SET(foo, "port #%1 revents = ");
|
||||||
|
DEBUG_STR(foo) << hex << pfd[p].revents << dec << endl;
|
||||||
|
DEBUG_TRACE (DEBUG::MidiIO, string_compose (DEBUG_STR(foo).str(), p));
|
||||||
|
|
||||||
|
if ((pfd[p].revents & ~POLLIN)) {
|
||||||
|
// error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pfd[p].revents & POLLIN) {
|
||||||
|
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("MIDI fd # %1 has data ready @ %2\n", p, now));
|
||||||
|
fds_ready++;
|
||||||
|
ports[p]->parse (now);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_main_context_remove_poll (&gpfd[p]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* timeout driven */
|
||||||
|
|
||||||
|
if (fds_ready < 2 && timeout != -1) {
|
||||||
|
|
||||||
|
DEBUG_TRACE (DEBUG::MidiIO, "Check timeouts\n");
|
||||||
|
for (MidiTimeoutList::iterator i = midi_timeouts.begin(); i != midi_timeouts.end(); ) {
|
||||||
|
|
||||||
|
MidiTimeoutList::iterator tmp;
|
||||||
|
tmp = i;
|
||||||
|
++tmp;
|
||||||
|
|
||||||
|
if (!(*i)()) {
|
||||||
|
midi_timeouts.erase (i);
|
||||||
|
}
|
||||||
|
|
||||||
|
i = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
Session::midi_thread_work ()
|
Session::midi_thread_work ()
|
||||||
{
|
{
|
||||||
|
@ -66,12 +66,6 @@ Track::~Track ()
|
|||||||
DEBUG_TRACE (DEBUG::Destruction, string_compose ("track %1 destructor\n", _name));
|
DEBUG_TRACE (DEBUG::Destruction, string_compose ("track %1 destructor\n", _name));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Track::set_meter_point (MeterPoint p, void *src)
|
|
||||||
{
|
|
||||||
Route::set_meter_point (p, src);
|
|
||||||
}
|
|
||||||
|
|
||||||
XMLNode&
|
XMLNode&
|
||||||
Track::get_state ()
|
Track::get_state ()
|
||||||
{
|
{
|
||||||
@ -192,17 +186,15 @@ Track::set_record_enable (bool yn, void *src)
|
|||||||
|
|
||||||
_diskstream->set_record_enabled (yn);
|
_diskstream->set_record_enabled (yn);
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (_diskstream->record_enabled()) {
|
if (_diskstream->record_enabled()) {
|
||||||
set_meter_point (MeterInput, this);
|
if (_meter_point != MeterCustom) {
|
||||||
|
set_meter_point (MeterInput, this);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
set_meter_point (_saved_meter_point, this);
|
set_meter_point (_saved_meter_point, this);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
cerr << "4\n";
|
|
||||||
_rec_enable_control->Changed ();
|
_rec_enable_control->Changed ();
|
||||||
cerr << "5\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user