# HG changeset patch # User Chris Cannam # Date 1487869526 0 # Node ID 9b52f1a952b5ea62810aedbf99e2ad884ea6e580 # Parent 0d45fff7ccd1177d7da1c3902665388bf2e34eac# Parent b061b9f8fca5b839057cbbbcea6f19a24bddb52a merge diff -r 0d45fff7ccd1 -r 9b52f1a952b5 base/LogRange.cpp --- a/base/LogRange.cpp Fri Feb 10 14:49:45 2017 +0000 +++ b/base/LogRange.cpp Thu Feb 23 17:05:26 2017 +0000 @@ -23,25 +23,30 @@ void LogRange::mapRange(double &min, double &max, double logthresh) { + // ensure that max > min: if (min > max) std::swap(min, max); if (max == min) max = min + 1; // cerr << "LogRange::mapRange: min = " << min << ", max = " << max << endl; - if (min >= 0.f) { + if (min >= 0.0) { - max = log10(max); // we know max != 0 + // and max > min, so we know min >= 0 and max > 0 + + max = log10(max); - if (min == 0.f) min = std::min(logthresh, max); + if (min == 0.0) min = std::min(logthresh, max); else min = log10(min); // cerr << "LogRange::mapRange: positive: min = " << min << ", max = " << max << endl; - } else if (max <= 0.f) { + } else if (max <= 0.0) { + + // and max > min, so we know min < 0 and max <= 0 - min = log10(-min); // we know min != 0 - - if (max == 0.f) max = std::min(logthresh, min); + min = log10(-min); + + if (max == 0.0) max = std::min(logthresh, min); else max = log10(-max); std::swap(min, max); @@ -64,7 +69,7 @@ double LogRange::map(double value, double thresh) { - if (value == 0.f) return thresh; + if (value == 0.0) return thresh; return log10(fabs(value)); } @@ -77,7 +82,7 @@ static double sd(const std::vector &values, int start, int n) { - double sum = 0.f, mean = 0.f, variance = 0.f; + double sum = 0.0, mean = 0.0, variance = 0.0; for (int i = 0; i < n; ++i) { sum += values[start + i]; } diff -r 0d45fff7ccd1 -r 9b52f1a952b5 base/test/TestColumnOp.h --- a/base/test/TestColumnOp.h Fri Feb 10 14:49:45 2017 +0000 +++ b/base/test/TestColumnOp.h Thu Feb 23 17:05:26 2017 +0000 @@ -55,7 +55,7 @@ QCOMPARE(C::applyGain({}, 1.0), Column()); Column c { 1, 2, 3, -4, 5, 6 }; Column actual(C::applyGain(c, 1.5)); - Column expected { 1.5, 3, 4.5, -6, 7.5, 9 }; + Column expected { 1.5f, 3, 4.5f, -6, 7.5f, 9 }; QCOMPARE(actual, expected); actual = C::applyGain(c, 1.0); QCOMPARE(actual, c); @@ -68,7 +68,7 @@ QCOMPARE(C::fftScale({}, 2.0), Column()); Column c { 1, 2, 3, -4, 5 }; Column actual(C::fftScale(c, 8)); - Column expected { 0.25, 0.5, 0.75, -1, 1.25 }; + Column expected { 0.25f, 0.5f, 0.75f, -1, 1.25f }; QCOMPARE(actual, expected); } @@ -79,33 +79,33 @@ } void isPeak_obvious() { - Column c { 0.4, 0.5, 0.3 }; + Column c { 0.4f, 0.5f, 0.3f }; QVERIFY(!C::isPeak(c, 0)); QVERIFY(C::isPeak(c, 1)); QVERIFY(!C::isPeak(c, 2)); } void isPeak_edges() { - Column c { 0.5, 0.4, 0.3 }; + Column c { 0.5f, 0.4f, 0.3f }; QVERIFY(C::isPeak(c, 0)); QVERIFY(!C::isPeak(c, 1)); QVERIFY(!C::isPeak(c, 2)); QVERIFY(!C::isPeak(c, 3)); QVERIFY(!C::isPeak(c, -1)); - c = { 1.4, 1.5 }; + c = { 1.4f, 1.5f }; QVERIFY(!C::isPeak(c, 0)); QVERIFY(C::isPeak(c, 1)); } void isPeak_flat() { - Column c { 0.0, 0.0, 0.0 }; + Column c { 0.0f, 0.0f, 0.0f }; QVERIFY(C::isPeak(c, 0)); QVERIFY(!C::isPeak(c, 1)); QVERIFY(!C::isPeak(c, 2)); } void isPeak_mixedSign() { - Column c { 0.4, -0.5, -0.3, -0.6, 0.1, -0.3 }; + Column c { 0.4f, -0.5f, -0.3f, -0.6f, 0.1f, -0.3f }; QVERIFY(C::isPeak(c, 0)); QVERIFY(!C::isPeak(c, 1)); QVERIFY(C::isPeak(c, 2)); @@ -115,12 +115,12 @@ } void isPeak_duplicate() { - Column c({ 0.5, 0.5, 0.4, 0.4 }); + Column c({ 0.5f, 0.5f, 0.4f, 0.4f }); QVERIFY(C::isPeak(c, 0)); QVERIFY(!C::isPeak(c, 1)); QVERIFY(!C::isPeak(c, 2)); QVERIFY(!C::isPeak(c, 3)); - c = { 0.4, 0.4, 0.5, 0.5 }; + c = { 0.4f, 0.4f, 0.5f, 0.5f }; QVERIFY(C::isPeak(c, 0)); // counterintuitive but necessary QVERIFY(!C::isPeak(c, 1)); QVERIFY(C::isPeak(c, 2)); @@ -129,10 +129,10 @@ void peakPick() { QCOMPARE(C::peakPick({}), Column()); - Column c({ 0.5, 0.5, 0.4, 0.4 }); - QCOMPARE(C::peakPick(c), Column({ 0.5, 0.0, 0.0, 0.0 })); - c = Column({ 0.4, -0.5, -0.3, -0.6, 0.1, -0.3 }); - QCOMPARE(C::peakPick(c), Column({ 0.4, 0.0, -0.3, 0.0, 0.1, 0.0 })); + Column c({ 0.5f, 0.5f, 0.4f, 0.4f }); + QCOMPARE(C::peakPick(c), Column({ 0.5f, 0.0f, 0.0f, 0.0f })); + c = Column({ 0.4f, -0.5f, -0.3f, -0.6f, 0.1f, -0.3f }); + QCOMPARE(C::peakPick(c), Column({ 0.4f, 0.0f, -0.3f, 0.0f, 0.1f, 0.0f })); } void normalize_null() { @@ -155,44 +155,44 @@ void normalize_sum1() { Column c { 1, 2, 4, 3 }; QCOMPARE(C::normalize(c, ColumnNormalization::Sum1), - Column({ 0.1, 0.2, 0.4, 0.3 })); + Column({ 0.1f, 0.2f, 0.4f, 0.3f })); } void normalize_sum1_mixedSign() { Column c { 1, 2, -4, -3 }; QCOMPARE(C::normalize(c, ColumnNormalization::Sum1), - Column({ 0.1, 0.2, -0.4, -0.3 })); + Column({ 0.1f, 0.2f, -0.4f, -0.3f })); } void normalize_max1() { Column c { 4, 3, 2, 1 }; QCOMPARE(C::normalize(c, ColumnNormalization::Max1), - Column({ 1.0, 0.75, 0.5, 0.25 })); + Column({ 1.0f, 0.75f, 0.5f, 0.25f })); } void normalize_max1_mixedSign() { Column c { -4, -3, 2, 1 }; QCOMPARE(C::normalize(c, ColumnNormalization::Max1), - Column({ -1.0, -0.75, 0.5, 0.25 })); + Column({ -1.0f, -0.75f, 0.5f, 0.25f })); } void normalize_hybrid() { // with max == 99, log10(max+1) == 2 so scale factor will be 2/99 Column c { 22, 44, 99, 66 }; QCOMPARE(C::normalize(c, ColumnNormalization::Hybrid), - Column({ 44.0/99.0, 88.0/99.0, 2.0, 132.0/99.0 })); + Column({ 44.0f/99.0f, 88.0f/99.0f, 2.0f, 132.0f/99.0f })); } void normalize_hybrid_mixedSign() { // with max == 99, log10(max+1) == 2 so scale factor will be 2/99 Column c { 22, 44, -99, -66 }; QCOMPARE(C::normalize(c, ColumnNormalization::Hybrid), - Column({ 44.0/99.0, 88.0/99.0, -2.0, -132.0/99.0 })); + Column({ 44.0f/99.0f, 88.0f/99.0f, -2.0f, -132.0f/99.0f })); } void distribute_simple() { Column in { 1, 2, 3 }; - BinMapping binfory { 0.0, 0.5, 1.0, 1.5, 2.0, 2.5 }; + BinMapping binfory { 0.0f, 0.5f, 1.0f, 1.5f, 2.0f, 2.5f }; Column expected { 1, 1, 2, 2, 3, 3 }; Column actual(C::distribute(in, 6, binfory, 0, false)); report(actual); @@ -201,7 +201,7 @@ void distribute_simple_interpolated() { Column in { 1, 2, 3 }; - BinMapping binfory { 0.0, 0.5, 1.0, 1.5, 2.0, 2.5 }; + BinMapping binfory { 0.0f, 0.5f, 1.0f, 1.5f, 2.0f, 2.5f }; // There is a 0.5-bin offset from the distribution you might // expect, because this corresponds visually to the way that // bin values are duplicated upwards in simple_distribution. @@ -209,7 +209,7 @@ // non-interpolated views retains the visual position of each // bin peak as somewhere in the middle of the scale area for // that bin. - Column expected { 1, 1, 1.5, 2, 2.5, 3 }; + Column expected { 1, 1, 1.5f, 2, 2.5f, 3 }; Column actual(C::distribute(in, 6, binfory, 0, true)); report(actual); QCOMPARE(actual, expected); @@ -217,7 +217,7 @@ void distribute_nonlinear() { Column in { 1, 2, 3 }; - BinMapping binfory { 0.0, 0.2, 0.5, 1.0, 2.0, 2.5 }; + BinMapping binfory { 0.0f, 0.2f, 0.5f, 1.0f, 2.0f, 2.5f }; Column expected { 1, 1, 1, 2, 3, 3 }; Column actual(C::distribute(in, 6, binfory, 0, false)); report(actual); @@ -227,7 +227,7 @@ void distribute_nonlinear_interpolated() { // See distribute_simple_interpolated Column in { 1, 2, 3 }; - BinMapping binfory { 0.0, 0.2, 0.5, 1.0, 2.0, 2.5 }; + BinMapping binfory { 0.0f, 0.2f, 0.5f, 1.0f, 2.0f, 2.5f }; Column expected { 1, 1, 1, 1.5, 2.5, 3 }; Column actual(C::distribute(in, 6, binfory, 0, true)); report(actual); @@ -236,7 +236,7 @@ void distribute_shrinking() { Column in { 4, 1, 2, 3, 5, 6 }; - BinMapping binfory { 0.0, 2.0, 4.0 }; + BinMapping binfory { 0.0f, 2.0f, 4.0f }; Column expected { 4, 3, 6 }; Column actual(C::distribute(in, 3, binfory, 0, false)); report(actual); @@ -247,7 +247,7 @@ // should be same as distribute_shrinking, we don't // interpolate when resizing down Column in { 4, 1, 2, 3, 5, 6 }; - BinMapping binfory { 0.0, 2.0, 4.0 }; + BinMapping binfory { 0.0f, 2.0f, 4.0f }; Column expected { 4, 3, 6 }; Column actual(C::distribute(in, 3, binfory, 0, true)); report(actual); @@ -259,13 +259,13 @@ // shrinking some bins but expanding others. See // distribute_simple_interpolated for note on 0.5 offset Column in { 4, 1, 2, 3, 5, 6 }; - BinMapping binfory { 0.0, 3.0, 4.0, 4.5 }; - Column expected { 4.0, 2.5, 4.0, 5.0 }; + BinMapping binfory { 0.0f, 3.0f, 4.0f, 4.5f }; + Column expected { 4.0f, 2.5f, 4.0f, 5.0f }; Column actual(C::distribute(in, 4, binfory, 0, true)); report(actual); QCOMPARE(actual, expected); - binfory = BinMapping { 0.5, 1.0, 2.0, 5.0 }; - expected = { 4.0, 2.5, 1.5, 5.5 }; + binfory = BinMapping { 0.5f, 1.0f, 2.0f, 5.0f }; + expected = { 4.0f, 2.5f, 1.5f, 5.5f }; actual = (C::distribute(in, 4, binfory, 0, true)); report(actual); QCOMPARE(actual, expected); diff -r 0d45fff7ccd1 -r 9b52f1a952b5 data/fileio/BZipFileDevice.cpp --- a/data/fileio/BZipFileDevice.cpp Fri Feb 10 14:49:45 2017 +0000 +++ b/data/fileio/BZipFileDevice.cpp Thu Feb 23 17:05:26 2017 +0000 @@ -21,6 +21,13 @@ #include "base/Debug.h" +// for dup: +#ifdef _MSC_VER +#include +#else +#include +#endif + BZipFileDevice::BZipFileDevice(QString fileName) : m_fileName(fileName), m_qfile(fileName), @@ -71,6 +78,27 @@ return false; } + // This is all going to be a bit silly. + // + // We open the file with QFile so as not to have to worry about locale + // support ourselves (especially on Windows). Then we get a fd from + // QFile and "convert" it to a FILE* using fdopen because that is what + // the bz2 library needs for reading and writing an already-open file. + // + // fdopen takes over the fd it is given, and will close it when fclose + // is called. (We must call fclose, because it's needed to avoid + // leaking the file stream structure.) + // + // But QFile will also close its fd, either when we call QFile::close + // or on destruction -- there doesn't seem to be a way to avoid that + // for a file that QFile opened. + // + // So we have to add an extra dup() in to the fdopen to avoid a double + // close. + // + // Note that bz2 will *not* fclose the FILE* it was passed, so we + // don't have a problem with calling both bzWriteClose and fclose. + if (mode & WriteOnly) { if (!m_qfile.open(QIODevice::WriteOnly)) { @@ -79,7 +107,7 @@ return false; } - m_file = fdopen(m_qfile.handle(), "wb"); + m_file = fdopen(dup(m_qfile.handle()), "wb"); if (!m_file) { setErrorString(tr("Failed to open file handle for writing")); m_qfile.close(); @@ -114,7 +142,7 @@ return false; } - m_file = fdopen(m_qfile.handle(), "rb"); + m_file = fdopen(dup(m_qfile.handle()), "rb"); if (!m_file) { setErrorString(tr("Failed to open file handle for reading")); m_ok = false; @@ -162,9 +190,9 @@ unsigned int in = 0, out = 0; BZ2_bzWriteClose(&bzError, m_bzFile, 0, &in, &out); // cerr << "Wrote bzip2 stream (in=" << in << ", out=" << out << ")" << endl; - if (bzError != BZ_OK) { - setErrorString(tr("bzip2 stream write close error")); - } + if (bzError != BZ_OK) { + setErrorString(tr("bzip2 stream write close error")); + } fclose(m_file); m_qfile.close(); m_bzFile = 0; diff -r 0d45fff7ccd1 -r 9b52f1a952b5 data/fileio/CodedAudioFileReader.cpp --- a/data/fileio/CodedAudioFileReader.cpp Fri Feb 10 14:49:45 2017 +0000 +++ b/data/fileio/CodedAudioFileReader.cpp Thu Feb 23 17:05:26 2017 +0000 @@ -525,8 +525,12 @@ ratio, true); - if (m_frameCount + out > sv_frame_t(double(m_fileFrameCount) * ratio)) { - out = sv_frame_t(double(m_fileFrameCount) * ratio) - m_frameCount; + SVDEBUG << "CodedAudioFileReader::pushBufferResampling: resampled padFrames to " << out << " frames" << endl; + + sv_frame_t expected = sv_frame_t(round(double(m_fileFrameCount) * ratio)); + if (m_frameCount + out > expected) { + out = expected - m_frameCount; + SVDEBUG << "CodedAudioFileReader::pushBufferResampling: clipping that to " << out << " to avoid producing more samples than desired" << endl; } pushBufferNonResampling(m_resampleBuffer, out); diff -r 0d45fff7ccd1 -r 9b52f1a952b5 data/fileio/OggVorbisFileReader.cpp --- a/data/fileio/OggVorbisFileReader.cpp Fri Feb 10 14:49:45 2017 +0000 +++ b/data/fileio/OggVorbisFileReader.cpp Thu Feb 23 17:05:26 2017 +0000 @@ -78,7 +78,7 @@ m_fileSize = m_qfile->size(); - m_ffile = fdopen(dup(m_qfile->handle()), "r"); + m_ffile = fdopen(dup(m_qfile->handle()), "rb"); if (!m_ffile) { m_error = QString("Failed to open file pointer for file %1").arg(m_path); SVDEBUG << "OggVorbisFileReader: " << m_error << endl; diff -r 0d45fff7ccd1 -r 9b52f1a952b5 data/model/Dense3DModelPeakCache.cpp --- a/data/model/Dense3DModelPeakCache.cpp Fri Feb 10 14:49:45 2017 +0000 +++ b/data/model/Dense3DModelPeakCache.cpp Thu Feb 23 17:05:26 2017 +0000 @@ -35,11 +35,11 @@ this, SLOT(sourceModelChanged())); connect(source, SIGNAL(aboutToBeDeleted()), this, SLOT(sourceModelAboutToBeDeleted())); - } Dense3DModelPeakCache::~Dense3DModelPeakCache() { + if (m_cache) m_cache->aboutToDelete(); delete m_cache; } diff -r 0d45fff7ccd1 -r 9b52f1a952b5 data/model/Model.cpp --- a/data/model/Model.cpp Fri Feb 10 14:49:45 2017 +0000 +++ b/data/model/Model.cpp Thu Feb 23 17:05:26 2017 +0000 @@ -27,9 +27,11 @@ // SVDEBUG << "Model::~Model(" << this << ")" << endl; if (!m_aboutToDelete) { - SVDEBUG << "NOTE: Model::~Model(" << this << ", \"" - << objectName() << "\"): Model deleted " - << "with no aboutToDelete notification" << endl; + SVDEBUG << "NOTE: Model(" << this << ", \"" + << objectName() << "\", type uri <" + << m_typeUri << ">)::~Model(): Model deleted " + << "with no aboutToDelete notification" + << endl; } if (m_alignment) { @@ -59,13 +61,16 @@ void Model::aboutToDelete() { -// cerr << "Model(" << this << ")::aboutToDelete()" << endl; +// SVDEBUG << "Model(" << this << ", \"" +// << objectName() << "\", type uri <" +// << m_typeUri << ">)::aboutToDelete()" << endl; if (m_aboutToDelete) { - cerr << "WARNING: Model(" << this << ", \"" - << objectName() << "\")::aboutToDelete: " - << "aboutToDelete called more than once for the same model" - << endl; + SVDEBUG << "WARNING: Model(" << this << ", \"" + << objectName() << "\", type uri <" + << m_typeUri << ">)::aboutToDelete: " + << "aboutToDelete called more than once for the same model" + << endl; } emit aboutToBeDeleted(); diff -r 0d45fff7ccd1 -r 9b52f1a952b5 data/osc/demoscript.sh --- a/data/osc/demoscript.sh Fri Feb 10 14:49:45 2017 +0000 +++ b/data/osc/demoscript.sh Thu Feb 23 17:05:26 2017 +0000 @@ -1,6 +1,6 @@ #!/bin/bash -audio=/share/music +audio=/data/Music preferred=$audio/free list=audiofiles.txt used=audiofiles-used.txt