MatchFileReader.cpp

Go to the documentation of this file.
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 {
00028 }
00029 
00030 double
00031 Alignment::fromReference(double t) const
00032 {
00033     int ri = lrint(t / refHopTime);
00034     int index = search(refIndex, ri);
00035     return thisIndex[index] * thisHopTime;
00036 }
00037 
00038 double
00039 Alignment::toReference(double t) const
00040 {
00041     int ti = lrint(t / thisHopTime);
00042     int index = search(thisIndex, ti);
00043     return refIndex[index] * refHopTime;
00044 }
00045 
00046 int
00047 Alignment::search(const FrameArray &arr, int val) const
00048 {
00049     int len = arr.size();
00050     int max = len - 1;
00051     int min = 0;
00052     while (max > min) {
00053         int mid = (max + min) / 2;
00054         if (val > arr[mid]) {
00055             min = mid + 1;
00056         } else {
00057             max = mid;
00058         }
00059     } // max = MIN_j (arr[j] >= val)   i.e. the first equal or next highest
00060     while ((max + 1 < len) && (arr[max + 1] == val)) {
00061         max++;
00062     }
00063     return (min + max) / 2;
00064 }
00065 
00066 MatchFileReader::MatchFileReader(QString path) :
00067     m_file(0)
00068 {
00069     m_file = new QFile(path);
00070     bool good = false;
00071     
00072     if (!m_file->exists()) {
00073         m_error = QFile::tr("File \"%1\" does not exist").arg(path);
00074     } else if (!m_file->open(QIODevice::ReadOnly | QIODevice::Text)) {
00075         m_error = QFile::tr("Failed to open file \"%1\"").arg(path);
00076     } else {
00077         good = true;
00078     }
00079 
00080     if (!good) {
00081         delete m_file;
00082         m_file = 0;
00083     }
00084 }
00085 
00086 MatchFileReader::~MatchFileReader()
00087 {
00088     if (m_file) {
00089         std::cerr << "MatchFileReader::MatchFileReader: Closing file" << std::endl;
00090         m_file->close();
00091     }
00092     delete m_file;
00093 }
00094 
00095 bool
00096 MatchFileReader::isOK() const
00097 {
00098     return (m_file != 0);
00099 }
00100 
00101 QString
00102 MatchFileReader::getError() const
00103 {
00104     return m_error;
00105 }
00106 
00107 Alignment
00108 MatchFileReader::load() const
00109 {
00110     Alignment alignment;
00111 
00112     if (!m_file) return alignment;
00113 
00114     QTextStream in(m_file);
00115 
00116 /*
00117 File: /home/studio/match-test/mahler-3-boulez-5.wav
00118 Marks: -1
00119 FixedPoints: true 0
00120 0
00121 0
00122 0
00123 0
00124 File: /home/studio/match-test/mahler-3-haitink-5.wav
00125 Marks: 0
00126 FixedPoints: true 0
00127 0.02
00128 0.02
00129 12836
00130 */
00131 
00132     int fileCount = 0;
00133     int state = 0;
00134     int count = 0;
00135 
00136     while (!in.atEnd()) {
00137 
00138         QString line = in.readLine().trimmed();
00139         if (line.startsWith("File: ")) {
00140             ++fileCount;
00141             continue;
00142         }
00143         if (fileCount != 2) continue;
00144         if (line.startsWith("Marks:") || line.startsWith("FixedPoints:")) {
00145             continue;
00146         }
00147 
00148         switch (state) {
00149         case 0:
00150             alignment.thisHopTime = line.toDouble();
00151             break;
00152         case 1:
00153             alignment.refHopTime = line.toDouble();
00154             break;
00155         case 2: 
00156             count = line.toInt();
00157             break;
00158         case 3:
00159             alignment.thisIndex.push_back(line.toInt());
00160             break;
00161         case 4:
00162             alignment.refIndex.push_back(line.toInt());
00163             break;
00164         }
00165 
00166         if (state < 3) ++state;
00167         else if (state == 3 && alignment.thisIndex.size() == count) ++state;
00168     }
00169 
00170     if (alignment.thisHopTime == 0.0) {
00171         std::cerr << "ERROR in Match file: this hop time == 0, using 0.01 instead" << std::endl;
00172         alignment.thisHopTime = 0.01;
00173     }
00174 
00175     if (alignment.refHopTime == 0.0) {
00176         std::cerr << "ERROR in Match file: ref hop time == 0, using 0.01 instead" << std::endl;
00177         alignment.refHopTime = 0.01;
00178     }
00179 
00180     std::cerr << "MatchFileReader: this hop = " << alignment.thisHopTime << ", ref hop = " << alignment.refHopTime << ", this index count = " << alignment.thisIndex.size() << ", ref index count = " << alignment.refIndex.size() << std::endl;
00181 
00182     return alignment;
00183 }

Generated on Wed Feb 20 15:45:26 2008 for SonicVisualiser by  doxygen 1.5.1