diff --git a/src/system/Allocators.cpp b/src/system/Allocators.cpp new file mode 100644 index 0000000..6df8282 --- /dev/null +++ b/src/system/Allocators.cpp @@ -0,0 +1,26 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Rubber Band + An audio time-stretching and pitch-shifting library. + Copyright 2007-2009 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 "Allocators.h" + + +#include +using std::cerr; +using std::endl; + +namespace RubberBand { + + +} + diff --git a/src/system/Allocators.h b/src/system/Allocators.h new file mode 100644 index 0000000..092f3cc --- /dev/null +++ b/src/system/Allocators.h @@ -0,0 +1,150 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Rubber Band + An audio time-stretching and pitch-shifting library. + Copyright 2007-2009 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 _RUBBERBAND_ALLOCATORS_H_ +#define _RUBBERBAND_ALLOCATORS_H_ + +#include "VectorOps.h" + +#include // for std::bad_alloc +#include + +#ifndef HAVE_POSIX_MEMALIGN +#ifndef _WIN32 +#ifndef __APPLE__ +#ifndef LACK_POSIX_MEMALIGN +#define HAVE_POSIX_MEMALIGN +#endif +#endif +#endif +#endif + +#ifdef HAVE_POSIX_MEMALIGN +#include +#endif + +namespace RubberBand { + +template +T *allocate(size_t count) +{ + void *ptr = 0; +#ifdef HAVE_POSIX_MEMALIGN + if (posix_memalign(&ptr, 16, count * sizeof(T))) { + ptr = malloc(count * sizeof(T)); + } +#else +#ifdef _WIN32 + ptr = _aligned_malloc(count * sizeof(T), 16); +#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 +#endif + if (!ptr) throw(std::bad_alloc()); + return (T *)ptr; +} + + +template +T *allocate_and_zero(size_t count) +{ + T *ptr = allocate(count); + v_zero(ptr, count); + return ptr; +} + +template +void deallocate(T *ptr) +{ +#ifdef _WIN32 + if (ptr) _aligned_free((void *)ptr); +#else + if (ptr) free((void *)ptr); +#endif +} + + +template +T *reallocate(T *ptr, size_t oldcount, size_t count) +{ + T *newptr = 0; + try { + newptr = allocate(count); + } catch (std::bad_alloc) { + if (ptr) deallocate(ptr); + throw; + } + if (oldcount && ptr) { + v_copy(newptr, ptr, oldcount < count ? oldcount : count); + } + if (ptr) deallocate(ptr); + return newptr; +} + +template +T **allocate_channels(size_t channels, size_t count) +{ + T **ptr = allocate(channels); + for (size_t c = 0; c < channels; ++c) { + ptr[c] = allocate(count); + } + return ptr; +} + +template +T **allocate_and_zero_channels(size_t channels, size_t count) +{ + T **ptr = allocate(channels); + for (size_t c = 0; c < channels; ++c) { + ptr[c] = allocate_and_zero(count); + } + return ptr; +} + +template +void deallocate_channels(T **ptr, size_t channels) +{ + if (!ptr) return; + for (size_t c = 0; c < channels; ++c) { + deallocate(ptr[c]); + } + deallocate(ptr); +} + +template +T **reallocate_channels(T **ptr, + size_t oldchannels, size_t oldcount, + size_t channels, size_t count) +{ + T **newptr = 0; + try { + newptr = allocate_channels(channels, count); + } catch (std::bad_alloc) { + if (ptr) deallocate_channels(ptr); + throw; + } + if (oldcount && ptr) { + v_copy_channels(newptr, ptr, channels, oldcount < count ? oldcount : count); + } + if (ptr) deallocate_channels(ptr); + return newptr; +} + +} + +#endif + diff --git a/src/system/VectorOps.h b/src/system/VectorOps.h new file mode 100644 index 0000000..bce72c1 --- /dev/null +++ b/src/system/VectorOps.h @@ -0,0 +1,333 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Rubber Band + An audio time-stretching and pitch-shifting library. + Copyright 2007-2009 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 _RUBBERBAND_VECTOR_OPS_H_ +#define _RUBBERBAND_VECTOR_OPS_H_ + + + +#include +#include "sysutils.h" + +namespace RubberBand { + +// Note that all functions with a "target" vector have their arguments +// in the same order as memcpy and friends, i.e. target vector first. +// This is the reverse order from the IPP functions. + +// The aim here is to write the basic loops in such a way as to be +// auto-vectorizable by a sensible compiler (definitely gcc-4.3 on +// Linux, ideally also gcc-4.0 on OS/X), but also include calls to +// vector library implementations as alternatives (since not every +// platform will be using a sensible compiler, it isn't always +// possible to achieve the aim of writing loops in an +// auto-vectorizable manner, and some functions are more +// sophisticated). + +template +inline void v_zero(T *const R__ ptr, + const int count) +{ + const T value = T(0); + for (int i = 0; i < count; ++i) { + ptr[i] = value; + } +} + + +template +inline void v_zero_channels(T *const R__ *const R__ ptr, + const int channels, + const int count) +{ + for (int c = 0; c < channels; ++c) { + v_zero(ptr[c], count); + } +} + +template +inline void v_copy(T *const R__ dst, + const T *const R__ src, + const int count) +{ + for (int i = 0; i < count; ++i) { + dst[i] = src[i]; + } +} + + +template +inline void v_copy_channels(T *const R__ *const R__ dst, + const T *const R__ *const R__ src, + const int channels, + const int count) +{ + for (int c = 0; c < channels; ++c) { + v_copy(dst[c], src[c], count); + } +} + +template +inline void v_move(T *const R__ dst, + const T *const R__ src, + const int count) +{ + memmove(dst, src, count * sizeof(T)); +} + + +template +inline void v_convert(U *const R__ dst, + const T *const R__ src, + const int count) +{ + for (int i = 0; i < count; ++i) { + dst[i] = U(src[i]); + } +} + +template<> +inline void v_convert(float *const R__ dst, + const float *const R__ src, + const int count) +{ + v_copy(dst, src, count); +} +template<> +inline void v_convert(double *const R__ dst, + const double *const R__ src, + const int count) +{ + v_copy(dst, src, count); +} + + +template +inline void v_convert_channels(U *const R__ *const R__ dst, + const T *const R__ *const R__ src, + const int channels, + const int count) +{ + for (int c = 0; c < channels; ++c) { + v_convert(dst[c], src[c], count); + } +} + +template +inline void v_add(T *const R__ dst, + const T *const R__ src, + const int count) +{ + for (int i = 0; i < count; ++i) { + dst[i] += src[i]; + } +} + + +template +inline void v_add_channels(T *const R__ *const R__ dst, + const T *const R__ *const R__ src, + const int channels, const int count) +{ + for (int c = 0; c < channels; ++c) { + v_add(dst[c], src[c], count); + } +} + +template +inline void v_add_with_gain(T *const R__ dst, + const T *const R__ src, + const int count, + const G gain) +{ + for (int i = 0; i < count; ++i) { + dst[i] += src[i] * gain; + } +} + +template +inline void v_add_channels_with_gain(T *const R__ *const R__ dst, + const T *const R__ *const R__ src, + const int channels, + const int count, + const G gain) +{ + for (int c = 0; c < channels; ++c) { + v_add_with_gain(dst[c], src[c], count, gain); + } +} + +template +inline void v_subtract(T *const R__ dst, + const T *const R__ src, + const int count) +{ + for (int i = 0; i < count; ++i) { + dst[i] -= src[i]; + } +} + + +template +inline void v_scale(T *const R__ dst, + const G gain, + const int count) +{ + for (int i = 0; i < count; ++i) { + dst[i] *= gain; + } +} + + +template +inline void v_multiply(T *const R__ dst, + const T *const R__ src, + const int count) +{ + for (int i = 0; i < count; ++i) { + dst[i] *= src[i]; + } +} + + +template +inline void v_multiply(T *const R__ dst, + const T *const R__ src1, + const T *const R__ src2, + const int count) +{ + for (int i = 0; i < count; ++i) { + dst[i] = src1[i] * src2[i]; + } +} + +template +inline void v_divide(T *const R__ dst, + const T *const R__ src, + const int count) +{ + for (int i = 0; i < count; ++i) { + dst[i] /= src[i]; + } +} + + + +template +inline void v_multiply_and_add(T *const R__ dst, + const T *const R__ src1, + const T *const R__ src2, + const int count) +{ + for (int i = 0; i < count; ++i) { + dst[i] += src1[i] * src2[i]; + } +} + + +template +inline void v_log(T *const R__ dst, + const int count) +{ + for (int i = 0; i < count; ++i) { + dst[i] = log(dst[i]); + } +} + + +template +inline void v_exp(T *const R__ dst, + const int count) +{ + for (int i = 0; i < count; ++i) { + dst[i] = exp(dst[i]); + } +} + + +template +inline void v_sqrt(T *const R__ dst, + const int count) +{ + for (int i = 0; i < count; ++i) { + dst[i] = sqrt(dst[i]); + } +} + + +template +inline void v_square(T *const R__ dst, + const int count) +{ + for (int i = 0; i < count; ++i) { + dst[i] = dst[i] * dst[i]; + } +} + + +template +inline void v_abs(T *const R__ dst, + const int count) +{ + for (int i = 0; i < count; ++i) { + dst[i] = fabs(dst[i]); + } +} + + +template +inline void v_interleave(T *const R__ dst, + const T *const R__ *const R__ src, + const int channels, + const int count) +{ + int idx = 0; + for (int i = 0; i < count; ++i) { + for (int j = 0; j < channels; ++j) { + dst[idx++] = src[j][i]; + } + } +} + + +template +inline void v_deinterleave(T *const R__ *const R__ dst, + const T *const R__ src, + const int channels, + const int count) +{ + int idx = 0; + for (int i = 0; i < count; ++i) { + for (int j = 0; j < channels; ++j) { + dst[j][i] = src[idx++]; + } + } +} + + +template +inline void v_fftshift(T *const R__ ptr, + const int count) +{ + const int hs = count/2; + for (int i = 0; i < hs; ++i) { + T t = ptr[i]; + ptr[i] = ptr[i + hs]; + ptr[i + hs] = t; + } +} + +} + +#endif