/* * Copyright (C) 2015-2017 Robin Gareus * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef WINMME_MIDI_OUTPUT_DEVICE_H #define WINMME_MIDI_OUTPUT_DEVICE_H #include #include #include #include #include #include #define MaxWinMidiEventSize 256 namespace ARDOUR { class WinMMEMidiOutputDevice { public: WinMMEMidiOutputDevice (int index); ~WinMMEMidiOutputDevice (); bool enqueue_midi_event (uint64_t rel_event_time_us, const uint8_t* data, const size_t size); bool start (); bool stop (); void set_enabled (bool enable); bool get_enabled (); std::string name () const { return m_name; } private: // Methods bool open (UINT index, std::string& error_msg); bool close (std::string& error_msg); bool set_device_name (UINT index); std::string get_error_string (MMRESULT error_code); bool start_midi_output_thread (); bool stop_midi_output_thread (); bool signal (HANDLE semaphore); bool wait (HANDLE semaphore); static void* midi_output_thread (void*); void midi_output_thread (); bool wait_for_microseconds (int64_t us); static void CALLBACK winmm_output_callback (HMIDIOUT handle, UINT msg, DWORD_PTR instance, DWORD_PTR midi_data, DWORD_PTR timestamp); void midi_output_callback (UINT msg, DWORD_PTR data, DWORD_PTR timestamp); private: // Data HMIDIOUT m_handle; HANDLE m_queue_semaphore; HANDLE m_sysex_semaphore; HANDLE m_timer; bool m_started; bool m_enabled; std::string m_name; pthread_t m_output_thread_handle; bool m_thread_running; bool m_thread_quit; const std::unique_ptr > m_midi_buffer; }; } // namespace ARDOUR #endif // WINMME_MIDI_OUTPUT_DEVICE_H