├── AudioRecorder.xcodeproj
├── xcuserdata
│ ├── apple.xcuserdatad
│ │ ├── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ └── AudioRecorder.xcscheme
│ └── xiaokai.zhan.xcuserdatad
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── AudioRecorder.xcscheme
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── AudioRecorder
├── AudioSession
│ ├── AVAudioSession+RouteUtils.h
│ ├── ELAudioSession.h
│ ├── ELAudioSession.m
│ └── AVAudioSession+RouteUtils.m
├── ViewController.h
├── AppDelegate.h
├── AudioRecorder.h
├── utils
│ ├── CommonUtil.h
│ └── CommonUtil.m
├── main.m
├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── ViewController.m
├── Info.plist
├── Base.lproj
│ └── LaunchScreen.storyboard
├── AppDelegate.m
├── ViewController.xib
└── AudioRecorder.m
├── AudioRecorderTests
├── Info.plist
└── AudioRecorderTests.m
└── AudioRecorderUITests
├── Info.plist
└── AudioRecorderUITests.m
/AudioRecorder.xcodeproj/xcuserdata/apple.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/AudioRecorder.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/AudioRecorder/AudioSession/AVAudioSession+RouteUtils.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface AVAudioSession (RouteUtils)
4 |
5 | - (BOOL)usingBlueTooth;
6 |
7 | - (BOOL)usingWiredMicrophone;
8 |
9 | - (BOOL)shouldShowEarphoneAlert;
10 |
11 | @end
12 |
--------------------------------------------------------------------------------
/AudioRecorder/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // AudioRecorder
4 | //
5 | // Created by apple on 2017/2/16.
6 | // Copyright © 2017年 xiaokai.zhan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/AudioRecorder/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // AudioRecorder
4 | //
5 | // Created by apple on 2017/2/16.
6 | // Copyright © 2017年 xiaokai.zhan. 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 |
--------------------------------------------------------------------------------
/AudioRecorder/AudioRecorder.h:
--------------------------------------------------------------------------------
1 | //
2 | // AudioRecorder.h
3 | // AudioRecorder
4 | //
5 | // Created by apple on 2017/2/21.
6 | // Copyright © 2017年 xiaokai.zhan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AudioRecorder : NSObject
12 |
13 | - (id) initWithPath:(NSString*) path;
14 |
15 | - (void)start;
16 |
17 | - (void)stop;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/AudioRecorder/utils/CommonUtil.h:
--------------------------------------------------------------------------------
1 | //
2 | // CommonUtil.h
3 | // video_player
4 | //
5 | // Created by apple on 16/8/25.
6 | // Copyright © 2016年 xiaokai.zhan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CommonUtil : NSObject
12 |
13 | +(NSString *)bundlePath:(NSString *)fileName;
14 |
15 | +(NSString *)documentsPath:(NSString *)fileName;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/AudioRecorder/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // AudioRecorder
4 | //
5 | // Created by apple on 2017/2/16.
6 | // Copyright © 2017年 xiaokai.zhan. 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 |
--------------------------------------------------------------------------------
/AudioRecorder/utils/CommonUtil.m:
--------------------------------------------------------------------------------
1 | //
2 | // CommonUtil.m
3 | // video_player
4 | //
5 | // Created by apple on 16/8/25.
6 | // Copyright © 2016年 xiaokai.zhan. All rights reserved.
7 | //
8 |
9 | #import "CommonUtil.h"
10 |
11 | @implementation CommonUtil
12 |
13 | +(NSString *)bundlePath:(NSString *)fileName {
14 | return [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:fileName];
15 | }
16 |
17 | +(NSString *)documentsPath:(NSString *)fileName {
18 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
19 | NSString *documentsDirectory = [paths objectAtIndex:0];
20 | return [documentsDirectory stringByAppendingPathComponent:fileName];
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/AudioRecorderTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/AudioRecorderUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/AudioRecorder/Assets.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" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/AudioRecorder.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | AudioRecorder.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 188EA2421E55D4FE00E858A4
16 |
17 | primary
18 |
19 |
20 | 188EA25B1E55D4FF00E858A4
21 |
22 | primary
23 |
24 |
25 | 188EA2661E55D4FF00E858A4
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/AudioRecorder.xcodeproj/xcuserdata/xiaokai.zhan.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | AudioRecorder.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 188EA2421E55D4FE00E858A4
16 |
17 | primary
18 |
19 |
20 | 188EA25B1E55D4FF00E858A4
21 |
22 | primary
23 |
24 |
25 | 188EA2661E55D4FF00E858A4
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/AudioRecorder/AudioSession/ELAudioSession.h:
--------------------------------------------------------------------------------
1 | //
2 | // ELAudioSession.h
3 | // video_player
4 | //
5 | // Created by apple on 16/9/5.
6 | // Copyright © 2016年 xiaokai.zhan. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | extern const NSTimeInterval AUSAudioSessionLatency_Background;
13 | extern const NSTimeInterval AUSAudioSessionLatency_Default;
14 | extern const NSTimeInterval AUSAudioSessionLatency_LowLatency;
15 |
16 | @interface ELAudioSession : NSObject
17 |
18 | + (ELAudioSession *)sharedInstance;
19 |
20 | @property(nonatomic, strong) AVAudioSession *audioSession; // Underlying system audio session
21 | @property(nonatomic, assign) Float64 preferredSampleRate;
22 | @property(nonatomic, assign, readonly) Float64 currentSampleRate;
23 | @property(nonatomic, assign) NSTimeInterval preferredLatency;
24 | @property(nonatomic, assign) BOOL active;
25 | @property(nonatomic, strong) NSString *category;
26 |
27 | - (void)addRouteChangeListener;
28 | @end
29 |
--------------------------------------------------------------------------------
/AudioRecorderTests/AudioRecorderTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // AudioRecorderTests.m
3 | // AudioRecorderTests
4 | //
5 | // Created by apple on 2017/2/16.
6 | // Copyright © 2017年 xiaokai.zhan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AudioRecorderTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation AudioRecorderTests
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 | // Use XCTAssert and related functions to verify your tests produce the correct results.
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 |
--------------------------------------------------------------------------------
/AudioRecorder/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // AudioRecorder
4 | //
5 | // Created by apple on 2017/2/16.
6 | // Copyright © 2017年 xiaokai.zhan. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "AudioRecorder.h"
11 | #import "CommonUtil.h"
12 |
13 | @interface ViewController ()
14 |
15 | @end
16 |
17 | @implementation ViewController
18 | {
19 | AudioRecorder* _recorder;
20 | }
21 | - (void)viewDidLoad {
22 | [super viewDidLoad];
23 | // Do any additional setup after loading the view, typically from a nib.
24 | }
25 |
26 | - (IBAction)record:(id)sender {
27 | NSLog(@"Forward To Recorder Page...");
28 | NSString* filePath = [CommonUtil documentsPath:@"recorder.caf"];
29 | _recorder = [[AudioRecorder alloc] initWithPath:filePath];
30 | [_recorder start];
31 | }
32 |
33 | - (IBAction)stop:(id)sender {
34 | if(_recorder) {
35 | [_recorder stop];
36 | }
37 | }
38 |
39 | - (void)didReceiveMemoryWarning {
40 | [super didReceiveMemoryWarning];
41 | // Dispose of any resources that can be recreated.
42 | }
43 |
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/AudioRecorder/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSMicrophoneUsageDescription
6 | microphoneDesciption
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/AudioRecorderUITests/AudioRecorderUITests.m:
--------------------------------------------------------------------------------
1 | //
2 | // AudioRecorderUITests.m
3 | // AudioRecorderUITests
4 | //
5 | // Created by apple on 2017/2/16.
6 | // Copyright © 2017年 xiaokai.zhan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AudioRecorderUITests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation AudioRecorderUITests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 |
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 |
22 | // In UI tests it is usually best to stop immediately when a failure occurs.
23 | self.continueAfterFailure = NO;
24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
25 | [[[XCUIApplication alloc] init] launch];
26 |
27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
28 | }
29 |
30 | - (void)tearDown {
31 | // Put teardown code here. This method is called after the invocation of each test method in the class.
32 | [super tearDown];
33 | }
34 |
35 | - (void)testExample {
36 | // Use recording to get started writing UI tests.
37 | // Use XCTAssert and related functions to verify your tests produce the correct results.
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/AudioRecorder/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/AudioRecorder/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // AudioRecorder
4 | //
5 | // Created by apple on 2017/2/16.
6 | // Copyright © 2017年 xiaokai.zhan. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "ViewController.h"
11 |
12 | @interface AppDelegate ()
13 |
14 | @end
15 |
16 | @implementation AppDelegate
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
21 | UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] initWithNibName:@"ViewController" bundle:nil]];
22 | self.window.rootViewController = navigationController;
23 | [self.window makeKeyAndVisible];
24 | return YES;
25 | }
26 |
27 |
28 | - (void)applicationWillResignActive:(UIApplication *)application {
29 | // 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.
30 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
31 | }
32 |
33 |
34 | - (void)applicationDidEnterBackground:(UIApplication *)application {
35 | // 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.
36 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
37 | }
38 |
39 |
40 | - (void)applicationWillEnterForeground:(UIApplication *)application {
41 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
42 | }
43 |
44 |
45 | - (void)applicationDidBecomeActive:(UIApplication *)application {
46 | // 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.
47 | }
48 |
49 |
50 | - (void)applicationWillTerminate:(UIApplication *)application {
51 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
52 | }
53 |
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/AudioRecorder/AudioSession/ELAudioSession.m:
--------------------------------------------------------------------------------
1 | //
2 | // ELAudioSession.m
3 | // video_player
4 | //
5 | // Created by apple on 16/9/5.
6 | // Copyright © 2016年 xiaokai.zhan. All rights reserved.
7 | //
8 |
9 | #import "ELAudioSession.h"
10 | #import "AVAudioSession+RouteUtils.h"
11 |
12 | const NSTimeInterval AUSAudioSessionLatency_Background = 0.0929;
13 | const NSTimeInterval AUSAudioSessionLatency_Default = 0.0232;
14 | const NSTimeInterval AUSAudioSessionLatency_LowLatency = 0.0058;
15 |
16 | @implementation ELAudioSession
17 |
18 | + (ELAudioSession *)sharedInstance
19 | {
20 | static ELAudioSession *instance = NULL;
21 | static dispatch_once_t onceToken;
22 | dispatch_once(&onceToken, ^{
23 | instance = [[ELAudioSession alloc] init];
24 | });
25 | return instance;
26 | }
27 |
28 | - (id)init
29 | {
30 | if((self = [super init]))
31 | {
32 | _preferredSampleRate = _currentSampleRate = 44100.0;
33 | _audioSession = [AVAudioSession sharedInstance];
34 | }
35 | return self;
36 | }
37 |
38 | - (void)setCategory:(NSString *)category
39 | {
40 | _category = category;
41 |
42 | NSError *error = nil;
43 | if(![self.audioSession setCategory:_category error:&error])
44 | NSLog(@"Could note set category on audio session: %@", error.localizedDescription);
45 | }
46 |
47 | - (void)setActive:(BOOL)active
48 | {
49 | _active = active;
50 |
51 | NSError *error = nil;
52 |
53 | if(![self.audioSession setPreferredSampleRate:self.preferredSampleRate error:&error])
54 | NSLog(@"Error when setting sample rate on audio session: %@", error.localizedDescription);
55 |
56 | if(![self.audioSession setActive:_active error:&error])
57 | NSLog(@"Error when setting active state of audio session: %@", error.localizedDescription);
58 |
59 | _currentSampleRate = [self.audioSession sampleRate];
60 | }
61 |
62 | - (void)setPreferredLatency:(NSTimeInterval)preferredLatency
63 | {
64 | _preferredLatency = preferredLatency;
65 |
66 | NSError *error = nil;
67 | if(![self.audioSession setPreferredIOBufferDuration:_preferredLatency error:&error])
68 | NSLog(@"Error when setting preferred I/O buffer duration");
69 | }
70 |
71 | - (void)addRouteChangeListener
72 | {
73 | [[NSNotificationCenter defaultCenter] addObserver:self
74 | selector:@selector(onNotificationAudioRouteChange:)
75 | name:AVAudioSessionRouteChangeNotification
76 | object:nil];
77 | [self adjustOnRouteChange];
78 | }
79 |
80 | #pragma mark - notification observer
81 |
82 | - (void)onNotificationAudioRouteChange:(NSNotification *)sender {
83 | [self adjustOnRouteChange];
84 | }
85 |
86 | - (void)adjustOnRouteChange
87 | {
88 | AVAudioSessionRouteDescription *currentRoute = [[AVAudioSession sharedInstance] currentRoute];
89 | if (currentRoute) {
90 | if ([[AVAudioSession sharedInstance] usingWiredMicrophone]) {
91 | } else {
92 | if (![[AVAudioSession sharedInstance] usingBlueTooth]) {
93 | [[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];
94 | }
95 | }
96 | }
97 | }
98 | @end
99 |
--------------------------------------------------------------------------------
/AudioRecorder/ViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
29 |
37 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/AudioRecorder/AudioSession/AVAudioSession+RouteUtils.m:
--------------------------------------------------------------------------------
1 | #import "AVAudioSession+RouteUtils.h"
2 |
3 |
4 | // /* input port types */
5 | // AVF_EXPORT NSString *const AVAudioSessionPortLineIn NS_AVAILABLE_IOS(6_0); /* Line level input on a dock connector */
6 | // AVF_EXPORT NSString *const AVAudioSessionPortBuiltInMic NS_AVAILABLE_IOS(6_0); /* Built-in microphone on an iOS device */
7 | // AVF_EXPORT NSString *const AVAudioSessionPortHeadsetMic NS_AVAILABLE_IOS(6_0); /* Microphone on a wired headset. Headset refers to an
8 | //
9 | // /* output port types */
10 | // AVF_EXPORT NSString *const AVAudioSessionPortLineOut NS_AVAILABLE_IOS(6_0); /* Line level output on a dock connector */
11 | // AVF_EXPORT NSString *const AVAudioSessionPortHeadphones NS_AVAILABLE_IOS(6_0); /* Headphone or headset output */
12 | // AVF_EXPORT NSString *const AVAudioSessionPortBluetoothA2DP NS_AVAILABLE_IOS(6_0); /* Output on a Bluetooth A2DP device */
13 | // AVF_EXPORT NSString *const AVAudioSessionPortBuiltInReceiver NS_AVAILABLE_IOS(6_0); /* The speaker you hold to your ear when on a phone call */
14 | // AVF_EXPORT NSString *const AVAudioSessionPortBuiltInSpeaker NS_AVAILABLE_IOS(6_0); /* Built-in speaker on an iOS device */
15 | // AVF_EXPORT NSString *const AVAudioSessionPortHDMI NS_AVAILABLE_IOS(6_0); /* Output via High-Definition Multimedia Interface */
16 | // AVF_EXPORT NSString *const AVAudioSessionPortAirPlay NS_AVAILABLE_IOS(6_0); /* Output on a remote Air Play device */
17 | // AVF_EXPORT NSString *const AVAudioSessionPortBluetoothLE NS_AVAILABLE_IOS(7_0); /* Output on a Bluetooth Low Energy device */
18 | //
19 | // /* port types that refer to either input or output */
20 | // AVF_EXPORT NSString *const AVAudioSessionPortBluetoothHFP NS_AVAILABLE_IOS(6_0); /* Input or output on a Bluetooth Hands-Free Profile device */
21 | // AVF_EXPORT NSString *const AVAudioSessionPortUSBAudio NS_AVAILABLE_IOS(6_0); /* Input or output on a Universal Serial Bus device */
22 | // AVF_EXPORT NSString *const AVAudioSessionPortCarAudio NS_AVAILABLE_IOS(7_0); /* Input or output via Car Audio */
23 |
24 |
25 | @implementation AVAudioSession (RouteUtils)
26 |
27 | - (BOOL)usingBlueTooth {
28 | NSArray *inputs = self.currentRoute.inputs;
29 | NSArray *blueToothInputRoutes = @[AVAudioSessionPortBluetoothHFP];
30 | for (AVAudioSessionPortDescription *description in inputs) {
31 | if ([blueToothInputRoutes containsObject:description.portType]) {
32 | return YES;
33 | }
34 | }
35 |
36 | NSArray *outputs = self.currentRoute.outputs;
37 | NSArray *blueToothOutputRoutes = @[AVAudioSessionPortBluetoothHFP, AVAudioSessionPortBluetoothA2DP, AVAudioSessionPortBluetoothLE];
38 | for (AVAudioSessionPortDescription *description in outputs) {
39 | if ([blueToothOutputRoutes containsObject:description.portType]) {
40 | return YES;
41 | }
42 | }
43 |
44 | return NO;
45 | }
46 |
47 | - (BOOL)usingWiredMicrophone {
48 | NSArray *inputs = self.currentRoute.inputs;
49 | NSArray *headSetInputRoutes = @[AVAudioSessionPortHeadsetMic];
50 | for (AVAudioSessionPortDescription *description in inputs) {
51 | if ([headSetInputRoutes containsObject:description.portType]) {
52 | return YES;
53 | }
54 | }
55 |
56 | NSArray *outputs = self.currentRoute.outputs;
57 | NSArray *headSetOutputRoutes = @[AVAudioSessionPortHeadphones, AVAudioSessionPortUSBAudio];
58 | for (AVAudioSessionPortDescription *description in outputs) {
59 | if ([headSetOutputRoutes containsObject:description.portType]) {
60 | return YES;
61 | }
62 | }
63 | return NO;
64 | }
65 |
66 | - (BOOL)shouldShowEarphoneAlert
67 | {
68 | // 用户如果没有带耳机,则应该提出提示,目前采用保守策略,即尽量减少alert弹出,所以,我们认为只要不是用手机内置的听筒或者喇叭作为声音外放的,都认为用户带了耳机
69 | NSArray *outputs = self.currentRoute.outputs;
70 | NSArray *headSetOutputRoutes = @[AVAudioSessionPortBuiltInReceiver, AVAudioSessionPortBuiltInSpeaker];
71 | for (AVAudioSessionPortDescription *description in outputs) {
72 | if ([headSetOutputRoutes containsObject:description.portType]) {
73 | return YES;
74 | }
75 | }
76 | return NO;
77 | }
78 |
79 | @end
80 |
--------------------------------------------------------------------------------
/AudioRecorder.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/AudioRecorder.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
74 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
95 |
101 |
102 |
103 |
104 |
106 |
107 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/AudioRecorder.xcodeproj/xcuserdata/xiaokai.zhan.xcuserdatad/xcschemes/AudioRecorder.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
74 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
95 |
101 |
102 |
103 |
104 |
106 |
107 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/AudioRecorder/AudioRecorder.m:
--------------------------------------------------------------------------------
1 | //
2 | // AudioRecorder.m
3 | // AudioRecorder
4 | //
5 | // Created by apple on 2017/2/21.
6 | // Copyright © 2017年 xiaokai.zhan. All rights reserved.
7 | //
8 |
9 | /**
10 | * Setup AudioSession
11 | * 1: Category
12 | * 2: Set Listener
13 | * Interrupt Listener
14 | * AudioRoute Change Listener
15 | * Hardwate output Volume Listener
16 | * 3: Set IO BufferDuration
17 | * 4: Active AudioSession
18 | *
19 | * Setup AudioUnit
20 | * 1:Build AudioComponentDescription To Build AudioUnit Instance
21 | * 2:Build AudioStreamBasicDescription To Set AudioUnit Property
22 | * 3:Connect Node Or Set RenderCallback For AudioUnit
23 | * 4:Initialize AudioUnit
24 | * 5:Initialize AudioUnit
25 | * 6:AudioOutputUnitStart
26 | *
27 | **/
28 | #import "AudioRecorder.h"
29 | #import "ELAudioSession.h"
30 |
31 |
32 | static const AudioUnitElement inputElement = 1;
33 |
34 | @interface AudioRecorder()
35 | @property(nonatomic, assign) AUGraph auGraph;
36 | @property(nonatomic, assign) AUNode ioNode;
37 | @property(nonatomic, assign) AudioUnit ioUnit;
38 | @property(nonatomic, assign) AUNode mixerNode;
39 | @property(nonatomic, assign) AudioUnit mixerUnit;
40 | @property(nonatomic, assign) AUNode convertNode;
41 | @property(nonatomic, assign) AudioUnit convertUnit;
42 | @property(nonatomic, assign) Float64 sampleRate;
43 |
44 | @end
45 |
46 | @implementation AudioRecorder
47 | {
48 | NSString* _destinationFilePath;
49 | ExtAudioFileRef finalAudioFile;
50 | }
51 |
52 | - (id) initWithPath:(NSString*) path {
53 | self = [super init];
54 | if(self) {
55 | _sampleRate = 44100.0;
56 | _destinationFilePath = path;
57 | [[ELAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord];
58 | [[ELAudioSession sharedInstance] setPreferredSampleRate:_sampleRate];
59 | [[ELAudioSession sharedInstance] setActive:YES];
60 | [[ELAudioSession sharedInstance] addRouteChangeListener];
61 | [self addAudioSessionInterruptedObserver];
62 | [self createAudioUnitGraph];
63 | }
64 | return self;
65 | }
66 |
67 |
68 | - (void)createAudioUnitGraph
69 | {
70 | OSStatus status = NewAUGraph(&_auGraph);
71 | CheckStatus(status, @"Could not create a new AUGraph", YES);
72 | [self addAudioUnitNodes];
73 | status = AUGraphOpen(_auGraph);
74 | CheckStatus(status, @"Could not open AUGraph", YES);
75 | [self getUnitsFromNodes];
76 | [self setAudioUnitProperties];
77 | [self makeNodeConnections];
78 | CAShow(_auGraph);
79 | status = AUGraphInitialize(_auGraph);
80 | CheckStatus(status, @"Could not initialize AUGraph", YES);
81 | }
82 |
83 | - (void)addAudioUnitNodes
84 | {
85 | OSStatus status = noErr;
86 | AudioComponentDescription ioDescription;
87 | bzero(&ioDescription, sizeof(ioDescription));
88 | ioDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
89 | ioDescription.componentType = kAudioUnitType_Output;
90 | ioDescription.componentSubType = kAudioUnitSubType_RemoteIO;
91 | status = AUGraphAddNode(_auGraph, &ioDescription, &_ioNode);
92 | CheckStatus(status, @"Could not add I/O node to AUGraph", YES);
93 |
94 | AudioComponentDescription converterDescription;
95 | bzero(&converterDescription, sizeof(converterDescription));
96 | converterDescription.componentType = kAudioUnitType_FormatConverter;
97 | converterDescription.componentSubType = kAudioUnitSubType_AUConverter;
98 | converterDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
99 | status = AUGraphAddNode(_auGraph, &converterDescription, &_convertNode);
100 | CheckStatus(status, @"Could not add Converter node to AUGraph", YES);
101 |
102 | AudioComponentDescription mixerDescription;
103 | bzero(&mixerDescription, sizeof(mixerDescription));
104 | mixerDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
105 | mixerDescription.componentType = kAudioUnitType_Mixer;
106 | mixerDescription.componentSubType = kAudioUnitSubType_MultiChannelMixer;
107 | status = AUGraphAddNode(_auGraph, &mixerDescription, &_mixerNode);
108 | CheckStatus(status, @"Could not add mixer node to AUGraph", YES);
109 | }
110 |
111 | - (void)getUnitsFromNodes
112 | {
113 | OSStatus status = noErr;
114 | status = AUGraphNodeInfo(_auGraph, _ioNode, NULL, &_ioUnit);
115 | CheckStatus(status, @"Could not retrieve node info for I/O node", YES);
116 | status = AUGraphNodeInfo(_auGraph, _convertNode, NULL, &_convertUnit);
117 | CheckStatus(status, @"Could not retrieve node info for convert node", YES);
118 | status = AUGraphNodeInfo(_auGraph, _mixerNode, NULL, &_mixerUnit);
119 | CheckStatus(status, @"Could not retrieve node info for mixer node", YES);
120 | }
121 |
122 | - (void)setAudioUnitProperties
123 | {
124 | OSStatus status = noErr;
125 | AudioStreamBasicDescription stereoStreamFormat = [self noninterleavedPCMFormatWithChannels:2];
126 | status = AudioUnitSetProperty(_ioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, inputElement,
127 | &stereoStreamFormat, sizeof(stereoStreamFormat));
128 | CheckStatus(status, @"Could not set stream format on I/O unit output scope", YES);
129 | UInt32 enableIO = 1;
130 | status = AudioUnitSetProperty(_ioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, inputElement,
131 | &enableIO, sizeof(enableIO));
132 | CheckStatus(status, @"Could not enable I/O on I/O unit input scope", YES);
133 | UInt32 mixerElementCount = 1;
134 | status = AudioUnitSetProperty(_mixerUnit, kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0,
135 | &mixerElementCount, sizeof(mixerElementCount));
136 | CheckStatus(status, @"Could not set element count on mixer unit input scope", YES);
137 | status = AudioUnitSetProperty(_mixerUnit, kAudioUnitProperty_SampleRate, kAudioUnitScope_Output, 0,
138 | &_sampleRate, sizeof(_sampleRate));
139 | CheckStatus(status, @"Could not set sample rate on mixer unit output scope", YES);
140 |
141 | UInt32 maximumFramesPerSlice = 4096;
142 | AudioUnitSetProperty (
143 | _ioUnit,
144 | kAudioUnitProperty_MaximumFramesPerSlice,
145 | kAudioUnitScope_Global,
146 | 0,
147 | &maximumFramesPerSlice,
148 | sizeof (maximumFramesPerSlice)
149 | );
150 |
151 |
152 |
153 | UInt32 bytesPerSample = sizeof (AudioUnitSampleType);
154 | AudioStreamBasicDescription _clientFormat32float;
155 | _clientFormat32float.mFormatID = kAudioFormatLinearPCM;
156 | _clientFormat32float.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved;
157 | _clientFormat32float.mBytesPerPacket = bytesPerSample;
158 | _clientFormat32float.mFramesPerPacket = 1;
159 | _clientFormat32float.mBytesPerFrame = bytesPerSample;
160 | _clientFormat32float.mChannelsPerFrame = 2;
161 | _clientFormat32float.mBitsPerChannel = 8 * bytesPerSample;
162 | _clientFormat32float.mSampleRate = _sampleRate;
163 | AudioUnitSetProperty(_mixerUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &_clientFormat32float, sizeof(_clientFormat32float));
164 | AudioUnitSetProperty(_ioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &_clientFormat32float, sizeof(_clientFormat32float));
165 | AudioUnitSetProperty(_convertUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &stereoStreamFormat, sizeof(stereoStreamFormat));
166 | AudioUnitSetProperty(_convertUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &_clientFormat32float, sizeof(_clientFormat32float));
167 | }
168 |
169 | - (void)prepareFinalWriteFile{
170 | AudioStreamBasicDescription destinationFormat;
171 | memset(&destinationFormat, 0, sizeof(destinationFormat));
172 |
173 | destinationFormat.mFormatID = kAudioFormatLinearPCM;
174 | destinationFormat.mSampleRate = _sampleRate;
175 | // if we want pcm, default to signed 16-bit little-endian
176 | destinationFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
177 | destinationFormat.mBitsPerChannel = 16;
178 | destinationFormat.mChannelsPerFrame = 2;
179 | destinationFormat.mBytesPerPacket = destinationFormat.mBytesPerFrame = (destinationFormat.mBitsPerChannel / 8) * destinationFormat.mChannelsPerFrame;
180 | destinationFormat.mFramesPerPacket = 1;
181 |
182 | UInt32 size = sizeof(destinationFormat);
183 | OSStatus result = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &size, &destinationFormat);
184 |
185 | if(result) printf("AudioFormatGetProperty %d \n", (int)result);
186 | CFURLRef destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
187 | (CFStringRef)_destinationFilePath,
188 | kCFURLPOSIXPathStyle,
189 | false);
190 |
191 | // specify codec Saving the output in .m4a format
192 | result = ExtAudioFileCreateWithURL(destinationURL,
193 | kAudioFileCAFType,
194 | &destinationFormat,
195 | NULL,
196 | kAudioFileFlags_EraseFile,
197 | &finalAudioFile);
198 | if(result) printf("ExtAudioFileCreateWithURL %d \n", (int)result);
199 | CFRelease(destinationURL);
200 |
201 | // // This is a very important part and easiest way to set the ASBD for the File with correct format.
202 | AudioStreamBasicDescription clientFormat;
203 | UInt32 fSize = sizeof (clientFormat);
204 | memset(&clientFormat, 0, sizeof(clientFormat));
205 | // get the audio data format from the Output Unit
206 | CheckStatus(AudioUnitGetProperty(_mixerUnit,
207 | kAudioUnitProperty_StreamFormat,
208 | kAudioUnitScope_Output,
209 | 0,
210 | &clientFormat,
211 | &fSize),@"AudioUnitGetProperty on failed", YES);
212 |
213 | // set the audio data format of mixer Unit
214 | CheckStatus(ExtAudioFileSetProperty(finalAudioFile,
215 | kExtAudioFileProperty_ClientDataFormat,
216 | sizeof(clientFormat),
217 | &clientFormat),
218 | @"ExtAudioFileSetProperty kExtAudioFileProperty_ClientDataFormat failed", YES);
219 |
220 |
221 | // specify codec
222 | UInt32 codec = kAppleHardwareAudioCodecManufacturer;
223 | CheckStatus(ExtAudioFileSetProperty(finalAudioFile,
224 | kExtAudioFileProperty_CodecManufacturer,
225 | sizeof(codec),
226 | &codec),@"ExtAudioFileSetProperty on extAudioFile Faild", YES);
227 |
228 | CheckStatus(ExtAudioFileWriteAsync(finalAudioFile, 0, NULL),@"ExtAudioFileWriteAsync Failed", YES);
229 | }
230 |
231 | static OSStatus renderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
232 | {
233 | OSStatus result = noErr;
234 | __unsafe_unretained AudioRecorder *THIS = (__bridge AudioRecorder *)inRefCon;
235 | AudioUnitRender(THIS->_mixerUnit, ioActionFlags, inTimeStamp, 0, inNumberFrames, ioData);
236 | result = ExtAudioFileWriteAsync(THIS->finalAudioFile, inNumberFrames, ioData);
237 | return result;
238 | }
239 |
240 | - (void)makeNodeConnections
241 | {
242 | OSStatus status = noErr;
243 | status = AUGraphConnectNodeInput(_auGraph, _ioNode, 1, _convertNode, 0);
244 | CheckStatus(status, @"Could not connect I/O node input to convert node input", YES);
245 | status = AUGraphConnectNodeInput(_auGraph, _convertNode, 0, _mixerNode, 0);
246 | CheckStatus(status, @"Could not connect I/O node input to mixer node input", YES);
247 | AURenderCallbackStruct finalRenderProc;
248 | finalRenderProc.inputProc = &renderCallback;
249 | finalRenderProc.inputProcRefCon = (__bridge void *)self;
250 | status = AUGraphSetNodeInputCallback(_auGraph, _ioNode, 0, &finalRenderProc);
251 | CheckStatus(status, @"Could not set InputCallback For IONode", YES);
252 |
253 | // status = AUGraphConnectNodeInput(_auGraph, _mixerNode, 0, _ioNode, 0);
254 | // CheckStatus(status, @"Could not connect mixer node output to I/O node input", YES);
255 | }
256 |
257 | - (void)dealloc
258 | {
259 | [self destroyAudioUnitGraph];
260 | }
261 |
262 | - (AudioStreamBasicDescription)noninterleavedPCMFormatWithChannels:(UInt32)channels
263 | {
264 | UInt32 bytesPerSample = sizeof(AudioUnitSampleType);
265 |
266 | AudioStreamBasicDescription asbd;
267 | bzero(&asbd, sizeof(asbd));
268 | asbd.mSampleRate = _sampleRate;
269 | asbd.mFormatID = kAudioFormatLinearPCM;
270 | // asbd.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved;
271 | asbd.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical | kAudioFormatFlagIsNonInterleaved;
272 | asbd.mBitsPerChannel = 8 * bytesPerSample;
273 | asbd.mBytesPerFrame = bytesPerSample;
274 | asbd.mBytesPerPacket = bytesPerSample;
275 | asbd.mFramesPerPacket = 1;
276 | asbd.mChannelsPerFrame = channels;
277 |
278 | return asbd;
279 | }
280 |
281 | - (void)destroyAudioUnitGraph
282 | {
283 | AUGraphStop(_auGraph);
284 | AUGraphUninitialize(_auGraph);
285 | AUGraphClose(_auGraph);
286 | AUGraphRemoveNode(_auGraph, _mixerNode);
287 | AUGraphRemoveNode(_auGraph, _ioNode);
288 | DisposeAUGraph(_auGraph);
289 | _ioUnit = NULL;
290 | _mixerUnit = NULL;
291 | _mixerNode = 0;
292 | _ioNode = 0;
293 | _auGraph = NULL;
294 | }
295 |
296 | - (void)start
297 | {
298 | [self prepareFinalWriteFile];
299 | OSStatus status = AUGraphStart(_auGraph);
300 | CheckStatus(status, @"Could not start AUGraph", YES);
301 | }
302 |
303 | - (void)stop
304 | {
305 | OSStatus status = AUGraphStop(_auGraph);
306 | CheckStatus(status, @"Could not stop AUGraph", YES);
307 | ExtAudioFileDispose(finalAudioFile);
308 | }
309 |
310 | // AudioSession 被打断的通知
311 | - (void)addAudioSessionInterruptedObserver
312 | {
313 | [self removeAudioSessionInterruptedObserver];
314 | [[NSNotificationCenter defaultCenter] addObserver:self
315 | selector:@selector(onNotificationAudioInterrupted:)
316 | name:AVAudioSessionInterruptionNotification
317 | object:[AVAudioSession sharedInstance]];
318 | }
319 |
320 | - (void)removeAudioSessionInterruptedObserver
321 | {
322 | [[NSNotificationCenter defaultCenter] removeObserver:self
323 | name:AVAudioSessionInterruptionNotification
324 | object:nil];
325 | }
326 |
327 | - (void)onNotificationAudioInterrupted:(NSNotification *)sender {
328 | AVAudioSessionInterruptionType interruptionType = [[[sender userInfo] objectForKey:AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
329 | switch (interruptionType) {
330 | case AVAudioSessionInterruptionTypeBegan:
331 | [self stop];
332 | break;
333 | case AVAudioSessionInterruptionTypeEnded:
334 | [self start];
335 | break;
336 | default:
337 | break;
338 | }
339 | }
340 |
341 | static void CheckStatus(OSStatus status, NSString *message, BOOL fatal)
342 | {
343 | if(status != noErr)
344 | {
345 | char fourCC[16];
346 | *(UInt32 *)fourCC = CFSwapInt32HostToBig(status);
347 | fourCC[4] = '\0';
348 |
349 | if(isprint(fourCC[0]) && isprint(fourCC[1]) && isprint(fourCC[2]) && isprint(fourCC[3]))
350 | NSLog(@"%@: %s", message, fourCC);
351 | else
352 | NSLog(@"%@: %d", message, (int)status);
353 |
354 | if(fatal)
355 | exit(-1);
356 | }
357 | }
358 | @end
359 |
--------------------------------------------------------------------------------
/AudioRecorder.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 188EA2481E55D4FE00E858A4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 188EA2471E55D4FE00E858A4 /* main.m */; };
11 | 188EA24B1E55D4FE00E858A4 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 188EA24A1E55D4FE00E858A4 /* AppDelegate.m */; };
12 | 188EA24E1E55D4FE00E858A4 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 188EA24D1E55D4FE00E858A4 /* ViewController.m */; };
13 | 188EA2531E55D4FE00E858A4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 188EA2521E55D4FE00E858A4 /* Assets.xcassets */; };
14 | 188EA2561E55D4FE00E858A4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 188EA2541E55D4FE00E858A4 /* LaunchScreen.storyboard */; };
15 | 188EA2611E55D4FF00E858A4 /* AudioRecorderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 188EA2601E55D4FF00E858A4 /* AudioRecorderTests.m */; };
16 | 188EA26C1E55D4FF00E858A4 /* AudioRecorderUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 188EA26B1E55D4FF00E858A4 /* AudioRecorderUITests.m */; };
17 | 188EA27A1E55D57300E858A4 /* ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 188EA2791E55D57300E858A4 /* ViewController.xib */; };
18 | 188EA2C31E55DC1500E858A4 /* CommonUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 188EA2C21E55DC1500E858A4 /* CommonUtil.m */; };
19 | 18A9E72D1E5C79F2002069FA /* AVAudioSession+RouteUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 18A9E72A1E5C79F2002069FA /* AVAudioSession+RouteUtils.m */; };
20 | 18A9E72E1E5C79F2002069FA /* ELAudioSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 18A9E72C1E5C79F2002069FA /* ELAudioSession.m */; };
21 | 18A9E7311E5C7A5D002069FA /* AudioRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 18A9E7301E5C7A5D002069FA /* AudioRecorder.m */; };
22 | /* End PBXBuildFile section */
23 |
24 | /* Begin PBXContainerItemProxy section */
25 | 188EA25D1E55D4FF00E858A4 /* PBXContainerItemProxy */ = {
26 | isa = PBXContainerItemProxy;
27 | containerPortal = 188EA23B1E55D4FE00E858A4 /* Project object */;
28 | proxyType = 1;
29 | remoteGlobalIDString = 188EA2421E55D4FE00E858A4;
30 | remoteInfo = AudioRecorder;
31 | };
32 | 188EA2681E55D4FF00E858A4 /* PBXContainerItemProxy */ = {
33 | isa = PBXContainerItemProxy;
34 | containerPortal = 188EA23B1E55D4FE00E858A4 /* Project object */;
35 | proxyType = 1;
36 | remoteGlobalIDString = 188EA2421E55D4FE00E858A4;
37 | remoteInfo = AudioRecorder;
38 | };
39 | /* End PBXContainerItemProxy section */
40 |
41 | /* Begin PBXFileReference section */
42 | 188EA2431E55D4FE00E858A4 /* AudioRecorder.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AudioRecorder.app; sourceTree = BUILT_PRODUCTS_DIR; };
43 | 188EA2471E55D4FE00E858A4 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
44 | 188EA2491E55D4FE00E858A4 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
45 | 188EA24A1E55D4FE00E858A4 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
46 | 188EA24C1E55D4FE00E858A4 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
47 | 188EA24D1E55D4FE00E858A4 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
48 | 188EA2521E55D4FE00E858A4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
49 | 188EA2551E55D4FE00E858A4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
50 | 188EA2571E55D4FE00E858A4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
51 | 188EA25C1E55D4FF00E858A4 /* AudioRecorderTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AudioRecorderTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
52 | 188EA2601E55D4FF00E858A4 /* AudioRecorderTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AudioRecorderTests.m; sourceTree = ""; };
53 | 188EA2621E55D4FF00E858A4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
54 | 188EA2671E55D4FF00E858A4 /* AudioRecorderUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AudioRecorderUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
55 | 188EA26B1E55D4FF00E858A4 /* AudioRecorderUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AudioRecorderUITests.m; sourceTree = ""; };
56 | 188EA26D1E55D4FF00E858A4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
57 | 188EA2791E55D57300E858A4 /* ViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ViewController.xib; sourceTree = ""; };
58 | 188EA2C11E55DC1500E858A4 /* CommonUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonUtil.h; sourceTree = ""; };
59 | 188EA2C21E55DC1500E858A4 /* CommonUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CommonUtil.m; sourceTree = ""; };
60 | 18A9E7291E5C79F2002069FA /* AVAudioSession+RouteUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AVAudioSession+RouteUtils.h"; sourceTree = ""; };
61 | 18A9E72A1E5C79F2002069FA /* AVAudioSession+RouteUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AVAudioSession+RouteUtils.m"; sourceTree = ""; };
62 | 18A9E72B1E5C79F2002069FA /* ELAudioSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ELAudioSession.h; sourceTree = ""; };
63 | 18A9E72C1E5C79F2002069FA /* ELAudioSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ELAudioSession.m; sourceTree = ""; };
64 | 18A9E72F1E5C7A5D002069FA /* AudioRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioRecorder.h; sourceTree = ""; };
65 | 18A9E7301E5C7A5D002069FA /* AudioRecorder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioRecorder.m; sourceTree = ""; };
66 | /* End PBXFileReference section */
67 |
68 | /* Begin PBXFrameworksBuildPhase section */
69 | 188EA2401E55D4FE00E858A4 /* Frameworks */ = {
70 | isa = PBXFrameworksBuildPhase;
71 | buildActionMask = 2147483647;
72 | files = (
73 | );
74 | runOnlyForDeploymentPostprocessing = 0;
75 | };
76 | 188EA2591E55D4FF00E858A4 /* Frameworks */ = {
77 | isa = PBXFrameworksBuildPhase;
78 | buildActionMask = 2147483647;
79 | files = (
80 | );
81 | runOnlyForDeploymentPostprocessing = 0;
82 | };
83 | 188EA2641E55D4FF00E858A4 /* Frameworks */ = {
84 | isa = PBXFrameworksBuildPhase;
85 | buildActionMask = 2147483647;
86 | files = (
87 | );
88 | runOnlyForDeploymentPostprocessing = 0;
89 | };
90 | /* End PBXFrameworksBuildPhase section */
91 |
92 | /* Begin PBXGroup section */
93 | 188EA23A1E55D4FE00E858A4 = {
94 | isa = PBXGroup;
95 | children = (
96 | 188EA2451E55D4FE00E858A4 /* AudioRecorder */,
97 | 188EA25F1E55D4FF00E858A4 /* AudioRecorderTests */,
98 | 188EA26A1E55D4FF00E858A4 /* AudioRecorderUITests */,
99 | 188EA2441E55D4FE00E858A4 /* Products */,
100 | );
101 | sourceTree = "";
102 | };
103 | 188EA2441E55D4FE00E858A4 /* Products */ = {
104 | isa = PBXGroup;
105 | children = (
106 | 188EA2431E55D4FE00E858A4 /* AudioRecorder.app */,
107 | 188EA25C1E55D4FF00E858A4 /* AudioRecorderTests.xctest */,
108 | 188EA2671E55D4FF00E858A4 /* AudioRecorderUITests.xctest */,
109 | );
110 | name = Products;
111 | sourceTree = "";
112 | };
113 | 188EA2451E55D4FE00E858A4 /* AudioRecorder */ = {
114 | isa = PBXGroup;
115 | children = (
116 | 18A9E7281E5C79F2002069FA /* AudioSession */,
117 | 188EA2C01E55DC1500E858A4 /* utils */,
118 | 188EA2491E55D4FE00E858A4 /* AppDelegate.h */,
119 | 188EA24A1E55D4FE00E858A4 /* AppDelegate.m */,
120 | 188EA24C1E55D4FE00E858A4 /* ViewController.h */,
121 | 188EA24D1E55D4FE00E858A4 /* ViewController.m */,
122 | 188EA2521E55D4FE00E858A4 /* Assets.xcassets */,
123 | 188EA2541E55D4FE00E858A4 /* LaunchScreen.storyboard */,
124 | 188EA2571E55D4FE00E858A4 /* Info.plist */,
125 | 188EA2461E55D4FE00E858A4 /* Supporting Files */,
126 | 188EA2791E55D57300E858A4 /* ViewController.xib */,
127 | 18A9E72F1E5C7A5D002069FA /* AudioRecorder.h */,
128 | 18A9E7301E5C7A5D002069FA /* AudioRecorder.m */,
129 | );
130 | path = AudioRecorder;
131 | sourceTree = "";
132 | };
133 | 188EA2461E55D4FE00E858A4 /* Supporting Files */ = {
134 | isa = PBXGroup;
135 | children = (
136 | 188EA2471E55D4FE00E858A4 /* main.m */,
137 | );
138 | name = "Supporting Files";
139 | sourceTree = "";
140 | };
141 | 188EA25F1E55D4FF00E858A4 /* AudioRecorderTests */ = {
142 | isa = PBXGroup;
143 | children = (
144 | 188EA2601E55D4FF00E858A4 /* AudioRecorderTests.m */,
145 | 188EA2621E55D4FF00E858A4 /* Info.plist */,
146 | );
147 | path = AudioRecorderTests;
148 | sourceTree = "";
149 | };
150 | 188EA26A1E55D4FF00E858A4 /* AudioRecorderUITests */ = {
151 | isa = PBXGroup;
152 | children = (
153 | 188EA26B1E55D4FF00E858A4 /* AudioRecorderUITests.m */,
154 | 188EA26D1E55D4FF00E858A4 /* Info.plist */,
155 | );
156 | path = AudioRecorderUITests;
157 | sourceTree = "";
158 | };
159 | 188EA2C01E55DC1500E858A4 /* utils */ = {
160 | isa = PBXGroup;
161 | children = (
162 | 188EA2C11E55DC1500E858A4 /* CommonUtil.h */,
163 | 188EA2C21E55DC1500E858A4 /* CommonUtil.m */,
164 | );
165 | path = utils;
166 | sourceTree = "";
167 | };
168 | 18A9E7281E5C79F2002069FA /* AudioSession */ = {
169 | isa = PBXGroup;
170 | children = (
171 | 18A9E7291E5C79F2002069FA /* AVAudioSession+RouteUtils.h */,
172 | 18A9E72A1E5C79F2002069FA /* AVAudioSession+RouteUtils.m */,
173 | 18A9E72B1E5C79F2002069FA /* ELAudioSession.h */,
174 | 18A9E72C1E5C79F2002069FA /* ELAudioSession.m */,
175 | );
176 | path = AudioSession;
177 | sourceTree = "";
178 | };
179 | /* End PBXGroup section */
180 |
181 | /* Begin PBXNativeTarget section */
182 | 188EA2421E55D4FE00E858A4 /* AudioRecorder */ = {
183 | isa = PBXNativeTarget;
184 | buildConfigurationList = 188EA2701E55D4FF00E858A4 /* Build configuration list for PBXNativeTarget "AudioRecorder" */;
185 | buildPhases = (
186 | 188EA23F1E55D4FE00E858A4 /* Sources */,
187 | 188EA2401E55D4FE00E858A4 /* Frameworks */,
188 | 188EA2411E55D4FE00E858A4 /* Resources */,
189 | );
190 | buildRules = (
191 | );
192 | dependencies = (
193 | );
194 | name = AudioRecorder;
195 | productName = AudioRecorder;
196 | productReference = 188EA2431E55D4FE00E858A4 /* AudioRecorder.app */;
197 | productType = "com.apple.product-type.application";
198 | };
199 | 188EA25B1E55D4FF00E858A4 /* AudioRecorderTests */ = {
200 | isa = PBXNativeTarget;
201 | buildConfigurationList = 188EA2731E55D4FF00E858A4 /* Build configuration list for PBXNativeTarget "AudioRecorderTests" */;
202 | buildPhases = (
203 | 188EA2581E55D4FF00E858A4 /* Sources */,
204 | 188EA2591E55D4FF00E858A4 /* Frameworks */,
205 | 188EA25A1E55D4FF00E858A4 /* Resources */,
206 | );
207 | buildRules = (
208 | );
209 | dependencies = (
210 | 188EA25E1E55D4FF00E858A4 /* PBXTargetDependency */,
211 | );
212 | name = AudioRecorderTests;
213 | productName = AudioRecorderTests;
214 | productReference = 188EA25C1E55D4FF00E858A4 /* AudioRecorderTests.xctest */;
215 | productType = "com.apple.product-type.bundle.unit-test";
216 | };
217 | 188EA2661E55D4FF00E858A4 /* AudioRecorderUITests */ = {
218 | isa = PBXNativeTarget;
219 | buildConfigurationList = 188EA2761E55D4FF00E858A4 /* Build configuration list for PBXNativeTarget "AudioRecorderUITests" */;
220 | buildPhases = (
221 | 188EA2631E55D4FF00E858A4 /* Sources */,
222 | 188EA2641E55D4FF00E858A4 /* Frameworks */,
223 | 188EA2651E55D4FF00E858A4 /* Resources */,
224 | );
225 | buildRules = (
226 | );
227 | dependencies = (
228 | 188EA2691E55D4FF00E858A4 /* PBXTargetDependency */,
229 | );
230 | name = AudioRecorderUITests;
231 | productName = AudioRecorderUITests;
232 | productReference = 188EA2671E55D4FF00E858A4 /* AudioRecorderUITests.xctest */;
233 | productType = "com.apple.product-type.bundle.ui-testing";
234 | };
235 | /* End PBXNativeTarget section */
236 |
237 | /* Begin PBXProject section */
238 | 188EA23B1E55D4FE00E858A4 /* Project object */ = {
239 | isa = PBXProject;
240 | attributes = {
241 | LastUpgradeCheck = 0820;
242 | ORGANIZATIONNAME = xiaokai.zhan;
243 | TargetAttributes = {
244 | 188EA2421E55D4FE00E858A4 = {
245 | CreatedOnToolsVersion = 8.2.1;
246 | DevelopmentTeam = MY5GTD35UJ;
247 | ProvisioningStyle = Automatic;
248 | };
249 | 188EA25B1E55D4FF00E858A4 = {
250 | CreatedOnToolsVersion = 8.2.1;
251 | DevelopmentTeam = MY5GTD35UJ;
252 | ProvisioningStyle = Automatic;
253 | TestTargetID = 188EA2421E55D4FE00E858A4;
254 | };
255 | 188EA2661E55D4FF00E858A4 = {
256 | CreatedOnToolsVersion = 8.2.1;
257 | DevelopmentTeam = MY5GTD35UJ;
258 | ProvisioningStyle = Automatic;
259 | TestTargetID = 188EA2421E55D4FE00E858A4;
260 | };
261 | };
262 | };
263 | buildConfigurationList = 188EA23E1E55D4FE00E858A4 /* Build configuration list for PBXProject "AudioRecorder" */;
264 | compatibilityVersion = "Xcode 3.2";
265 | developmentRegion = English;
266 | hasScannedForEncodings = 0;
267 | knownRegions = (
268 | en,
269 | Base,
270 | );
271 | mainGroup = 188EA23A1E55D4FE00E858A4;
272 | productRefGroup = 188EA2441E55D4FE00E858A4 /* Products */;
273 | projectDirPath = "";
274 | projectRoot = "";
275 | targets = (
276 | 188EA2421E55D4FE00E858A4 /* AudioRecorder */,
277 | 188EA25B1E55D4FF00E858A4 /* AudioRecorderTests */,
278 | 188EA2661E55D4FF00E858A4 /* AudioRecorderUITests */,
279 | );
280 | };
281 | /* End PBXProject section */
282 |
283 | /* Begin PBXResourcesBuildPhase section */
284 | 188EA2411E55D4FE00E858A4 /* Resources */ = {
285 | isa = PBXResourcesBuildPhase;
286 | buildActionMask = 2147483647;
287 | files = (
288 | 188EA2561E55D4FE00E858A4 /* LaunchScreen.storyboard in Resources */,
289 | 188EA27A1E55D57300E858A4 /* ViewController.xib in Resources */,
290 | 188EA2531E55D4FE00E858A4 /* Assets.xcassets in Resources */,
291 | );
292 | runOnlyForDeploymentPostprocessing = 0;
293 | };
294 | 188EA25A1E55D4FF00E858A4 /* Resources */ = {
295 | isa = PBXResourcesBuildPhase;
296 | buildActionMask = 2147483647;
297 | files = (
298 | );
299 | runOnlyForDeploymentPostprocessing = 0;
300 | };
301 | 188EA2651E55D4FF00E858A4 /* Resources */ = {
302 | isa = PBXResourcesBuildPhase;
303 | buildActionMask = 2147483647;
304 | files = (
305 | );
306 | runOnlyForDeploymentPostprocessing = 0;
307 | };
308 | /* End PBXResourcesBuildPhase section */
309 |
310 | /* Begin PBXSourcesBuildPhase section */
311 | 188EA23F1E55D4FE00E858A4 /* Sources */ = {
312 | isa = PBXSourcesBuildPhase;
313 | buildActionMask = 2147483647;
314 | files = (
315 | 18A9E72E1E5C79F2002069FA /* ELAudioSession.m in Sources */,
316 | 188EA24E1E55D4FE00E858A4 /* ViewController.m in Sources */,
317 | 188EA24B1E55D4FE00E858A4 /* AppDelegate.m in Sources */,
318 | 18A9E7311E5C7A5D002069FA /* AudioRecorder.m in Sources */,
319 | 18A9E72D1E5C79F2002069FA /* AVAudioSession+RouteUtils.m in Sources */,
320 | 188EA2C31E55DC1500E858A4 /* CommonUtil.m in Sources */,
321 | 188EA2481E55D4FE00E858A4 /* main.m in Sources */,
322 | );
323 | runOnlyForDeploymentPostprocessing = 0;
324 | };
325 | 188EA2581E55D4FF00E858A4 /* Sources */ = {
326 | isa = PBXSourcesBuildPhase;
327 | buildActionMask = 2147483647;
328 | files = (
329 | 188EA2611E55D4FF00E858A4 /* AudioRecorderTests.m in Sources */,
330 | );
331 | runOnlyForDeploymentPostprocessing = 0;
332 | };
333 | 188EA2631E55D4FF00E858A4 /* Sources */ = {
334 | isa = PBXSourcesBuildPhase;
335 | buildActionMask = 2147483647;
336 | files = (
337 | 188EA26C1E55D4FF00E858A4 /* AudioRecorderUITests.m in Sources */,
338 | );
339 | runOnlyForDeploymentPostprocessing = 0;
340 | };
341 | /* End PBXSourcesBuildPhase section */
342 |
343 | /* Begin PBXTargetDependency section */
344 | 188EA25E1E55D4FF00E858A4 /* PBXTargetDependency */ = {
345 | isa = PBXTargetDependency;
346 | target = 188EA2421E55D4FE00E858A4 /* AudioRecorder */;
347 | targetProxy = 188EA25D1E55D4FF00E858A4 /* PBXContainerItemProxy */;
348 | };
349 | 188EA2691E55D4FF00E858A4 /* PBXTargetDependency */ = {
350 | isa = PBXTargetDependency;
351 | target = 188EA2421E55D4FE00E858A4 /* AudioRecorder */;
352 | targetProxy = 188EA2681E55D4FF00E858A4 /* PBXContainerItemProxy */;
353 | };
354 | /* End PBXTargetDependency section */
355 |
356 | /* Begin PBXVariantGroup section */
357 | 188EA2541E55D4FE00E858A4 /* LaunchScreen.storyboard */ = {
358 | isa = PBXVariantGroup;
359 | children = (
360 | 188EA2551E55D4FE00E858A4 /* Base */,
361 | );
362 | name = LaunchScreen.storyboard;
363 | sourceTree = "";
364 | };
365 | /* End PBXVariantGroup section */
366 |
367 | /* Begin XCBuildConfiguration section */
368 | 188EA26E1E55D4FF00E858A4 /* Debug */ = {
369 | isa = XCBuildConfiguration;
370 | buildSettings = {
371 | ALWAYS_SEARCH_USER_PATHS = NO;
372 | CLANG_ANALYZER_NONNULL = YES;
373 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
374 | CLANG_CXX_LIBRARY = "libc++";
375 | CLANG_ENABLE_MODULES = YES;
376 | CLANG_ENABLE_OBJC_ARC = YES;
377 | CLANG_WARN_BOOL_CONVERSION = YES;
378 | CLANG_WARN_CONSTANT_CONVERSION = YES;
379 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
380 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
381 | CLANG_WARN_EMPTY_BODY = YES;
382 | CLANG_WARN_ENUM_CONVERSION = YES;
383 | CLANG_WARN_INFINITE_RECURSION = YES;
384 | CLANG_WARN_INT_CONVERSION = YES;
385 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
386 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
387 | CLANG_WARN_UNREACHABLE_CODE = YES;
388 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
389 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
390 | COPY_PHASE_STRIP = NO;
391 | DEBUG_INFORMATION_FORMAT = dwarf;
392 | ENABLE_STRICT_OBJC_MSGSEND = YES;
393 | ENABLE_TESTABILITY = YES;
394 | GCC_C_LANGUAGE_STANDARD = gnu99;
395 | GCC_DYNAMIC_NO_PIC = NO;
396 | GCC_NO_COMMON_BLOCKS = YES;
397 | GCC_OPTIMIZATION_LEVEL = 0;
398 | GCC_PREPROCESSOR_DEFINITIONS = (
399 | "DEBUG=1",
400 | "$(inherited)",
401 | );
402 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
403 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
404 | GCC_WARN_UNDECLARED_SELECTOR = YES;
405 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
406 | GCC_WARN_UNUSED_FUNCTION = YES;
407 | GCC_WARN_UNUSED_VARIABLE = YES;
408 | IPHONEOS_DEPLOYMENT_TARGET = 10.2;
409 | MTL_ENABLE_DEBUG_INFO = YES;
410 | ONLY_ACTIVE_ARCH = YES;
411 | SDKROOT = iphoneos;
412 | };
413 | name = Debug;
414 | };
415 | 188EA26F1E55D4FF00E858A4 /* Release */ = {
416 | isa = XCBuildConfiguration;
417 | buildSettings = {
418 | ALWAYS_SEARCH_USER_PATHS = NO;
419 | CLANG_ANALYZER_NONNULL = YES;
420 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
421 | CLANG_CXX_LIBRARY = "libc++";
422 | CLANG_ENABLE_MODULES = YES;
423 | CLANG_ENABLE_OBJC_ARC = YES;
424 | CLANG_WARN_BOOL_CONVERSION = YES;
425 | CLANG_WARN_CONSTANT_CONVERSION = YES;
426 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
427 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
428 | CLANG_WARN_EMPTY_BODY = YES;
429 | CLANG_WARN_ENUM_CONVERSION = YES;
430 | CLANG_WARN_INFINITE_RECURSION = YES;
431 | CLANG_WARN_INT_CONVERSION = YES;
432 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
433 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
434 | CLANG_WARN_UNREACHABLE_CODE = YES;
435 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
436 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
437 | COPY_PHASE_STRIP = NO;
438 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
439 | ENABLE_NS_ASSERTIONS = NO;
440 | ENABLE_STRICT_OBJC_MSGSEND = YES;
441 | GCC_C_LANGUAGE_STANDARD = gnu99;
442 | GCC_NO_COMMON_BLOCKS = YES;
443 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
444 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
445 | GCC_WARN_UNDECLARED_SELECTOR = YES;
446 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
447 | GCC_WARN_UNUSED_FUNCTION = YES;
448 | GCC_WARN_UNUSED_VARIABLE = YES;
449 | IPHONEOS_DEPLOYMENT_TARGET = 10.2;
450 | MTL_ENABLE_DEBUG_INFO = NO;
451 | SDKROOT = iphoneos;
452 | VALIDATE_PRODUCT = YES;
453 | };
454 | name = Release;
455 | };
456 | 188EA2711E55D4FF00E858A4 /* Debug */ = {
457 | isa = XCBuildConfiguration;
458 | buildSettings = {
459 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
460 | DEVELOPMENT_TEAM = MY5GTD35UJ;
461 | INFOPLIST_FILE = AudioRecorder/Info.plist;
462 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
463 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
464 | PRODUCT_BUNDLE_IDENTIFIER = com.phuket.tour.audiotoolbox.encoder.AudioRecorder;
465 | PRODUCT_NAME = "$(TARGET_NAME)";
466 | };
467 | name = Debug;
468 | };
469 | 188EA2721E55D4FF00E858A4 /* Release */ = {
470 | isa = XCBuildConfiguration;
471 | buildSettings = {
472 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
473 | DEVELOPMENT_TEAM = MY5GTD35UJ;
474 | INFOPLIST_FILE = AudioRecorder/Info.plist;
475 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
476 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
477 | PRODUCT_BUNDLE_IDENTIFIER = com.phuket.tour.audiotoolbox.encoder.AudioRecorder;
478 | PRODUCT_NAME = "$(TARGET_NAME)";
479 | };
480 | name = Release;
481 | };
482 | 188EA2741E55D4FF00E858A4 /* Debug */ = {
483 | isa = XCBuildConfiguration;
484 | buildSettings = {
485 | BUNDLE_LOADER = "$(TEST_HOST)";
486 | DEVELOPMENT_TEAM = MY5GTD35UJ;
487 | INFOPLIST_FILE = AudioRecorderTests/Info.plist;
488 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
489 | PRODUCT_BUNDLE_IDENTIFIER = com.phuket.tour.audiotoolbox.encoder.AudioRecorderTests;
490 | PRODUCT_NAME = "$(TARGET_NAME)";
491 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AudioRecorder.app/AudioRecorder";
492 | };
493 | name = Debug;
494 | };
495 | 188EA2751E55D4FF00E858A4 /* Release */ = {
496 | isa = XCBuildConfiguration;
497 | buildSettings = {
498 | BUNDLE_LOADER = "$(TEST_HOST)";
499 | DEVELOPMENT_TEAM = MY5GTD35UJ;
500 | INFOPLIST_FILE = AudioRecorderTests/Info.plist;
501 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
502 | PRODUCT_BUNDLE_IDENTIFIER = com.phuket.tour.audiotoolbox.encoder.AudioRecorderTests;
503 | PRODUCT_NAME = "$(TARGET_NAME)";
504 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AudioRecorder.app/AudioRecorder";
505 | };
506 | name = Release;
507 | };
508 | 188EA2771E55D4FF00E858A4 /* Debug */ = {
509 | isa = XCBuildConfiguration;
510 | buildSettings = {
511 | DEVELOPMENT_TEAM = MY5GTD35UJ;
512 | INFOPLIST_FILE = AudioRecorderUITests/Info.plist;
513 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
514 | PRODUCT_BUNDLE_IDENTIFIER = com.phuket.tour.audiotoolbox.encoder.AudioRecorderUITests;
515 | PRODUCT_NAME = "$(TARGET_NAME)";
516 | TEST_TARGET_NAME = AudioRecorder;
517 | };
518 | name = Debug;
519 | };
520 | 188EA2781E55D4FF00E858A4 /* Release */ = {
521 | isa = XCBuildConfiguration;
522 | buildSettings = {
523 | DEVELOPMENT_TEAM = MY5GTD35UJ;
524 | INFOPLIST_FILE = AudioRecorderUITests/Info.plist;
525 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
526 | PRODUCT_BUNDLE_IDENTIFIER = com.phuket.tour.audiotoolbox.encoder.AudioRecorderUITests;
527 | PRODUCT_NAME = "$(TARGET_NAME)";
528 | TEST_TARGET_NAME = AudioRecorder;
529 | };
530 | name = Release;
531 | };
532 | /* End XCBuildConfiguration section */
533 |
534 | /* Begin XCConfigurationList section */
535 | 188EA23E1E55D4FE00E858A4 /* Build configuration list for PBXProject "AudioRecorder" */ = {
536 | isa = XCConfigurationList;
537 | buildConfigurations = (
538 | 188EA26E1E55D4FF00E858A4 /* Debug */,
539 | 188EA26F1E55D4FF00E858A4 /* Release */,
540 | );
541 | defaultConfigurationIsVisible = 0;
542 | defaultConfigurationName = Release;
543 | };
544 | 188EA2701E55D4FF00E858A4 /* Build configuration list for PBXNativeTarget "AudioRecorder" */ = {
545 | isa = XCConfigurationList;
546 | buildConfigurations = (
547 | 188EA2711E55D4FF00E858A4 /* Debug */,
548 | 188EA2721E55D4FF00E858A4 /* Release */,
549 | );
550 | defaultConfigurationIsVisible = 0;
551 | defaultConfigurationName = Release;
552 | };
553 | 188EA2731E55D4FF00E858A4 /* Build configuration list for PBXNativeTarget "AudioRecorderTests" */ = {
554 | isa = XCConfigurationList;
555 | buildConfigurations = (
556 | 188EA2741E55D4FF00E858A4 /* Debug */,
557 | 188EA2751E55D4FF00E858A4 /* Release */,
558 | );
559 | defaultConfigurationIsVisible = 0;
560 | defaultConfigurationName = Release;
561 | };
562 | 188EA2761E55D4FF00E858A4 /* Build configuration list for PBXNativeTarget "AudioRecorderUITests" */ = {
563 | isa = XCConfigurationList;
564 | buildConfigurations = (
565 | 188EA2771E55D4FF00E858A4 /* Debug */,
566 | 188EA2781E55D4FF00E858A4 /* Release */,
567 | );
568 | defaultConfigurationIsVisible = 0;
569 | defaultConfigurationName = Release;
570 | };
571 | /* End XCConfigurationList section */
572 | };
573 | rootObject = 188EA23B1E55D4FE00E858A4 /* Project object */;
574 | }
575 |
--------------------------------------------------------------------------------