* 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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user