[Visualization System] Change API a bit

Now the API makes both PCM and FFT data optional, and will do nothing if
neither are requested. Also, it now supports a latency offset in seconds
with floating point precision. The two built-in visualizations currently
request zero larency. Increasing the latency asks for even older samples
while specifying a negative count requests samples from the "future"
relative to what the listener is hearing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
lastfm
Christopher Snowhill 2022-06-26 05:36:20 -07:00
parent 8068a506b9
commit db181bde4d
4 changed files with 19 additions and 9 deletions

View File

@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)postSampleRate:(double)sampleRate;
- (void)postVisPCM:(const float *)inPCM amount:(int)amount;
- (double)readSampleRate;
- (void)copyVisPCM:(float *)outPCM visFFT:(float *)outFFT;
- (void)copyVisPCM:(float *)outPCM visFFT:(float *)outFFT latencyOffset:(double)latency;
@end

View File

@ -80,20 +80,28 @@ static VisualizationController *_sharedController = nil;
}
}
- (void)copyVisPCM:(float *)outPCM visFFT:(float *)outFFT {
- (void)copyVisPCM:(float *)outPCM visFFT:(float *)outFFT latencyOffset:(double)latency {
if(!outPCM && !outFFT) return;
float tempPCM[4096];
if(!outPCM) outPCM = &tempPCM[0];
@synchronized(self) {
if(!sampleRate) {
bzero(outPCM, 4096 * sizeof(float));
bzero(outFFT, 2048 * sizeof(float));
if(outFFT) {
bzero(outFFT, 2048 * sizeof(float));
}
return;
}
int latencySamples = (int)(sampleRate * latency);
int latencySamples = (int)(sampleRate * (self->latency + latency));
if(latencySamples < 4096) latencySamples = 4096;
int readCursor = visAudioCursor - latencySamples;
int samples = 4096;
int samplesRead = 0;
if(readCursor < 0)
while(readCursor < 0)
readCursor += visAudioSize;
else if(readCursor >= visAudioSize)
while(readCursor >= visAudioSize)
readCursor -= visAudioSize;
while(samples > 0) {
int samplesToRead = (int)(visAudioSize - readCursor);
@ -105,7 +113,9 @@ static VisualizationController *_sharedController = nil;
if(readCursor >= visAudioSize) readCursor -= visAudioSize;
}
}
fft_calculate(outPCM, outFFT, 2048);
if(outFFT) {
fft_calculate(outPCM, outFFT, 2048);
}
}
@end

View File

@ -370,7 +370,7 @@ extern NSString *CogPlaybackDidStopNotficiation;
float visAudio[4096], visFFT[2048];
[self->visController copyVisPCM:&visAudio[0] visFFT:&visFFT[0]];
[self->visController copyVisPCM:&visAudio[0] visFFT:&visFFT[0] latencyOffset:0];
ddb_analyzer_process(&_analyzer, [self->visController readSampleRate] / 2.0, 1, visFFT, 2048);
ddb_analyzer_tick(&_analyzer);

View File

@ -273,7 +273,7 @@ extern NSString *CogPlaybackDidStopNotficiation;
float visAudio[4096], visFFT[2048];
[self->visController copyVisPCM:&visAudio[0] visFFT:&visFFT[0]];
[self->visController copyVisPCM:&visAudio[0] visFFT:&visFFT[0] latencyOffset:0];
ddb_analyzer_process(&_analyzer, [self->visController readSampleRate] / 2.0, 1, visFFT, 2048);
ddb_analyzer_tick(&_analyzer);