pthread_mutex_init (&_freewheel_mutex, 0);
pthread_cond_init (&_freewheel_signal, 0);
+ _port_connection_queue.reserve (128);
+
_pcmio = new PortAudioIO ();
_midiio = new WinMMEMidiIO ();
}
}
/* reset internal state */
+ assert (_run == false);
+ _run = false;
_dsp_load = 0;
_freewheeling = false;
_freewheel = false;
_measure_latency = for_latency_measurement;
- _run = true;
_port_change_flag = false;
if (_midi_driver_option == winmme_driver_name) {
if (register_system_midi_ports () != 0) {
DEBUG_PORTS("Failed to register system midi ports.\n")
- _run = false;
return PortRegistrationError;
}
if (register_system_audio_ports()) {
DEBUG_PORTS("Failed to register system audio ports.\n");
- _run = false;
return PortRegistrationError;
}
if (engine.reestablish_ports ()) {
DEBUG_PORTS("Could not re-establish ports.\n");
- _run = false;
return PortReconnectError;
}
- engine.reconnect_ports ();
_run = true;
+
+ engine.reconnect_ports ();
_port_change_flag = false;
if (_use_blocking_api) {
stop();
return ProcessThreadStartError;
}
+
+ /* wait for backend to become active */
+ int timeout = 5000;
+ while (!_active && --timeout > 0) { Glib::usleep (1000); }
+
+ if (timeout == 0 || !_active) {
+ PBD::error << _("PortAudio:: failed to start device.") << endmsg;
+ stop ();
+ return ProcessThreadStartError;
+ }
}
return NoError;
ThreadData* td = new ThreadData (this, func, stacksize);
- if (_realtime_pthread_create (SCHED_FIFO, -21, stacksize,
+ if (_realtime_pthread_create (SCHED_FIFO, -22, stacksize,
&thread_id, portaudio_process_thread, td)) {
pthread_attr_init (&attr);
pthread_attr_setstacksize (&attr, stacksize);
int
PortAudioBackend::midi_event_get (
pframes_t& timestamp,
- size_t& size, uint8_t** buf, void* port_buffer,
+ size_t& size, uint8_t const** buf, void* port_buffer,
uint32_t event_index)
{
if (!buf || !port_buffer) return -1;
if (event_index >= source.size ()) {
return -1;
}
- PortMidiEvent * const event = source[event_index].get ();
+ PortMidiEvent const& event = source[event_index];
- timestamp = event->timestamp ();
- size = event->size ();
- *buf = event->data ();
+ timestamp = event.timestamp ();
+ size = event.size ();
+ *buf = event.data ();
return 0;
}
{
if (!buffer || !port_buffer) return -1;
PortMidiBuffer& dst = * static_cast<PortMidiBuffer*>(port_buffer);
- if (dst.size () && (pframes_t)dst.back ()->timestamp () > timestamp) {
+#ifndef NDEBUG
+ if (dst.size () && (pframes_t)dst.back ().timestamp () > timestamp) {
// nevermind, ::get_buffer() sorts events
DEBUG_MIDI (string_compose ("PortMidiBuffer: unordered event: %1 > %2\n",
- (pframes_t)dst.back ()->timestamp (),
+ (pframes_t)dst.back ().timestamp (),
timestamp));
}
- dst.push_back (boost::shared_ptr<PortMidiEvent>(new PortMidiEvent (timestamp, buffer, size)));
+#endif
+ dst.push_back (PortMidiEvent (timestamp, buffer, size));
return 0;
}
void*
PortAudioBackend::get_buffer (PortEngine::PortHandle port, pframes_t nframes)
{
- if (!port || !valid_port (port)) return NULL;
+ assert (port);
+ assert (valid_port (port));
+ if (!port || !valid_port (port)) return NULL; // XXX remove me
return static_cast<PamPort*>(port)->get_buffer (nframes);
}
mbuf->clear();
uint64_t timestamp;
pframes_t sample_offset;
- uint8_t data[256];
+ uint8_t data[MaxWinMidiEventSize];
size_t size = sizeof(data);
while (_midiio->dequeue_input_event(i,
_cycle_timer.get_start(),
for (PortMidiBuffer::const_iterator mit = src->begin(); mit != src->end();
++mit) {
uint64_t timestamp =
- _cycle_timer.timestamp_from_sample_offset((*mit)->timestamp());
+ _cycle_timer.timestamp_from_sample_offset(mit->timestamp());
DEBUG_MIDI(string_compose("Queuing outgoing MIDI data for device: "
"%1 sample_offset: %2 timestamp: %3, size: %4\n",
_midiio->get_outputs()[i]->name(),
- (*mit)->timestamp(),
+ mit->timestamp(),
timestamp,
- (*mit)->size()));
- _midiio->enqueue_output_event(i, timestamp, (*mit)->data(), (*mit)->size());
+ mit->size()));
+ _midiio->enqueue_output_event(i, timestamp, mit->data(), mit->size());
}
}
}
{
_buffer[0].clear ();
_buffer[1].clear ();
+
+ _buffer[0].reserve (256);
+ _buffer[1].reserve (256);
}
PortMidiPort::~PortMidiPort () { }
struct MidiEventSorter {
- bool operator() (const boost::shared_ptr<PortMidiEvent>& a, const boost::shared_ptr<PortMidiEvent>& b) {
- return *a < *b;
+ bool operator() (PortMidiEvent const& a, PortMidiEvent const& b) {
+ return a < b;
}
};
++i) {
const PortMidiBuffer * src = static_cast<const PortMidiPort*>(*i)->const_buffer ();
for (PortMidiBuffer::const_iterator it = src->begin (); it != src->end (); ++it) {
- (_buffer[_bufperiod]).push_back (boost::shared_ptr<PortMidiEvent>(new PortMidiEvent (**it)));
+ (_buffer[_bufperiod]).push_back (*it);
}
}
std::stable_sort ((_buffer[_bufperiod]).begin (), (_buffer[_bufperiod]).end (), MidiEventSorter());
PortMidiEvent::PortMidiEvent (const pframes_t timestamp, const uint8_t* data, size_t size)
: _size (size)
, _timestamp (timestamp)
- , _data (0)
{
- if (size > 0) {
- _data = (uint8_t*) malloc (size);
+ if (size > 0 && size < MaxWinMidiEventSize) {
memcpy (_data, data, size);
}
}
PortMidiEvent::PortMidiEvent (const PortMidiEvent& other)
: _size (other.size ())
, _timestamp (other.timestamp ())
- , _data (0)
{
- if (other.size () && other.const_data ()) {
- _data = (uint8_t*) malloc (other.size ());
- memcpy (_data, other.const_data (), other.size ());
+ if (other._size > 0) {
+ assert (other._size < MaxWinMidiEventSize);
+ memcpy (_data, other._data, other._size);
}
};
-
-PortMidiEvent::~PortMidiEvent () {
- free (_data);
-};