* Add centre-focus option (mid/side processing)

* Simplify RingBuffer and add explicit memory locks
* Fix hang with certain unfortunate combinations of parameters
* Bump version to 1.7
This commit is contained in:
Chris Cannam
2011-11-25 11:11:59 +00:00
parent 9c52352c24
commit c26dc1dc88
19 changed files with 588 additions and 373 deletions

View File

@@ -34,6 +34,7 @@
#include <sys/mman.h>
#endif
namespace RubberBand {
template <typename T>
@@ -44,13 +45,15 @@ T *allocate(size_t count)
if (posix_memalign(&ptr, 16, count * sizeof(T))) {
ptr = malloc(count * sizeof(T));
}
#else
#else
// Note that malloc always aligns to 16 byte boundaries on OS/X,
// so we don't need posix_memalign there (which is fortunate,
// since it doesn't exist)
ptr = malloc(count * sizeof(T));
#endif
if (!ptr) throw(std::bad_alloc());
#endif
if (!ptr) {
throw(std::bad_alloc());
}
return (T *)ptr;
}
@@ -74,13 +77,7 @@ void deallocate(T *ptr)
template <typename T>
T *reallocate(T *ptr, size_t oldcount, size_t count)
{
T *newptr = 0;
try {
newptr = allocate<T>(count);
} catch (std::bad_alloc) {
if (ptr) deallocate<T>(ptr);
throw;
}
T *newptr = allocate<T>(count);
if (oldcount && ptr) {
v_copy(newptr, ptr, oldcount < count ? oldcount : count);
}
@@ -141,13 +138,7 @@ T **reallocate_channels(T **ptr,
size_t oldchannels, size_t oldcount,
size_t channels, size_t count)
{
T **newptr = 0;
try {
newptr = allocate_channels<T>(channels, count);
} catch (std::bad_alloc) {
if (ptr) deallocate_channels<T>(ptr, channels);
throw;
}
T **newptr = allocate_channels<T>(channels, count);
if (oldcount && ptr) {
v_copy_channels(newptr, ptr, channels, oldcount < count ? oldcount : count);
}
@@ -160,13 +151,7 @@ T **reallocate_and_zero_extend_channels(T **ptr,
size_t oldchannels, size_t oldcount,
size_t channels, size_t count)
{
T **newptr = 0;
try {
newptr = allocate_and_zero_channels<T>(channels, count);
} catch (std::bad_alloc) {
if (ptr) deallocate_channels<T>(ptr, channels);
throw;
}
T **newptr = allocate_and_zero_channels<T>(channels, count);
if (oldcount && ptr) {
v_copy_channels(newptr, ptr, channels, oldcount < count ? oldcount : count);
}

View File

@@ -83,6 +83,7 @@ inline void v_copy_channels(T *const R__ *const R__ dst,
}
}
// src and dst alias by definition, so not restricted
template<typename T>
inline void v_move(T *const dst,
const T *const src,
@@ -139,6 +140,16 @@ inline void v_add(T *const R__ dst,
}
}
template<typename T>
inline void v_add(T *const R__ dst,
const T value,
const int count)
{
for (int i = 0; i < count; ++i) {
dst[i] += value;
}
}
template<typename T>
inline void v_add_channels(T *const R__ *const R__ dst,
@@ -241,6 +252,17 @@ inline void v_multiply_and_add(T *const R__ dst,
}
template<typename T>
inline T v_sum(const T *const R__ src,
const int count)
{
T result = T();
for (int i = 0; i < count; ++i) {
result += src[i];
}
return result;
}
template<typename T>
inline void v_log(T *const R__ dst,
const int count)

View File

@@ -23,6 +23,8 @@
#include <unistd.h>
#ifdef __APPLE__
#include <sys/sysctl.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#else /* !__APPLE__, !_WIN32 */
#include <stdio.h>
#include <string.h>
@@ -53,17 +55,17 @@ system_get_platform_tag()
#else /* !_WIN32 */
#ifdef __APPLE__
return "osx";
#else /* !__APPLE__ */
#else
#ifdef __LINUX__
if (sizeof(long) == 8) {
return "linux64";
} else {
return "linux";
}
#else /* !__LINUX__ */
#else
return "posix";
#endif /* !__LINUX__ */
#endif /* !__APPLE__ */
#endif
#endif
#endif /* !_WIN32 */
}
@@ -146,6 +148,27 @@ void gettimeofday(struct timeval *tv, void *tz)
tv->tv_sec = (long)((now.ns100 - 116444736000000000LL) / 10000000LL);
}
void clock_gettime(int, struct timespec *ts)
{
static LARGE_INTEGER cps;
static bool haveCps = false;
if (!haveCps) {
QueryPerformanceFrequency(&cps);
haveCps = true;
}
LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);
//!!! check this
ts->tv_sec = counter.QuadPart / cps.QuadPart;
double sub = counter.QuadPart % cps.QuadPart;
sub = sub / cps.QuadPart;
sub = sub * 1000000000.;
ts->tv_nsec = long(sub) ;
}
void usleep(unsigned long usec)
{
::Sleep(usec == 0 ? 0 : usec < 1000 ? 1 : usec / 1000);
@@ -153,6 +176,20 @@ void usleep(unsigned long usec)
#endif
#ifdef __APPLE__
void clock_gettime(int, struct timespec *ts)
{
uint64_t t = mach_absolute_time();
static mach_timebase_info_data_t sTimebaseInfo;
if (sTimebaseInfo.denom == 0) (void)mach_timebase_info(&sTimebaseInfo);
uint64_t n = t * sTimebaseInfo.numer / sTimebaseInfo.denom;
ts->tv_sec = n / 1000000000;
ts->tv_nsec = n % 1000000000;
}
#endif
void system_specific_initialise()
{
}
@@ -163,7 +200,7 @@ void system_specific_application_initialise()
ProcessStatus
GetProcessStatus(int pid)
system_get_process_status(int pid)
{
#ifdef _WIN32
HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
@@ -186,6 +223,24 @@ GetProcessStatus(int pid)
#endif
}
#ifdef _WIN32
void system_memorybarrier()
{
MemoryBarrier();
}
#else /* !_WIN32 */
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
// Not required
#else
#include <pthread.h>
void system_memorybarrier()
{
pthread_mutex_t dummy = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&dummy);
pthread_mutex_unlock(&dummy);
}
#endif
#endif
}

