Just Intonation  Version 1.3.1 (19)
Explore key-independent dynamically adapting tuning in just intonation
logfile.cpp
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright 2016-2017 Karolin Stange, Christoph Wick, and Haye Hinrichsen
3  *
4  * This file is part of JustIntonation.
5  *
6  * JustIntonation is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * JustIntonation is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14  * for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with JustIntonation. If not, see http://www.gnu.org/licenses/.
18  *****************************************************************************/
19 
20 //=============================================================================
21 // Create a data log of all tuning events
22 //=============================================================================
23 
24 #include "logfile.h"
25 
26 #include <QTimer>
27 #include <QTime>
28 
29 //-----------------------------------------------------------------------------
30 // Constructor
31 //-----------------------------------------------------------------------------
35 
37  : mTimer()
38  , isActive(false)
39  , mPressed()
40  , mReleased()
41  , mTimeOfLastKeypress(-1)
42  , mTuningMessage("")
43 {
44  setModuleName("LogFile");
45  mTimer.start();
46 }
47 
48 
49 //-----------------------------------------------------------------------------
50 // Switch logging on and off
51 //-----------------------------------------------------------------------------
56 
58 {
59 
60  LOGMESSAGE << "TURNED" << on;
61  isActive = on;
62 }
63 
64 
65 //-----------------------------------------------------------------------------
66 // Note Name of a key
67 //-----------------------------------------------------------------------------
73 
74 QString LogFile::noteName (int key)
75 {
76  const QVector<QString> names =
77  {"C","C#","D","D#","E","F","F#","G","G#","A",tr("A#"),tr("B")};
78  return names[key%12] + QString::number(key/12-1);
79 }
80 
81 //-----------------------------------------------------------------------------
82 // Public slot: Receive MIDI event
83 //-----------------------------------------------------------------------------
91 
92 void LogFile::receiveMidiEvent(QMidiMessage event)
93 {
94  int key = event.byte1() & 0x7F;
95 
96  switch (event.byte0() & 0xF0)
97  {
98  // Press key: Note on
99  case 0x90:
100  registerKeypress (key,event.byte2()>0);
101  break;
102 
103  // Release key: Note off
104  case 0x80:
105  registerKeypress (key,false);
106  break;
107  }
108 }
109 
110 
111 //-----------------------------------------------------------------------------
112 // Public slot: Receive tuning corrections
113 //-----------------------------------------------------------------------------
123 
124 void LogFile::receiveTuningCorrections (const QMap<int, double> &corrections)
125 {
126  if (not isActive) return;
127  if (corrections.size() == 0) return;
128 
129  qint64 time = mTimer.elapsed();
130  if ((mPressed.size()>0 or mReleased.size()>0) and time != mTimeOfLastKeypress)
131  flushKeypress();
132 
133  QString msg = "<font color=\"orange\">" +
134  QString::number(0.01*qRound(100*(corrections.first()))) + "</font> ";
135  double prevValue = 0;
136  for (auto it = corrections.begin(); it != corrections.end(); it++)
137  {
138  int key = it.key() % 128;
139  if (key != corrections.firstKey())
140  {
141  msg += " " + QString::number(0.01*qRound(100*(it.value()-prevValue))) + " ";
142  prevValue = it.value();
143  }
144  msg += "</font>|<b>"+noteName(key)+"</b>|<font color=\"blue\">";
145  prevValue = it.value();
146  }
147  if (mTuningMessage.length()==0) addLine(mTimer.elapsed(),msg);
148  mTuningMessage = msg;
149 }
150 
151 
152 //-----------------------------------------------------------------------------
153 // Add a line to the logfile output
154 //-----------------------------------------------------------------------------
160 
161 void LogFile::addLine (quint64 milliseconds, const QString &line)
162 {
163  if (not isActive) return;
164  QTime time(0,static_cast<int>(milliseconds/60000L),
165  static_cast<int>((milliseconds/1000L)%60L),
166  static_cast<int>(milliseconds%1000L));
167  emit signalNewLogMessage(time.toString("mm:ss.zzz") + " <font color=\"blue\">" + line + "</font>");
168 }
169 
170 
171 //-----------------------------------------------------------------------------
172 // Public slot: Register pressed or released key
173 //-----------------------------------------------------------------------------
185 
186 void LogFile::registerKeypress(int key, bool pressed)
187 {
188  if (mTuningMessage.length()>0) { addLine(mTimer.elapsed(),mTuningMessage);
189  mTuningMessage.clear(); }
190  qint64 time = mTimer.elapsed();
191  if ((mPressed.size()>0 or mReleased.size()>0) and time != mTimeOfLastKeypress)
192  flushKeypress();
193 
194  {
195  if (pressed) mPressed.append(key); else mReleased.append(key);
196  mTimeOfLastKeypress = time;
197  }
198 }
199 
200 
201 //-----------------------------------------------------------------------------
202 // Terminate collection of multiple keypresses/releases and send them to the logfile
203 //-----------------------------------------------------------------------------
208 
210 {
211  if (mPressed.empty() and mReleased.empty()) return;
212  QString line; QTextStream str(&line);
213  if (mReleased.size()>0)
214  {
215  qSort(mReleased);
216  str << "<font color=\"red\">RELEASED";
217  for (auto &e : mReleased) str << " - " << noteName(e);
218  str << "</font> ";
219  }
220  if (mPressed.size()>0)
221  {
222  qSort(mPressed);
223  str << "<font color=\"green\">PRESSED";
224  for (auto &e : mPressed) str << " - " << noteName(e);
225  str << "</font> ";
226  }
228  mPressed.clear(); mReleased.clear();
229 }
void registerKeypress(int key, bool pressed)
Public slot: Register pressed or released key.
Definition: logfile.cpp:186
QList< int > mReleased
Definition: logfile.h:66
void setModuleName(const QString &name)
Specify the name of the class-specific module.
Definition: log.cpp:82
void flushKeypress()
Terminate collection of multiple keypresses/releases and send them to the logfile.
Definition: logfile.cpp:209
void signalNewLogMessage(QVariant str)
bool isActive
Definition: logfile.h:65
#define LOGMESSAGE
Definition: log.h:43
void receiveTuningCorrections(const QMap< int, double > &corrections)
Public slot: Receive tuning corrections.
Definition: logfile.cpp:124
QElapsedTimer mTimer
Definition: logfile.h:64
QList< int > mPressed
Definition: logfile.h:66
QString mTuningMessage
Definition: logfile.h:68
void activateLogFile(bool on)
Switch logging on and off.
Definition: logfile.cpp:57
void receiveMidiEvent(QMidiMessage event)
Public slot: Receive MIDI event.
Definition: logfile.cpp:92
qint64 mTimeOfLastKeypress
Definition: logfile.h:67
QString noteName(int key)
Note Name of a key.
Definition: logfile.cpp:74
void addLine(quint64 milliseconds, const QString &line)
Add a line to the logfile output.
Definition: logfile.cpp:161
LogFile()
Constructor of the LogFile, resets member variables.
Definition: logfile.cpp:36