You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
3.4 KiB
120 lines
3.4 KiB
//
|
|
// Ruler.m
|
|
// SpectogramPrototype
|
|
//
|
|
// Created by Joshua Moerman on 25/02/14.
|
|
// Copyright (c) 2014 Joshua Moerman. All rights reserved.
|
|
//
|
|
|
|
#import "Ruler.h"
|
|
#import "UIScreen+Util.h"
|
|
|
|
|
|
@implementation AbstractRuler
|
|
@synthesize visibleInterval;
|
|
|
|
- (void)setVisibleInterval:(Interval)visible_interval_{
|
|
if (visibleInterval.begin != visible_interval_.begin || visibleInterval.end != visible_interval_.end) {
|
|
[self setNeedsDisplay];
|
|
visibleInterval = visible_interval_;
|
|
}
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
@implementation HorizontalRuler
|
|
|
|
- (void)drawRect:(CGRect) __unused rect{
|
|
[[UIColor grayColor] setFill];
|
|
UIRectFill(self.bounds);
|
|
|
|
const Interval visibleInterval = self.visibleInterval;
|
|
if(visibleInterval.end <= visibleInterval.begin) return;
|
|
|
|
const CGFloat f = 60 * 44100.0 / 4096.0;
|
|
const CGFloat start = f * ceil(visibleInterval.begin / f);
|
|
const CGFloat d = visibleInterval.end - visibleInterval.begin;
|
|
const int n = (int)floor(d / f) + 1;
|
|
|
|
for(int i = 0; i < n; ++i){
|
|
const CGFloat x = start + i * f;
|
|
const CGFloat r = (x - visibleInterval.begin) / d;
|
|
const CGFloat gx = r * self.bounds.size.width;
|
|
|
|
[[UIColor blackColor] setFill];
|
|
if([UIScreen isRetinaDisplay]){
|
|
UIRectFill(CGRectMake(gx, 0, 0.5, self.bounds.size.height));
|
|
} else {
|
|
UIRectFill(CGRectMake(gx, 0, 1.0, self.bounds.size.height));
|
|
}
|
|
|
|
NSString* string = [NSString stringWithFormat:@"%.0f:00", x/f];
|
|
NSMutableParagraphStyle* style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
|
|
style.alignment = NSTextAlignmentCenter;
|
|
UIFont* font = [UIFont boldSystemFontOfSize:14];
|
|
[string drawInRect:CGRectMake(gx-50, 20, 100, self.bounds.size.height-20)
|
|
withAttributes:@{NSParagraphStyleAttributeName: style,
|
|
NSFontAttributeName: font}];
|
|
}
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
@implementation VerticalRuler
|
|
@synthesize tuning;
|
|
|
|
- (void)setTuning:(float)tuning_{
|
|
tuning = tuning_;
|
|
[self setNeedsDisplay];
|
|
}
|
|
|
|
- (UIColor*)colorForKey:(int)j{
|
|
switch (j) {
|
|
case 0:
|
|
return [UIColor redColor];
|
|
case 2:
|
|
case 3:
|
|
case 5:
|
|
case 7:
|
|
case 8:
|
|
case 10:
|
|
return [UIColor whiteColor];
|
|
|
|
default:
|
|
return [UIColor blackColor];
|
|
}
|
|
}
|
|
|
|
- (void)drawRect:(CGRect) __unused rect{
|
|
[[UIColor grayColor] setFill];
|
|
UIRectFill(self.bounds);
|
|
|
|
const Interval visibleInterval = self.visibleInterval;
|
|
if(visibleInterval.end <= visibleInterval.begin) return;
|
|
|
|
const CGFloat d = visibleInterval.end - visibleInterval.begin;
|
|
const CGFloat f = 44100;
|
|
const CGFloat N = 1 << 13;
|
|
const CGFloat height = (1 << 13) >> 3;
|
|
|
|
for(int i = 110; i < 44100/8; i *= 2){
|
|
for(int j = 0; j < 12; ++j){
|
|
const CGFloat k = (tuning/440.0) * i * pow(2, j/12.0);
|
|
const CGFloat y = N*k/f;
|
|
const CGFloat y2 = (height - y);
|
|
const CGFloat gy = self.bounds.size.height * (y2 - visibleInterval.begin) / d;
|
|
|
|
[[self colorForKey:j] setFill];
|
|
|
|
if([UIScreen isRetinaDisplay]){
|
|
UIRectFill(CGRectMake(0, gy, self.bounds.size.width, 0.5));
|
|
} else {
|
|
UIRectFill(CGRectMake(0, gy, self.bounds.size.width, 1.0));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@end
|
|
|