From 2fe8b1b92fa2a9b93fea0ed0cb62802237b82e8d Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Tue, 8 Dec 2020 22:26:17 +0900 Subject: Renaming of files in preparation for code style tools. Signed-off-by: Michele Calgaro (cherry picked from commit fce86b22a2367f1be1f9aae5e1ba3d18d1371b74) --- arts/midi/CMakeLists.txt | 18 +- arts/midi/Makefile.am | 20 +- arts/midi/README.midi | 2 +- arts/midi/alsamidigateway_impl.cc | 243 ------------------------ arts/midi/alsamidigateway_impl.cpp | 243 ++++++++++++++++++++++++ arts/midi/alsamidiport_impl.cc | 232 ----------------------- arts/midi/alsamidiport_impl.cpp | 232 +++++++++++++++++++++++ arts/midi/artsmidi.idl | 2 +- arts/midi/audiomiditimer_impl.cc | 116 ------------ arts/midi/audiomiditimer_impl.cpp | 116 ++++++++++++ arts/midi/audiosync_impl.cc | 203 -------------------- arts/midi/audiosync_impl.cpp | 203 ++++++++++++++++++++ arts/midi/audiotimer.cc | 98 ---------- arts/midi/audiotimer.cpp | 98 ++++++++++ arts/midi/midiclient_impl.cc | 274 --------------------------- arts/midi/midiclient_impl.cpp | 274 +++++++++++++++++++++++++++ arts/midi/midimanager_impl.cc | 156 --------------- arts/midi/midimanager_impl.cpp | 156 +++++++++++++++ arts/midi/midimanagerport_impl.cc | 71 ------- arts/midi/midimanagerport_impl.cpp | 71 +++++++ arts/midi/midisend.cc | 375 ------------------------------------- arts/midi/midisend.cpp | 375 +++++++++++++++++++++++++++++++++++++ arts/midi/midisyncgroup_impl.cc | 125 ------------- arts/midi/midisyncgroup_impl.cpp | 125 +++++++++++++ arts/midi/midisynctest.cc | 137 -------------- arts/midi/midisynctest.cpp | 137 ++++++++++++++ arts/midi/miditest_impl.cc | 57 ------ arts/midi/miditest_impl.cpp | 57 ++++++ arts/midi/miditimercommon.cc | 72 ------- arts/midi/miditimercommon.cpp | 72 +++++++ arts/midi/rawmidiport_impl.cc | 306 ------------------------------ arts/midi/rawmidiport_impl.cpp | 306 ++++++++++++++++++++++++++++++ arts/midi/systemmiditimer_impl.cc | 105 ----------- arts/midi/systemmiditimer_impl.cpp | 105 +++++++++++ arts/midi/timestampmath.cc | 112 ----------- arts/midi/timestampmath.cpp | 112 +++++++++++ 36 files changed, 2703 insertions(+), 2703 deletions(-) delete mode 100644 arts/midi/alsamidigateway_impl.cc create mode 100644 arts/midi/alsamidigateway_impl.cpp delete mode 100644 arts/midi/alsamidiport_impl.cc create mode 100644 arts/midi/alsamidiport_impl.cpp delete mode 100644 arts/midi/audiomiditimer_impl.cc create mode 100644 arts/midi/audiomiditimer_impl.cpp delete mode 100644 arts/midi/audiosync_impl.cc create mode 100644 arts/midi/audiosync_impl.cpp delete mode 100644 arts/midi/audiotimer.cc create mode 100644 arts/midi/audiotimer.cpp delete mode 100644 arts/midi/midiclient_impl.cc create mode 100644 arts/midi/midiclient_impl.cpp delete mode 100644 arts/midi/midimanager_impl.cc create mode 100644 arts/midi/midimanager_impl.cpp delete mode 100644 arts/midi/midimanagerport_impl.cc create mode 100644 arts/midi/midimanagerport_impl.cpp delete mode 100644 arts/midi/midisend.cc create mode 100644 arts/midi/midisend.cpp delete mode 100644 arts/midi/midisyncgroup_impl.cc create mode 100644 arts/midi/midisyncgroup_impl.cpp delete mode 100644 arts/midi/midisynctest.cc create mode 100644 arts/midi/midisynctest.cpp delete mode 100644 arts/midi/miditest_impl.cc create mode 100644 arts/midi/miditest_impl.cpp delete mode 100644 arts/midi/miditimercommon.cc create mode 100644 arts/midi/miditimercommon.cpp delete mode 100644 arts/midi/rawmidiport_impl.cc create mode 100644 arts/midi/rawmidiport_impl.cpp delete mode 100644 arts/midi/systemmiditimer_impl.cc create mode 100644 arts/midi/systemmiditimer_impl.cpp delete mode 100644 arts/midi/timestampmath.cc create mode 100644 arts/midi/timestampmath.cpp (limited to 'arts/midi') diff --git a/arts/midi/CMakeLists.txt b/arts/midi/CMakeLists.txt index 0b91a9fe..c8c0925d 100644 --- a/arts/midi/CMakeLists.txt +++ b/arts/midi/CMakeLists.txt @@ -29,7 +29,7 @@ link_directories( ##### artsmidi (library) ######################## tde_add_library( artsmidi_idl SHARED - SOURCES artsmidi.cc + SOURCES artsmidi.cpp VERSION 0.0.0 LINK ${ARTS_LIBRARIES} ${GLIB2_LIBRARIES} ${GTHREAD2_LIBRARIES} mcop artsflow artsflow_idl DESTINATION ${LIB_INSTALL_DIR} @@ -37,11 +37,11 @@ tde_add_library( artsmidi_idl SHARED tde_add_library( artsmidi SHARED SOURCES - midimanager_impl.cc midiclient_impl.cc - miditest_impl.cc midimanagerport_impl.cc rawmidiport_impl.cc - systemmiditimer_impl.cc audiomiditimer_impl.cc miditimercommon.cc - audiosync_impl.cc audiotimer.cc alsamidigateway_impl.cc - alsamidiport_impl.cc midisyncgroup_impl.cc timestampmath.cc + midimanager_impl.cpp midiclient_impl.cpp + miditest_impl.cpp midimanagerport_impl.cpp rawmidiport_impl.cpp + systemmiditimer_impl.cpp audiomiditimer_impl.cpp miditimercommon.cpp + audiosync_impl.cpp audiotimer.cpp alsamidigateway_impl.cpp + alsamidiport_impl.cpp midisyncgroup_impl.cpp timestampmath.cpp VERSION 0.0.0 LINK artsmidi_idl-shared @@ -50,7 +50,7 @@ tde_add_library( artsmidi SHARED add_custom_command( OUTPUT - artsmidi.cc artsmidi.h + artsmidi.cpp artsmidi.h artsmidi.mcopclass artsmidi.mcoptype COMMAND ${ARTS_MCOPIDL_EXECUTABLE} -t -I${ARTS_INCLUDEDIR} ${CMAKE_CURRENT_SOURCE_DIR}/artsmidi.idl @@ -61,13 +61,13 @@ add_custom_command( ##### midisend (executable) ##################### tde_add_executable( midisend - SOURCES midisend.cc midimsg.c + SOURCES midisend.cpp midimsg.c LINK artsmidi_idl-shared DESTINATION ${BIN_INSTALL_DIR} ) tde_add_check_executable( midisynctest - SOURCES midisynctest.cc + SOURCES midisynctest.cpp LINK artsmidi-shared soundserver_idl ) diff --git a/arts/midi/Makefile.am b/arts/midi/Makefile.am index d097dc85..679ff700 100644 --- a/arts/midi/Makefile.am +++ b/arts/midi/Makefile.am @@ -8,26 +8,26 @@ lib_LTLIBRARIES = libartsmidi_idl.la libartsmidi.la bin_PROGRAMS = midisend noinst_PROGRAMS = midisynctest -midisend_SOURCES = midisend.cc midimsg.c +midisend_SOURCES = midisend.cpp midimsg.c midisend_LDFLAGS = $(all_libraries) $(LIB_QT) $(KDE_RPATH) $(LIBPTHREAD) $(LIB_QT) -lmcop -lartsflow_idl midisend_LDADD = libartsmidi_idl.la -lartsflow_idl midisend_COMPILE_FIRST = artsmidi.h -midisynctest_SOURCES = midisynctest.cc +midisynctest_SOURCES = midisynctest.cpp midisynctest_LDFLAGS = $(all_libraries) $(LIB_QT) $(KDE_RPATH) $(LIBPTHREAD) $(LIB_QT) -lmcop -lartsflow_idl -lartsmidi_idl midisynctest_LDADD = libartsmidi.la -lsoundserver_idl -lartsflow_idl -lartsmidi_idl midisynctest_COMPILE_FIRST = artsmidi.h -libartsmidi_idl_la_SOURCES = artsmidi.cc +libartsmidi_idl_la_SOURCES = artsmidi.cpp libartsmidi_idl_la_LIBADD = -lmcop -lartsflow -lartsflow_idl libartsmidi_idl_la_LDFLAGS = $(all_libraries) -L$(arts_libraries) \ -no-undefined -lartsflow_idl -libartsmidi_la_SOURCES = midimanager_impl.cc midiclient_impl.cc \ - miditest_impl.cc midimanagerport_impl.cc rawmidiport_impl.cc \ - systemmiditimer_impl.cc audiomiditimer_impl.cc miditimercommon.cc \ - audiosync_impl.cc audiotimer.cc alsamidigateway_impl.cc \ - alsamidiport_impl.cc midisyncgroup_impl.cc timestampmath.cc +libartsmidi_la_SOURCES = midimanager_impl.cpp midiclient_impl.cpp \ + miditest_impl.cpp midimanagerport_impl.cpp rawmidiport_impl.cpp \ + systemmiditimer_impl.cpp audiomiditimer_impl.cpp miditimercommon.cpp \ + audiosync_impl.cpp audiotimer.cpp alsamidigateway_impl.cpp \ + alsamidiport_impl.cpp midisyncgroup_impl.cpp timestampmath.cpp libartsmidi_la_COMPILE_FIRST = artsmidi.h libartsmidi_la_LIBADD = libartsmidi_idl.la -lartsflow_idl -lartsflow $(ARTS_LIBASOUND) @@ -36,10 +36,10 @@ libartsmidi_la_LDFLAGS = $(all_libraries) -L$(arts_libraries) \ artsmidi.mcopclass: artsmidi.h artsmidi.mcoptype: artsmidi.h -artsmidi.cc artsmidi.h: $(srcdir)/artsmidi.idl $(MCOPIDL) +artsmidi.cpp artsmidi.h: $(srcdir)/artsmidi.idl $(MCOPIDL) $(MCOPIDL) -t -I$(arts_includes) $(srcdir)/artsmidi.idl -DISTCLEANFILES = artsmidi.cc artsmidi.h \ +DISTCLEANFILES = artsmidi.cpp artsmidi.h \ artsmidi.mcoptype artsmidi.mcopclass ####### install idl files diff --git a/arts/midi/README.midi b/arts/midi/README.midi index 69342b32..a3463fde 100644 --- a/arts/midi/README.midi +++ b/arts/midi/README.midi @@ -250,7 +250,7 @@ synchronized to those of the midi channels. --------------- An example that illustrates most things discussed in this document is -midisynctest.cc, which plays back two synchronized midi streams and samples. +midisynctest.cpp, which plays back two synchronized midi streams and samples. Note that you might want to change the source code, as it hardcodes the location of the .wav file. diff --git a/arts/midi/alsamidigateway_impl.cc b/arts/midi/alsamidigateway_impl.cc deleted file mode 100644 index 4b31042e..00000000 --- a/arts/midi/alsamidigateway_impl.cc +++ /dev/null @@ -1,243 +0,0 @@ - /* - - Copyright (C) 2001-2002 Stefan Westerfeld - stefan@space.twc.de - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - */ - -#include "artsmidi.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -/** - * compile real version if we have ALSA support, dummy version otherwise - */ -#if defined(HAVE_ARTS_LIBASOUND2) || defined(HAVE_ARTS_LIBASOUND) - -#ifdef HAVE_ALSA_ASOUNDLIB_H -#include -#elif defined(HAVE_SYS_ASOUNDLIB_H) -#include -#endif - -#include "alsamidiport_impl.h" -#include -#include - -using namespace Arts; -using namespace std; - -class AlsaMidiGateway_impl : virtual public AlsaMidiGateway_skel { -protected: - snd_seq_t *seq; - - struct PortEntry { - int alsaClient, alsaPort; - bool keep; - - AlsaMidiPort port; - MidiClient client; - }; - list ports; - -#ifdef HAVE_ARTS_LIBASOUND2 -/* ALSA-0.9 specific code */ - int alsaOpen() { - return snd_seq_open(&seq, "hw", SND_SEQ_OPEN_DUPLEX, 0); - } - bool alsaScan(MidiManager midiManager) { - snd_seq_client_info_t *cinfo; - snd_seq_port_info_t *pinfo; - - snd_seq_client_info_alloca(&cinfo); - snd_seq_client_info_set_client(cinfo, -1); - - while (snd_seq_query_next_client(seq, cinfo) >= 0) { - int client = snd_seq_client_info_get_client(cinfo); - - snd_seq_port_info_alloca(&pinfo); - snd_seq_port_info_set_client(pinfo, client); - - snd_seq_port_info_set_port(pinfo, -1); - while (snd_seq_query_next_port(seq, pinfo) >= 0) { - unsigned int cap; - - cap = (SND_SEQ_PORT_CAP_SUBS_WRITE|SND_SEQ_PORT_CAP_WRITE); - if ((snd_seq_port_info_get_capability(pinfo) & cap) == cap) { - string name = snd_seq_port_info_get_name(pinfo); - int client = snd_seq_port_info_get_client(pinfo); - int port = snd_seq_port_info_get_port(pinfo); - - createPort(midiManager, name, client, port); - } - } - } - - return true; - } -#else -/* ALSA-0.5 specific code */ - int alsaOpen() { - return snd_seq_open(&seq, SND_SEQ_OPEN); - } - - bool alsaScan(MidiManager midiManager) { - snd_seq_system_info_t sysinfo; - - int err = snd_seq_system_info(seq, &sysinfo); - if (err < 0) - { - arts_warning("snd_seq_systeminfo failed: %s", snd_strerror(err)); - return false; - } - - for(int client = 0; client < sysinfo.clients; client++) - { - snd_seq_client_info_t cinfo; - if (snd_seq_get_any_client_info(seq, client, &cinfo) == 0) - { - for(int port = 0; port < sysinfo.ports; port++) - { - snd_seq_port_info_t pinfo; - if(snd_seq_get_any_port_info(seq, client, port, &pinfo) == 0) - { - unsigned int cap; - cap = (SND_SEQ_PORT_CAP_SUBS_WRITE|SND_SEQ_PORT_CAP_WRITE); - - if ((pinfo.capability & cap) == cap) - createPort(midiManager, pinfo.name, client, port); - } - } - } - } - - return true; - } -#endif - -public: - AlsaMidiGateway_impl() : seq(0) - { - } - - ~AlsaMidiGateway_impl() - { - if(seq) - snd_seq_close(seq); - } - - void createPort(MidiManager midiManager, string name, int client, int port) - { - if(name != "aRts") - { - char nr[1024]; - - sprintf(nr, " (%3d:%-3d)", client, port); - name += nr; - - list::iterator pi = ports.begin(); - while(pi != ports.end() && (pi->alsaClient != client || pi->alsaPort != port)) - pi++; - - if(pi != ports.end()) /* we already have this port */ - pi->keep = true; - else /* we need to create it */ - { - PortEntry pe; - pe.port = AlsaMidiPort::_from_base( - new AlsaMidiPort_impl(seq, client, port)); - - if(pe.port.open()) - { - pe.client = midiManager.addClient(mcdRecord, - mctDestination, - name, name); - pe.client.addInputPort(pe.port); - pe.alsaClient = client; - pe.alsaPort = port; - pe.keep = true; - - ports.push_back(pe); - } - } - } - } - - bool rescan() - { - MidiManager midiManager = DynamicCast(Reference("global:Arts_MidiManager")); - if(midiManager.isNull()) - { - arts_warning("AlsaMidiGateway: can't find MidiManager"); - return false; - } - - if(!seq) - { - int err = alsaOpen(); - if (err < 0) - { - arts_warning("AlsaMidiGateway: could not open sequencer %s", - snd_strerror(err)); - seq = 0; - return false; - } - } - - list::iterator pi; - for(pi = ports.begin(); pi != ports.end(); pi++) - pi->keep = false; - - if(!alsaScan(midiManager)) - return false; - - /* erase those ports that are no longer needed */ - pi = ports.begin(); - while(pi != ports.end()) - { - if(!pi->keep) - pi = ports.erase(pi); - else - pi++; - } - - return true; - } -}; - -#else - -using namespace Arts; -using namespace std; - -class AlsaMidiGateway_impl : virtual public AlsaMidiGateway_skel { -public: - bool rescan() - { - /* dummy version: no ALSA support compiled in */ - return false; - } -}; - -#endif - -namespace Arts { - REGISTER_IMPLEMENTATION(AlsaMidiGateway_impl); -} diff --git a/arts/midi/alsamidigateway_impl.cpp b/arts/midi/alsamidigateway_impl.cpp new file mode 100644 index 00000000..4b31042e --- /dev/null +++ b/arts/midi/alsamidigateway_impl.cpp @@ -0,0 +1,243 @@ + /* + + Copyright (C) 2001-2002 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + */ + +#include "artsmidi.h" + +#ifdef HAVE_CONFIG_H +#include +#endif + +/** + * compile real version if we have ALSA support, dummy version otherwise + */ +#if defined(HAVE_ARTS_LIBASOUND2) || defined(HAVE_ARTS_LIBASOUND) + +#ifdef HAVE_ALSA_ASOUNDLIB_H +#include +#elif defined(HAVE_SYS_ASOUNDLIB_H) +#include +#endif + +#include "alsamidiport_impl.h" +#include +#include + +using namespace Arts; +using namespace std; + +class AlsaMidiGateway_impl : virtual public AlsaMidiGateway_skel { +protected: + snd_seq_t *seq; + + struct PortEntry { + int alsaClient, alsaPort; + bool keep; + + AlsaMidiPort port; + MidiClient client; + }; + list ports; + +#ifdef HAVE_ARTS_LIBASOUND2 +/* ALSA-0.9 specific code */ + int alsaOpen() { + return snd_seq_open(&seq, "hw", SND_SEQ_OPEN_DUPLEX, 0); + } + bool alsaScan(MidiManager midiManager) { + snd_seq_client_info_t *cinfo; + snd_seq_port_info_t *pinfo; + + snd_seq_client_info_alloca(&cinfo); + snd_seq_client_info_set_client(cinfo, -1); + + while (snd_seq_query_next_client(seq, cinfo) >= 0) { + int client = snd_seq_client_info_get_client(cinfo); + + snd_seq_port_info_alloca(&pinfo); + snd_seq_port_info_set_client(pinfo, client); + + snd_seq_port_info_set_port(pinfo, -1); + while (snd_seq_query_next_port(seq, pinfo) >= 0) { + unsigned int cap; + + cap = (SND_SEQ_PORT_CAP_SUBS_WRITE|SND_SEQ_PORT_CAP_WRITE); + if ((snd_seq_port_info_get_capability(pinfo) & cap) == cap) { + string name = snd_seq_port_info_get_name(pinfo); + int client = snd_seq_port_info_get_client(pinfo); + int port = snd_seq_port_info_get_port(pinfo); + + createPort(midiManager, name, client, port); + } + } + } + + return true; + } +#else +/* ALSA-0.5 specific code */ + int alsaOpen() { + return snd_seq_open(&seq, SND_SEQ_OPEN); + } + + bool alsaScan(MidiManager midiManager) { + snd_seq_system_info_t sysinfo; + + int err = snd_seq_system_info(seq, &sysinfo); + if (err < 0) + { + arts_warning("snd_seq_systeminfo failed: %s", snd_strerror(err)); + return false; + } + + for(int client = 0; client < sysinfo.clients; client++) + { + snd_seq_client_info_t cinfo; + if (snd_seq_get_any_client_info(seq, client, &cinfo) == 0) + { + for(int port = 0; port < sysinfo.ports; port++) + { + snd_seq_port_info_t pinfo; + if(snd_seq_get_any_port_info(seq, client, port, &pinfo) == 0) + { + unsigned int cap; + cap = (SND_SEQ_PORT_CAP_SUBS_WRITE|SND_SEQ_PORT_CAP_WRITE); + + if ((pinfo.capability & cap) == cap) + createPort(midiManager, pinfo.name, client, port); + } + } + } + } + + return true; + } +#endif + +public: + AlsaMidiGateway_impl() : seq(0) + { + } + + ~AlsaMidiGateway_impl() + { + if(seq) + snd_seq_close(seq); + } + + void createPort(MidiManager midiManager, string name, int client, int port) + { + if(name != "aRts") + { + char nr[1024]; + + sprintf(nr, " (%3d:%-3d)", client, port); + name += nr; + + list::iterator pi = ports.begin(); + while(pi != ports.end() && (pi->alsaClient != client || pi->alsaPort != port)) + pi++; + + if(pi != ports.end()) /* we already have this port */ + pi->keep = true; + else /* we need to create it */ + { + PortEntry pe; + pe.port = AlsaMidiPort::_from_base( + new AlsaMidiPort_impl(seq, client, port)); + + if(pe.port.open()) + { + pe.client = midiManager.addClient(mcdRecord, + mctDestination, + name, name); + pe.client.addInputPort(pe.port); + pe.alsaClient = client; + pe.alsaPort = port; + pe.keep = true; + + ports.push_back(pe); + } + } + } + } + + bool rescan() + { + MidiManager midiManager = DynamicCast(Reference("global:Arts_MidiManager")); + if(midiManager.isNull()) + { + arts_warning("AlsaMidiGateway: can't find MidiManager"); + return false; + } + + if(!seq) + { + int err = alsaOpen(); + if (err < 0) + { + arts_warning("AlsaMidiGateway: could not open sequencer %s", + snd_strerror(err)); + seq = 0; + return false; + } + } + + list::iterator pi; + for(pi = ports.begin(); pi != ports.end(); pi++) + pi->keep = false; + + if(!alsaScan(midiManager)) + return false; + + /* erase those ports that are no longer needed */ + pi = ports.begin(); + while(pi != ports.end()) + { + if(!pi->keep) + pi = ports.erase(pi); + else + pi++; + } + + return true; + } +}; + +#else + +using namespace Arts; +using namespace std; + +class AlsaMidiGateway_impl : virtual public AlsaMidiGateway_skel { +public: + bool rescan() + { + /* dummy version: no ALSA support compiled in */ + return false; + } +}; + +#endif + +namespace Arts { + REGISTER_IMPLEMENTATION(AlsaMidiGateway_impl); +} diff --git a/arts/midi/alsamidiport_impl.cc b/arts/midi/alsamidiport_impl.cc deleted file mode 100644 index 97c8dffa..00000000 --- a/arts/midi/alsamidiport_impl.cc +++ /dev/null @@ -1,232 +0,0 @@ - /* - - Copyright (C) 2001-2002 Stefan Westerfeld - stefan@space.twc.de - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - */ - -#include "alsamidiport_impl.h" - -#if defined(HAVE_ARTS_LIBASOUND2) || defined(HAVE_ARTS_LIBASOUND) -#include - -#ifdef HAVE_ARTS_LIBASOUND -#define snd_seq_queue_status_alloca(x) \ - *x = (snd_seq_queue_status_t *)alloca(sizeof(snd_seq_queue_status_t)) -#define snd_seq_queue_status_get_tick_time(x) x->tick -#define snd_seq_queue_status_get_real_time(x) (&(x->time)) -#endif - -using namespace std; -using namespace Arts; - -AlsaMidiPort_impl::AlsaMidiPort_impl(snd_seq_t *seq, long client, long port) - : _client(client), _port(port), alsaSeq(seq) -{ - opened = false; -} - -/* interface MidiPort */ -Arts::TimeStamp AlsaMidiPort_impl::time() -{ - snd_seq_queue_status_t *status; - snd_seq_queue_status_alloca(&status); - - snd_seq_get_queue_status(alsaSeq, alsaQueue, status); - snd_seq_tick_time_t ttime = snd_seq_queue_status_get_tick_time(status); - const snd_seq_real_time_t *rtime = - snd_seq_queue_status_get_real_time(status); - - return Arts::TimeStamp(rtime->tv_sec, rtime->tv_nsec / 1000); -} - -Arts::TimeStamp AlsaMidiPort_impl::playTime() -{ - return time(); -} - -void AlsaMidiPort_impl::fillAlsaEvent(snd_seq_event_t *ev, - const MidiCommand& command) -{ - ev->source = alsaSourceAddr; - ev->dest = alsaDestAddr; - - mcopbyte channel = command.status & mcsChannelMask; - - switch(command.status & mcsCommandMask) - { - case mcsNoteOn: - snd_seq_ev_set_noteon(ev, channel, command.data1, command.data2); - break; - case mcsNoteOff: - snd_seq_ev_set_noteoff(ev, channel, command.data1, command.data2); - break; - case mcsProgram: - snd_seq_ev_set_pgmchange(ev, channel, command.data1); - break; - case mcsParameter: - snd_seq_ev_set_controller(ev, channel, command.data1, command.data2); - break; - default: - /* unhandled */ - return; - } -} - -void AlsaMidiPort_impl::sendAlsaEvent(snd_seq_event_t *ev) -{ - int ret = snd_seq_event_output(alsaSeq, ev); - if (ret < 0) { - arts_warning("AlsaMidiPort: error writing note %s\n", - snd_strerror(ret)); - return; - } - flushAlsa(); -} - -void AlsaMidiPort_impl::processCommand(const MidiCommand& command) -{ - snd_seq_event_t ev; - snd_seq_ev_clear(&ev); - - fillAlsaEvent(&ev, command); - sendAlsaEvent(&ev); -} - -void AlsaMidiPort_impl::processEvent(const MidiEvent& event) -{ - snd_seq_event_t ev; - snd_seq_real_time_t time; - - time.tv_sec = event.time.sec; - time.tv_nsec = event.time.usec * 1000; - - snd_seq_ev_clear(&ev); - snd_seq_ev_schedule_real(&ev, alsaQueue, 0, &time); - - fillAlsaEvent(&ev, event.command); - sendAlsaEvent(&ev); -} - -/* interface AlsaMidiPort */ -void AlsaMidiPort_impl::client(long newClient) -{ - if(newClient != _client) - { - _client = newClient; - - if(opened) - { - close(); - open(); - } - - client_changed(newClient); - } -} - -long AlsaMidiPort_impl::client() -{ - return _client; -} - -void AlsaMidiPort_impl::port(long newPort) -{ - if(newPort != _port) - { - _port = newPort; - - if(opened) - { - close(); - open(); - } - - port_changed(newPort); - } -} - -long AlsaMidiPort_impl::port() -{ - return _port; -} - -bool AlsaMidiPort_impl::open() -{ - arts_return_val_if_fail(opened == false, false); - - alsaQueue = snd_seq_alloc_queue(alsaSeq); - alsaClientId = snd_seq_client_id(alsaSeq); - - alsaPort = snd_seq_create_simple_port(alsaSeq, "aRts", - SND_SEQ_PORT_CAP_WRITE | - SND_SEQ_PORT_CAP_SUBS_WRITE | - SND_SEQ_PORT_CAP_READ, - SND_SEQ_PORT_TYPE_MIDI_GENERIC); - if (alsaPort < 0) { - arts_warning("AlsaMidiPort: can't creating port %s\n", - snd_strerror(alsaPort)); - return false; - } - - alsaSourceAddr.client = alsaClientId; - alsaSourceAddr.port = alsaPort; - - alsaDestAddr.client = _client; - alsaDestAddr.port = _port; - - int ret; - ret = snd_seq_connect_to(alsaSeq, alsaPort, - alsaDestAddr.client, - alsaDestAddr.port); - if (ret < 0) { - arts_warning("AlsaMidiPort: error connecting port %s\n", - snd_strerror(ret)); - /* FIXME: destroy port here */ - return false; - } - - snd_seq_start_queue(alsaSeq, alsaQueue, 0); - flushAlsa(); - - opened = true; - return true; -} - -void AlsaMidiPort_impl::close() -{ - if(!opened) - return; - - opened = false; -} - -void AlsaMidiPort_impl::flushAlsa() -{ -#ifdef HAVE_ARTS_LIBASOUND2 - snd_seq_drain_output(alsaSeq); -#else - int err; - while((err = snd_seq_flush_output(alsaSeq)) > 0) - { - arts_debug("alsa flush error %d\n",snd_strerror(err)); - usleep(2000); - } -#endif -} -#endif diff --git a/arts/midi/alsamidiport_impl.cpp b/arts/midi/alsamidiport_impl.cpp new file mode 100644 index 00000000..97c8dffa --- /dev/null +++ b/arts/midi/alsamidiport_impl.cpp @@ -0,0 +1,232 @@ + /* + + Copyright (C) 2001-2002 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + */ + +#include "alsamidiport_impl.h" + +#if defined(HAVE_ARTS_LIBASOUND2) || defined(HAVE_ARTS_LIBASOUND) +#include + +#ifdef HAVE_ARTS_LIBASOUND +#define snd_seq_queue_status_alloca(x) \ + *x = (snd_seq_queue_status_t *)alloca(sizeof(snd_seq_queue_status_t)) +#define snd_seq_queue_status_get_tick_time(x) x->tick +#define snd_seq_queue_status_get_real_time(x) (&(x->time)) +#endif + +using namespace std; +using namespace Arts; + +AlsaMidiPort_impl::AlsaMidiPort_impl(snd_seq_t *seq, long client, long port) + : _client(client), _port(port), alsaSeq(seq) +{ + opened = false; +} + +/* interface MidiPort */ +Arts::TimeStamp AlsaMidiPort_impl::time() +{ + snd_seq_queue_status_t *status; + snd_seq_queue_status_alloca(&status); + + snd_seq_get_queue_status(alsaSeq, alsaQueue, status); + snd_seq_tick_time_t ttime = snd_seq_queue_status_get_tick_time(status); + const snd_seq_real_time_t *rtime = + snd_seq_queue_status_get_real_time(status); + + return Arts::TimeStamp(rtime->tv_sec, rtime->tv_nsec / 1000); +} + +Arts::TimeStamp AlsaMidiPort_impl::playTime() +{ + return time(); +} + +void AlsaMidiPort_impl::fillAlsaEvent(snd_seq_event_t *ev, + const MidiCommand& command) +{ + ev->source = alsaSourceAddr; + ev->dest = alsaDestAddr; + + mcopbyte channel = command.status & mcsChannelMask; + + switch(command.status & mcsCommandMask) + { + case mcsNoteOn: + snd_seq_ev_set_noteon(ev, channel, command.data1, command.data2); + break; + case mcsNoteOff: + snd_seq_ev_set_noteoff(ev, channel, command.data1, command.data2); + break; + case mcsProgram: + snd_seq_ev_set_pgmchange(ev, channel, command.data1); + break; + case mcsParameter: + snd_seq_ev_set_controller(ev, channel, command.data1, command.data2); + break; + default: + /* unhandled */ + return; + } +} + +void AlsaMidiPort_impl::sendAlsaEvent(snd_seq_event_t *ev) +{ + int ret = snd_seq_event_output(alsaSeq, ev); + if (ret < 0) { + arts_warning("AlsaMidiPort: error writing note %s\n", + snd_strerror(ret)); + return; + } + flushAlsa(); +} + +void AlsaMidiPort_impl::processCommand(const MidiCommand& command) +{ + snd_seq_event_t ev; + snd_seq_ev_clear(&ev); + + fillAlsaEvent(&ev, command); + sendAlsaEvent(&ev); +} + +void AlsaMidiPort_impl::processEvent(const MidiEvent& event) +{ + snd_seq_event_t ev; + snd_seq_real_time_t time; + + time.tv_sec = event.time.sec; + time.tv_nsec = event.time.usec * 1000; + + snd_seq_ev_clear(&ev); + snd_seq_ev_schedule_real(&ev, alsaQueue, 0, &time); + + fillAlsaEvent(&ev, event.command); + sendAlsaEvent(&ev); +} + +/* interface AlsaMidiPort */ +void AlsaMidiPort_impl::client(long newClient) +{ + if(newClient != _client) + { + _client = newClient; + + if(opened) + { + close(); + open(); + } + + client_changed(newClient); + } +} + +long AlsaMidiPort_impl::client() +{ + return _client; +} + +void AlsaMidiPort_impl::port(long newPort) +{ + if(newPort != _port) + { + _port = newPort; + + if(opened) + { + close(); + open(); + } + + port_changed(newPort); + } +} + +long AlsaMidiPort_impl::port() +{ + return _port; +} + +bool AlsaMidiPort_impl::open() +{ + arts_return_val_if_fail(opened == false, false); + + alsaQueue = snd_seq_alloc_queue(alsaSeq); + alsaClientId = snd_seq_client_id(alsaSeq); + + alsaPort = snd_seq_create_simple_port(alsaSeq, "aRts", + SND_SEQ_PORT_CAP_WRITE | + SND_SEQ_PORT_CAP_SUBS_WRITE | + SND_SEQ_PORT_CAP_READ, + SND_SEQ_PORT_TYPE_MIDI_GENERIC); + if (alsaPort < 0) { + arts_warning("AlsaMidiPort: can't creating port %s\n", + snd_strerror(alsaPort)); + return false; + } + + alsaSourceAddr.client = alsaClientId; + alsaSourceAddr.port = alsaPort; + + alsaDestAddr.client = _client; + alsaDestAddr.port = _port; + + int ret; + ret = snd_seq_connect_to(alsaSeq, alsaPort, + alsaDestAddr.client, + alsaDestAddr.port); + if (ret < 0) { + arts_warning("AlsaMidiPort: error connecting port %s\n", + snd_strerror(ret)); + /* FIXME: destroy port here */ + return false; + } + + snd_seq_start_queue(alsaSeq, alsaQueue, 0); + flushAlsa(); + + opened = true; + return true; +} + +void AlsaMidiPort_impl::close() +{ + if(!opened) + return; + + opened = false; +} + +void AlsaMidiPort_impl::flushAlsa() +{ +#ifdef HAVE_ARTS_LIBASOUND2 + snd_seq_drain_output(alsaSeq); +#else + int err; + while((err = snd_seq_flush_output(alsaSeq)) > 0) + { + arts_debug("alsa flush error %d\n",snd_strerror(err)); + usleep(2000); + } +#endif +} +#endif diff --git a/arts/midi/artsmidi.idl b/arts/midi/artsmidi.idl index ce1c5891..9531d763 100644 --- a/arts/midi/artsmidi.idl +++ b/arts/midi/artsmidi.idl @@ -21,7 +21,7 @@ */ /* - * DISCLAIMER: The interfaces in artsmidi.idl (and the derived .cc/.h files) + * DISCLAIMER: The interfaces in artsmidi.idl (and the derived .cpp/.h files) * DO NOT GUARANTEE BINARY COMPATIBILITY YET. * * They are intended for developers. You shouldn't expect that applications in diff --git a/arts/midi/audiomiditimer_impl.cc b/arts/midi/audiomiditimer_impl.cc deleted file mode 100644 index a185b1cb..00000000 --- a/arts/midi/audiomiditimer_impl.cc +++ /dev/null @@ -1,116 +0,0 @@ - /* - - Copyright (C) 2001 Stefan Westerfeld - stefan@space.twc.de - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - */ - -#include "artsmidi.h" -#include "artsflow.h" -#include "stdsynthmodule.h" -#include "debug.h" -#include "miditimercommon.h" -#include "audiotimer.h" -#include "flowsystem.h" - -using namespace std; - -namespace Arts { - -class AudioMidiTimerCommon : public MidiTimerCommon, public AudioTimerCallback -{ -protected: - AudioMidiTimerCommon(); - virtual ~AudioMidiTimerCommon(); - - AudioTimer *audioTimer; - -public: - // allocation: share one AudioMidiTimerCommon for everbody who needs one - static AudioMidiTimerCommon *subscribe(); - - TimeStamp time(); - void updateTime(); -}; - -} - -using namespace Arts; - -static AudioMidiTimerCommon *AudioMidiTimerCommon_the = 0; - -AudioMidiTimerCommon::AudioMidiTimerCommon() -{ - AudioMidiTimerCommon_the = this; - - audioTimer = AudioTimer::subscribe(); - audioTimer->addCallback(this); -} - -AudioMidiTimerCommon::~AudioMidiTimerCommon() -{ - audioTimer->removeCallback(this); - audioTimer->unsubscribe(); - - AudioMidiTimerCommon_the = 0; -} - -TimeStamp AudioMidiTimerCommon::time() -{ - return audioTimer->time(); -} - -void AudioMidiTimerCommon::updateTime() -{ - processQueue(); -} - -AudioMidiTimerCommon *AudioMidiTimerCommon::subscribe() -{ - if(!AudioMidiTimerCommon_the) - AudioMidiTimerCommon_the = new AudioMidiTimerCommon(); - AudioMidiTimerCommon_the->refCount++; - return AudioMidiTimerCommon_the; -} - -namespace Arts { - -class AudioMidiTimer_impl : public AudioMidiTimer_skel { -protected: - AudioMidiTimerCommon *timer; -public: - AudioMidiTimer_impl() - { - timer = AudioMidiTimerCommon::subscribe(); - } - ~AudioMidiTimer_impl() - { - timer->unsubscribe(); - } - TimeStamp time() - { - return timer->time(); - } - void queueEvent(MidiPort port, const MidiEvent& event) - { - timer->queueEvent(port, event); - } -}; - -REGISTER_IMPLEMENTATION(AudioMidiTimer_impl); -} diff --git a/arts/midi/audiomiditimer_impl.cpp b/arts/midi/audiomiditimer_impl.cpp new file mode 100644 index 00000000..a185b1cb --- /dev/null +++ b/arts/midi/audiomiditimer_impl.cpp @@ -0,0 +1,116 @@ + /* + + Copyright (C) 2001 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + */ + +#include "artsmidi.h" +#include "artsflow.h" +#include "stdsynthmodule.h" +#include "debug.h" +#include "miditimercommon.h" +#include "audiotimer.h" +#include "flowsystem.h" + +using namespace std; + +namespace Arts { + +class AudioMidiTimerCommon : public MidiTimerCommon, public AudioTimerCallback +{ +protected: + AudioMidiTimerCommon(); + virtual ~AudioMidiTimerCommon(); + + AudioTimer *audioTimer; + +public: + // allocation: share one AudioMidiTimerCommon for everbody who needs one + static AudioMidiTimerCommon *subscribe(); + + TimeStamp time(); + void updateTime(); +}; + +} + +using namespace Arts; + +static AudioMidiTimerCommon *AudioMidiTimerCommon_the = 0; + +AudioMidiTimerCommon::AudioMidiTimerCommon() +{ + AudioMidiTimerCommon_the = this; + + audioTimer = AudioTimer::subscribe(); + audioTimer->addCallback(this); +} + +AudioMidiTimerCommon::~AudioMidiTimerCommon() +{ + audioTimer->removeCallback(this); + audioTimer->unsubscribe(); + + AudioMidiTimerCommon_the = 0; +} + +TimeStamp AudioMidiTimerCommon::time() +{ + return audioTimer->time(); +} + +void AudioMidiTimerCommon::updateTime() +{ + processQueue(); +} + +AudioMidiTimerCommon *AudioMidiTimerCommon::subscribe() +{ + if(!AudioMidiTimerCommon_the) + AudioMidiTimerCommon_the = new AudioMidiTimerCommon(); + AudioMidiTimerCommon_the->refCount++; + return AudioMidiTimerCommon_the; +} + +namespace Arts { + +class AudioMidiTimer_impl : public AudioMidiTimer_skel { +protected: + AudioMidiTimerCommon *timer; +public: + AudioMidiTimer_impl() + { + timer = AudioMidiTimerCommon::subscribe(); + } + ~AudioMidiTimer_impl() + { + timer->unsubscribe(); + } + TimeStamp time() + { + return timer->time(); + } + void queueEvent(MidiPort port, const MidiEvent& event) + { + timer->queueEvent(port, event); + } +}; + +REGISTER_IMPLEMENTATION(AudioMidiTimer_impl); +} diff --git a/arts/midi/audiosync_impl.cc b/arts/midi/audiosync_impl.cc deleted file mode 100644 index 20f089df..00000000 --- a/arts/midi/audiosync_impl.cc +++ /dev/null @@ -1,203 +0,0 @@ - /* - - Copyright (C) 2001-2002 Stefan Westerfeld - stefan@space.twc.de - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - */ - -#include "audiosync_impl.h" -#include "midisyncgroup_impl.h" -#include "audiotimer.h" -#include "audiosubsys.h" -#include "timestampmath.h" - -#undef AUDIO_DEBUG_DRIFT - -using namespace std; -using namespace Arts; - -namespace Arts { - static list audioSyncImplList; -} - -void AudioSync_impl::AudioSyncEvent::execute() -{ - list::iterator i; - - for(i = startModules.begin(); i != startModules.end(); i++) - i->start(); - - for(i = stopModules.begin(); i != stopModules.end(); i++) - i->stop(); -} - -AudioSync_impl::AudioSync_impl() - : newEvent(new AudioSyncEvent), syncGroup(0) -{ - syncOffset = TimeStamp(0,0); - - timer = AudioTimer::subscribe(); - timer->addCallback(this); - - audioSyncImplList.push_back(this); -} - -AudioSync_impl::~AudioSync_impl() -{ - delete newEvent; - - while(!events.empty()) - { - delete events.front(); - events.pop_front(); - } - - if(syncGroup) - { - syncGroup->audioSyncDied(this); - syncGroup = 0; - } - audioSyncImplList.remove(this); - timer->removeCallback(this); - timer->unsubscribe(); -} - -TimeStamp AudioSync_impl::time() -{ - if(syncGroup) - return syncGroup->time(); - else - return audioTime(); -} - -TimeStamp AudioSync_impl::playTime() -{ - if(syncGroup) - return syncGroup->playTime(); - else - return audioPlayTime(); -} - -TimeStamp AudioSync_impl::audioTime() -{ - return timer->time(); -} - -TimeStamp AudioSync_impl::audioPlayTime() -{ - double delay = AudioSubSystem::the()->outputDelay(); - - TimeStamp time = audioTime(); - timeStampDec(time,timeStampFromDouble(delay)); - return time; -} - -TimeStamp AudioSync_impl::clientTime() -{ - TimeStamp time = audioTime(); - timeStampDec(time, syncOffset); - return time; -} - -void AudioSync_impl::queueStart(SynthModule synthModule) -{ - newEvent->startModules.push_back(synthModule); -} - -void AudioSync_impl::queueStop(SynthModule synthModule) -{ - newEvent->stopModules.push_back(synthModule); -} - -void AudioSync_impl::execute() -{ - newEvent->execute(); - newEvent->startModules.clear(); - newEvent->stopModules.clear(); -} - -void AudioSync_impl::executeAt(const TimeStamp& timeStamp) -{ - newEvent->time = timeStamp; - if(syncGroup) - timeStampInc(newEvent->time, syncOffset); - - events.push_back(newEvent); - - newEvent = new AudioSyncEvent; -} - -void AudioSync_impl::updateTime() -{ - TimeStamp now = audioTime(); - list::iterator i; - - i = events.begin(); - while(i != events.end()) - { - AudioSyncEvent *event = *i; - TimeStamp& eventTime = event->time; - - if( now.sec > eventTime.sec - || ((now.sec == eventTime.sec) && (now.usec > eventTime.usec))) - { - event->execute(); - delete event; - i = events.erase(i); - } - else - { - i++; - } - } -} - -void AudioSync_impl::setSyncGroup(MidiSyncGroup_impl *newSyncGroup) -{ - syncGroup = newSyncGroup; -} - -void AudioSync_impl::synchronizeTo(const TimeStamp& time) -{ -#ifdef AUDIO_DEBUG_DRIFT - TimeStamp drift = syncOffset; // debug drift -#endif - - syncOffset = audioPlayTime(); - timeStampDec(syncOffset, time); - -#ifdef AUDIO_DEBUG_DRIFT - timeStampDec(drift, syncOffset); // debug drift - printf("SYNC DRIFT %30s %30s: %f\n", - "AudioSync", "AudioSync", timeStampToDouble(drift)); -#endif -} - -AudioSync_impl *AudioSync_impl::find(AudioSync audioSync) -{ - list::iterator i; - - for(i = audioSyncImplList.begin(); i != audioSyncImplList.end(); i++) - { - if((*i)->_isEqual(audioSync._base())) - return (*i); - } - return 0; -} - -namespace Arts { REGISTER_IMPLEMENTATION(AudioSync_impl); } diff --git a/arts/midi/audiosync_impl.cpp b/arts/midi/audiosync_impl.cpp new file mode 100644 index 00000000..20f089df --- /dev/null +++ b/arts/midi/audiosync_impl.cpp @@ -0,0 +1,203 @@ + /* + + Copyright (C) 2001-2002 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + */ + +#include "audiosync_impl.h" +#include "midisyncgroup_impl.h" +#include "audiotimer.h" +#include "audiosubsys.h" +#include "timestampmath.h" + +#undef AUDIO_DEBUG_DRIFT + +using namespace std; +using namespace Arts; + +namespace Arts { + static list audioSyncImplList; +} + +void AudioSync_impl::AudioSyncEvent::execute() +{ + list::iterator i; + + for(i = startModules.begin(); i != startModules.end(); i++) + i->start(); + + for(i = stopModules.begin(); i != stopModules.end(); i++) + i->stop(); +} + +AudioSync_impl::AudioSync_impl() + : newEvent(new AudioSyncEvent), syncGroup(0) +{ + syncOffset = TimeStamp(0,0); + + timer = AudioTimer::subscribe(); + timer->addCallback(this); + + audioSyncImplList.push_back(this); +} + +AudioSync_impl::~AudioSync_impl() +{ + delete newEvent; + + while(!events.empty()) + { + delete events.front(); + events.pop_front(); + } + + if(syncGroup) + { + syncGroup->audioSyncDied(this); + syncGroup = 0; + } + audioSyncImplList.remove(this); + timer->removeCallback(this); + timer->unsubscribe(); +} + +TimeStamp AudioSync_impl::time() +{ + if(syncGroup) + return syncGroup->time(); + else + return audioTime(); +} + +TimeStamp AudioSync_impl::playTime() +{ + if(syncGroup) + return syncGroup->playTime(); + else + return audioPlayTime(); +} + +TimeStamp AudioSync_impl::audioTime() +{ + return timer->time(); +} + +TimeStamp AudioSync_impl::audioPlayTime() +{ + double delay = AudioSubSystem::the()->outputDelay(); + + TimeStamp time = audioTime(); + timeStampDec(time,timeStampFromDouble(delay)); + return time; +} + +TimeStamp AudioSync_impl::clientTime() +{ + TimeStamp time = audioTime(); + timeStampDec(time, syncOffset); + return time; +} + +void AudioSync_impl::queueStart(SynthModule synthModule) +{ + newEvent->startModules.push_back(synthModule); +} + +void AudioSync_impl::queueStop(SynthModule synthModule) +{ + newEvent->stopModules.push_back(synthModule); +} + +void AudioSync_impl::execute() +{ + newEvent->execute(); + newEvent->startModules.clear(); + newEvent->stopModules.clear(); +} + +void AudioSync_impl::executeAt(const TimeStamp& timeStamp) +{ + newEvent->time = timeStamp; + if(syncGroup) + timeStampInc(newEvent->time, syncOffset); + + events.push_back(newEvent); + + newEvent = new AudioSyncEvent; +} + +void AudioSync_impl::updateTime() +{ + TimeStamp now = audioTime(); + list::iterator i; + + i = events.begin(); + while(i != events.end()) + { + AudioSyncEvent *event = *i; + TimeStamp& eventTime = event->time; + + if( now.sec > eventTime.sec + || ((now.sec == eventTime.sec) && (now.usec > eventTime.usec))) + { + event->execute(); + delete event; + i = events.erase(i); + } + else + { + i++; + } + } +} + +void AudioSync_impl::setSyncGroup(MidiSyncGroup_impl *newSyncGroup) +{ + syncGroup = newSyncGroup; +} + +void AudioSync_impl::synchronizeTo(const TimeStamp& time) +{ +#ifdef AUDIO_DEBUG_DRIFT + TimeStamp drift = syncOffset; // debug drift +#endif + + syncOffset = audioPlayTime(); + timeStampDec(syncOffset, time); + +#ifdef AUDIO_DEBUG_DRIFT + timeStampDec(drift, syncOffset); // debug drift + printf("SYNC DRIFT %30s %30s: %f\n", + "AudioSync", "AudioSync", timeStampToDouble(drift)); +#endif +} + +AudioSync_impl *AudioSync_impl::find(AudioSync audioSync) +{ + list::iterator i; + + for(i = audioSyncImplList.begin(); i != audioSyncImplList.end(); i++) + { + if((*i)->_isEqual(audioSync._base())) + return (*i); + } + return 0; +} + +namespace Arts { REGISTER_IMPLEMENTATION(AudioSync_impl); } diff --git a/arts/midi/audiotimer.cc b/arts/midi/audiotimer.cc deleted file mode 100644 index a80e551c..00000000 --- a/arts/midi/audiotimer.cc +++ /dev/null @@ -1,98 +0,0 @@ - /* - - Copyright (C) 2001-2002 Stefan Westerfeld - stefan@space.twc.de - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - */ - -#include "artsmidi.h" -#include "artsflow.h" -#include "stdsynthmodule.h" -#include "debug.h" -#include "miditimercommon.h" -#include "audiotimer.h" -#include "flowsystem.h" - -using namespace std; -using namespace Arts; - -static AudioTimer *AudioTimer_the = 0; - -AudioTimer::AudioTimer() -{ - AudioTimer_the = this; - samples = seconds = 0; -} - -AudioTimer::~AudioTimer() -{ - AudioTimer_the = 0; -} - -TimeStamp AudioTimer::time() -{ - return TimeStamp(seconds, - (long)((float)samples / samplingRateFloat * 1000000.0)); -} - -void AudioTimer::notify(const Notification &) -{ - list::iterator i; - for(i = callbacks.begin(); i != callbacks.end(); i++) - (*i)->updateTime(); -} - -void AudioTimer::calculateBlock(unsigned long s) -{ - samples += s; - while(samples > samplingRate) - { - samples -= samplingRate; - seconds++; - } - Notification n; - n.receiver = this; - n.ID = 0; - n.data = 0; - n.internal = 0; - NotificationManager::the()->send(n); -} - -AudioTimer *AudioTimer::subscribe() -{ - if(!AudioTimer_the) - { - new AudioTimer(); - AudioTimer_the->_node()->start(); - } - else - { - AudioTimer_the->_copy(); - } - return AudioTimer_the; -} - -void AudioTimer::addCallback(AudioTimerCallback *callback) -{ - callbacks.push_back(callback); -} - -void AudioTimer::removeCallback(AudioTimerCallback *callback) -{ - callbacks.remove(callback); -} diff --git a/arts/midi/audiotimer.cpp b/arts/midi/audiotimer.cpp new file mode 100644 index 00000000..a80e551c --- /dev/null +++ b/arts/midi/audiotimer.cpp @@ -0,0 +1,98 @@ + /* + + Copyright (C) 2001-2002 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + */ + +#include "artsmidi.h" +#include "artsflow.h" +#include "stdsynthmodule.h" +#include "debug.h" +#include "miditimercommon.h" +#include "audiotimer.h" +#include "flowsystem.h" + +using namespace std; +using namespace Arts; + +static AudioTimer *AudioTimer_the = 0; + +AudioTimer::AudioTimer() +{ + AudioTimer_the = this; + samples = seconds = 0; +} + +AudioTimer::~AudioTimer() +{ + AudioTimer_the = 0; +} + +TimeStamp AudioTimer::time() +{ + return TimeStamp(seconds, + (long)((float)samples / samplingRateFloat * 1000000.0)); +} + +void AudioTimer::notify(const Notification &) +{ + list::iterator i; + for(i = callbacks.begin(); i != callbacks.end(); i++) + (*i)->updateTime(); +} + +void AudioTimer::calculateBlock(unsigned long s) +{ + samples += s; + while(samples > samplingRate) + { + samples -= samplingRate; + seconds++; + } + Notification n; + n.receiver = this; + n.ID = 0; + n.data = 0; + n.internal = 0; + NotificationManager::the()->send(n); +} + +AudioTimer *AudioTimer::subscribe() +{ + if(!AudioTimer_the) + { + new AudioTimer(); + AudioTimer_the->_node()->start(); + } + else + { + AudioTimer_the->_copy(); + } + return AudioTimer_the; +} + +void AudioTimer::addCallback(AudioTimerCallback *callback) +{ + callbacks.push_back(callback); +} + +void AudioTimer::removeCallback(AudioTimerCallback *callback) +{ + callbacks.remove(callback); +} diff --git a/arts/midi/midiclient_impl.cc b/arts/midi/midiclient_impl.cc deleted file mode 100644 index 0aa2ec6f..00000000 --- a/arts/midi/midiclient_impl.cc +++ /dev/null @@ -1,274 +0,0 @@ - /* - - Copyright (C) 2000-2002 Stefan Westerfeld - stefan@space.twc.de - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - */ - -#include "midiclient_impl.h" -#include "midimanager_impl.h" -#include "midimanagerport_impl.h" -#include "midisyncgroup_impl.h" -#include "timestampmath.h" - -#undef DEBUG_SYNC_DRIFT - -using namespace Arts; -using namespace std; - -MidiClient_impl::MidiClient_impl(const MidiClientInfo& info, - MidiManager_impl *manager) :_info(info), manager(manager), syncGroup(0) -{ -} - -MidiClient_impl::~MidiClient_impl() -{ - while(!_info.connections.empty()) - disconnect(manager->findClient(_info.connections[0])); - - if(syncGroup) - { - syncGroup->clientDied(this); - syncGroup = 0; - } - manager->removeClient(this); -} - -MidiClientInfo MidiClient_impl::info() -{ - return _info; -} - -void MidiClient_impl::title(const string &newvalue) -{ - _info.title = newvalue; -} - -string MidiClient_impl::title() -{ - return _info.title; -} - -void MidiClient_impl::addInputPort(MidiPort port) -{ - assert(_info.direction == mcdRecord); - - ports.push_back(port); - - // FIXME: should we synchronize inputPorts at all - rebuildConnections(); -} - -MidiPort MidiClient_impl::addOutputPort() -{ - assert(_info.direction == mcdPlay); - - MidiPort port = MidiPort::_from_base(new MidiManagerPort_impl(this)); - ports.push_back(port); - - rebuildConnections(); - return port; -} - -void MidiClient_impl::removePort(MidiPort port) -{ - list::iterator i = ports.begin(); - while(i != ports.end()) - { - if (i->_isEqual(port)) - i = ports.erase(i); - else - i++; - } - - rebuildConnections(); -} - -void MidiClient_impl::rebuildConnections() -{ - _connections.clear(); - - vector::iterator li; - for(li = _info.connections.begin(); li != _info.connections.end(); li++) - { - MidiClient_impl *other = manager->findClient(*li); - assert(other); - - list::iterator pi; - for(pi = other->ports.begin(); pi != other->ports.end(); pi++) - { - MidiClientConnection mcc; - mcc.offset = TimeStamp(0,0); - mcc.port = *pi; - _connections.push_back(mcc); - } - } - adjustSync(); -} - -list *MidiClient_impl::connections() -{ - return &_connections; -} - -static void removeElement(vector& vec, long el) -{ - vector tmp; - vec.swap(tmp); - vector::iterator i; - for(i = tmp.begin(); i != tmp.end(); i++) - if(*i != el) vec.push_back(*i); -} - -void MidiClient_impl::connect(MidiClient_impl *dest) -{ - assert(_info.direction != dest->_info.direction); - - disconnect(dest); - - _info.connections.push_back(dest->ID()); - dest->_info.connections.push_back(ID()); - - list::iterator pi; - - /* add the other clients ports to our connection list */ - for(pi = dest->ports.begin(); pi != dest->ports.end(); pi++) - { - MidiClientConnection mcc; - mcc.offset = TimeStamp(0,0); - mcc.port = *pi; - _connections.push_back(mcc); - } - - /* add our ports to the other clients connection list */ - for(pi = ports.begin(); pi != ports.end(); pi++) - { - MidiClientConnection mcc; - mcc.offset = TimeStamp(0,0); - mcc.port = *pi; - dest->_connections.push_back(mcc); - } - adjustSync(); -} - -void MidiClient_impl::disconnect(MidiClient_impl *dest) -{ - assert(_info.direction != dest->_info.direction); - - removeElement(_info.connections,dest->ID()); - removeElement(dest->_info.connections,ID()); - - list::iterator pi; - - /* remove the other clients ports from our connection list */ - for(pi = dest->ports.begin(); pi != dest->ports.end(); pi++) - { - list::iterator ci = _connections.begin(); - - while(ci != _connections.end()) - { - if(ci->port._isEqual(*pi)) - ci = _connections.erase(ci); - else - ci++; - } - } - - /* remove our ports from the other clients connection list */ - for(pi = ports.begin(); pi != ports.end(); pi++) - { - list::iterator ci = dest->_connections.begin(); - - while(ci != dest->_connections.end()) - { - if(ci->port._isEqual(*pi)) - ci = dest->_connections.erase(ci); - else - ci++; - } - } - adjustSync(); -} - -void MidiClient_impl::synchronizeTo(const TimeStamp& time) -{ - list::iterator i; - - for(i = _connections.begin(); i != _connections.end(); i++) - { - MidiClientConnection& mcc = *i; - -#ifdef DEBUG_SYNC_DRIFT - TimeStamp drift = mcc.offset; // debug drift -#endif - - mcc.offset = mcc.port.playTime(); - timeStampDec(mcc.offset, time); - -#ifdef DEBUG_SYNC_DRIFT - timeStampDec(drift,mcc.offset); // debug drift - printf("SYNC DRIFT %30s %30s: %f\n", - mcc.port._interfaceName().c_str(), _info.title.c_str(), - timeStampToDouble(drift)); -#endif - } -} - -void MidiClient_impl::setSyncGroup(MidiSyncGroup_impl *newSyncGroup) -{ - syncGroup = newSyncGroup; -} - -void MidiClient_impl::adjustSync() -{ - if(syncGroup) - syncGroup->clientChanged(this); - else - synchronizeTo(systemMidiTimer.time()); -} - -TimeStamp MidiClient_impl::time() -{ - if(syncGroup) - return syncGroup->time(); - else - return clientTime(); -} - -TimeStamp MidiClient_impl::playTime() -{ - if(syncGroup) - return syncGroup->playTime(); - else - return systemMidiTimer.time(); -} - -TimeStamp MidiClient_impl::clientTime() -{ - TimeStamp result = playTime(); - - list::iterator i; - for(i = _connections.begin(); i != _connections.end(); i++) - { - TimeStamp time = i->port.time(); - timeStampDec(time, i->offset); - result = timeStampMax(result, time); - } - - return result; -} diff --git a/arts/midi/midiclient_impl.cpp b/arts/midi/midiclient_impl.cpp new file mode 100644 index 00000000..0aa2ec6f --- /dev/null +++ b/arts/midi/midiclient_impl.cpp @@ -0,0 +1,274 @@ + /* + + Copyright (C) 2000-2002 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + */ + +#include "midiclient_impl.h" +#include "midimanager_impl.h" +#include "midimanagerport_impl.h" +#include "midisyncgroup_impl.h" +#include "timestampmath.h" + +#undef DEBUG_SYNC_DRIFT + +using namespace Arts; +using namespace std; + +MidiClient_impl::MidiClient_impl(const MidiClientInfo& info, + MidiManager_impl *manager) :_info(info), manager(manager), syncGroup(0) +{ +} + +MidiClient_impl::~MidiClient_impl() +{ + while(!_info.connections.empty()) + disconnect(manager->findClient(_info.connections[0])); + + if(syncGroup) + { + syncGroup->clientDied(this); + syncGroup = 0; + } + manager->removeClient(this); +} + +MidiClientInfo MidiClient_impl::info() +{ + return _info; +} + +void MidiClient_impl::title(const string &newvalue) +{ + _info.title = newvalue; +} + +string MidiClient_impl::title() +{ + return _info.title; +} + +void MidiClient_impl::addInputPort(MidiPort port) +{ + assert(_info.direction == mcdRecord); + + ports.push_back(port); + + // FIXME: should we synchronize inputPorts at all + rebuildConnections(); +} + +MidiPort MidiClient_impl::addOutputPort() +{ + assert(_info.direction == mcdPlay); + + MidiPort port = MidiPort::_from_base(new MidiManagerPort_impl(this)); + ports.push_back(port); + + rebuildConnections(); + return port; +} + +void MidiClient_impl::removePort(MidiPort port) +{ + list::iterator i = ports.begin(); + while(i != ports.end()) + { + if (i->_isEqual(port)) + i = ports.erase(i); + else + i++; + } + + rebuildConnections(); +} + +void MidiClient_impl::rebuildConnections() +{ + _connections.clear(); + + vector::iterator li; + for(li = _info.connections.begin(); li != _info.connections.end(); li++) + { + MidiClient_impl *other = manager->findClient(*li); + assert(other); + + list::iterator pi; + for(pi = other->ports.begin(); pi != other->ports.end(); pi++) + { + MidiClientConnection mcc; + mcc.offset = TimeStamp(0,0); + mcc.port = *pi; + _connections.push_back(mcc); + } + } + adjustSync(); +} + +list *MidiClient_impl::connections() +{ + return &_connections; +} + +static void removeElement(vector& vec, long el) +{ + vector tmp; + vec.swap(tmp); + vector::iterator i; + for(i = tmp.begin(); i != tmp.end(); i++) + if(*i != el) vec.push_back(*i); +} + +void MidiClient_impl::connect(MidiClient_impl *dest) +{ + assert(_info.direction != dest->_info.direction); + + disconnect(dest); + + _info.connections.push_back(dest->ID()); + dest->_info.connections.push_back(ID()); + + list::iterator pi; + + /* add the other clients ports to our connection list */ + for(pi = dest->ports.begin(); pi != dest->ports.end(); pi++) + { + MidiClientConnection mcc; + mcc.offset = TimeStamp(0,0); + mcc.port = *pi; + _connections.push_back(mcc); + } + + /* add our ports to the other clients connection list */ + for(pi = ports.begin(); pi != ports.end(); pi++) + { + MidiClientConnection mcc; + mcc.offset = TimeStamp(0,0); + mcc.port = *pi; + dest->_connections.push_back(mcc); + } + adjustSync(); +} + +void MidiClient_impl::disconnect(MidiClient_impl *dest) +{ + assert(_info.direction != dest->_info.direction); + + removeElement(_info.connections,dest->ID()); + removeElement(dest->_info.connections,ID()); + + list::iterator pi; + + /* remove the other clients ports from our connection list */ + for(pi = dest->ports.begin(); pi != dest->ports.end(); pi++) + { + list::iterator ci = _connections.begin(); + + while(ci != _connections.end()) + { + if(ci->port._isEqual(*pi)) + ci = _connections.erase(ci); + else + ci++; + } + } + + /* remove our ports from the other clients connection list */ + for(pi = ports.begin(); pi != ports.end(); pi++) + { + list::iterator ci = dest->_connections.begin(); + + while(ci != dest->_connections.end()) + { + if(ci->port._isEqual(*pi)) + ci = dest->_connections.erase(ci); + else + ci++; + } + } + adjustSync(); +} + +void MidiClient_impl::synchronizeTo(const TimeStamp& time) +{ + list::iterator i; + + for(i = _connections.begin(); i != _connections.end(); i++) + { + MidiClientConnection& mcc = *i; + +#ifdef DEBUG_SYNC_DRIFT + TimeStamp drift = mcc.offset; // debug drift +#endif + + mcc.offset = mcc.port.playTime(); + timeStampDec(mcc.offset, time); + +#ifdef DEBUG_SYNC_DRIFT + timeStampDec(drift,mcc.offset); // debug drift + printf("SYNC DRIFT %30s %30s: %f\n", + mcc.port._interfaceName().c_str(), _info.title.c_str(), + timeStampToDouble(drift)); +#endif + } +} + +void MidiClient_impl::setSyncGroup(MidiSyncGroup_impl *newSyncGroup) +{ + syncGroup = newSyncGroup; +} + +void MidiClient_impl::adjustSync() +{ + if(syncGroup) + syncGroup->clientChanged(this); + else + synchronizeTo(systemMidiTimer.time()); +} + +TimeStamp MidiClient_impl::time() +{ + if(syncGroup) + return syncGroup->time(); + else + return clientTime(); +} + +TimeStamp MidiClient_impl::playTime() +{ + if(syncGroup) + return syncGroup->playTime(); + else + return systemMidiTimer.time(); +} + +TimeStamp MidiClient_impl::clientTime() +{ + TimeStamp result = playTime(); + + list::iterator i; + for(i = _connections.begin(); i != _connections.end(); i++) + { + TimeStamp time = i->port.time(); + timeStampDec(time, i->offset); + result = timeStampMax(result, time); + } + + return result; +} diff --git a/arts/midi/midimanager_impl.cc b/arts/midi/midimanager_impl.cc deleted file mode 100644 index ea310503..00000000 --- a/arts/midi/midimanager_impl.cc +++ /dev/null @@ -1,156 +0,0 @@ - /* - - Copyright (C) 2000 Stefan Westerfeld - stefan@space.twc.de - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - */ - -#include "midimanager_impl.h" -#include "midiclient_impl.h" -#include "midisyncgroup_impl.h" -#include "debug.h" - -using namespace Arts; -using namespace std; - -static int cleanReference(const string& reference) -{ - Object test = Reference("global:"+reference); - if(test.isNull()) - { - Dispatcher::the()->globalComm().erase(reference); - return 1; - } - else - return 0; -} - -MidiManager_impl::MidiManager_impl() : nextID(1) -{ - cleanReference("Arts_MidiManager"); - if(!ObjectManager::the()->addGlobalReference(Object::_from_base(_copy()), - "Arts_MidiManager")) - { - arts_warning("can't register Arts::MidiManager"); - } - else - { - arts_debug("Arts::MidiManager registered successfully."); - } - Dispatcher::the()->ioManager()->addTimer(1000, this); -} - -MidiManager_impl::~MidiManager_impl() -{ - Dispatcher::the()->ioManager()->removeTimer(this); -} - -vector *MidiManager_impl::clients() -{ - if(!alsaMidiGateway.isNull()) - { - if(!alsaMidiGateway.rescan()) - alsaMidiGateway = AlsaMidiGateway::null(); - } - - vector *result = new vector; - - list::iterator i; - for(i = _clients.begin(); i != _clients.end(); i++) - result->push_back((*i)->info()); - - return result; -} - -MidiClient MidiManager_impl::addClient(MidiClientDirection direction, - MidiClientType type, const string& title, const string& autoRestoreID) -{ - MidiClientInfo info; - - info.ID = nextID++; - info.direction = direction; - info.type = type; - info.title = title; - info.autoRestoreID = autoRestoreID; - - MidiClient_impl *impl = new MidiClient_impl(info, this); - _clients.push_back(impl); - return MidiClient::_from_base(impl); -} - -void MidiManager_impl::removeClient(MidiClient_impl *client) -{ - _clients.remove(client); -} - -MidiClient_impl *MidiManager_impl::findClient(long clientID) -{ - list::iterator i; - - for(i = _clients.begin(); i != _clients.end(); i++) - { - if((*i)->ID() == clientID) - return (*i); - } - return 0; -} - -void MidiManager_impl::connect(long clientID, long destinationID) -{ - MidiClient_impl *src = findClient(clientID); - MidiClient_impl *dest = findClient(destinationID); - - arts_return_if_fail(src); - arts_return_if_fail(dest); - src->connect(dest); -} - -void MidiManager_impl::disconnect(long clientID, long destinationID) -{ - MidiClient_impl *src = findClient(clientID); - MidiClient_impl *dest = findClient(destinationID); - - arts_return_if_fail(src); - arts_return_if_fail(dest); - src->disconnect(dest); -} - -MidiSyncGroup MidiManager_impl::addSyncGroup() -{ - MidiSyncGroup_impl *impl = new MidiSyncGroup_impl(this); - syncGroups.push_back(impl); - return MidiSyncGroup::_from_base(impl); -} - -void MidiManager_impl::removeSyncGroup(MidiSyncGroup_impl *group) -{ - syncGroups.remove(group); -} - -void MidiManager_impl::notifyTime() -{ - list::iterator i; - for(i = _clients.begin(); i != _clients.end(); i++) - (*i)->adjustSync(); - - list::iterator gi; - for(gi = syncGroups.begin(); gi != syncGroups.end(); gi++) - (*gi)->adjustSync(); -} - -namespace Arts { REGISTER_IMPLEMENTATION(MidiManager_impl); } diff --git a/arts/midi/midimanager_impl.cpp b/arts/midi/midimanager_impl.cpp new file mode 100644 index 00000000..ea310503 --- /dev/null +++ b/arts/midi/midimanager_impl.cpp @@ -0,0 +1,156 @@ + /* + + Copyright (C) 2000 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + */ + +#include "midimanager_impl.h" +#include "midiclient_impl.h" +#include "midisyncgroup_impl.h" +#include "debug.h" + +using namespace Arts; +using namespace std; + +static int cleanReference(const string& reference) +{ + Object test = Reference("global:"+reference); + if(test.isNull()) + { + Dispatcher::the()->globalComm().erase(reference); + return 1; + } + else + return 0; +} + +MidiManager_impl::MidiManager_impl() : nextID(1) +{ + cleanReference("Arts_MidiManager"); + if(!ObjectManager::the()->addGlobalReference(Object::_from_base(_copy()), + "Arts_MidiManager")) + { + arts_warning("can't register Arts::MidiManager"); + } + else + { + arts_debug("Arts::MidiManager registered successfully."); + } + Dispatcher::the()->ioManager()->addTimer(1000, this); +} + +MidiManager_impl::~MidiManager_impl() +{ + Dispatcher::the()->ioManager()->removeTimer(this); +} + +vector *MidiManager_impl::clients() +{ + if(!alsaMidiGateway.isNull()) + { + if(!alsaMidiGateway.rescan()) + alsaMidiGateway = AlsaMidiGateway::null(); + } + + vector *result = new vector; + + list::iterator i; + for(i = _clients.begin(); i != _clients.end(); i++) + result->push_back((*i)->info()); + + return result; +} + +MidiClient MidiManager_impl::addClient(MidiClientDirection direction, + MidiClientType type, const string& title, const string& autoRestoreID) +{ + MidiClientInfo info; + + info.ID = nextID++; + info.direction = direction; + info.type = type; + info.title = title; + info.autoRestoreID = autoRestoreID; + + MidiClient_impl *impl = new MidiClient_impl(info, this); + _clients.push_back(impl); + return MidiClient::_from_base(impl); +} + +void MidiManager_impl::removeClient(MidiClient_impl *client) +{ + _clients.remove(client); +} + +MidiClient_impl *MidiManager_impl::findClient(long clientID) +{ + list::iterator i; + + for(i = _clients.begin(); i != _clients.end(); i++) + { + if((*i)->ID() == clientID) + return (*i); + } + return 0; +} + +void MidiManager_impl::connect(long clientID, long destinationID) +{ + MidiClient_impl *src = findClient(clientID); + MidiClient_impl *dest = findClient(destinationID); + + arts_return_if_fail(src); + arts_return_if_fail(dest); + src->connect(dest); +} + +void MidiManager_impl::disconnect(long clientID, long destinationID) +{ + MidiClient_impl *src = findClient(clientID); + MidiClient_impl *dest = findClient(destinationID); + + arts_return_if_fail(src); + arts_return_if_fail(dest); + src->disconnect(dest); +} + +MidiSyncGroup MidiManager_impl::addSyncGroup() +{ + MidiSyncGroup_impl *impl = new MidiSyncGroup_impl(this); + syncGroups.push_back(impl); + return MidiSyncGroup::_from_base(impl); +} + +void MidiManager_impl::removeSyncGroup(MidiSyncGroup_impl *group) +{ + syncGroups.remove(group); +} + +void MidiManager_impl::notifyTime() +{ + list::iterator i; + for(i = _clients.begin(); i != _clients.end(); i++) + (*i)->adjustSync(); + + list::iterator gi; + for(gi = syncGroups.begin(); gi != syncGroups.end(); gi++) + (*gi)->adjustSync(); +} + +namespace Arts { REGISTER_IMPLEMENTATION(MidiManager_impl); } diff --git a/arts/midi/midimanagerport_impl.cc b/arts/midi/midimanagerport_impl.cc deleted file mode 100644 index 3b4261a7..00000000 --- a/arts/midi/midimanagerport_impl.cc +++ /dev/null @@ -1,71 +0,0 @@ - /* - - Copyright (C) 2000 Stefan Westerfeld - stefan@space.twc.de - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - */ - -#include "midimanagerport_impl.h" -#include "midimanager_impl.h" -#include "midiclient_impl.h" -#include "timestampmath.h" - -#include - -using namespace Arts; -using namespace std; - -MidiManagerPort_impl::MidiManagerPort_impl(MidiClient_impl *client) - : client(client) -{ -} - -TimeStamp MidiManagerPort_impl::time() -{ - return client->time(); -} - -TimeStamp MidiManagerPort_impl::playTime() -{ - return client->playTime(); -} - - -void MidiManagerPort_impl::processCommand(const MidiCommand& command) -{ - list *connections = client->connections(); - list::iterator i; - - for(i = connections->begin(); i != connections->end(); i++) - i->port.processCommand(command); -} - -void MidiManagerPort_impl::processEvent(const MidiEvent& event) -{ - list *connections = client->connections(); - list::iterator i; - - for(i = connections->begin(); i != connections->end(); i++) - { - /* relocate the event to the synchronized time */ - TimeStamp time = event.time; - timeStampInc(time, i->offset); - - i->port.processEvent(MidiEvent(time, event.command)); - } -} diff --git a/arts/midi/midimanagerport_impl.cpp b/arts/midi/midimanagerport_impl.cpp new file mode 100644 index 00000000..3b4261a7 --- /dev/null +++ b/arts/midi/midimanagerport_impl.cpp @@ -0,0 +1,71 @@ + /* + + Copyright (C) 2000 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + */ + +#include "midimanagerport_impl.h" +#include "midimanager_impl.h" +#include "midiclient_impl.h" +#include "timestampmath.h" + +#include + +using namespace Arts; +using namespace std; + +MidiManagerPort_impl::MidiManagerPort_impl(MidiClient_impl *client) + : client(client) +{ +} + +TimeStamp MidiManagerPort_impl::time() +{ + return client->time(); +} + +TimeStamp MidiManagerPort_impl::playTime() +{ + return client->playTime(); +} + + +void MidiManagerPort_impl::processCommand(const MidiCommand& command) +{ + list *connections = client->connections(); + list::iterator i; + + for(i = connections->begin(); i != connections->end(); i++) + i->port.processCommand(command); +} + +void MidiManagerPort_impl::processEvent(const MidiEvent& event) +{ + list *connections = client->connections(); + list::iterator i; + + for(i = connections->begin(); i != connections->end(); i++) + { + /* relocate the event to the synchronized time */ + TimeStamp time = event.time; + timeStampInc(time, i->offset); + + i->port.processEvent(MidiEvent(time, event.command)); + } +} diff --git a/arts/midi/midisend.cc b/arts/midi/midisend.cc deleted file mode 100644 index 2b976d61..00000000 --- a/arts/midi/midisend.cc +++ /dev/null @@ -1,375 +0,0 @@ -/* - -Copyright (C) 1999 Emmeran Seehuber - the_emmy@gmx.de - -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. - -*/ - -/* - Changes: - 16.09.1999 Emmeran "Emmy" Seehuber - - Implementeted mapping of channels and pitches. - - Reworked option parsing, now using getopt(). - Note: The parameters of the programms have changed ! -*/ - -/* -** This program was in original by David G. Slomin. -** It was released to the Public Domain on 1/25/99. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "midisend.h" -#include -#include -#include - -using namespace std; - -int input_fd = -1, test = 0, verbose = 0; -char cFileName[1025]; -int optch; -CMidiMap Map; - -void usage(char *prog) -{ - fprintf(stderr,"\n"); - fprintf(stderr,"Usage: %s [ -f ] [ -m ] [ -v ] [ -t ]\n",prog); - fprintf(stderr," -f the mididevice to read the input from.\n"); - fprintf(stderr," Default is /dev/midi. If you specify a dash, it is stdin\n"); - fprintf(stderr," -m the mapfile to load.\n"); - fprintf(stderr," -v verbose output.\n"); - fprintf(stderr," -t test mode. Generates a testoutput on the midibus\n"); - fprintf(stderr," -l long test mode. Generates a testoutput on the midibus\n"); - exit(1); -} - -void parseArgs(int argc, char** argv) -{ - // Setup default - strcpy(cFileName,"/dev/midi"); - - while((optch = getopt(argc,argv,"m:f:vtl")) > 0) - { - switch(optch) - { - case 'm': if( !Map.readMap(optarg) ) - fprintf(stderr,"%s: can't read file %s!\n",argv[0],optarg); - break; - case 't': test = 1; - break; - case 'l': test = 2; - break; -#ifdef VERSION - case 'v': verbose = 1; printf("MidiSend %s\n", VERSION ); - break; -#endif - case 'f': strncpy(cFileName,optarg,1024); - break; - default: usage(argv[0]); - break; - } - } -} - - -#ifdef COMMON_BINARY -int midisend_main(int argc, char *argv[]) -#else -int main(int argc, char *argv[]) -#endif -{ - Arts::Dispatcher dispatcher; - Arts::MidiManager manager = Arts::Reference("global:Arts_MidiManager"); - - if (manager.isNull()) - { - fprintf(stderr, "%s trouble: No midimanager object found; please start " - "artsd.\n",argv[0]); - exit(EXIT_FAILURE); - } - - /* - ** MIDI input initialization. - */ - - parseArgs(argc,argv); - - string title = string("midisend (") + cFileName +")"; - Arts::MidiClient client - = manager.addClient(Arts::mcdPlay,Arts::mctApplication,title,"midisend"); - Arts::MidiPort port = client.addOutputPort(); - - if(test) - { - if( verbose ) - printf("performing test ...\n"); - unsigned long i,max=5000; - if(test==2) max = 20000; - for(i=0;i Word begins here. - } - } - - // The word starts here - pszWord = pszLine; - - // And now, goto the end of the word. - bCont = true; - while(bCont) { - char cHelp = *pszLine; - switch( cHelp ) - { - case 0: - case ',': - case ';': - case ' ': - case '\n': - case '\r': - case '\t': *pszLine++ = 0; bCont = false; break; // Goto next char - default: pszLine++; break; - } - } - - return true; -} - -void CMidiMap::parseLine(char* pszLine, const char* pszConfigFile, int nConfigLine ) -{ - char* pszWord = 0; - bool bOk = true; - - // Get first word of the line - bOk = bOk && getNextWord(pszLine,pszWord); - if( !bOk ) - return; - - // Skip comments - if( *pszWord == '#' ) - return; - - if( strcmp(pszWord,"PRC") == 0 ) { - bOk = bOk && getNextWord(pszLine,pszWord); - int nOrigChannel = atol(pszWord); - bOk = bOk && getNextWord(pszLine,pszWord); - int nStart = atol(pszWord); - bOk = bOk && getNextWord(pszLine,pszWord); - int nEnd = atol(pszWord); - bOk = bOk && getNextWord(pszLine,pszWord); - int nChannel = atol(pszWord); - if( bOk ) { - channelMaps[nOrigChannel].nChannel = nOrigChannel; - for( int i = nStart; i <= nEnd; i++ ) { - channelMaps[nOrigChannel].channelRemaps[i].nPitch = i; - channelMaps[nOrigChannel].channelRemaps[i].nChannel = nChannel; - } - } - else { - printf("midisend: (PRC) missing parameters at %s:%d\n", pszConfigFile,nConfigLine); - } - return; - } - - if( strcmp(pszWord,"PRD") == 0 ) { - bOk = bOk && getNextWord(pszLine,pszWord); - int nOrigChannel = atol(pszWord); - bOk = bOk && getNextWord(pszLine,pszWord); - int nStart = atol(pszWord); - bOk = bOk && getNextWord(pszLine,pszWord); - int nEnd = atol(pszWord); - bOk = bOk && getNextWord(pszLine,pszWord); - int nPitchDiff = atol(pszWord); - if( bOk ) { - channelMaps[nOrigChannel].nChannel = nOrigChannel; - for( int i = nStart; i <= nEnd; i++ ) { - channelMaps[nOrigChannel].pitchRemaps[i].nPitch = i; - channelMaps[nOrigChannel].pitchRemaps[i].nToPitch = i + nPitchDiff; - } - } - else { - printf("midisend: (PRD) missing parameters at %s:%d\n", pszConfigFile,nConfigLine); - } - return; - } - - if( strcmp(pszWord,"PTC") == 0 ) { - bOk = bOk && getNextWord(pszLine,pszWord); - int nOrigChannel = atol(pszWord); - bOk = bOk && getNextWord(pszLine,pszWord); - int nPitch = atol(pszWord); - bOk = bOk && getNextWord(pszLine,pszWord); - int nToChannel = atol(pszWord); - if( bOk ) { - channelMaps[nOrigChannel].nChannel = nOrigChannel; - channelMaps[nOrigChannel].channelRemaps[nPitch].nPitch = nPitch; - channelMaps[nOrigChannel].channelRemaps[nPitch].nChannel = nToChannel; - } - else { - printf("midisend: (PTC) missing parameters at %s:%d\n", pszConfigFile,nConfigLine); - } - return; - } - - if( strcmp(pszWord,"PTP") == 0 ) { - bOk = bOk && getNextWord(pszLine,pszWord); - int nOrigChannel = atol(pszWord); - bOk = bOk && getNextWord(pszLine,pszWord); - int nPitch = atol(pszWord); - bOk = bOk && getNextWord(pszLine,pszWord); - int nToPitch = atol(pszWord); - if( bOk ) { - channelMaps[nOrigChannel].nChannel = nOrigChannel; - channelMaps[nOrigChannel].pitchRemaps[nPitch].nPitch = nPitch; - channelMaps[nOrigChannel].pitchRemaps[nPitch].nToPitch = nToPitch; - } - else { - printf("midisend: (PTP) missing parameters at %s:%d\n", pszConfigFile,nConfigLine); - } - return; - } - - printf("midisend: Unknown command at %s:%d\n", pszConfigFile,nConfigLine); -} - -void CMidiMap::mapMsg(Byte* msg) -{ - // Get out the data for mapping - int nChannel = midimsgGetChannel(msg); - int nPitch = midimsgGetPitch(msg); - - // Is there something to map for this channel ? - if( channelMaps.find(nChannel) != channelMaps.end() ) { - // => Yes, than do it. - - // C/P => C - if( channelMaps[nChannel].channelRemaps.find(nPitch) != channelMaps[nChannel].channelRemaps.end() ) - midimsgSetChannel(msg,channelMaps[nChannel].channelRemaps[nPitch].nChannel); - - // C/P => P - if( channelMaps[nChannel].pitchRemaps.find(nPitch) != channelMaps[nChannel].pitchRemaps.end() ) { - midimsgSetPitch(msg,channelMaps[nChannel].pitchRemaps[nPitch].nToPitch); - } - } -} diff --git a/arts/midi/midisend.cpp b/arts/midi/midisend.cpp new file mode 100644 index 00000000..2b976d61 --- /dev/null +++ b/arts/midi/midisend.cpp @@ -0,0 +1,375 @@ +/* + +Copyright (C) 1999 Emmeran Seehuber + the_emmy@gmx.de + +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. + +*/ + +/* + Changes: + 16.09.1999 Emmeran "Emmy" Seehuber + - Implementeted mapping of channels and pitches. + - Reworked option parsing, now using getopt(). + Note: The parameters of the programms have changed ! +*/ + +/* +** This program was in original by David G. Slomin. +** It was released to the Public Domain on 1/25/99. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "midisend.h" +#include +#include +#include + +using namespace std; + +int input_fd = -1, test = 0, verbose = 0; +char cFileName[1025]; +int optch; +CMidiMap Map; + +void usage(char *prog) +{ + fprintf(stderr,"\n"); + fprintf(stderr,"Usage: %s [ -f ] [ -m ] [ -v ] [ -t ]\n",prog); + fprintf(stderr," -f the mididevice to read the input from.\n"); + fprintf(stderr," Default is /dev/midi. If you specify a dash, it is stdin\n"); + fprintf(stderr," -m the mapfile to load.\n"); + fprintf(stderr," -v verbose output.\n"); + fprintf(stderr," -t test mode. Generates a testoutput on the midibus\n"); + fprintf(stderr," -l long test mode. Generates a testoutput on the midibus\n"); + exit(1); +} + +void parseArgs(int argc, char** argv) +{ + // Setup default + strcpy(cFileName,"/dev/midi"); + + while((optch = getopt(argc,argv,"m:f:vtl")) > 0) + { + switch(optch) + { + case 'm': if( !Map.readMap(optarg) ) + fprintf(stderr,"%s: can't read file %s!\n",argv[0],optarg); + break; + case 't': test = 1; + break; + case 'l': test = 2; + break; +#ifdef VERSION + case 'v': verbose = 1; printf("MidiSend %s\n", VERSION ); + break; +#endif + case 'f': strncpy(cFileName,optarg,1024); + break; + default: usage(argv[0]); + break; + } + } +} + + +#ifdef COMMON_BINARY +int midisend_main(int argc, char *argv[]) +#else +int main(int argc, char *argv[]) +#endif +{ + Arts::Dispatcher dispatcher; + Arts::MidiManager manager = Arts::Reference("global:Arts_MidiManager"); + + if (manager.isNull()) + { + fprintf(stderr, "%s trouble: No midimanager object found; please start " + "artsd.\n",argv[0]); + exit(EXIT_FAILURE); + } + + /* + ** MIDI input initialization. + */ + + parseArgs(argc,argv); + + string title = string("midisend (") + cFileName +")"; + Arts::MidiClient client + = manager.addClient(Arts::mcdPlay,Arts::mctApplication,title,"midisend"); + Arts::MidiPort port = client.addOutputPort(); + + if(test) + { + if( verbose ) + printf("performing test ...\n"); + unsigned long i,max=5000; + if(test==2) max = 20000; + for(i=0;i Word begins here. + } + } + + // The word starts here + pszWord = pszLine; + + // And now, goto the end of the word. + bCont = true; + while(bCont) { + char cHelp = *pszLine; + switch( cHelp ) + { + case 0: + case ',': + case ';': + case ' ': + case '\n': + case '\r': + case '\t': *pszLine++ = 0; bCont = false; break; // Goto next char + default: pszLine++; break; + } + } + + return true; +} + +void CMidiMap::parseLine(char* pszLine, const char* pszConfigFile, int nConfigLine ) +{ + char* pszWord = 0; + bool bOk = true; + + // Get first word of the line + bOk = bOk && getNextWord(pszLine,pszWord); + if( !bOk ) + return; + + // Skip comments + if( *pszWord == '#' ) + return; + + if( strcmp(pszWord,"PRC") == 0 ) { + bOk = bOk && getNextWord(pszLine,pszWord); + int nOrigChannel = atol(pszWord); + bOk = bOk && getNextWord(pszLine,pszWord); + int nStart = atol(pszWord); + bOk = bOk && getNextWord(pszLine,pszWord); + int nEnd = atol(pszWord); + bOk = bOk && getNextWord(pszLine,pszWord); + int nChannel = atol(pszWord); + if( bOk ) { + channelMaps[nOrigChannel].nChannel = nOrigChannel; + for( int i = nStart; i <= nEnd; i++ ) { + channelMaps[nOrigChannel].channelRemaps[i].nPitch = i; + channelMaps[nOrigChannel].channelRemaps[i].nChannel = nChannel; + } + } + else { + printf("midisend: (PRC) missing parameters at %s:%d\n", pszConfigFile,nConfigLine); + } + return; + } + + if( strcmp(pszWord,"PRD") == 0 ) { + bOk = bOk && getNextWord(pszLine,pszWord); + int nOrigChannel = atol(pszWord); + bOk = bOk && getNextWord(pszLine,pszWord); + int nStart = atol(pszWord); + bOk = bOk && getNextWord(pszLine,pszWord); + int nEnd = atol(pszWord); + bOk = bOk && getNextWord(pszLine,pszWord); + int nPitchDiff = atol(pszWord); + if( bOk ) { + channelMaps[nOrigChannel].nChannel = nOrigChannel; + for( int i = nStart; i <= nEnd; i++ ) { + channelMaps[nOrigChannel].pitchRemaps[i].nPitch = i; + channelMaps[nOrigChannel].pitchRemaps[i].nToPitch = i + nPitchDiff; + } + } + else { + printf("midisend: (PRD) missing parameters at %s:%d\n", pszConfigFile,nConfigLine); + } + return; + } + + if( strcmp(pszWord,"PTC") == 0 ) { + bOk = bOk && getNextWord(pszLine,pszWord); + int nOrigChannel = atol(pszWord); + bOk = bOk && getNextWord(pszLine,pszWord); + int nPitch = atol(pszWord); + bOk = bOk && getNextWord(pszLine,pszWord); + int nToChannel = atol(pszWord); + if( bOk ) { + channelMaps[nOrigChannel].nChannel = nOrigChannel; + channelMaps[nOrigChannel].channelRemaps[nPitch].nPitch = nPitch; + channelMaps[nOrigChannel].channelRemaps[nPitch].nChannel = nToChannel; + } + else { + printf("midisend: (PTC) missing parameters at %s:%d\n", pszConfigFile,nConfigLine); + } + return; + } + + if( strcmp(pszWord,"PTP") == 0 ) { + bOk = bOk && getNextWord(pszLine,pszWord); + int nOrigChannel = atol(pszWord); + bOk = bOk && getNextWord(pszLine,pszWord); + int nPitch = atol(pszWord); + bOk = bOk && getNextWord(pszLine,pszWord); + int nToPitch = atol(pszWord); + if( bOk ) { + channelMaps[nOrigChannel].nChannel = nOrigChannel; + channelMaps[nOrigChannel].pitchRemaps[nPitch].nPitch = nPitch; + channelMaps[nOrigChannel].pitchRemaps[nPitch].nToPitch = nToPitch; + } + else { + printf("midisend: (PTP) missing parameters at %s:%d\n", pszConfigFile,nConfigLine); + } + return; + } + + printf("midisend: Unknown command at %s:%d\n", pszConfigFile,nConfigLine); +} + +void CMidiMap::mapMsg(Byte* msg) +{ + // Get out the data for mapping + int nChannel = midimsgGetChannel(msg); + int nPitch = midimsgGetPitch(msg); + + // Is there something to map for this channel ? + if( channelMaps.find(nChannel) != channelMaps.end() ) { + // => Yes, than do it. + + // C/P => C + if( channelMaps[nChannel].channelRemaps.find(nPitch) != channelMaps[nChannel].channelRemaps.end() ) + midimsgSetChannel(msg,channelMaps[nChannel].channelRemaps[nPitch].nChannel); + + // C/P => P + if( channelMaps[nChannel].pitchRemaps.find(nPitch) != channelMaps[nChannel].pitchRemaps.end() ) { + midimsgSetPitch(msg,channelMaps[nChannel].pitchRemaps[nPitch].nToPitch); + } + } +} diff --git a/arts/midi/midisyncgroup_impl.cc b/arts/midi/midisyncgroup_impl.cc deleted file mode 100644 index 5d5305dd..00000000 --- a/arts/midi/midisyncgroup_impl.cc +++ /dev/null @@ -1,125 +0,0 @@ - /* - - Copyright (C) 2002 Stefan Westerfeld - stefan@space.twc.de - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - */ - -#include "midisyncgroup_impl.h" -#include "audiosync_impl.h" -#include "midiclient_impl.h" -#include "midimanager_impl.h" -#include "timestampmath.h" - -using namespace Arts; -using namespace std; - -MidiSyncGroup_impl::MidiSyncGroup_impl(MidiManager_impl *manager) - : manager(manager) -{ -} - -MidiSyncGroup_impl::~MidiSyncGroup_impl() -{ - /* tell clients we're dead */ - list::iterator i; - for(i = clients.begin(); i != clients.end(); i++) - (*i)->setSyncGroup(0); - - list::iterator ai; - for(ai = audioSyncs.begin(); ai != audioSyncs.end(); ai++) - (*ai)->setSyncGroup(0); - - manager->removeSyncGroup(this); -} - -void MidiSyncGroup_impl::addClient(MidiClient client) -{ - /* add client to list */ - MidiClient_impl *impl = manager->findClient(client.info().ID); - impl->setSyncGroup(this); - clients.push_back(impl); - - impl->synchronizeTo(masterTimer.time()); -} - -void MidiSyncGroup_impl::removeClient(MidiClient client) -{ - /* remove client from the list */ - MidiClient_impl *impl = manager->findClient(client.info().ID); - impl->setSyncGroup(0); - clients.remove(impl); -} - -void MidiSyncGroup_impl::addAudioSync(AudioSync audioSync) -{ - AudioSync_impl *impl = AudioSync_impl::find(audioSync); - impl->setSyncGroup(this); - audioSyncs.push_back(impl); - - impl->synchronizeTo(masterTimer.time()); -} - -void MidiSyncGroup_impl::removeAudioSync(AudioSync audioSync) -{ - AudioSync_impl *impl = AudioSync_impl::find(audioSync); - impl->setSyncGroup(0); - audioSyncs.remove(impl); -} - -void MidiSyncGroup_impl::clientChanged(MidiClient_impl *client) -{ - client->synchronizeTo(masterTimer.time()); -} - -void MidiSyncGroup_impl::clientDied(MidiClient_impl *client) -{ - clients.remove(client); -} - -void MidiSyncGroup_impl::audioSyncDied(AudioSync_impl *audioSync) -{ - audioSyncs.remove(audioSync); -} - -TimeStamp MidiSyncGroup_impl::time() -{ - TimeStamp result = masterTimer.time(); - - list::iterator i; - for(i = clients.begin(); i != clients.end(); i++) - result = timeStampMax(result, (*i)->clientTime()); - - list::iterator ai; - for(ai = audioSyncs.begin(); ai != audioSyncs.end(); ai++) - result = timeStampMax(result, (*ai)->clientTime()); - - return result; -} - -TimeStamp MidiSyncGroup_impl::playTime() -{ - return masterTimer.time(); -} - -void MidiSyncGroup_impl::adjustSync() -{ - list::iterator ai; - for(ai = audioSyncs.begin(); ai != audioSyncs.end(); ai++) - (*ai)->synchronizeTo(masterTimer.time()); -} diff --git a/arts/midi/midisyncgroup_impl.cpp b/arts/midi/midisyncgroup_impl.cpp new file mode 100644 index 00000000..5d5305dd --- /dev/null +++ b/arts/midi/midisyncgroup_impl.cpp @@ -0,0 +1,125 @@ + /* + + Copyright (C) 2002 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + */ + +#include "midisyncgroup_impl.h" +#include "audiosync_impl.h" +#include "midiclient_impl.h" +#include "midimanager_impl.h" +#include "timestampmath.h" + +using namespace Arts; +using namespace std; + +MidiSyncGroup_impl::MidiSyncGroup_impl(MidiManager_impl *manager) + : manager(manager) +{ +} + +MidiSyncGroup_impl::~MidiSyncGroup_impl() +{ + /* tell clients we're dead */ + list::iterator i; + for(i = clients.begin(); i != clients.end(); i++) + (*i)->setSyncGroup(0); + + list::iterator ai; + for(ai = audioSyncs.begin(); ai != audioSyncs.end(); ai++) + (*ai)->setSyncGroup(0); + + manager->removeSyncGroup(this); +} + +void MidiSyncGroup_impl::addClient(MidiClient client) +{ + /* add client to list */ + MidiClient_impl *impl = manager->findClient(client.info().ID); + impl->setSyncGroup(this); + clients.push_back(impl); + + impl->synchronizeTo(masterTimer.time()); +} + +void MidiSyncGroup_impl::removeClient(MidiClient client) +{ + /* remove client from the list */ + MidiClient_impl *impl = manager->findClient(client.info().ID); + impl->setSyncGroup(0); + clients.remove(impl); +} + +void MidiSyncGroup_impl::addAudioSync(AudioSync audioSync) +{ + AudioSync_impl *impl = AudioSync_impl::find(audioSync); + impl->setSyncGroup(this); + audioSyncs.push_back(impl); + + impl->synchronizeTo(masterTimer.time()); +} + +void MidiSyncGroup_impl::removeAudioSync(AudioSync audioSync) +{ + AudioSync_impl *impl = AudioSync_impl::find(audioSync); + impl->setSyncGroup(0); + audioSyncs.remove(impl); +} + +void MidiSyncGroup_impl::clientChanged(MidiClient_impl *client) +{ + client->synchronizeTo(masterTimer.time()); +} + +void MidiSyncGroup_impl::clientDied(MidiClient_impl *client) +{ + clients.remove(client); +} + +void MidiSyncGroup_impl::audioSyncDied(AudioSync_impl *audioSync) +{ + audioSyncs.remove(audioSync); +} + +TimeStamp MidiSyncGroup_impl::time() +{ + TimeStamp result = masterTimer.time(); + + list::iterator i; + for(i = clients.begin(); i != clients.end(); i++) + result = timeStampMax(result, (*i)->clientTime()); + + list::iterator ai; + for(ai = audioSyncs.begin(); ai != audioSyncs.end(); ai++) + result = timeStampMax(result, (*ai)->clientTime()); + + return result; +} + +TimeStamp MidiSyncGroup_impl::playTime() +{ + return masterTimer.time(); +} + +void MidiSyncGroup_impl::adjustSync() +{ + list::iterator ai; + for(ai = audioSyncs.begin(); ai != audioSyncs.end(); ai++) + (*ai)->synchronizeTo(masterTimer.time()); +} diff --git a/arts/midi/midisynctest.cc b/arts/midi/midisynctest.cc deleted file mode 100644 index e1278f1b..00000000 --- a/arts/midi/midisynctest.cc +++ /dev/null @@ -1,137 +0,0 @@ - /* - - Copyright (C) 2002 Stefan Westerfeld - stefan@space.twc.de - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - */ - -#include "config.h" -#include "artsmidi.h" -#include "soundserver.h" -#include "timestampmath.h" -#include "debug.h" -#include -#include - -using namespace Arts; -using namespace std; - -int main() -{ - Dispatcher dispatcher; - - MidiManager midiManager = DynamicCast(Reference("global:Arts_MidiManager")); - if(midiManager.isNull()) - arts_fatal("midimanager is null"); - - SoundServer soundServer = DynamicCast(Reference("global:Arts_SoundServer")); - if(soundServer.isNull()) - arts_fatal("soundServer is null"); - - MidiSyncGroup syncGroup = midiManager.addSyncGroup(); - MidiClient client = midiManager.addClient(mcdPlay, mctApplication, "midisynctest", "midisynctest"); - syncGroup.addClient(client); - - MidiPort port = client.addOutputPort(); - - MidiClient client2 = midiManager.addClient(mcdPlay, mctApplication, "midisynctest2", "midisynctest2"); - - syncGroup.addClient(client2); - - MidiPort port2 = client2.addOutputPort(); - - /* setup audio synchronization */ - AudioSync audioSync; - audioSync = DynamicCast(soundServer.createObject("Arts::AudioSync")); - if(audioSync.isNull()) - arts_fatal("audioSync is null"); - - syncGroup.addAudioSync(audioSync); - - const int C = 60; - const int D = 62; - const int E = 64; - const int F = 65, f = F - 12; - const int G = 67, g = G - 12; - const int A = 69, a = A - 12; - const int H = 71, h = H - 12; - int np = 0; - int notes[] = { C,E,G,E,a,C,E,C,f,a,C,a,g,h,D,h,0 }; - - printf("connect port1 and port2 to two different ports in the artscontrol midi manager,\n" - "hit return"); - getchar(); - - TimeStamp t = port.time(); - timeStampInc(t,TimeStamp(0,100000)); - for(;;) - { - Synth_PLAY_WAV wav; - Synth_AMAN_PLAY sap; - - MidiEvent e; - - e = MidiEvent(t,MidiCommand(mcsNoteOn|0, notes[np], 100)); - - port.processEvent(e); - port2.processEvent(e); - - if((np & 1) == 0) - { - /* setup wave player */ - wav = DynamicCast(soundServer.createObject("Arts::Synth_PLAY_WAV")); - if(wav.isNull()) - arts_fatal("can't create Arts::Synth_PLAY_WAV"); - - sap = DynamicCast(soundServer.createObject("Arts::Synth_AMAN_PLAY")); - if(sap.isNull()) - arts_fatal("can't create Arts::Synth_AMAN_PLAY"); - - wav.filename("/opt/trinity/share/sounds/pop.wav"); - sap.title("midisynctest2"); - sap.autoRestoreID("midisynctest2"); - connect(wav,sap); - - audioSync.queueStart(wav); - audioSync.queueStart(sap); - audioSync.executeAt(t); - } - - timeStampInc(t,TimeStamp(0,100000)); - - e = MidiEvent(t,MidiCommand(mcsNoteOff|0, notes[np], 100)); - - port.processEvent(e); - port2.processEvent(e); - - if((np & 1) == 0) - { - audioSync.queueStop(wav); - audioSync.queueStop(sap); - audioSync.executeAt(t); - } - - timeStampInc(t,TimeStamp(0,400000)); - - while(port.time().sec < (t.sec - 2)) - usleep(100000); - - np++; - if(notes[np] == 0) np = 0; - } -} diff --git a/arts/midi/midisynctest.cpp b/arts/midi/midisynctest.cpp new file mode 100644 index 00000000..e1278f1b --- /dev/null +++ b/arts/midi/midisynctest.cpp @@ -0,0 +1,137 @@ + /* + + Copyright (C) 2002 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + */ + +#include "config.h" +#include "artsmidi.h" +#include "soundserver.h" +#include "timestampmath.h" +#include "debug.h" +#include +#include + +using namespace Arts; +using namespace std; + +int main() +{ + Dispatcher dispatcher; + + MidiManager midiManager = DynamicCast(Reference("global:Arts_MidiManager")); + if(midiManager.isNull()) + arts_fatal("midimanager is null"); + + SoundServer soundServer = DynamicCast(Reference("global:Arts_SoundServer")); + if(soundServer.isNull()) + arts_fatal("soundServer is null"); + + MidiSyncGroup syncGroup = midiManager.addSyncGroup(); + MidiClient client = midiManager.addClient(mcdPlay, mctApplication, "midisynctest", "midisynctest"); + syncGroup.addClient(client); + + MidiPort port = client.addOutputPort(); + + MidiClient client2 = midiManager.addClient(mcdPlay, mctApplication, "midisynctest2", "midisynctest2"); + + syncGroup.addClient(client2); + + MidiPort port2 = client2.addOutputPort(); + + /* setup audio synchronization */ + AudioSync audioSync; + audioSync = DynamicCast(soundServer.createObject("Arts::AudioSync")); + if(audioSync.isNull()) + arts_fatal("audioSync is null"); + + syncGroup.addAudioSync(audioSync); + + const int C = 60; + const int D = 62; + const int E = 64; + const int F = 65, f = F - 12; + const int G = 67, g = G - 12; + const int A = 69, a = A - 12; + const int H = 71, h = H - 12; + int np = 0; + int notes[] = { C,E,G,E,a,C,E,C,f,a,C,a,g,h,D,h,0 }; + + printf("connect port1 and port2 to two different ports in the artscontrol midi manager,\n" + "hit return"); + getchar(); + + TimeStamp t = port.time(); + timeStampInc(t,TimeStamp(0,100000)); + for(;;) + { + Synth_PLAY_WAV wav; + Synth_AMAN_PLAY sap; + + MidiEvent e; + + e = MidiEvent(t,MidiCommand(mcsNoteOn|0, notes[np], 100)); + + port.processEvent(e); + port2.processEvent(e); + + if((np & 1) == 0) + { + /* setup wave player */ + wav = DynamicCast(soundServer.createObject("Arts::Synth_PLAY_WAV")); + if(wav.isNull()) + arts_fatal("can't create Arts::Synth_PLAY_WAV"); + + sap = DynamicCast(soundServer.createObject("Arts::Synth_AMAN_PLAY")); + if(sap.isNull()) + arts_fatal("can't create Arts::Synth_AMAN_PLAY"); + + wav.filename("/opt/trinity/share/sounds/pop.wav"); + sap.title("midisynctest2"); + sap.autoRestoreID("midisynctest2"); + connect(wav,sap); + + audioSync.queueStart(wav); + audioSync.queueStart(sap); + audioSync.executeAt(t); + } + + timeStampInc(t,TimeStamp(0,100000)); + + e = MidiEvent(t,MidiCommand(mcsNoteOff|0, notes[np], 100)); + + port.processEvent(e); + port2.processEvent(e); + + if((np & 1) == 0) + { + audioSync.queueStop(wav); + audioSync.queueStop(sap); + audioSync.executeAt(t); + } + + timeStampInc(t,TimeStamp(0,400000)); + + while(port.time().sec < (t.sec - 2)) + usleep(100000); + + np++; + if(notes[np] == 0) np = 0; + } +} diff --git a/arts/midi/miditest_impl.cc b/arts/midi/miditest_impl.cc deleted file mode 100644 index b6ecce90..00000000 --- a/arts/midi/miditest_impl.cc +++ /dev/null @@ -1,57 +0,0 @@ - /* - - Copyright (C) 2000 Stefan Westerfeld - stefan@space.twc.de - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - */ - -#include "midimanager_impl.h" -#include - -namespace Arts { - -class MidiTest_impl : virtual public MidiTest_skel { -public: - Arts::TimeStamp time() - { - return TimeStamp(0,0); - } - Arts::TimeStamp playTime() - { - return time(); - } - void processCommand(const MidiCommand& command) - { - if((command.status & mcsCommandMask) == mcsNoteOn) - { - mcopbyte ch = command.status & mcsChannelMask; - - printf("noteon ch = %d, note = %d, vel = %d\n", - ch,command.data1,command.data2); - } - } - void processEvent(const MidiEvent& event) - { - printf("At %ld.%06ld: ",event.time.sec,event.time.usec); - processCommand(event.command); - } -}; - -REGISTER_IMPLEMENTATION(MidiTest_impl); -} - diff --git a/arts/midi/miditest_impl.cpp b/arts/midi/miditest_impl.cpp new file mode 100644 index 00000000..b6ecce90 --- /dev/null +++ b/arts/midi/miditest_impl.cpp @@ -0,0 +1,57 @@ + /* + + Copyright (C) 2000 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + */ + +#include "midimanager_impl.h" +#include + +namespace Arts { + +class MidiTest_impl : virtual public MidiTest_skel { +public: + Arts::TimeStamp time() + { + return TimeStamp(0,0); + } + Arts::TimeStamp playTime() + { + return time(); + } + void processCommand(const MidiCommand& command) + { + if((command.status & mcsCommandMask) == mcsNoteOn) + { + mcopbyte ch = command.status & mcsChannelMask; + + printf("noteon ch = %d, note = %d, vel = %d\n", + ch,command.data1,command.data2); + } + } + void processEvent(const MidiEvent& event) + { + printf("At %ld.%06ld: ",event.time.sec,event.time.usec); + processCommand(event.command); + } +}; + +REGISTER_IMPLEMENTATION(MidiTest_impl); +} + diff --git a/arts/midi/miditimercommon.cc b/arts/midi/miditimercommon.cc deleted file mode 100644 index 69597b32..00000000 --- a/arts/midi/miditimercommon.cc +++ /dev/null @@ -1,72 +0,0 @@ - /* - - Copyright (C) 2001 Stefan Westerfeld - stefan@space.twc.de - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - */ - -#include "artsmidi.h" -#include "debug.h" -#include "miditimercommon.h" -#include "math.h" - -#undef DEBUG_JITTER - -using namespace std; -using namespace Arts; - -MidiTimerCommon::MidiTimerCommon() :refCount(0) -{ - refCount = 0; -} - -MidiTimerCommon::~MidiTimerCommon() -{ - arts_assert(refCount == 0); -} - -void MidiTimerCommon::processQueue() -{ - TimeStamp now = time(); - - list::iterator n = noteQueue.begin(); - while(n != noteQueue.end()) - { - TSNote& note = *n; - TimeStamp& noteTime = note.event.time; - - if( now.sec > noteTime.sec - || ((now.sec == noteTime.sec) && (now.usec > noteTime.usec))) - { -#ifdef DEBUG_JITTER - float jitter = (now.sec-noteTime.sec) * 1000.0; - jitter += (float)(now.usec-noteTime.usec) / 1000.0; - arts_debug("midi jitter: %f",jitter); -#endif - - note.port.processCommand(note.event.command); - n = noteQueue.erase(n); - } - else n++; - } -} - -void MidiTimerCommon::queueEvent(MidiPort port,const MidiEvent& event) -{ - noteQueue.push_back(TSNote(port, event)); -} diff --git a/arts/midi/miditimercommon.cpp b/arts/midi/miditimercommon.cpp new file mode 100644 index 00000000..69597b32 --- /dev/null +++ b/arts/midi/miditimercommon.cpp @@ -0,0 +1,72 @@ + /* + + Copyright (C) 2001 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + */ + +#include "artsmidi.h" +#include "debug.h" +#include "miditimercommon.h" +#include "math.h" + +#undef DEBUG_JITTER + +using namespace std; +using namespace Arts; + +MidiTimerCommon::MidiTimerCommon() :refCount(0) +{ + refCount = 0; +} + +MidiTimerCommon::~MidiTimerCommon() +{ + arts_assert(refCount == 0); +} + +void MidiTimerCommon::processQueue() +{ + TimeStamp now = time(); + + list::iterator n = noteQueue.begin(); + while(n != noteQueue.end()) + { + TSNote& note = *n; + TimeStamp& noteTime = note.event.time; + + if( now.sec > noteTime.sec + || ((now.sec == noteTime.sec) && (now.usec > noteTime.usec))) + { +#ifdef DEBUG_JITTER + float jitter = (now.sec-noteTime.sec) * 1000.0; + jitter += (float)(now.usec-noteTime.usec) / 1000.0; + arts_debug("midi jitter: %f",jitter); +#endif + + note.port.processCommand(note.event.command); + n = noteQueue.erase(n); + } + else n++; + } +} + +void MidiTimerCommon::queueEvent(MidiPort port,const MidiEvent& event) +{ + noteQueue.push_back(TSNote(port, event)); +} diff --git a/arts/midi/rawmidiport_impl.cc b/arts/midi/rawmidiport_impl.cc deleted file mode 100644 index f8311bd6..00000000 --- a/arts/midi/rawmidiport_impl.cc +++ /dev/null @@ -1,306 +0,0 @@ - /* - - Copyright (C) 2000 Stefan Westerfeld - stefan@space.twc.de - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - */ - -#include "artsmidi.h" -#include -#include -#include - -using namespace std; - -namespace Arts { - -class RawMidiPort_impl : virtual public RawMidiPort_skel, - virtual public IONotify -{ -protected: - int fd; - - string _device; - bool _input, _output; - bool _running; - mcopbyte laststatus; - queue inq; - MidiClient clientRecord, clientPlay; - MidiPort outputPort; - MidiManager manager; - - RawMidiPort self() { - return RawMidiPort::_from_base(_copy()); - } - SystemMidiTimer timer; - -public: - RawMidiPort_impl() - :_device("/dev/midi"), _input(true), _output(true), _running(false), - clientRecord(MidiClient::null()), clientPlay(MidiClient::null()), - outputPort(MidiPort::null()), - manager(Reference("global:Arts_MidiManager")) - { - } - Arts::TimeStamp time() - { - return timer.time(); - } - Arts::TimeStamp playTime() - { - return timer.time(); - } - - // attribute string running; - bool running() { return _running; } - void running(bool newrunning) { - if(_running == newrunning) return; - - if(newrunning) - open(); - else - close(); - - running_changed(_running); - } - - // attribute string device; - void device(const string& newdevice) - { - if(newdevice == _device) return; - - if(_running) - { - close(); - _device = newdevice; - open(); - } - else _device = newdevice; - - device_changed(newdevice); - } - string device() { return _device; } - - // attribute boolean input; - void input(bool newinput) - { - if(newinput == _input) return; - - if(_running) - { - close(); - _input = newinput; - open(); - } - else _input = newinput; - - input_changed(newinput); - } - bool input() { return _input; } - - // attribute boolean output; - void output(bool newoutput) - { - if(newoutput == _output) return; - - if(_running) - { - close(); - _output = newoutput; - open(); - } - else _output = newoutput; - - output_changed(newoutput); - } - bool output() { return _output; } - - bool open() { - arts_return_val_if_fail(_running == false, true); - arts_return_val_if_fail(_output || _input, false); - arts_return_val_if_fail(manager.isNull() == false, false); - laststatus = 0; - - int mode = O_NDELAY; - if(_input) - { - if(_output) - mode |= O_RDWR; - else - mode |= O_RDONLY; - } - else mode |= O_WRONLY; - - fd = ::open(_device.c_str(),mode); - if(fd != -1) - { - IOManager *iom = Dispatcher::the()->ioManager(); - if(_output) - iom->watchFD(fd,IOType::read,this); - - string name = "OSS Midi Port ("+_device+")"; - if(_input) - { - clientRecord = - manager.addClient(mcdRecord,mctDestination,name,name); - clientRecord.addInputPort(self()); - } - if(_output) - { - clientPlay = - manager.addClient(mcdPlay,mctDestination,name,name); - outputPort = clientPlay.addOutputPort(); - } - - _running = true; - running_changed(true); - } - return _running; - } - - void close() - { - arts_return_if_fail(_running == true); - - if(_input) - { - clientRecord.removePort(self()); - clientRecord = MidiClient::null(); - } - if(_output) - { - clientPlay.removePort(outputPort); - clientPlay = MidiClient::null(); - } - - Dispatcher::the()->ioManager()->remove(this,IOType::all); - ::close(fd); - } - - int midiMsgLen(mcopbyte status) - { - switch(status & mcsCommandMask) - { - case mcsNoteOn: - case mcsNoteOff: - case mcsKeyPressure: - case mcsParameter: - case mcsPitchWheel: - return 3; - break; - case mcsProgram: - case mcsChannelPressure: - return 2; - break; - } - return 0; - } - void notifyIO(int fd, int type) - { - arts_return_if_fail(_running); - assert(fd == this->fd); - - // convert iomanager notification types to audiosubsys notification - if(type & IOType::read) - { - mcopbyte buffer[1024]; - int count = read(fd,buffer,1024); - for(int i=0; i read something - * away and hope we'll find a status byte */ - inq.pop(); - } - } - } - void processCommand(const MidiCommand& command) - { - unsigned char message[3] = { command.status, command.data1, command.data2 }; - - int len = midiMsgLen(command.status); - if(midiMsgLen(command.status)) - write(fd, message, len); - } - void processEvent(const MidiEvent& event) - { - timer.queueEvent(self(), event); - } -}; - -REGISTER_IMPLEMENTATION(RawMidiPort_impl); -} - diff --git a/arts/midi/rawmidiport_impl.cpp b/arts/midi/rawmidiport_impl.cpp new file mode 100644 index 00000000..f8311bd6 --- /dev/null +++ b/arts/midi/rawmidiport_impl.cpp @@ -0,0 +1,306 @@ + /* + + Copyright (C) 2000 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + */ + +#include "artsmidi.h" +#include +#include +#include + +using namespace std; + +namespace Arts { + +class RawMidiPort_impl : virtual public RawMidiPort_skel, + virtual public IONotify +{ +protected: + int fd; + + string _device; + bool _input, _output; + bool _running; + mcopbyte laststatus; + queue inq; + MidiClient clientRecord, clientPlay; + MidiPort outputPort; + MidiManager manager; + + RawMidiPort self() { + return RawMidiPort::_from_base(_copy()); + } + SystemMidiTimer timer; + +public: + RawMidiPort_impl() + :_device("/dev/midi"), _input(true), _output(true), _running(false), + clientRecord(MidiClient::null()), clientPlay(MidiClient::null()), + outputPort(MidiPort::null()), + manager(Reference("global:Arts_MidiManager")) + { + } + Arts::TimeStamp time() + { + return timer.time(); + } + Arts::TimeStamp playTime() + { + return timer.time(); + } + + // attribute string running; + bool running() { return _running; } + void running(bool newrunning) { + if(_running == newrunning) return; + + if(newrunning) + open(); + else + close(); + + running_changed(_running); + } + + // attribute string device; + void device(const string& newdevice) + { + if(newdevice == _device) return; + + if(_running) + { + close(); + _device = newdevice; + open(); + } + else _device = newdevice; + + device_changed(newdevice); + } + string device() { return _device; } + + // attribute boolean input; + void input(bool newinput) + { + if(newinput == _input) return; + + if(_running) + { + close(); + _input = newinput; + open(); + } + else _input = newinput; + + input_changed(newinput); + } + bool input() { return _input; } + + // attribute boolean output; + void output(bool newoutput) + { + if(newoutput == _output) return; + + if(_running) + { + close(); + _output = newoutput; + open(); + } + else _output = newoutput; + + output_changed(newoutput); + } + bool output() { return _output; } + + bool open() { + arts_return_val_if_fail(_running == false, true); + arts_return_val_if_fail(_output || _input, false); + arts_return_val_if_fail(manager.isNull() == false, false); + laststatus = 0; + + int mode = O_NDELAY; + if(_input) + { + if(_output) + mode |= O_RDWR; + else + mode |= O_RDONLY; + } + else mode |= O_WRONLY; + + fd = ::open(_device.c_str(),mode); + if(fd != -1) + { + IOManager *iom = Dispatcher::the()->ioManager(); + if(_output) + iom->watchFD(fd,IOType::read,this); + + string name = "OSS Midi Port ("+_device+")"; + if(_input) + { + clientRecord = + manager.addClient(mcdRecord,mctDestination,name,name); + clientRecord.addInputPort(self()); + } + if(_output) + { + clientPlay = + manager.addClient(mcdPlay,mctDestination,name,name); + outputPort = clientPlay.addOutputPort(); + } + + _running = true; + running_changed(true); + } + return _running; + } + + void close() + { + arts_return_if_fail(_running == true); + + if(_input) + { + clientRecord.removePort(self()); + clientRecord = MidiClient::null(); + } + if(_output) + { + clientPlay.removePort(outputPort); + clientPlay = MidiClient::null(); + } + + Dispatcher::the()->ioManager()->remove(this,IOType::all); + ::close(fd); + } + + int midiMsgLen(mcopbyte status) + { + switch(status & mcsCommandMask) + { + case mcsNoteOn: + case mcsNoteOff: + case mcsKeyPressure: + case mcsParameter: + case mcsPitchWheel: + return 3; + break; + case mcsProgram: + case mcsChannelPressure: + return 2; + break; + } + return 0; + } + void notifyIO(int fd, int type) + { + arts_return_if_fail(_running); + assert(fd == this->fd); + + // convert iomanager notification types to audiosubsys notification + if(type & IOType::read) + { + mcopbyte buffer[1024]; + int count = read(fd,buffer,1024); + for(int i=0; i read something + * away and hope we'll find a status byte */ + inq.pop(); + } + } + } + void processCommand(const MidiCommand& command) + { + unsigned char message[3] = { command.status, command.data1, command.data2 }; + + int len = midiMsgLen(command.status); + if(midiMsgLen(command.status)) + write(fd, message, len); + } + void processEvent(const MidiEvent& event) + { + timer.queueEvent(self(), event); + } +}; + +REGISTER_IMPLEMENTATION(RawMidiPort_impl); +} + diff --git a/arts/midi/systemmiditimer_impl.cc b/arts/midi/systemmiditimer_impl.cc deleted file mode 100644 index 4f7329b2..00000000 --- a/arts/midi/systemmiditimer_impl.cc +++ /dev/null @@ -1,105 +0,0 @@ - /* - - Copyright (C) 2001 Stefan Westerfeld - stefan@space.twc.de - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - */ - -#include "artsmidi.h" -#include "debug.h" -#include "miditimercommon.h" - -using namespace std; -using namespace Arts; - -namespace Arts { - -class SystemMidiTimerCommon : public MidiTimerCommon, - public TimeNotify { -protected: - SystemMidiTimerCommon(); - virtual ~SystemMidiTimerCommon(); - -public: - // allocation: share one SystemMidiTimerCommon for everbody who needs one - static SystemMidiTimerCommon *subscribe(); - - void notifyTime(); - TimeStamp time(); -}; - -} - -static SystemMidiTimerCommon *SystemMidiTimerCommon_the = 0; - -SystemMidiTimerCommon::SystemMidiTimerCommon() -{ - SystemMidiTimerCommon_the = this; - Dispatcher::the()->ioManager()->addTimer(10, this); -} - -SystemMidiTimerCommon::~SystemMidiTimerCommon() -{ - Dispatcher::the()->ioManager()->removeTimer(this); - SystemMidiTimerCommon_the = 0; -} - -TimeStamp SystemMidiTimerCommon::time() -{ - timeval tv; - gettimeofday(&tv,0); - return TimeStamp(tv.tv_sec, tv.tv_usec); -} - -void SystemMidiTimerCommon::notifyTime() -{ - processQueue(); -} - -SystemMidiTimerCommon *SystemMidiTimerCommon::subscribe() -{ - if(!SystemMidiTimerCommon_the) new SystemMidiTimerCommon(); - SystemMidiTimerCommon_the->refCount++; - return SystemMidiTimerCommon_the; -} - -class SystemMidiTimer_impl : public SystemMidiTimer_skel { -protected: - SystemMidiTimerCommon *timer; -public: - SystemMidiTimer_impl() - { - timer = SystemMidiTimerCommon::subscribe(); - } - ~SystemMidiTimer_impl() - { - timer->unsubscribe(); - } - TimeStamp time() - { - return timer->time(); - } - void queueEvent(MidiPort port, const MidiEvent& event) - { - timer->queueEvent(port, event); - } -}; - -namespace Arts { - REGISTER_IMPLEMENTATION(SystemMidiTimer_impl); -} diff --git a/arts/midi/systemmiditimer_impl.cpp b/arts/midi/systemmiditimer_impl.cpp new file mode 100644 index 00000000..4f7329b2 --- /dev/null +++ b/arts/midi/systemmiditimer_impl.cpp @@ -0,0 +1,105 @@ + /* + + Copyright (C) 2001 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + */ + +#include "artsmidi.h" +#include "debug.h" +#include "miditimercommon.h" + +using namespace std; +using namespace Arts; + +namespace Arts { + +class SystemMidiTimerCommon : public MidiTimerCommon, + public TimeNotify { +protected: + SystemMidiTimerCommon(); + virtual ~SystemMidiTimerCommon(); + +public: + // allocation: share one SystemMidiTimerCommon for everbody who needs one + static SystemMidiTimerCommon *subscribe(); + + void notifyTime(); + TimeStamp time(); +}; + +} + +static SystemMidiTimerCommon *SystemMidiTimerCommon_the = 0; + +SystemMidiTimerCommon::SystemMidiTimerCommon() +{ + SystemMidiTimerCommon_the = this; + Dispatcher::the()->ioManager()->addTimer(10, this); +} + +SystemMidiTimerCommon::~SystemMidiTimerCommon() +{ + Dispatcher::the()->ioManager()->removeTimer(this); + SystemMidiTimerCommon_the = 0; +} + +TimeStamp SystemMidiTimerCommon::time() +{ + timeval tv; + gettimeofday(&tv,0); + return TimeStamp(tv.tv_sec, tv.tv_usec); +} + +void SystemMidiTimerCommon::notifyTime() +{ + processQueue(); +} + +SystemMidiTimerCommon *SystemMidiTimerCommon::subscribe() +{ + if(!SystemMidiTimerCommon_the) new SystemMidiTimerCommon(); + SystemMidiTimerCommon_the->refCount++; + return SystemMidiTimerCommon_the; +} + +class SystemMidiTimer_impl : public SystemMidiTimer_skel { +protected: + SystemMidiTimerCommon *timer; +public: + SystemMidiTimer_impl() + { + timer = SystemMidiTimerCommon::subscribe(); + } + ~SystemMidiTimer_impl() + { + timer->unsubscribe(); + } + TimeStamp time() + { + return timer->time(); + } + void queueEvent(MidiPort port, const MidiEvent& event) + { + timer->queueEvent(port, event); + } +}; + +namespace Arts { + REGISTER_IMPLEMENTATION(SystemMidiTimer_impl); +} diff --git a/arts/midi/timestampmath.cc b/arts/midi/timestampmath.cc deleted file mode 100644 index e8d5500a..00000000 --- a/arts/midi/timestampmath.cc +++ /dev/null @@ -1,112 +0,0 @@ - /* - - Copyright (C) 2002 Stefan Westerfeld - stefan@space.twc.de - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - */ - -#include "timestampmath.h" -#include -#include - -using namespace std; - -namespace Arts { -void timeStampInc(TimeStamp& t, const TimeStamp& delta) -{ - /* expect a normalized t, delta */ - arts_return_if_fail(t.usec >= 0 && t.usec < 1000000); - arts_return_if_fail(delta.usec >= 0 && delta.usec < 1000000); - - t.sec += delta.sec; - t.usec += delta.usec; - - if (t.usec >= 1000000) - { - t.usec -= 1000000; - t.sec += 1; - } - - arts_assert (t.usec >= 0 && t.usec < 1000000); -} - -void timeStampDec(TimeStamp& t, const TimeStamp& delta) -{ - /* expect a normalized t, delta */ - arts_return_if_fail(t.usec >= 0 && t.usec < 1000000); - arts_return_if_fail(delta.usec >= 0 && delta.usec < 1000000); - - t.sec -= delta.sec; - t.usec -= delta.usec; - - if(t.usec < 0) - { - t.usec += 1000000; - t.sec -= 1; - } - - arts_assert(t.usec >= 0 && t.usec < 1000000); -} - -string timeStampToString(const TimeStamp& t) -{ - arts_return_val_if_fail(t.usec >= 0 && t.usec < 1000000, ""); - - char buffer[1024]; - if(t.sec < 0 && t.usec != 0) - { - sprintf(buffer, "-%d.%06d", -t.sec-1, 1000000-t.usec); - } - else - { - sprintf(buffer, "%d.%06d", t.sec, t.usec); - } - return buffer; -} - -double timeStampToDouble(const TimeStamp& t) -{ - arts_return_val_if_fail(t.usec >= 0 && t.usec < 1000000, 0.0); - - return double(t.sec) + double(t.usec)/1000000.0; -} - -TimeStamp timeStampFromDouble(double d) -{ - TimeStamp t; - - arts_return_val_if_fail(d >= 0, t); - - t.sec = int(d); - d -= t.sec; - t.usec = int(d * 1000000.0); - - return t; -} - -TimeStamp timeStampMax(const TimeStamp& t1, const TimeStamp& t2) -{ - if(t1.sec > t2.sec) - return t1; - else if((t1.sec == t2.sec) && (t1.usec > t2.usec)) - return t1; - else - return t2; -} - -} diff --git a/arts/midi/timestampmath.cpp b/arts/midi/timestampmath.cpp new file mode 100644 index 00000000..e8d5500a --- /dev/null +++ b/arts/midi/timestampmath.cpp @@ -0,0 +1,112 @@ + /* + + Copyright (C) 2002 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + */ + +#include "timestampmath.h" +#include +#include + +using namespace std; + +namespace Arts { +void timeStampInc(TimeStamp& t, const TimeStamp& delta) +{ + /* expect a normalized t, delta */ + arts_return_if_fail(t.usec >= 0 && t.usec < 1000000); + arts_return_if_fail(delta.usec >= 0 && delta.usec < 1000000); + + t.sec += delta.sec; + t.usec += delta.usec; + + if (t.usec >= 1000000) + { + t.usec -= 1000000; + t.sec += 1; + } + + arts_assert (t.usec >= 0 && t.usec < 1000000); +} + +void timeStampDec(TimeStamp& t, const TimeStamp& delta) +{ + /* expect a normalized t, delta */ + arts_return_if_fail(t.usec >= 0 && t.usec < 1000000); + arts_return_if_fail(delta.usec >= 0 && delta.usec < 1000000); + + t.sec -= delta.sec; + t.usec -= delta.usec; + + if(t.usec < 0) + { + t.usec += 1000000; + t.sec -= 1; + } + + arts_assert(t.usec >= 0 && t.usec < 1000000); +} + +string timeStampToString(const TimeStamp& t) +{ + arts_return_val_if_fail(t.usec >= 0 && t.usec < 1000000, ""); + + char buffer[1024]; + if(t.sec < 0 && t.usec != 0) + { + sprintf(buffer, "-%d.%06d", -t.sec-1, 1000000-t.usec); + } + else + { + sprintf(buffer, "%d.%06d", t.sec, t.usec); + } + return buffer; +} + +double timeStampToDouble(const TimeStamp& t) +{ + arts_return_val_if_fail(t.usec >= 0 && t.usec < 1000000, 0.0); + + return double(t.sec) + double(t.usec)/1000000.0; +} + +TimeStamp timeStampFromDouble(double d) +{ + TimeStamp t; + + arts_return_val_if_fail(d >= 0, t); + + t.sec = int(d); + d -= t.sec; + t.usec = int(d * 1000000.0); + + return t; +} + +TimeStamp timeStampMax(const TimeStamp& t1, const TimeStamp& t2) +{ + if(t1.sec > t2.sec) + return t1; + else if((t1.sec == t2.sec) && (t1.usec > t2.usec)) + return t1; + else + return t2; +} + +} -- cgit v1.2.1