Visualization: Make latency animation smoother
Compensate for latency by incrementing an offset according to animation frame rate. Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
edbdc8d98e
commit
2e5140a321
4 changed files with 36 additions and 2 deletions
|
@ -15,12 +15,15 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
float *visAudio;
|
float *visAudio;
|
||||||
int visAudioCursor, visAudioSize;
|
int visAudioCursor, visAudioSize;
|
||||||
float *visAudioTemp;
|
float *visAudioTemp;
|
||||||
|
uint64_t visSamplesPosted;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (VisualizationController *)sharedController;
|
+ (VisualizationController *)sharedController;
|
||||||
|
|
||||||
- (void)postLatency:(double)latency;
|
- (void)postLatency:(double)latency;
|
||||||
|
|
||||||
|
- (UInt64)samplesPosted;
|
||||||
|
|
||||||
- (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;
|
||||||
|
|
|
@ -15,6 +15,7 @@ class VisualizationController : NSObject {
|
||||||
var visAudio: [Float] = Array(repeating: 0.0, count: 44100 * 45)
|
var visAudio: [Float] = Array(repeating: 0.0, count: 44100 * 45)
|
||||||
var visAudioCursor = 0
|
var visAudioCursor = 0
|
||||||
var visAudioSize = 0
|
var visAudioSize = 0
|
||||||
|
var visSamplesPosted: UInt64 = 0
|
||||||
|
|
||||||
private static var sharedVisualizationController: VisualizationController = {
|
private static var sharedVisualizationController: VisualizationController = {
|
||||||
let visualizationController = VisualizationController()
|
let visualizationController = VisualizationController()
|
||||||
|
@ -34,6 +35,7 @@ class VisualizationController : NSObject {
|
||||||
for i in 0..<amount {
|
for i in 0..<amount {
|
||||||
self.visAudio[i] = 0
|
self.visAudio[i] = 0
|
||||||
}
|
}
|
||||||
|
self.visSamplesPosted = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +43,11 @@ class VisualizationController : NSObject {
|
||||||
func postLatency(_ latency: Double) {
|
func postLatency(_ latency: Double) {
|
||||||
self.latency = latency
|
self.latency = latency
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
func samplesPosted() -> UInt64 {
|
||||||
|
return self.visSamplesPosted
|
||||||
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
func postSampleRate(_ sampleRate: Double) {
|
func postSampleRate(_ sampleRate: Double) {
|
||||||
|
@ -67,6 +74,7 @@ class VisualizationController : NSObject {
|
||||||
}
|
}
|
||||||
self.visAudioCursor = j
|
self.visAudioCursor = j
|
||||||
self.latency += Double(amount) / self.sampleRate
|
self.latency += Double(amount) / self.sampleRate
|
||||||
|
self.visSamplesPosted += UInt64(amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +109,9 @@ class VisualizationController : NSObject {
|
||||||
// Offset latency so the target sample is in the center of the window
|
// Offset latency so the target sample is in the center of the window
|
||||||
let latencySamples = (Int)((self.latency + latencyOffset) * self.sampleRate) + 2048
|
let latencySamples = (Int)((self.latency + latencyOffset) * self.sampleRate) + 2048
|
||||||
var samplesToDo = 4096;
|
var samplesToDo = 4096;
|
||||||
|
if(latencySamples < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(latencySamples < 4096) {
|
if(latencySamples < 4096) {
|
||||||
// Latency can sometimes dip below this threshold
|
// Latency can sometimes dip below this threshold
|
||||||
samplesToDo = latencySamples;
|
samplesToDo = latencySamples;
|
||||||
|
|
|
@ -42,6 +42,9 @@ extern NSString *CogPlaybackDidStopNotificiation;
|
||||||
ddb_analyzer_draw_data_t _draw_data;
|
ddb_analyzer_draw_data_t _draw_data;
|
||||||
|
|
||||||
float visAudio[4096], visFFT[2048];
|
float visAudio[4096], visFFT[2048];
|
||||||
|
|
||||||
|
UInt64 visSamplesLastPosted;
|
||||||
|
double visLatencyOffset;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -234,6 +237,7 @@ extern NSString *CogPlaybackDidStopNotificiation;
|
||||||
|
|
||||||
- (void)timerRun:(NSTimer *)timer {
|
- (void)timerRun:(NSTimer *)timer {
|
||||||
[self repaint];
|
[self repaint];
|
||||||
|
visLatencyOffset -= 1.0 / 60.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)colorsDidChange:(NSNotification *)notification {
|
- (void)colorsDidChange:(NSNotification *)notification {
|
||||||
|
@ -403,7 +407,13 @@ extern NSString *CogPlaybackDidStopNotificiation;
|
||||||
_analyzer.view_width = self.bounds.size.width;
|
_analyzer.view_width = self.bounds.size.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
[self->visController copyVisPCM:&visAudio[0] visFFT:&visFFT[0] latencyOffset:0];
|
UInt64 samplesPosted = [self->visController samplesPosted];
|
||||||
|
if (samplesPosted != visSamplesLastPosted) {
|
||||||
|
visSamplesLastPosted = samplesPosted;
|
||||||
|
visLatencyOffset = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[self->visController copyVisPCM:&visAudio[0] visFFT:&visFFT[0] latencyOffset:visLatencyOffset];
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -45,6 +45,9 @@ extern NSString *CogPlaybackDidStopNotificiation;
|
||||||
SCNVector3 cameraEulerAngles3d;
|
SCNVector3 cameraEulerAngles3d;
|
||||||
|
|
||||||
float visAudio[4096], visFFT[2048];
|
float visAudio[4096], visFFT[2048];
|
||||||
|
|
||||||
|
UInt64 visSamplesLastPosted;
|
||||||
|
double visLatencyOffset;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -307,7 +310,13 @@ extern NSString *CogPlaybackDidStopNotificiation;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
[self->visController copyVisPCM:&visAudio[0] visFFT:&visFFT[0] latencyOffset:0];
|
UInt64 samplesPosted = [self->visController samplesPosted];
|
||||||
|
if (samplesPosted != visSamplesLastPosted) {
|
||||||
|
visSamplesLastPosted = samplesPosted;
|
||||||
|
visLatencyOffset = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[self->visController copyVisPCM:&visAudio[0] visFFT:&visFFT[0] latencyOffset:visLatencyOffset];
|
||||||
|
|
||||||
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);
|
||||||
|
@ -333,6 +342,7 @@ extern NSString *CogPlaybackDidStopNotificiation;
|
||||||
|
|
||||||
- (void)timerRun:(NSTimer *)timer {
|
- (void)timerRun:(NSTimer *)timer {
|
||||||
[self repaint];
|
[self repaint];
|
||||||
|
visLatencyOffset -= 1.0 / 60.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)startPlayback {
|
- (void)startPlayback {
|
||||||
|
|
Loading…
Reference in a new issue