diff --git a/src/spek-fft.h b/src/spek-fft.h index 76595fa..4c848b8 100644 --- a/src/spek-fft.h +++ b/src/spek-fft.h @@ -3,6 +3,8 @@ #include #include +#include "spek-platform.h" + class FFTPlan; class FFT @@ -17,8 +19,16 @@ class FFTPlan public: FFTPlan(int nbits) : input_size(1 << nbits), output_size((1 << (nbits - 1)) + 1), - input(input_size), output(output_size) {} - virtual ~FFTPlan() {} + output(output_size) + { + // FFmpeg uses various assembly optimizations which expect + // input data to be aligned by up to 32 bytes (e.g. AVX) + this->input = (float*) spek_platform_aligned_alloc(32, sizeof(float) * input_size); + } + virtual ~FFTPlan() + { + spek_platform_aligned_free(this->input); + } int get_input_size() const { return this->input_size; } int get_output_size() const { return this->output_size; } @@ -30,11 +40,11 @@ public: virtual void execute() = 0; protected: - float *get_input() { return this->input.data(); } + float *get_input() { return this->input; } private: int input_size; int output_size; - std::vector input; + float *input; std::vector output; }; diff --git a/src/spek-platform.cc b/src/spek-platform.cc index 2800f15..ed67cc3 100644 --- a/src/spek-platform.cc +++ b/src/spek-platform.cc @@ -1,4 +1,6 @@ +#include #include +#include #ifdef OS_OSX #include @@ -50,3 +52,26 @@ double spek_platform_font_scale() return 1.0; #endif } + +void *spek_platform_aligned_alloc(size_t alignment, size_t size) +{ + void *ptr; +#ifdef OS_WIN + ptr = _aligned_malloc(size, alignment); + if (!ptr) + throw std::bad_alloc(); +#else + if (posix_memalign(&ptr, alignment, size) != 0) + throw std::bad_alloc(); +#endif + return ptr; +} + +void spek_platform_aligned_free(void *mem) +{ +#ifdef OS_WIN + _aligned_free(mem); +#else + free(mem); +#endif +} diff --git a/src/spek-platform.h b/src/spek-platform.h index ec94bdf..917d203 100644 --- a/src/spek-platform.h +++ b/src/spek-platform.h @@ -1,6 +1,7 @@ #pragma once #include +#include // Platform-specific initialisation code. void spek_platform_init(); @@ -14,3 +15,7 @@ bool spek_platform_can_change_language(); // Fonts are smaller on OSX. double spek_platform_font_scale(); + +// Allocating aligned memory is very dependent on platform or compiler. +void *spek_platform_aligned_alloc(size_t alignment, size_t size); +void spek_platform_aligned_free(void *mem);