mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 16:46:35 +01:00
De-templatify Evoral::SMF which has no concept of time other than SMF time.
git-svn-id: svn://localhost/ardour2/branches/3.0@4571 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
5a48f99f72
commit
5d519f8bb1
7 changed files with 33 additions and 51 deletions
|
|
@ -34,7 +34,7 @@ namespace ARDOUR {
|
||||||
template<typename T> class MidiRingBuffer;
|
template<typename T> class MidiRingBuffer;
|
||||||
|
|
||||||
/** Standard Midi File (Type 0) Source */
|
/** Standard Midi File (Type 0) Source */
|
||||||
class SMFSource : public MidiSource, public Evoral::SMF<double> {
|
class SMFSource : public MidiSource, public Evoral::SMF {
|
||||||
public:
|
public:
|
||||||
enum Flag {
|
enum Flag {
|
||||||
Writable = 0x1,
|
Writable = 0x1,
|
||||||
|
|
|
||||||
|
|
@ -309,7 +309,7 @@ write_audio_data_to_new_files (ImportableSource* source, Session::import_status&
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_midi_data_to_new_files (Evoral::SMF<double>* source, Session::import_status& status,
|
write_midi_data_to_new_files (Evoral::SMF* source, Session::import_status& status,
|
||||||
vector<boost::shared_ptr<Source> >& newfiles)
|
vector<boost::shared_ptr<Source> >& newfiles)
|
||||||
{
|
{
|
||||||
uint32_t buf_size = 4;
|
uint32_t buf_size = 4;
|
||||||
|
|
@ -402,8 +402,8 @@ Session::import_audiofiles (import_status& status)
|
||||||
p != status.paths.end() && !status.cancel;
|
p != status.paths.end() && !status.cancel;
|
||||||
++p, ++cnt)
|
++p, ++cnt)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<ImportableSource> source;
|
boost::shared_ptr<ImportableSource> source;
|
||||||
std::auto_ptr< Evoral::SMF<double> > smf_reader;
|
std::auto_ptr<Evoral::SMF> smf_reader;
|
||||||
const DataType type = ((*p).rfind(".mid") != string::npos) ?
|
const DataType type = ((*p).rfind(".mid") != string::npos) ?
|
||||||
DataType::MIDI : DataType::AUDIO;
|
DataType::MIDI : DataType::AUDIO;
|
||||||
|
|
||||||
|
|
@ -419,7 +419,7 @@ Session::import_audiofiles (import_status& status)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
smf_reader = std::auto_ptr< Evoral::SMF<double> >(new Evoral::SMF<double>());
|
smf_reader = std::auto_ptr<Evoral::SMF>(new Evoral::SMF());
|
||||||
smf_reader->open(*p);
|
smf_reader->open(*p);
|
||||||
channels = smf_reader->num_tracks();
|
channels = smf_reader->num_tracks();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ string SMFSource::_search_path;
|
||||||
|
|
||||||
SMFSource::SMFSource (Session& s, std::string path, Flag flags)
|
SMFSource::SMFSource (Session& s, std::string path, Flag flags)
|
||||||
: MidiSource (s, region_name_from_path(path, false))
|
: MidiSource (s, region_name_from_path(path, false))
|
||||||
, Evoral::SMF<double> ()
|
, Evoral::SMF ()
|
||||||
, _flags (Flag(flags | Writable)) // FIXME: this needs to be writable for now
|
, _flags (Flag(flags | Writable)) // FIXME: this needs to be writable for now
|
||||||
, _allow_remove_if_empty(true)
|
, _allow_remove_if_empty(true)
|
||||||
, _last_ev_time(0)
|
, _last_ev_time(0)
|
||||||
|
|
@ -144,7 +144,7 @@ SMFSource::read_unlocked (MidiRingBuffer<nframes_t>& dst, nframes_t start, nfram
|
||||||
size_t scratch_size = 0; // keep track of scratch to minimize reallocs
|
size_t scratch_size = 0; // keep track of scratch to minimize reallocs
|
||||||
|
|
||||||
// FIXME: don't seek to start and search every read (brutal!)
|
// FIXME: don't seek to start and search every read (brutal!)
|
||||||
Evoral::SMF<double>::seek_to_start();
|
Evoral::SMF::seek_to_start();
|
||||||
|
|
||||||
// FIXME: assumes tempo never changes after start
|
// FIXME: assumes tempo never changes after start
|
||||||
const double frames_per_beat = _session.tempo_map().tempo_at(_timeline_position).frames_per_beat(
|
const double frames_per_beat = _session.tempo_map().tempo_at(_timeline_position).frames_per_beat(
|
||||||
|
|
@ -153,7 +153,7 @@ SMFSource::read_unlocked (MidiRingBuffer<nframes_t>& dst, nframes_t start, nfram
|
||||||
|
|
||||||
const uint64_t start_ticks = (uint64_t)((start / frames_per_beat) * ppqn());
|
const uint64_t start_ticks = (uint64_t)((start / frames_per_beat) * ppqn());
|
||||||
|
|
||||||
while (!Evoral::SMF<double>::eof()) {
|
while (!Evoral::SMF::eof()) {
|
||||||
int ret = read_event(&ev_delta_t, &ev_size, &ev_buffer);
|
int ret = read_event(&ev_delta_t, &ev_size, &ev_buffer);
|
||||||
if (ret == -1) { // EOF
|
if (ret == -1) { // EOF
|
||||||
//cerr << "SMF - EOF\n";
|
//cerr << "SMF - EOF\n";
|
||||||
|
|
@ -250,7 +250,7 @@ SMFSource::write_unlocked (MidiRingBuffer<nframes_t>& src, nframes_t cnt)
|
||||||
set_default_controls_interpolation();
|
set_default_controls_interpolation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Evoral::SMF<double>::flush();
|
Evoral::SMF::flush();
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
||||||
const nframes_t oldlen = _length;
|
const nframes_t oldlen = _length;
|
||||||
|
|
@ -300,7 +300,7 @@ SMFSource::append_event_unlocked(EventTimeUnit unit, const Evoral::Event<double>
|
||||||
delta_time = (uint32_t)((ev.time() - last_event_time()) * ppqn());
|
delta_time = (uint32_t)((ev.time() - last_event_time()) * ppqn());
|
||||||
}
|
}
|
||||||
|
|
||||||
Evoral::SMF<double>::append_event_delta(delta_time, ev.size(), ev.buffer());
|
Evoral::SMF::append_event_delta(delta_time, ev.size(), ev.buffer());
|
||||||
_last_ev_time = ev.time();
|
_last_ev_time = ev.time();
|
||||||
|
|
||||||
_write_data_count += ev.size();
|
_write_data_count += ev.size();
|
||||||
|
|
@ -356,7 +356,7 @@ void
|
||||||
SMFSource::mark_streaming_midi_write_started (NoteMode mode, nframes_t start_frame)
|
SMFSource::mark_streaming_midi_write_started (NoteMode mode, nframes_t start_frame)
|
||||||
{
|
{
|
||||||
MidiSource::mark_streaming_midi_write_started (mode, start_frame);
|
MidiSource::mark_streaming_midi_write_started (mode, start_frame);
|
||||||
Evoral::SMF<double>::begin_write ();
|
Evoral::SMF::begin_write ();
|
||||||
_last_ev_time = 0;
|
_last_ev_time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -370,7 +370,7 @@ SMFSource::mark_streaming_write_completed ()
|
||||||
}
|
}
|
||||||
|
|
||||||
_model->set_edited(false);
|
_model->set_edited(false);
|
||||||
Evoral::SMF<double>::end_write ();
|
Evoral::SMF::end_write ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -634,7 +634,7 @@ SMFSource::load_model(bool lock, bool force_reload)
|
||||||
}
|
}
|
||||||
|
|
||||||
_model->start_write();
|
_model->start_write();
|
||||||
Evoral::SMF<double>::seek_to_start();
|
Evoral::SMF::seek_to_start();
|
||||||
|
|
||||||
uint64_t time = 0; /* in SMF ticks */
|
uint64_t time = 0; /* in SMF ticks */
|
||||||
Evoral::Event<double> ev;
|
Evoral::Event<double> ev;
|
||||||
|
|
@ -706,6 +706,6 @@ SMFSource::destroy_model()
|
||||||
void
|
void
|
||||||
SMFSource::flush_midi()
|
SMFSource::flush_midi()
|
||||||
{
|
{
|
||||||
Evoral::SMF<double>::end_write();
|
Evoral::SMF::end_write();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,15 +29,11 @@ typedef smf_track_struct smf_track_t;
|
||||||
|
|
||||||
namespace Evoral {
|
namespace Evoral {
|
||||||
|
|
||||||
template<typename Time> class Event;
|
#define THROW_FILE_ERROR throw(FileError)
|
||||||
template<typename Time> class EventRingBuffer;
|
|
||||||
|
|
||||||
#define THROW_FILE_ERROR throw(typename SMF<Time>::FileError)
|
|
||||||
|
|
||||||
/** Standard Midi File.
|
/** Standard Midi File.
|
||||||
* Currently only tempo-based time of a given PPQN is supported.
|
* Currently only tempo-based time of a given PPQN is supported.
|
||||||
*/
|
*/
|
||||||
template<typename Time>
|
|
||||||
class SMF {
|
class SMF {
|
||||||
public:
|
public:
|
||||||
class FileError : public std::exception {
|
class FileError : public std::exception {
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,7 @@ using namespace std;
|
||||||
|
|
||||||
namespace Evoral {
|
namespace Evoral {
|
||||||
|
|
||||||
template<typename Time>
|
SMF::~SMF()
|
||||||
SMF<Time>::~SMF()
|
|
||||||
{
|
{
|
||||||
if (_smf) {
|
if (_smf) {
|
||||||
smf_delete(_smf);
|
smf_delete(_smf);
|
||||||
|
|
@ -39,16 +38,14 @@ SMF<Time>::~SMF()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Time>
|
|
||||||
uint16_t
|
uint16_t
|
||||||
SMF<Time>::num_tracks() const
|
SMF::num_tracks() const
|
||||||
{
|
{
|
||||||
return _smf->number_of_tracks;
|
return _smf->number_of_tracks;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Time>
|
|
||||||
uint16_t
|
uint16_t
|
||||||
SMF<Time>::ppqn() const
|
SMF::ppqn() const
|
||||||
{
|
{
|
||||||
return _smf->ppqn;
|
return _smf->ppqn;
|
||||||
}
|
}
|
||||||
|
|
@ -56,9 +53,8 @@ SMF<Time>::ppqn() const
|
||||||
/** Seek to the specified track (1-based indexing)
|
/** Seek to the specified track (1-based indexing)
|
||||||
* \return 0 on success
|
* \return 0 on success
|
||||||
*/
|
*/
|
||||||
template<typename Time>
|
|
||||||
int
|
int
|
||||||
SMF<Time>::seek_to_track(int track)
|
SMF::seek_to_track(int track)
|
||||||
{
|
{
|
||||||
_smf_track = smf_get_track_by_number(_smf, track);
|
_smf_track = smf_get_track_by_number(_smf, track);
|
||||||
if (_smf_track != NULL) {
|
if (_smf_track != NULL) {
|
||||||
|
|
@ -75,9 +71,8 @@ SMF<Time>::seek_to_track(int track)
|
||||||
* -1 if the file can not be opened or created
|
* -1 if the file can not be opened or created
|
||||||
* -2 if the file exists but specified track does not exist
|
* -2 if the file exists but specified track does not exist
|
||||||
*/
|
*/
|
||||||
template<typename Time>
|
|
||||||
int
|
int
|
||||||
SMF<Time>::open(const std::string& path, int track) THROW_FILE_ERROR
|
SMF::open(const std::string& path, int track) THROW_FILE_ERROR
|
||||||
{
|
{
|
||||||
assert(track >= 1);
|
assert(track >= 1);
|
||||||
if (_smf) {
|
if (_smf) {
|
||||||
|
|
@ -113,9 +108,8 @@ SMF<Time>::open(const std::string& path, int track) THROW_FILE_ERROR
|
||||||
* -1 if the file can not be created
|
* -1 if the file can not be created
|
||||||
* -2 if the track can not be created
|
* -2 if the track can not be created
|
||||||
*/
|
*/
|
||||||
template<typename Time>
|
|
||||||
int
|
int
|
||||||
SMF<Time>::create(const std::string& path, int track, uint16_t ppqn) THROW_FILE_ERROR
|
SMF::create(const std::string& path, int track, uint16_t ppqn) THROW_FILE_ERROR
|
||||||
{
|
{
|
||||||
assert(track >= 1);
|
assert(track >= 1);
|
||||||
if (_smf) {
|
if (_smf) {
|
||||||
|
|
@ -149,9 +143,8 @@ SMF<Time>::create(const std::string& path, int track, uint16_t ppqn) THROW_FILE_
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Time>
|
|
||||||
void
|
void
|
||||||
SMF<Time>::close() THROW_FILE_ERROR
|
SMF::close() THROW_FILE_ERROR
|
||||||
{
|
{
|
||||||
if (_smf) {
|
if (_smf) {
|
||||||
if (smf_save(_smf, _path.c_str()) != 0) {
|
if (smf_save(_smf, _path.c_str()) != 0) {
|
||||||
|
|
@ -163,9 +156,8 @@ SMF<Time>::close() THROW_FILE_ERROR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Time>
|
|
||||||
void
|
void
|
||||||
SMF<Time>::seek_to_start() const
|
SMF::seek_to_start() const
|
||||||
{
|
{
|
||||||
_smf_track->next_event_number = 1;
|
_smf_track->next_event_number = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -184,9 +176,8 @@ SMF<Time>::seek_to_start() const
|
||||||
* \return event length (including status byte) on success, 0 if event was
|
* \return event length (including status byte) on success, 0 if event was
|
||||||
* skipped (e.g. a meta event), or -1 on EOF (or end of track).
|
* skipped (e.g. a meta event), or -1 on EOF (or end of track).
|
||||||
*/
|
*/
|
||||||
template<typename Time>
|
|
||||||
int
|
int
|
||||||
SMF<Time>::read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const
|
SMF::read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const
|
||||||
{
|
{
|
||||||
smf_event_t* event;
|
smf_event_t* event;
|
||||||
|
|
||||||
|
|
@ -221,9 +212,8 @@ SMF<Time>::read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Time>
|
|
||||||
void
|
void
|
||||||
SMF<Time>::append_event_delta(uint32_t delta_t, uint32_t size, const uint8_t* buf)
|
SMF::append_event_delta(uint32_t delta_t, uint32_t size, const uint8_t* buf)
|
||||||
{
|
{
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -244,9 +234,8 @@ SMF<Time>::append_event_delta(uint32_t delta_t, uint32_t size, const uint8_t* bu
|
||||||
_empty = false;
|
_empty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Time>
|
|
||||||
void
|
void
|
||||||
SMF<Time>::begin_write()
|
SMF::begin_write()
|
||||||
{
|
{
|
||||||
assert(_smf_track);
|
assert(_smf_track);
|
||||||
smf_track_delete(_smf_track);
|
smf_track_delete(_smf_track);
|
||||||
|
|
@ -258,14 +247,12 @@ SMF<Time>::begin_write()
|
||||||
assert(_smf->number_of_tracks == 1);
|
assert(_smf->number_of_tracks == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Time>
|
|
||||||
void
|
void
|
||||||
SMF<Time>::end_write() THROW_FILE_ERROR
|
SMF::end_write() THROW_FILE_ERROR
|
||||||
{
|
{
|
||||||
if (smf_save(_smf, _path.c_str()) != 0)
|
if (smf_save(_smf, _path.c_str()) != 0)
|
||||||
throw FileError();
|
throw FileError();
|
||||||
}
|
}
|
||||||
|
|
||||||
template class SMF<double>;
|
|
||||||
|
|
||||||
} // namespace Evoral
|
} // namespace Evoral
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ CPPUNIT_TEST_SUITE_REGISTRATION( SMFTest );
|
||||||
void
|
void
|
||||||
SMFTest::createNewFileTest ()
|
SMFTest::createNewFileTest ()
|
||||||
{
|
{
|
||||||
TestSMF<Time> smf;
|
TestSMF smf;
|
||||||
smf.create("NewFile.mid");
|
smf.create("NewFile.mid");
|
||||||
smf.close();
|
smf.close();
|
||||||
CPPUNIT_ASSERT(access("NewFile.mid", R_OK) == 0);
|
CPPUNIT_ASSERT(access("NewFile.mid", R_OK) == 0);
|
||||||
|
|
@ -17,7 +17,7 @@ SMFTest::createNewFileTest ()
|
||||||
void
|
void
|
||||||
SMFTest::takeFiveTest ()
|
SMFTest::takeFiveTest ()
|
||||||
{
|
{
|
||||||
TestSMF<Time> smf;
|
TestSMF smf;
|
||||||
smf.open("./test/testdata/TakeFive.mid");
|
smf.open("./test/testdata/TakeFive.mid");
|
||||||
CPPUNIT_ASSERT(!smf.is_empty());
|
CPPUNIT_ASSERT(!smf.is_empty());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,22 +25,21 @@
|
||||||
|
|
||||||
using namespace Evoral;
|
using namespace Evoral;
|
||||||
|
|
||||||
template<typename Time>
|
class TestSMF : public SMF {
|
||||||
class TestSMF : public SMF<Time> {
|
|
||||||
public:
|
public:
|
||||||
std::string path() const { return _path; }
|
std::string path() const { return _path; }
|
||||||
|
|
||||||
int open(const std::string& path) THROW_FILE_ERROR {
|
int open(const std::string& path) THROW_FILE_ERROR {
|
||||||
_path = path;
|
_path = path;
|
||||||
return SMF<Time>::open(path);
|
return SMF::open(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void close() THROW_FILE_ERROR {
|
void close() THROW_FILE_ERROR {
|
||||||
return SMF<Time>::close();
|
return SMF::close();
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const {
|
int read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const {
|
||||||
return SMF<Time>::read_event(delta_t, size, buf);
|
return SMF::read_event(delta_t, size, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue