svcore
1.9
|
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 00002 00003 /* 00004 Sonic Visualiser 00005 An audio file viewer and annotation editor. 00006 Centre for Digital Music, Queen Mary, University of London. 00007 This file copyright 2007 QMUL. 00008 00009 This program is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU General Public License as 00011 published by the Free Software Foundation; either version 2 of the 00012 License, or (at your option) any later version. See the file 00013 COPYING included with this distribution for more information. 00014 */ 00015 00016 #include "MatchFileReader.h" 00017 00018 #include <QFile> 00019 #include <QTextStream> 00020 00021 #include <cmath> 00022 #include <iostream> 00023 00024 Alignment::Alignment() : 00025 thisHopTime(0.0), 00026 refHopTime(0.0), 00027 m_mainModel(0) 00028 { 00029 } 00030 00031 double 00032 Alignment::fromReference(double t) const 00033 { 00034 int ri = lrint(t / refHopTime); 00035 int index = search(refIndex, ri); 00036 return thisIndex[index] * thisHopTime; 00037 } 00038 00039 double 00040 Alignment::toReference(double t) const 00041 { 00042 int ti = lrint(t / thisHopTime); 00043 int index = search(thisIndex, ti); 00044 return refIndex[index] * refHopTime; 00045 } 00046 00047 int 00048 Alignment::search(const FrameArray &arr, int val) const 00049 { 00050 int len = arr.size(); 00051 int max = len - 1; 00052 int min = 0; 00053 while (max > min) { 00054 int mid = (max + min) / 2; 00055 if (val > arr[mid]) { 00056 min = mid + 1; 00057 } else { 00058 max = mid; 00059 } 00060 } // max = MIN_j (arr[j] >= val) i.e. the first equal or next highest 00061 while ((max + 1 < len) && (arr[max + 1] == val)) { 00062 max++; 00063 } 00064 return (min + max) / 2; 00065 } 00066 00067 MatchFileReader::MatchFileReader(QString path) : 00068 m_file(0) 00069 { 00070 m_file = new QFile(path); 00071 bool good = false; 00072 00073 if (!m_file->exists()) { 00074 m_error = QFile::tr("File \"%1\" does not exist").arg(path); 00075 } else if (!m_file->open(QIODevice::ReadOnly | QIODevice::Text)) { 00076 m_error = QFile::tr("Failed to open file \"%1\"").arg(path); 00077 } else { 00078 good = true; 00079 } 00080 00081 if (!good) { 00082 delete m_file; 00083 m_file = 0; 00084 } 00085 } 00086 00087 MatchFileReader::~MatchFileReader() 00088 { 00089 if (m_file) { 00090 SVDEBUG << "MatchFileReader::MatchFileReader: Closing file" << endl; 00091 m_file->close(); 00092 } 00093 delete m_file; 00094 } 00095 00096 bool 00097 MatchFileReader::isOK() const 00098 { 00099 return (m_file != 0); 00100 } 00101 00102 QString 00103 MatchFileReader::getError() const 00104 { 00105 return m_error; 00106 } 00107 00108 Alignment 00109 MatchFileReader::load() const 00110 { 00111 Alignment alignment; 00112 00113 if (!m_file) return alignment; 00114 00115 QTextStream in(m_file); 00116 00117 /* 00118 File: /home/studio/match-test/mahler-3-boulez-5.wav 00119 Marks: -1 00120 FixedPoints: true 0 00121 0 00122 0 00123 0 00124 0 00125 File: /home/studio/match-test/mahler-3-haitink-5.wav 00126 Marks: 0 00127 FixedPoints: true 0 00128 0.02 00129 0.02 00130 12836 00131 */ 00132 00133 int fileCount = 0; 00134 int state = 0; 00135 int count = 0; 00136 00137 while (!in.atEnd()) { 00138 00139 QString line = in.readLine().trimmed(); 00140 if (line.startsWith("File: ")) { 00141 ++fileCount; 00142 continue; 00143 } 00144 if (fileCount != 2) continue; 00145 if (line.startsWith("Marks:") || line.startsWith("FixedPoints:")) { 00146 continue; 00147 } 00148 00149 switch (state) { 00150 case 0: 00151 alignment.thisHopTime = line.toDouble(); 00152 break; 00153 case 1: 00154 alignment.refHopTime = line.toDouble(); 00155 break; 00156 case 2: 00157 count = line.toInt(); 00158 break; 00159 case 3: 00160 alignment.thisIndex.push_back(line.toInt()); 00161 break; 00162 case 4: 00163 alignment.refIndex.push_back(line.toInt()); 00164 break; 00165 } 00166 00167 if (state < 3) { 00168 ++state; 00169 } else if (state == 3 && int(alignment.thisIndex.size()) == count) { 00170 ++state; 00171 } 00172 } 00173 00174 if (alignment.thisHopTime == 0.0) { 00175 cerr << "ERROR in Match file: this hop time == 0, using 0.01 instead" << endl; 00176 alignment.thisHopTime = 0.01; 00177 } 00178 00179 if (alignment.refHopTime == 0.0) { 00180 cerr << "ERROR in Match file: ref hop time == 0, using 0.01 instead" << endl; 00181 alignment.refHopTime = 0.01; 00182 } 00183 00184 cerr << "MatchFileReader: this hop = " << alignment.thisHopTime << ", ref hop = " << alignment.refHopTime << ", this index count = " << alignment.thisIndex.size() << ", ref index count = " << alignment.refIndex.size() << endl; 00185 00186 return alignment; 00187 }