-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathSPBigOscilloscopeView.m
More file actions
159 lines (138 loc) · 5.19 KB
/
Copy pathSPBigOscilloscopeView.m
File metadata and controls
159 lines (138 loc) · 5.19 KB
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//
// SPBigOscilloscopeView.m
// SIDPLAY
//
// Created by Alexander Coers on 12.04.24.
//
#import <Cocoa/Cocoa.h>
#import <CoreImage/CIFilter.h>
#import "SPBigOscilloscopeView.h"
#import "SPPlayerWindow.h"
@implementation SPBigOscilloscopeView
- (void) awakeFromNib
// ----------------------------------------------------------------------------
{
[self setWantsLayer:YES];
CIFilter *filter = [CIFilter filterWithName:@"CIBloom"];
[filter setDefaults];
[filter setValue:@4.0f forKey:@"inputRadius"];
filter.name = @"bloomFilter";
self.contentFilters = @[filter];
}
- (void)setPlayerWindow:(SPPlayerWindow*)newPlayerW
{
@synchronized (playerW) {
playerW = (SPPlayerWindow*)newPlayerW;
}
hSample = 0;
}
-(void)updatePlayerInfo
{
currentTitle = [playerW currentTitle];
currentAuthor = [playerW currentAuthor];
updateNeeded = YES;
}
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
// Drawing code here.
NSColor* darkColor = nil;
NSColor* brightColor = nil;
darkColor = [NSColor colorWithDeviceRed:0.117f green:0.117f blue:0.117f alpha:1.0f];
brightColor = [NSColor colorWithDeviceRed:0.321f green:0.321f blue:0.321f alpha:1.0f];
//NSFrameRect(bounds);
NSRect bounds = self.bounds;
CGRect contextRect;
contextRect.origin.x = dirtyRect.origin.x;
contextRect.origin.y = dirtyRect.origin.y;
contextRect.size.width = dirtyRect.size.width;
contextRect.size.height = dirtyRect.size.height;
CGContextRef context = (CGContextRef) [NSGraphicsContext currentContext].graphicsPort;
CGContextSetRGBFillColor(context, 0.0f, 0.0f, 0.0f, 0.8f);
CGContextFillRect(context, contextRect);
short* sampleBuffer = NULL;
BOOL isPlaying = NO;
/* we use protocols here, simply because I don't want
* to change the whole LibPlayerClass here
*/
if ([playerW conformsToProtocol: @protocol (PlayerInfo)]== YES)
{
sampleBuffer = [playerW audioDriverSampleBuffer];
}
if (sampleBuffer == NULL)
return;
unsigned int numSamples = 0;
/* normally we could skip this test, since we tested it aleady above, but...*/
if ([(id)playerW conformsToProtocol: @protocol (PlayerInfo)]== YES)
{
isPlaying = [(id)playerW audioDriverIsPlaying];
numSamples = [(id)playerW currentNumberOfSamples];
}
float zeroLineHeight = contextRect.size.height * 0.5f + 0.5f;
float width = contextRect.size.width;
float height = contextRect.size.height;
if (isPlaying)
CGContextSetRGBStrokeColor(context, 0.2f, 1.0f, 1.0f, 1.0f);
else
{
float error = 0.1f * (random() & 0xffff) / 65535.0f;
float brightness = error + 0.9f;
CGContextSetRGBStrokeColor(context, 0.2f, brightness, brightness, 1.0f);
}
CGContextBeginPath(context);
CGContextSetLineWidth(context, 1.2f);
if (isPlaying && sampleBuffer != nil)
{
static CGPoint linePoints[2048];
float stepW;
//sample buffer contains signed 16 bit samples
// -32768 - 32767
float factorH = height/33000/2;
// create a ratio for the width, since the audio buffer can differ in size
// and maybe less than width pixels
if ((width == 0) || (numSamples == 0))
stepW = 0;
else
stepW = (float)numSamples/(float)width;
float indexS = 0;
for (int i = 0; i < width; i++)
{
linePoints[i].x = i + 0.5f;
linePoints[i].y = zeroLineHeight + (sampleBuffer[(int)trunc(indexS)] * factorH);
if (sampleBuffer[(int)trunc(indexS)] > hSample)
hSample = sampleBuffer[(int)trunc(indexS)];
indexS +=stepW;
}
CGContextAddLines(context, linePoints, width);
CGContextDrawPath(context, kCGPathStroke);
}
else
{
static CGPoint linePoints[2];
linePoints[0].x = contextRect.origin.x;
linePoints[0].y = zeroLineHeight;
linePoints[1].x = width;
linePoints[1].y = zeroLineHeight;
CGContextAddLines(context, linePoints, 2);
CGContextDrawPath(context, kCGPathFillStroke);
}
if (updateNeeded)
{
// new text needs to be printed
NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:currentTitle];
if ([text length] != 0) {
[text appendAttributedString:[[NSAttributedString alloc] initWithString:@" by "]];
[text appendAttributedString:[[NSAttributedString alloc] initWithString:currentAuthor]];
[text addAttribute:NSForegroundColorAttributeName value:[NSColor colorWithCalibratedRed:0.2f green:1.0f blue:1.0f alpha:1.0f] range:NSMakeRange(0,[text length])];
CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)text);
// Set text position and draw the line into the graphics context
CGContextSetTextPosition(context, 10.0, 50.0);
CTLineDraw(line, context);
CFRelease(line);
}
}
//draw a frame around the view
[darkColor set];
NSFrameRect(NSInsetRect(bounds, 1.0f, 1.0f));
[brightColor set];
}
@end