123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- /*
- This file is part of QTau
- Copyright (C) 2013-2018 Tobias "Tomoko" Platen <tplaten@posteo.de>
- Copyright (C) 2013 digited <https://github.com/digited>
- Copyright (C) 2010-2013 HAL@ShurabaP <https://github.com/haruneko>
- QTau 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 3 of the License, or
- (at your option) any later version.
- This program 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 more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- SPDX-License-Identifier: GPL-3.0+
- */
- #include "tempomap.h"
- #include <Utils.h>
- #include <QJsonObject>
- #define __devloglevel__ 4
- bool indexCompare(const tempoindex &i1, const tempoindex &i2) {
- return i1.pos < i2.pos;
- }
- void TempoMap::updateIndexList() {
- qSort(_index.begin(), _index.end(), indexCompare);
- // calculate bar offsets for gui and sound
- }
- TempoMap::TempoMap() {
- }
- void TempoMap::addTempo(int pos, float tempo) {
- beginInsertRows(QModelIndex(), 1, 1);
- _tempo[pos] = tempo;
- tempoindex idx;
- idx.pos = pos;
- idx.type = 0;
- _index.append(idx);
- updateIndexList();
- endInsertRows();
- }
- void TempoMap::addTimeSignature(int pos, int numerator, int denominator) {
- beginInsertRows(QModelIndex(), 1, 1);
- fraction time;
- time.denominator = denominator;
- time.numerator = numerator;
- tempoindex idx;
- idx.pos = pos;
- idx.type = 1;
- _index.append(idx);
- _time[pos] = time;
- updateIndexList();
- endInsertRows();
- }
- void TempoMap::removeEventAt(int index) {
- if (index < _index.size() && index >= 0) {
- beginRemoveRows(QModelIndex(), index, index);
- if (_index[index].type == 1) {
- _time.remove(_index[index].pos);
- } else if (_index[index].type == 0) {
- _tempo.remove(_index[index].pos);
- }
- _index.removeAt(index);
- updateIndexList();
- endRemoveRows();
- }
- }
- void TempoMap::removeTempoForBar(int pos)
- {
- for(int index=0; index<_index.size(); index++)
- {
- if(_index[index].pos==pos && _index[index].type == 0)
- {
- removeEventAt(index);
- return;
- }
- }
- }
- void TempoMap::removeTimeSignatureForBar(int pos)
- {
- for(int index=0; index<_index.size(); index++)
- {
- if(_index[index].pos==pos && _index[index].type == 1)
- {
- removeEventAt(index);
- return;
- }
- }
- }
- fraction TempoMap::getTimeSignatureForBar(int pos) {
- fraction time = _time[pos];
- while (time.denominator == 0 && time.numerator == 0) {
- pos--;
- time = _time[pos];
- }
- return time;
- }
- QModelIndex TempoMap::index(int row, int column,
- const QModelIndex &parent) const {
- Q_UNUSED(parent);
- return createIndex(row, column);
- }
- QModelIndex TempoMap::parent(const QModelIndex &child) const {
- Q_UNUSED(child);
- return QModelIndex();
- }
- int TempoMap::rowCount(const QModelIndex &parent) const {
- Q_UNUSED(parent);
- return _index.count();
- }
- int TempoMap::columnCount(const QModelIndex &parent) const {
- Q_UNUSED(parent);
- return 3;
- }
- QVariant TempoMap::data(const QModelIndex &index, int role) const {
- if (role != Qt::DisplayRole) return QVariant();
- int row = index.row();
- int col = index.column();
- int pos = _index[row].pos;
- int type = _index[row].type;
- if (col == 0) return QVariant(pos + 1).toString();
- if (col == 1) {
- if (type == 0) return "Tempo";
- if (type == 1) return "Time Signature";
- }
- if (col == 2) {
- if (type == 0) return _tempo[pos];
- if (type == 1)
- return QVariant(_time[pos].numerator).toString() + "/" +
- QVariant(_time[pos].denominator).toString();
- }
- return QVariant();
- }
- void TempoMap::beginEditing() {
- _origIndex = _index;
- _origTempo = _tempo;
- _origTime = _time;
- }
- void TempoMap::toJson(QJsonArray &array) {
- DEVLOG_DEBUG("tempoMap::toJson "+STR(_index.size()));
- for (int i = 0; i < _index.length(); i++) {
- int pos = _index[i].pos;
- int type = _index[i].type;
- if (type == 1) {
- QJsonObject val;
- val["pos"] = pos;
- val["type"] = "timeSig";
- val["denominator"] = _time[pos].denominator;
- val["numerator"] = _time[pos].numerator;
- DEVLOG_DEBUG("type==1");
- array.append(val);
- } else if (type == 0) {
- QJsonObject val;
- val["pos"] = pos;
- val["type"] = "tempo";
- val["tempo"] = _tempo[pos];
- DEVLOG_DEBUG("type==0");
- array.append(val);
- }
- else {
- DEVLOG_DEBUG("type is invalid");
- }
- }
- }
- void TempoMap::fromJson(QJsonArray &array) {
- _index.clear();
- _time.clear();
- _tempo.clear();
- for (int i = 0; i < array.size(); i++) {
- QJsonObject val = array[i].toObject();
- if (val["type"].toString() == "timeSig") {
- int pos = val["pos"].toInt();
- int denominator = val["denominator"].toInt();
- int numerator = val["numerator"].toInt();
- this->addTimeSignature(pos, numerator, denominator);
- } else if (val["type"].toString() == "tempo") {
- int pos = val["pos"].toInt();
- int tempo = val["tempo"].toInt();
- this->addTempo(pos, tempo);
- }
- }
- }
- void TempoMap::undo() {
- _index = _origIndex;
- _tempo = _origTempo;
- _time = _origTime;
- }
- bool TempoMap::getBar(int pulses, float &time, int &bar, int end) {
- time = 0;
- for (int i = 0; i < 128; i++) {
- fraction ts = getTimeSignatureForBar(i);
- float bpm = getBPMforBar(i);
- int barLength = ts.numerator * 480 * 4 / ts.denominator;
- if (pulses >= barLength) {
- pulses -= barLength;
- time += ts.numerator * 60 / bpm;
- } else {
- pulses += end;
- time += pulses * 60 / bpm / 480;
- bar = i;
- return true;
- }
- }
- return false;
- }
- float TempoMap::getBPMforBar(int pos) {
- bool found = _tempo.keys().contains(pos);
- if(found) return _tempo[pos];
- while (pos>0) {
- pos--;
- found = _tempo.keys().contains(pos);
- if(found) return _tempo[pos];
- }
- return 120.0;
- }
- QString TempoMap::getLabel(int bar, tmlabel mode) {
- if (mode == TM_BPM) {
- if (_tempo.keys().contains(bar) && _tempo[bar] > 0)
- return STR(_tempo[bar]) + " BPM";
- }
- if (mode == TM_SIG) {
- if (_time.keys().contains(bar) && _time[bar].denominator > 0)
- return STR(_time[bar].numerator) + "/" + STR(_time[bar].denominator);
- }
- return "";
- }
- bool TempoMap::setLabel(tmlabel mode, int bar, QString label) {
- if (mode == TM_BPM) {
- if (label.length() == 0) {
- this->removeTempoForBar(bar);
- return true;
- } else {
- float tempo = QVariant(label).toFloat();
- if (tempo > 0) {
- this->removeTempoForBar(bar);
- this->addTempo(bar, tempo);
- return true;
- }
- }
- }
- if (mode == TM_SIG) {
- if (label.length() == 0) {
- this->removeTimeSignatureForBar(bar);
- return true;
- } else {
- QStringList tmp = label.split("/");
- if (tmp.length() == 2) {
- fraction time;
- time.numerator = QVariant(tmp[0]).toInt();
- time.denominator = QVariant(tmp[1]).toInt();
- if (time.denominator > 0 && time.numerator > 0) {
- this->removeTimeSignatureForBar(bar);
- this->addTimeSignature(bar,time.numerator,time.denominator);
- return true;
- }
- }
- }
- }
- return false;
- }
|