├── .gitignore ├── DTMFDemo ├── DTMFDemo │ ├── ViewController.h │ ├── AppDelegate.h │ ├── main.m │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── AppDelegate.m │ ├── Info.plist │ ├── ViewController.m │ └── Base.lproj │ │ └── Main.storyboard ├── DTMFDemoTests │ ├── Info.plist │ └── DTMFDemoTests.m └── DTMFDemo.xcodeproj │ └── project.pbxproj ├── README.md ├── TGSineWaveToneGenerator.h └── TGSineWaveToneGenerator.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | *.xcworkspace 13 | !default.xcworkspace 14 | xcuserdata 15 | profile 16 | *.moved-aside 17 | DerivedData 18 | .idea/ 19 | -------------------------------------------------------------------------------- /DTMFDemo/DTMFDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // DTMFDemo 4 | // 5 | // Created by Simon Grätzer on 04.07.14. 6 | // Copyright (c) 2014 Simon Grätzer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | - (IBAction)makeSound:(UIButton *)sender; 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /DTMFDemo/DTMFDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // DTMFDemo 4 | // 5 | // Created by Simon Grätzer on 04.07.14. 6 | // Copyright (c) 2014 Simon Grätzer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /DTMFDemo/DTMFDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // DTMFDemo 4 | // 5 | // Created by Simon Grätzer on 04.07.14. 6 | // Copyright (c) 2014 Simon Grätzer. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /DTMFDemo/DTMFDemo/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /DTMFDemo/DTMFDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // DTMFDemo 4 | // 5 | // Created by Simon Grätzer on 04.07.14. 6 | // Copyright (c) 2014 Simon Grätzer. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @implementation AppDelegate 12 | 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /DTMFDemo/DTMFDemo/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /DTMFDemo/DTMFDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | org.graetzer.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /DTMFDemo/DTMFDemoTests/DTMFDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // DTMFDemoTests.m 3 | // DTMFDemoTests 4 | // 5 | // Created by Simon Grätzer on 04.07.14. 6 | // Copyright (c) 2014 Simon Grätzer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DTMFDemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation DTMFDemoTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | XCTAssert(YES, @"Pass"); 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /DTMFDemo/DTMFDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | org.graetzer.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /DTMFDemo/DTMFDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // DTMFDemo 4 | // 5 | // Created by Simon Grätzer on 04.07.14. 6 | // Copyright (c) 2014 Simon Grätzer. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "TGSineWaveToneGenerator.h" 11 | 12 | @implementation ViewController { 13 | TGSineWaveToneGenerator *_generator; 14 | } 15 | 16 | - (void)viewDidLoad { 17 | [super viewDidLoad]; 18 | _generator = [[TGSineWaveToneGenerator alloc] initWithChannels:2]; 19 | } 20 | 21 | - (IBAction)makeSound:(UIButton *)sender { 22 | 23 | unichar c = [[sender titleForState:UIControlStateNormal] characterAtIndex:0]; 24 | 25 | // DTMF keypad frequencies 26 | double freqA[] = {1209, 1336, 1477}; 27 | double freqB[] = {697, 770, 852}; 28 | if (c == '0') { 29 | _generator->_channels[0].frequency = 1336; 30 | _generator->_channels[1].frequency = 941; 31 | } else if ('0' < c && c <= '9') { 32 | c = c -'1'; 33 | _generator->_channels[0].frequency = freqA[c % 3]; 34 | _generator->_channels[1].frequency = freqB[c / 3]; 35 | } else if (c == '#') { 36 | _generator->_channels[0].frequency = 1477; 37 | _generator->_channels[1].frequency = 941; 38 | } else {// Not sure 39 | _generator->_channels[0].frequency = 1209; 40 | _generator->_channels[1].frequency = 941; 41 | } 42 | [_generator playForDuration:0.5]; 43 | } 44 | @end 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | iOS-Tone-Generator 2 | ================== 3 | 4 | Tone Generator for iOS 5 | 6 | A reusable Tone Generator class roughly based upon the fine work of Matt Galagher, http://www.cocoawithlove.com/2010/10/ios-tone-generator-introduction-to.html 7 | 8 | 9 | 10 | A reusable class for generating simple sine waveform audio tones with specified frequency and amplitude. Can play continuously or for a specified duration. 11 | 12 | 13 | ### Multiple Channels 14 | 15 | You can add more than one tone channel, for example to generate [DTMF](http://en.wikipedia.org/wiki/Dual-tone_multi-frequency_signaling) 16 | tones. These are the tones you may hear when dialing on a keypad (either analog or even on iOS in the Telephone.app) 17 | 18 | ![DTMF Keypad](http://upload.wikimedia.org/wikipedia/commons/0/03/Phone_keypad_layout_color.png) 19 | 20 | ```Objective-C 21 | unichar c = '2'; // Example character, from a keypad 22 | 23 | TGSineWaveToneGenerator *gen = [[TGSineWaveToneGenerator alloc] initWithChannels:2]; 24 | // DTMF keypad frequencies 25 | double freqA[] = {1209, 1336, 1477}; 26 | double freqB[] = {697, 770, 852}; 27 | if (c == '0') { 28 | _toneGenerator->_channels[0].frequency = 1336; 29 | _toneGenerator->_channels[1].frequency = 941; 30 | } else if ('0' < c && c <= '9') { 31 | c = c -'1'; 32 | _toneGenerator->_channels[0].frequency = freqA[c % 3]; 33 | _toneGenerator->_channels[1].frequency = freqB[c / 3]; 34 | } else if (c == '#') { 35 | _toneGenerator->_channels[0].frequency = 1477; 36 | _toneGenerator->_channels[1].frequency = 941; 37 | } else {// Not sure 38 | _toneGenerator->_channels[0].frequency = 1209; 39 | _toneGenerator->_channels[1].frequency = 941; 40 | } 41 | [_toneGenerator playForDuration:0.15]; 42 | ``` 43 | -------------------------------------------------------------------------------- /TGSineWaveToneGenerator.h: -------------------------------------------------------------------------------- 1 | // 2 | // TGSineWaveToneGenerator.h 3 | // Tone Generator 4 | // 5 | // Created by Anthony Picciano on 6/12/13. 6 | // Copyright (c) 2013 Anthony Picciano. All rights reserved. 7 | // 8 | // Major contributions and updates by Simon Grätzer on 12/23/14. 9 | // 10 | // Based upon work by Matt Gallagher on 2010/10/20. 11 | // Copyright 2010 Matt Gallagher. All rights reserved. 12 | // 13 | // Permission is given to use this source code file, free of charge, in any 14 | // project, commercial or otherwise, entirely at your risk, with the condition 15 | // that any redistribution (in part or whole) of source code must retain 16 | // this copyright and permission notice. Attribution in compiled projects is 17 | // appreciated but not required. 18 | // 19 | 20 | #import 21 | @import AudioToolbox; 22 | @import AVFoundation; 23 | 24 | 25 | #define SINE_WAVE_TONE_GENERATOR_FREQUENCY_DEFAULT 440.0f 26 | 27 | #define SINE_WAVE_TONE_GENERATOR_SAMPLE_RATE_DEFAULT 44100.0f 28 | 29 | #define SINE_WAVE_TONE_GENERATOR_AMPLITUDE_LOW 0.01f 30 | #define SINE_WAVE_TONE_GENERATOR_AMPLITUDE_MEDIUM 0.02f 31 | #define SINE_WAVE_TONE_GENERATOR_AMPLITUDE_HIGH 0.03f 32 | #define SINE_WAVE_TONE_GENERATOR_AMPLITUDE_FULL 0.25f 33 | #define SINE_WAVE_TONE_GENERATOR_AMPLITUDE_DEFAULT SINE_WAVE_TONE_GENERATOR_AMPLITUDE_MEDIUM 34 | 35 | typedef struct { 36 | double frequency; 37 | double amplitude; 38 | double theta; 39 | } TGChannelInfo; 40 | 41 | @interface TGSineWaveToneGenerator : NSObject { 42 | @public 43 | AudioComponentInstance _toneUnit; 44 | double _sampleRate; 45 | TGChannelInfo *_channels; 46 | UInt32 _numChannels; 47 | } 48 | 49 | - (id)initWithChannels:(UInt32)size; 50 | - (id)initWithFrequency:(double)hertz amplitude:(double)volume; 51 | - (void)playForDuration:(NSTimeInterval)time; 52 | - (void)play; 53 | - (void)stop; 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /TGSineWaveToneGenerator.m: -------------------------------------------------------------------------------- 1 | // 2 | // TGSineWaveToneGenerator.m 3 | // Tone Generator 4 | // 5 | // Created by Anthony Picciano on 6/12/13. 6 | // Copyright (c) 2013 Anthony Picciano. All rights reserved. 7 | // 8 | // Major contributions and updates by Simon Grätzer on 12/23/14. 9 | // 10 | // Based upon work by Matt Gallagher on 2010/10/20. 11 | // Copyright 2010 Matt Gallagher. All rights reserved. 12 | // 13 | // Permission is given to use this source code file, free of charge, in any 14 | // project, commercial or otherwise, entirely at your risk, with the condition 15 | // that any redistribution (in part or whole) of source code must retain 16 | // this copyright and permission notice. Attribution in compiled projects is 17 | // appreciated but not required. 18 | // 19 | 20 | #import "TGSineWaveToneGenerator.h" 21 | #import 22 | 23 | 24 | OSStatus RenderTone( 25 | void *inRefCon, 26 | AudioUnitRenderActionFlags *ioActionFlags, 27 | const AudioTimeStamp *inTimeStamp, 28 | UInt32 inBusNumber, 29 | UInt32 inNumberFrames, 30 | AudioBufferList *ioData) 31 | 32 | { 33 | // Get the tone parameters out of the object 34 | TGSineWaveToneGenerator *toneGenerator = (__bridge TGSineWaveToneGenerator *)inRefCon; 35 | assert(ioData->mNumberBuffers == toneGenerator->_numChannels); 36 | 37 | for (size_t chan = 0; chan < toneGenerator->_numChannels; chan++) { 38 | double theta = toneGenerator->_channels[chan].theta; 39 | double amplitude = toneGenerator->_channels[chan].amplitude; 40 | double theta_increment = 2.0 * M_PI * toneGenerator->_channels[chan].frequency / toneGenerator->_sampleRate; 41 | 42 | Float32 *buffer = (Float32 *)ioData->mBuffers[chan].mData; 43 | // Generate the samples 44 | for (UInt32 frame = 0; frame < inNumberFrames; frame++) { 45 | buffer[frame] = sin(theta) * amplitude; 46 | 47 | theta += theta_increment; 48 | // Basically do modulo 49 | if (theta > 2.0 * M_PI) { 50 | theta -= 2.0 * M_PI; 51 | } 52 | } 53 | 54 | // Store the theta back in the view controller 55 | toneGenerator->_channels[chan].theta = theta; 56 | } 57 | 58 | return noErr; 59 | } 60 | 61 | @implementation TGSineWaveToneGenerator 62 | 63 | - (id)init 64 | { 65 | return [self initWithFrequency:SINE_WAVE_TONE_GENERATOR_FREQUENCY_DEFAULT amplitude:SINE_WAVE_TONE_GENERATOR_AMPLITUDE_DEFAULT]; 66 | } 67 | 68 | - (id)initWithFrequency:(double)hertz amplitude:(double)volume { 69 | if (self = [super init]) { 70 | _numChannels = 1; 71 | _channels = calloc(sizeof(TGChannelInfo), _numChannels); 72 | if (_channels == NULL) return nil; 73 | 74 | _channels[0].frequency = hertz; 75 | _channels[0].amplitude = volume; 76 | 77 | _sampleRate = SINE_WAVE_TONE_GENERATOR_SAMPLE_RATE_DEFAULT; 78 | [self _setupAudioSession]; 79 | // OSStatus result = AudioSessionInitialize(NULL, NULL, ToneInterruptionListener, (__bridge void *)(self)); 80 | // if (result == kAudioSessionNoError) 81 | // { 82 | // UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback; 83 | // AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory); 84 | // } 85 | // AudioSessionSetActive(true); 86 | } 87 | 88 | return self; 89 | } 90 | 91 | - (id)initWithChannels:(UInt32)size { 92 | if (self = [super init]) { 93 | _numChannels = size; 94 | _channels = calloc(sizeof(TGChannelInfo), _numChannels); 95 | if (_channels == NULL) return nil; 96 | 97 | for (size_t i = 0; i < _numChannels; i++) { 98 | _channels[i].frequency = SINE_WAVE_TONE_GENERATOR_FREQUENCY_DEFAULT / ( i + 0.4);//Just because 99 | _channels[i].amplitude = SINE_WAVE_TONE_GENERATOR_AMPLITUDE_DEFAULT; 100 | } 101 | _sampleRate = SINE_WAVE_TONE_GENERATOR_SAMPLE_RATE_DEFAULT; 102 | [self _setupAudioSession]; 103 | } 104 | 105 | return self; 106 | 107 | } 108 | 109 | - (void)dealloc { 110 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 111 | if (_channels != NULL) { 112 | free(_channels); 113 | } 114 | } 115 | 116 | - (void)playForDuration:(NSTimeInterval)time { 117 | [self play]; 118 | [self performSelector:@selector(stop) withObject:nil afterDelay:time]; 119 | } 120 | 121 | - (void)play { 122 | if (!_toneUnit) { 123 | [self _createToneUnit]; 124 | 125 | // Stop changing parameters on the unit 126 | OSErr err = AudioUnitInitialize(_toneUnit); 127 | NSAssert1(err == noErr, @"Error initializing unit: %hd", err); 128 | 129 | // Start playback 130 | err = AudioOutputUnitStart(_toneUnit); 131 | NSAssert1(err == noErr, @"Error starting unit: %hd", err); 132 | } 133 | } 134 | 135 | - (void)stop { 136 | if (_toneUnit) { 137 | AudioOutputUnitStop(_toneUnit); 138 | AudioUnitUninitialize(_toneUnit); 139 | AudioComponentInstanceDispose(_toneUnit); 140 | _toneUnit = nil; 141 | } 142 | } 143 | 144 | - (void)_setupAudioSession { 145 | AVAudioSession *audioSession = [AVAudioSession sharedInstance]; 146 | BOOL ok; 147 | NSError *setCategoryError = nil; 148 | ok = [audioSession setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError]; 149 | NSAssert1(ok, @"Audio error %@", setCategoryError); 150 | [[NSNotificationCenter defaultCenter] addObserver:self 151 | selector:@selector(_handleInterruption:) 152 | name:AVAudioSessionInterruptionNotification 153 | object:audioSession]; 154 | } 155 | 156 | - (void)_handleInterruption:(id)sender { 157 | [self stop]; 158 | } 159 | 160 | - (void)_createToneUnit { 161 | // Configure the search parameters to find the default playback output unit 162 | // (called the kAudioUnitSubType_RemoteIO on iOS but 163 | // kAudioUnitSubType_DefaultOutput on Mac OS X) 164 | AudioComponentDescription defaultOutputDescription; 165 | defaultOutputDescription.componentType = kAudioUnitType_Output; 166 | defaultOutputDescription.componentSubType = kAudioUnitSubType_RemoteIO; 167 | defaultOutputDescription.componentManufacturer = kAudioUnitManufacturer_Apple; 168 | defaultOutputDescription.componentFlags = 0; 169 | defaultOutputDescription.componentFlagsMask = 0; 170 | 171 | // Get the default playback output unit 172 | AudioComponent defaultOutput = AudioComponentFindNext(NULL, &defaultOutputDescription); 173 | NSAssert(defaultOutput, @"Can't find default output"); 174 | 175 | // Create a new unit based on this that we'll use for output 176 | OSErr err = AudioComponentInstanceNew(defaultOutput, &_toneUnit); 177 | NSAssert1(_toneUnit, @"Error creating unit: %hd", err); 178 | 179 | // Set our tone rendering function on the unit 180 | AURenderCallbackStruct input; 181 | input.inputProc = RenderTone; 182 | input.inputProcRefCon = (__bridge void *)(self); 183 | err = AudioUnitSetProperty(_toneUnit, 184 | kAudioUnitProperty_SetRenderCallback, 185 | kAudioUnitScope_Input, 186 | 0, 187 | &input, 188 | sizeof(input)); 189 | NSAssert1(err == noErr, @"Error setting callback: %hd", err); 190 | 191 | // Set the format to 32 bit, single channel, floating point, linear PCM 192 | const int four_bytes_per_float = 4; 193 | const int eight_bits_per_byte = 8; 194 | AudioStreamBasicDescription streamFormat; 195 | streamFormat.mSampleRate = _sampleRate; 196 | streamFormat.mFormatID = kAudioFormatLinearPCM; 197 | streamFormat.mFormatFlags = 198 | kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved; 199 | streamFormat.mBytesPerPacket = four_bytes_per_float; 200 | streamFormat.mFramesPerPacket = 1; 201 | streamFormat.mBytesPerFrame = four_bytes_per_float; 202 | streamFormat.mChannelsPerFrame = _numChannels; 203 | streamFormat.mBitsPerChannel = four_bytes_per_float * eight_bits_per_byte; 204 | err = AudioUnitSetProperty (_toneUnit, 205 | kAudioUnitProperty_StreamFormat, 206 | kAudioUnitScope_Input, 207 | 0, 208 | &streamFormat, 209 | sizeof(AudioStreamBasicDescription)); 210 | NSAssert1(err == noErr, @"Error setting stream format: %hd", err); 211 | } 212 | 213 | @end 214 | -------------------------------------------------------------------------------- /DTMFDemo/DTMFDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 28 | 41 | 54 | 67 | 80 | 93 | 106 | 119 | 132 | 145 | 158 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | -------------------------------------------------------------------------------- /DTMFDemo/DTMFDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | F415880519660C15003377E3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F415880419660C15003377E3 /* main.m */; }; 11 | F415880819660C15003377E3 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F415880719660C15003377E3 /* AppDelegate.m */; }; 12 | F415880B19660C15003377E3 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F415880A19660C15003377E3 /* ViewController.m */; }; 13 | F415880E19660C15003377E3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F415880C19660C15003377E3 /* Main.storyboard */; }; 14 | F415881019660C15003377E3 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F415880F19660C15003377E3 /* Images.xcassets */; }; 15 | F415881C19660C15003377E3 /* DTMFDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F415881B19660C15003377E3 /* DTMFDemoTests.m */; }; 16 | F415882719660C25003377E3 /* TGSineWaveToneGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = F415882619660C25003377E3 /* TGSineWaveToneGenerator.m */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXContainerItemProxy section */ 20 | F415881619660C15003377E3 /* PBXContainerItemProxy */ = { 21 | isa = PBXContainerItemProxy; 22 | containerPortal = F41587F719660C15003377E3 /* Project object */; 23 | proxyType = 1; 24 | remoteGlobalIDString = F41587FE19660C15003377E3; 25 | remoteInfo = DTMFDemo; 26 | }; 27 | /* End PBXContainerItemProxy section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | F41587FF19660C15003377E3 /* DTMFDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DTMFDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | F415880319660C15003377E3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 32 | F415880419660C15003377E3 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 33 | F415880619660C15003377E3 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 34 | F415880719660C15003377E3 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 35 | F415880919660C15003377E3 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 36 | F415880A19660C15003377E3 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 37 | F415880D19660C15003377E3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 38 | F415880F19660C15003377E3 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 39 | F415881519660C15003377E3 /* DTMFDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DTMFDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | F415881A19660C15003377E3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 41 | F415881B19660C15003377E3 /* DTMFDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DTMFDemoTests.m; sourceTree = ""; }; 42 | F415882519660C25003377E3 /* TGSineWaveToneGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TGSineWaveToneGenerator.h; path = ../TGSineWaveToneGenerator.h; sourceTree = ""; }; 43 | F415882619660C25003377E3 /* TGSineWaveToneGenerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TGSineWaveToneGenerator.m; path = ../TGSineWaveToneGenerator.m; sourceTree = ""; }; 44 | /* End PBXFileReference section */ 45 | 46 | /* Begin PBXFrameworksBuildPhase section */ 47 | F41587FC19660C15003377E3 /* Frameworks */ = { 48 | isa = PBXFrameworksBuildPhase; 49 | buildActionMask = 2147483647; 50 | files = ( 51 | ); 52 | runOnlyForDeploymentPostprocessing = 0; 53 | }; 54 | F415881219660C15003377E3 /* Frameworks */ = { 55 | isa = PBXFrameworksBuildPhase; 56 | buildActionMask = 2147483647; 57 | files = ( 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | F41587F619660C15003377E3 = { 65 | isa = PBXGroup; 66 | children = ( 67 | F415882519660C25003377E3 /* TGSineWaveToneGenerator.h */, 68 | F415882619660C25003377E3 /* TGSineWaveToneGenerator.m */, 69 | F415880119660C15003377E3 /* DTMFDemo */, 70 | F415881819660C15003377E3 /* DTMFDemoTests */, 71 | F415880019660C15003377E3 /* Products */, 72 | ); 73 | sourceTree = ""; 74 | }; 75 | F415880019660C15003377E3 /* Products */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | F41587FF19660C15003377E3 /* DTMFDemo.app */, 79 | F415881519660C15003377E3 /* DTMFDemoTests.xctest */, 80 | ); 81 | name = Products; 82 | sourceTree = ""; 83 | }; 84 | F415880119660C15003377E3 /* DTMFDemo */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | F415880619660C15003377E3 /* AppDelegate.h */, 88 | F415880719660C15003377E3 /* AppDelegate.m */, 89 | F415880919660C15003377E3 /* ViewController.h */, 90 | F415880A19660C15003377E3 /* ViewController.m */, 91 | F415880C19660C15003377E3 /* Main.storyboard */, 92 | F415880F19660C15003377E3 /* Images.xcassets */, 93 | F415880219660C15003377E3 /* Supporting Files */, 94 | ); 95 | path = DTMFDemo; 96 | sourceTree = ""; 97 | }; 98 | F415880219660C15003377E3 /* Supporting Files */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | F415880319660C15003377E3 /* Info.plist */, 102 | F415880419660C15003377E3 /* main.m */, 103 | ); 104 | name = "Supporting Files"; 105 | sourceTree = ""; 106 | }; 107 | F415881819660C15003377E3 /* DTMFDemoTests */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | F415881B19660C15003377E3 /* DTMFDemoTests.m */, 111 | F415881919660C15003377E3 /* Supporting Files */, 112 | ); 113 | path = DTMFDemoTests; 114 | sourceTree = ""; 115 | }; 116 | F415881919660C15003377E3 /* Supporting Files */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | F415881A19660C15003377E3 /* Info.plist */, 120 | ); 121 | name = "Supporting Files"; 122 | sourceTree = ""; 123 | }; 124 | /* End PBXGroup section */ 125 | 126 | /* Begin PBXNativeTarget section */ 127 | F41587FE19660C15003377E3 /* DTMFDemo */ = { 128 | isa = PBXNativeTarget; 129 | buildConfigurationList = F415881F19660C15003377E3 /* Build configuration list for PBXNativeTarget "DTMFDemo" */; 130 | buildPhases = ( 131 | F41587FB19660C15003377E3 /* Sources */, 132 | F41587FC19660C15003377E3 /* Frameworks */, 133 | F41587FD19660C15003377E3 /* Resources */, 134 | ); 135 | buildRules = ( 136 | ); 137 | dependencies = ( 138 | ); 139 | name = DTMFDemo; 140 | productName = DTMFDemo; 141 | productReference = F41587FF19660C15003377E3 /* DTMFDemo.app */; 142 | productType = "com.apple.product-type.application"; 143 | }; 144 | F415881419660C15003377E3 /* DTMFDemoTests */ = { 145 | isa = PBXNativeTarget; 146 | buildConfigurationList = F415882219660C15003377E3 /* Build configuration list for PBXNativeTarget "DTMFDemoTests" */; 147 | buildPhases = ( 148 | F415881119660C15003377E3 /* Sources */, 149 | F415881219660C15003377E3 /* Frameworks */, 150 | F415881319660C15003377E3 /* Resources */, 151 | ); 152 | buildRules = ( 153 | ); 154 | dependencies = ( 155 | F415881719660C15003377E3 /* PBXTargetDependency */, 156 | ); 157 | name = DTMFDemoTests; 158 | productName = DTMFDemoTests; 159 | productReference = F415881519660C15003377E3 /* DTMFDemoTests.xctest */; 160 | productType = "com.apple.product-type.bundle.unit-test"; 161 | }; 162 | /* End PBXNativeTarget section */ 163 | 164 | /* Begin PBXProject section */ 165 | F41587F719660C15003377E3 /* Project object */ = { 166 | isa = PBXProject; 167 | attributes = { 168 | LastUpgradeCheck = 0600; 169 | ORGANIZATIONNAME = "Simon Grätzer"; 170 | TargetAttributes = { 171 | F41587FE19660C15003377E3 = { 172 | CreatedOnToolsVersion = 6.0; 173 | }; 174 | F415881419660C15003377E3 = { 175 | CreatedOnToolsVersion = 6.0; 176 | TestTargetID = F41587FE19660C15003377E3; 177 | }; 178 | }; 179 | }; 180 | buildConfigurationList = F41587FA19660C15003377E3 /* Build configuration list for PBXProject "DTMFDemo" */; 181 | compatibilityVersion = "Xcode 3.2"; 182 | developmentRegion = English; 183 | hasScannedForEncodings = 0; 184 | knownRegions = ( 185 | en, 186 | Base, 187 | ); 188 | mainGroup = F41587F619660C15003377E3; 189 | productRefGroup = F415880019660C15003377E3 /* Products */; 190 | projectDirPath = ""; 191 | projectRoot = ""; 192 | targets = ( 193 | F41587FE19660C15003377E3 /* DTMFDemo */, 194 | F415881419660C15003377E3 /* DTMFDemoTests */, 195 | ); 196 | }; 197 | /* End PBXProject section */ 198 | 199 | /* Begin PBXResourcesBuildPhase section */ 200 | F41587FD19660C15003377E3 /* Resources */ = { 201 | isa = PBXResourcesBuildPhase; 202 | buildActionMask = 2147483647; 203 | files = ( 204 | F415880E19660C15003377E3 /* Main.storyboard in Resources */, 205 | F415881019660C15003377E3 /* Images.xcassets in Resources */, 206 | ); 207 | runOnlyForDeploymentPostprocessing = 0; 208 | }; 209 | F415881319660C15003377E3 /* Resources */ = { 210 | isa = PBXResourcesBuildPhase; 211 | buildActionMask = 2147483647; 212 | files = ( 213 | ); 214 | runOnlyForDeploymentPostprocessing = 0; 215 | }; 216 | /* End PBXResourcesBuildPhase section */ 217 | 218 | /* Begin PBXSourcesBuildPhase section */ 219 | F41587FB19660C15003377E3 /* Sources */ = { 220 | isa = PBXSourcesBuildPhase; 221 | buildActionMask = 2147483647; 222 | files = ( 223 | F415880B19660C15003377E3 /* ViewController.m in Sources */, 224 | F415880819660C15003377E3 /* AppDelegate.m in Sources */, 225 | F415882719660C25003377E3 /* TGSineWaveToneGenerator.m in Sources */, 226 | F415880519660C15003377E3 /* main.m in Sources */, 227 | ); 228 | runOnlyForDeploymentPostprocessing = 0; 229 | }; 230 | F415881119660C15003377E3 /* Sources */ = { 231 | isa = PBXSourcesBuildPhase; 232 | buildActionMask = 2147483647; 233 | files = ( 234 | F415881C19660C15003377E3 /* DTMFDemoTests.m in Sources */, 235 | ); 236 | runOnlyForDeploymentPostprocessing = 0; 237 | }; 238 | /* End PBXSourcesBuildPhase section */ 239 | 240 | /* Begin PBXTargetDependency section */ 241 | F415881719660C15003377E3 /* PBXTargetDependency */ = { 242 | isa = PBXTargetDependency; 243 | target = F41587FE19660C15003377E3 /* DTMFDemo */; 244 | targetProxy = F415881619660C15003377E3 /* PBXContainerItemProxy */; 245 | }; 246 | /* End PBXTargetDependency section */ 247 | 248 | /* Begin PBXVariantGroup section */ 249 | F415880C19660C15003377E3 /* Main.storyboard */ = { 250 | isa = PBXVariantGroup; 251 | children = ( 252 | F415880D19660C15003377E3 /* Base */, 253 | ); 254 | name = Main.storyboard; 255 | sourceTree = ""; 256 | }; 257 | /* End PBXVariantGroup section */ 258 | 259 | /* Begin XCBuildConfiguration section */ 260 | F415881D19660C15003377E3 /* Debug */ = { 261 | isa = XCBuildConfiguration; 262 | buildSettings = { 263 | ALWAYS_SEARCH_USER_PATHS = NO; 264 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 265 | CLANG_CXX_LIBRARY = "libc++"; 266 | CLANG_ENABLE_MODULES = YES; 267 | CLANG_ENABLE_OBJC_ARC = YES; 268 | CLANG_WARN_BOOL_CONVERSION = YES; 269 | CLANG_WARN_CONSTANT_CONVERSION = YES; 270 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 271 | CLANG_WARN_EMPTY_BODY = YES; 272 | CLANG_WARN_ENUM_CONVERSION = YES; 273 | CLANG_WARN_INT_CONVERSION = YES; 274 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 275 | CLANG_WARN_UNREACHABLE_CODE = YES; 276 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 277 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 278 | COPY_PHASE_STRIP = NO; 279 | ENABLE_STRICT_OBJC_MSGSEND = YES; 280 | GCC_C_LANGUAGE_STANDARD = gnu99; 281 | GCC_DYNAMIC_NO_PIC = NO; 282 | GCC_OPTIMIZATION_LEVEL = 0; 283 | GCC_PREPROCESSOR_DEFINITIONS = ( 284 | "DEBUG=1", 285 | "$(inherited)", 286 | ); 287 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 288 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 289 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 290 | GCC_WARN_UNDECLARED_SELECTOR = YES; 291 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 292 | GCC_WARN_UNUSED_FUNCTION = YES; 293 | GCC_WARN_UNUSED_VARIABLE = YES; 294 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 295 | METAL_ENABLE_DEBUG_INFO = YES; 296 | ONLY_ACTIVE_ARCH = YES; 297 | SDKROOT = iphoneos; 298 | }; 299 | name = Debug; 300 | }; 301 | F415881E19660C15003377E3 /* Release */ = { 302 | isa = XCBuildConfiguration; 303 | buildSettings = { 304 | ALWAYS_SEARCH_USER_PATHS = NO; 305 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 306 | CLANG_CXX_LIBRARY = "libc++"; 307 | CLANG_ENABLE_MODULES = YES; 308 | CLANG_ENABLE_OBJC_ARC = YES; 309 | CLANG_WARN_BOOL_CONVERSION = YES; 310 | CLANG_WARN_CONSTANT_CONVERSION = YES; 311 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 312 | CLANG_WARN_EMPTY_BODY = YES; 313 | CLANG_WARN_ENUM_CONVERSION = YES; 314 | CLANG_WARN_INT_CONVERSION = YES; 315 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 316 | CLANG_WARN_UNREACHABLE_CODE = YES; 317 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 318 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 319 | COPY_PHASE_STRIP = YES; 320 | ENABLE_NS_ASSERTIONS = NO; 321 | ENABLE_STRICT_OBJC_MSGSEND = YES; 322 | GCC_C_LANGUAGE_STANDARD = gnu99; 323 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 324 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 325 | GCC_WARN_UNDECLARED_SELECTOR = YES; 326 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 327 | GCC_WARN_UNUSED_FUNCTION = YES; 328 | GCC_WARN_UNUSED_VARIABLE = YES; 329 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 330 | METAL_ENABLE_DEBUG_INFO = NO; 331 | SDKROOT = iphoneos; 332 | VALIDATE_PRODUCT = YES; 333 | }; 334 | name = Release; 335 | }; 336 | F415882019660C15003377E3 /* Debug */ = { 337 | isa = XCBuildConfiguration; 338 | buildSettings = { 339 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 340 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 341 | INFOPLIST_FILE = DTMFDemo/Info.plist; 342 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 343 | PRODUCT_NAME = "$(TARGET_NAME)"; 344 | }; 345 | name = Debug; 346 | }; 347 | F415882119660C15003377E3 /* Release */ = { 348 | isa = XCBuildConfiguration; 349 | buildSettings = { 350 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 351 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 352 | INFOPLIST_FILE = DTMFDemo/Info.plist; 353 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 354 | PRODUCT_NAME = "$(TARGET_NAME)"; 355 | }; 356 | name = Release; 357 | }; 358 | F415882319660C15003377E3 /* Debug */ = { 359 | isa = XCBuildConfiguration; 360 | buildSettings = { 361 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/DTMFDemo.app/DTMFDemo"; 362 | FRAMEWORK_SEARCH_PATHS = ( 363 | "$(SDKROOT)/Developer/Library/Frameworks", 364 | "$(inherited)", 365 | ); 366 | GCC_PREPROCESSOR_DEFINITIONS = ( 367 | "DEBUG=1", 368 | "$(inherited)", 369 | ); 370 | INFOPLIST_FILE = DTMFDemoTests/Info.plist; 371 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 372 | METAL_ENABLE_DEBUG_INFO = YES; 373 | PRODUCT_NAME = "$(TARGET_NAME)"; 374 | TEST_HOST = "$(BUNDLE_LOADER)"; 375 | }; 376 | name = Debug; 377 | }; 378 | F415882419660C15003377E3 /* Release */ = { 379 | isa = XCBuildConfiguration; 380 | buildSettings = { 381 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/DTMFDemo.app/DTMFDemo"; 382 | FRAMEWORK_SEARCH_PATHS = ( 383 | "$(SDKROOT)/Developer/Library/Frameworks", 384 | "$(inherited)", 385 | ); 386 | INFOPLIST_FILE = DTMFDemoTests/Info.plist; 387 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 388 | METAL_ENABLE_DEBUG_INFO = NO; 389 | PRODUCT_NAME = "$(TARGET_NAME)"; 390 | TEST_HOST = "$(BUNDLE_LOADER)"; 391 | }; 392 | name = Release; 393 | }; 394 | /* End XCBuildConfiguration section */ 395 | 396 | /* Begin XCConfigurationList section */ 397 | F41587FA19660C15003377E3 /* Build configuration list for PBXProject "DTMFDemo" */ = { 398 | isa = XCConfigurationList; 399 | buildConfigurations = ( 400 | F415881D19660C15003377E3 /* Debug */, 401 | F415881E19660C15003377E3 /* Release */, 402 | ); 403 | defaultConfigurationIsVisible = 0; 404 | defaultConfigurationName = Release; 405 | }; 406 | F415881F19660C15003377E3 /* Build configuration list for PBXNativeTarget "DTMFDemo" */ = { 407 | isa = XCConfigurationList; 408 | buildConfigurations = ( 409 | F415882019660C15003377E3 /* Debug */, 410 | F415882119660C15003377E3 /* Release */, 411 | ); 412 | defaultConfigurationIsVisible = 0; 413 | }; 414 | F415882219660C15003377E3 /* Build configuration list for PBXNativeTarget "DTMFDemoTests" */ = { 415 | isa = XCConfigurationList; 416 | buildConfigurations = ( 417 | F415882319660C15003377E3 /* Debug */, 418 | F415882419660C15003377E3 /* Release */, 419 | ); 420 | defaultConfigurationIsVisible = 0; 421 | }; 422 | /* End XCConfigurationList section */ 423 | }; 424 | rootObject = F41587F719660C15003377E3 /* Project object */; 425 | } 426 | --------------------------------------------------------------------------------