add midi-bypass to re-configurable-i/o instruments
[ardour.git] / libs / evoral / src / SMF.cpp
index 42c5369b7662fdb2001bbf27f8136ae08599b76e..45109b50e57e01a7016ca1e630dc8438afe14fe7 100644 (file)
 #include <cmath>
 #include <iostream>
 #include <stdint.h>
+
+#include <glib/gstdio.h>
+
 #include "libsmf/smf.h"
+
 #include "evoral/Event.hpp"
 #include "evoral/SMF.hpp"
 #include "evoral/midi_util.h"
@@ -78,7 +82,7 @@ SMF::seek_to_track(int track)
 bool
 SMF::test(const std::string& path)
 {
-       FILE* f = fopen(path.c_str(), "r");
+       FILE* f = g_fopen(path.c_str(), "r");
        if (f == 0) {
                return false;
        }
@@ -108,9 +112,7 @@ SMF::open(const std::string& path, int track) THROW_FILE_ERROR
                smf_delete(_smf);
        }
 
-       _file_path = path;
-
-       FILE* f = fopen(_file_path.c_str(), "r");
+       FILE* f = g_fopen(path.c_str(), "r");
        if (f == 0) {
                return -1;
        } else if ((_smf = smf_load(f)) == 0) {
@@ -151,8 +153,6 @@ SMF::create(const std::string& path, int track, uint16_t ppqn) THROW_FILE_ERROR
                smf_delete(_smf);
        }
 
-       _file_path = path;
-
        _smf = smf_new();
 
        if (_smf == NULL) {
@@ -180,7 +180,7 @@ SMF::create(const std::string& path, int track, uint16_t ppqn) THROW_FILE_ERROR
        {
                /* put a stub file on disk */
 
-               FILE* f = fopen (_file_path.c_str(), "w+");
+               FILE* f = g_fopen (path.c_str(), "w+");
                if (f == 0) {
                        return -1;
                }
@@ -287,6 +287,11 @@ SMF::read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf, event_id_t* no
                }
                memcpy(*buf, event->midi_buffer, size_t(event_size));
                *size = event_size;
+               if (((*buf)[0] & 0xF0) == 0x90 && (*buf)[2] == 0) {
+                       /* normalize note on with velocity 0 to proper note off */
+                       (*buf)[0] = 0x80 | ((*buf)[0] & 0x0F);  /* note off */
+                       (*buf)[2] = 0x40;  /* default velocity */
+               }
 
                if (!midi_event_is_valid(*buf, *size)) {
                        cerr << "WARNING: SMF ignoring illegal MIDI event" << endl;
@@ -396,17 +401,22 @@ SMF::begin_write()
 }
 
 void
-SMF::end_write() THROW_FILE_ERROR
+SMF::end_write(string const & path) THROW_FILE_ERROR
 {
        Glib::Threads::Mutex::Lock lm (_smf_lock);
-       FILE* f = fopen (_file_path.c_str(), "w+");
+
+       if (!_smf) {
+               return;
+       }
+
+       FILE* f = g_fopen (path.c_str(), "w+");
        if (f == 0) {
-               throw FileError (_file_path);
+               throw FileError (path);
        }
 
        if (smf_save(_smf, f) != 0) {
                fclose(f);
-               throw FileError (_file_path);
+               throw FileError (path);
        }
 
        fclose(f);
@@ -420,10 +430,4 @@ SMF::round_to_file_precision (double val) const
        return round (val * div) / div;
 }
 
-void
-SMF::set_path (const std::string& p)
-{
-       _file_path = p;
-}
-
 } // namespace Evoral