Thin out qm-dsp code: no threading
authorRobin Gareus <robin@gareus.org>
Wed, 5 Oct 2016 22:51:32 +0000 (00:51 +0200)
committerRobin Gareus <robin@gareus.org>
Wed, 5 Oct 2016 22:58:20 +0000 (00:58 +0200)
libs/qm-dsp/README.txt
libs/qm-dsp/dsp/rateconversion/Resampler.cpp [deleted file]
libs/qm-dsp/dsp/rateconversion/Resampler.h [deleted file]
libs/qm-dsp/thread/AsynchronousTask.h [deleted file]
libs/qm-dsp/thread/BlockAllocator.h [deleted file]
libs/qm-dsp/thread/Thread.cpp [deleted file]
libs/qm-dsp/thread/Thread.h [deleted file]
libs/qm-dsp/wscript

index 6927c7a1b835c3dcdbe3298dcd6eca5a721a7669..03d8b04316a36be71298a2df7218f7a0e4c5c5af 100644 (file)
@@ -17,9 +17,6 @@ maths/pca.c -- Fionn Murtagh, from StatLib; with permission
 maths/Polyfit.h -- Allen Miller, David J Taylor and others; also for
 Delphi in the the JEDI Math Library, under the Mozilla Public License
 
-thread/BlockAllocator.h -- derived from FSB Allocator by Juha Nieminen,
-under BSD-style license
-
 See individual files for further authorship details.
 
 
