Joshua Moerman
11 years ago
6 changed files with 118 additions and 54 deletions
@ -0,0 +1,16 @@ |
|||||
|
//
|
||||
|
// Spectographer.h
|
||||
|
// SpectogramPrototype
|
||||
|
//
|
||||
|
// Created by Joshua Moerman on 29/12/13.
|
||||
|
// Copyright (c) 2013 Joshua Moerman. All rights reserved.
|
||||
|
//
|
||||
|
|
||||
|
#import <Foundation/Foundation.h> |
||||
|
|
||||
|
@interface Spectographer : NSObject |
||||
|
|
||||
|
- (void)openAudioFile:(NSURL*)url; |
||||
|
- (CGImageRef)generate; |
||||
|
|
||||
|
@end |
@ -0,0 +1,78 @@ |
|||||
|
// |
||||
|
// Spectographer.m |
||||
|
// SpectogramPrototype |
||||
|
// |
||||
|
// Created by Joshua Moerman on 29/12/13. |
||||
|
// Copyright (c) 2013 Joshua Moerman. All rights reserved. |
||||
|
// |
||||
|
|
||||
|
#import "Spectographer.h" |
||||
|
#import "FFTTest.h" |
||||
|
#import "AudioFile.h" |
||||
|
|
||||
|
UInt8 clamp_to_uint8(float x){ |
||||
|
if(x >= 1.0) return 255; |
||||
|
if(x <= 0.0) return 0; |
||||
|
return 255.0 * x; |
||||
|
} |
||||
|
|
||||
|
@interface Spectographer (){ |
||||
|
FFTTest * FFTHandler; |
||||
|
AudioFile * audioFile; |
||||
|
float * left; |
||||
|
float * right; |
||||
|
} |
||||
|
|
||||
|
@end |
||||
|
|
||||
|
@implementation Spectographer |
||||
|
|
||||
|
- (id)init{ |
||||
|
if(self = [super init]){ |
||||
|
FFTHandler = [[FFTTest alloc] init]; |
||||
|
left = calloc(FFTHandler.acceptedSize, sizeof(float)); |
||||
|
right = calloc(FFTHandler.acceptedSize, sizeof(float)); |
||||
|
} |
||||
|
return self; |
||||
|
} |
||||
|
|
||||
|
- (void)openAudioFile:(NSURL *)url{ |
||||
|
audioFile = [AudioFile audioFileFromURL: url]; |
||||
|
assert(audioFile); |
||||
|
} |
||||
|
|
||||
|
- (CGImageRef)generate{ |
||||
|
unsigned int size = FFTHandler.acceptedSize; |
||||
|
unsigned int width = size/4; |
||||
|
unsigned int height = size/8; |
||||
|
|
||||
|
char * rgba = calloc(width*height*4, sizeof(char)); |
||||
|
|
||||
|
for(unsigned int x = 0; x < width; ++x){ |
||||
|
[audioFile fillLeft:left andRight:right withNumberOfSamples:size]; |
||||
|
[FFTHandler inPlaceFFT:left forSize:size]; |
||||
|
[FFTHandler inPlaceFFT:right forSize:size]; |
||||
|
for(unsigned int y = 0; y < height; ++y){ |
||||
|
unsigned int yy = height - y - 1; |
||||
|
rgba[4*width*yy + 4*x + 0] = clamp_to_uint8(100.0 * left[y]); |
||||
|
rgba[4*width*yy + 4*x + 1] = clamp_to_uint8(100.0 * right[y]); |
||||
|
rgba[4*width*yy + 4*x + 2] = clamp_to_uint8(10.0 * (left[y] + right[y])); |
||||
|
rgba[4*width*yy + 4*x + 3] = 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); |
||||
|
assert(colorSpace); |
||||
|
CGContextRef bitmapContext = CGBitmapContextCreate(rgba, width, height, 8, 4*width, colorSpace, (CGBitmapInfo)kCGImageAlphaNoneSkipLast); |
||||
|
assert(bitmapContext); |
||||
|
CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext); |
||||
|
assert(cgImage); |
||||
|
|
||||
|
CGContextRelease(bitmapContext); |
||||
|
CGColorSpaceRelease(colorSpace); |
||||
|
free(rgba); |
||||
|
|
||||
|
return cgImage; |
||||
|
} |
||||
|
|
||||
|
@end |
Reference in new issue