* Allow building on Win32 with MinGW

This commit is contained in:
Chris Cannam
2007-11-28 11:50:47 +00:00
parent 09dadc239a
commit b3c4ce045f
12 changed files with 358 additions and 24 deletions

View File

@@ -1,6 +1,6 @@
CXX := @CXX@
CXXFLAGS := @CXXFLAGS@ @SRC_CFLAGS@ @SNDFILE_CFLAGS@ @FFTW_CFLAGS@ @Vamp_CFLAGS@ -Irubberband -Isrc $(CXXFLAGS)
CXXFLAGS := @CXXFLAGS@ @SRC_CFLAGS@ @SNDFILE_CFLAGS@ @FFTW_CFLAGS@ @Vamp_CFLAGS@ -Irubberband -Isrc $(OPTFLAGS)
LDFLAGS := @LDFLAGS@ -lpthread $(LDFLAGS)
LIBRARY_LIBS := @SRC_LIBS@ @FFTW_LIBS@

View File

@@ -157,14 +157,19 @@ public:
if (save) {
switch (type) {
#ifndef FFTW_DOUBLE_ONLY
#ifdef FFTW_DOUBLE_ONLY
case 'f': break;
#else
case 'f': fftwf_export_wisdom_to_file(f); break;
#endif
case 'd': fftw_export_wisdom_to_file(f); break;
default: break;
}
} else {
switch (type) {
#ifndef FFTW_DOUBLE_ONLY
#ifdef FFTW_DOUBLE_ONLY
case 'f': break;
#else
case 'f': fftwf_import_wisdom_from_file(f); break;
#endif
case 'd': fftw_import_wisdom_from_file(f); break;
@@ -341,7 +346,6 @@ D_FFTW::m_extantd = 0;
Mutex
D_FFTW::m_extantMutex;
#endif
class D_Cross : public FFTImpl
{
@@ -613,8 +617,8 @@ FFT::FFT(unsigned int size)
break;
default:
// std::cerr << "FFT::FFT(" << size << "): using built-in implementation"
// << std::endl;
std::cerr << "FFT::FFT(" << size << "): WARNING: using slow built-in implementation"
<< std::endl;
d = new D_Cross(size);
break;
}

View File

@@ -16,14 +16,22 @@
#define _RUBBERBAND_RINGBUFFER_H_
#include <sys/types.h>
#ifndef _WIN32
#include <sys/mman.h>
#endif
#include "Scavenger.h"
//#define DEBUG_RINGBUFFER 1
#ifdef _WIN32
#define MLOCK(a,b) 1
#define MUNLOCK(a,b) 1
#else
#define MLOCK(a,b) ::mlock(a,b)
#define MUNLOCK(a,b) ::munlock(a,b)
#endif
#ifdef DEBUG_RINGBUFFER
#include <iostream>

View File

@@ -18,9 +18,11 @@
#include <vector>
#include <list>
#include <sys/time.h>
#include <pthread.h>
#include <iostream>
#include "Thread.h"
#include "sysutils.h"
namespace RubberBand {
/**
@@ -62,7 +64,7 @@ protected:
typedef std::list<T *> ObjectList;
ObjectList m_excess;
int m_lastExcess;
pthread_mutex_t m_excessMutex;
Mutex m_excessMutex;
void pushExcess(T *);
void clearExcess(int);
@@ -93,7 +95,6 @@ Scavenger<T>::Scavenger(int sec, int defaultObjectListSize) :
m_claimed(0),
m_scavenged(0)
{
pthread_mutex_init(&m_excessMutex, 0);
}
template <typename T>
@@ -171,26 +172,26 @@ template <typename T>
void
Scavenger<T>::pushExcess(T *t)
{
pthread_mutex_lock(&m_excessMutex);
m_excessMutex.lock();
m_excess.push_back(t);
struct timeval tv;
(void)gettimeofday(&tv, 0);
m_lastExcess = tv.tv_sec;
pthread_mutex_unlock(&m_excessMutex);
m_excessMutex.unlock();
}
template <typename T>
void
Scavenger<T>::clearExcess(int sec)
{
pthread_mutex_lock(&m_excessMutex);
m_excessMutex.lock();
for (typename ObjectList::iterator i = m_excess.begin();
i != m_excess.end(); ++i) {
delete *i;
}
m_excess.clear();
m_lastExcess = sec;
pthread_mutex_unlock(&m_excessMutex);
m_excessMutex.unlock();
}
}

View File

@@ -242,7 +242,7 @@ RubberBandStretcher::Impl::processChunkForChannel(size_t c,
if (m_debugLevel > 2) {
if (phaseReset) {
for (int i = 0; i < 10; ++i) {
cd.accumulator[i] = ((drand48() * 2 - 1.0) > 0 ? 1 : -1);
cd.accumulator[i] = 1.2f - (i % 3) * 1.2f;
}
}
}

View File

@@ -30,6 +30,245 @@ using std::string;
namespace RubberBand
{
#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() :
m_locked(false)
{
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()
{
if (m_locked) {
cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl;
}
#ifdef DEBUG_MUTEX
cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Want to lock mutex " << &m_mutex << endl;
#endif
WaitForSingleObject(m_mutex, INFINITE);
m_locked = true;
#ifdef DEBUG_MUTEX
cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Locked mutex " << &m_mutex << endl;
#endif
}
void
Mutex::unlock()
{
#ifdef DEBUG_MUTEX
cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Unlocking mutex " << &m_mutex << endl;
#endif
m_locked = false;
ReleaseMutex(m_mutex);
}
bool
Mutex::trylock()
{
DWORD result = WaitForSingleObject(m_mutex, 0);
if (result == WAIT_TIMEOUT || result == WAIT_FAILED) {
#ifdef DEBUG_MUTEX
cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Mutex " << &m_mutex << " unavailable" << endl;
#endif
return false;
} else {
m_locked = true;
#ifdef DEBUG_MUTEX
cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Locked mutex " << &m_mutex << " (from trylock)" << endl;
#endif
return true;
}
}
Condition::Condition(string name) :
m_name(name),
m_locked(false)
{
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()
{
if (m_locked) {
#ifdef DEBUG_CONDITION
cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Already locked " << &m_condition << " \"" << m_name << "\"" << endl;
#endif
return;
}
#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 (!m_locked) lock();
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);
}
ReleaseMutex(m_mutex);
#ifdef DEBUG_CONDITION
cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl;
#endif
m_locked = false;
}
void
Condition::signal()
{
#ifdef DEBUG_CONDITION
cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Signalling " << &m_condition << " \"" << m_name << "\"" << endl;
#endif
SetEvent(m_condition);
}
#else /* !_WIN32 */
Thread::Thread() :
m_id(0),
@@ -98,7 +337,7 @@ Thread::threadingAvailable()
void *
Thread::staticRun(void *arg)
{
Thread *thread = (Thread *)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
@@ -106,7 +345,8 @@ Thread::staticRun(void *arg)
return 0;
}
Mutex::Mutex()
Mutex::Mutex() :
m_locked(false)
{
pthread_mutex_init(&m_mutex, 0);
#ifdef DEBUG_MUTEX
@@ -166,10 +406,10 @@ Mutex::trylock()
}
Condition::Condition(string name) :
m_locked(false),
m_name(name)
{
pthread_mutex_init(&m_mutex, 0);
m_locked = false;
pthread_cond_init(&m_condition, 0);
#ifdef DEBUG_CONDITION
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Initialised condition " << &m_condition << " \"" << m_name << "\"" << endl;
@@ -254,10 +494,11 @@ Condition::wait(int us)
pthread_cond_timedwait(&m_condition, &m_mutex, &timeout);
}
pthread_mutex_unlock(&m_mutex);
#ifdef DEBUG_CONDITION
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl;
#endif
pthread_mutex_unlock(&m_mutex);
m_locked = false;
}
@@ -270,6 +511,7 @@ Condition::signal()
pthread_cond_signal(&m_condition);
}
#endif /* !_WIN32 */
MutexLocker::MutexLocker(Mutex *mutex) :
m_mutex(mutex)

View File

@@ -15,7 +15,11 @@
#ifndef _RUBBERBAND_THREAD_H_
#define _RUBBERBAND_THREAD_H_
#ifdef _WIN32
#include <windows.h>
#else /* !_WIN32 */
#include <pthread.h>
#endif /* !_WIN32 */
#include <string>
@@ -25,7 +29,11 @@ namespace RubberBand
class Thread
{
public:
#ifdef _WIN32
typedef HANDLE Id;
#else
typedef pthread_t Id;
#endif
Thread();
virtual ~Thread();
@@ -41,9 +49,15 @@ protected:
virtual void run() = 0;
private:
#ifdef _WIN32
HANDLE m_id;
bool m_extant;
static DWORD WINAPI staticRun(LPVOID lpParam);
#else
pthread_t m_id;
bool m_extant;
static void *staticRun(void *);
#endif
};
class Mutex
@@ -57,8 +71,13 @@ public:
bool trylock();
private:
#ifdef _WIN32
HANDLE m_mutex;
bool m_locked;
#else
pthread_mutex_t m_mutex;
bool m_locked;
#endif
};
class MutexLocker
@@ -77,16 +96,34 @@ public:
Condition(std::string name);
~Condition();
// To wait on a condition, either simply call wait(), or call
// lock() and then wait() (perhaps testing some state in between).
// To signal a condition, call signal().
// Although any thread may signal on a given condition, only one
// thread should ever wait on any given condition object --
// otherwise there will be a race conditions in the logic that
// avoids the thread code having to track whether the condition's
// mutex is locked or not. If that is your requirement, this
// Condition wrapper is not for you.
void lock();
void unlock();
void wait(int us = 0);
void signal();
private:
#ifdef _WIN32
HANDLE m_mutex;
bool m_locked;
HANDLE m_condition;
std::string m_name;
#else
pthread_mutex_t m_mutex;
bool m_locked;
pthread_cond_t m_condition;
std::string m_name;
#endif
};
}

