-
Notifications
You must be signed in to change notification settings - Fork 1
/
SPAnalyzerSampleView.mm
131 lines (96 loc) · 4.25 KB
/
SPAnalyzerSampleView.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#import "SPAnalyzerWindowController.h"
#import "SPAnalyzerSampleView.h"
@implementation SPAnalyzerSampleView
// ----------------------------------------------------------------------------
- (id)initWithFrame:(NSRect)frame
// ----------------------------------------------------------------------------
{
self = [super initWithFrame:frame];
if (self)
{
}
return self;
}
// ----------------------------------------------------------------------------
- (BOOL) isOpaque
// ----------------------------------------------------------------------------
{
return YES;
}
// ----------------------------------------------------------------------------
- (void)drawRect:(NSRect)rect
// ----------------------------------------------------------------------------
{
if (![SPAnalyzerWindowController isInitialized])
return;
// Draws from cache if possible, otherwise calls drawContent:
[super drawRect:rect];
[[SPAnalyzerWindowController sharedInstance] drawCursorInRect:rect];
}
// ----------------------------------------------------------------------------
- (void)drawContent:(NSRect)rect
// ----------------------------------------------------------------------------
{
NSRect bounds = [self bounds];
NSColor* upperColor = [NSColor colorWithCalibratedRed:0.478f green:0.564f blue:0.655f alpha:1.0f];
NSColor* lowerColor = [NSColor colorWithCalibratedRed:0.353f green:0.482f blue:0.557f alpha:1.0f];
NSGradient* gradient = [[NSGradient alloc] initWithStartingColor:upperColor endingColor:lowerColor];
[gradient drawInRect:bounds angle:-90];
NSColor* lineColor = [NSColor colorWithCalibratedRed:0.227f green:0.275f blue:0.322f alpha:1.0f];
[lineColor set];
[NSBezierPath setDefaultLineWidth:1.0f];
NSBezierPath* path = [NSBezierPath bezierPath];
double cycleToPixelRatio = [[SPAnalyzerWindowController sharedInstance] cycleToPixelRatio];
const float margin = 4.0f;
const float lineHeight = NSHeight(bounds) - 2.0f * margin;
double drawStart = rect.origin.x - 4.0f;
double drawEnd = rect.origin.x + NSWidth(rect) + 4.0f;
float zeroLine = floorf(NSHeight(bounds) / 2.0f) + 0.5f;
[path moveToPoint:NSMakePoint(drawStart, zeroLine)];
short* samples = [[SPAnalyzerWindowController sharedInstance] renderBufferSamples];
int sampleCount = [[SPAnalyzerWindowController sharedInstance] renderBufferSampleCount];
int previousSampleOffset = 0;
int sampleRate = [[SPAnalyzerWindowController sharedInstance] effectiveSampleRate];
double clockRate = [[SPAnalyzerWindowController sharedInstance] effectiveCpuClockRate];
const double detailThreshold = (double(sampleRate) / clockRate) / 32.0;
//NSLog(@"cycleToPixelRatio: %f, detailThreshold: %f\n", cycleToPixelRatio, detailThreshold);
if (sampleCount > 0)
{
if (cycleToPixelRatio < detailThreshold)
{
for (double xPos = drawStart; xPos < drawEnd; xPos += 1.0f)
{
double timeInCycles = xPos / cycleToPixelRatio;
double timeInSeconds = timeInCycles / clockRate;
int currentSampleOffset = timeInSeconds > 0.0f ? timeInSeconds * sampleRate : 0;
short minSample = 0;
short maxSample = 0;
for (int sampleIndex = previousSampleOffset; sampleIndex < currentSampleOffset && sampleIndex < sampleCount; sampleIndex++)
{
minSample = MIN(minSample, samples[sampleIndex]);
maxSample = MAX(maxSample, samples[sampleIndex]);
}
float relativeMinSample = float(minSample) / 32768.0f;
float relativeMaxSample = float(maxSample) / 32768.0f;
[path moveToPoint:NSMakePoint(xPos, zeroLine + relativeMinSample * lineHeight * 0.5f - 0.5f)];
[path lineToPoint:NSMakePoint(xPos, zeroLine + relativeMaxSample * lineHeight * 0.5f + 0.5f)];
previousSampleOffset = currentSampleOffset;
}
}
else
{
for (double xPos = drawStart; xPos < drawEnd; xPos += 1.0f)
{
double timeInCycles = xPos / cycleToPixelRatio;
double timeInSeconds = timeInCycles / clockRate;
int currentSampleOffset = timeInSeconds > 0.0f ? timeInSeconds * sampleRate : 0;
float relativeSample = float(currentSampleOffset < sampleCount ? samples[currentSampleOffset] : 0) / 32768.0f;
[path lineToPoint:NSMakePoint(xPos, zeroLine + relativeSample * lineHeight * 0.5f)];
}
}
}
else
[path lineToPoint:NSMakePoint(drawEnd, zeroLine)];
[path stroke];
}
@end