diff --git a/libs/qm-dsp/dsp/rateconversion/Resampler.cpp b/libs/qm-dsp/dsp/rateconversion/Resampler.cpp
deleted file mode 100644 (file)
index f0598ca..0000000
+++ /dev/null
@@ -1,416 +0,0 @@
-/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
-/*
-    QM DSP Library
-
-    Centre for Digital Music, Queen Mary, University of London.
-    This file by Chris Cannam.
-
-    This program is free software; you can redistribute it and/or
-    modify it under the terms of the GNU General Public License as
-    published by the Free Software Foundation; either version 2 of the
-    License, or (at your option) any later version.  See the file
-    COPYING included with this distribution for more information.
-*/
-
-#include "Resampler.h"
-
-#include "maths/MathUtilities.h"
-#include "base/KaiserWindow.h"
-#include "base/SincWindow.h"
-#include "thread/Thread.h"
-
-#include <iostream>
-#include <vector>
-#include <map>
-#include <cassert>
-
-using std::vector;
-using std::map;
-using std::cerr;
-using std::endl;
-
-//#define DEBUG_RESAMPLER 1
-//#define DEBUG_RESAMPLER_VERBOSE 1
-
-Resampler::Resampler(int sourceRate, int targetRate) :
-    m_sourceRate(sourceRate),
-    m_targetRate(targetRate)
-{
-    initialise(100, 0.02);
-}
-
-Resampler::Resampler(int sourceRate, int targetRate, 
-                     double snr, double bandwidth) :
-    m_sourceRate(sourceRate),
-    m_targetRate(targetRate)
-{
-    initialise(snr, bandwidth);
-}
-
-Resampler::~Resampler()
-{
-    delete[] m_phaseData;
-}
-
-// peakToPole -> length -> beta -> window
-static map<double, map<int, map<double, vector<double> > > >
-knownFilters;
-
-static Mutex
-knownFilterMutex;
-
-void
-Resampler::initialise(double snr, double bandwidth)
-{
-    int higher = std::max(m_sourceRate, m_targetRate);
-    int lower = std::min(m_sourceRate, m_targetRate);
-
-    m_gcd = MathUtilities::gcd(lower, higher);
-    m_peakToPole = higher / m_gcd;
-
-    if (m_targetRate < m_sourceRate) {
-        // antialiasing filter, should be slightly below nyquist
-        m_peakToPole = m_peakToPole / (1.0 - bandwidth/2.0);
-    }
-
-    KaiserWindow::Parameters params =
-       KaiserWindow::parametersForBandwidth(snr, bandwidth, higher / m_gcd);
-
-    params.length =
-       (params.length % 2 == 0 ? params.length + 1 : params.length);
-    
-    params.length =
-        (params.length > 200001 ? 200001 : params.length);
-
-    m_filterLength = params.length;
-
-    vector<double> filter;
-    knownFilterMutex.lock();
-
-    if (knownFilters[m_peakToPole][m_filterLength].find(params.beta) ==
-       knownFilters[m_peakToPole][m_filterLength].end()) {
-
-       KaiserWindow kw(params);
-       SincWindow sw(m_filterLength, m_peakToPole * 2);
-
-       filter = vector<double>(m_filterLength, 0.0);
-       for (int i = 0; i < m_filterLength; ++i) filter[i] = 1.0;
-       sw.cut(filter.data());
-       kw.cut(filter.data());
-
-       knownFilters[m_peakToPole][m_filterLength][params.beta] = filter;
-    }
-
-    filter = knownFilters[m_peakToPole][m_filterLength][params.beta];
-    knownFilterMutex.unlock();
-
-    int inputSpacing = m_targetRate / m_gcd;
-    int outputSpacing = m_sourceRate / m_gcd;
-
-#ifdef DEBUG_RESAMPLER
-    cerr << "resample " << m_sourceRate << " -> " << m_targetRate
-         << ": inputSpacing " << inputSpacing << ", outputSpacing "
-         << outputSpacing << ": filter length " << m_filterLength
-         << endl;
-#endif
-
-    // Now we have a filter of (odd) length flen in which the lower
-    // sample rate corresponds to every n'th point and the higher rate
-    // to every m'th where n and m are higher and lower rates divided
-    // by their gcd respectively. So if x coordinates are on the same
-    // scale as our filter resolution, then source sample i is at i *
-    // (targetRate / gcd) and target sample j is at j * (sourceRate /
-    // gcd).
-
-    // To reconstruct a single target sample, we want a buffer (real
-    // or virtual) of flen values formed of source samples spaced at
-    // intervals of (targetRate / gcd), in our example case 3.  This
-    // is initially formed with the first sample at the filter peak.
-    //
-    // 0  0  0  0  a  0  0  b  0
-    //
-    // and of course we have our filter
-    //
-    // f1 f2 f3 f4 f5 f6 f7 f8 f9
-    //
-    // We take the sum of products of non-zero values from this buffer
-    // with corresponding values in the filter
-    //
-    // a * f5 + b * f8
-    //
-    // Then we drop (sourceRate / gcd) values, in our example case 4,
-    // from the start of the buffer and fill until it has flen values
-    // again
-    //
-    // a  0  0  b  0  0  c  0  0
-    //
-    // repeat to reconstruct the next target sample
-    //
-    // a * f1 + b * f4 + c * f7
-    //
-    // and so on.
-    //
-    // Above I said the buffer could be "real or virtual" -- ours is
-    // virtual. We don't actually store all the zero spacing values,
-    // except for padding at the start; normally we store only the
-    // values that actually came from the source stream, along with a
-    // phase value that tells us how many virtual zeroes there are at
-    // the start of the virtual buffer.  So the two examples above are
-    //
-    // 0 a b  [ with phase 1 ]
-    // a b c  [ with phase 0 ]
-    //
-    // Having thus broken down the buffer so that only the elements we
-    // need to multiply are present, we can also unzip the filter into
-    // every-nth-element subsets at each phase, allowing us to do the
-    // filter multiplication as a simply vector multiply. That is, rather
-    // than store
-    //
-    // f1 f2 f3 f4 f5 f6 f7 f8 f9
-    // 
-    // we store separately
-    //
-    // f1 f4 f7
-    // f2 f5 f8
-    // f3 f6 f9
-    //
-    // Each time we complete a multiply-and-sum, we need to work out
-    // how many (real) samples to drop from the start of our buffer,
-    // and how many to add at the end of it for the next multiply.  We
-    // know we want to drop enough real samples to move along by one
-    // computed output sample, which is our outputSpacing number of
-    // virtual buffer samples. Depending on the relationship between
-    // input and output spacings, this may mean dropping several real
-    // samples, one real sample, or none at all (and simply moving to
-    // a different "phase").
-
-    m_phaseData = new Phase[inputSpacing];
-
-    for (int phase = 0; phase < inputSpacing; ++phase) {
-
-       Phase p;
-
-       p.nextPhase = phase - outputSpacing;
-       while (p.nextPhase < 0) p.nextPhase += inputSpacing;
-       p.nextPhase %= inputSpacing;
-       
-       p.drop = int(ceil(std::max(0.0, double(outputSpacing - phase))
-                         / inputSpacing));
-
-       int filtZipLength = int(ceil(double(m_filterLength - phase)
-                                    / inputSpacing));
-
-       for (int i = 0; i < filtZipLength; ++i) {
-           p.filter.push_back(filter[i * inputSpacing + phase]);
-       }
-
-       m_phaseData[phase] = p;
-    }
-
-#ifdef DEBUG_RESAMPLER
-    int cp = 0;
-    int totDrop = 0;
-    for (int i = 0; i < inputSpacing; ++i) {
-        cerr << "phase = " << cp << ", drop = " << m_phaseData[cp].drop
-             << ", filter length = " << m_phaseData[cp].filter.size()
-             << ", next phase = " << m_phaseData[cp].nextPhase << endl;
-        totDrop += m_phaseData[cp].drop;
-        cp = m_phaseData[cp].nextPhase;
-    }
-    cerr << "total drop = " << totDrop << endl;
-#endif
-
-    // The May implementation of this uses a pull model -- we ask the
-    // resampler for a certain number of output samples, and it asks
-    // its source stream for as many as it needs to calculate
-    // those. This means (among other things) that the source stream
-    // can be asked for enough samples up-front to fill the buffer
-    // before the first output sample is generated.
-    // 
-    // In this implementation we're using a push model in which a
-    // certain number of source samples is provided and we're asked
-    // for as many output samples as that makes available. But we
-    // can't return any samples from the beginning until half the
-    // filter length has been provided as input. This means we must
-    // either return a very variable number of samples (none at all
-    // until the filter fills, then half the filter length at once) or
-    // else have a lengthy declared latency on the output. We do the
-    // latter. (What do other implementations do?)
-    //
-    // We want to make sure the first "real" sample will eventually be
-    // aligned with the centre sample in the filter (it's tidier, and
-    // easier to do diagnostic calculations that way). So we need to
-    // pick the initial phase and buffer fill accordingly.
-    // 
-    // Example: if the inputSpacing is 2, outputSpacing is 3, and
-    // filter length is 7,
-    // 
-    //    x     x     x     x     a     b     c ... input samples
-    // 0  1  2  3  4  5  6  7  8  9 10 11 12 13 ... 
-    //          i        j        k        l    ... output samples
-    // [--------|--------] <- filter with centre mark
-    //
-    // Let h be the index of the centre mark, here 3 (generally
-    // int(filterLength/2) for odd-length filters).
-    //
-    // The smallest n such that h + n * outputSpacing > filterLength
-    // is 2 (that is, ceil((filterLength - h) / outputSpacing)), and
-    // (h + 2 * outputSpacing) % inputSpacing == 1, so the initial
-    // phase is 1.
-    //
-    // To achieve our n, we need to pre-fill the "virtual" buffer with
-    // 4 zero samples: the x's above. This is int((h + n *
-    // outputSpacing) / inputSpacing). It's the phase that makes this
-    // buffer get dealt with in such a way as to give us an effective
-    // index for sample a of 9 rather than 8 or 10 or whatever.
-    //
-    // This gives us output latency of 2 (== n), i.e. output samples i
-    // and j will appear before the one in which input sample a is at
-    // the centre of the filter.
-
-    int h = int(m_filterLength / 2);
-    int n = ceil(double(m_filterLength - h) / outputSpacing);
-    
-    m_phase = (h + n * outputSpacing) % inputSpacing;
-
-    int fill = (h + n * outputSpacing) / inputSpacing;
-    
-    m_latency = n;
-
-    m_buffer = vector<double>(fill, 0);
-    m_bufferOrigin = 0;
-
-#ifdef DEBUG_RESAMPLER
-    cerr << "initial phase " << m_phase << " (as " << (m_filterLength/2) << " % " << inputSpacing << ")"
-             << ", latency " << m_latency << endl;
-#endif
-}
-
-double
-Resampler::reconstructOne()
-{
-    Phase &pd = m_phaseData[m_phase];
-    double v = 0.0;
-    int n = pd.filter.size();
-
-    assert(n + m_bufferOrigin <= (int)m_buffer.size());
-
-    const double *const __restrict__ buf = m_buffer.data() + m_bufferOrigin;
-    const double *const __restrict__ filt = pd.filter.data();
-
-    for (int i = 0; i < n; ++i) {
-       // NB gcc can only vectorize this with -ffast-math
-       v += buf[i] * filt[i];
-    }
-
-    m_bufferOrigin += pd.drop;
-    m_phase = pd.nextPhase;
-    return v;
-}
-
-int
-Resampler::process(const double *src, double *dst, int n)
-{
-    for (int i = 0; i < n; ++i) {
-       m_buffer.push_back(src[i]);
-    }
-
-    int maxout = int(ceil(double(n) * m_targetRate / m_sourceRate));
-    int outidx = 0;
-
-#ifdef DEBUG_RESAMPLER
-    cerr << "process: buf siz " << m_buffer.size() << " filt siz for phase " << m_phase << " " << m_phaseData[m_phase].filter.size() << endl;
-#endif
-
-    double scaleFactor = (double(m_targetRate) / m_gcd) / m_peakToPole;
-
-    while (outidx < maxout &&
-          m_buffer.size() >= m_phaseData[m_phase].filter.size() + m_bufferOrigin) {
-       dst[outidx] = scaleFactor * reconstructOne();
-       outidx++;
-    }
-
-    m_buffer = vector<double>(m_buffer.begin() + m_bufferOrigin, m_buffer.end());
-    m_bufferOrigin = 0;
-    
-    return outidx;
-}
-    
-vector<double>
-Resampler::process(const double *src, int n)
-{
-    int maxout = int(ceil(double(n) * m_targetRate / m_sourceRate));
-    vector<double> out(maxout, 0.0);
-    int got = process(src, out.data(), n);
-    assert(got <= maxout);
-    if (got < maxout) out.resize(got);
-    return out;
-}
-
-vector<double>
-Resampler::resample(int sourceRate, int targetRate, const double *data, int n)
-{
-    Resampler r(sourceRate, targetRate);
-
-    int latency = r.getLatency();
-
-    // latency is the output latency. We need to provide enough
-    // padding input samples at the end of input to guarantee at
-    // *least* the latency's worth of output samples. that is,
-
-    int inputPad = int(ceil((double(latency) * sourceRate) / targetRate));
-
-    // that means we are providing this much input in total:
-
-    int n1 = n + inputPad;
-
-    // and obtaining this much output in total:
-
-    int m1 = int(ceil((double(n1) * targetRate) / sourceRate));
-
-    // in order to return this much output to the user:
-
-    int m = int(ceil((double(n) * targetRate) / sourceRate));
-    
-#ifdef DEBUG_RESAMPLER
-    cerr << "n = " << n << ", sourceRate = " << sourceRate << ", targetRate = " << targetRate << ", m = " << m << ", latency = " << latency << ", inputPad = " << inputPad << ", m1 = " << m1 << ", n1 = " << n1 << ", n1 - n = " << n1 - n << endl;
-#endif
-
-    vector<double> pad(n1 - n, 0.0);
-    vector<double> out(m1 + 1, 0.0);
-
-    int gotData = r.process(data, out.data(), n);
-    int gotPad = r.process(pad.data(), out.data() + gotData, pad.size());
-    int got = gotData + gotPad;
-    
-#ifdef DEBUG_RESAMPLER
-    cerr << "resample: " << n << " in, " << pad.size() << " padding, " << got << " out (" << gotData << " data, " << gotPad << " padding, latency = " << latency << ")" << endl;
-#endif
-#ifdef DEBUG_RESAMPLER_VERBOSE
-    int printN = 50;
-    cerr << "first " << printN << " in:" << endl;
-    for (int i = 0; i < printN && i < n; ++i) {
-       if (i % 5 == 0) cerr << endl << i << "... ";
-        cerr << data[i] << " ";
-    }
-    cerr << endl;
-#endif
-
-    int toReturn = got - latency;
-    if (toReturn > m) toReturn = m;
-
-    vector<double> sliced(out.begin() + latency, 
-                         out.begin() + latency + toReturn);
-
-#ifdef DEBUG_RESAMPLER_VERBOSE
-    cerr << "first " << printN << " out (after latency compensation), length " << sliced.size() << ":";
-    for (int i = 0; i < printN && i < sliced.size(); ++i) {
-       if (i % 5 == 0) cerr << endl << i << "... ";
-       cerr << sliced[i] << " ";
-    }
-    cerr << endl;
-#endif
-
-    return sliced;
-}
-
diff --git a/libs/qm-dsp/dsp/rateconversion/Resampler.h b/libs/qm-dsp/dsp/rateconversion/Resampler.h
deleted file mode 100644 (file)
index 92c0169..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
-/*
-    QM DSP Library
-
-    Centre for Digital Music, Queen Mary, University of London.
-    This file by Chris Cannam.
-
-    This program is free software; you can redistribute it and/or
-    modify it under the terms of the GNU General Public License as
-    published by the Free Software Foundation; either version 2 of the
-    License, or (at your option) any later version.  See the file
-    COPYING included with this distribution for more information.
-*/
-
-#ifndef RESAMPLER_H
-#define RESAMPLER_H
-
-#include <vector>
-
-/**
- * Resampler resamples a stream from one integer sample rate to
- * another (arbitrary) rate, using a kaiser-windowed sinc filter.  The
- * results and performance are pretty similar to libraries such as
- * libsamplerate, though this implementation does not support
- * time-varying ratios (the ratio is fixed on construction).
- *
- * See also Decimator, which is faster and rougher but supports only
- * power-of-two downsampling factors.
- */
-class Resampler
-{
-public:
-    /**
-     * Construct a Resampler to resample from sourceRate to
-     * targetRate.
-     */
-    Resampler(int sourceRate, int targetRate);
-
-    /**
-     * Construct a Resampler to resample from sourceRate to
-     * targetRate, using the given filter parameters.
-     */
-    Resampler(int sourceRate, int targetRate,
-              double snr, double bandwidth);
-
-    virtual ~Resampler();
-
-    /**
-     * Read n input samples from src and write resampled data to
-     * dst. The return value is the number of samples written, which
-     * will be no more than ceil((n * targetRate) / sourceRate). The
-     * caller must ensure the dst buffer has enough space for the
-     * samples returned.
-     */
-    int process(const double *src, double *dst, int n);
-
-    /**
-     * Read n input samples from src and return resampled data by
-     * value.
-     */
-    std::vector<double> process(const double *src, int n);
-
-    /**
-     * Return the number of samples of latency at the output due by
-     * the filter. (That is, the output will be delayed by this number
-     * of samples relative to the input.)
-     */
-    int getLatency() const { return m_latency; }
-
-    /**
-     * Carry out a one-off resample of a single block of n
-     * samples. The output is latency-compensated.
-     */
-    static std::vector<double> resample
-    (int sourceRate, int targetRate, const double *data, int n);
-
-private:
-    int m_sourceRate;
-    int m_targetRate;
-    int m_gcd;
-    int m_filterLength;
-    int m_bufferLength;
-    int m_latency;
-    double m_peakToPole;
-    
-    struct Phase {
-        int nextPhase;
-        std::vector<double> filter;
-        int drop;
-    };
-
-    Phase *m_phaseData;
-    int m_phase;
-    std::vector<double> m_buffer;
-    int m_bufferOrigin;
-
-    void initialise(double, double);
-    double reconstructOne();
-};
-
-#endif
-    
diff --git a/libs/qm-dsp/thread/AsynchronousTask.h b/libs/qm-dsp/thread/AsynchronousTask.h
deleted file mode 100644 (file)
index d9d7d87..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
-
-/*
-    QM DSP Library
-
-    Centre for Digital Music, Queen Mary, University of London.
-    This file Copyright 2009 QMUL.
-*/
-
-#ifndef _ASYNCHRONOUS_TASK_H_
-#define _ASYNCHRONOUS_TASK_H_
-
-#include "Thread.h"
-
-#include <iostream>
-
-/**
- * AsynchronousTask provides a thread pattern implementation for
- * threads which are used to perform a series of similar operations in
- * parallel with other threads of the same type.
- *
- * For example, a thread used to calculate FFTs of a particular block
- * size in the context of a class that needs to calculate many block
- * sizes of FFT at once may be a candidate for an AsynchronousTask.
- *
- * The general use pattern is:
- *
- *   caller -> request thread A calculate something
- *   caller -> request thread B calculate something
- *   caller -> request thread C calculate something
- *   caller -> wait for threads A, B, and C
- *
- * Here threads A, B, and C may be AsynchronousTasks.  An important
- * point is that the caller must be prepared to block when waiting for
- * these threads to complete (i.e. they are started asynchronously,
- * but testing for completion is synchronous).
- */
-class AsynchronousTask : public Thread
-{
-public:
-    AsynchronousTask() :
-        m_todo("AsynchronousTask: task to perform"),
-        m_done("AsynchronousTask: task complete"),
-        m_inTask(false),
-        m_finishing(false)
-    {
-        start();
-    }
-    virtual ~AsynchronousTask()
-    {
-        m_todo.lock();
-        m_finishing = true;
-        m_todo.signal();
-        m_todo.unlock();
-        wait();
-    }
-
-    // Subclass must provide methods to request task and obtain
-    // results, which the caller calls.  The method that requests a
-    // new task should set up any internal state and call startTask(),
-    // which then calls back on the subclass implementation of
-    // performTask from within its work thread.  The method that
-    // obtains results should call awaitTask() and then return any
-    // results from internal state.
-
-protected:
-    void startTask() {
-        m_done.lock();
-        m_todo.lock();
-        m_inTask = true;
-        m_todo.signal();
-        m_todo.unlock();
-    }
-    void awaitTask() {
-        m_done.wait();
-        m_done.unlock();
-    }
-
-    virtual void performTask() = 0;
-    
-private:
-    virtual void run() {
-        m_todo.lock();
-        while (1) {
-            while (!m_inTask && !m_finishing) {
-                m_todo.wait();
-            }
-            if (m_finishing) {
-                m_done.lock();
-                m_inTask = false;
-                m_done.signal();
-                m_done.unlock();
-                break;
-            }
-            performTask();
-            m_done.lock();
-            m_inTask = false;
-            m_done.signal();
-            m_done.unlock();
-        }
-        m_todo.unlock();
-    }
-
-    Condition m_todo;
-    Condition m_done;
-    bool m_inTask;
-    bool m_finishing;
-};
-
-#endif
diff --git a/libs/qm-dsp/thread/BlockAllocator.h b/libs/qm-dsp/thread/BlockAllocator.h
deleted file mode 100644 (file)
index 5c311d6..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
-
-/*
-    QM DSP Library
-
-    Centre for Digital Music, Queen Mary, University of London.
-
-    This file is derived from the FSB Allocator by Juha Nieminen.  The
-    underlying method is unchanged, but the class has been refactored
-    to permit multiple separate allocators (e.g. one per thread)
-    rather than use a single global one (and to fit house style).
-
-Copyright (c) 2008 Juha Nieminen
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#ifndef _BLOCK_ALLOCATOR_H_
-#define _BLOCK_ALLOCATOR_H_
-
-#include <cstdlib>
-
-/**
- * BlockAllocator is a simple allocator for fixed-size (usually small)
- * chunks of memory.  The size of an element is specified in the
- * BlockAllocator constructor, and the functions allocate() and
- * deallocate() are used to obtain and release a single element at a
- * time.
- *
- * BlockAllocator may be an appropriate class to use in situations
- * involving a very large number of allocations and deallocations of
- * simple, identical objects across multiple threads (a hard situation
- * for a generic system malloc implementation to handle well).  Retain
- * one BlockAllocator per thread (the class itself is not
- * thread-safe), and ensure that each thread uses its own allocator
- * exclusively.
- *
- * BlockAllocator is based on Juha Nieminen's more general
- * FSBAllocator.
- */
-class BlockAllocator
-{
-public:
-    typedef std::size_t data_t;
-
-    BlockAllocator(int elementSize) : m_sz(elementSize) { }
-
-    void *
-    allocate()
-    {
-        if (m_freelist.empty()) {
-            m_freelist.push_back(m_blocks.data.size());
-            m_blocks.data.push_back(Block(this));
-        }
-
-        const data_t index = m_freelist.back();
-        Block &block = m_blocks.data[index];
-        void *retval = block.allocate(index);
-        if (block.isFull()) m_freelist.pop_back();
-
-        return retval;
-    }
-
-    void
-    deallocate(void *ptr)
-    {
-        if (!ptr) return;
-
-        data_t *unitPtr = (data_t *)ptr;
-        const data_t blockIndex = unitPtr[elementSizeInDataUnits()];
-        Block& block = m_blocks.data[blockIndex];
-
-        if (block.isFull()) m_freelist.push_back(blockIndex);
-        block.deallocate(unitPtr);
-    }
-
-private:
-    inline data_t elementsPerBlock() const {
-        return 512;
-    }
-    inline data_t dataSize() const {
-        return sizeof(data_t);
-    }
-    inline data_t elementSizeInDataUnits() const {
-        return (m_sz + (dataSize() - 1)) / dataSize();
-    }
-    inline data_t unitSizeInDataUnits() const {
-        return elementSizeInDataUnits() + 1;
-    }
-    inline data_t blockSizeInDataUnits() const {
-        return elementsPerBlock() * unitSizeInDataUnits();
-    }
-
-    class Block
-    {
-    public:
-        Block(BlockAllocator *a) :
-            m_a(a),
-            m_block(0),
-            m_firstFreeUnit(data_t(-1)),
-            m_allocated(0),
-            m_end(0)
-        {}
-
-        ~Block() {
-            delete[] m_block;
-        }
-
-        bool isFull() const {
-            return m_allocated == m_a->elementsPerBlock();
-        }
-
-        void clear() {
-            delete[] m_block;
-            m_block = 0;
-            m_firstFreeUnit = data_t(-1);
-        }
-
-        void *allocate(data_t index) {
-
-            if (m_firstFreeUnit == data_t(-1)) {
-
-                if (!m_block) {
-                    m_block = new data_t[m_a->blockSizeInDataUnits()];
-                    m_end = 0;
-                }
-
-                data_t *retval = m_block + m_end;
-                m_end += m_a->unitSizeInDataUnits();
-                retval[m_a->elementSizeInDataUnits()] = index;
-                ++m_allocated;
-                return retval;
-
-            } else {
-
-                data_t *retval = m_block + m_firstFreeUnit;
-                m_firstFreeUnit = *retval;
-                ++m_allocated;
-                return retval;
-            }
-        }
-
-        void deallocate(data_t *ptr) {
-
-            *ptr = m_firstFreeUnit;
-            m_firstFreeUnit = ptr - m_block;
-
-            if (--m_allocated == 0) clear();
-        }
-
-    private:
-        const BlockAllocator *m_a;
-        data_t *m_block;
-        data_t m_firstFreeUnit;
-        data_t m_allocated;
-        data_t m_end;
-    };
-
-    struct Blocks
-    {
-        std::vector<Block> data;
-
-        Blocks() {
-            data.reserve(1024);
-        }
-    };
-
-    const int m_sz;
-    Blocks m_blocks;
-    std::vector<data_t> m_freelist;
-};
-
-#endif
diff --git a/libs/qm-dsp/thread/Thread.cpp b/libs/qm-dsp/thread/Thread.cpp
deleted file mode 100644 (file)
index 85dcec3..0000000
+++ /dev/null
@@ -1,643 +0,0 @@
-/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
-
-/*
-    QM DSP Library
-
-    Centre for Digital Music, Queen Mary, University of London.
-    This file copyright Chris Cannam, used with permission.
-*/
-
-#include "Thread.h"
-
-#include <iostream>
-#include <cstdlib>
-
-#ifdef USE_PTHREADS
-#include <sys/time.h>
-#include <time.h>
-#endif
-
-using std::cerr;
-using std::endl;
-using std::string;
-
-#ifdef _WIN32
-
-Thread::Thread() :
-    m_id(0),
-    m_extant(false)
-{
-#ifdef DEBUG_THREAD
-    cerr << "THREAD DEBUG: Created thread object " << this << endl;
-#endif
-}
-
-Thread::~Thread()
-{
-#ifdef DEBUG_THREAD
-    cerr << "THREAD DEBUG: Destroying thread object " << this << ", id " << m_id << endl;
-#endif
-    if (m_extant) {
-        WaitForSingleObject(m_id, INFINITE);
-    }
-#ifdef DEBUG_THREAD
-    cerr << "THREAD DEBUG: Destroyed thread object " << this << endl;
-#endif
-}
-
-void
-Thread::start()
-{
-    m_id = CreateThread(NULL, 0, staticRun, this, 0, 0);
-    if (!m_id) {
-        cerr << "ERROR: thread creation failed" << endl;
-        exit(1);
-    } else {
-#ifdef DEBUG_THREAD
-        cerr << "THREAD DEBUG: Created thread " << m_id << " for thread object " << this << endl;
-#endif
-        m_extant = true;
-    }
-}    
-
-void 
-Thread::wait()
-{
-    if (m_extant) {
-#ifdef DEBUG_THREAD
-        cerr << "THREAD DEBUG: Waiting on thread " << m_id << " for thread object " << this << endl;
-#endif
-        WaitForSingleObject(m_id, INFINITE);
-#ifdef DEBUG_THREAD
-        cerr << "THREAD DEBUG: Waited on thread " << m_id << " for thread object " << this << endl;
-#endif
-        m_extant = false;
-    }
-}
-
-Thread::Id
-Thread::id()
-{
-    return m_id;
-}
-
-bool
-Thread::threadingAvailable()
-{
-    return true;
-}
-
-DWORD
-Thread::staticRun(LPVOID arg)
-{
-    Thread *thread = static_cast<Thread *>(arg);
-#ifdef DEBUG_THREAD
-    cerr << "THREAD DEBUG: " << (void *)GetCurrentThreadId() << ": Running thread " << thread->m_id << " for thread object " << thread << endl;
-#endif
-    thread->run();
-    return 0;
-}
-
-Mutex::Mutex()
-#ifndef NO_THREAD_CHECKS
-    :
-    m_lockedBy(-1)
-#endif
-{
-    m_mutex = CreateMutex(NULL, FALSE, NULL);
-#ifdef DEBUG_MUTEX
-    cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Initialised mutex " << &m_mutex << endl;
-#endif
-}
-
-Mutex::~Mutex()
-{
-#ifdef DEBUG_MUTEX
-    cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Destroying mutex " << &m_mutex << endl;
-#endif
-    CloseHandle(m_mutex);
-}
-
-void
-Mutex::lock()
-{
-#ifndef NO_THREAD_CHECKS
-    DWORD tid = GetCurrentThreadId();
-    if (m_lockedBy == tid) {
-        cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl;
-    }
-#endif
-#ifdef DEBUG_MUTEX
-    cerr << "MUTEX DEBUG: " << (void *)tid << ": Want to lock mutex " << &m_mutex << endl;
-#endif
-    WaitForSingleObject(m_mutex, INFINITE);
-#ifndef NO_THREAD_CHECKS
-    m_lockedBy = tid;
-#endif
-#ifdef DEBUG_MUTEX
-    cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << endl;
-#endif
-}
-
-void
-Mutex::unlock()
-{
-#ifndef NO_THREAD_CHECKS
-    DWORD tid = GetCurrentThreadId();
-    if (m_lockedBy != tid) {
-        cerr << "ERROR: Mutex " << &m_mutex << " not owned by unlocking thread" << endl;
-        return;
-    }
-#endif
-#ifdef DEBUG_MUTEX
-    cerr << "MUTEX DEBUG: " << (void *)tid << ": Unlocking mutex " << &m_mutex << endl;
-#endif
-#ifndef NO_THREAD_CHECKS
-    m_lockedBy = -1;
-#endif
-    ReleaseMutex(m_mutex);
-}
-
-bool
-Mutex::trylock()
-{
-#ifndef NO_THREAD_CHECKS
-    DWORD tid = GetCurrentThreadId();
-#endif
-    DWORD result = WaitForSingleObject(m_mutex, 0);
-    if (result == WAIT_TIMEOUT || result == WAIT_FAILED) {
-#ifdef DEBUG_MUTEX
-        cerr << "MUTEX DEBUG: " << (void *)tid << ": Mutex " << &m_mutex << " unavailable" << endl;
-#endif
-        return false;
-    } else {
-#ifndef NO_THREAD_CHECKS
-        m_lockedBy = tid;
-#endif
-#ifdef DEBUG_MUTEX
-        cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << " (from trylock)" << endl;
-#endif
-        return true;
-    }
-}
-
-Condition::Condition(string name) :
-    m_locked(false)
-#ifdef DEBUG_CONDITION
-    , m_name(name)
-#endif
-{
-    m_mutex = CreateMutex(NULL, FALSE, NULL);
-    m_condition = CreateEvent(NULL, FALSE, FALSE, NULL);
-#ifdef DEBUG_CONDITION
-    cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Initialised condition " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-}
-
-Condition::~Condition()
-{
-#ifdef DEBUG_CONDITION
-    cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Destroying condition " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-    if (m_locked) ReleaseMutex(m_mutex);
-    CloseHandle(m_condition);
-    CloseHandle(m_mutex);
-}
-
-void
-Condition::lock()
-{
-#ifdef DEBUG_CONDITION
-    cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Want to lock " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-    WaitForSingleObject(m_mutex, INFINITE);
-    m_locked = true;
-#ifdef DEBUG_CONDITION
-    cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Locked " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-}
-
-void
-Condition::unlock()
-{
-    if (!m_locked) {
-#ifdef DEBUG_CONDITION
-        cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Not locked " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-        return;
-    }
-#ifdef DEBUG_CONDITION
-    cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Unlocking " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-    m_locked = false;
-    ReleaseMutex(m_mutex);
-}
-
-void 
-Condition::wait(int us)
-{
-    if (us == 0) {
-
-#ifdef DEBUG_CONDITION
-        cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-        SignalObjectAndWait(m_mutex, m_condition, INFINITE, FALSE);
-        WaitForSingleObject(m_mutex, INFINITE);
-
-    } else {
-
-        DWORD ms = us / 1000;
-        if (us > 0 && ms == 0) ms = 1;
-    
-#ifdef DEBUG_CONDITION
-        cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Timed waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-        SignalObjectAndWait(m_mutex, m_condition, ms, FALSE);
-        WaitForSingleObject(m_mutex, INFINITE);
-    }
-
-#ifdef DEBUG_CONDITION
-    cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-
-    m_locked = true;
-}
-
-void
-Condition::signal()
-{
-#ifdef DEBUG_CONDITION
-    cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Signalling " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-    SetEvent(m_condition);
-}
-
-#else /* !_WIN32 */
-
-#ifdef USE_PTHREADS
-
-Thread::Thread() :
-    m_id(0),
-    m_extant(false)
-{
-#ifdef DEBUG_THREAD
-    cerr << "THREAD DEBUG: Created thread object " << this << endl;
-#endif
-}
-
-Thread::~Thread()
-{
-#ifdef DEBUG_THREAD
-    cerr << "THREAD DEBUG: Destroying thread object " << this << ", id " << m_id << endl;
-#endif
-    if (m_extant) {
-        pthread_join(m_id, 0);
-    }
-#ifdef DEBUG_THREAD
-    cerr << "THREAD DEBUG: Destroyed thread object " << this << endl;
-#endif
-}
-
-void
-Thread::start()
-{
-    if (pthread_create(&m_id, 0, staticRun, this)) {
-        cerr << "ERROR: thread creation failed" << endl;
-        exit(1);
-    } else {
-#ifdef DEBUG_THREAD
-        cerr << "THREAD DEBUG: Created thread " << m_id << " for thread object " << this << endl;
-#endif
-        m_extant = true;
-    }
-}    
-
-void 
-Thread::wait()
-{
-    if (m_extant) {
-#ifdef DEBUG_THREAD
-        cerr << "THREAD DEBUG: Waiting on thread " << m_id << " for thread object " << this << endl;
-#endif
-        pthread_join(m_id, 0);
-#ifdef DEBUG_THREAD
-        cerr << "THREAD DEBUG: Waited on thread " << m_id << " for thread object " << this << endl;
-#endif
-        m_extant = false;
-    }
-}
-
-Thread::Id
-Thread::id()
-{
-    return m_id;
-}
-
-bool
-Thread::threadingAvailable()
-{
-    return true;
-}
-
-void *
-Thread::staticRun(void *arg)
-{
-    Thread *thread = static_cast<Thread *>(arg);
-#ifdef DEBUG_THREAD
-    cerr << "THREAD DEBUG: " << (void *)pthread_self() << ": Running thread " << thread->m_id << " for thread object " << thread << endl;
-#endif
-    thread->run();
-    return 0;
-}
-
-Mutex::Mutex()
-#ifndef NO_THREAD_CHECKS
-    :
-    m_lockedBy(0),
-    m_locked(false)
-#endif
-{
-    pthread_mutex_init(&m_mutex, 0);
-#ifdef DEBUG_MUTEX
-    cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Initialised mutex " << &m_mutex << endl;
-#endif
-}
-
-Mutex::~Mutex()
-{
-#ifdef DEBUG_MUTEX
-    cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Destroying mutex " << &m_mutex << endl;
-#endif
-    pthread_mutex_destroy(&m_mutex);
-}
-
-void
-Mutex::lock()
-{
-#ifndef NO_THREAD_CHECKS
-    pthread_t tid = pthread_self();
-    if (m_locked && m_lockedBy == tid) {
-        cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl;
-    }
-#endif
-#ifdef DEBUG_MUTEX
-    cerr << "MUTEX DEBUG: " << (void *)tid << ": Want to lock mutex " << &m_mutex << endl;
-#endif
-    pthread_mutex_lock(&m_mutex);
-#ifndef NO_THREAD_CHECKS
-    m_lockedBy = tid;
-    m_locked = true;
-#endif
-#ifdef DEBUG_MUTEX
-    cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << endl;
-#endif
-}
-
-void
-Mutex::unlock()
-{
-#ifndef NO_THREAD_CHECKS
-    pthread_t tid = pthread_self();
-    if (!m_locked) {
-        cerr << "ERROR: Mutex " << &m_mutex << " not locked in unlock" << endl;
-        return;
-    } else if (m_lockedBy != tid) {
-        cerr << "ERROR: Mutex " << &m_mutex << " not owned by unlocking thread" << endl;
-        return;
-    }
-#endif
-#ifdef DEBUG_MUTEX
-    cerr << "MUTEX DEBUG: " << (void *)tid << ": Unlocking mutex " << &m_mutex << endl;
-#endif
-#ifndef NO_THREAD_CHECKS
-    m_locked = false;
-#endif
-    pthread_mutex_unlock(&m_mutex);
-}
-
-bool
-Mutex::trylock()
-{
-#ifndef NO_THREAD_CHECKS
-    pthread_t tid = pthread_self();
-#endif
-    if (pthread_mutex_trylock(&m_mutex)) {
-#ifdef DEBUG_MUTEX
-        cerr << "MUTEX DEBUG: " << (void *)tid << ": Mutex " << &m_mutex << " unavailable" << endl;
-#endif
-        return false;
-    } else {
-#ifndef NO_THREAD_CHECKS
-        m_lockedBy = tid;
-        m_locked = true;
-#endif
-#ifdef DEBUG_MUTEX
-        cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << " (from trylock)" << endl;
-#endif
-        return true;
-    }
-}
-
-Condition::Condition(string name) :
-    m_locked(false)
-#ifdef DEBUG_CONDITION
-    , m_name(name)
-#endif
-{
-    pthread_mutex_init(&m_mutex, 0);
-    pthread_cond_init(&m_condition, 0);
-#ifdef DEBUG_CONDITION
-    cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Initialised condition " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-}
-
-Condition::~Condition()
-{
-#ifdef DEBUG_CONDITION
-    cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Destroying condition " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-    if (m_locked) pthread_mutex_unlock(&m_mutex);
-    pthread_cond_destroy(&m_condition);
-    pthread_mutex_destroy(&m_mutex);
-}
-
-void
-Condition::lock()
-{
-#ifdef DEBUG_CONDITION
-    cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Want to lock " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-    pthread_mutex_lock(&m_mutex);
-    m_locked = true;
-#ifdef DEBUG_CONDITION
-    cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Locked " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-}
-
-void
-Condition::unlock()
-{
-    if (!m_locked) {
-#ifdef DEBUG_CONDITION
-        cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Not locked " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-        return;
-    }
-#ifdef DEBUG_CONDITION
-    cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Unlocking " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-    m_locked = false;
-    pthread_mutex_unlock(&m_mutex);
-}
-
-void 
-Condition::wait(int us)
-{
-    if (us == 0) {
-
-#ifdef DEBUG_CONDITION
-        cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-        pthread_cond_wait(&m_condition, &m_mutex);
-
-    } else {
-
-        struct timeval now;
-        gettimeofday(&now, 0);
-
-        now.tv_usec += us;
-        while (now.tv_usec > 1000000) {
-            now.tv_usec -= 1000000;
-            ++now.tv_sec;
-        }
-
-        struct timespec timeout;
-        timeout.tv_sec = now.tv_sec;
-        timeout.tv_nsec = now.tv_usec * 1000;
-    
-#ifdef DEBUG_CONDITION
-        cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Timed waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-        pthread_cond_timedwait(&m_condition, &m_mutex, &timeout);
-    }
-
-#ifdef DEBUG_CONDITION
-    cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-
-    m_locked = true;
-}
-
-void
-Condition::signal()
-{
-#ifdef DEBUG_CONDITION
-    cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Signalling " << &m_condition << " \"" << m_name << "\"" << endl;
-#endif
-    pthread_cond_signal(&m_condition);
-}
-
-#else /* !USE_PTHREADS */
-
-Thread::Thread()
-{
-}
-
-Thread::~Thread()
-{
-}
-
-void
-Thread::start()
-{
-    abort();
-}    
-
-void 
-Thread::wait()
-{
-    abort();
-}
-
-Thread::Id
-Thread::id()
-{
-    abort();
-}
-
-bool
-Thread::threadingAvailable()
-{
-    return false;
-}
-
-Mutex::Mutex()
-{
-}
-
-Mutex::~Mutex()
-{
-}
-
-void
-Mutex::lock()
-{
-    abort();
-}
-
-void
-Mutex::unlock()
-{
-    abort();
-}
-
-bool
-Mutex::trylock()
-{
-    abort();
-}
-
-Condition::Condition(const char *)
-{
-}
-
-Condition::~Condition()
-{
-}
-
-void
-Condition::lock()
-{
-    abort();
-}
-
-void 
-Condition::wait(int us)
-{
-    abort();
-}
-
-void
-Condition::signal()
-{
-    abort();
-}
-
-#endif /* !USE_PTHREADS */
-#endif /* !_WIN32 */
-
-MutexLocker::MutexLocker(Mutex *mutex) :
-    m_mutex(mutex)
-{
-    if (m_mutex) {
-        m_mutex->lock();
-    }
-}
-
-MutexLocker::~MutexLocker()
-{
-    if (m_mutex) {
-        m_mutex->unlock();
-    }
-}
-
diff --git a/libs/qm-dsp/thread/Thread.h b/libs/qm-dsp/thread/Thread.h
deleted file mode 100644 (file)
index cd5489d..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
-
-/*
-    QM DSP Library
-
-    Centre for Digital Music, Queen Mary, University of London.
-    This file copyright Chris Cannam, used with permission.
-*/
-
-#ifndef _THREAD_H_
-#define _THREAD_H_
-
-#ifdef _WIN32
-#include <windows.h>
-#else /* !_WIN32 */
-#define USE_PTHREADS
-#ifdef USE_PTHREADS
-#include <pthread.h>
-#else
-#error Must have either _WIN32 or USE_PTHREADS defined
-#endif /* USE_PTHREADS */
-#endif /* !_WIN32 */
-
-#include <string>
-
-//#define DEBUG_THREAD 1
-//#define DEBUG_MUTEX 1
-//#define DEBUG_CONDITION 1
-
-class Thread
-{
-public:
-#ifdef _WIN32
-    typedef HANDLE Id;
-#else
-#ifdef USE_PTHREADS
-    typedef pthread_t Id;
-#endif
-#endif
-
-    Thread();
-    virtual ~Thread();
-
-    Id id();
-
-    void start();
-    void wait();
-
-    static bool threadingAvailable();
-
-protected:
-    virtual void run() = 0;
-
-private:
-#ifdef _WIN32
-    HANDLE m_id;
-    bool m_extant;
-    static DWORD WINAPI staticRun(LPVOID lpParam);
-#else
-#ifdef USE_PTHREADS
-    pthread_t m_id;
-    bool m_extant;
-    static void *staticRun(void *);
-#endif
-#endif
-};
-
-class Mutex
-{
-public:
-    Mutex();
-    ~Mutex();
-
-    void lock();
-    void unlock();
-    bool trylock();
-
-private:
-#ifdef _WIN32
-    HANDLE m_mutex;
-#ifndef NO_THREAD_CHECKS
-    DWORD m_lockedBy;
-#endif
-#else
-#ifdef USE_PTHREADS
-    pthread_mutex_t m_mutex;
-#ifndef NO_THREAD_CHECKS
-    pthread_t m_lockedBy;
-    bool m_locked;
-#endif
-#endif
-#endif
-};
-
-class MutexLocker
-{
-public:
-    MutexLocker(Mutex *);
-    ~MutexLocker();
-
-private:
-    Mutex *m_mutex;
-};
-
-class Condition
-{
-public:
-    Condition(std::string name);
-    ~Condition();
-
-    // Condition bundles a pthread-style condition variable and mutex
-    // into one class.
-
-    // To wait on a condition, call lock(), test termination variables
-    // as appropriate, and then wait().  The condition will be
-    // unlocked for the duration of the wait() call, which will end
-    // when the condition is signalled.  The condition will be locked
-    // again when wait() returns.
-    //
-    // To signal a condition, call signal().  If the waiting thread
-    // will be performing tests between its own lock() and wait(),
-    // then the signalling thread should also lock() before it signals
-    // (and then unlock afterwards).  If the signalling thread always
-    // locks the mutex during signalling, then the waiting thread
-    // knows that signals will only happen during wait() and not be
-    // missed at other times.
-
-    void lock();
-    void unlock();
-    void wait(int us = 0);
-
-    void signal();
-    
-private:
-
-#ifdef _WIN32
-    HANDLE m_mutex;
-    HANDLE m_condition;
-    bool m_locked;
-#else
-#ifdef USE_PTHREADS
-    pthread_mutex_t m_mutex;
-    pthread_cond_t m_condition;
-    bool m_locked;
-#endif
-#endif
-#ifdef DEBUG_CONDITION
-    std::string m_name;
-#endif
-};
-
-#endif
index c4592750b202685aa7049cfb4baa4cbaee9eae40..11ea9c8011289fe524e03d97b21170fcb5ce410f 100644 (file)
@@ -49,7 +49,6 @@ def build(bld):
             dsp/phasevocoder/PhaseVocoder.cpp
             dsp/rateconversion/Decimator.cpp
             dsp/rateconversion/DecimatorB.cpp
-            dsp/rateconversion/Resampler.cpp
             dsp/rhythm/BeatSpectrum.cpp
             dsp/segmentation/cluster_melt.c
             dsp/segmentation/ClusterMeltSegmenter.cpp
@@ -73,7 +72,6 @@ def build(bld):
             maths/KLDivergence.cpp
             maths/MathUtilities.cpp
             maths/pca/pca.c
-            thread/Thread.cpp
             ext/kissfft/kiss_fft.c
             ext/kissfft/tools/kiss_fftr.c
     '''