svcore  1.9
MatchFileReader.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  Sonic Visualiser
5  An audio file viewer and annotation editor.
6  Centre for Digital Music, Queen Mary, University of London.
7  This file copyright 2007 QMUL.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2 of the
12  License, or (at your option) any later version. See the file
13  COPYING included with this distribution for more information.
14 */
15 
16 #include "MatchFileReader.h"
17 
18 #include <QFile>
19 #include <QTextStream>
20 
21 #include <cmath>
22 #include <iostream>
23 
25  thisHopTime(0.0),
26  refHopTime(0.0),
27  m_mainModel(0)
28 {
29 }
30 
31 double
32 Alignment::fromReference(double t) const
33 {
34  int ri = lrint(t / refHopTime);
35  int index = search(refIndex, ri);
36  return thisIndex[index] * thisHopTime;
37 }
38 
39 double
40 Alignment::toReference(double t) const
41 {
42  int ti = lrint(t / thisHopTime);
43  int index = search(thisIndex, ti);
44  return refIndex[index] * refHopTime;
45 }
46 
47 int
48 Alignment::search(const FrameArray &arr, int val) const
49 {
50  int len = arr.size();
51  int max = len - 1;
52  int min = 0;
53  while (max > min) {
54  int mid = (max + min) / 2;
55  if (val > arr[mid]) {
56  min = mid + 1;
57  } else {
58  max = mid;
59  }
60  } // max = MIN_j (arr[j] >= val) i.e. the first equal or next highest
61  while ((max + 1 < len) && (arr[max + 1] == val)) {
62  max++;
63  }
64  return (min + max) / 2;
65 }
66 
68  m_file(0)
69 {
70  m_file = new QFile(path);
71  bool good = false;
72 
73  if (!m_file->exists()) {
74  m_error = QFile::tr("File \"%1\" does not exist").arg(path);
75  } else if (!m_file->open(QIODevice::ReadOnly | QIODevice::Text)) {
76  m_error = QFile::tr("Failed to open file \"%1\"").arg(path);
77  } else {
78  good = true;
79  }
80 
81  if (!good) {
82  delete m_file;
83  m_file = 0;
84  }
85 }
86 
88 {
89  if (m_file) {
90  SVDEBUG << "MatchFileReader::MatchFileReader: Closing file" << endl;
91  m_file->close();
92  }
93  delete m_file;
94 }
95 
96 bool
98 {
99  return (m_file != 0);
100 }
101 
102 QString
104 {
105  return m_error;
106 }
107 
108 Alignment
110 {
111  Alignment alignment;
112 
113  if (!m_file) return alignment;
114 
115  QTextStream in(m_file);
116 
117 /*
118 File: /home/studio/match-test/mahler-3-boulez-5.wav
119 Marks: -1
120 FixedPoints: true 0
121 0
122 0
123 0
124 0
125 File: /home/studio/match-test/mahler-3-haitink-5.wav
126 Marks: 0
127 FixedPoints: true 0
128 0.02
129 0.02
130 12836
131 */
132 
133  int fileCount = 0;
134  int state = 0;
135  int count = 0;
136 
137  while (!in.atEnd()) {
138 
139  QString line = in.readLine().trimmed();
140  if (line.startsWith("File: ")) {
141  ++fileCount;
142  continue;
143  }
144  if (fileCount != 2) continue;
145  if (line.startsWith("Marks:") || line.startsWith("FixedPoints:")) {
146  continue;
147  }
148 
149  switch (state) {
150  case 0:
151  alignment.thisHopTime = line.toDouble();
152  break;
153  case 1:
154  alignment.refHopTime = line.toDouble();
155  break;
156  case 2:
157  count = line.toInt();
158  break;
159  case 3:
160  alignment.thisIndex.push_back(line.toInt());
161  break;
162  case 4:
163  alignment.refIndex.push_back(line.toInt());
164  break;
165  }
166 
167  if (state < 3) {
168  ++state;
169  } else if (state == 3 && int(alignment.thisIndex.size()) == count) {
170  ++state;
171  }
172  }
173 
174  if (alignment.thisHopTime == 0.0) {
175  cerr << "ERROR in Match file: this hop time == 0, using 0.01 instead" << endl;
176  alignment.thisHopTime = 0.01;
177  }
178 
179  if (alignment.refHopTime == 0.0) {
180  cerr << "ERROR in Match file: ref hop time == 0, using 0.01 instead" << endl;
181  alignment.refHopTime = 0.01;
182  }
183 
184  cerr << "MatchFileReader: this hop = " << alignment.thisHopTime << ", ref hop = " << alignment.refHopTime << ", this index count = " << alignment.thisIndex.size() << ", ref index count = " << alignment.refIndex.size() << endl;
185 
186  return alignment;
187 }
double fromReference(double) const
FrameArray thisIndex
double refHopTime
double toReference(double) const
int search(const FrameArray &arr, int val) const
virtual QString getError() const
virtual bool isOK() const
std::vector< int > FrameArray
double thisHopTime
virtual ~MatchFileReader()
virtual Alignment load() const
#define SVDEBUG
Definition: Debug.h:42
MatchFileReader(QString path)
FrameArray refIndex