Compare commits
No commits in common. "6340b0830837519b1f30297c8fab9456ac50260e" and "23334dd4525e9a0f34c6dcad13066378a164d9d7" have entirely different histories.
6340b08308
...
23334dd452
4 changed files with 49 additions and 72 deletions
|
@ -379,11 +379,6 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)seek:(id)sender {
|
- (IBAction)seek:(id)sender {
|
||||||
if(![sender respondsToSelector:@selector(doubleValue)]) {
|
|
||||||
ALog(@"Someone sent [PlaybackController seek:] a non-seekbar object: %@", sender);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
double time = [sender doubleValue];
|
double time = [sender doubleValue];
|
||||||
|
|
||||||
[audioPlayer performSelectorOnMainThread:@selector(seekToTimeBG:) withObjects:@(time), nil];
|
[audioPlayer performSelectorOnMainThread:@selector(seekToTimeBG:) withObjects:@(time), nil];
|
||||||
|
|
108
Audio/ThirdParty/deadbeef/fft_accelerate.c
vendored
108
Audio/ThirdParty/deadbeef/fft_accelerate.c
vendored
|
@ -24,28 +24,17 @@
|
||||||
#include "fft.h"
|
#include "fft.h"
|
||||||
#include <Accelerate/Accelerate.h>
|
#include <Accelerate/Accelerate.h>
|
||||||
|
|
||||||
// Some newer spectrum calculation methodology, adapted but not copied wholesale
|
static int _fft_size;
|
||||||
// Mostly about a dozen or two lines of Cocoa and vDSP code
|
static float *_input_real;
|
||||||
|
static float *_input_imaginary;
|
||||||
|
static float *_output_real;
|
||||||
|
static float *_output_imaginary;
|
||||||
|
static float *_hamming;
|
||||||
|
static float *_sq_mags;
|
||||||
|
|
||||||
// AudioSpectrum: A sample app using Audio Unit and vDSP
|
static vDSP_DFT_Setup _dft_setup;
|
||||||
// By Keijiro Takahashi, 2013, 2014
|
|
||||||
// https://github.com/keijiro/AudioSpectrum
|
|
||||||
|
|
||||||
struct SpectrumData
|
|
||||||
{
|
|
||||||
unsigned long length;
|
|
||||||
Float32 data[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
static int _fft_size = 0;
|
|
||||||
static vDSP_DFT_Setup _dftSetup = NULL;
|
|
||||||
static DSPSplitComplex _dftBuffer = {0};
|
|
||||||
static Float32 *_window = NULL;
|
|
||||||
|
|
||||||
static struct SpectrumData *_rawSpectrum = NULL;
|
|
||||||
|
|
||||||
// Apparently _mm_malloc is Intel-only on newer macOS targets, so use supported posix_memalign
|
// Apparently _mm_malloc is Intel-only on newer macOS targets, so use supported posix_memalign
|
||||||
// malloc() is allegedly aligned on macOS, but I don't know for sure
|
|
||||||
static void *_memalign_calloc(size_t count, size_t size, size_t align) {
|
static void *_memalign_calloc(size_t count, size_t size, size_t align) {
|
||||||
size *= count;
|
size *= count;
|
||||||
void *ret = NULL;
|
void *ret = NULL;
|
||||||
|
@ -61,66 +50,57 @@ _init_buffers(int fft_size) {
|
||||||
if(fft_size != _fft_size) {
|
if(fft_size != _fft_size) {
|
||||||
fft_free();
|
fft_free();
|
||||||
|
|
||||||
_dftSetup = vDSP_DFT_zrop_CreateSetup(NULL, fft_size * 2, vDSP_DFT_FORWARD);
|
_input_real = _memalign_calloc(fft_size * 2, sizeof(float), 16);
|
||||||
|
_input_imaginary = _memalign_calloc(fft_size * 2, sizeof(float), 16);
|
||||||
|
_hamming = _memalign_calloc(fft_size * 2, sizeof(float), 16);
|
||||||
|
_sq_mags = _memalign_calloc(fft_size, sizeof(float), 16);
|
||||||
|
_output_real = _memalign_calloc(fft_size * 2 + 1, sizeof(float), 16);
|
||||||
|
_output_imaginary = _memalign_calloc(fft_size * 2 + 1, sizeof(float), 16);
|
||||||
|
|
||||||
_dftBuffer.realp = _memalign_calloc(fft_size, sizeof(Float32), 16);
|
_dft_setup = vDSP_DFT_zop_CreateSetup(NULL, fft_size * 2, FFT_FORWARD);
|
||||||
_dftBuffer.imagp = _memalign_calloc(fft_size, sizeof(Float32), 16);
|
vDSP_hamm_window(_hamming, fft_size * 2, 0);
|
||||||
|
|
||||||
_window = _memalign_calloc(fft_size * 2, sizeof(Float32), 16);
|
|
||||||
vDSP_blkman_window(_window, fft_size * 2, 0);
|
|
||||||
|
|
||||||
Float32 normFactor = 2.0f / (fft_size * 2);
|
|
||||||
vDSP_vsmul(_window, 1, &normFactor, _window, 1, fft_size * 2);
|
|
||||||
|
|
||||||
_rawSpectrum = (struct SpectrumData *) _memalign_calloc(sizeof(struct SpectrumData) + sizeof(Float32) * fft_size, 1, 16);
|
|
||||||
_rawSpectrum->length = fft_size;
|
|
||||||
|
|
||||||
_fft_size = fft_size;
|
_fft_size = fft_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fft_calculate(const float *data, float *freq, int fft_size) {
|
void fft_calculate(const float *data, float *freq, int fft_size) {
|
||||||
|
int dft_size = fft_size * 2;
|
||||||
|
|
||||||
_init_buffers(fft_size);
|
_init_buffers(fft_size);
|
||||||
|
|
||||||
// Split the waveform
|
vDSP_vmul(data, 1, _hamming, 1, _input_real, 1, dft_size);
|
||||||
DSPSplitComplex dest = { _dftBuffer.realp, _dftBuffer.imagp };
|
|
||||||
vDSP_ctoz((const DSPComplex*)data, 2, &dest, 1, fft_size);
|
|
||||||
|
|
||||||
// Apply the window function
|
vDSP_DFT_Execute(_dft_setup, _input_real, _input_imaginary, _output_real, _output_imaginary);
|
||||||
vDSP_vmul(_dftBuffer.realp, 1, _window, 2, _dftBuffer.realp, 1, fft_size);
|
|
||||||
vDSP_vmul(_dftBuffer.imagp, 1, _window + 1, 2, _dftBuffer.imagp, 1, fft_size);
|
|
||||||
|
|
||||||
// DFT
|
DSPSplitComplex split_complex = {
|
||||||
vDSP_DFT_Execute(_dftSetup, _dftBuffer.realp, _dftBuffer.imagp, _dftBuffer.realp, _dftBuffer.imagp);
|
.realp = _output_real,
|
||||||
|
.imagp = _output_imaginary
|
||||||
|
};
|
||||||
|
vDSP_zvmags(&split_complex, 1, _sq_mags, 1, fft_size);
|
||||||
|
|
||||||
// Zero out the Nyquist value
|
int sq_count = fft_size;
|
||||||
_dftBuffer.imagp[0] = 0.0;
|
vvsqrtf(_sq_mags, _sq_mags, &sq_count);
|
||||||
|
|
||||||
// Calculate power spectrum
|
float mult = 2.f / fft_size;
|
||||||
Float32 *rawSpectrum = _rawSpectrum->data;
|
vDSP_vsmul(_sq_mags, 1, &mult, freq, 1, fft_size);
|
||||||
vDSP_zvmags(&_dftBuffer, 1, rawSpectrum, 1, fft_size);
|
|
||||||
|
|
||||||
// Add -128dB offset to avoid log(0)
|
|
||||||
float kZeroOffset = 1.5849e-13;
|
|
||||||
vDSP_vsadd(rawSpectrum, 1, &kZeroOffset, rawSpectrum, 1, fft_size);
|
|
||||||
|
|
||||||
// Convert power to decibel
|
|
||||||
float kZeroDB = 0.70710678118f; // 1/sqrt(2)
|
|
||||||
vDSP_vdbcon(rawSpectrum, 1, &kZeroDB, rawSpectrum, 1, fft_size, 0);
|
|
||||||
|
|
||||||
cblas_scopy(fft_size, rawSpectrum, 1, freq, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fft_free(void) {
|
void fft_free(void) {
|
||||||
free(_dftBuffer.realp);
|
free(_input_real);
|
||||||
free(_dftBuffer.imagp);
|
free(_input_imaginary);
|
||||||
free(_window);
|
free(_hamming);
|
||||||
free(_rawSpectrum);
|
free(_sq_mags);
|
||||||
if(_dftSetup != NULL) {
|
free(_output_real);
|
||||||
vDSP_DFT_DestroySetup(_dftSetup);
|
free(_output_imaginary);
|
||||||
|
if(_dft_setup != NULL) {
|
||||||
|
vDSP_DFT_DestroySetup(_dft_setup);
|
||||||
}
|
}
|
||||||
_dftBuffer.realp = NULL;
|
_input_real = NULL;
|
||||||
_dftBuffer.imagp = NULL;
|
_input_imaginary = NULL;
|
||||||
_window = NULL;
|
_hamming = NULL;
|
||||||
_rawSpectrum = NULL;
|
_sq_mags = NULL;
|
||||||
|
_dft_setup = NULL;
|
||||||
|
_output_real = NULL;
|
||||||
|
_output_imaginary = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,8 +130,10 @@ static VisualizationController *_sharedController = nil;
|
||||||
|
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
if(!sampleRate) {
|
if(!sampleRate) {
|
||||||
if(outPCM) bzero(outPCM, 4096 * sizeof(float));
|
bzero(outPCM, 4096 * sizeof(float));
|
||||||
if(outFFT) bzero(outFFT, 2048 * sizeof(float));
|
if(outFFT) {
|
||||||
|
bzero(outFFT, 2048 * sizeof(float));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int latencySamples = (int)(sampleRate * (self->latency + latency)) + 2048;
|
int latencySamples = (int)(sampleRate * (self->latency + latency)) + 2048;
|
||||||
|
|
2
Visualization/ThirdParty/deadbeef/analyzer.c
vendored
2
Visualization/ThirdParty/deadbeef/analyzer.c
vendored
|
@ -148,7 +148,7 @@ void ddb_analyzer_tick(ddb_analyzer_t *analyzer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float bound = -analyzer->db_lower_bound;
|
float bound = -analyzer->db_lower_bound;
|
||||||
float height = (norm_h + bound) / bound;
|
float height = (20 * log10(norm_h) + bound) / bound;
|
||||||
|
|
||||||
if(ch == 0) {
|
if(ch == 0) {
|
||||||
bar->height = height;
|
bar->height = height;
|
||||||
|
|
Loading…
Reference in a new issue