// // 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