Joshua Moerman
11 years ago
8 changed files with 222 additions and 48 deletions
@ -0,0 +1,24 @@ |
|||
//
|
|||
// Ruler.h
|
|||
// SpectogramPrototype
|
|||
//
|
|||
// Created by Joshua Moerman on 25/02/14.
|
|||
// Copyright (c) 2014 Joshua Moerman. All rights reserved.
|
|||
//
|
|||
|
|||
#import <UIKit/UIKit.h> |
|||
|
|||
typedef struct Interval { |
|||
CGFloat begin; |
|||
CGFloat end; |
|||
} Interval; |
|||
|
|||
@interface AbstractRuler : UIView |
|||
@property (nonatomic) Interval visibleInterval; |
|||
@end |
|||
|
|||
@interface HorizontalRuler : AbstractRuler |
|||
@end |
|||
|
|||
@interface VerticalRuler : AbstractRuler |
|||
@end |
@ -0,0 +1,114 @@ |
|||
// |
|||
// 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 |
|||
|
|||
- (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 << 12; |
|||
const CGFloat height = (1 << 12) >> 3; |
|||
|
|||
for(int i = 220; i < 44100/8; i *= 2){ |
|||
for(int j = 0; j < 12; ++j){ |
|||
const CGFloat k = i * pow(2, j/12.0); |
|||
const CGFloat y = N*k/f; |
|||
const CGFloat y2 = (height - y); |
|||
const CGFloat gy = 1024 * (y2 - visibleInterval.begin) / d; |
|||
|
|||
[[self colorForKey:j] setFill]; |
|||
|
|||
if([UIScreen isRetinaDisplay]){ |
|||
UIRectFill(CGRectMake(0, gy-0.5, self.bounds.size.width, 1.0)); |
|||
} else { |
|||
UIRectFill(CGRectMake(0, gy-1, self.bounds.size.width, 2.0)); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
@end |
@ -0,0 +1,15 @@ |
|||
//
|
|||
// UIScreen+Util.h
|
|||
// SpectogramPrototype
|
|||
//
|
|||
// Created by Joshua Moerman on 25/02/14.
|
|||
// Copyright (c) 2014 Joshua Moerman. All rights reserved.
|
|||
//
|
|||
|
|||
#import <UIKit/UIKit.h> |
|||
|
|||
@interface UIScreen (Util) |
|||
|
|||
+ (BOOL) isRetinaDisplay; |
|||
|
|||
@end |
@ -0,0 +1,27 @@ |
|||
// |
|||
// UIScreen+Util.m |
|||
// SpectogramPrototype |
|||
// |
|||
// Created by Joshua Moerman on 25/02/14. |
|||
// Copyright (c) 2014 Joshua Moerman. All rights reserved. |
|||
// |
|||
|
|||
#import "UIScreen+Util.h" |
|||
|
|||
@implementation UIScreen (Util) |
|||
|
|||
// from http://stackoverflow.com/questions/3504173/detect-retina-display |
|||
+ (BOOL) isRetinaDisplay { |
|||
static BOOL retina = NO; |
|||
static BOOL alreadyChecked = NO; |
|||
if (!alreadyChecked) { |
|||
UIScreen *mainScreen = self.mainScreen; |
|||
if (mainScreen) { |
|||
retina = mainScreen.scale > 1.0; |
|||
alreadyChecked = YES; |
|||
} |
|||
} |
|||
return retina; |
|||
} |
|||
|
|||
@end |
Reference in new issue