Factor out and extend MIDIXML implementation

This commit is contained in:
David Robillard 2016-11-06 19:27:26 -05:00
parent 0f5a73a7fd
commit 875b1367b2
6 changed files with 99 additions and 129 deletions

View file

@ -409,8 +409,7 @@ def build(bld):
'DATA_DIR="' + os.path.normpath(bld.env['DATADIR']) + '"',
'CONFIG_DIR="' + os.path.normpath(bld.env['SYSCONFDIR']) + '"',
'LOCALEDIR="' + os.path.normpath(bld.env['LOCALEDIR']) + '"',
'LIBARDOUR="' + bld.env['lwrcase_dirname'] + '"',
'EVORAL_MIDI_XML=1',
'LIBARDOUR="' + bld.env['lwrcase_dirname'] + '"'
]
#obj.source += ' st_stretch.cc st_pitch.cc '

View file

@ -26,10 +26,6 @@
#include "evoral/Event.hpp"
#include "evoral/midi_events.h"
#ifdef EVORAL_MIDI_XML
class XMLNode;
#endif
namespace Evoral {
/** MIDI helper functions for an Event.
@ -49,14 +45,6 @@ public:
: Event<Time>(copy, alloc)
{}
#ifdef EVORAL_MIDI_XML
/** Event from XML ala http://www.midi.org/dtds/MIDIEvents10.dtd */
MIDIEvent(const XMLNode& event);
/** Event to XML ala http://www.midi.org/dtds/MIDIEvents10.dtd */
boost::shared_ptr<XMLNode> to_xml() const;
#endif
inline uint8_t type() const { return (this->_buf[0] & 0xF0); }
inline void set_type(uint8_t type) { this->_buf[0] = (0x0F & this->_buf[0])
| (0xF0 & type); }

View file

@ -0,0 +1,96 @@
/* This file is part of Evoral.
* Copyright (C) 2008-2016 David Robillard <http://drobilla.net>
* Copyright (C) 2000-2008 Paul Davis
*
* Evoral 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.
*
* Evoral 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 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef EVORAL_MIDI_XML_HPP
#define EVORAL_MIDI_XML_HPP
#include "evoral/MIDIEvent.hpp"
#include "pbd/xml++.h"
namespace Evoral {
namespace MIDIXML {
template<typename Time>
bool
xml_to_midi(const XMLNode& node, Evoral::MIDIEvent<Time>& ev)
{
if (node.name() == "ControlChange") {
ev.set_type(MIDI_CMD_CONTROL);
ev.set_cc_number(atoi(node.property("Control")->value().c_str()));
ev.set_cc_value(atoi(node.property("Value")->value().c_str()));
return true;
} else if (node.name() == "ProgramChange") {
ev.set_type(MIDI_CMD_PGM_CHANGE);
ev.set_pgm_number(atoi(node.property("Number")->value().c_str()));
return true;
}
return false;
}
template<typename Time>
boost::shared_ptr<XMLNode>
midi_to_xml(const Evoral::MIDIEvent<Time>& ev)
{
XMLNode* result = 0;
switch (ev.type()) {
case MIDI_CMD_CONTROL:
result = new XMLNode("ControlChange");
result->add_property("Channel", long(ev.channel()));
result->add_property("Control", long(ev.cc_number()));
result->add_property("Value", long(ev.cc_value()));
break;
case MIDI_CMD_PGM_CHANGE:
result = new XMLNode("ProgramChange");
result->add_property("Channel", long(ev.channel()));
result->add_property("Number", long(ev.pgm_number()));
break;
case MIDI_CMD_NOTE_ON:
result = new XMLNode("NoteOn");
result->add_property("Channel", long(ev.channel()));
result->add_property("Note", long(ev.note()));
result->add_property("Velocity", long(ev.velocity()));
break;
case MIDI_CMD_NOTE_OFF:
result = new XMLNode("NoteOff");
result->add_property("Channel", long(ev.channel()));
result->add_property("Note", long(ev.note()));
result->add_property("Velocity", long(ev.velocity()));
break;
case MIDI_CMD_BENDER:
result = new XMLNode("PitchBendChange");
result->add_property("Channel", long(ev.channel()));
result->add_property("Value", long(ev.pitch_bender_value()));
break;
default:
return boost::shared_ptr<XMLNode>();
}
return boost::shared_ptr<XMLNode>(result);
}
} // namespace MIDIXML
} // namespace Evoral
#endif // EVORAL_MIDI_XML_HPP

View file

@ -1,109 +0,0 @@
/* This file is part of Evoral.
* Copyright (C) 2008 David Robillard <http://drobilla.net>
* Copyright (C) 2000-2008 Paul Davis
*
* Evoral 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.
*
* Evoral 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 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string>
#include "evoral/Beats.hpp"
#include "evoral/MIDIEvent.hpp"
#ifdef EVORAL_MIDI_XML
#include "pbd/xml++.h"
#endif
using namespace std;
namespace Evoral {
#ifdef EVORAL_MIDI_XML
template<typename Time>
MIDIEvent<Time>::MIDIEvent(const XMLNode& event)
: Event<Time>()
{
string name = event.name();
if (name == "ControlChange") {
this->_buf = (uint8_t*) ::malloc(3);
this->_owns_buf = true;
set_type(MIDI_CMD_CONTROL);
set_cc_number(atoi(event.property("Control")->value().c_str()));
set_cc_value (atoi(event.property("Value")->value().c_str()));
} else if (name == "ProgramChange") {
this->_buf = (uint8_t*) ::malloc(2);
this->_owns_buf = true;
set_type(MIDI_CMD_PGM_CHANGE);
set_pgm_number(atoi(event.property("Number")->value().c_str()));
}
}
template<typename Time>
boost::shared_ptr<XMLNode>
MIDIEvent<Time>::to_xml() const
{
XMLNode *result = 0;
switch (type()) {
case MIDI_CMD_CONTROL:
result = new XMLNode("ControlChange");
result->add_property("Channel", long(channel()));
result->add_property("Control", long(cc_number()));
result->add_property("Value", long(cc_value()));
break;
case MIDI_CMD_PGM_CHANGE:
result = new XMLNode("ProgramChange");
result->add_property("Channel", long(channel()));
result->add_property("Number", long(pgm_number()));
break;
case MIDI_CMD_NOTE_ON:
result = new XMLNode("NoteOn");
result->add_property("Channel", long(channel()));
result->add_property("Note", long(note()));
result->add_property("Velocity", long(velocity()));
break;
case MIDI_CMD_NOTE_OFF:
result = new XMLNode("NoteOff");
result->add_property("Channel", long(channel()));
result->add_property("Note", long(note()));
result->add_property("Velocity", long(velocity()));
break;
case MIDI_CMD_BENDER:
result = new XMLNode("PitchBendChange");
result->add_property("Channel", long(channel()));
result->add_property("Value", long(pitch_bender_value()));
break;
default:
// The implementation is continued as needed
result = new XMLNode("NotImplemented");
break;
}
return boost::shared_ptr<XMLNode>(result);
}
#endif // EVORAL_MIDI_XML
template class MIDIEvent<Evoral::Beats>;
} // namespace Evoral

View file

@ -82,7 +82,6 @@ def build(bld):
src/ControlSet.cpp
src/Curve.cpp
src/Event.cpp
src/MIDIEvent.cpp
src/Note.cpp
src/SMF.cpp
src/Sequence.cpp
@ -110,7 +109,7 @@ def build(bld):
obj.use = 'libsmf libpbd'
obj.vnum = EVORAL_LIB_VERSION
obj.install_path = bld.env['LIBDIR']
obj.defines += [ 'PACKAGE="libevoral"', 'EVORAL_MIDI_XML=1' ]
obj.defines += [ 'PACKAGE="libevoral"' ]
if bld.env['BUILD_TESTS'] and bld.is_defined('HAVE_CPPUNIT'):
# Static library (for unit test code coverage)
@ -129,7 +128,7 @@ def build(bld):
obj.linkflags = '-lgcov'
obj.cflags = [ '-fprofile-arcs', '-ftest-coverage' ]
obj.cxxflags = [ '-fprofile-arcs', '-ftest-coverage' ]
obj.defines = ['PACKAGE="libevoral"', 'EVORAL_MIDI_XML=1' ]
obj.defines = ['PACKAGE="libevoral"']
# Unit tests
obj = bld(features = 'cxx cxxprogram')

View file

@ -37,9 +37,6 @@
*/
#define EVORAL_EVENT_ALLOC 1
/** Support serialisation of MIDI events to/from XML */
#define EVORAL_MIDI_XML 1
#include "evoral/Event.hpp"
#include "evoral/MIDIEvent.hpp"