View File

@@ -42,17 +42,28 @@ extern bool system_is_multiprocessor();
extern void system_specific_initialise();
extern void system_specific_application_initialise();
enum ProcessStatus { ProcessRunning, ProcessNotRunning, UnknownProcessStatus };
extern ProcessStatus system_get_process_status(int pid);
#ifdef __APPLE__
struct timespec { long tv_sec; long tv_nsec; };
void clock_gettime(int clk_id, struct timespec *p);
#define CLOCK_MONOTONIC 1
#endif
#ifdef _WIN32
struct timeval { long tv_sec; long tv_usec; };
void gettimeofday(struct timeval *p, void *tz);
struct timespec { long tv_sec; long tv_nsec; };
// always uses GetPerformanceCounter, does not check whether it's valid or not:
void clock_gettime(int clk_id, struct timespec *p);
#define CLOCK_MONOTONIC 1
#endif
enum ProcessStatus { ProcessRunning, ProcessNotRunning, UnknownProcessStatus };
extern ProcessStatus GetProcessStatus(int pid);
inline double mod(double x, double y) { return x - (y * floor(x / y)); }
inline float modf(float x, float y) { return x - (y * float(floor(x / y))); }
@@ -73,6 +84,11 @@ inline float princargf(float a) { return modf(a + (float)M_PI, -2.f * (float)M_P
#define MUNLOCK(a,b) 1
#define MUNLOCK_SAMPLEBLOCK(a) 1
namespace RubberBand {
extern void system_memorybarrier();
}
#define MBARRIER() RubberBand::system_memorybarrier()
#define DLOPEN(a,b) LoadLibrary((a).toStdWString().c_str())
#define DLSYM(a,b) GetProcAddress((HINSTANCE)(a),(b))
#define DLCLOSE(a) FreeLibrary((HINSTANCE)(a))
@@ -88,6 +104,20 @@ inline float princargf(float a) { return modf(a + (float)M_PI, -2.f * (float)M_P
#define MUNLOCK(a,b) (::munlock((char *)(a),(b)) ? (::perror("munlock failed"), 0) : 0)
#define MUNLOCK_SAMPLEBLOCK(a) do { if (!(a).empty()) { const float &b = *(a).begin(); MUNLOCK(&b, (a).capacity() * sizeof(float)); } } while(0);
#ifdef __APPLE__
#include <libkern/OSAtomic.h>
#define MBARRIER() OSMemoryBarrier()
#else
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
#define MBARRIER() __sync_synchronize()
#else
namespace RubberBand {
extern void system_memorybarrier();
}
#define MBARRIER() ::RubberBand::system_memorybarrier()
#endif
#endif
#define DLOPEN(a,b) dlopen((a).toStdString().c_str(),(b))
#define DLSYM(a,b) dlsym((a),(b))
#define DLCLOSE(a) dlclose((a))