├── README.md └── GreyVoiceRecord ├── VoiceRecord ├── arm │ ├── lib │ │ ├── libopencore-amrnb.a │ │ └── libopencore-amrwb.a │ ├── RecordVoice.h │ ├── include │ │ ├── opencore-amrwb │ │ │ ├── if_rom.h │ │ │ └── dec_if.h │ │ └── opencore-amrnb │ │ │ ├── interf_dec.h │ │ │ └── interf_enc.h │ ├── amrFileCodec.h │ ├── RecordVoice.m │ └── amrFileCodec.m ├── cf027d55-bdfd-48ae-bdcf-e9304ca934fc.amr ├── ViewController.h ├── AppDelegate.h ├── main.m ├── RecordButton.h ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── RecordManager.h ├── Info.plist ├── Base.lproj │ ├── Main.storyboard │ └── LaunchScreen.storyboard ├── AppDelegate.m ├── RecordButton.m ├── ViewController.m └── RecordManager.m ├── VoiceRecordTests ├── Info.plist └── VoiceRecordTests.m ├── VoiceRecordUITests ├── Info.plist └── VoiceRecordUITests.m └── VoiceRecord.xcodeproj └── project.pbxproj /README.md: -------------------------------------------------------------------------------- 1 | # GreyRecordCafToAMR 2 | OC - audio caf and amr file transfers 3 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/arm/lib/libopencore-amrnb.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyLove/GreyRecordCafToAMR/HEAD/GreyVoiceRecord/VoiceRecord/arm/lib/libopencore-amrnb.a -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/arm/lib/libopencore-amrwb.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyLove/GreyRecordCafToAMR/HEAD/GreyVoiceRecord/VoiceRecord/arm/lib/libopencore-amrwb.a -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/cf027d55-bdfd-48ae-bdcf-e9304ca934fc.amr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyLove/GreyRecordCafToAMR/HEAD/GreyVoiceRecord/VoiceRecord/cf027d55-bdfd-48ae-bdcf-e9304ca934fc.amr -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // VoiceRecord 4 | // 5 | // Created by 好价网络科技有限公司 on 15/12/15. 6 | // Copyright © 2015年 Grey. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // VoiceRecord 4 | // 5 | // Created by 好价网络科技有限公司 on 15/12/15. 6 | // Copyright © 2015年 Grey. 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 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // VoiceRecord 4 | // 5 | // Created by 好价网络科技有限公司 on 15/12/15. 6 | // Copyright © 2015年 Grey. 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 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/RecordButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // RecordButton.h 3 | // VoiceRecord 4 | // 5 | // Created by 好价网络科技有限公司 on 15/12/25. 6 | // Copyright © 2015年 Grey. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef void(^recordClick)(); 12 | typedef void(^stopClick)(); 13 | typedef void(^cancleClick)(); 14 | 15 | @interface RecordButton : UIButton 16 | 17 | +(RecordButton *)createRecord:(CGRect)frame; 18 | 19 | 20 | 21 | @property (nonatomic, copy) recordClick recordClickBlock; 22 | 23 | @property (nonatomic, copy) stopClick stopClickBlock; 24 | 25 | @property (nonatomic, copy) cancleClick cancleClickBlock; 26 | @end 27 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/arm/RecordVoice.h: -------------------------------------------------------------------------------- 1 | // 2 | // RecordVoice.h 3 | // VoiceRecord 4 | // 5 | // Created by 好价网络科技有限公司 on 15/12/25. 6 | // Copyright © 2015年 Grey. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef void (^progressBlock)(float progress); 12 | 13 | 14 | 15 | @interface RecordVoice : NSObject 16 | 17 | 18 | @property (nonatomic,copy)progressBlock progress; 19 | 20 | /* 录音 uid文件名_时间戳*/ 21 | - (void)recordVioce:(NSString*)uid; 22 | - (NSURL*)stopVioce; 23 | - (void)cancleVoice; 24 | 25 | /* 获取时长 */ 26 | - (NSString*)getAudioTime:(NSData *) data; 27 | 28 | /* 播放caf类型字节 */ 29 | - (void)playCafData:(NSData*)data; 30 | 31 | /* 销毁对象 */ 32 | - (void)destroy; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/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 | } -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecordTests/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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecordUITests/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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/RecordManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // RecordManager.h 3 | // VoiceRecord 4 | // 5 | // Created by 好价网络科技有限公司 on 16/1/15. 6 | // Copyright © 2016年 Grey. All rights reserved. 7 | // 8 | 9 | #import 10 | typedef void (^writeSuccessBlock)(BOOL success,NSData *amrData); 11 | typedef void (^progressBlock)(float progress); 12 | 13 | @interface RecordManager : NSObject 14 | 15 | +(RecordManager*)shareManager; 16 | 17 | @property (nonatomic,copy)progressBlock progress; 18 | 19 | - (void)writeAuToAmrFile:(NSURL*)tmpFileUrl callback:(writeSuccessBlock)block; 20 | 21 | /* 存储文件名 */ 22 | - (void)startTalkVoice:(NSString*)fileName; 23 | 24 | /* 停止返回存储caf的地址 */ 25 | - (NSURL*)stopTalkVoice; 26 | 27 | /* 取消录音,删除文件 */ 28 | - (void)cancelTalkVoice; 29 | 30 | /* 播放amr 文件 */ 31 | - (void)playAmrData:(NSData*)amrData; 32 | 33 | /* 录音时长 */ 34 | - (NSString*)getAudioTime:(NSData *)data; 35 | 36 | /* 销毁对象 */ 37 | - (void)destroy; 38 | @end 39 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecordTests/VoiceRecordTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // VoiceRecordTests.m 3 | // VoiceRecordTests 4 | // 5 | // Created by 好价网络科技有限公司 on 15/12/15. 6 | // Copyright © 2015年 Grey. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface VoiceRecordTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation VoiceRecordTests 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 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/arm/include/opencore-amrwb/if_rom.h: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ 2 | * Copyright (C) 2009 Martin Storsjo 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 | * express or implied. 14 | * See the License for the specific language governing permissions 15 | * and limitations under the License. 16 | * ------------------------------------------------------------------- 17 | */ 18 | 19 | #ifndef OPENCORE_AMRWB_IF_ROM_H 20 | #define OPENCORE_AMRWB_IF_ROM_H 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | #include 27 | typedef int16_t Word16; 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/arm/include/opencore-amrwb/dec_if.h: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ 2 | * Copyright (C) 2009 Martin Storsjo 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 | * express or implied. 14 | * See the License for the specific language governing permissions 15 | * and limitations under the License. 16 | * ------------------------------------------------------------------- 17 | */ 18 | 19 | #ifndef OPENCORE_AMRWB_DEC_IF_H 20 | #define OPENCORE_AMRWB_DEC_IF_H 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | #define _good_frame 0 27 | 28 | void* D_IF_init(void); 29 | void D_IF_decode(void* state, const unsigned char* bits, short* synth, int bfi); 30 | void D_IF_exit(void* state); 31 | 32 | #ifdef __cplusplus 33 | } 34 | #endif 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/arm/include/opencore-amrnb/interf_dec.h: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ 2 | * Copyright (C) 2009 Martin Storsjo 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 | * express or implied. 14 | * See the License for the specific language governing permissions 15 | * and limitations under the License. 16 | * ------------------------------------------------------------------- 17 | */ 18 | 19 | #ifndef OPENCORE_AMRNB_INTERF_DEC_H 20 | #define OPENCORE_AMRNB_INTERF_DEC_H 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | void* Decoder_Interface_init(void); 27 | void Decoder_Interface_exit(void* state); 28 | void Decoder_Interface_Decode(void* state, const unsigned char* in, short* out, int bfi); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/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 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecordUITests/VoiceRecordUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // VoiceRecordUITests.m 3 | // VoiceRecordUITests 4 | // 5 | // Created by 好价网络科技有限公司 on 15/12/15. 6 | // Copyright © 2015年 Grey. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface VoiceRecordUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation VoiceRecordUITests 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 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/Base.lproj/Main.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 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/arm/include/opencore-amrnb/interf_enc.h: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------ 2 | * Copyright (C) 2009 Martin Storsjo 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 | * express or implied. 14 | * See the License for the specific language governing permissions 15 | * and limitations under the License. 16 | * ------------------------------------------------------------------- 17 | */ 18 | 19 | #ifndef OPENCORE_AMRNB_INTERF_ENC_H 20 | #define OPENCORE_AMRNB_INTERF_ENC_H 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | #ifndef AMRNB_WRAPPER_INTERNAL 27 | /* Copied from enc/src/gsmamr_enc.h */ 28 | enum Mode { 29 | MR475 = 0,/* 4.75 kbps */ 30 | MR515, /* 5.15 kbps */ 31 | MR59, /* 5.90 kbps */ 32 | MR67, /* 6.70 kbps */ 33 | MR74, /* 7.40 kbps */ 34 | MR795, /* 7.95 kbps */ 35 | MR102, /* 10.2 kbps */ 36 | MR122, /* 12.2 kbps */ 37 | MRDTX, /* DTX */ 38 | N_MODES /* Not Used */ 39 | }; 40 | #endif 41 | 42 | void* Encoder_Interface_init(int dtx); 43 | void Encoder_Interface_exit(void* state); 44 | int Encoder_Interface_Encode(void* state, enum Mode mode, const short* speech, unsigned char* out, int forceSpeech); 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/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 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/arm/amrFileCodec.h: -------------------------------------------------------------------------------- 1 | // 2 | // amrFileCodec.h 3 | // amrDemoForiOS 4 | // 5 | // Created by Tang Xiaoping on 9/27/11. 6 | // Copyright 2011 test. All rights reserved. 7 | // 8 | #ifndef amrFileCodec_h 9 | #define amrFileCodec_h 10 | #include 11 | #include 12 | #include 13 | #include "interf_dec.h" 14 | #include "interf_enc.h" 15 | #import 16 | #import 17 | #define AMR_MAGIC_NUMBER "#!AMR\n" 18 | 19 | #define PCM_FRAME_SIZE 160 // 8khz 8000*0.02=160 20 | #define MAX_AMR_FRAME_SIZE 32 21 | #define AMR_FRAME_COUNT_PER_SECOND 50 22 | 23 | typedef struct 24 | { 25 | char chChunkID[4]; 26 | int nChunkSize; 27 | }XCHUNKHEADER; 28 | 29 | typedef struct 30 | { 31 | short nFormatTag; 32 | short nChannels; 33 | int nSamplesPerSec; 34 | int nAvgBytesPerSec; 35 | short nBlockAlign; 36 | short nBitsPerSample; 37 | }WAVEFORMAT; 38 | 39 | typedef struct 40 | { 41 | short nFormatTag; 42 | short nChannels; 43 | int nSamplesPerSec; 44 | int nAvgBytesPerSec; 45 | short nBlockAlign; 46 | short nBitsPerSample; 47 | short nExSize; 48 | }WAVEFORMATX; 49 | 50 | typedef struct 51 | { 52 | char chRiffID[4]; 53 | int nRiffSize; 54 | char chRiffFormat[4]; 55 | }RIFFHEADER; 56 | 57 | typedef struct 58 | { 59 | char chFmtID[4]; 60 | int nFmtSize; 61 | WAVEFORMAT wf; 62 | }FMTBLOCK; 63 | 64 | // WAVE音频采样频率是8khz 65 | // 音频样本单元数 = 8000*0.02 = 160 (由采样频率决定) 66 | // 声道数 1 : 160 67 | // 2 : 160*2 = 320 68 | // bps决定样本(sample)大小 69 | // bps = 8 --> 8位 unsigned char 70 | // 16 --> 16位 unsigned short 71 | int EncodeWAVEFileToAMRFile(const char* pchWAVEFilename, const char* pchAMRFileName, int nChannels, int nBitsPerSample); 72 | 73 | 74 | // 将AMR文件解码成WAVE文件 75 | int DecodeAMRFileToWAVEFile(const char* pchAMRFileName, const char* pchWAVEFilename); 76 | 77 | 78 | NSData* DecodeAMRToWAVE(NSData* data); 79 | NSData* EncodeWAVEToAMR(NSData* data, int nChannels, int nBitsPerSample); 80 | 81 | #endif -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // VoiceRecord 4 | // 5 | // Created by 好价网络科技有限公司 on 15/12/15. 6 | // Copyright © 2015年 Grey. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // 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. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // 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. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/RecordButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // RecordButton.m 3 | // VoiceRecord 4 | // 5 | // Created by 好价网络科技有限公司 on 15/12/25. 6 | // Copyright © 2015年 Grey. All rights reserved. 7 | // 8 | 9 | #import "RecordButton.h" 10 | 11 | @implementation RecordButton 12 | 13 | +(RecordButton *)createRecord:(CGRect)frame{ 14 | RecordButton *record = [RecordButton buttonWithType:UIButtonTypeCustom]; 15 | if (!frame.size.width) { 16 | record.frame = CGRectMake(20, 30, 100, 60); 17 | }else{ 18 | record.frame = frame; 19 | } 20 | 21 | [record setTitle:@"长按开始录音" forState:UIControlStateNormal]; 22 | [record setTitle:@"正在录音..." forState:UIControlStateHighlighted]; 23 | [record setTitle:@"正在录音..." forState:UIControlStateSelected]; 24 | 25 | [record setBackgroundColor:[UIColor brownColor]]; 26 | record.titleLabel.font = [UIFont systemFontOfSize:15]; 27 | [record setTitleColor:[UIColor yellowColor] forState:UIControlStateHighlighted]; 28 | 29 | [record addTarget:record action:@selector(recordButtonTouchDown) forControlEvents:UIControlEventTouchDown]; 30 | [record addTarget:record action:@selector(recordButtonTouchUpOutside) forControlEvents:UIControlEventTouchUpOutside]; 31 | [record addTarget:record action:@selector(recordButtonTouchUpInside) forControlEvents:UIControlEventTouchUpInside]; 32 | [record addTarget:record action:@selector(recordDragOutside) forControlEvents:UIControlEventTouchDragExit]; 33 | [record addTarget:record action:@selector(recordDragInside) forControlEvents:UIControlEventTouchDragEnter]; 34 | return record; 35 | 36 | } 37 | - (void)recordButtonTouchDown{ 38 | NSLog(@"UIControlEventTouchDown--开始点击"); 39 | // [self recordClick]; 40 | [self record]; 41 | } 42 | - (void)recordButtonTouchUpOutside{ 43 | NSLog(@"UIControlEventTouchUpOutside--松手取消录音");//松手取消录音 44 | // [self stopClick]; 45 | [self cancel]; 46 | } 47 | - (void)recordButtonTouchUpInside{ 48 | NSLog(@"UIControlEventTouchUpInside--松开点击"); 49 | // [self stopClick]; 50 | [self stop]; 51 | } 52 | - (void)recordDragOutside{ 53 | NSLog(@"UIControlEventTouchDragExit--手指移到外面"); 54 | // [self pauseClick]; 55 | // [self cancel]; 56 | } 57 | - (void)recordDragInside{ 58 | NSLog(@"UIControlEventTouchDragEnter--手指移到里面"); 59 | // [self resumeClick]; 60 | // [self stop]; 61 | } 62 | - (void)record{ 63 | if (_recordClickBlock) { 64 | _recordClickBlock(); 65 | } 66 | } 67 | - (void)stop{ 68 | if (_stopClickBlock) { 69 | _stopClickBlock(); 70 | } 71 | } 72 | 73 | - (void)cancel{ 74 | if (_cancleClickBlock) { 75 | _cancleClickBlock(); 76 | } 77 | } 78 | 79 | @end 80 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // VoiceRecord 4 | // 5 | // Created by 好价网络科技有限公司 on 15/12/15. 6 | // Copyright © 2015年 Grey. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import 11 | #import "RecordButton.h" 12 | 13 | #import "RecordManager.h" 14 | @interface ViewController () 15 | { 16 | UIProgressView *_audioPower;//音频波动 17 | } 18 | @end 19 | static double startRecordTime=0; 20 | static double endRecordTime=0; 21 | 22 | @implementation ViewController 23 | 24 | - (void)viewDidLoad { 25 | [super viewDidLoad]; 26 | 27 | _audioPower = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 400, CGRectGetWidth(self.view.bounds), 20)]; 28 | [self.view addSubview:_audioPower]; 29 | 30 | RecordButton *button = [RecordButton createRecord:CGRectMake(0, 0, 0, 0)]; 31 | [self.view addSubview:button]; 32 | __weak __typeof(self) weakSelf = self; 33 | 34 | button.recordClickBlock = ^(){ 35 | NSLog(@"录音了.."); 36 | [weakSelf recordVoice]; 37 | }; 38 | button.stopClickBlock = ^(){ 39 | 40 | NSLog(@"停止录音了.."); 41 | [weakSelf stopVoice]; 42 | }; 43 | 44 | button.cancleClickBlock = ^(){ 45 | NSLog(@"取消录音"); 46 | [weakSelf cancelRecored]; 47 | }; 48 | [RecordManager shareManager].progress = ^(float progress){ 49 | [weakSelf refreshProgress:progress]; 50 | }; 51 | 52 | } 53 | #pragma mark --获取到amr data字节 54 | 55 | 56 | - (void)recordVoice{ 57 | startRecordTime = [NSDate timeIntervalSinceReferenceDate]; 58 | [[RecordManager shareManager] startTalkVoice:@"3"]; 59 | } 60 | - (void)stopVoice{ 61 | endRecordTime = [NSDate timeIntervalSinceReferenceDate]; 62 | endRecordTime -= startRecordTime; 63 | NSURL *url = [[RecordManager shareManager] stopTalkVoice]; 64 | 65 | [_audioPower setProgress:0.0]; 66 | 67 | if (endRecordTime<2.00f) { 68 | return; 69 | } else if (endRecordTime>30.00f){ 70 | return; 71 | } 72 | 73 | NSData *data = [NSData dataWithContentsOfURL:url]; 74 | 75 | /** 获取时间 */ 76 | NSString *time = [[RecordManager shareManager] getAudioTime:data]; 77 | NSLog(@"%@",time); 78 | 79 | 80 | __weak __typeof(self) weakSelf = self; 81 | 82 | [[RecordManager shareManager] writeAuToAmrFile:url callback:^(BOOL success, NSData *amrData) { 83 | if (success) { 84 | [weakSelf play:amrData]; 85 | 86 | } 87 | }]; 88 | } 89 | 90 | - (void)cancelRecored{ 91 | [_audioPower setProgress:0.0]; 92 | [[RecordManager shareManager] cancelTalkVoice]; 93 | } 94 | - (void)play:(NSData*)data{ 95 | // NSData *data = [NSData dataWithContentsOfFile:path]; 96 | [[RecordManager shareManager] playAmrData:data]; 97 | } 98 | 99 | - (void)refreshProgress:(CGFloat)progress{ 100 | [_audioPower setProgress:progress]; 101 | } 102 | 103 | @end 104 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/RecordManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // RecordManager.m 3 | // VoiceRecord 4 | // 5 | // Created by 好价网络科技有限公司 on 16/1/15. 6 | // Copyright © 2016年 Grey. All rights reserved. 7 | // 8 | 9 | #import "RecordManager.h" 10 | #import "RecordVoice.h" 11 | #import "amrFileCodec.h" 12 | static RecordManager *signle = nil; 13 | @implementation RecordManager 14 | { 15 | RecordVoice *recordVoice; 16 | BOOL isRecording; 17 | } 18 | +(RecordManager*)shareManager{ 19 | static dispatch_once_t onceToken; 20 | dispatch_once(&onceToken, ^{ 21 | signle = [[self alloc] init]; 22 | }); 23 | return signle; 24 | } 25 | 26 | - (id)init{ 27 | if (self = [super init]) { 28 | __weak __typeof(self) weakSelf = self; 29 | recordVoice = [[RecordVoice alloc] init]; 30 | recordVoice.progress = ^(float progress){ 31 | [weakSelf refreshProgress:progress]; 32 | }; 33 | 34 | } 35 | return self; 36 | } 37 | 38 | - (void)refreshProgress:(float)progress{ 39 | if (_progress) { 40 | _progress(progress); 41 | } 42 | } 43 | 44 | - (void)startTalkVoice:(NSString*)fileName{ 45 | [recordVoice recordVioce:fileName]; 46 | } 47 | 48 | - (NSURL*)stopTalkVoice{ 49 | NSURL *fileUrl = [recordVoice stopVioce]; 50 | return fileUrl; 51 | } 52 | 53 | - (void)cancelTalkVoice{ 54 | [recordVoice cancleVoice]; 55 | } 56 | 57 | - (void)playAmrData:(NSData*)amrData{ 58 | 59 | if ([amrData isKindOfClass:[NSData class]]) { 60 | [recordVoice playCafData:DecodeAMRToWAVE(amrData)]; 61 | } 62 | } 63 | - (NSString*)getAudioTime:(NSData *)data{ 64 | 65 | return [recordVoice getAudioTime:data]; 66 | } 67 | /** 68 | * 得到arm格式的Data 69 | */ 70 | - (NSData*)encodeWAVEToAMROfData:(NSData*)cafData{ 71 | NSData *data = EncodeWAVEToAMR(cafData, 1, 16); 72 | return data; 73 | } 74 | 75 | - (NSData*)encodeWAVEToAMROfFile:(NSURL*)cafFileUrl{ 76 | NSData *data = EncodeWAVEToAMR([NSData dataWithContentsOfURL:cafFileUrl], 1, 16); 77 | return data; 78 | } 79 | 80 | /** 81 | * 写入文件 82 | */ 83 | - (void)writeAuToAmrFile:(NSURL*)tmpFileUrl callback:(writeSuccessBlock)block{ 84 | if ([tmpFileUrl isKindOfClass:[NSURL class]]) { 85 | NSData *amrData = [self encodeWAVEToAMROfFile:tmpFileUrl]; 86 | [self writeToAmrFile:tmpFileUrl amrData:amrData call:block]; 87 | } 88 | } 89 | 90 | - (void)writeToAmrFile:(NSURL*)tempFile0 amrData:(NSData*)curAudioData call:(writeSuccessBlock)block{ 91 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 92 | NSString *documentPath = [paths objectAtIndex:0]; 93 | NSString *amrName = [[[tempFile0 lastPathComponent] componentsSeparatedByString:@"."] firstObject]; 94 | NSString *amrFile = [documentPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.amr",amrName]]; 95 | BOOL ist = [curAudioData writeToFile:amrFile atomically:YES]; 96 | if (block) { 97 | block(ist,curAudioData); 98 | } 99 | 100 | } 101 | - (void)destroy{ 102 | [recordVoice destroy]; 103 | } 104 | @end 105 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/arm/RecordVoice.m: -------------------------------------------------------------------------------- 1 | // 2 | // RecordVoice.m 3 | // VoiceRecord 4 | // 5 | // Created by 好价网络科技有限公司 on 15/12/25. 6 | // Copyright © 2015年 Grey. All rights reserved. 7 | // 8 | 9 | #import "RecordVoice.h" 10 | #import 11 | #import 12 | //#import "amrFileCodec.h" 13 | 14 | @interface RecordVoice() 15 | { 16 | NSData *curAudio; 17 | NSURL *tempFile; 18 | //录音 19 | AVAudioRecorder *_audioRecorder; 20 | 21 | //音频播放器,用于播放录音文件 22 | AVAudioPlayer *_audioPlayer; 23 | } 24 | @property (nonatomic,strong) NSTimer *timer;//录音声波监控(注意这里暂时不对播放进行监控) 25 | 26 | @end 27 | 28 | @implementation RecordVoice 29 | 30 | 31 | - (id)init{ 32 | if (self = [super init]) { 33 | [self setAudioSession]; 34 | [[UIDevice currentDevice] setProximityMonitoringEnabled:YES]; //建议在播放之前设置yes,播放结束设置NO,这个功能是开启红外感应 35 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sensorStateChange:) name:UIDeviceProximityStateDidChangeNotification object:nil]; 36 | } 37 | return self; 38 | } 39 | //处理监听触发事件 40 | -(void)sensorStateChange:(NSNotificationCenter *)notification; 41 | { 42 | if ([[UIDevice currentDevice] proximityState] == YES){ 43 | NSLog(@"Device is close to user"); 44 | [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; 45 | } 46 | else{ 47 | NSLog(@"Device is not close to user"); 48 | [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; 49 | } 50 | } 51 | 52 | -(void)setAudioSession{ 53 | AVAudioSession *audioSession=[AVAudioSession sharedInstance]; 54 | //设置为播放和录音状态,以便可以在录制完之后播放录音 55 | [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil]; 56 | [audioSession setActive:YES error:nil]; 57 | 58 | } 59 | 60 | 61 | 62 | /** 63 | * 取得录音文件设置 64 | * 65 | * @return 录音设置 66 | */ 67 | -(NSDictionary *)getAudioSetting{ 68 | // NSMutableDictionary *dicM=[NSMutableDictionary dictionary]; 69 | // //设置录音格式 70 | // [dicM setObject:@(kAudioFormatLinearPCM) forKey:AVFormatIDKey]; 71 | // //设置录音采样率,8000是电话采样率,对于一般录音已经够了 72 | // [dicM setObject:@(8000) forKey:AVSampleRateKey]; 73 | // //设置通道,这里采用单声道 74 | // [dicM setObject:@(1) forKey:AVNumberOfChannelsKey]; 75 | // //每个采样点位数,分为8、16、24、32 76 | // [dicM setObject:@(16) forKey:AVLinearPCMBitDepthKey]; 77 | // //是否使用浮点数采样 78 | // [dicM setObject:@(YES) forKey:AVLinearPCMIsFloatKey]; 79 | // //....其他设置等 80 | // return dicM; 81 | NSDictionary *recordSetting = [NSDictionary dictionaryWithObjectsAndKeys: 82 | [NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey, 83 | //[NSNumber numberWithFloat:44100.0], AVSampleRateKey, 84 | [NSNumber numberWithFloat:8000.00], AVSampleRateKey, 85 | [NSNumber numberWithInt:1], AVNumberOfChannelsKey, 86 | // [NSData dataWithBytes:&channelLayout length:sizeof(AudioChannelLayout)], AVChannelLayoutKey, 87 | [NSNumber numberWithInt:16], AVLinearPCMBitDepthKey, 88 | [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved, 89 | [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey, 90 | [NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey, 91 | nil]; 92 | return recordSetting; 93 | } 94 | 95 | /** 96 | * 获得录音机对象 97 | * 98 | * @return 录音机对象 99 | */ 100 | -(AVAudioRecorder *)setupAudioRecorder:(NSString*)uid{ 101 | 102 | //创建录音文件保存路径 103 | NSURL *url=[self getSavePath:uid]; 104 | /** 获取录音对象 */ 105 | tempFile = url; 106 | //创建录音格式设置 107 | NSDictionary *setting=[self getAudioSetting]; 108 | //创建录音机 109 | NSError *error=nil; 110 | _audioRecorder=[[AVAudioRecorder alloc]initWithURL:tempFile settings:setting error:&error]; 111 | _audioRecorder.delegate= self; 112 | _audioRecorder.meteringEnabled=YES;//如果要监控声波则必须设置为YES 113 | if (error) { 114 | NSLog(@"创建录音机对象时发生错误,错误信息:%@",error.localizedDescription); 115 | return nil; 116 | } 117 | 118 | return _audioRecorder; 119 | } 120 | /** 121 | * 取得录音文件保存路径 122 | * 123 | * @return 录音文件路径 124 | */ 125 | -(NSURL *)getSavePath:(NSString*)uid{ 126 | NSString *tmpDir = NSTemporaryDirectory(); 127 | /** 当前时间搓 */ 128 | NSString *timeSp = [NSString stringWithFormat:@"%.f",[[NSDate date] timeIntervalSince1970]]; 129 | if (uid.length) { 130 | NSString *cafFlileStr = [NSString stringWithFormat:@"%@_%@.caf",uid,timeSp]; 131 | tmpDir=[tmpDir stringByAppendingPathComponent:cafFlileStr]; 132 | }else{ 133 | NSString *cafFlileStr = [NSString stringWithFormat:@"%@.caf",timeSp]; 134 | tmpDir=[tmpDir stringByAppendingPathComponent:cafFlileStr]; 135 | } 136 | NSLog(@"file path---:%@",tmpDir); 137 | NSURL *url=[NSURL fileURLWithPath:tmpDir]; 138 | return url; 139 | } 140 | /** 141 | * 录音声波监控定制器 142 | * 143 | * @return 定时器 144 | */ 145 | -(NSTimer *)timer{ 146 | if (!_timer) { 147 | _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self 148 | selector:@selector(audioPowerChange) 149 | userInfo:nil 150 | repeats:YES]; 151 | /** 防止强引用 */ 152 | [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes]; 153 | } 154 | return _timer; 155 | } 156 | /** 157 | * 录音声波状态设置 158 | */ 159 | -(void)audioPowerChange{ 160 | [_audioRecorder updateMeters];//更新测量值 161 | float power= [_audioRecorder averagePowerForChannel:0];//取得第一个通道的音频,注意音频强度范围时-160到0 162 | CGFloat progress=(1.0/160.0)*(power+160.0); 163 | if (_progress) { 164 | _progress(progress); 165 | } 166 | } 167 | #pragma mark --录音代理 168 | -(void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{ 169 | NSLog(@"录音完成!"); 170 | _audioRecorder = nil; 171 | [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; 172 | } 173 | - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{ 174 | NSLog(@"播放完成"); 175 | [[UIDevice currentDevice] setProximityMonitoringEnabled:NO]; 176 | _audioPlayer = nil; 177 | } 178 | 179 | /** 180 | * 播放 181 | */ 182 | - (void)playCafData:(NSData*)data{ 183 | NSError *error; 184 | /** 只能播放caf的 amr的是播放不了的*/ 185 | _audioPlayer=[[AVAudioPlayer alloc]initWithData:data 186 | error:&error]; 187 | _audioPlayer.numberOfLoops=0; 188 | _audioPlayer.delegate = self; 189 | [_audioPlayer prepareToPlay]; 190 | 191 | 192 | if (error) { 193 | NSLog(@"创建播放器过程中发生错误,错误信息:%@",error.localizedDescription); 194 | return ; 195 | } 196 | if (![_audioPlayer isPlaying]) { 197 | [_audioPlayer play]; 198 | } 199 | 200 | } 201 | 202 | /** 203 | * 录制的时间 204 | */ 205 | - (NSString*)getAudioTime:(NSData *) data { 206 | NSError * error; 207 | AVAudioPlayer*play = [[AVAudioPlayer alloc] initWithData:data error:&error]; 208 | NSTimeInterval n = [play duration]; 209 | NSString *timeStr = [NSString stringWithFormat:@"%.1f",n]; 210 | 211 | return timeStr; 212 | } 213 | 214 | 215 | /** 216 | * 录制 217 | */ 218 | - (void)recordVioce:(NSString*)uid{ 219 | [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; 220 | [self checkMicrophone]; 221 | [_audioPlayer stop]; 222 | _audioPlayer = nil; 223 | [self setupAudioRecorder:uid]; 224 | if (![_audioRecorder isRecording]) { 225 | [_audioRecorder record];//首次使用应用时如果调用record方法会询问用户是否允许使用麦克风 226 | self.timer.fireDate=[NSDate distantPast]; 227 | } 228 | } 229 | -(void)checkMicrophone 230 | { 231 | [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) { 232 | if (!granted) { 233 | NSString * messageString = [NSString stringWithFormat:@"请在iPhone\"设置-隐私-麦克风\"中,允许手机看病访问你的麦克风"]; 234 | UIAlertView* alert = [[UIAlertView alloc] initWithTitle:nil message:messageString delegate:self cancelButtonTitle:@"确定" otherButtonTitles:@"立即设置", nil]; 235 | [alert show]; 236 | } 237 | }]; 238 | 239 | 240 | } 241 | 242 | - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 243 | { 244 | if (buttonIndex==1) { 245 | if(([[UIDevice currentDevice].systemVersion floatValue])>=8.0){ 246 | NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; 247 | if ([[UIApplication sharedApplication] canOpenURL:url]) { 248 | [[UIApplication sharedApplication] openURL:url]; 249 | } 250 | } else { 251 | NSURL*url=[NSURL URLWithString:@"prefs:root=Privacy"]; 252 | [[UIApplication sharedApplication] openURL:url]; 253 | } 254 | } 255 | } 256 | /** 257 | * 停止录音 258 | */ 259 | - (NSURL*)stopVioce{ 260 | 261 | [_audioRecorder stop]; 262 | _audioRecorder = nil; 263 | self.timer.fireDate=[NSDate distantFuture]; 264 | return tempFile; 265 | } 266 | /** 267 | * 暂停录音 268 | */ 269 | 270 | - (void)pauseVoice{ 271 | if ([_audioRecorder isRecording]) { 272 | 273 | [_audioRecorder pause]; 274 | } 275 | } 276 | /** 277 | * 取消 278 | */ 279 | - (void)cancleVoice{ 280 | _audioRecorder.delegate = nil; 281 | 282 | if ([_audioRecorder isRecording]) { 283 | [_audioRecorder stop]; 284 | [_audioRecorder deleteRecording]; 285 | self.timer.fireDate=[NSDate distantFuture]; 286 | } 287 | _audioRecorder = nil; 288 | } 289 | 290 | /** 291 | * 销毁 292 | */ 293 | - (void)destroy{ 294 | [_audioPlayer stop]; 295 | [_audioRecorder stop]; 296 | _audioRecorder = nil; 297 | _audioPlayer = nil; 298 | [self.timer invalidate]; 299 | self.timer = nil; 300 | [[UIDevice currentDevice] setProximityMonitoringEnabled:NO]; 301 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 302 | } 303 | 304 | - (void)dealloc{ 305 | [_audioPlayer stop]; 306 | [_audioRecorder stop]; 307 | _audioRecorder = nil; 308 | _audioPlayer = nil; 309 | [self.timer invalidate]; 310 | self.timer = nil; 311 | [[UIDevice currentDevice] setProximityMonitoringEnabled:NO]; 312 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 313 | } 314 | 315 | @end 316 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord/arm/amrFileCodec.m: -------------------------------------------------------------------------------- 1 | // 2 | // amrFileCodec.cpp 3 | // amrDemoForiOS 4 | // 5 | // Created by Tang Xiaoping on 9/27/11. 6 | // Copyright 2011 test. All rights reserved. 7 | // 8 | 9 | #include "amrFileCodec.h" 10 | #import 11 | #import 12 | typedef unsigned long long u64; 13 | typedef long long s64; 14 | typedef unsigned int u32; 15 | typedef unsigned short u16; 16 | typedef unsigned char u8; 17 | int amrEncodeMode[] = {4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200}; // amr 编码方式 18 | 19 | u16 readUInt16(char* bis) { 20 | u16 result = 0; 21 | result += ((u16)(bis[0])) << 8; 22 | result += (u8)(bis[1]); 23 | return result; 24 | } 25 | 26 | u32 readUint32(char* bis) { 27 | u32 result = 0; 28 | result += ((u32) readUInt16(bis)) << 16; 29 | bis+=2; 30 | result += readUInt16(bis); 31 | return result; 32 | } 33 | 34 | s64 readSint64(char* bis) { 35 | s64 result = 0; 36 | result += ((u64) readUint32(bis)) << 32; 37 | bis+=4; 38 | result += readUint32(bis); 39 | return result; 40 | } 41 | 42 | NSData * fuckAndroid3GP(NSData *data) { 43 | //http://android.amberfog.com/?p=181 44 | u32 size = 0; 45 | u32 type =0; 46 | u32 boxSize =0; 47 | //char HEADER_TYPE[] = {'f', 't', 'y', 'p'}; 48 | 49 | char AMR_MAGIC_HEADER[6] = {0x23, 0x21, 0x41, 0x4d, 0x52, 0x0a}; 50 | 51 | u32 brand =0; 52 | u32 minorVersion=0; 53 | //u32 *compatibleBrands; 54 | 55 | if (data.length<50) { 56 | NSLog(@"not android 3gp"); 57 | return data; 58 | } 59 | char *bis = (char *)[data bytes]; 60 | 61 | size = readUint32(bis); 62 | boxSize += 4; 63 | bis+=4; 64 | type = readUint32(bis); 65 | boxSize += 4; 66 | bis+=4; 67 | if (type!=0x66747970) { 68 | NSLog(@"not android 3gp"); 69 | return data; 70 | } 71 | 72 | brand = readUint32(bis); 73 | boxSize += 4; 74 | bis+=4; 75 | minorVersion = readUint32(bis); 76 | boxSize += 4; 77 | bis+=4; 78 | int remainSize = (int)(size - boxSize); 79 | if (remainSize > 0) { 80 | //compatibleBrands = new u32[remainSize / 4]; 81 | for (int i = 0; i < remainSize / 4; i++) { 82 | //compatibleBrands[i] = 83 | readUint32(bis); 84 | bis+=4; 85 | } 86 | } 87 | 88 | boxSize = 0; 89 | size = readUint32(bis); 90 | boxSize += 4; 91 | bis+=4; 92 | type = readUint32(bis); 93 | boxSize += 4; 94 | bis+=4; 95 | 96 | int rawAmrDataLength=(size - boxSize); 97 | int fullAmrDataLength = 6 + rawAmrDataLength; 98 | //char* amrData = new char[fullAmrDataLength]; 99 | NSMutableData *amrData = [[NSMutableData alloc]initWithCapacity:fullAmrDataLength]; 100 | //memcpy(amrData,AMR_MAGIC_HEADER,6); 101 | //memcpy(amrData+6,bis,rawAmrDataLength); 102 | [amrData appendBytes:AMR_MAGIC_HEADER length:6]; 103 | [amrData appendBytes:bis length:rawAmrDataLength]; 104 | 105 | return amrData; 106 | } 107 | 108 | 109 | #pragma mark - Decode 110 | //decode 111 | 112 | const int myround(const double x) 113 | { 114 | return((int)(x+0.5)); 115 | } 116 | 117 | // 根据帧头计算当前帧大小 118 | int caclAMRFrameSize(unsigned char frameHeader) 119 | { 120 | int mode; 121 | int temp1 = 0; 122 | int temp2 = 0; 123 | int frameSize; 124 | 125 | temp1 = frameHeader; 126 | 127 | // 编码方式编号 = 帧头的3-6位 128 | temp1 &= 0x78; // 0111-1000 129 | temp1 >>= 3; 130 | 131 | mode = amrEncodeMode[temp1]; 132 | 133 | // 计算amr音频数据帧大小 134 | // 原理: amr 一帧对应20ms,那么一秒有50帧的音频数据 135 | temp2 = myround((double)(((double)mode / (double)AMR_FRAME_COUNT_PER_SECOND) / (double)8)); 136 | 137 | frameSize = myround((double)temp2 + 0.5); 138 | return frameSize; 139 | } 140 | 141 | // 读第一个帧 - (参考帧) 142 | // 返回值: 0-出错; 1-正确 143 | int ReadAMRFrameFirstData(char* fpamr,int pos,int maxLen, unsigned char frameBuffer[], int* stdFrameSize, unsigned char* stdFrameHeader) 144 | { 145 | int nPos = 0; 146 | memset(frameBuffer, 0, sizeof(frameBuffer)); 147 | 148 | // 先读帧头 149 | //fread(stdFrameHeader, 1, sizeof(unsigned char), fpamr); 150 | stdFrameHeader[0] = fpamr[pos];nPos++; 151 | if (pos+nPos >= maxLen) { 152 | return 0; 153 | } 154 | //if (feof(fpamr)) return 0; 155 | 156 | // 根据帧头计算帧大小 157 | *stdFrameSize = caclAMRFrameSize(*stdFrameHeader); 158 | 159 | // 读首帧 160 | frameBuffer[0] = *stdFrameHeader; 161 | if ((*stdFrameSize-1)*sizeof(unsigned char)<=0) { 162 | return 0; 163 | } 164 | 165 | memcpy(&(frameBuffer[1]), fpamr+pos+nPos, (*stdFrameSize-1)*sizeof(unsigned char)); 166 | //fread(&(frameBuffer[1]), 1, (*stdFrameSize-1)*sizeof(unsigned char), fpamr); 167 | //if (feof(fpamr)) return 0; 168 | nPos += (*stdFrameSize-1)*sizeof(unsigned char); 169 | if (pos+nPos >= maxLen) { 170 | return 0; 171 | } 172 | 173 | return nPos; 174 | } 175 | 176 | // 返回值: 0-出错; 1-正确 177 | int ReadAMRFrameData(char* fpamr,int pos,int maxLen, unsigned char frameBuffer[], int stdFrameSize, unsigned char stdFrameHeader) 178 | { 179 | int bytes = 0; 180 | int nPos = 0; 181 | unsigned char frameHeader; // 帧头 182 | 183 | memset(frameBuffer, 0, sizeof(frameBuffer)); 184 | 185 | // 读帧头 186 | // 如果是坏帧(不是标准帧头),则继续读下一个字节,直到读到标准帧头 187 | while(1) 188 | { 189 | //bytes = fread(&frameHeader, 1, sizeof(unsigned char), fpamr); 190 | //if (feof(fpamr)) return 0; 191 | if (pos+nPos >=maxLen) { 192 | return 0; 193 | } 194 | frameHeader = fpamr[pos+nPos]; nPos++; 195 | if (frameHeader == stdFrameHeader) break; 196 | } 197 | 198 | // 读该帧的语音数据(帧头已经读过) 199 | frameBuffer[0] = frameHeader; 200 | //bytes = fread(&(frameBuffer[1]), 1, (stdFrameSize-1)*sizeof(unsigned char), fpamr); 201 | //if (feof(fpamr)) return 0; 202 | if ((stdFrameSize-1)*sizeof(unsigned char)<=0) { 203 | return 0; 204 | } 205 | memcpy(&(frameBuffer[1]), fpamr+pos+nPos, (stdFrameSize-1)*sizeof(unsigned char)); 206 | nPos += (stdFrameSize-1)*sizeof(unsigned char); 207 | if (pos+nPos >= maxLen) { 208 | return 0; 209 | } 210 | 211 | return nPos; 212 | } 213 | 214 | void WriteWAVEHeader(NSMutableData* fpwave, int nFrame) 215 | { 216 | char tag[10] = ""; 217 | 218 | // 1. 写RIFF头 219 | RIFFHEADER riff; 220 | strcpy(tag, "RIFF"); 221 | memcpy(riff.chRiffID, tag, 4); 222 | riff.nRiffSize = 4 // WAVE 223 | + sizeof(XCHUNKHEADER) // fmt 224 | + sizeof(WAVEFORMATX) // WAVEFORMATX 225 | + sizeof(XCHUNKHEADER) // DATA 226 | + nFrame*160*sizeof(short); // 227 | strcpy(tag, "WAVE"); 228 | memcpy(riff.chRiffFormat, tag, 4); 229 | //fwrite(&riff, 1, sizeof(RIFFHEADER), fpwave); 230 | [fpwave appendBytes:&riff length:sizeof(RIFFHEADER)]; 231 | 232 | // 2. 写FMT块 233 | XCHUNKHEADER chunk; 234 | WAVEFORMATX wfx; 235 | strcpy(tag, "fmt "); 236 | memcpy(chunk.chChunkID, tag, 4); 237 | chunk.nChunkSize = sizeof(WAVEFORMATX); 238 | //fwrite(&chunk, 1, sizeof(XCHUNKHEADER), fpwave); 239 | [fpwave appendBytes:&chunk length:sizeof(XCHUNKHEADER)]; 240 | memset(&wfx, 0, sizeof(WAVEFORMATX)); 241 | wfx.nFormatTag = 1; 242 | wfx.nChannels = 1; // 单声道 243 | wfx.nSamplesPerSec = 8000; // 8khz 244 | wfx.nAvgBytesPerSec = 16000; 245 | wfx.nBlockAlign = 2; 246 | wfx.nBitsPerSample = 16; // 16位 247 | //fwrite(&wfx, 1, sizeof(WAVEFORMATX), fpwave); 248 | [fpwave appendBytes:&wfx length:sizeof(WAVEFORMATX)]; 249 | 250 | // 3. 写data块头 251 | strcpy(tag, "data"); 252 | memcpy(chunk.chChunkID, tag, 4); 253 | chunk.nChunkSize = nFrame*160*sizeof(short); 254 | //fwrite(&chunk, 1, sizeof(XCHUNKHEADER), fpwave); 255 | [fpwave appendBytes:&chunk length:sizeof(XCHUNKHEADER)]; 256 | 257 | } 258 | 259 | NSData* DecodeAMRToWAVE(NSData* data) { 260 | NSMutableData* fpwave = nil; 261 | void * destate; 262 | int nFrameCount = 0; 263 | int stdFrameSize; 264 | int nTemp; 265 | char bErr = 0; 266 | unsigned char stdFrameHeader; 267 | 268 | unsigned char amrFrame[MAX_AMR_FRAME_SIZE]; 269 | short pcmFrame[PCM_FRAME_SIZE]; 270 | 271 | if (data.length<=0) { 272 | return nil; 273 | } 274 | 275 | const char* rfile = [data bytes]; 276 | int maxLen = [data length]; 277 | int pos = 0; 278 | 279 | //有可能是android 3gp格式 280 | if (strncmp(rfile, AMR_MAGIC_NUMBER, strlen(AMR_MAGIC_NUMBER))) 281 | { 282 | data = fuckAndroid3GP(data); 283 | } 284 | 285 | rfile = [data bytes]; 286 | // 检查amr文件头 287 | if (strncmp(rfile, AMR_MAGIC_NUMBER, strlen(AMR_MAGIC_NUMBER))) 288 | { 289 | return nil; 290 | } 291 | 292 | pos += strlen(AMR_MAGIC_NUMBER); 293 | // 创建并初始化WAVE文件 294 | 295 | fpwave = [[NSMutableData alloc]init]; 296 | //WriteWAVEHeader(fpwave, nFrameCount); 297 | 298 | /* init decoder */ 299 | destate = Decoder_Interface_init(); 300 | 301 | // 读第一帧 - 作为参考帧 302 | memset(amrFrame, 0, sizeof(amrFrame)); 303 | memset(pcmFrame, 0, sizeof(pcmFrame)); 304 | //ReadAMRFrameFirst(fpamr, amrFrame, &stdFrameSize, &stdFrameHeader); 305 | 306 | nTemp = ReadAMRFrameFirstData(rfile,pos,maxLen, amrFrame, &stdFrameSize, &stdFrameHeader); 307 | if (nTemp==0) { 308 | Decoder_Interface_exit(destate); 309 | return data; 310 | } 311 | pos += nTemp; 312 | 313 | // 解码一个AMR音频帧成PCM数据 314 | Decoder_Interface_Decode(destate, amrFrame, pcmFrame, 0); 315 | nFrameCount++; 316 | //fwrite(pcmFrame, sizeof(short), PCM_FRAME_SIZE, fpwave); 317 | [fpwave appendBytes:pcmFrame length:PCM_FRAME_SIZE*sizeof(short)]; 318 | 319 | 320 | // 逐帧解码AMR并写到WAVE文件里 321 | while(1) 322 | { 323 | memset(amrFrame, 0, sizeof(amrFrame)); 324 | memset(pcmFrame, 0, sizeof(pcmFrame)); 325 | //if (!ReadAMRFrame(fpamr, amrFrame, stdFrameSize, stdFrameHeader)) break; 326 | nTemp = ReadAMRFrameData(rfile,pos,maxLen, amrFrame, stdFrameSize, stdFrameHeader); 327 | if (!nTemp) {bErr = 1;break;} 328 | pos += nTemp; 329 | 330 | // 解码一个AMR音频帧成PCM数据 (8k-16b-单声道) 331 | Decoder_Interface_Decode(destate, amrFrame, pcmFrame, 0); 332 | nFrameCount++; 333 | //fwrite(pcmFrame, sizeof(short), PCM_FRAME_SIZE, fpwave); 334 | [fpwave appendBytes:pcmFrame length:PCM_FRAME_SIZE*sizeof(short)]; 335 | } 336 | // NSLog(@"frame = %d", nFrameCount); 337 | Decoder_Interface_exit(destate); 338 | 339 | //fclose(fpwave); 340 | 341 | // 重写WAVE文件头 342 | //fpwave = fopen([docFilePath cStringUsingEncoding:NSASCIIStringEncoding], "r+"); 343 | //if (!bErr) { 344 | 345 | NSMutableData *out = [[NSMutableData alloc]init]; 346 | WriteWAVEHeader(out, nFrameCount); 347 | [out appendData:fpwave]; 348 | //fclose(fpwave); 349 | 350 | return out; 351 | //} 352 | 353 | // return data; 354 | } 355 | 356 | 357 | #pragma mark Encode 358 | // 从WAVE文件读一个完整的PCM音频帧 359 | // 返回值: 0-错误 >0: 完整帧大小 360 | int ReadPCMFrameData(short speech[], char* fpwave, int nChannels, int nBitsPerSample) 361 | { 362 | int nRead = 0; 363 | int x = 0, y=0; 364 | unsigned short ush1=0, ush2=0, ush=0; 365 | 366 | // 原始PCM音频帧数据 367 | unsigned char pcmFrame_8b1[PCM_FRAME_SIZE]; 368 | unsigned char pcmFrame_8b2[PCM_FRAME_SIZE<<1]; 369 | unsigned short pcmFrame_16b1[PCM_FRAME_SIZE]; 370 | unsigned short pcmFrame_16b2[PCM_FRAME_SIZE<<1]; 371 | 372 | nRead = (nBitsPerSample/8) * PCM_FRAME_SIZE*nChannels; 373 | if (nBitsPerSample==8 && nChannels==1) 374 | { 375 | //nRead = fread(pcmFrame_8b1, (nBitsPerSample/8), PCM_FRAME_SIZE*nChannels, fpwave); 376 | memcpy(pcmFrame_8b1,fpwave,nRead); 377 | for(x=0; x> 1; 398 | //speech[y] = (short)((short)ush << 7); 399 | } 400 | } 401 | else 402 | if (nBitsPerSample==16 && nChannels==1) 403 | { 404 | //nRead = fread(pcmFrame_16b1, (nBitsPerSample/8), PCM_FRAME_SIZE*nChannels, fpwave); 405 | memcpy(pcmFrame_16b1,fpwave,nRead); 406 | 407 | for(x=0; x> 1; 422 | } 423 | } 424 | 425 | // 如果读到的数据不是一个完整的PCM帧, 就返回0 426 | return nRead; 427 | } 428 | 429 | // WAVE音频采样频率是8khz 430 | // 音频样本单元数 = 8000*0.02 = 160 (由采样频率决定) 431 | // 声道数 1 : 160 432 | // 2 : 160*2 = 320 433 | // bps决定样本(sample)大小 434 | // bps = 8 --> 8位 unsigned char 435 | // 16 --> 16位 unsigned short 436 | NSData* EncodePCMToAMR(char* data, int maxLen,int nChannels, int nBitsPerSample) 437 | { 438 | char* oldBuf = data; 439 | /* input speech vector */ 440 | short speech[160]; 441 | 442 | /* counters */ 443 | int byte_counter, frames = 0, bytes = 0; 444 | 445 | /* pointer to encoder state structure */ 446 | void *enstate; 447 | 448 | /* requested mode */ 449 | enum Mode req_mode = MR122; 450 | int dtx = 0; 451 | 452 | /* bitstream filetype */ 453 | unsigned char amrFrame[MAX_AMR_FRAME_SIZE]; 454 | 455 | NSMutableData* out = [[NSMutableData alloc]init]; 456 | /* write magic number to indicate single channel AMR file storage format */ 457 | //bytes = fwrite(AMR_MAGIC_NUMBER, sizeof(char), strlen(AMR_MAGIC_NUMBER), fpamr); 458 | [out appendBytes:AMR_MAGIC_NUMBER length:strlen(AMR_MAGIC_NUMBER)]; 459 | 460 | /* skip to pcm audio data*/ 461 | //SkipToPCMAudioData(fpwave); 462 | 463 | enstate = Encoder_Interface_init(dtx); 464 | 465 | while(1) 466 | { 467 | // read one pcm frame 468 | if ((data-oldBuf+320)>maxLen) { 469 | break; 470 | } 471 | int nRead = ReadPCMFrameData(speech, data, nChannels, nBitsPerSample); 472 | data += nRead; 473 | 474 | 475 | frames++; 476 | 477 | /* call encoder */ 478 | byte_counter = Encoder_Interface_Encode(enstate, req_mode, speech, amrFrame, 0); 479 | 480 | bytes += byte_counter; 481 | //fwrite(amrFrame, sizeof (unsigned char), byte_counter, fpamr ); 482 | [out appendBytes:amrFrame length:byte_counter]; 483 | } 484 | 485 | Encoder_Interface_exit(enstate); 486 | 487 | #ifdef DEBUG 488 | // NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 489 | // NSString *documentPath = [paths objectAtIndex:0]; 490 | // NSString *wavFile = [documentPath stringByAppendingPathComponent:[NSString stringWithFormat:@"88.amr"]]; 491 | // [out writeToFile:wavFile atomically:YES]; 492 | #endif 493 | 494 | return out; 495 | } 496 | 497 | //http://developer.apple.com/library/mac/#documentation/MusicAudio/Reference/CAFSpec/CAF_spec/CAF_spec.html#//apple_ref/doc/uid/TP40001862-CH210-SW1 498 | 499 | //struct CAFFileHeader { 500 | // UInt32 mFileType; 501 | // UInt16 mFileVersion; 502 | // UInt16 mFileFlags; 503 | //}; 504 | // 505 | //struct CAFChunkHeader { 506 | // UInt32 mChunkType; 507 | // SInt64 mChunkSize; 508 | //}; 509 | 510 | int SkipCaffHead(char* buf){ 511 | 512 | if (!buf) { 513 | return 0; 514 | } 515 | char* oldBuf = buf; 516 | u32 mFileType = readUint32(buf); 517 | if (0x63616666!=mFileType) { 518 | return 0; 519 | } 520 | buf+=4; 521 | 522 | u16 mFileVersion = readUInt16(buf); 523 | buf+=2; 524 | u16 mFileFlags = readUInt16(buf); 525 | buf+=2; 526 | 527 | //desc free data 528 | u32 magics[3] = {0x64657363,0x66726565,0x64617461}; 529 | for (int i=0; i<3; ++i) { 530 | u32 mChunkType = readUint32(buf);buf+=4; 531 | if (magics[i]!=mChunkType) { 532 | return 0; 533 | } 534 | 535 | u32 mChunkSize = readSint64(buf);buf+=8; 536 | if (mChunkSize<=0) { 537 | return 0; 538 | } 539 | if (i==2) { 540 | return buf-oldBuf; 541 | } 542 | buf += mChunkSize; 543 | 544 | } 545 | 546 | 547 | return 1; 548 | } 549 | 550 | 551 | //此处将一个录制的pcm直接转换为amr格式 552 | //调用方式为 EncodeWAVEToAMR(pcmData,1,16); 553 | NSData* EncodeWAVEToAMR(NSData* data, int nChannels, int nBitsPerSample) 554 | { 555 | // NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 556 | // NSString *documentPath = [paths objectAtIndex:0]; 557 | // NSString *wavFile = [documentPath stringByAppendingPathComponent:[NSString stringWithFormat:@"11.caf"]]; 558 | // NSLog(@"documentPath=%@", documentPath); 559 | 560 | if (data==nil){ 561 | //data = [NSData dataWithContentsOfFile:wavFile]; 562 | return nil; 563 | } 564 | 565 | int nPos = 0; 566 | char* buf = [data bytes]; 567 | int maxLen = [data length]; 568 | 569 | 570 | nPos += SkipCaffHead(buf); 571 | if (nPos>=maxLen) { 572 | return nil; 573 | } 574 | 575 | //这时取出来的是纯pcm数据 576 | buf += nPos; 577 | 578 | return EncodePCMToAMR(buf,maxLen- nPos,nChannels,nBitsPerSample); 579 | } 580 | 581 | -------------------------------------------------------------------------------- /GreyVoiceRecord/VoiceRecord.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 191DF6A11C2CEB9800B896CB /* RecordButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 191DF6A01C2CEB9800B896CB /* RecordButton.m */; }; 11 | 199DB6E61C1FC61400CE9518 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 199DB6E51C1FC61400CE9518 /* main.m */; }; 12 | 199DB6E91C1FC61400CE9518 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 199DB6E81C1FC61400CE9518 /* AppDelegate.m */; }; 13 | 199DB6EC1C1FC61400CE9518 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 199DB6EB1C1FC61400CE9518 /* ViewController.m */; }; 14 | 199DB6EF1C1FC61400CE9518 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 199DB6ED1C1FC61400CE9518 /* Main.storyboard */; }; 15 | 199DB6F11C1FC61400CE9518 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 199DB6F01C1FC61400CE9518 /* Assets.xcassets */; }; 16 | 199DB6F41C1FC61400CE9518 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 199DB6F21C1FC61400CE9518 /* LaunchScreen.storyboard */; }; 17 | 199DB6FF1C1FC61400CE9518 /* VoiceRecordTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 199DB6FE1C1FC61400CE9518 /* VoiceRecordTests.m */; }; 18 | 199DB70A1C1FC61400CE9518 /* VoiceRecordUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 199DB7091C1FC61400CE9518 /* VoiceRecordUITests.m */; }; 19 | 199DB71C1C1FEA1200CE9518 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 199DB71B1C1FEA1200CE9518 /* AVFoundation.framework */; }; 20 | 19D1B8961C48A8CB0091B905 /* RecordManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 19D1B8951C48A8CB0091B905 /* RecordManager.m */; }; 21 | 19D1B8981C48C8150091B905 /* cf027d55-bdfd-48ae-bdcf-e9304ca934fc.amr in Resources */ = {isa = PBXBuildFile; fileRef = 19D1B8971C48C8150091B905 /* cf027d55-bdfd-48ae-bdcf-e9304ca934fc.amr */; }; 22 | 19D1B89B1C48D9820091B905 /* RecordVoice.m in Sources */ = {isa = PBXBuildFile; fileRef = 19D1B89A1C48D9820091B905 /* RecordVoice.m */; }; 23 | 19E8ED4E1C3146B700038723 /* amrFileCodec.m in Sources */ = {isa = PBXBuildFile; fileRef = 19E8ED411C3146B700038723 /* amrFileCodec.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 24 | 19E8ED4F1C3146B700038723 /* libopencore-amrnb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19E8ED4A1C3146B700038723 /* libopencore-amrnb.a */; }; 25 | 19E8ED501C3146B700038723 /* libopencore-amrwb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19E8ED4B1C3146B700038723 /* libopencore-amrwb.a */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXContainerItemProxy section */ 29 | 199DB6FB1C1FC61400CE9518 /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = 199DB6D91C1FC61400CE9518 /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = 199DB6E01C1FC61400CE9518; 34 | remoteInfo = VoiceRecord; 35 | }; 36 | 199DB7061C1FC61400CE9518 /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 199DB6D91C1FC61400CE9518 /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = 199DB6E01C1FC61400CE9518; 41 | remoteInfo = VoiceRecord; 42 | }; 43 | /* End PBXContainerItemProxy section */ 44 | 45 | /* Begin PBXFileReference section */ 46 | 191DF69F1C2CEB9800B896CB /* RecordButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecordButton.h; sourceTree = ""; }; 47 | 191DF6A01C2CEB9800B896CB /* RecordButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RecordButton.m; sourceTree = ""; }; 48 | 199DB6E11C1FC61400CE9518 /* VoiceRecord.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VoiceRecord.app; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 199DB6E51C1FC61400CE9518 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 50 | 199DB6E71C1FC61400CE9518 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 51 | 199DB6E81C1FC61400CE9518 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 52 | 199DB6EA1C1FC61400CE9518 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 53 | 199DB6EB1C1FC61400CE9518 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 54 | 199DB6EE1C1FC61400CE9518 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 55 | 199DB6F01C1FC61400CE9518 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 56 | 199DB6F31C1FC61400CE9518 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 57 | 199DB6F51C1FC61400CE9518 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | 199DB6FA1C1FC61400CE9518 /* VoiceRecordTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VoiceRecordTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 59 | 199DB6FE1C1FC61400CE9518 /* VoiceRecordTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VoiceRecordTests.m; sourceTree = ""; }; 60 | 199DB7001C1FC61400CE9518 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 61 | 199DB7051C1FC61400CE9518 /* VoiceRecordUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VoiceRecordUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 62 | 199DB7091C1FC61400CE9518 /* VoiceRecordUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VoiceRecordUITests.m; sourceTree = ""; }; 63 | 199DB70B1C1FC61400CE9518 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 64 | 199DB71B1C1FEA1200CE9518 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; 65 | 19D1B8941C48A8CB0091B905 /* RecordManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecordManager.h; sourceTree = ""; }; 66 | 19D1B8951C48A8CB0091B905 /* RecordManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RecordManager.m; sourceTree = ""; }; 67 | 19D1B8971C48C8150091B905 /* cf027d55-bdfd-48ae-bdcf-e9304ca934fc.amr */ = {isa = PBXFileReference; lastKnownFileType = file; path = "cf027d55-bdfd-48ae-bdcf-e9304ca934fc.amr"; sourceTree = ""; }; 68 | 19D1B8991C48D9820091B905 /* RecordVoice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecordVoice.h; sourceTree = ""; }; 69 | 19D1B89A1C48D9820091B905 /* RecordVoice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RecordVoice.m; sourceTree = ""; }; 70 | 19E8ED401C3146B700038723 /* amrFileCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = amrFileCodec.h; sourceTree = ""; }; 71 | 19E8ED411C3146B700038723 /* amrFileCodec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = amrFileCodec.m; sourceTree = ""; }; 72 | 19E8ED441C3146B700038723 /* interf_dec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = interf_dec.h; sourceTree = ""; }; 73 | 19E8ED451C3146B700038723 /* interf_enc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = interf_enc.h; sourceTree = ""; }; 74 | 19E8ED471C3146B700038723 /* dec_if.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dec_if.h; sourceTree = ""; }; 75 | 19E8ED481C3146B700038723 /* if_rom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = if_rom.h; sourceTree = ""; }; 76 | 19E8ED4A1C3146B700038723 /* libopencore-amrnb.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libopencore-amrnb.a"; sourceTree = ""; }; 77 | 19E8ED4B1C3146B700038723 /* libopencore-amrwb.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libopencore-amrwb.a"; sourceTree = ""; }; 78 | /* End PBXFileReference section */ 79 | 80 | /* Begin PBXFrameworksBuildPhase section */ 81 | 199DB6DE1C1FC61400CE9518 /* Frameworks */ = { 82 | isa = PBXFrameworksBuildPhase; 83 | buildActionMask = 2147483647; 84 | files = ( 85 | 199DB71C1C1FEA1200CE9518 /* AVFoundation.framework in Frameworks */, 86 | 19E8ED501C3146B700038723 /* libopencore-amrwb.a in Frameworks */, 87 | 19E8ED4F1C3146B700038723 /* libopencore-amrnb.a in Frameworks */, 88 | ); 89 | runOnlyForDeploymentPostprocessing = 0; 90 | }; 91 | 199DB6F71C1FC61400CE9518 /* Frameworks */ = { 92 | isa = PBXFrameworksBuildPhase; 93 | buildActionMask = 2147483647; 94 | files = ( 95 | ); 96 | runOnlyForDeploymentPostprocessing = 0; 97 | }; 98 | 199DB7021C1FC61400CE9518 /* Frameworks */ = { 99 | isa = PBXFrameworksBuildPhase; 100 | buildActionMask = 2147483647; 101 | files = ( 102 | ); 103 | runOnlyForDeploymentPostprocessing = 0; 104 | }; 105 | /* End PBXFrameworksBuildPhase section */ 106 | 107 | /* Begin PBXGroup section */ 108 | 199DB6D81C1FC61400CE9518 = { 109 | isa = PBXGroup; 110 | children = ( 111 | 199DB71B1C1FEA1200CE9518 /* AVFoundation.framework */, 112 | 199DB6E31C1FC61400CE9518 /* VoiceRecord */, 113 | 199DB6FD1C1FC61400CE9518 /* VoiceRecordTests */, 114 | 199DB7081C1FC61400CE9518 /* VoiceRecordUITests */, 115 | 199DB6E21C1FC61400CE9518 /* Products */, 116 | ); 117 | sourceTree = ""; 118 | }; 119 | 199DB6E21C1FC61400CE9518 /* Products */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 199DB6E11C1FC61400CE9518 /* VoiceRecord.app */, 123 | 199DB6FA1C1FC61400CE9518 /* VoiceRecordTests.xctest */, 124 | 199DB7051C1FC61400CE9518 /* VoiceRecordUITests.xctest */, 125 | ); 126 | name = Products; 127 | sourceTree = ""; 128 | }; 129 | 199DB6E31C1FC61400CE9518 /* VoiceRecord */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | 19D1B8971C48C8150091B905 /* cf027d55-bdfd-48ae-bdcf-e9304ca934fc.amr */, 133 | 19E8ED3F1C3146B700038723 /* arm */, 134 | 199DB6E71C1FC61400CE9518 /* AppDelegate.h */, 135 | 199DB6E81C1FC61400CE9518 /* AppDelegate.m */, 136 | 199DB6EA1C1FC61400CE9518 /* ViewController.h */, 137 | 199DB6EB1C1FC61400CE9518 /* ViewController.m */, 138 | 19D1B8941C48A8CB0091B905 /* RecordManager.h */, 139 | 19D1B8951C48A8CB0091B905 /* RecordManager.m */, 140 | 191DF69F1C2CEB9800B896CB /* RecordButton.h */, 141 | 191DF6A01C2CEB9800B896CB /* RecordButton.m */, 142 | 199DB6ED1C1FC61400CE9518 /* Main.storyboard */, 143 | 199DB6F01C1FC61400CE9518 /* Assets.xcassets */, 144 | 199DB6F21C1FC61400CE9518 /* LaunchScreen.storyboard */, 145 | 199DB6F51C1FC61400CE9518 /* Info.plist */, 146 | 199DB6E41C1FC61400CE9518 /* Supporting Files */, 147 | ); 148 | path = VoiceRecord; 149 | sourceTree = ""; 150 | }; 151 | 199DB6E41C1FC61400CE9518 /* Supporting Files */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | 199DB6E51C1FC61400CE9518 /* main.m */, 155 | ); 156 | name = "Supporting Files"; 157 | sourceTree = ""; 158 | }; 159 | 199DB6FD1C1FC61400CE9518 /* VoiceRecordTests */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | 199DB6FE1C1FC61400CE9518 /* VoiceRecordTests.m */, 163 | 199DB7001C1FC61400CE9518 /* Info.plist */, 164 | ); 165 | path = VoiceRecordTests; 166 | sourceTree = ""; 167 | }; 168 | 199DB7081C1FC61400CE9518 /* VoiceRecordUITests */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | 199DB7091C1FC61400CE9518 /* VoiceRecordUITests.m */, 172 | 199DB70B1C1FC61400CE9518 /* Info.plist */, 173 | ); 174 | path = VoiceRecordUITests; 175 | sourceTree = ""; 176 | }; 177 | 19E8ED3F1C3146B700038723 /* arm */ = { 178 | isa = PBXGroup; 179 | children = ( 180 | 19D1B8991C48D9820091B905 /* RecordVoice.h */, 181 | 19D1B89A1C48D9820091B905 /* RecordVoice.m */, 182 | 19E8ED401C3146B700038723 /* amrFileCodec.h */, 183 | 19E8ED411C3146B700038723 /* amrFileCodec.m */, 184 | 19E8ED421C3146B700038723 /* include */, 185 | 19E8ED491C3146B700038723 /* lib */, 186 | ); 187 | path = arm; 188 | sourceTree = ""; 189 | }; 190 | 19E8ED421C3146B700038723 /* include */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | 19E8ED431C3146B700038723 /* opencore-amrnb */, 194 | 19E8ED461C3146B700038723 /* opencore-amrwb */, 195 | ); 196 | path = include; 197 | sourceTree = ""; 198 | }; 199 | 19E8ED431C3146B700038723 /* opencore-amrnb */ = { 200 | isa = PBXGroup; 201 | children = ( 202 | 19E8ED441C3146B700038723 /* interf_dec.h */, 203 | 19E8ED451C3146B700038723 /* interf_enc.h */, 204 | ); 205 | path = "opencore-amrnb"; 206 | sourceTree = ""; 207 | }; 208 | 19E8ED461C3146B700038723 /* opencore-amrwb */ = { 209 | isa = PBXGroup; 210 | children = ( 211 | 19E8ED471C3146B700038723 /* dec_if.h */, 212 | 19E8ED481C3146B700038723 /* if_rom.h */, 213 | ); 214 | path = "opencore-amrwb"; 215 | sourceTree = ""; 216 | }; 217 | 19E8ED491C3146B700038723 /* lib */ = { 218 | isa = PBXGroup; 219 | children = ( 220 | 19E8ED4A1C3146B700038723 /* libopencore-amrnb.a */, 221 | 19E8ED4B1C3146B700038723 /* libopencore-amrwb.a */, 222 | ); 223 | path = lib; 224 | sourceTree = ""; 225 | }; 226 | /* End PBXGroup section */ 227 | 228 | /* Begin PBXNativeTarget section */ 229 | 199DB6E01C1FC61400CE9518 /* VoiceRecord */ = { 230 | isa = PBXNativeTarget; 231 | buildConfigurationList = 199DB70E1C1FC61400CE9518 /* Build configuration list for PBXNativeTarget "VoiceRecord" */; 232 | buildPhases = ( 233 | 199DB6DD1C1FC61400CE9518 /* Sources */, 234 | 199DB6DE1C1FC61400CE9518 /* Frameworks */, 235 | 199DB6DF1C1FC61400CE9518 /* Resources */, 236 | ); 237 | buildRules = ( 238 | ); 239 | dependencies = ( 240 | ); 241 | name = VoiceRecord; 242 | productName = VoiceRecord; 243 | productReference = 199DB6E11C1FC61400CE9518 /* VoiceRecord.app */; 244 | productType = "com.apple.product-type.application"; 245 | }; 246 | 199DB6F91C1FC61400CE9518 /* VoiceRecordTests */ = { 247 | isa = PBXNativeTarget; 248 | buildConfigurationList = 199DB7111C1FC61400CE9518 /* Build configuration list for PBXNativeTarget "VoiceRecordTests" */; 249 | buildPhases = ( 250 | 199DB6F61C1FC61400CE9518 /* Sources */, 251 | 199DB6F71C1FC61400CE9518 /* Frameworks */, 252 | 199DB6F81C1FC61400CE9518 /* Resources */, 253 | ); 254 | buildRules = ( 255 | ); 256 | dependencies = ( 257 | 199DB6FC1C1FC61400CE9518 /* PBXTargetDependency */, 258 | ); 259 | name = VoiceRecordTests; 260 | productName = VoiceRecordTests; 261 | productReference = 199DB6FA1C1FC61400CE9518 /* VoiceRecordTests.xctest */; 262 | productType = "com.apple.product-type.bundle.unit-test"; 263 | }; 264 | 199DB7041C1FC61400CE9518 /* VoiceRecordUITests */ = { 265 | isa = PBXNativeTarget; 266 | buildConfigurationList = 199DB7141C1FC61400CE9518 /* Build configuration list for PBXNativeTarget "VoiceRecordUITests" */; 267 | buildPhases = ( 268 | 199DB7011C1FC61400CE9518 /* Sources */, 269 | 199DB7021C1FC61400CE9518 /* Frameworks */, 270 | 199DB7031C1FC61400CE9518 /* Resources */, 271 | ); 272 | buildRules = ( 273 | ); 274 | dependencies = ( 275 | 199DB7071C1FC61400CE9518 /* PBXTargetDependency */, 276 | ); 277 | name = VoiceRecordUITests; 278 | productName = VoiceRecordUITests; 279 | productReference = 199DB7051C1FC61400CE9518 /* VoiceRecordUITests.xctest */; 280 | productType = "com.apple.product-type.bundle.ui-testing"; 281 | }; 282 | /* End PBXNativeTarget section */ 283 | 284 | /* Begin PBXProject section */ 285 | 199DB6D91C1FC61400CE9518 /* Project object */ = { 286 | isa = PBXProject; 287 | attributes = { 288 | LastUpgradeCheck = 0720; 289 | ORGANIZATIONNAME = Grey; 290 | TargetAttributes = { 291 | 199DB6E01C1FC61400CE9518 = { 292 | CreatedOnToolsVersion = 7.2; 293 | }; 294 | 199DB6F91C1FC61400CE9518 = { 295 | CreatedOnToolsVersion = 7.2; 296 | TestTargetID = 199DB6E01C1FC61400CE9518; 297 | }; 298 | 199DB7041C1FC61400CE9518 = { 299 | CreatedOnToolsVersion = 7.2; 300 | TestTargetID = 199DB6E01C1FC61400CE9518; 301 | }; 302 | }; 303 | }; 304 | buildConfigurationList = 199DB6DC1C1FC61400CE9518 /* Build configuration list for PBXProject "VoiceRecord" */; 305 | compatibilityVersion = "Xcode 3.2"; 306 | developmentRegion = English; 307 | hasScannedForEncodings = 0; 308 | knownRegions = ( 309 | en, 310 | Base, 311 | ); 312 | mainGroup = 199DB6D81C1FC61400CE9518; 313 | productRefGroup = 199DB6E21C1FC61400CE9518 /* Products */; 314 | projectDirPath = ""; 315 | projectRoot = ""; 316 | targets = ( 317 | 199DB6E01C1FC61400CE9518 /* VoiceRecord */, 318 | 199DB6F91C1FC61400CE9518 /* VoiceRecordTests */, 319 | 199DB7041C1FC61400CE9518 /* VoiceRecordUITests */, 320 | ); 321 | }; 322 | /* End PBXProject section */ 323 | 324 | /* Begin PBXResourcesBuildPhase section */ 325 | 199DB6DF1C1FC61400CE9518 /* Resources */ = { 326 | isa = PBXResourcesBuildPhase; 327 | buildActionMask = 2147483647; 328 | files = ( 329 | 199DB6F41C1FC61400CE9518 /* LaunchScreen.storyboard in Resources */, 330 | 19D1B8981C48C8150091B905 /* cf027d55-bdfd-48ae-bdcf-e9304ca934fc.amr in Resources */, 331 | 199DB6F11C1FC61400CE9518 /* Assets.xcassets in Resources */, 332 | 199DB6EF1C1FC61400CE9518 /* Main.storyboard in Resources */, 333 | ); 334 | runOnlyForDeploymentPostprocessing = 0; 335 | }; 336 | 199DB6F81C1FC61400CE9518 /* Resources */ = { 337 | isa = PBXResourcesBuildPhase; 338 | buildActionMask = 2147483647; 339 | files = ( 340 | ); 341 | runOnlyForDeploymentPostprocessing = 0; 342 | }; 343 | 199DB7031C1FC61400CE9518 /* Resources */ = { 344 | isa = PBXResourcesBuildPhase; 345 | buildActionMask = 2147483647; 346 | files = ( 347 | ); 348 | runOnlyForDeploymentPostprocessing = 0; 349 | }; 350 | /* End PBXResourcesBuildPhase section */ 351 | 352 | /* Begin PBXSourcesBuildPhase section */ 353 | 199DB6DD1C1FC61400CE9518 /* Sources */ = { 354 | isa = PBXSourcesBuildPhase; 355 | buildActionMask = 2147483647; 356 | files = ( 357 | 19D1B8961C48A8CB0091B905 /* RecordManager.m in Sources */, 358 | 19D1B89B1C48D9820091B905 /* RecordVoice.m in Sources */, 359 | 191DF6A11C2CEB9800B896CB /* RecordButton.m in Sources */, 360 | 199DB6EC1C1FC61400CE9518 /* ViewController.m in Sources */, 361 | 199DB6E91C1FC61400CE9518 /* AppDelegate.m in Sources */, 362 | 199DB6E61C1FC61400CE9518 /* main.m in Sources */, 363 | 19E8ED4E1C3146B700038723 /* amrFileCodec.m in Sources */, 364 | ); 365 | runOnlyForDeploymentPostprocessing = 0; 366 | }; 367 | 199DB6F61C1FC61400CE9518 /* Sources */ = { 368 | isa = PBXSourcesBuildPhase; 369 | buildActionMask = 2147483647; 370 | files = ( 371 | 199DB6FF1C1FC61400CE9518 /* VoiceRecordTests.m in Sources */, 372 | ); 373 | runOnlyForDeploymentPostprocessing = 0; 374 | }; 375 | 199DB7011C1FC61400CE9518 /* Sources */ = { 376 | isa = PBXSourcesBuildPhase; 377 | buildActionMask = 2147483647; 378 | files = ( 379 | 199DB70A1C1FC61400CE9518 /* VoiceRecordUITests.m in Sources */, 380 | ); 381 | runOnlyForDeploymentPostprocessing = 0; 382 | }; 383 | /* End PBXSourcesBuildPhase section */ 384 | 385 | /* Begin PBXTargetDependency section */ 386 | 199DB6FC1C1FC61400CE9518 /* PBXTargetDependency */ = { 387 | isa = PBXTargetDependency; 388 | target = 199DB6E01C1FC61400CE9518 /* VoiceRecord */; 389 | targetProxy = 199DB6FB1C1FC61400CE9518 /* PBXContainerItemProxy */; 390 | }; 391 | 199DB7071C1FC61400CE9518 /* PBXTargetDependency */ = { 392 | isa = PBXTargetDependency; 393 | target = 199DB6E01C1FC61400CE9518 /* VoiceRecord */; 394 | targetProxy = 199DB7061C1FC61400CE9518 /* PBXContainerItemProxy */; 395 | }; 396 | /* End PBXTargetDependency section */ 397 | 398 | /* Begin PBXVariantGroup section */ 399 | 199DB6ED1C1FC61400CE9518 /* Main.storyboard */ = { 400 | isa = PBXVariantGroup; 401 | children = ( 402 | 199DB6EE1C1FC61400CE9518 /* Base */, 403 | ); 404 | name = Main.storyboard; 405 | sourceTree = ""; 406 | }; 407 | 199DB6F21C1FC61400CE9518 /* LaunchScreen.storyboard */ = { 408 | isa = PBXVariantGroup; 409 | children = ( 410 | 199DB6F31C1FC61400CE9518 /* Base */, 411 | ); 412 | name = LaunchScreen.storyboard; 413 | sourceTree = ""; 414 | }; 415 | /* End PBXVariantGroup section */ 416 | 417 | /* Begin XCBuildConfiguration section */ 418 | 199DB70C1C1FC61400CE9518 /* Debug */ = { 419 | isa = XCBuildConfiguration; 420 | buildSettings = { 421 | ALWAYS_SEARCH_USER_PATHS = NO; 422 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 423 | CLANG_CXX_LIBRARY = "libc++"; 424 | CLANG_ENABLE_MODULES = YES; 425 | CLANG_ENABLE_OBJC_ARC = YES; 426 | CLANG_WARN_BOOL_CONVERSION = YES; 427 | CLANG_WARN_CONSTANT_CONVERSION = YES; 428 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 429 | CLANG_WARN_EMPTY_BODY = YES; 430 | CLANG_WARN_ENUM_CONVERSION = YES; 431 | CLANG_WARN_INT_CONVERSION = YES; 432 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 433 | CLANG_WARN_UNREACHABLE_CODE = YES; 434 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 435 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 436 | COPY_PHASE_STRIP = NO; 437 | DEBUG_INFORMATION_FORMAT = dwarf; 438 | ENABLE_STRICT_OBJC_MSGSEND = YES; 439 | ENABLE_TESTABILITY = YES; 440 | GCC_C_LANGUAGE_STANDARD = gnu99; 441 | GCC_DYNAMIC_NO_PIC = NO; 442 | GCC_NO_COMMON_BLOCKS = YES; 443 | GCC_OPTIMIZATION_LEVEL = 0; 444 | GCC_PREPROCESSOR_DEFINITIONS = ( 445 | "DEBUG=1", 446 | "$(inherited)", 447 | ); 448 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 449 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 450 | GCC_WARN_UNDECLARED_SELECTOR = YES; 451 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 452 | GCC_WARN_UNUSED_FUNCTION = YES; 453 | GCC_WARN_UNUSED_VARIABLE = YES; 454 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 455 | MTL_ENABLE_DEBUG_INFO = YES; 456 | ONLY_ACTIVE_ARCH = YES; 457 | SDKROOT = iphoneos; 458 | }; 459 | name = Debug; 460 | }; 461 | 199DB70D1C1FC61400CE9518 /* Release */ = { 462 | isa = XCBuildConfiguration; 463 | buildSettings = { 464 | ALWAYS_SEARCH_USER_PATHS = NO; 465 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 466 | CLANG_CXX_LIBRARY = "libc++"; 467 | CLANG_ENABLE_MODULES = YES; 468 | CLANG_ENABLE_OBJC_ARC = YES; 469 | CLANG_WARN_BOOL_CONVERSION = YES; 470 | CLANG_WARN_CONSTANT_CONVERSION = YES; 471 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 472 | CLANG_WARN_EMPTY_BODY = YES; 473 | CLANG_WARN_ENUM_CONVERSION = YES; 474 | CLANG_WARN_INT_CONVERSION = YES; 475 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 476 | CLANG_WARN_UNREACHABLE_CODE = YES; 477 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 478 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 479 | COPY_PHASE_STRIP = NO; 480 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 481 | ENABLE_NS_ASSERTIONS = NO; 482 | ENABLE_STRICT_OBJC_MSGSEND = YES; 483 | GCC_C_LANGUAGE_STANDARD = gnu99; 484 | GCC_NO_COMMON_BLOCKS = YES; 485 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 486 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 487 | GCC_WARN_UNDECLARED_SELECTOR = YES; 488 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 489 | GCC_WARN_UNUSED_FUNCTION = YES; 490 | GCC_WARN_UNUSED_VARIABLE = YES; 491 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 492 | MTL_ENABLE_DEBUG_INFO = NO; 493 | SDKROOT = iphoneos; 494 | VALIDATE_PRODUCT = YES; 495 | }; 496 | name = Release; 497 | }; 498 | 199DB70F1C1FC61400CE9518 /* Debug */ = { 499 | isa = XCBuildConfiguration; 500 | buildSettings = { 501 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 502 | ENABLE_BITCODE = NO; 503 | INFOPLIST_FILE = VoiceRecord/Info.plist; 504 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 505 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 506 | LIBRARY_SEARCH_PATHS = ( 507 | "$(inherited)", 508 | "$(PROJECT_DIR)/VoiceRecord/arm/lib", 509 | ); 510 | PRODUCT_BUNDLE_IDENTIFIER = haojia.nethospital.VoiceRecord; 511 | PRODUCT_NAME = "$(TARGET_NAME)"; 512 | }; 513 | name = Debug; 514 | }; 515 | 199DB7101C1FC61400CE9518 /* Release */ = { 516 | isa = XCBuildConfiguration; 517 | buildSettings = { 518 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 519 | ENABLE_BITCODE = NO; 520 | INFOPLIST_FILE = VoiceRecord/Info.plist; 521 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 522 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 523 | LIBRARY_SEARCH_PATHS = ( 524 | "$(inherited)", 525 | "$(PROJECT_DIR)/VoiceRecord/arm/lib", 526 | ); 527 | PRODUCT_BUNDLE_IDENTIFIER = haojia.nethospital.VoiceRecord; 528 | PRODUCT_NAME = "$(TARGET_NAME)"; 529 | }; 530 | name = Release; 531 | }; 532 | 199DB7121C1FC61400CE9518 /* Debug */ = { 533 | isa = XCBuildConfiguration; 534 | buildSettings = { 535 | BUNDLE_LOADER = "$(TEST_HOST)"; 536 | INFOPLIST_FILE = VoiceRecordTests/Info.plist; 537 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 538 | PRODUCT_BUNDLE_IDENTIFIER = haojia.nethospital.VoiceRecordTests; 539 | PRODUCT_NAME = "$(TARGET_NAME)"; 540 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VoiceRecord.app/VoiceRecord"; 541 | }; 542 | name = Debug; 543 | }; 544 | 199DB7131C1FC61400CE9518 /* Release */ = { 545 | isa = XCBuildConfiguration; 546 | buildSettings = { 547 | BUNDLE_LOADER = "$(TEST_HOST)"; 548 | INFOPLIST_FILE = VoiceRecordTests/Info.plist; 549 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 550 | PRODUCT_BUNDLE_IDENTIFIER = haojia.nethospital.VoiceRecordTests; 551 | PRODUCT_NAME = "$(TARGET_NAME)"; 552 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VoiceRecord.app/VoiceRecord"; 553 | }; 554 | name = Release; 555 | }; 556 | 199DB7151C1FC61400CE9518 /* Debug */ = { 557 | isa = XCBuildConfiguration; 558 | buildSettings = { 559 | INFOPLIST_FILE = VoiceRecordUITests/Info.plist; 560 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 561 | PRODUCT_BUNDLE_IDENTIFIER = haojia.nethospital.VoiceRecordUITests; 562 | PRODUCT_NAME = "$(TARGET_NAME)"; 563 | TEST_TARGET_NAME = VoiceRecord; 564 | USES_XCTRUNNER = YES; 565 | }; 566 | name = Debug; 567 | }; 568 | 199DB7161C1FC61400CE9518 /* Release */ = { 569 | isa = XCBuildConfiguration; 570 | buildSettings = { 571 | INFOPLIST_FILE = VoiceRecordUITests/Info.plist; 572 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 573 | PRODUCT_BUNDLE_IDENTIFIER = haojia.nethospital.VoiceRecordUITests; 574 | PRODUCT_NAME = "$(TARGET_NAME)"; 575 | TEST_TARGET_NAME = VoiceRecord; 576 | USES_XCTRUNNER = YES; 577 | }; 578 | name = Release; 579 | }; 580 | /* End XCBuildConfiguration section */ 581 | 582 | /* Begin XCConfigurationList section */ 583 | 199DB6DC1C1FC61400CE9518 /* Build configuration list for PBXProject "VoiceRecord" */ = { 584 | isa = XCConfigurationList; 585 | buildConfigurations = ( 586 | 199DB70C1C1FC61400CE9518 /* Debug */, 587 | 199DB70D1C1FC61400CE9518 /* Release */, 588 | ); 589 | defaultConfigurationIsVisible = 0; 590 | defaultConfigurationName = Release; 591 | }; 592 | 199DB70E1C1FC61400CE9518 /* Build configuration list for PBXNativeTarget "VoiceRecord" */ = { 593 | isa = XCConfigurationList; 594 | buildConfigurations = ( 595 | 199DB70F1C1FC61400CE9518 /* Debug */, 596 | 199DB7101C1FC61400CE9518 /* Release */, 597 | ); 598 | defaultConfigurationIsVisible = 0; 599 | defaultConfigurationName = Release; 600 | }; 601 | 199DB7111C1FC61400CE9518 /* Build configuration list for PBXNativeTarget "VoiceRecordTests" */ = { 602 | isa = XCConfigurationList; 603 | buildConfigurations = ( 604 | 199DB7121C1FC61400CE9518 /* Debug */, 605 | 199DB7131C1FC61400CE9518 /* Release */, 606 | ); 607 | defaultConfigurationIsVisible = 0; 608 | defaultConfigurationName = Release; 609 | }; 610 | 199DB7141C1FC61400CE9518 /* Build configuration list for PBXNativeTarget "VoiceRecordUITests" */ = { 611 | isa = XCConfigurationList; 612 | buildConfigurations = ( 613 | 199DB7151C1FC61400CE9518 /* Debug */, 614 | 199DB7161C1FC61400CE9518 /* Release */, 615 | ); 616 | defaultConfigurationIsVisible = 0; 617 | defaultConfigurationName = Release; 618 | }; 619 | /* End XCConfigurationList section */ 620 | }; 621 | rootObject = 199DB6D91C1FC61400CE9518 /* Project object */; 622 | } 623 | --------------------------------------------------------------------------------