View File

@@ -15,7 +15,7 @@
#ifndef _RUBBERBAND_PITCH_SHIFTER_H_
#define _RUBBERBAND_PITCH_SHIFTER_H_
#include <ladspa.h>
#include "ladspa.h"
#include "RingBuffer.h"

View File

@@ -12,8 +12,6 @@
COPYING included with this distribution for more information.
*/
#include <ladspa.h>
#include "RubberBandPitchShifter.h"
#include <stdio.h>

View File

@@ -19,6 +19,7 @@
#include <cmath>
#include <sys/time.h>
#include <time.h>
#include "sysutils.h"
#include <getopt.h>
@@ -28,6 +29,11 @@
using namespace std;
using namespace RubberBand;
#ifdef _WIN32
using RubberBand::gettimeofday;
using RubberBand::usleep;
#endif
int main(int argc, char **argv)
{
int c;
@@ -251,7 +257,10 @@ int main(int argc, char **argv)
frequencyshift *= pow(2.0, pitchshift / 12);
}
struct timeval tv;
#ifdef _WIN32
RubberBand::
#endif
timeval tv;
(void)gettimeofday(&tv, 0);
RubberBandStretcher::setDefaultDebugLevel(debug);
@@ -446,7 +455,10 @@ int main(int argc, char **argv)
cerr << "input peak: " << inpeak << "; output peak " << outpeak << "; gain " << (inpeak > 0 ? outpeak/inpeak : 1) << endl;
cerr << "input rms: " << inmean << "; output rms " << outmean << "; gain " << (inmean > 0 ? outmean/inmean : 1) << endl;
struct timeval etv;
#ifdef _WIN32
RubberBand::
#endif
timeval etv;
(void)gettimeofday(&etv, 0);
etv.tv_sec -= tv.tv_sec;

