Patch from agorka to add some includes required for building with the GCC shipped...
[ardour.git] / libs / evoral / src / SMF.cpp
index 7e5e5935ce52c4eb581ac69cef909117a7f7d17b..372c37c0bb79b4ba5a493d8dd830dec5b6fc001f 100644 (file)
 #include <cassert>
 #include <iostream>
 #include <stdint.h>
+#include "libsmf/smf.h"
 #include "evoral/Event.hpp"
 #include "evoral/SMF.hpp"
-#include "libsmf/smf.h"
+#include "evoral/midi_util.h"
 
 using namespace std;
 
 namespace Evoral {
 
-template<typename Time>
-SMF<Time>::~SMF()
+SMF::~SMF()
 {      
        if (_smf) {
                smf_delete(_smf);
@@ -39,16 +39,14 @@ SMF<Time>::~SMF()
        } 
 }
 
-template<typename Time>
 uint16_t
-SMF<Time>::num_tracks() const
+SMF::num_tracks() const
 {
        return _smf->number_of_tracks;
 }
 
-template<typename Time>
 uint16_t
-SMF<Time>::ppqn() const
+SMF::ppqn() const
 {
        return _smf->ppqn;
 }
@@ -56,9 +54,8 @@ SMF<Time>::ppqn() const
 /** Seek to the specified track (1-based indexing)
  * \return 0 on success
  */
-template<typename Time>
 int
-SMF<Time>::seek_to_track(int track)
+SMF::seek_to_track(int track)
 {
        _smf_track = smf_get_track_by_number(_smf, track);
        if (_smf_track != NULL) {
@@ -75,17 +72,16 @@ SMF<Time>::seek_to_track(int track)
  *         -1 if the file can not be opened or created
  *         -2 if the file exists but specified track does not exist
  */
-template<typename Time>
 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);
        if (_smf) { 
                smf_delete(_smf);
        }
        
-       _path = path;
-       _smf = smf_load(_path.c_str());
+       _file_path = path;
+       _smf = smf_load(_file_path.c_str());
        if (_smf == NULL) {
                return -1;
        }
@@ -94,7 +90,7 @@ SMF<Time>::open(const std::string& path, int track) THROW_FILE_ERROR
        if (!_smf_track)
                return -2;
 
-       cerr << "Track " << track << " # events: " << _smf_track->number_of_events << endl;
+       //cerr << "Track " << track << " # events: " << _smf_track->number_of_events << endl;
        if (_smf_track->number_of_events == 0) {
                _smf_track->next_event_number = 0;
                _empty = true;
@@ -113,16 +109,15 @@ SMF<Time>::open(const std::string& path, int track) THROW_FILE_ERROR
  *         -1 if the file can not be created
  *         -2 if the track can not be created
  */
-template<typename Time>
 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);
        if (_smf) { 
                smf_delete(_smf);
        }
        
-       _path = path;
+       _file_path = path;
 
        _smf = smf_new();
        if (smf_set_ppqn(_smf, ppqn) != 0) {
@@ -149,12 +144,11 @@ SMF<Time>::create(const std::string& path, int track, uint16_t ppqn) THROW_FILE_
        return 0;
 }
 
-template<typename Time>
 void
-SMF<Time>::close() THROW_FILE_ERROR
+SMF::close() THROW_FILE_ERROR
 {
        if (_smf) {
-               if (smf_save(_smf, _path.c_str()) != 0) {
+               if (smf_save(_smf, _file_path.c_str()) != 0) {
                        throw FileError();
                }
                smf_delete(_smf);
@@ -163,9 +157,8 @@ SMF<Time>::close() THROW_FILE_ERROR
        }
 }
 
-template<typename Time>
 void
-SMF<Time>::seek_to_start() const
+SMF::seek_to_start() const
 {
        _smf_track->next_event_number = 1;
 }
@@ -184,9 +177,8 @@ SMF<Time>::seek_to_start() const
  * \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).
  */
-template<typename Time>
 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;
        
@@ -210,8 +202,10 @@ SMF<Time>::read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const
        memcpy(*buf, event->midi_buffer, size_t(event_size));
        *size = event_size;
        
+               assert(midi_event_is_valid(*buf, *size));
+
                /*printf("SMF::read_event:\n");
-               for (size_t i=0; i < *size; ++i) {
+               for (size_t i = 0; i < *size; ++i) {
                        printf("%X ", (*buf)[i]);
                } printf("\n");*/
        
@@ -221,35 +215,35 @@ SMF<Time>::read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const
     }
 }
 
-template<typename Time>
 void
-SMF<Time>::append_event_delta(uint32_t delta_t, const Event<Time>& ev)
+SMF::append_event_delta(uint32_t delta_t, uint32_t size, const uint8_t* buf)
 {
-       assert(ev.size() > 0);
+       if (size == 0) {
+               return;
+       }
        
        /*printf("SMF::append_event_delta:\n");
-       for (size_t i=0; i < ev.size(); ++i) {
-               printf("%X ", ev.buffer()[i]);
+       for (size_t i = 0; i < size; ++i) {
+               printf("%X ", buf[i]);
        } printf("\n");*/
 
+       if (!midi_event_is_valid(buf, size)) {
+               cerr << "WARNING: SMF ignoring illegal MIDI event" << endl;
+               return;
+       }
+
        smf_event_t* event;
 
-       event = smf_event_new_from_pointer((void *) ev.buffer(), int(ev.size()));
+       event = smf_event_new_from_pointer(buf, size);
        assert(event != NULL);
        
-       memcpy(event->midi_buffer, ev.buffer(), ev.size());
-       
        assert(_smf_track);
-       smf_track_add_event_delta_pulses(_smf_track, event, int(delta_t));
-       
-       if (ev.size() > 0) {
-               _empty = false;
-       }
+       smf_track_add_event_delta_pulses(_smf_track, event, delta_t);
+       _empty = false;
 }
 
-template<typename Time>
 void
-SMF<Time>::begin_write()
+SMF::begin_write()
 {
        assert(_smf_track);
        smf_track_delete(_smf_track);
@@ -261,14 +255,12 @@ SMF<Time>::begin_write()
        assert(_smf->number_of_tracks == 1);
 }
 
-template<typename Time>
 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, _file_path.c_str()) != 0)
                throw FileError();
 }
 
-template class SMF<double>;
 
 } // namespace Evoral