24 #include <glibmm/timer.h>
29 #include "midi++/types.h"
40 pthread_t AsyncMIDIPort::_process_thread;
42 #define port_engine AudioEngine::instance()->port_engine()
47 , _currently_in_cycle (false)
48 , _last_write_timestamp (0)
80 for (
size_t n = 0; n < vec.len[0]; ++n, ++evp) {
88 for (
size_t n = 0; n < vec.len[1]; ++n, ++evp) {
93 if ((written = vec.len[0] + vec.len[1]) != 0) {
170 error <<
"Process thread called MIDI::AsyncMIDIPort::drain() - this cannot work" <<
endmsg;
179 Glib::usleep (check_interval_usecs);
199 for (
size_t n = 0; n < msglen; ++n) {
200 _parser->scanner (msg[n]);
208 if (vec.len[0] + vec.len[1] < 1) {
209 error <<
"no space in FIFO for non-process thread MIDI write" <<
endmsg;
214 if (!vec.
buf[0]->owns_buffer()) {
215 vec.
buf[0]->set_buffer (0, 0,
true);
217 vec.
buf[0]->set (msg, msglen, timestamp);
219 if (!vec.
buf[1]->owns_buffer()) {
220 vec.
buf[1]->set_buffer (0, 0,
true);
222 vec.
buf[1]->set (msg, msglen, timestamp);
232 for (
size_t n = 0; n < msglen; ++n) {
233 _parser->scanner (msg[n]);
237 std::cerr <<
"attempting to write MIDI event of " << msglen <<
" MIDI::bytes at time "
239 <<
" (this will not work - needs a code fix)"
253 if (timestamp == 0) {
257 if (mb.
push_back (timestamp, msglen, msg)) {
262 cerr <<
"AsyncMIDIPort (" <<
ARDOUR::Port::name() <<
"): write of " << msglen <<
" @ " << timestamp <<
" failed\n" << endl;
267 cerr <<
"write to JACK midi port failed: not currently in a process cycle." << endl;
289 _parser->set_timestamp (time);
290 for (uint32_t i = 0; i < size; ++i) {
291 _parser->scanner (buffer[i]);
304 read (buf,
sizeof (buf));
RingBuffer< Evoral::Event< double > > output_fifo
void flush_output_fifo(pframes_t)
void cycle_end(pframes_t nframes)
LIBPBD_API void stacktrace(std::ostream &out, int levels=0)
boost::function< framecnt_t(void)> timer
EventRingBuffer< MIDI::timestamp_t > input_fifo
Glib::Threads::Mutex output_fifo_lock
bool sends_output() const
LIBPBD_API Transmitter error
void get_read_vector(rw_vector *)
uint32_t write(Time time, Evoral::EventType type, uint32_t size, const uint8_t *buf)
bool read(Time *time, Evoral::EventType *type, uint32_t *size, uint8_t *buf)
std::ostream & endmsg(std::ostream &ostr)
static pthread_t _process_thread
static AudioEngine * instance()
void increment_read_idx(guint cnt)
static pframes_t _cycle_nframes
void parse(framecnt_t timestamp)
void cycle_start(pframes_t nframes)
void cycle_end(pframes_t nframes)
void drain(int check_interval_usecs)
void get_write_vector(rw_vector *)
void set_timer(boost::function< framecnt_t(void)> &)
framepos_t sample_time_at_cycle_start()
MidiBuffer & get_midi_buffer(pframes_t nframes)
void increment_write_idx(guint cnt)
static void set_process_thread(pthread_t)
static bool is_process_thread()
MIDI::timestamp_t _last_write_timestamp
bool receives_input() const
int read(MIDI::byte *buf, size_t bufsize)
bool push_back(const Evoral::MIDIEvent< TimeType > &event)
const uint8_t * buffer() const
int write(const MIDI::byte *msg, size_t msglen, MIDI::timestamp_t timestamp)
CrossThreadChannel _xthread
void cycle_start(pframes_t nframes)