[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>swiftingly
parent
038b0b8067
commit
6f6b5d6986
|
@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
- (void)postSampleRate:(double)sampleRate;
|
- (void)postSampleRate:(double)sampleRate;
|
||||||
- (void)postVisPCM:(const float *)inPCM amount:(int)amount;
|
- (void)postVisPCM:(const float *)inPCM amount:(int)amount;
|
||||||
- (double)readSampleRate;
|
- (double)readSampleRate;
|
||||||
- (void)copyVisPCM:(float *)outPCM visFFT:(float *)outFFT;
|
- (void)copyVisPCM:(float *)outPCM visFFT:(float *)outFFT latencyOffset:(double)latency;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
@synchronized(self) {
|
||||||
if(!sampleRate) {
|
if(!sampleRate) {
|
||||||
bzero(outPCM, 4096 * sizeof(float));
|
bzero(outPCM, 4096 * sizeof(float));
|
||||||
bzero(outFFT, 2048 * sizeof(float));
|
if(outFFT) {
|
||||||
|
bzero(outFFT, 2048 * sizeof(float));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int latencySamples = (int)(sampleRate * latency);
|
int latencySamples = (int)(sampleRate * (self->latency + latency));
|
||||||
|
if(latencySamples < 4096) latencySamples = 4096;
|
||||||
int readCursor = visAudioCursor - latencySamples;
|
int readCursor = visAudioCursor - latencySamples;
|
||||||
int samples = 4096;
|
int samples = 4096;
|
||||||
int samplesRead = 0;
|
int samplesRead = 0;
|
||||||
if(readCursor < 0)
|
while(readCursor < 0)
|
||||||
readCursor += visAudioSize;
|
readCursor += visAudioSize;
|
||||||
else if(readCursor >= visAudioSize)
|
while(readCursor >= visAudioSize)
|
||||||
readCursor -= visAudioSize;
|
readCursor -= visAudioSize;
|
||||||
while(samples > 0) {
|
while(samples > 0) {
|
||||||
int samplesToRead = (int)(visAudioSize - readCursor);
|
int samplesToRead = (int)(visAudioSize - readCursor);
|
||||||
|
@ -105,7 +113,9 @@ static VisualizationController *_sharedController = nil;
|
||||||
if(readCursor >= visAudioSize) readCursor -= visAudioSize;
|
if(readCursor >= visAudioSize) readCursor -= visAudioSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fft_calculate(outPCM, outFFT, 2048);
|
if(outFFT) {
|
||||||
|
fft_calculate(outPCM, outFFT, 2048);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -370,7 +370,7 @@ extern NSString *CogPlaybackDidStopNotficiation;
|
||||||
|
|
||||||
float visAudio[4096], visFFT[2048];
|
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_process(&_analyzer, [self->visController readSampleRate] / 2.0, 1, visFFT, 2048);
|
||||||
ddb_analyzer_tick(&_analyzer);
|
ddb_analyzer_tick(&_analyzer);
|
||||||
|
|
|
@ -273,7 +273,7 @@ extern NSString *CogPlaybackDidStopNotficiation;
|
||||||
|
|
||||||
float visAudio[4096], visFFT[2048];
|
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_process(&_analyzer, [self->visController readSampleRate] / 2.0, 1, visFFT, 2048);
|
||||||
ddb_analyzer_tick(&_analyzer);
|
ddb_analyzer_tick(&_analyzer);
|
||||||
|
|
Loading…
Reference in New Issue