diff options
Diffstat (limited to 'libs/evoral/src')
-rw-r--r-- | libs/evoral/src/Control.cpp | 8 | ||||
-rw-r--r-- | libs/evoral/src/ControlList.cpp | 176 | ||||
-rw-r--r-- | libs/evoral/src/ControlSet.cpp | 16 | ||||
-rw-r--r-- | libs/evoral/src/Curve.cpp | 90 | ||||
-rw-r--r-- | libs/evoral/src/Event.cpp | 6 | ||||
-rw-r--r-- | libs/evoral/src/MIDIEvent.cpp | 22 | ||||
-rw-r--r-- | libs/evoral/src/Note.cpp | 16 | ||||
-rw-r--r-- | libs/evoral/src/OldSMF.cpp | 28 | ||||
-rw-r--r-- | libs/evoral/src/SMF.cpp | 46 | ||||
-rw-r--r-- | libs/evoral/src/SMFReader.cpp | 22 | ||||
-rw-r--r-- | libs/evoral/src/Sequence.cpp | 46 | ||||
-rw-r--r-- | libs/evoral/src/midi_util.cpp | 8 |
12 files changed, 242 insertions, 242 deletions
diff --git a/libs/evoral/src/Control.cpp b/libs/evoral/src/Control.cpp index 079bd2929e..6824dc7f5a 100644 --- a/libs/evoral/src/Control.cpp +++ b/libs/evoral/src/Control.cpp @@ -1,16 +1,16 @@ /* This file is part of Evoral. * Copyright (C) 2008 Dave 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 @@ -48,7 +48,7 @@ void Control::set_float(float value, bool to_list, FrameTime frame) { _user_value = value; - + if (to_list) _list->add(frame, value); } diff --git a/libs/evoral/src/ControlList.cpp b/libs/evoral/src/ControlList.cpp index 82cd87ed1e..bb348625e6 100644 --- a/libs/evoral/src/ControlList.cpp +++ b/libs/evoral/src/ControlList.cpp @@ -1,16 +1,16 @@ /* This file is part of Evoral. * Copyright (C) 2008 Dave 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 @@ -38,7 +38,7 @@ ControlList::ControlList (const Parameter& id) : _parameter(id) , _interpolation(Linear) , _curve(0) -{ +{ _frozen = 0; _changed_when_thawed = false; _min_yval = id.min(); @@ -72,7 +72,7 @@ ControlList::ControlList (const ControlList& other) for (const_iterator i = other._events.begin(); i != other._events.end(); ++i) { _events.push_back (new ControlEvent (**i)); } - + mark_dirty (); } @@ -101,7 +101,7 @@ ControlList::ControlList (const ControlList& other, double start, double end) _events.push_back (new ControlEvent ((*i)->when, (*i)->value)); } } - + mark_dirty (); } @@ -130,18 +130,18 @@ ControlList& ControlList::operator= (const ControlList& other) { if (this != &other) { - + _events.clear (); - + for (const_iterator i = other._events.begin(); i != other._events.end(); ++i) { _events.push_back (new ControlEvent (**i)); } - + _min_yval = other._min_yval; _max_yval = other._max_yval; _max_xval = other._max_xval; _default_value = other._default_value; - + mark_dirty (); maybe_signal_changed (); } @@ -166,7 +166,7 @@ void ControlList::maybe_signal_changed () { mark_dirty (); - + if (_frozen) _changed_when_thawed = true; } @@ -265,16 +265,16 @@ ControlList::rt_add (double when, double value) where = after; } - + iterator previous = _rt_insertion_point; --previous; - + if (_rt_insertion_point != _events.begin() && (*_rt_insertion_point)->value == value && (*previous)->value == value) { (*_rt_insertion_point)->when = when; done = true; - + } - + } else { where = lower_bound (_events.begin(), _events.end(), &cp, time_comparator); @@ -290,7 +290,7 @@ ControlList::rt_add (double when, double value) if (!done) { _rt_insertion_point = _events.insert (where, new ControlEvent (when, value)); } - + _new_value = false; mark_dirty (); } @@ -325,7 +325,7 @@ ControlList::add (double when, double value) (*insertion_point)->value = value; insert = false; break; - } + } if ((*insertion_point)->when >= when) { break; @@ -333,11 +333,11 @@ ControlList::add (double when, double value) } if (insert) { - + _events.insert (insertion_point, new ControlEvent (when, value)); reposition_for_rt_add (0); - } + } mark_dirty (); } @@ -367,7 +367,7 @@ ControlList::erase (iterator start, iterator end) mark_dirty (); } maybe_signal_changed (); -} +} void ControlList::reset_range (double start, double endt) @@ -379,7 +379,7 @@ ControlList::reset_range (double start, double endt) ControlEvent cp (start, 0.0f); iterator s; iterator e; - + if ((s = lower_bound (_events.begin(), _events.end(), &cp, time_comparator)) != _events.end()) { cp.when = endt; @@ -388,7 +388,7 @@ ControlList::reset_range (double start, double endt) for (iterator i = s; i != e; ++i) { (*i)->value = _default_value; } - + reset = true; mark_dirty (); @@ -413,7 +413,7 @@ ControlList::erase_range (double start, double endt) reposition_for_rt_add (0); mark_dirty (); } - + } if (erased) { @@ -448,7 +448,7 @@ ControlList::slide (iterator before, double distance) if (before == _events.end()) { return; } - + while (before != _events.end()) { (*before)->when += distance; ++before; @@ -500,7 +500,7 @@ ControlList::control_points_adjacent (double xval) ret.second = _events.end(); for (i = lower_bound (_events.begin(), _events.end(), &cp, time_comparator); i != _events.end(); ++i) { - + if (ret.first == _events.end()) { if ((*i)->when >= xval) { if (i != _events.begin()) { @@ -510,8 +510,8 @@ ControlList::control_points_adjacent (double xval) return ret; } } - } - + } + if ((*i)->when > xval) { ret.second = i; break; @@ -552,7 +552,7 @@ ControlList::thaw () } } -void +void ControlList::mark_dirty () const { _lookup_cache.left = -1; @@ -579,7 +579,7 @@ ControlList::truncate_end (double last_coordinate) } if (last_coordinate > _events.back()->when) { - + /* extending end: */ @@ -607,7 +607,7 @@ ControlList::truncate_end (double last_coordinate) iterator penultimate = _events.end(); --penultimate; /* points at last point */ --penultimate; /* points at the penultimate point */ - + if (_events.back()->value == (*penultimate)->value) { _events.back()->when = last_coordinate; } else { @@ -622,13 +622,13 @@ ControlList::truncate_end (double last_coordinate) last_val = unlocked_eval (last_coordinate); last_val = max ((double) _min_yval, last_val); last_val = min ((double) _max_yval, last_val); - + i = _events.rbegin(); - + /* make i point to the last control point */ - + ++i; - + /* now go backwards, removing control points that are beyond the new last coordinate. */ @@ -636,23 +636,23 @@ ControlList::truncate_end (double last_coordinate) // FIXME: SLOW! (size() == O(n)) uint32_t sz = _events.size(); - + while (i != _events.rend() && sz > 2) { ControlList::reverse_iterator tmp; - + tmp = i; ++tmp; - + if ((*i)->when < last_coordinate) { break; } - + _events.erase (i.base()); --sz; i = tmp; } - + _events.back()->when = last_coordinate; _events.back()->value = last_val; } @@ -674,14 +674,14 @@ ControlList::truncate_start (double overall_length) double first_legal_coordinate; assert(!_events.empty()); - + if (overall_length == _events.back()->when) { /* no change in overall length */ return; } - + if (overall_length > _events.back()->when) { - + /* growing at front: duplicate first point. shift all others */ double shift = overall_length - _events.back()->when; @@ -705,7 +705,7 @@ ControlList::truncate_start (double overall_length) iterator second = _events.begin(); ++second; /* points at the second point */ - + if (_events.front()->value == (*second)->value) { /* first segment is flat, just move start point back to zero */ _events.front()->when = 0; @@ -718,7 +718,7 @@ ControlList::truncate_start (double overall_length) } else { /* shrinking at front */ - + first_legal_coordinate = _events.back()->when - overall_length; first_legal_value = unlocked_eval (first_legal_coordinate); first_legal_value = max (_min_yval, first_legal_value); @@ -727,35 +727,35 @@ ControlList::truncate_start (double overall_length) /* remove all events earlier than the new "front" */ i = _events.begin(); - + while (i != _events.end() && !_events.empty()) { ControlList::iterator tmp; - + tmp = i; ++tmp; - + if ((*i)->when > first_legal_coordinate) { break; } - + _events.erase (i); - + i = tmp; } - + /* shift all remaining points left to keep their same relative position */ - + for (i = _events.begin(); i != _events.end(); ++i) { (*i)->when -= first_legal_coordinate; } /* add a new point for the interpolated new value */ - + _events.push_front (new ControlEvent (0, first_legal_value)); - } + } reposition_for_rt_add (0); @@ -787,7 +787,7 @@ ControlList::unlocked_eval (double x) const case 1: return _events.front()->value; - + case 2: if (x >= _events.back()->when) { return _events.back()->value; @@ -799,7 +799,7 @@ ControlList::unlocked_eval (double x) const lval = _events.front()->value; upos = _events.back()->when; uval = _events.back()->value; - + if (_interpolation == Discrete) { return lval; } @@ -828,7 +828,7 @@ ControlList::multipoint_eval (double x) const double upos, lpos; double uval, lval; double fraction; - + /* "Stepped" lookup (no interpolation) */ /* FIXME: no cache. significant? */ if (_interpolation == Discrete) { @@ -847,15 +847,15 @@ ControlList::multipoint_eval (double x) const /* Only do the range lookup if x is in a different range than last time * this was called (or if the lookup cache has been marked "dirty" (left<0) */ if ((_lookup_cache.left < 0) || - ((_lookup_cache.left > x) || - (_lookup_cache.range.first == _events.end()) || + ((_lookup_cache.left > x) || + (_lookup_cache.range.first == _events.end()) || ((*_lookup_cache.range.second)->when < x))) { const ControlEvent cp (x, 0); - + _lookup_cache.range = equal_range (_events.begin(), _events.end(), &cp, time_comparator); } - + pair<const_iterator,const_iterator> range = _lookup_cache.range; if (range.first == range.second) { @@ -873,7 +873,7 @@ ControlList::multipoint_eval (double x) const // return _default_value; return _events.front()->value; } - + if (range.second == _events.end()) { /* we're after the last point */ return _events.back()->value; @@ -881,7 +881,7 @@ ControlList::multipoint_eval (double x) const upos = (*range.second)->when; uval = (*range.second)->value; - + /* linear interpolation betweeen the two points on either side of x */ @@ -889,7 +889,7 @@ ControlList::multipoint_eval (double x) const fraction = (double) (x - lpos) / (double) (upos - lpos); return lval + (fraction * (uval - lval)); - } + } /* x is a control point in the data */ _lookup_cache.left = -1; @@ -936,7 +936,7 @@ ControlList::rt_safe_earliest_event(double start, double end, double& x, double& } return rt_safe_earliest_event_unlocked(start, end, x, y, inclusive); -} +} /** Get the earliest event between \a start and \a end, using the current interpolation style. @@ -953,7 +953,7 @@ ControlList::rt_safe_earliest_event_unlocked(double start, double end, double& x return rt_safe_earliest_event_discrete_unlocked(start, end, x, y, inclusive); else return rt_safe_earliest_event_linear_unlocked(start, end, x, y, inclusive); -} +} /** Get the earliest event between \a start and \a end (Discrete (lack of) interpolation) @@ -993,7 +993,7 @@ ControlList::rt_safe_earliest_event_discrete_unlocked (double start, double end, } else { return false; } - + /* No points in range */ } else { return false; @@ -1021,7 +1021,7 @@ ControlList::rt_safe_earliest_event_linear_unlocked (double start, double end, d // Hack to avoid infinitely repeating the same event build_search_cache_if_necessary(start, end); - + pair<const_iterator,const_iterator> range = _search_cache.range; if (range.first != _events.end()) { @@ -1046,7 +1046,7 @@ ControlList::rt_safe_earliest_event_linear_unlocked (double start, double end, d first = *prev; next = *range.first; } - + if (inclusive && first->when == start) { x = first->when; y = first->value; @@ -1057,7 +1057,7 @@ ControlList::rt_safe_earliest_event_linear_unlocked (double start, double end, d assert(x >= start); return true; } - + if (fabs(first->value - next->value) <= 1) { if (next->when <= end && (next->when > start)) { x = next->when; @@ -1085,9 +1085,9 @@ ControlList::rt_safe_earliest_event_linear_unlocked (double start, double end, d y = floor(y); x = first->when + (y - first->value) / (double)slope; - + while ((inclusive && x < start) || (x <= start && y != next->value)) { - + if (first->value < next->value) // ramping up y += 1.0; else // ramping down @@ -1103,7 +1103,7 @@ ControlList::rt_safe_earliest_event_linear_unlocked (double start, double end, d assert( (y >= first->value && y <= next->value) || (y <= first->value && y >= next->value) ); - + const bool past_start = (inclusive ? x >= start : x > start); if (past_start && x < end) { /* Move left of cache to this point @@ -1114,7 +1114,7 @@ ControlList::rt_safe_earliest_event_linear_unlocked (double start, double end, d } else { return false; } - + /* No points in the future, so no steps (towards them) in the future */ } else { return false; @@ -1131,13 +1131,13 @@ ControlList::cut (iterator start, iterator end) for (iterator x = start; x != end; ) { iterator tmp; - + tmp = x; ++tmp; - + nal->_events.push_back (new ControlEvent (**x)); _events.erase (x); - + reposition_for_rt_add (0); x = tmp; @@ -1158,7 +1158,7 @@ ControlList::cut_copy_clear (double start, double end, int op) iterator s, e; ControlEvent cp (start, 0.0); bool changed = false; - + { Glib::Mutex::Lock lm (_lock); @@ -1175,16 +1175,16 @@ ControlList::cut_copy_clear (double start, double end, int op) for (iterator x = s; x != e; ) { iterator tmp; - + tmp = x; ++tmp; changed = true; - + /* adjust new points to be relative to start, which has been set to zero. */ - + if (op != 2) { nal->_events.push_back (new ControlEvent ((*x)->when - start, (*x)->value)); } @@ -1192,7 +1192,7 @@ ControlList::cut_copy_clear (double start, double end, int op) if (op != 1) { _events.erase (x); } - + x = tmp; } @@ -1220,15 +1220,15 @@ ControlList::copy (iterator start, iterator end) { Glib::Mutex::Lock lm (_lock); - + for (iterator x = start; x != end; ) { iterator tmp; - + tmp = x; ++tmp; - + nal->_events.push_back (new ControlEvent (**x)); - + x = tmp; } } @@ -1274,9 +1274,9 @@ ControlList::paste (ControlList& alist, double pos, float /*times*/) _events.insert (where, new ControlEvent( (*i)->when+pos,( *i)->value)); end = (*i)->when + pos; } - - - /* move all points after the insertion along the timeline by + + + /* move all points after the insertion along the timeline by the correct amount. */ diff --git a/libs/evoral/src/ControlSet.cpp b/libs/evoral/src/ControlSet.cpp index 4a583b5a55..0ccefdc284 100644 --- a/libs/evoral/src/ControlSet.cpp +++ b/libs/evoral/src/ControlSet.cpp @@ -1,16 +1,16 @@ /* This file is part of Evoral. * Copyright (C) 2008 Dave 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 @@ -72,22 +72,22 @@ ControlSet::control (const Parameter& parameter, bool create_if_missing) bool ControlSet::find_next_event (FrameTime now, FrameTime end, ControlEvent& next_event) const { - Controls::const_iterator li; + Controls::const_iterator li; next_event.when = std::numeric_limits<FrameTime>::max(); - + for (li = _controls.begin(); li != _controls.end(); ++li) { ControlList::const_iterator i; boost::shared_ptr<const ControlList> alist (li->second->list()); ControlEvent cp (now, 0.0f); - + for (i = lower_bound (alist->begin(), alist->end(), &cp, ControlList::time_comparator); i != alist->end() && (*i)->when < end; ++i) { if ((*i)->when > now) { - break; + break; } } - + if (i != alist->end() && (*i)->when < end) { if ((*i)->when < next_event.when) { next_event.when = (*i)->when; diff --git a/libs/evoral/src/Curve.cpp b/libs/evoral/src/Curve.cpp index 2ae79a3917..92633688ac 100644 --- a/libs/evoral/src/Curve.cpp +++ b/libs/evoral/src/Curve.cpp @@ -1,16 +1,16 @@ /* This file is part of Evoral. * Copyright (C) 2008 Dave 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 @@ -48,9 +48,9 @@ Curve::solve () if (!_dirty) { return; } - + if ((npoints = _list.events().size()) > 2) { - + /* Compute coefficients needed to efficiently compute a constrained spline curve. See "Constrained Cubic Spline Interpolation" by CJC Kruger (www.korf.co.uk/spline.pdf) for more details. @@ -80,7 +80,7 @@ Curve::solve () double fplast = 0; for (i = 0, xx = _list.events().begin(); xx != _list.events().end(); ++xx, ++i) { - + double xdelta; /* gcc is wrong about possible uninitialized use */ double xdelta2; /* ditto */ double ydelta; /* ditto */ @@ -94,11 +94,11 @@ Curve::solve () } /* compute (constrained) first derivatives */ - + if (i == 0) { /* first segment */ - + fplast = ((3 * (y[1] - y[0]) / (2 * (x[1] - x[0]))) - (fpone * 0.5)); /* we don't store coefficients for i = 0 */ @@ -110,7 +110,7 @@ Curve::solve () /* last segment */ fpi = ((3 * ydelta) / (2 * xdelta)) - (fplast * 0.5); - + } else { /* all other segments */ @@ -124,32 +124,32 @@ Curve::solve () } else { fpi = 2 / (slope_before + slope_after); } - + } /* compute second derivative for either side of control point `i' */ - + fppL = (((-2 * (fpi + (2 * fplast))) / (xdelta))) + ((6 * ydelta) / xdelta2); - + fppR = (2 * ((2 * fpi) + fplast) / xdelta) - ((6 * ydelta) / xdelta2); - + /* compute polynomial coefficients */ double b, c, d; - d = (fppR - fppL) / (6 * xdelta); + d = (fppR - fppL) / (6 * xdelta); c = ((x[i] * fppL) - (x[i-1] * fppR))/(2 * xdelta); - + double xim12, xim13; double xi2, xi3; - + xim12 = x[i-1] * x[i-1]; /* "x[i-1] squared" */ xim13 = xim12 * x[i-1]; /* "x[i-1] cubed" */ xi2 = x[i] * x[i]; /* "x[i] squared" */ xi3 = xi2 * x[i]; /* "x[i] cubed" */ - + b = (ydelta - (c * (xi2 - xim12)) - (d * (xi3 - xim13))) / xdelta; /* store */ @@ -162,7 +162,7 @@ Curve::solve () fplast = fpi; } - + } _dirty = false; @@ -220,13 +220,13 @@ Curve::_get_vector (double x0, double x1, float *vec, int32_t veclen) if (x0 < min_x) { - /* fill some beginning section of the array with the - initial (used to be default) value + /* fill some beginning section of the array with the + initial (used to be default) value */ double frac = (min_x - x0) / (x1 - x0); int32_t subveclen = (int32_t) floor (veclen * frac); - + subveclen = min (subveclen, veclen); for (i = 0; i < subveclen; ++i) { @@ -246,7 +246,7 @@ Curve::_get_vector (double x0, double x1, float *vec, int32_t veclen) int32_t subveclen = (int32_t) floor (original_veclen * frac); float val; - + subveclen = min (subveclen, veclen); val = _list.events().back()->value; @@ -265,42 +265,42 @@ Curve::_get_vector (double x0, double x1, float *vec, int32_t veclen) } if (npoints == 1 ) { - + for (i = 0; i < veclen; ++i) { vec[i] = _list.events().front()->value; } return; } - - + + if (npoints == 2) { - + /* linear interpolation between 2 points */ - + /* XXX I'm not sure that this is the right thing to do here. but its not a common case for the envisaged uses. */ - + if (veclen > 1) { dx = (hx - lx) / (veclen - 1) ; } else { dx = 0; // not used } - - double slope = (_list.events().back()->value - _list.events().front()->value)/ + + double slope = (_list.events().back()->value - _list.events().front()->value)/ (_list.events().back()->when - _list.events().front()->when); double yfrac = dx*slope; - + vec[0] = _list.events().front()->value + slope * (lx - _list.events().front()->when); - + for (i = 1; i < veclen; ++i) { vec[i] = vec[i-1] + yfrac; } - + return; } - + if (_dirty) { solve (); } @@ -331,16 +331,16 @@ Curve::unlocked_eval (double x) double Curve::multipoint_eval (double x) -{ +{ pair<ControlList::EventList::const_iterator,ControlList::EventList::const_iterator> range; ControlList::LookupCache& lookup_cache = _list.lookup_cache(); if ((lookup_cache.left < 0) || - ((lookup_cache.left > x) || - (lookup_cache.range.first == _list.events().end()) || + ((lookup_cache.left > x) || + (lookup_cache.range.first == _list.events().end()) || ((*lookup_cache.range.second)->when < x))) { - + ControlEvent cp (x, 0.0); lookup_cache.range = equal_range (_list.events().begin(), _list.events().end(), &cp, ControlList::time_comparator); @@ -348,21 +348,21 @@ Curve::multipoint_eval (double x) range = lookup_cache.range; - /* EITHER - + /* EITHER + a) x is an existing control point, so first == existing point, second == next point OR b) x is between control points, so range is empty (first == second, points to where to insert x) - + */ if (range.first == range.second) { /* x does not exist within the list as a control point */ - + lookup_cache.left = x; if (range.first == _list.events().begin()) { @@ -370,7 +370,7 @@ Curve::multipoint_eval (double x) // return default_value; _list.events().front()->value; } - + if (range.second == _list.events().end()) { /* we're after the last point */ return _list.events().back()->value; @@ -380,7 +380,7 @@ Curve::multipoint_eval (double x) ControlEvent* ev = *range.second; return ev->coeff[0] + (ev->coeff[1] * x) + (ev->coeff[2] * x2) + (ev->coeff[3] * x2 * x); - } + } /* x is a control point in the data */ /* invalidate the cached range because its not usable */ @@ -392,7 +392,7 @@ Curve::multipoint_eval (double x) extern "C" { -void +void curve_get_vector_from_c (void *arg, double x0, double x1, float* vec, int32_t vecsize) { static_cast<Evoral::Curve*>(arg)->get_vector (x0, x1, vec, vecsize); diff --git a/libs/evoral/src/Event.cpp b/libs/evoral/src/Event.cpp index d70ba1a04b..b64ab7347c 100644 --- a/libs/evoral/src/Event.cpp +++ b/libs/evoral/src/Event.cpp @@ -1,16 +1,16 @@ /* This file is part of Evoral. * Copyright (C) 2008 Dave 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 diff --git a/libs/evoral/src/MIDIEvent.cpp b/libs/evoral/src/MIDIEvent.cpp index 4af451a3b1..9793b31476 100644 --- a/libs/evoral/src/MIDIEvent.cpp +++ b/libs/evoral/src/MIDIEvent.cpp @@ -1,16 +1,16 @@ /* This file is part of Evoral. * Copyright (C) 2008 Dave 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 @@ -29,16 +29,16 @@ namespace Evoral { #ifdef EVORAL_MIDI_XML template<typename Time> -MIDIEvent<Time>::MIDIEvent(const XMLNode& event) +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") { @@ -52,11 +52,11 @@ MIDIEvent<Time>::MIDIEvent(const XMLNode& event) template<typename Time> -boost::shared_ptr<XMLNode> +boost::shared_ptr<XMLNode> MIDIEvent<Time>::to_xml() const { XMLNode *result = 0; - + switch (type()) { case MIDI_CMD_CONTROL: result = new XMLNode("ControlChange"); @@ -64,18 +64,18 @@ MIDIEvent<Time>::to_xml() const result->add_property("Control", cc_number()); result->add_property("Value", cc_value()); break; - + case MIDI_CMD_PGM_CHANGE: result = new XMLNode("ProgramChange"); result->add_property("Channel", channel()); result->add_property("Number", pgm_number()); break; - + default: // The implementation is continued as needed break; } - + return boost::shared_ptr<XMLNode>(result); } diff --git a/libs/evoral/src/Note.cpp b/libs/evoral/src/Note.cpp index d97cfef429..ead5d1eff5 100644 --- a/libs/evoral/src/Note.cpp +++ b/libs/evoral/src/Note.cpp @@ -1,16 +1,16 @@ /* This file is part of Evoral. * Copyright (C) 2008 Dave 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 @@ -33,11 +33,11 @@ Note<Time>::Note(uint8_t chan, Time t, Time l, uint8_t n, uint8_t v) _on_event.buffer()[0] = MIDI_CMD_NOTE_ON + chan; _on_event.buffer()[1] = n; _on_event.buffer()[2] = v; - + _off_event.buffer()[0] = MIDI_CMD_NOTE_OFF + chan; _off_event.buffer()[1] = n; _off_event.buffer()[2] = 0x40; - + assert(time() == t); assert(musical_time_equal (length(), l)); assert(note() == n); @@ -58,7 +58,7 @@ Note<Time>::Note(const Note<Time>& copy) assert(copy._on_event.size == 3); _on_event.buffer = _on_event_buffer; memcpy(_on_event_buffer, copy._on_event_buffer, 3); - + assert(copy._off_event.size == 3); _off_event.buffer = _off_event_buffer; memcpy(_off_event_buffer, copy._off_event_buffer, 3); @@ -84,7 +84,7 @@ Note<Time>::operator=(const Note<Time>& other) { _on_event = other._on_event; _off_event = other._off_event; - + assert(time() == other.time()); assert(end_time() == other.end_time()); assert(note() == other.note()); @@ -92,7 +92,7 @@ Note<Time>::operator=(const Note<Time>& other) assert(length() == other.length()); assert(_on_event.channel() == _off_event.channel()); assert(channel() == other.channel()); - + return *this; } diff --git a/libs/evoral/src/OldSMF.cpp b/libs/evoral/src/OldSMF.cpp index 7fc079aaed..622c8d534f 100644 --- a/libs/evoral/src/OldSMF.cpp +++ b/libs/evoral/src/OldSMF.cpp @@ -1,16 +1,16 @@ /* This file is part of Evoral. * Copyright (C) 2008 Dave 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 @@ -87,7 +87,7 @@ SMF<Time>::open(const std::string& path) THROW_FILE_ERROR flush_header(); flush_footer(); } - + return (_fd == 0) ? -1 : 0; } @@ -115,7 +115,7 @@ void SMF<Time>::seek_to_footer_position() { uint8_t buffer[4]; - + // Check if there is a track end marker at the end of the data fseek(_fd, -4, SEEK_END); size_t read_bytes = fread(buffer, sizeof(uint8_t), 4, _fd); @@ -145,7 +145,7 @@ int SMF<Time>::flush_header() { // FIXME: write timeline position somehow? - + //cerr << path() << " SMF Flushing header\n"; assert(_fd); @@ -163,7 +163,7 @@ SMF<Time>::flush_header() //assert(_fd); fseek(_fd, 0, SEEK_SET); write_chunk("MThd", 6, data); - write_chunk_header("MTrk", _track_size); + write_chunk_header("MTrk", _track_size); fflush(_fd); @@ -224,7 +224,7 @@ SMF<Time>::read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const } catch (...) { return -1; // Premature EOF } - + if (feof(_fd)) { return -1; // Premature EOF } @@ -249,7 +249,7 @@ SMF<Time>::read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const return 0; } } - + int event_size = midi_event_size((unsigned char)status); if (event_size <= 0) { if ((status & 0xff) == MIDI_CMD_COMMON_SYSEX) { @@ -259,11 +259,11 @@ SMF<Time>::read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const return 0; } } - + // Make sure we have enough scratch buffer if (*size < (unsigned)event_size) *buf = (uint8_t*)realloc(*buf, event_size); - + *size = event_size; (*buf)[0] = (unsigned char)status; @@ -275,7 +275,7 @@ SMF<Time>::read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const printf("%X ", (*buf)[i]); } printf("\n");*/ - + return (int)*size; } @@ -285,7 +285,7 @@ SMF<Time>::append_event_delta(uint32_t delta_t, const Event<Time>& ev) { if (ev.size() == 0) return; - + size_t stamp_size = write_var_len(delta_t); if (ev.buffer()[0] == MIDI_CMD_COMMON_SYSEX) { fputc(MIDI_CMD_COMMON_SYSEX, _fd); @@ -333,7 +333,7 @@ void SMF<Time>::write_chunk(const char id[4], uint32_t length, void* data) { write_chunk_header(id, length); - + fwrite(data, 1, length, _fd); } diff --git a/libs/evoral/src/SMF.cpp b/libs/evoral/src/SMF.cpp index 424b4d46f2..7055bb2e14 100644 --- a/libs/evoral/src/SMF.cpp +++ b/libs/evoral/src/SMF.cpp @@ -2,16 +2,16 @@ * Copyright (C) 2008 Dave Robillard <http://drobilla.net> * Copyright (C) 2000-2008 Paul Davis * Author: Hans Baier - * + * * 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 @@ -32,12 +32,12 @@ using namespace std; namespace Evoral { SMF::~SMF() -{ +{ if (_smf) { smf_delete(_smf); _smf = 0; _smf_track = 0; - } + } } uint16_t @@ -77,10 +77,10 @@ int SMF::open(const std::string& path, int track) THROW_FILE_ERROR { assert(track >= 1); - if (_smf) { + if (_smf) { smf_delete(_smf); } - + _file_path = path; _smf = smf_load(_file_path.c_str()); if (_smf == NULL) { @@ -99,7 +99,7 @@ SMF::open(const std::string& path, int track) THROW_FILE_ERROR _smf_track->next_event_number = 1; _empty = false; } - + return 0; } @@ -114,21 +114,21 @@ int SMF::create(const std::string& path, int track, uint16_t ppqn) THROW_FILE_ERROR { assert(track >= 1); - if (_smf) { + if (_smf) { smf_delete(_smf); } - + _file_path = path; _smf = smf_new(); if (smf_set_ppqn(_smf, ppqn) != 0) { throw FileError(); } - + if (_smf == NULL) { return -1; } - + for (int i = 0; i < track; ++i) { _smf_track = smf_track_new(); assert(_smf_track); @@ -141,7 +141,7 @@ SMF::create(const std::string& path, int track, uint16_t ppqn) THROW_FILE_ERROR _smf_track->next_event_number = 0; _empty = true; - + return 0; } @@ -182,34 +182,34 @@ int SMF::read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const { smf_event_t* event; - + assert(delta_t); assert(size); assert(buf); - + if ((event = smf_track_get_next_event(_smf_track)) != NULL) { if (smf_event_is_metadata(event)) { return 0; } *delta_t = event->delta_time_pulses; - + int event_size = event->midi_buffer_length; assert(event_size > 0); - + // Make sure we have enough scratch buffer if (*size < (unsigned)event_size) { *buf = (uint8_t*)realloc(*buf, event_size); } memcpy(*buf, event->midi_buffer, size_t(event_size)); *size = event_size; - + assert(midi_event_is_valid(*buf, *size)); /* printf("SMF::read_event @ %u: ", *delta_t); for (size_t i = 0; i < *size; ++i) { printf("%X ", (*buf)[i]); } printf("\n") */ - + return event_size; } else { return -1; @@ -222,7 +222,7 @@ SMF::append_event_delta(uint32_t delta_t, uint32_t size, const uint8_t* buf) if (size == 0) { return; } - + /* printf("SMF::append_event_delta @ %u:", delta_t); for (size_t i = 0; i < size; ++i) { printf("%X ", buf[i]); @@ -237,7 +237,7 @@ SMF::append_event_delta(uint32_t delta_t, uint32_t size, const uint8_t* buf) event = smf_event_new_from_pointer(buf, size); assert(event != NULL); - + assert(_smf_track); smf_track_add_event_delta_pulses(_smf_track, event, delta_t); _empty = false; @@ -248,10 +248,10 @@ SMF::begin_write() { assert(_smf_track); smf_track_delete(_smf_track); - + _smf_track = smf_track_new(); assert(_smf_track); - + smf_add_track(_smf, _smf_track); assert(_smf->number_of_tracks == 1); } diff --git a/libs/evoral/src/SMFReader.cpp b/libs/evoral/src/SMFReader.cpp index e992514191..b5b456348d 100644 --- a/libs/evoral/src/SMFReader.cpp +++ b/libs/evoral/src/SMFReader.cpp @@ -1,16 +1,16 @@ /* This file is part of Evoral. * Copyright(C) 2008 Dave 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 @@ -71,7 +71,7 @@ SMFReader::open(const string& filename) throw (logic_error, UnsupportedTime) _fd = NULL; return false; } - + // Read type (bytes 8..9) fseek(_fd, 8, SEEK_SET); uint16_t type_be = 0; @@ -87,20 +87,20 @@ SMFReader::open(const string& filename) throw (logic_error, UnsupportedTime) uint16_t ppqn_be = 0; fread(&ppqn_be, 2, 1, _fd); _ppqn = GUINT16_FROM_BE(ppqn_be); - + // TODO: Absolute (SMPTE seconds) time support if ((_ppqn & 0x8000) != 0) throw UnsupportedTime(); seek_to_track(1); - + return true; } else { return false; } } - + /** Seek to the start of a given track, starting from 1. * Returns true if specified track was found. */ @@ -148,7 +148,7 @@ SMFReader::seek_to_track(unsigned track) throw (std::logic_error) } } - + /** Read an event from the current position in file. * * File position MUST be at the beginning of a delta time, or this will die very messily. @@ -234,14 +234,14 @@ SMFReader::read_event(size_t buf_len, // Read event, return size if (ferror(_fd)) throw CorruptFile(); - + fread(buf+1, 1, *ev_size - 1, _fd); - + if ((buf[0] & 0xF0) == 0x90 && buf[2] == 0) { buf[0] = (0x80 | (buf[0] & 0x0F)); buf[2] = 0x40; } - + return *ev_size; } } diff --git a/libs/evoral/src/Sequence.cpp b/libs/evoral/src/Sequence.cpp index 91943c03a6..124a0acd4c 100644 --- a/libs/evoral/src/Sequence.cpp +++ b/libs/evoral/src/Sequence.cpp @@ -1,16 +1,16 @@ /* This file is part of Evoral. * Copyright (C) 2008 Dave 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 @@ -92,7 +92,7 @@ Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>& seq, Time t , _control_iter(_control_iters.end()) { DUMP(format("Created Iterator @ %1% (is end: %2%)\n)") % t % _is_end); - + if (_is_end) { return; } @@ -108,7 +108,7 @@ Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>& seq, Time t } } assert(_note_iter == seq.notes().end() || (*_note_iter)->time() >= t); - + // Find first sysex event after t for (typename Sequence<Time>::SysExes::const_iterator i = seq.sysexes().begin(); i != seq.sysexes().end(); ++i) { @@ -142,7 +142,7 @@ Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>& seq, Time t << "], event ignored" << endl; continue; } - + DUMP(format("Iterator: CC %1% added (%2%, %3%)\n") % i->first.id() % x % y); const ControlIterator new_iter(i->second->list(), x, y); @@ -161,7 +161,7 @@ Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>& seq, Time t } else { _control_iter = _control_iters.end(); } - + // Now find the earliest event overall and point to it Time earliest_t = t; @@ -169,7 +169,7 @@ Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>& seq, Time t _type = NOTE_ON; earliest_t = (*_note_iter)->time(); } - + if (_sysex_iter != seq.sysexes().end() && (*_sysex_iter)->time() < earliest_t) { _type = SYSEX; earliest_t = (*_sysex_iter)->time(); @@ -181,7 +181,7 @@ Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>& seq, Time t _type = CONTROL; earliest_t = earliest_control.x; } - + switch (_type) { case NOTE_ON: DUMP(format("Starting at note on event @ %1%\n") % earliest_t); @@ -252,10 +252,10 @@ Sequence<Time>::const_iterator::operator++() if (_is_end) { throw std::logic_error("Attempt to iterate past end of Sequence"); } - + DUMP("Sequence::const_iterator++\n"); assert(_event && _event->buffer() && _event->size() > 0); - + const MIDIEvent<Time>& ev = *((MIDIEvent<Time>*)_event.get()); if (!( ev.is_note() @@ -267,11 +267,11 @@ Sequence<Time>::const_iterator::operator++() cerr << "WARNING: Unknown event (type " << _type << "): " << hex << int(ev.buffer()[0]) << int(ev.buffer()[1]) << int(ev.buffer()[2]) << endl; } - + double x = 0.0; double y = 0.0; bool ret = false; - + // Increment past current event switch (_type) { case NOTE_ON: @@ -292,7 +292,7 @@ Sequence<Time>::const_iterator::operator++() _control_iter->x = DBL_MAX; _control_iter->y = DBL_MAX; } - + // Find the controller with the next earliest event time _control_iter = _control_iters.begin(); for (ControlIterators::iterator i = _control_iters.begin(); @@ -334,7 +334,7 @@ Sequence<Time>::const_iterator::operator++() earliest_t = _control_iter->x; } } - + // Use the next earliest SysEx iff it's earlier than the controller if (_sysex_iter != _seq->sysexes().end()) { if (_type == NIL || (*_sysex_iter)->time() < earliest_t) { @@ -413,7 +413,7 @@ Sequence<Time>::const_iterator::operator=(const const_iterator& other) _note_iter = other._note_iter; _sysex_iter = other._sysex_iter; _control_iters = other._control_iters; - + if (other._control_iter == other._control_iters.end()) { _control_iter = _control_iters.end(); } else { @@ -455,12 +455,12 @@ Sequence<Time>::control_to_midi_event( { assert(iter.list.get()); const uint32_t event_type = iter.list->parameter().type(); - + // initialize the event pointer with a new event, if necessary if (!ev) { ev = boost::shared_ptr< Event<Time> >(new Event<Time>(event_type, 0, 3, NULL, true)); } - + uint8_t midi_type = _type_map.parameter_midi_type(iter.list->parameter()); ev->set_event_type(_type_map.midi_event_type(midi_type)); switch (midi_type) { @@ -469,7 +469,7 @@ Sequence<Time>::control_to_midi_event( assert(iter.list->parameter().channel() < 16); assert(iter.list->parameter().id() <= INT8_MAX); assert(iter.y <= INT8_MAX); - + ev->time() = iter.x; ev->realloc(3); ev->buffer()[0] = MIDI_CMD_CONTROL + iter.list->parameter().channel(); @@ -481,7 +481,7 @@ Sequence<Time>::control_to_midi_event( assert(iter.list.get()); assert(iter.list->parameter().channel() < 16); assert(iter.y <= INT8_MAX); - + ev->time() = iter.x; ev->realloc(2); ev->buffer()[0] = MIDI_CMD_PGM_CHANGE + iter.list->parameter().channel(); @@ -492,7 +492,7 @@ Sequence<Time>::control_to_midi_event( assert(iter.list.get()); assert(iter.list->parameter().channel() < 16); assert(iter.y < (1<<14)); - + ev->time() = iter.x; ev->realloc(3); ev->buffer()[0] = MIDI_CMD_BENDER + iter.list->parameter().channel(); @@ -591,7 +591,7 @@ Sequence<Time>::end_write(bool delete_stuck) for (ControlLists::const_iterator i = _dirty_controls.begin(); i != _dirty_controls.end(); ++i) { (*i)->mark_dirty(); } - + _writing = false; write_unlock(); } @@ -608,7 +608,7 @@ Sequence<Time>::append(const Event<Time>& event) { write_lock(); _edited = true; - + const MIDIEvent<Time>& ev = (const MIDIEvent<Time>&)event; assert(_notes.empty() || ev.time() >= _notes.back()->time()); diff --git a/libs/evoral/src/midi_util.cpp b/libs/evoral/src/midi_util.cpp index 5f088cb925..4076337137 100644 --- a/libs/evoral/src/midi_util.cpp +++ b/libs/evoral/src/midi_util.cpp @@ -1,16 +1,16 @@ /* This file is part of Evoral. * Copyright (C) 2008 Dave Robillard <http://drobilla.net> * Copyright (C) 2009 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 @@ -45,7 +45,7 @@ midi_note_name (uint8_t val) int octave = val/12; static char buf[8]; - + val -= octave*12; snprintf (buf, sizeof (buf), "%s%d", notes[val], octave); |