├── PitchDetectorExample
├── en.lproj
│ └── InfoPlist.strings
├── AppDelegate.h
├── PitchDetectorExample-Prefix.pch
├── main.m
├── PitchDetectorExample-Info.plist
├── FreqViewController.h
├── AudioController.h
├── PitchDetector.h
├── AppDelegate.m
├── TPCircularBuffer.h
├── FreqViewController.m
├── TPCircularBuffer.c
├── PitchDetector.m
└── AudioController.m
├── README.txt
└── PitchDetectorExample.xcodeproj
├── project.xcworkspace
├── contents.xcworkspacedata
└── xcuserdata
│ └── kevinmurphy.xcuserdatad
│ └── UserInterfaceState.xcuserstate
├── xcuserdata
└── kevinmurphy.xcuserdatad
│ └── xcschemes
│ ├── xcschememanagement.plist
│ └── PitchDetectorExample.xcscheme
└── project.pbxproj
/PitchDetectorExample/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
1 | This was written a some time ago and is not a great example. It might be helpful to get you started on your own project, but you've been warned that this is by no means an example of good coding practices.
2 |
--------------------------------------------------------------------------------
/PitchDetectorExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/PitchDetectorExample.xcodeproj/project.xcworkspace/xcuserdata/kevinmurphy.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swiftlypatrick/PitchDetectorExample/HEAD/PitchDetectorExample.xcodeproj/project.xcworkspace/xcuserdata/kevinmurphy.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/PitchDetectorExample/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // PitchDetectorExample
4 | //
5 | // Created by Kevin Murphy on 7/4/12.
6 | // Copyright (c) 2012 New York University. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/PitchDetectorExample/PitchDetectorExample-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'PitchDetectorExample' target in the 'PitchDetectorExample' project
3 | //
4 |
5 | #import
6 |
7 | #ifndef __IPHONE_3_0
8 | #warning "This project uses features only available in iOS SDK 3.0 and later."
9 | #endif
10 |
11 | #ifdef __OBJC__
12 | #import
13 | #import
14 | #endif
15 |
--------------------------------------------------------------------------------
/PitchDetectorExample/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // PitchDetectorExample
4 | //
5 | // Created by Kevin Murphy on 7/4/12.
6 | // Copyright (c) 2012 New York University. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "AppDelegate.h"
12 |
13 | int main(int argc, char *argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/PitchDetectorExample.xcodeproj/xcuserdata/kevinmurphy.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | PitchDetectorExample.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 101E675415A511E700FFF744
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/PitchDetectorExample/PitchDetectorExample-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | com.kevmdev.${PRODUCT_NAME:rfc1034identifier}
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | LSRequiresIPhoneOS
26 |
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/PitchDetectorExample/FreqViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) Kevin P Murphy June 2012
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5 |
6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 |
8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
9 | */
10 |
11 | #import
12 | #import "AudioController.h"
13 | #import "PitchDetector.h"
14 |
15 | @interface FreqViewController : UIViewController
16 | {
17 | UILabel *freqLabel;
18 | AudioController *audioManager;
19 | PitchDetector *autoCorrelator;
20 |
21 | NSMutableArray *medianPitchFollow;
22 | }
23 |
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/PitchDetectorExample/AudioController.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) Kevin P Murphy June 2012
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5 |
6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 |
8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
9 | */
10 |
11 | #import
12 | #import
13 |
14 | @protocol AudioControllerDelegate
15 | @required
16 | - (void) receivedAudioSamples:(SInt16*) samples length:(int) len;
17 | @end
18 |
19 | @interface AudioController : NSObject
20 | {
21 | @public
22 | AudioBufferList bufferList;
23 | }
24 | @property (nonatomic, assign) AudioStreamBasicDescription audioFormat;
25 | @property (nonatomic, assign) AudioUnit rioUnit;
26 | @property (nonatomic, assign) id delegate;
27 |
28 | + (AudioController*) sharedAudioManager;
29 | - (void) startAudio;
30 |
31 |
32 | @end
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/PitchDetectorExample/PitchDetector.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) Kevin P Murphy June 2012
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5 |
6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 |
8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
9 | */
10 | #import
11 |
12 | @protocol PitchDetectorDelegate
13 | - (void) updatedPitch: (float) frequency;
14 | @end
15 |
16 | @class AudioController;
17 |
18 | @interface PitchDetector : NSObject
19 | {
20 | float *hann, *result;
21 | SInt16 *sampleBuffer;
22 | int samplesInSampleBuffer;
23 | int bufferLength;
24 | int windowLength;
25 | }
26 |
27 | @property (nonatomic) BOOL running;
28 | @property (nonatomic, assign) id delegate;
29 | @property int hiBoundFrequency, lowBoundFrequency;
30 | @property float sampleRate;
31 |
32 | //Optional Init Method (calls the second init method but sets the frequency bounds to default values)
33 | -(id) initWithSampleRate: (float) rate andDelegate: (id) initDelegate;
34 | -(id) initWithSampleRate: (float) rate lowBoundFreq: (int) low hiBoundFreq: (int) hi andDelegate: (id) initDelegate;
35 | - (void) addSamples: (SInt16*) samples inNumberFrames: (int) frames;
36 |
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/PitchDetectorExample/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // PitchDetectorExample
4 | //
5 | // Created by Kevin Murphy on 7/4/12.
6 | // Copyright (c) 2012 New York University. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "FreqViewController.h"
11 |
12 | @implementation AppDelegate
13 |
14 | @synthesize window = _window;
15 |
16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
17 | {
18 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
19 | // Override point for customization after application launch.
20 | self.window.backgroundColor = [UIColor whiteColor];
21 | self.window.rootViewController = [[FreqViewController alloc] initWithNibName:nil bundle:nil];
22 | [self.window makeKeyAndVisible];
23 | return YES;
24 | }
25 |
26 | - (void)applicationWillResignActive:(UIApplication *)application
27 | {
28 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
29 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
30 | }
31 |
32 | - (void)applicationDidEnterBackground:(UIApplication *)application
33 | {
34 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
35 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
36 | }
37 |
38 | - (void)applicationWillEnterForeground:(UIApplication *)application
39 | {
40 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
41 | }
42 |
43 | - (void)applicationDidBecomeActive:(UIApplication *)application
44 | {
45 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
46 | }
47 |
48 | - (void)applicationWillTerminate:(UIApplication *)application
49 | {
50 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
51 | }
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/PitchDetectorExample.xcodeproj/xcuserdata/kevinmurphy.xcuserdatad/xcschemes/PitchDetectorExample.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
14 |
20 |
21 |
22 |
23 |
24 |
29 |
30 |
31 |
32 |
38 |
39 |
40 |
41 |
50 |
51 |
57 |
58 |
59 |
60 |
61 |
62 |
68 |
69 |
75 |
76 |
77 |
78 |
80 |
81 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/PitchDetectorExample/TPCircularBuffer.h:
--------------------------------------------------------------------------------
1 | //
2 | // TPCircularBuffer.h
3 | // Circular/Ring buffer implementation
4 | //
5 | // Created by Michael Tyson on 10/12/2011.
6 | // Copyright 2011 A Tasty Pixel. All rights reserved.
7 | //
8 | //
9 | // This implementation makes use of a virtual memory mapping technique that inserts a virtual copy
10 | // of the buffer memory directly after the buffer's end, negating the need for any buffer wrap-around
11 | // logic. Clients can simply use the returned memory address as if it were contiguous space.
12 | //
13 | // The implementation is thread-safe in the case of a single producer and single consumer.
14 | //
15 | // Virtual memory technique originally proposed by Philip Howard (http://vrb.slashusr.org/), and
16 | // adapted to Darwin by Kurt Revis (http://www.snoize.com,
17 | // http://www.snoize.com/Code/PlayBufferedSoundFile.tar.gz)
18 | //
19 | // MIT license:
20 | //
21 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
22 | // associated documentation files (the "Software"), to deal in the Software without restriction,
23 | // including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
24 | // and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
25 | // subject to the following conditions:
26 | //
27 | // The above copyright notice and this permission notice shall be included in all copies or substantial
28 | // portions of the Software.
29 | //
30 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
31 | // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
32 | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
33 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
34 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 |
36 | #include
37 | #include
38 |
39 | #ifdef __cplusplus
40 | extern "C" {
41 | #endif//
42 |
43 | typedef struct {
44 | void *buffer;
45 | int32_t length;
46 | int32_t tail;
47 | int32_t head;
48 | volatile int32_t fillCount;
49 | int count;
50 | } TPCircularBuffer;
51 |
52 | bool TPCircularBufferInit(TPCircularBuffer *buffer, int32_t length);
53 | void TPCircularBufferCleanup(TPCircularBuffer *buffer);
54 | void TPCircularBufferClear(TPCircularBuffer *buffer);
55 |
56 | // Reading (consuming)
57 |
58 | static __inline__ __attribute__((always_inline)) void* TPCircularBufferTail(TPCircularBuffer *buffer, int32_t* availableBytes) {
59 | *availableBytes = buffer->fillCount;
60 | return (void*)((char*)buffer->buffer + buffer->tail);
61 | }
62 |
63 | static __inline__ __attribute__((always_inline)) void TPCircularBufferConsume(TPCircularBuffer *buffer, int32_t amount) {
64 | buffer->tail = (buffer->tail + amount) % buffer->length;
65 | OSAtomicAdd32Barrier(-amount, &buffer->fillCount);
66 | buffer->count -= amount;
67 | }
68 |
69 | static __inline__ __attribute__((always_inline)) void* TPCircularBufferHead(TPCircularBuffer *buffer, int32_t * availableBytes) {
70 | *availableBytes = (buffer->length - buffer->fillCount);
71 | return (void*)((char*)buffer->buffer + buffer->head);
72 | }
73 |
74 | // Writing (producing)
75 |
76 | static __inline__ __attribute__((always_inline)) void TPCircularBufferProduce(TPCircularBuffer *buffer, int amount) {
77 | buffer->head = (buffer->head + amount) % buffer->length;
78 | OSAtomicAdd32Barrier(amount, &buffer->fillCount);
79 | buffer->count += amount;
80 | }
81 |
82 | static __inline__ __attribute__((always_inline)) int TPCircularBufferProduceBytes(TPCircularBuffer *buffer, const void* src, int32_t len) {
83 | int32_t space;
84 | void *ptr = TPCircularBufferHead(buffer, &space);
85 | int copied = len > space ? space : len;
86 | memcpy(ptr, src, copied);
87 | TPCircularBufferProduce(buffer, copied);
88 | return copied;
89 | }
90 |
91 | #ifdef __cplusplus
92 | }
93 | #endif
94 |
--------------------------------------------------------------------------------
/PitchDetectorExample/FreqViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) Kevin P Murphy June 2012
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5 |
6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 |
8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
9 | */
10 |
11 | #import "FreqViewController.h"
12 |
13 | @interface FreqViewController ()
14 |
15 | @end
16 |
17 | @implementation FreqViewController
18 | - (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
19 | self = [super initWithNibName:nil bundle:nil];
20 |
21 | self.view.backgroundColor = [UIColor whiteColor];
22 |
23 | return self;
24 |
25 | }
26 |
27 |
28 | - (void)viewDidLoad
29 | {
30 | [super viewDidLoad];
31 | audioManager = [AudioController sharedAudioManager];
32 | audioManager.delegate = self;
33 | autoCorrelator = [[PitchDetector alloc] initWithSampleRate:audioManager.audioFormat.mSampleRate lowBoundFreq:30 hiBoundFreq:4500 andDelegate:self];
34 |
35 | medianPitchFollow = [[NSMutableArray alloc] initWithCapacity:22];
36 |
37 | freqLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 80)];
38 | freqLabel.center = CGPointMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2);
39 | freqLabel.backgroundColor = [UIColor clearColor];
40 | freqLabel.textAlignment = UITextAlignmentCenter;
41 |
42 | [self.view addSubview:freqLabel];
43 |
44 | }
45 |
46 | - (void)viewDidUnload
47 | {
48 | [super viewDidUnload];
49 | }
50 |
51 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
52 | {
53 | return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
54 | }
55 |
56 | - (void) updatedPitch:(float)frequency {
57 |
58 | double value = frequency;
59 |
60 |
61 |
62 | //############ DATA SMOOTHING ###############
63 | //### The following code averages previous values ##
64 | //### received by the pitch follower by using a ##
65 | //### median filter. Provides sub cent precision! ##
66 | //#############################################
67 |
68 | NSNumber *nsnum = [NSNumber numberWithDouble:value];
69 | [medianPitchFollow insertObject:nsnum atIndex:0];
70 |
71 | if(medianPitchFollow.count>22) {
72 | [medianPitchFollow removeObjectAtIndex:medianPitchFollow.count-1];
73 | }
74 | double median = 0;
75 |
76 |
77 |
78 | if(medianPitchFollow.count>=2) {
79 | NSSortDescriptor *highestToLowest = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:NO];
80 | NSMutableArray *tempSort = [NSMutableArray arrayWithArray:medianPitchFollow];
81 | [tempSort sortUsingDescriptors:[NSArray arrayWithObject:highestToLowest]];
82 |
83 | if(tempSort.count%2==0) {
84 | double first = 0, second = 0;
85 | first = [[tempSort objectAtIndex:tempSort.count/2-1] doubleValue];
86 | second = [[tempSort objectAtIndex:tempSort.count/2] doubleValue];
87 | median = (first+second)/2;
88 | value = median;
89 | } else {
90 | median = [[tempSort objectAtIndex:tempSort.count/2] doubleValue];
91 | value = median;
92 | }
93 |
94 | [tempSort removeAllObjects];
95 | tempSort = nil;
96 | }
97 |
98 | freqLabel.text = [NSString stringWithFormat:@"%3.1f Hz", value];
99 |
100 | }
101 |
102 | - (void) receivedAudioSamples:(SInt16 *)samples length:(int)len {
103 | [autoCorrelator addSamples:samples inNumberFrames:len];
104 | }
105 |
106 | @end
107 |
--------------------------------------------------------------------------------
/PitchDetectorExample/TPCircularBuffer.c:
--------------------------------------------------------------------------------
1 | //
2 | // TPCircularBuffer.c
3 | // Circular/Ring buffer implementation
4 | //
5 | // Created by Michael Tyson on 10/12/2011.
6 | // Copyright 2011 A Tasty Pixel. All rights reserved.
7 | //
8 | // MIT license:
9 | //
10 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
11 | // associated documentation files (the "Software"), to deal in the Software without restriction,
12 | // including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | // and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
14 | // subject to the following conditions:
15 | //
16 | // The above copyright notice and this permission notice shall be included in all copies or substantial
17 | // portions of the Software.
18 | //
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
20 | // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | #include "TPCircularBuffer.h"
26 | #include
27 | #include
28 |
29 | #define checkResult(result,operation) (_checkResult((result),(operation),strrchr(__FILE__, '/'),__LINE__))
30 | static inline bool _checkResult(kern_return_t result, const char *operation, const char* file, int line) {
31 | if ( result != ERR_SUCCESS ) {
32 | printf("%s:%d: %s: %s\n", file, line, operation, mach_error_string(result));
33 | return false;
34 | }
35 | return true;
36 | }
37 |
38 | bool TPCircularBufferInit(TPCircularBuffer *buffer, int length) {
39 |
40 | buffer->length = round_page(length); // We need whole page sizes
41 | buffer->count = 0;
42 | // Temporarily allocate twice the length, so we have the contiguous address space to
43 | // support a second instance of the buffer directly after
44 | vm_address_t bufferAddress;
45 | if ( !checkResult(vm_allocate(mach_task_self(), &bufferAddress, buffer->length * 2, TRUE /* (don't use the current bufferAddress value) */),
46 | "Buffer allocation") ) return false;
47 |
48 | // Now replace the second half of the allocation with a virtual copy of the first half. Deallocate the second half...
49 | if ( !checkResult(vm_deallocate(mach_task_self(), bufferAddress + buffer->length, buffer->length),
50 | "Buffer deallocation") ) return false;
51 |
52 | // Then create a memory entry that refers to the buffer
53 | vm_size_t entry_length = buffer->length;
54 | mach_port_t memoryEntry;
55 | if ( !checkResult(mach_make_memory_entry(mach_task_self(), &entry_length, bufferAddress, VM_PROT_READ|VM_PROT_WRITE, &memoryEntry, 0),
56 | "Create memory entry") ) {
57 | vm_deallocate(mach_task_self(), bufferAddress, buffer->length);
58 | return false;
59 | }
60 |
61 | // And map the memory entry to the address space immediately after the buffer
62 | vm_address_t virtualAddress = bufferAddress + buffer->length;
63 | if ( !checkResult(vm_map(mach_task_self(), &virtualAddress, buffer->length, 0, FALSE, memoryEntry, 0, FALSE, VM_PROT_READ | VM_PROT_WRITE, VM_PROT_READ | VM_PROT_WRITE, VM_INHERIT_DEFAULT),
64 | "Map buffer memory") ) {
65 | vm_deallocate(mach_task_self(), bufferAddress, buffer->length);
66 | return false;
67 | }
68 |
69 | if ( virtualAddress != bufferAddress+buffer->length ) {
70 | printf("Couldn't map buffer memory to end of buffer\n");
71 | vm_deallocate(mach_task_self(), virtualAddress, buffer->length);
72 | vm_deallocate(mach_task_self(), bufferAddress, buffer->length);
73 | return false;
74 | }
75 |
76 | buffer->buffer = (void*)bufferAddress;
77 | buffer->fillCount = 0;
78 | buffer->head = buffer->tail = 0;
79 |
80 | return true;
81 | }
82 |
83 | void TPCircularBufferCleanup(TPCircularBuffer *buffer) {
84 | vm_deallocate(mach_task_self(), (vm_address_t)buffer->buffer, buffer->length * 2);
85 | memset(buffer, 0, sizeof(TPCircularBuffer));
86 | }
87 |
88 | void TPCircularBufferClear(TPCircularBuffer *buffer) {
89 | buffer->head = buffer->tail = 0;
90 | buffer->fillCount = 0;
91 | }
92 |
--------------------------------------------------------------------------------
/PitchDetectorExample/PitchDetector.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) Kevin P Murphy June 2012
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5 |
6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 |
8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
9 | */
10 |
11 |
12 | #import "PitchDetector.h"
13 | #import
14 |
15 |
16 | @implementation PitchDetector
17 | @synthesize lowBoundFrequency, hiBoundFrequency, sampleRate, delegate, running;
18 |
19 | #pragma mark Initialize Methods
20 |
21 |
22 | -(id) initWithSampleRate: (float) rate andDelegate: (id) initDelegate {
23 | return [self initWithSampleRate:rate lowBoundFreq:40 hiBoundFreq:4500 andDelegate:initDelegate];
24 | }
25 |
26 | -(id) initWithSampleRate: (float) rate lowBoundFreq: (int) low hiBoundFreq: (int) hi andDelegate: (id) initDelegate {
27 | self.lowBoundFrequency = low;
28 | self.hiBoundFrequency = hi;
29 | self.sampleRate = rate;
30 | self.delegate = initDelegate;
31 |
32 | bufferLength = self.sampleRate/self.lowBoundFrequency;
33 |
34 |
35 | hann = (float*) malloc(sizeof(float)*bufferLength);
36 | vDSP_hann_window(hann, bufferLength, vDSP_HANN_NORM);
37 |
38 | sampleBuffer = (SInt16*) malloc(512);
39 | samplesInSampleBuffer = 0;
40 |
41 | result = (float*) malloc(sizeof(float)*bufferLength);
42 |
43 | return self;
44 | }
45 |
46 | #pragma mark Insert Samples
47 |
48 | - (void) addSamples:(SInt16 *)samples inNumberFrames:(int)frames {
49 | int newLength = frames;
50 | if(samplesInSampleBuffer>0) {
51 | newLength += samplesInSampleBuffer;
52 | }
53 |
54 | SInt16 *newBuffer = (SInt16*) malloc(sizeof(SInt16)*newLength);
55 | memcpy(newBuffer, sampleBuffer, samplesInSampleBuffer*sizeof(SInt16));
56 | memcpy(&newBuffer[samplesInSampleBuffer], samples, frames*sizeof(SInt16));
57 |
58 | free(sampleBuffer);
59 | sampleBuffer = newBuffer;
60 | samplesInSampleBuffer = newLength;
61 |
62 | if(samplesInSampleBuffer>(self.sampleRate/self.lowBoundFrequency)) {
63 | if(!self.running) {
64 | [self performSelectorInBackground:@selector(performWithNumFrames:) withObject:[NSNumber numberWithInt:newLength]];
65 | self.running = YES;
66 | }
67 | samplesInSampleBuffer = 0;
68 | } else {
69 | //printf("NOT ENOUGH SAMPLES: %d\n", newLength);
70 | }
71 | }
72 |
73 |
74 | #pragma mark Perform Auto Correlation
75 |
76 | -(void) performWithNumFrames: (NSNumber*) numFrames;
77 | {
78 | int n = numFrames.intValue;
79 | float freq = 0;
80 |
81 | SInt16 *samples = sampleBuffer;
82 |
83 | int returnIndex = 0;
84 | float sum;
85 | bool goingUp = false;
86 | float normalize = 0;
87 |
88 | for(int i = 0; iresult[i-1] && goingUp == false && i >1) {
103 |
104 | //local min at i-1
105 |
106 | goingUp = true;
107 |
108 | } else if(goingUp == true && result[i]result[0]*0.95) {
113 | returnIndex = i-1;
114 | break;
115 | //############### NOTE ##################################
116 | // My implemenation breaks out of this loop when it finds the first peak.
117 | // This is (probably) the greatest source of error, so if you would like to
118 | // improve this algorithm, start here. the next else if() will trigger on
119 | // future local maxima (if you first take out the break; above this paragraph)
120 | //#######################################################
121 | } else if(result[i-1]>result[0]*0.85) {
122 | }
123 | goingUp = false;
124 | }
125 | }
126 | }
127 |
128 | freq =self.sampleRate/interp(result[returnIndex-1], result[returnIndex], result[returnIndex+1], returnIndex);
129 | if(freq >= 27.5 && freq <= 4500.0) {
130 | dispatch_async(dispatch_get_main_queue(), ^{
131 | [delegate updatedPitch:freq];
132 | });
133 | }
134 | self.running = NO;
135 | }
136 |
137 |
138 | float interp(float y1, float y2, float y3, int k);
139 | float interp(float y1, float y2, float y3, int k) {
140 |
141 | float d, kp;
142 | d = (y3 - y1) / (2 * (2 * y2 - y1 - y3));
143 | //printf("%f = %d + %f\n", k+d, k, d);
144 | kp = k + d;
145 | return kp;
146 | }
147 | @end
148 |
149 |
--------------------------------------------------------------------------------
/PitchDetectorExample/AudioController.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) Kevin P Murphy June 2012
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5 |
6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 |
8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
9 | */
10 |
11 | #import "AudioController.h"
12 |
13 | #define kOutputBus 0
14 | #define kInputBus 1
15 |
16 | @implementation AudioController
17 | @synthesize rioUnit, audioFormat, delegate;
18 |
19 |
20 | + (AudioController *) sharedAudioManager
21 | {
22 | static AudioController *sharedAudioManager;
23 |
24 | @synchronized(self)
25 | {
26 | if (!sharedAudioManager) {
27 | sharedAudioManager = [[AudioController alloc] init];
28 | [sharedAudioManager startAudio];
29 | }
30 | return sharedAudioManager;
31 | }
32 | }
33 |
34 |
35 | void checkStatus(OSStatus status);
36 | void checkStatus(OSStatus status) {
37 | if(status!=0)
38 | printf("Error: %ld\n", status);
39 | }
40 |
41 | #pragma mark init
42 |
43 | - (id)init
44 | {
45 | OSStatus status;
46 | status = AudioSessionInitialize(NULL, NULL, NULL, (__bridge void*) self);
47 | checkStatus(status);
48 |
49 | // Describe audio component
50 | AudioComponentDescription desc;
51 | desc.componentType = kAudioUnitType_Output;
52 | desc.componentSubType = kAudioUnitSubType_RemoteIO;
53 | desc.componentFlags = 0;
54 | desc.componentFlagsMask = 0;
55 | desc.componentManufacturer = kAudioUnitManufacturer_Apple;
56 |
57 | // Get component
58 | AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc);
59 |
60 | // Get audio units
61 | status = AudioComponentInstanceNew(inputComponent, &rioUnit);
62 | checkStatus(status);
63 |
64 |
65 | // Enable IO for recording
66 | UInt32 flag = 1;
67 |
68 | status = AudioUnitSetProperty(rioUnit,
69 | kAudioOutputUnitProperty_EnableIO,
70 | kAudioUnitScope_Input,
71 | kInputBus,
72 | &flag,
73 | sizeof(flag));
74 | checkStatus(status);
75 |
76 |
77 | // Describe format
78 | audioFormat.mSampleRate= 44100.0;
79 | audioFormat.mFormatID= kAudioFormatLinearPCM;
80 | audioFormat.mFormatFlags= kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
81 | audioFormat.mFramesPerPacket= 1;
82 | audioFormat.mChannelsPerFrame= 1;
83 | audioFormat.mBitsPerChannel= 16;
84 | audioFormat.mBytesPerPacket= 2;
85 | audioFormat.mBytesPerFrame= 2;
86 |
87 | // Apply format
88 | status = AudioUnitSetProperty(rioUnit,
89 | kAudioUnitProperty_StreamFormat,
90 | kAudioUnitScope_Output,
91 | kInputBus,
92 | &audioFormat,
93 | sizeof(audioFormat));
94 | checkStatus(status);
95 |
96 | status = AudioUnitSetProperty(rioUnit,
97 | kAudioUnitProperty_StreamFormat,
98 | kAudioUnitScope_Input,
99 | kOutputBus,
100 | &audioFormat,
101 | sizeof(audioFormat));
102 | checkStatus(status);
103 |
104 | // Set input callback
105 | AURenderCallbackStruct callbackStruct;
106 | callbackStruct.inputProc = recordingCallback;
107 | callbackStruct.inputProcRefCon = (__bridge void*)self;
108 |
109 | status = AudioUnitSetProperty(rioUnit,
110 | kAudioOutputUnitProperty_SetInputCallback,
111 | kAudioUnitScope_Global,
112 | kInputBus,
113 | &callbackStruct,
114 | sizeof(callbackStruct));
115 | checkStatus(status);
116 |
117 |
118 | // Disable buffer allocation for the recorder
119 | flag = 0;
120 | status = AudioUnitSetProperty(rioUnit, kAudioUnitProperty_ShouldAllocateBuffer, kAudioUnitScope_Global, kInputBus, &flag, sizeof(flag));
121 |
122 |
123 | // Initialise
124 | UInt32 category = kAudioSessionCategory_PlayAndRecord;
125 | status = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &category);
126 | checkStatus(status);
127 |
128 | status = 0;
129 | status = AudioSessionSetActive(YES);
130 | checkStatus(status);
131 |
132 | status = AudioUnitInitialize(rioUnit);
133 | checkStatus(status);
134 |
135 | return self;
136 | }
137 |
138 | #pragma mark Recording Callback
139 | static OSStatus recordingCallback(void *inRefCon,
140 | AudioUnitRenderActionFlags *ioActionFlags,
141 | const AudioTimeStamp *inTimeStamp,
142 | UInt32 inBusNumber,
143 | UInt32 inNumberFrames,
144 | AudioBufferList *ioData) {
145 |
146 | AudioController *THIS = (__bridge AudioController*) inRefCon;
147 |
148 | THIS->bufferList.mNumberBuffers = 1;
149 | THIS->bufferList.mBuffers[0].mDataByteSize = sizeof(SInt16)*inNumberFrames;
150 | THIS->bufferList.mBuffers[0].mNumberChannels = 1;
151 | THIS->bufferList.mBuffers[0].mData = (SInt16*) malloc(sizeof(SInt16)*inNumberFrames);
152 |
153 | OSStatus status;
154 |
155 | status = AudioUnitRender(THIS->rioUnit,
156 | ioActionFlags,
157 | inTimeStamp,
158 | inBusNumber,
159 | inNumberFrames,
160 | &(THIS->bufferList));
161 | checkStatus(status);
162 |
163 | dispatch_async(dispatch_get_main_queue(), ^{
164 | [THIS.delegate receivedAudioSamples:(SInt16*)THIS->bufferList.mBuffers[0].mData length:inNumberFrames];
165 | });
166 |
167 | return noErr;
168 | }
169 |
170 |
171 |
172 | -(void) startAudio
173 | {
174 | OSStatus status = AudioOutputUnitStart(rioUnit);
175 | checkStatus(status);
176 | printf("Audio Initialized - sampleRate: %f\n", audioFormat.mSampleRate);
177 | }
178 |
179 | @end
180 |
--------------------------------------------------------------------------------
/PitchDetectorExample.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 101E675A15A511E700FFF744 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 101E675915A511E700FFF744 /* UIKit.framework */; };
11 | 101E675C15A511E700FFF744 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 101E675B15A511E700FFF744 /* Foundation.framework */; };
12 | 101E675E15A511E700FFF744 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 101E675D15A511E700FFF744 /* CoreGraphics.framework */; };
13 | 101E676415A511E700FFF744 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 101E676215A511E700FFF744 /* InfoPlist.strings */; };
14 | 101E676615A511E700FFF744 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 101E676515A511E700FFF744 /* main.m */; };
15 | 101E676A15A511E700FFF744 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 101E676915A511E700FFF744 /* AppDelegate.m */; };
16 | 101E677E15A512A800FFF744 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 101E677C15A512A800FFF744 /* Accelerate.framework */; };
17 | 101E677F15A512A800FFF744 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 101E677D15A512A800FFF744 /* AudioToolbox.framework */; };
18 | 101E678815A5163300FFF744 /* AudioController.m in Sources */ = {isa = PBXBuildFile; fileRef = 101E678115A5163300FFF744 /* AudioController.m */; };
19 | 101E678915A5163300FFF744 /* FreqViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 101E678315A5163300FFF744 /* FreqViewController.m */; };
20 | 101E678A15A5163300FFF744 /* PitchDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 101E678515A5163300FFF744 /* PitchDetector.m */; };
21 | 101E678B15A5163300FFF744 /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 101E678615A5163300FFF744 /* TPCircularBuffer.c */; };
22 | 101E678D15A5177E00FFF744 /* README.txt in Resources */ = {isa = PBXBuildFile; fileRef = 101E678C15A5177E00FFF744 /* README.txt */; };
23 | /* End PBXBuildFile section */
24 |
25 | /* Begin PBXFileReference section */
26 | 101E675515A511E700FFF744 /* PitchDetectorExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PitchDetectorExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
27 | 101E675915A511E700FFF744 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
28 | 101E675B15A511E700FFF744 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
29 | 101E675D15A511E700FFF744 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
30 | 101E676115A511E700FFF744 /* PitchDetectorExample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "PitchDetectorExample-Info.plist"; sourceTree = ""; };
31 | 101E676315A511E700FFF744 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
32 | 101E676515A511E700FFF744 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
33 | 101E676715A511E700FFF744 /* PitchDetectorExample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PitchDetectorExample-Prefix.pch"; sourceTree = ""; };
34 | 101E676815A511E700FFF744 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
35 | 101E676915A511E700FFF744 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
36 | 101E677C15A512A800FFF744 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
37 | 101E677D15A512A800FFF744 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
38 | 101E678015A5163300FFF744 /* AudioController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioController.h; sourceTree = ""; };
39 | 101E678115A5163300FFF744 /* AudioController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioController.m; sourceTree = ""; };
40 | 101E678215A5163300FFF744 /* FreqViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FreqViewController.h; sourceTree = ""; };
41 | 101E678315A5163300FFF744 /* FreqViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FreqViewController.m; sourceTree = ""; };
42 | 101E678415A5163300FFF744 /* PitchDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PitchDetector.h; sourceTree = ""; };
43 | 101E678515A5163300FFF744 /* PitchDetector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PitchDetector.m; sourceTree = ""; };
44 | 101E678615A5163300FFF744 /* TPCircularBuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = TPCircularBuffer.c; sourceTree = ""; };
45 | 101E678715A5163300FFF744 /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = ""; };
46 | 101E678C15A5177E00FFF744 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README.txt; path = ../README.txt; sourceTree = ""; };
47 | /* End PBXFileReference section */
48 |
49 | /* Begin PBXFrameworksBuildPhase section */
50 | 101E675215A511E700FFF744 /* Frameworks */ = {
51 | isa = PBXFrameworksBuildPhase;
52 | buildActionMask = 2147483647;
53 | files = (
54 | 101E677E15A512A800FFF744 /* Accelerate.framework in Frameworks */,
55 | 101E677F15A512A800FFF744 /* AudioToolbox.framework in Frameworks */,
56 | 101E675A15A511E700FFF744 /* UIKit.framework in Frameworks */,
57 | 101E675C15A511E700FFF744 /* Foundation.framework in Frameworks */,
58 | 101E675E15A511E700FFF744 /* CoreGraphics.framework in Frameworks */,
59 | );
60 | runOnlyForDeploymentPostprocessing = 0;
61 | };
62 | /* End PBXFrameworksBuildPhase section */
63 |
64 | /* Begin PBXGroup section */
65 | 101E674A15A511E700FFF744 = {
66 | isa = PBXGroup;
67 | children = (
68 | 101E675F15A511E700FFF744 /* PitchDetectorExample */,
69 | 101E675815A511E700FFF744 /* Frameworks */,
70 | 101E675615A511E700FFF744 /* Products */,
71 | );
72 | sourceTree = "";
73 | };
74 | 101E675615A511E700FFF744 /* Products */ = {
75 | isa = PBXGroup;
76 | children = (
77 | 101E675515A511E700FFF744 /* PitchDetectorExample.app */,
78 | );
79 | name = Products;
80 | sourceTree = "";
81 | };
82 | 101E675815A511E700FFF744 /* Frameworks */ = {
83 | isa = PBXGroup;
84 | children = (
85 | 101E677C15A512A800FFF744 /* Accelerate.framework */,
86 | 101E677D15A512A800FFF744 /* AudioToolbox.framework */,
87 | 101E675915A511E700FFF744 /* UIKit.framework */,
88 | 101E675B15A511E700FFF744 /* Foundation.framework */,
89 | 101E675D15A511E700FFF744 /* CoreGraphics.framework */,
90 | );
91 | name = Frameworks;
92 | sourceTree = "";
93 | };
94 | 101E675F15A511E700FFF744 /* PitchDetectorExample */ = {
95 | isa = PBXGroup;
96 | children = (
97 | 101E678015A5163300FFF744 /* AudioController.h */,
98 | 101E678115A5163300FFF744 /* AudioController.m */,
99 | 101E678215A5163300FFF744 /* FreqViewController.h */,
100 | 101E678315A5163300FFF744 /* FreqViewController.m */,
101 | 101E678415A5163300FFF744 /* PitchDetector.h */,
102 | 101E678515A5163300FFF744 /* PitchDetector.m */,
103 | 101E678615A5163300FFF744 /* TPCircularBuffer.c */,
104 | 101E678715A5163300FFF744 /* TPCircularBuffer.h */,
105 | 101E676815A511E700FFF744 /* AppDelegate.h */,
106 | 101E676915A511E700FFF744 /* AppDelegate.m */,
107 | 101E676015A511E700FFF744 /* Supporting Files */,
108 | 101E678C15A5177E00FFF744 /* README.txt */,
109 | );
110 | path = PitchDetectorExample;
111 | sourceTree = "";
112 | };
113 | 101E676015A511E700FFF744 /* Supporting Files */ = {
114 | isa = PBXGroup;
115 | children = (
116 | 101E676115A511E700FFF744 /* PitchDetectorExample-Info.plist */,
117 | 101E676215A511E700FFF744 /* InfoPlist.strings */,
118 | 101E676515A511E700FFF744 /* main.m */,
119 | 101E676715A511E700FFF744 /* PitchDetectorExample-Prefix.pch */,
120 | );
121 | name = "Supporting Files";
122 | sourceTree = "";
123 | };
124 | /* End PBXGroup section */
125 |
126 | /* Begin PBXNativeTarget section */
127 | 101E675415A511E700FFF744 /* PitchDetectorExample */ = {
128 | isa = PBXNativeTarget;
129 | buildConfigurationList = 101E676D15A511E700FFF744 /* Build configuration list for PBXNativeTarget "PitchDetectorExample" */;
130 | buildPhases = (
131 | 101E675115A511E700FFF744 /* Sources */,
132 | 101E675215A511E700FFF744 /* Frameworks */,
133 | 101E675315A511E700FFF744 /* Resources */,
134 | );
135 | buildRules = (
136 | );
137 | dependencies = (
138 | );
139 | name = PitchDetectorExample;
140 | productName = PitchDetectorExample;
141 | productReference = 101E675515A511E700FFF744 /* PitchDetectorExample.app */;
142 | productType = "com.apple.product-type.application";
143 | };
144 | /* End PBXNativeTarget section */
145 |
146 | /* Begin PBXProject section */
147 | 101E674C15A511E700FFF744 /* Project object */ = {
148 | isa = PBXProject;
149 | attributes = {
150 | LastUpgradeCheck = 0430;
151 | ORGANIZATIONNAME = "New York University";
152 | };
153 | buildConfigurationList = 101E674F15A511E700FFF744 /* Build configuration list for PBXProject "PitchDetectorExample" */;
154 | compatibilityVersion = "Xcode 3.2";
155 | developmentRegion = English;
156 | hasScannedForEncodings = 0;
157 | knownRegions = (
158 | en,
159 | );
160 | mainGroup = 101E674A15A511E700FFF744;
161 | productRefGroup = 101E675615A511E700FFF744 /* Products */;
162 | projectDirPath = "";
163 | projectRoot = "";
164 | targets = (
165 | 101E675415A511E700FFF744 /* PitchDetectorExample */,
166 | );
167 | };
168 | /* End PBXProject section */
169 |
170 | /* Begin PBXResourcesBuildPhase section */
171 | 101E675315A511E700FFF744 /* Resources */ = {
172 | isa = PBXResourcesBuildPhase;
173 | buildActionMask = 2147483647;
174 | files = (
175 | 101E676415A511E700FFF744 /* InfoPlist.strings in Resources */,
176 | 101E678D15A5177E00FFF744 /* README.txt in Resources */,
177 | );
178 | runOnlyForDeploymentPostprocessing = 0;
179 | };
180 | /* End PBXResourcesBuildPhase section */
181 |
182 | /* Begin PBXSourcesBuildPhase section */
183 | 101E675115A511E700FFF744 /* Sources */ = {
184 | isa = PBXSourcesBuildPhase;
185 | buildActionMask = 2147483647;
186 | files = (
187 | 101E676615A511E700FFF744 /* main.m in Sources */,
188 | 101E676A15A511E700FFF744 /* AppDelegate.m in Sources */,
189 | 101E678815A5163300FFF744 /* AudioController.m in Sources */,
190 | 101E678915A5163300FFF744 /* FreqViewController.m in Sources */,
191 | 101E678A15A5163300FFF744 /* PitchDetector.m in Sources */,
192 | 101E678B15A5163300FFF744 /* TPCircularBuffer.c in Sources */,
193 | );
194 | runOnlyForDeploymentPostprocessing = 0;
195 | };
196 | /* End PBXSourcesBuildPhase section */
197 |
198 | /* Begin PBXVariantGroup section */
199 | 101E676215A511E700FFF744 /* InfoPlist.strings */ = {
200 | isa = PBXVariantGroup;
201 | children = (
202 | 101E676315A511E700FFF744 /* en */,
203 | );
204 | name = InfoPlist.strings;
205 | sourceTree = "";
206 | };
207 | /* End PBXVariantGroup section */
208 |
209 | /* Begin XCBuildConfiguration section */
210 | 101E676B15A511E700FFF744 /* Debug */ = {
211 | isa = XCBuildConfiguration;
212 | buildSettings = {
213 | ALWAYS_SEARCH_USER_PATHS = NO;
214 | ARCHS = "$(ARCHS_STANDARD_32_BIT)";
215 | CLANG_ENABLE_OBJC_ARC = YES;
216 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
217 | COPY_PHASE_STRIP = NO;
218 | GCC_C_LANGUAGE_STANDARD = gnu99;
219 | GCC_DYNAMIC_NO_PIC = NO;
220 | GCC_OPTIMIZATION_LEVEL = 0;
221 | GCC_PREPROCESSOR_DEFINITIONS = (
222 | "DEBUG=1",
223 | "$(inherited)",
224 | );
225 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
226 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
227 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
228 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
229 | GCC_WARN_UNUSED_VARIABLE = YES;
230 | IPHONEOS_DEPLOYMENT_TARGET = 5.1;
231 | SDKROOT = iphoneos;
232 | };
233 | name = Debug;
234 | };
235 | 101E676C15A511E700FFF744 /* Release */ = {
236 | isa = XCBuildConfiguration;
237 | buildSettings = {
238 | ALWAYS_SEARCH_USER_PATHS = NO;
239 | ARCHS = "$(ARCHS_STANDARD_32_BIT)";
240 | CLANG_ENABLE_OBJC_ARC = YES;
241 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
242 | COPY_PHASE_STRIP = YES;
243 | GCC_C_LANGUAGE_STANDARD = gnu99;
244 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
245 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
246 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
247 | GCC_WARN_UNUSED_VARIABLE = YES;
248 | IPHONEOS_DEPLOYMENT_TARGET = 5.1;
249 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
250 | SDKROOT = iphoneos;
251 | VALIDATE_PRODUCT = YES;
252 | };
253 | name = Release;
254 | };
255 | 101E676E15A511E700FFF744 /* Debug */ = {
256 | isa = XCBuildConfiguration;
257 | buildSettings = {
258 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
259 | GCC_PREFIX_HEADER = "PitchDetectorExample/PitchDetectorExample-Prefix.pch";
260 | INFOPLIST_FILE = "PitchDetectorExample/PitchDetectorExample-Info.plist";
261 | PRODUCT_NAME = "$(TARGET_NAME)";
262 | WRAPPER_EXTENSION = app;
263 | };
264 | name = Debug;
265 | };
266 | 101E676F15A511E700FFF744 /* Release */ = {
267 | isa = XCBuildConfiguration;
268 | buildSettings = {
269 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
270 | GCC_PREFIX_HEADER = "PitchDetectorExample/PitchDetectorExample-Prefix.pch";
271 | INFOPLIST_FILE = "PitchDetectorExample/PitchDetectorExample-Info.plist";
272 | PRODUCT_NAME = "$(TARGET_NAME)";
273 | WRAPPER_EXTENSION = app;
274 | };
275 | name = Release;
276 | };
277 | /* End XCBuildConfiguration section */
278 |
279 | /* Begin XCConfigurationList section */
280 | 101E674F15A511E700FFF744 /* Build configuration list for PBXProject "PitchDetectorExample" */ = {
281 | isa = XCConfigurationList;
282 | buildConfigurations = (
283 | 101E676B15A511E700FFF744 /* Debug */,
284 | 101E676C15A511E700FFF744 /* Release */,
285 | );
286 | defaultConfigurationIsVisible = 0;
287 | defaultConfigurationName = Release;
288 | };
289 | 101E676D15A511E700FFF744 /* Build configuration list for PBXNativeTarget "PitchDetectorExample" */ = {
290 | isa = XCConfigurationList;
291 | buildConfigurations = (
292 | 101E676E15A511E700FFF744 /* Debug */,
293 | 101E676F15A511E700FFF744 /* Release */,
294 | );
295 | defaultConfigurationIsVisible = 0;
296 | };
297 | /* End XCConfigurationList section */
298 | };
299 | rootObject = 101E674C15A511E700FFF744 /* Project object */;
300 | }
301 |
--------------------------------------------------------------------------------