View File

@@ -15,6 +15,7 @@
#include "sysutils.h"
#ifdef _WIN32
#include <windows.h>
#else /* !_WIN32 */
#ifdef __APPLE__
#include <sys/sysctl.h>
@@ -24,6 +25,8 @@
#endif /* !__APPLE__, !_WIN32 */
#endif /* !_WIN32 */
#include <iostream>
namespace RubberBand {
bool
@@ -36,7 +39,9 @@ system_is_multiprocessor()
#ifdef _WIN32
//...
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
count = sysinfo.dwNumberOfProcessors;
#else /* !_WIN32 */
#ifdef __APPLE__
@@ -74,6 +79,27 @@ system_is_multiprocessor()
return mp;
}
#ifdef _WIN32
void gettimeofday(struct timeval *tv, void *tz)
{
union {
long long ns100;
FILETIME ft;
} now;
::GetSystemTimeAsFileTime(&now.ft);
tv->tv_usec = (long)((now.ns100 / 10LL) % 1000000LL);
tv->tv_sec = (long)((now.ns100 - 116444736000000000LL) / 10000000LL);
}
void usleep(unsigned long usec)
{
::Sleep(usec == 0 ? 0 : usec < 1000 ? 1 : usec / 1000);
}
#endif
}

View File

@@ -19,6 +19,12 @@ namespace RubberBand {
extern bool system_is_multiprocessor();
#ifdef _WIN32
struct timeval { long tv_sec; long tv_usec; };
void gettimeofday(struct timeval *p, void *tz);
void usleep(unsigned long);
#endif
}
#endif