├── LGAudioKit ├── Assets.xcassets │ ├── Contents.json │ ├── headImage.imageset │ │ ├── h00032@2x.png │ │ └── Contents.json │ ├── bg_chat_me.imageset │ │ ├── bg_chat_me@2x.png │ │ └── Contents.json │ ├── icon_voice_sender_1.imageset │ │ ├── icon_voice_sender_1@2x.png │ │ └── Contents.json │ ├── icon_voice_sender_2.imageset │ │ ├── icon_voice_sender_2@2x.png │ │ └── Contents.json │ ├── icon_voice_sender_3.imageset │ │ ├── icon_voice_sender_3@2x.png │ │ └── Contents.json │ ├── btn_chatbar_press_normal.imageset │ │ ├── btn_chatbar_press_normal@2x.png │ │ └── Contents.json │ ├── btn_chatbar_press_selected.imageset │ │ ├── btn_chatbar_press_selected@2x.png │ │ └── Contents.json │ └── AppIcon.appiconset │ │ └── Contents.json ├── Class │ ├── Resource │ │ ├── toast_vol_1@2x.png │ │ ├── toast_vol_2@2x.png │ │ ├── toast_vol_3@2x.png │ │ ├── toast_vol_4@2x.png │ │ ├── toast_vol_5@2x.png │ │ ├── toast_vol_6@2x.png │ │ ├── toast_vol_7@2x.png │ │ ├── toast_cancelsend@2x.png │ │ ├── toast_microphone@2x.png │ │ └── toast_timeshort@2x.png │ ├── Vendor │ │ └── AMR │ │ │ ├── lib │ │ │ ├── libopencore-amrnb.a │ │ │ └── libopencore-amrwb.a │ │ │ ├── include │ │ │ ├── opencore-amrwb │ │ │ │ ├── if_rom.h │ │ │ │ └── dec_if.h │ │ │ └── opencore-amrnb │ │ │ │ ├── interf_dec.h │ │ │ │ └── interf_enc.h │ │ │ ├── amrFileCodec.h │ │ │ └── amrFileCodec.m │ ├── LGAudioKit.h │ ├── LGSoundPlayer │ │ ├── LGAudioPlayer.h │ │ └── LGAudioPlayer.m │ └── LGSoundRecorder │ │ ├── LGSoundRecorder.h │ │ └── LGSoundRecorder.m ├── Demo │ ├── Masonry │ │ ├── MASLayoutConstraint.m │ │ ├── NSLayoutConstraint+MASDebugAdditions.h │ │ ├── MASLayoutConstraint.h │ │ ├── MASCompositeConstraint.h │ │ ├── Masonry.h │ │ ├── ViewController+MASAdditions.h │ │ ├── NSArray+MASShorthandAdditions.h │ │ ├── MASViewAttribute.m │ │ ├── MASViewAttribute.h │ │ ├── ViewController+MASAdditions.m │ │ ├── MASViewConstraint.h │ │ ├── MASConstraint+Private.h │ │ ├── NSArray+MASAdditions.h │ │ ├── View+MASShorthandAdditions.h │ │ ├── View+MASAdditions.h │ │ ├── MASCompositeConstraint.m │ │ ├── MASConstraintMaker.h │ │ ├── View+MASAdditions.m │ │ ├── NSLayoutConstraint+MASDebugAdditions.m │ │ ├── MASUtilities.h │ │ ├── NSArray+MASAdditions.m │ │ ├── MASConstraint.h │ │ ├── MASConstraint.m │ │ ├── MASConstraintMaker.m │ │ └── MASViewConstraint.m │ ├── LGMessageModel.m │ ├── LGCellContentView.h │ ├── ViewController.h │ ├── LGMessageModel.h │ ├── LGCellContentView.m │ ├── LGTableViewCell.h │ ├── LGTableViewCell.m │ └── ViewController.m ├── AppDelegate.h ├── main.m ├── Base.lproj │ ├── Main.storyboard │ └── LaunchScreen.storyboard ├── Info.plist └── AppDelegate.m ├── LGAudioKit.xcodeproj ├── xcuserdata │ └── ligang.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ └── LGAudioKit.xcscheme └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ └── ligang.xcuserdatad │ └── UserInterfaceState.xcuserstate ├── LICENSE └── README.md /LGAudioKit/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /LGAudioKit/Class/Resource/toast_vol_1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Class/Resource/toast_vol_1@2x.png -------------------------------------------------------------------------------- /LGAudioKit/Class/Resource/toast_vol_2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Class/Resource/toast_vol_2@2x.png -------------------------------------------------------------------------------- /LGAudioKit/Class/Resource/toast_vol_3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Class/Resource/toast_vol_3@2x.png -------------------------------------------------------------------------------- /LGAudioKit/Class/Resource/toast_vol_4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Class/Resource/toast_vol_4@2x.png -------------------------------------------------------------------------------- /LGAudioKit/Class/Resource/toast_vol_5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Class/Resource/toast_vol_5@2x.png -------------------------------------------------------------------------------- /LGAudioKit/Class/Resource/toast_vol_6@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Class/Resource/toast_vol_6@2x.png -------------------------------------------------------------------------------- /LGAudioKit/Class/Resource/toast_vol_7@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Class/Resource/toast_vol_7@2x.png -------------------------------------------------------------------------------- /LGAudioKit/Class/Resource/toast_cancelsend@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Class/Resource/toast_cancelsend@2x.png -------------------------------------------------------------------------------- /LGAudioKit/Class/Resource/toast_microphone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Class/Resource/toast_microphone@2x.png -------------------------------------------------------------------------------- /LGAudioKit/Class/Resource/toast_timeshort@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Class/Resource/toast_timeshort@2x.png -------------------------------------------------------------------------------- /LGAudioKit/Class/Vendor/AMR/lib/libopencore-amrnb.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Class/Vendor/AMR/lib/libopencore-amrnb.a -------------------------------------------------------------------------------- /LGAudioKit/Class/Vendor/AMR/lib/libopencore-amrwb.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Class/Vendor/AMR/lib/libopencore-amrwb.a -------------------------------------------------------------------------------- /LGAudioKit/Assets.xcassets/headImage.imageset/h00032@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Assets.xcassets/headImage.imageset/h00032@2x.png -------------------------------------------------------------------------------- /LGAudioKit/Assets.xcassets/bg_chat_me.imageset/bg_chat_me@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Assets.xcassets/bg_chat_me.imageset/bg_chat_me@2x.png -------------------------------------------------------------------------------- /LGAudioKit.xcodeproj/xcuserdata/ligang.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /LGAudioKit/Assets.xcassets/icon_voice_sender_1.imageset/icon_voice_sender_1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Assets.xcassets/icon_voice_sender_1.imageset/icon_voice_sender_1@2x.png -------------------------------------------------------------------------------- /LGAudioKit/Assets.xcassets/icon_voice_sender_2.imageset/icon_voice_sender_2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Assets.xcassets/icon_voice_sender_2.imageset/icon_voice_sender_2@2x.png -------------------------------------------------------------------------------- /LGAudioKit/Assets.xcassets/icon_voice_sender_3.imageset/icon_voice_sender_3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Assets.xcassets/icon_voice_sender_3.imageset/icon_voice_sender_3@2x.png -------------------------------------------------------------------------------- /LGAudioKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LGAudioKit/Assets.xcassets/btn_chatbar_press_normal.imageset/btn_chatbar_press_normal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Assets.xcassets/btn_chatbar_press_normal.imageset/btn_chatbar_press_normal@2x.png -------------------------------------------------------------------------------- /LGAudioKit/Assets.xcassets/btn_chatbar_press_selected.imageset/btn_chatbar_press_selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit/Assets.xcassets/btn_chatbar_press_selected.imageset/btn_chatbar_press_selected@2x.png -------------------------------------------------------------------------------- /LGAudioKit.xcodeproj/project.xcworkspace/xcuserdata/ligang.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gang544043963/LGAudioKit/HEAD/LGAudioKit.xcodeproj/project.xcworkspace/xcuserdata/ligang.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/MASLayoutConstraint.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASLayoutConstraint.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "MASLayoutConstraint.h" 10 | 11 | @implementation MASLayoutConstraint 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/LGMessageModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // LGMessageModel.m 3 | // 下载地址:https://github.com/gang544043963/LGAudioKit 4 | // 5 | // Created by ligang on 16/8/20. 6 | // Copyright © 2016年 LG. All rights reserved. 7 | // 8 | 9 | #import "LGMessageModel.h" 10 | 11 | @implementation LGMessageModel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/LGCellContentView.h: -------------------------------------------------------------------------------- 1 | // 2 | // LGCellContentView.h 3 | // 下载地址:https://github.com/gang544043963/LGAudioKit 4 | // 5 | // Created by ligang on 16/8/20. 6 | // Copyright © 2016年 LG. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LGCellContentView : UIView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // 下载地址:https://github.com/gang544043963/LGAudioKit 4 | // 5 | // Created by ligang on 16/8/20. 6 | // Copyright © 2016年 LG. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /LGAudioKit/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // LGAudioKit 4 | // 5 | // Created by ligang on 16/8/20. 6 | // Copyright © 2016年 LG. 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 | -------------------------------------------------------------------------------- /LGAudioKit/Class/LGAudioKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // LGAudioKit.h 3 | // 下载地址:https://github.com/gang544043963/LGAudioKit 4 | // 5 | // Created by ligang on 16/8/20. 6 | // Copyright © 2016年 LG. All rights reserved. 7 | // 8 | 9 | #ifndef LGAudioKit_h 10 | #define LGAudioKit_h 11 | 12 | #import "LGSoundRecorder.h" 13 | #import "LGAudioPlayer.h" 14 | 15 | 16 | #endif /* LGAudioKit_h */ 17 | -------------------------------------------------------------------------------- /LGAudioKit/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // LGAudioKit 4 | // 5 | // Created by ligang on 16/8/20. 6 | // Copyright © 2016年 LG. 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 | -------------------------------------------------------------------------------- /LGAudioKit/Assets.xcassets/headImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "h00032@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /LGAudioKit/Assets.xcassets/bg_chat_me.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "bg_chat_me@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/NSLayoutConstraint+MASDebugAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSLayoutConstraint+MASDebugAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | 11 | /** 12 | * makes debug and log output of NSLayoutConstraints more readable 13 | */ 14 | @interface NSLayoutConstraint (MASDebugAdditions) 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/LGMessageModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // LGMessageModel.h 3 | // 下载地址:https://github.com/gang544043963/LGAudioKit 4 | // 5 | // Created by ligang on 16/8/20. 6 | // Copyright © 2016年 LG. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LGMessageModel : NSObject 12 | 13 | @property (nonatomic, copy) NSString *soundFilePath; 14 | @property (nonatomic, assign) NSTimeInterval seconds; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /LGAudioKit/Assets.xcassets/icon_voice_sender_1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "icon_voice_sender_1@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /LGAudioKit/Assets.xcassets/icon_voice_sender_2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "icon_voice_sender_2@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /LGAudioKit/Assets.xcassets/icon_voice_sender_3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "icon_voice_sender_3@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /LGAudioKit/Assets.xcassets/btn_chatbar_press_normal.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "btn_chatbar_press_normal@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /LGAudioKit/Assets.xcassets/btn_chatbar_press_selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "btn_chatbar_press_selected@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/MASLayoutConstraint.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASLayoutConstraint.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | 11 | /** 12 | * When you are debugging or printing the constraints attached to a view this subclass 13 | * makes it easier to identify which constraints have been created via Masonry 14 | */ 15 | @interface MASLayoutConstraint : NSLayoutConstraint 16 | 17 | /** 18 | * a key to associate with this constraint 19 | */ 20 | @property (nonatomic, strong) id mas_key; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/MASCompositeConstraint.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASCompositeConstraint.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASConstraint.h" 10 | #import "MASUtilities.h" 11 | 12 | /** 13 | * A group of MASConstraint objects 14 | */ 15 | @interface MASCompositeConstraint : MASConstraint 16 | 17 | /** 18 | * Creates a composite with a predefined array of children 19 | * 20 | * @param children child MASConstraints 21 | * 22 | * @return a composite constraint 23 | */ 24 | - (id)initWithChildren:(NSArray *)children; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /LGAudioKit.xcodeproj/xcuserdata/ligang.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | LGAudioKit.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | CEAB58EC1D6800D10026048C 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/LGCellContentView.m: -------------------------------------------------------------------------------- 1 | // 2 | // LGCellContentView.m 3 | // 下载地址:https://github.com/gang544043963/LGAudioKit 4 | // 5 | // Created by ligang on 16/8/20. 6 | // Copyright © 2016年 LG. All rights reserved. 7 | // 8 | 9 | #import "LGCellContentView.h" 10 | 11 | @implementation LGCellContentView 12 | 13 | - (instancetype)init { 14 | if ([super init]) { 15 | CAShapeLayer *maskLayer = [CAShapeLayer layer]; 16 | maskLayer.contentsCenter = CGRectMake(.5f, .7f, .1f, .1f); 17 | //2X图,contentsScale设为2 18 | maskLayer.contentsScale = 2; 19 | self.layer.mask = maskLayer; 20 | } 21 | return self; 22 | } 23 | - (void)layoutSublayersOfLayer:(CALayer *)layer { 24 | [super layoutSublayersOfLayer:layer]; 25 | self.layer.mask.frame = CGRectInset(self.bounds, 0, 0); 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/Masonry.h: -------------------------------------------------------------------------------- 1 | // 2 | // Masonry.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Masonry. 12 | FOUNDATION_EXPORT double MasonryVersionNumber; 13 | 14 | //! Project version string for Masonry. 15 | FOUNDATION_EXPORT const unsigned char MasonryVersionString[]; 16 | 17 | #import "MASUtilities.h" 18 | #import "View+MASAdditions.h" 19 | #import "View+MASShorthandAdditions.h" 20 | #import "ViewController+MASAdditions.h" 21 | #import "NSArray+MASAdditions.h" 22 | #import "NSArray+MASShorthandAdditions.h" 23 | #import "MASConstraint.h" 24 | #import "MASCompositeConstraint.h" 25 | #import "MASViewAttribute.h" 26 | #import "MASViewConstraint.h" 27 | #import "MASConstraintMaker.h" 28 | #import "MASLayoutConstraint.h" 29 | #import "NSLayoutConstraint+MASDebugAdditions.h" 30 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/LGTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // LGTableViewCell.h 3 | // 下载地址:https://github.com/gang544043963/LGAudioKit 4 | // 5 | // Created by ligang on 16/8/20. 6 | // Copyright © 2016年 LG. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "LGMessageModel.h" 11 | 12 | typedef NS_ENUM(NSUInteger, LGVoicePlayState){ 13 | LGVoicePlayStateNormal,/**< 未播放状态 */ 14 | LGVoicePlayStateDownloading,/**< 正在下载中 */ 15 | LGVoicePlayStatePlaying,/**< 正在播放 */ 16 | LGVoicePlayStateCancel,/**< 播放被取消 */ 17 | }; 18 | 19 | @class LGTableViewCell; 20 | @protocol LGTableViewCellDelegate 21 | 22 | - (void)voiceMessageTaped:(LGTableViewCell *)cell; 23 | 24 | @end 25 | 26 | @interface LGTableViewCell : UITableViewCell 27 | 28 | @property (nonatomic, assign) NSInteger soundSeconds; 29 | @property (nonatomic, assign) LGVoicePlayState voicePlayState; 30 | @property (nonatomic, weak) iddelegate; 31 | 32 | - (void)configureCellWithData:(LGMessageModel *)messageModel; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/ViewController+MASAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+MASAdditions.h 3 | // Masonry 4 | // 5 | // Created by Craig Siemens on 2015-06-23. 6 | // 7 | // 8 | 9 | #import "MASUtilities.h" 10 | #import "MASConstraintMaker.h" 11 | #import "MASViewAttribute.h" 12 | 13 | #ifdef MAS_VIEW_CONTROLLER 14 | 15 | @interface MAS_VIEW_CONTROLLER (MASAdditions) 16 | 17 | /** 18 | * following properties return a new MASViewAttribute with appropriate UILayoutGuide and NSLayoutAttribute 19 | */ 20 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuide; 21 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuide; 22 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideTop; 23 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideBottom; 24 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideTop; 25 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideBottom; 26 | 27 | 28 | @end 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /LGAudioKit/Class/Vendor/AMR/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 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 李刚 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LGAudioKit/Class/LGSoundPlayer/LGAudioPlayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // LGAudioPlayer.h 3 | // 下载地址:https://github.com/gang544043963/LGAudioKit 4 | // 5 | // Created by ligang on 16/8/20. 6 | // Copyright © 2016年 LG. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, LGAudioPlayerState){ 12 | LGAudioPlayerStateNormal = 0,/** 未播放状态 */ 13 | LGAudioPlayerStatePlaying = 2,/** 正在播放 */ 14 | LGAudioPlayerStateCancel = 3,/** 播放被取消 */ 15 | }; 16 | 17 | @protocol LGAudioPlayerDelegate 18 | 19 | - (void)audioPlayerStateDidChanged:(LGAudioPlayerState)audioPlayerState forIndex:(NSUInteger)index; 20 | 21 | @end 22 | 23 | @interface LGAudioPlayer : NSObject 24 | 25 | @property (nonatomic, copy) NSString *URLString; 26 | @property (nonatomic, assign) NSUInteger index; 27 | @property (nonatomic, weak) iddelegate; 28 | 29 | + (instancetype)sharePlayer; 30 | /// 可播放mp3、caf、wav、amr格式的音频 31 | - (void)playAudioWithURLString:(NSString *)URLString atIndex:(NSUInteger)index; 32 | 33 | - (void)stopAudioPlayer; 34 | /// 播放在线音频 35 | - (void)playAudioOnlineWithContentsOfURL:(NSURL *)url; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/NSArray+MASShorthandAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+MASShorthandAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 22/07/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "NSArray+MASAdditions.h" 10 | 11 | #ifdef MAS_SHORTHAND 12 | 13 | /** 14 | * Shorthand array additions without the 'mas_' prefixes, 15 | * only enabled if MAS_SHORTHAND is defined 16 | */ 17 | @interface NSArray (MASShorthandAdditions) 18 | 19 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block; 20 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block; 21 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block; 22 | 23 | @end 24 | 25 | @implementation NSArray (MASShorthandAdditions) 26 | 27 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *))block { 28 | return [self mas_makeConstraints:block]; 29 | } 30 | 31 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *))block { 32 | return [self mas_updateConstraints:block]; 33 | } 34 | 35 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *))block { 36 | return [self mas_remakeConstraints:block]; 37 | } 38 | 39 | @end 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /LGAudioKit/Class/Vendor/AMR/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 | -------------------------------------------------------------------------------- /LGAudioKit/Class/Vendor/AMR/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 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/MASViewAttribute.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASAttribute.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASViewAttribute.h" 10 | 11 | @implementation MASViewAttribute 12 | 13 | - (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute { 14 | self = [self initWithView:view item:view layoutAttribute:layoutAttribute]; 15 | return self; 16 | } 17 | 18 | - (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute { 19 | self = [super init]; 20 | if (!self) return nil; 21 | 22 | _view = view; 23 | _item = item; 24 | _layoutAttribute = layoutAttribute; 25 | 26 | return self; 27 | } 28 | 29 | - (BOOL)isSizeAttribute { 30 | return self.layoutAttribute == NSLayoutAttributeWidth 31 | || self.layoutAttribute == NSLayoutAttributeHeight; 32 | } 33 | 34 | - (BOOL)isEqual:(MASViewAttribute *)viewAttribute { 35 | if ([viewAttribute isKindOfClass:self.class]) { 36 | return self.view == viewAttribute.view 37 | && self.layoutAttribute == viewAttribute.layoutAttribute; 38 | } 39 | return [super isEqual:viewAttribute]; 40 | } 41 | 42 | - (NSUInteger)hash { 43 | return MAS_NSUINTROTATE([self.view hash], MAS_NSUINT_BIT / 2) ^ self.layoutAttribute; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/MASViewAttribute.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASAttribute.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | 11 | /** 12 | * An immutable tuple which stores the view and the related NSLayoutAttribute. 13 | * Describes part of either the left or right hand side of a constraint equation 14 | */ 15 | @interface MASViewAttribute : NSObject 16 | 17 | /** 18 | * The view which the reciever relates to. Can be nil if item is not a view. 19 | */ 20 | @property (nonatomic, weak, readonly) MAS_VIEW *view; 21 | 22 | /** 23 | * The item which the reciever relates to. 24 | */ 25 | @property (nonatomic, weak, readonly) id item; 26 | 27 | /** 28 | * The attribute which the reciever relates to 29 | */ 30 | @property (nonatomic, assign, readonly) NSLayoutAttribute layoutAttribute; 31 | 32 | /** 33 | * Convenience initializer. 34 | */ 35 | - (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute; 36 | 37 | /** 38 | * The designated initializer. 39 | */ 40 | - (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute; 41 | 42 | /** 43 | * Determine whether the layoutAttribute is a size attribute 44 | * 45 | * @return YES if layoutAttribute is equal to NSLayoutAttributeWidth or NSLayoutAttributeHeight 46 | */ 47 | - (BOOL)isSizeAttribute; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/ViewController+MASAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+MASAdditions.m 3 | // Masonry 4 | // 5 | // Created by Craig Siemens on 2015-06-23. 6 | // 7 | // 8 | 9 | #import "ViewController+MASAdditions.h" 10 | 11 | #ifdef MAS_VIEW_CONTROLLER 12 | 13 | @implementation MAS_VIEW_CONTROLLER (MASAdditions) 14 | 15 | - (MASViewAttribute *)mas_topLayoutGuide { 16 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; 17 | } 18 | - (MASViewAttribute *)mas_topLayoutGuideTop { 19 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeTop]; 20 | } 21 | - (MASViewAttribute *)mas_topLayoutGuideBottom { 22 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; 23 | } 24 | 25 | - (MASViewAttribute *)mas_bottomLayoutGuide { 26 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop]; 27 | } 28 | - (MASViewAttribute *)mas_bottomLayoutGuideTop { 29 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop]; 30 | } 31 | - (MASViewAttribute *)mas_bottomLayoutGuideBottom { 32 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; 33 | } 34 | 35 | 36 | 37 | @end 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/MASViewConstraint.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASConstraint.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASViewAttribute.h" 10 | #import "MASConstraint.h" 11 | #import "MASLayoutConstraint.h" 12 | #import "MASUtilities.h" 13 | 14 | /** 15 | * A single constraint. 16 | * Contains the attributes neccessary for creating a NSLayoutConstraint and adding it to the appropriate view 17 | */ 18 | @interface MASViewConstraint : MASConstraint 19 | 20 | /** 21 | * First item/view and first attribute of the NSLayoutConstraint 22 | */ 23 | @property (nonatomic, strong, readonly) MASViewAttribute *firstViewAttribute; 24 | 25 | /** 26 | * Second item/view and second attribute of the NSLayoutConstraint 27 | */ 28 | @property (nonatomic, strong, readonly) MASViewAttribute *secondViewAttribute; 29 | 30 | /** 31 | * initialises the MASViewConstraint with the first part of the equation 32 | * 33 | * @param firstViewAttribute view.mas_left, view.mas_width etc. 34 | * 35 | * @return a new view constraint 36 | */ 37 | - (id)initWithFirstViewAttribute:(MASViewAttribute *)firstViewAttribute; 38 | 39 | /** 40 | * Returns all MASViewConstraints installed with this view as a first item. 41 | * 42 | * @param view A view to retrieve constraints for. 43 | * 44 | * @return An array of MASViewConstraints. 45 | */ 46 | + (NSArray *)installedConstraintsForView:(MAS_VIEW *)view; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /LGAudioKit/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 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "83.5x83.5", 66 | "scale" : "2x" 67 | } 68 | ], 69 | "info" : { 70 | "version" : 1, 71 | "author" : "xcode" 72 | } 73 | } -------------------------------------------------------------------------------- /LGAudioKit/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 | -------------------------------------------------------------------------------- /LGAudioKit/Class/Vendor/AMR/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 | -------------------------------------------------------------------------------- /LGAudioKit/Class/LGSoundRecorder/LGSoundRecorder.h: -------------------------------------------------------------------------------- 1 | // 2 | // LGSoundRecorder.h 3 | // 下载地址:https://github.com/gang544043963/LGAudioKit 4 | // 5 | // Created by ligang on 16/8/20. 6 | // Copyright © 2016年 LG. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | @protocol LGSoundRecorderDelegate 14 | 15 | - (void)showSoundRecordFailed; 16 | - (void)didStopSoundRecord; 17 | 18 | @end 19 | 20 | @interface LGSoundRecorder : NSObject 21 | 22 | @property (nonatomic, copy) NSString *soundFilePath; 23 | @property (nonatomic, weak) iddelegate; 24 | 25 | + (LGSoundRecorder *)shareInstance; 26 | /** 27 | * 开始录音 28 | * 29 | * @param view 展现录音指示框的父视图 30 | * @param path 音频文件保存路径 31 | */ 32 | - (void)startSoundRecord:(UIView *)view recordPath:(NSString *)path; 33 | /** 34 | * 录音结束 35 | */ 36 | - (void)stopSoundRecord:(UIView *)view; 37 | /** 38 | * 录音失败/取消录音 39 | */ 40 | - (void)soundRecordFailed:(UIView *)view; 41 | /** 42 | * 提示‘松开手指,取消录音’ 43 | */ 44 | - (void)readyCancelSound; 45 | /** 46 | * 更新录音状态,手指重新滑动到按钮范围内,提示向上取消录音 47 | */ 48 | - (void)resetNormalRecord; 49 | /** 50 | * 录音时间过短 51 | */ 52 | - (void)showShotTimeSign:(UIView *)view; 53 | /** 54 | * 最后10秒,显示你还可以说X秒 55 | * 56 | * @param countDown X秒 57 | */ 58 | - (void)showCountdown:(int)countDown; 59 | 60 | - (NSTimeInterval)soundRecordTime; 61 | 62 | /** 63 | * caf文件转换为amr。预留方法,需要转换格式的童靴可以直接使用 64 | * 65 | * @param fielPath caf文件路径 66 | * 67 | * @return amr文件的二进制数据 68 | */ 69 | - (NSData *)convertCAFtoAMR:(NSString *)fielPath; 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /LGAudioKit/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 | -------------------------------------------------------------------------------- /LGAudioKit/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 | NSAppleMusicUsageDescription 26 | 27 | NSMicrophoneUsageDescription 28 | 29 | UILaunchStoryboardName 30 | LaunchScreen 31 | UIMainStoryboardFile 32 | Main 33 | UIRequiredDeviceCapabilities 34 | 35 | armv7 36 | 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationLandscapeLeft 41 | UIInterfaceOrientationLandscapeRight 42 | 43 | UISupportedInterfaceOrientations~ipad 44 | 45 | UIInterfaceOrientationPortrait 46 | UIInterfaceOrientationPortraitUpsideDown 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /LGAudioKit/Class/Vendor/AMR/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 | 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 -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/MASConstraint+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASConstraint+Private.h 3 | // Masonry 4 | // 5 | // Created by Nick Tymchenko on 29/04/14. 6 | // Copyright (c) 2014 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASConstraint.h" 10 | 11 | @protocol MASConstraintDelegate; 12 | 13 | 14 | @interface MASConstraint () 15 | 16 | /** 17 | * Whether or not to check for an existing constraint instead of adding constraint 18 | */ 19 | @property (nonatomic, assign) BOOL updateExisting; 20 | 21 | /** 22 | * Usually MASConstraintMaker but could be a parent MASConstraint 23 | */ 24 | @property (nonatomic, weak) id delegate; 25 | 26 | /** 27 | * Based on a provided value type, is equal to calling: 28 | * NSNumber - setOffset: 29 | * NSValue with CGPoint - setPointOffset: 30 | * NSValue with CGSize - setSizeOffset: 31 | * NSValue with MASEdgeInsets - setInsets: 32 | */ 33 | - (void)setLayoutConstantWithValue:(NSValue *)value; 34 | 35 | @end 36 | 37 | 38 | @interface MASConstraint (Abstract) 39 | 40 | /** 41 | * Sets the constraint relation to given NSLayoutRelation 42 | * returns a block which accepts one of the following: 43 | * MASViewAttribute, UIView, NSValue, NSArray 44 | * see readme for more details. 45 | */ 46 | - (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation; 47 | 48 | /** 49 | * Override to set a custom chaining behaviour 50 | */ 51 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute; 52 | 53 | @end 54 | 55 | 56 | @protocol MASConstraintDelegate 57 | 58 | /** 59 | * Notifies the delegate when the constraint needs to be replaced with another constraint. For example 60 | * A MASViewConstraint may turn into a MASCompositeConstraint when an array is passed to one of the equality blocks 61 | */ 62 | - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint; 63 | 64 | - (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute; 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /LGAudioKit/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // LGAudioKit 4 | // 5 | // Created by ligang on 16/8/20. 6 | // Copyright © 2016年 LG. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | 16 | 17 | 18 | @implementation AppDelegate 19 | 20 | 21 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 22 | // Override point for customization after application launch. 23 | return YES; 24 | } 25 | 26 | - (void)applicationWillResignActive:(UIApplication *)application { 27 | // 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. 28 | // 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. 29 | } 30 | 31 | - (void)applicationDidEnterBackground:(UIApplication *)application { 32 | // 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. 33 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 34 | } 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // 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. 38 | } 39 | 40 | - (void)applicationDidBecomeActive:(UIApplication *)application { 41 | // 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. 42 | } 43 | 44 | - (void)applicationWillTerminate:(UIApplication *)application { 45 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LGAudioKit 2 | 3 | [![Travis](https://img.shields.io/travis/rust-lang/rust.svg)]() [![License MIT](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://raw.githubusercontent.com/GIKICoder/GDataBase/master/LICENSE)  4 | 5 | [swift版传送门](https://github.com/gang544043963/LGAudioKit_swift) 6 | 7 | 简单易用的语音录制、播放控件。流程和界面参考微信 8 | 9 | ## 说明 10 | - Demo中包含两个控件: 11 | 12 | 录音控件:'LGSoundRecorder' 13 | 14 | 播放控件:'LGSoundPlayer' 15 | 16 | - 录音文件格式为.caf,提供转amr方法,可转成amr发给安卓 17 | 18 | - 播放语音格式支持:amr、caf、wav、mp3 19 | 20 | - 具体的使用细节请参考Demo中的ViewController.m 21 | 22 | - 语音录放的一些简单分析请参考 [iOS通信软件中的语音录制与播放 ](http://blog.csdn.net/gang544043963/article/details/52266903) 23 | 24 | ## 示例 25 | 26 | CXLSlideList Screenshot CXLSlideList Screenshot 27 | 28 | ## 添加到工程 29 | - 拷贝'Class'文件夹到你的工程 30 | - #import "LGAudioKit.h" 31 | 32 | ## 播放器 LGAudioPlayer 33 | 34 | - 开始播放 35 | ```OC 36 | - (void)playAudioWithURLString:(NSString *)URLString atIndex:(NSUInteger)index; 37 | ``` 38 | URLString: 语音文件本地路径。如果要播放网络文件,先下载到本地,再播放 39 | 40 | - 停止播放 41 | ```OC 42 | - (void)stopAudioPlayer 43 | ``` 44 | 45 | - 代理方法 46 | ```OC 47 | - (void)audioPlayerStateDidChanged:(LGAudioPlayerState)audioPlayerState forIndex:(NSUInteger)index 48 | ``` 49 | 50 | - 播放状态 LGAudioPlayerState 51 | ```OC 52 | typedef NS_ENUM(NSUInteger, LGAudioPlayerState){ 53 | LGAudioPlayerStateNormal = 0,/**< 未播放状态 */ 54 | LGAudioPlayerStatePlaying = 2,/**< 正在播放 */ 55 | LGAudioPlayerStateCancel = 3,/**< 播放被取消 */ 56 | }; 57 | ``` 58 | 59 | ## 录音器 60 | 61 | - 开始录音 62 | ```OC 63 | - (void)startSoundRecord:(UIView *)view recordPath:(NSString *)path; 64 | ``` 65 | view: 传入录音动画的父view(录音动画要展示的依托view); 66 | path: 语音文件存储路径 67 | 68 | - 结束录音 69 | ```OC 70 | - (void)stopSoundRecord:(UIView *)view; 71 | ``` 72 | 73 | - 录音失败/取消录音 74 | ```OC 75 | - (void)soundRecordFailed:(UIView *)view; 76 | ``` 77 | 78 | - 提示‘松开手指,取消录音’。这个状态下,录音继续。 79 | ```OC 80 | - (void)readyCancelSound; 81 | ``` 82 | 83 | - 恢复正常提示动画。(手指重新滑动到按钮范围内,提示‘手指上滑,取消发送’) 84 | ```OC 85 | - (void)resetNormalRecord; 86 | ``` 87 | 88 | - 提示‘说话时间太短’ 89 | ```OC 90 | - (void)showShotTimeSign:(UIView *)view 91 | ``` 92 | 93 | - 展示录音倒计时 94 | ```OC 95 | - (void)showCountdown:(int)countDown; 96 | ``` 97 | countDown: 剩余时间,秒。 98 | 99 | - 文件格式转换,caf文件转换为amr 100 | ```OC 101 | - (NSData *)convertCAFtoAMR:(NSString *)fielPath; 102 | ``` 103 | 104 | - 获取录音时长 105 | ```OC 106 | - (NSTimeInterval)soundRecordTime; 107 | ``` 108 | 109 | ## 环境支持 110 | - iOS7及以上 111 | 112 | 113 | 114 | _______________________________________________________ 115 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/NSArray+MASAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+MASAdditions.h 3 | // 4 | // 5 | // Created by Daniel Hammond on 11/26/13. 6 | // 7 | // 8 | 9 | #import "MASUtilities.h" 10 | #import "MASConstraintMaker.h" 11 | #import "MASViewAttribute.h" 12 | 13 | typedef NS_ENUM(NSUInteger, MASAxisType) { 14 | MASAxisTypeHorizontal, 15 | MASAxisTypeVertical 16 | }; 17 | 18 | @interface NSArray (MASAdditions) 19 | 20 | /** 21 | * Creates a MASConstraintMaker with each view in the callee. 22 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing on each view 23 | * 24 | * @param block scope within which you can build up the constraints which you wish to apply to each view. 25 | * 26 | * @return Array of created MASConstraints 27 | */ 28 | - (NSArray *)mas_makeConstraints:(void (^)(MASConstraintMaker *make))block; 29 | 30 | /** 31 | * Creates a MASConstraintMaker with each view in the callee. 32 | * Any constraints defined are added to each view or the appropriate superview once the block has finished executing on each view. 33 | * If an existing constraint exists then it will be updated instead. 34 | * 35 | * @param block scope within which you can build up the constraints which you wish to apply to each view. 36 | * 37 | * @return Array of created/updated MASConstraints 38 | */ 39 | - (NSArray *)mas_updateConstraints:(void (^)(MASConstraintMaker *make))block; 40 | 41 | /** 42 | * Creates a MASConstraintMaker with each view in the callee. 43 | * Any constraints defined are added to each view or the appropriate superview once the block has finished executing on each view. 44 | * All constraints previously installed for the views will be removed. 45 | * 46 | * @param block scope within which you can build up the constraints which you wish to apply to each view. 47 | * 48 | * @return Array of created/updated MASConstraints 49 | */ 50 | - (NSArray *)mas_remakeConstraints:(void (^)(MASConstraintMaker *make))block; 51 | 52 | /** 53 | * distribute with fixed spacing 54 | * 55 | * @param axisType which axis to distribute items along 56 | * @param fixedSpacing the spacing between each item 57 | * @param leadSpacing the spacing before the first item and the container 58 | * @param tailSpacing the spacing after the last item and the container 59 | */ 60 | - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing; 61 | 62 | /** 63 | * distribute with fixed item size 64 | * 65 | * @param axisType which axis to distribute items along 66 | * @param fixedItemLength the fixed length of each item 67 | * @param leadSpacing the spacing before the first item and the container 68 | * @param tailSpacing the spacing after the last item and the container 69 | */ 70 | - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing; 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /LGAudioKit.xcodeproj/xcuserdata/ligang.xcuserdatad/xcschemes/LGAudioKit.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/View+MASShorthandAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+MASShorthandAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 22/07/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "View+MASAdditions.h" 10 | 11 | #ifdef MAS_SHORTHAND 12 | 13 | /** 14 | * Shorthand view additions without the 'mas_' prefixes, 15 | * only enabled if MAS_SHORTHAND is defined 16 | */ 17 | @interface MAS_VIEW (MASShorthandAdditions) 18 | 19 | @property (nonatomic, strong, readonly) MASViewAttribute *left; 20 | @property (nonatomic, strong, readonly) MASViewAttribute *top; 21 | @property (nonatomic, strong, readonly) MASViewAttribute *right; 22 | @property (nonatomic, strong, readonly) MASViewAttribute *bottom; 23 | @property (nonatomic, strong, readonly) MASViewAttribute *leading; 24 | @property (nonatomic, strong, readonly) MASViewAttribute *trailing; 25 | @property (nonatomic, strong, readonly) MASViewAttribute *width; 26 | @property (nonatomic, strong, readonly) MASViewAttribute *height; 27 | @property (nonatomic, strong, readonly) MASViewAttribute *centerX; 28 | @property (nonatomic, strong, readonly) MASViewAttribute *centerY; 29 | @property (nonatomic, strong, readonly) MASViewAttribute *baseline; 30 | @property (nonatomic, strong, readonly) MASViewAttribute *(^attribute)(NSLayoutAttribute attr); 31 | 32 | #if TARGET_OS_IPHONE || TARGET_OS_TV 33 | 34 | @property (nonatomic, strong, readonly) MASViewAttribute *leftMargin; 35 | @property (nonatomic, strong, readonly) MASViewAttribute *rightMargin; 36 | @property (nonatomic, strong, readonly) MASViewAttribute *topMargin; 37 | @property (nonatomic, strong, readonly) MASViewAttribute *bottomMargin; 38 | @property (nonatomic, strong, readonly) MASViewAttribute *leadingMargin; 39 | @property (nonatomic, strong, readonly) MASViewAttribute *trailingMargin; 40 | @property (nonatomic, strong, readonly) MASViewAttribute *centerXWithinMargins; 41 | @property (nonatomic, strong, readonly) MASViewAttribute *centerYWithinMargins; 42 | 43 | #endif 44 | 45 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block; 46 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block; 47 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block; 48 | 49 | @end 50 | 51 | #define MAS_ATTR_FORWARD(attr) \ 52 | - (MASViewAttribute *)attr { \ 53 | return [self mas_##attr]; \ 54 | } 55 | 56 | @implementation MAS_VIEW (MASShorthandAdditions) 57 | 58 | MAS_ATTR_FORWARD(top); 59 | MAS_ATTR_FORWARD(left); 60 | MAS_ATTR_FORWARD(bottom); 61 | MAS_ATTR_FORWARD(right); 62 | MAS_ATTR_FORWARD(leading); 63 | MAS_ATTR_FORWARD(trailing); 64 | MAS_ATTR_FORWARD(width); 65 | MAS_ATTR_FORWARD(height); 66 | MAS_ATTR_FORWARD(centerX); 67 | MAS_ATTR_FORWARD(centerY); 68 | MAS_ATTR_FORWARD(baseline); 69 | 70 | #if TARGET_OS_IPHONE || TARGET_OS_TV 71 | 72 | MAS_ATTR_FORWARD(leftMargin); 73 | MAS_ATTR_FORWARD(rightMargin); 74 | MAS_ATTR_FORWARD(topMargin); 75 | MAS_ATTR_FORWARD(bottomMargin); 76 | MAS_ATTR_FORWARD(leadingMargin); 77 | MAS_ATTR_FORWARD(trailingMargin); 78 | MAS_ATTR_FORWARD(centerXWithinMargins); 79 | MAS_ATTR_FORWARD(centerYWithinMargins); 80 | 81 | #endif 82 | 83 | - (MASViewAttribute *(^)(NSLayoutAttribute))attribute { 84 | return [self mas_attribute]; 85 | } 86 | 87 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *))block { 88 | return [self mas_makeConstraints:block]; 89 | } 90 | 91 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *))block { 92 | return [self mas_updateConstraints:block]; 93 | } 94 | 95 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *))block { 96 | return [self mas_remakeConstraints:block]; 97 | } 98 | 99 | @end 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/View+MASAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+MASAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | #import "MASConstraintMaker.h" 11 | #import "MASViewAttribute.h" 12 | 13 | /** 14 | * Provides constraint maker block 15 | * and convience methods for creating MASViewAttribute which are view + NSLayoutAttribute pairs 16 | */ 17 | @interface MAS_VIEW (MASAdditions) 18 | 19 | /** 20 | * following properties return a new MASViewAttribute with current view and appropriate NSLayoutAttribute 21 | */ 22 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_left; 23 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_top; 24 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_right; 25 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottom; 26 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_leading; 27 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_trailing; 28 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_width; 29 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_height; 30 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerX; 31 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerY; 32 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_baseline; 33 | @property (nonatomic, strong, readonly) MASViewAttribute *(^mas_attribute)(NSLayoutAttribute attr); 34 | 35 | #if TARGET_OS_IPHONE || TARGET_OS_TV 36 | 37 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_leftMargin; 38 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_rightMargin; 39 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topMargin; 40 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomMargin; 41 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_leadingMargin; 42 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_trailingMargin; 43 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerXWithinMargins; 44 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerYWithinMargins; 45 | 46 | #endif 47 | 48 | /** 49 | * a key to associate with this view 50 | */ 51 | @property (nonatomic, strong) id mas_key; 52 | 53 | /** 54 | * Finds the closest common superview between this view and another view 55 | * 56 | * @param view other view 57 | * 58 | * @return returns nil if common superview could not be found 59 | */ 60 | - (instancetype)mas_closestCommonSuperview:(MAS_VIEW *)view; 61 | 62 | /** 63 | * Creates a MASConstraintMaker with the callee view. 64 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing 65 | * 66 | * @param block scope within which you can build up the constraints which you wish to apply to the view. 67 | * 68 | * @return Array of created MASConstraints 69 | */ 70 | - (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block; 71 | 72 | /** 73 | * Creates a MASConstraintMaker with the callee view. 74 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing. 75 | * If an existing constraint exists then it will be updated instead. 76 | * 77 | * @param block scope within which you can build up the constraints which you wish to apply to the view. 78 | * 79 | * @return Array of created/updated MASConstraints 80 | */ 81 | - (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block; 82 | 83 | /** 84 | * Creates a MASConstraintMaker with the callee view. 85 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing. 86 | * All constraints previously installed for the view will be removed. 87 | * 88 | * @param block scope within which you can build up the constraints which you wish to apply to the view. 89 | * 90 | * @return Array of created/updated MASConstraints 91 | */ 92 | - (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block; 93 | 94 | @end 95 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/MASCompositeConstraint.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASCompositeConstraint.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASCompositeConstraint.h" 10 | #import "MASConstraint+Private.h" 11 | 12 | @interface MASCompositeConstraint () 13 | 14 | @property (nonatomic, strong) id mas_key; 15 | @property (nonatomic, strong) NSMutableArray *childConstraints; 16 | 17 | @end 18 | 19 | @implementation MASCompositeConstraint 20 | 21 | - (id)initWithChildren:(NSArray *)children { 22 | self = [super init]; 23 | if (!self) return nil; 24 | 25 | _childConstraints = [children mutableCopy]; 26 | for (MASConstraint *constraint in _childConstraints) { 27 | constraint.delegate = self; 28 | } 29 | 30 | return self; 31 | } 32 | 33 | #pragma mark - MASConstraintDelegate 34 | 35 | - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint { 36 | NSUInteger index = [self.childConstraints indexOfObject:constraint]; 37 | NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint); 38 | [self.childConstraints replaceObjectAtIndex:index withObject:replacementConstraint]; 39 | } 40 | 41 | - (MASConstraint *)constraint:(MASConstraint __unused *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute { 42 | id strongDelegate = self.delegate; 43 | MASConstraint *newConstraint = [strongDelegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute]; 44 | newConstraint.delegate = self; 45 | [self.childConstraints addObject:newConstraint]; 46 | return newConstraint; 47 | } 48 | 49 | #pragma mark - NSLayoutConstraint multiplier proxies 50 | 51 | - (MASConstraint * (^)(CGFloat))multipliedBy { 52 | return ^id(CGFloat multiplier) { 53 | for (MASConstraint *constraint in self.childConstraints) { 54 | constraint.multipliedBy(multiplier); 55 | } 56 | return self; 57 | }; 58 | } 59 | 60 | - (MASConstraint * (^)(CGFloat))dividedBy { 61 | return ^id(CGFloat divider) { 62 | for (MASConstraint *constraint in self.childConstraints) { 63 | constraint.dividedBy(divider); 64 | } 65 | return self; 66 | }; 67 | } 68 | 69 | #pragma mark - MASLayoutPriority proxy 70 | 71 | - (MASConstraint * (^)(MASLayoutPriority))priority { 72 | return ^id(MASLayoutPriority priority) { 73 | for (MASConstraint *constraint in self.childConstraints) { 74 | constraint.priority(priority); 75 | } 76 | return self; 77 | }; 78 | } 79 | 80 | #pragma mark - NSLayoutRelation proxy 81 | 82 | - (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation { 83 | return ^id(id attr, NSLayoutRelation relation) { 84 | for (MASConstraint *constraint in self.childConstraints.copy) { 85 | constraint.equalToWithRelation(attr, relation); 86 | } 87 | return self; 88 | }; 89 | } 90 | 91 | #pragma mark - attribute chaining 92 | 93 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute { 94 | [self constraint:self addConstraintWithLayoutAttribute:layoutAttribute]; 95 | return self; 96 | } 97 | 98 | #pragma mark - Animator proxy 99 | 100 | #if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV) 101 | 102 | - (MASConstraint *)animator { 103 | for (MASConstraint *constraint in self.childConstraints) { 104 | [constraint animator]; 105 | } 106 | return self; 107 | } 108 | 109 | #endif 110 | 111 | #pragma mark - debug helpers 112 | 113 | - (MASConstraint * (^)(id))key { 114 | return ^id(id key) { 115 | self.mas_key = key; 116 | int i = 0; 117 | for (MASConstraint *constraint in self.childConstraints) { 118 | constraint.key([NSString stringWithFormat:@"%@[%d]", key, i++]); 119 | } 120 | return self; 121 | }; 122 | } 123 | 124 | #pragma mark - NSLayoutConstraint constant setters 125 | 126 | - (void)setInsets:(MASEdgeInsets)insets { 127 | for (MASConstraint *constraint in self.childConstraints) { 128 | constraint.insets = insets; 129 | } 130 | } 131 | 132 | - (void)setOffset:(CGFloat)offset { 133 | for (MASConstraint *constraint in self.childConstraints) { 134 | constraint.offset = offset; 135 | } 136 | } 137 | 138 | - (void)setSizeOffset:(CGSize)sizeOffset { 139 | for (MASConstraint *constraint in self.childConstraints) { 140 | constraint.sizeOffset = sizeOffset; 141 | } 142 | } 143 | 144 | - (void)setCenterOffset:(CGPoint)centerOffset { 145 | for (MASConstraint *constraint in self.childConstraints) { 146 | constraint.centerOffset = centerOffset; 147 | } 148 | } 149 | 150 | #pragma mark - MASConstraint 151 | 152 | - (void)activate { 153 | for (MASConstraint *constraint in self.childConstraints) { 154 | [constraint activate]; 155 | } 156 | } 157 | 158 | - (void)deactivate { 159 | for (MASConstraint *constraint in self.childConstraints) { 160 | [constraint deactivate]; 161 | } 162 | } 163 | 164 | - (void)install { 165 | for (MASConstraint *constraint in self.childConstraints) { 166 | constraint.updateExisting = self.updateExisting; 167 | [constraint install]; 168 | } 169 | } 170 | 171 | - (void)uninstall { 172 | for (MASConstraint *constraint in self.childConstraints) { 173 | [constraint uninstall]; 174 | } 175 | } 176 | 177 | @end 178 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/MASConstraintMaker.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASConstraintBuilder.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASConstraint.h" 10 | #import "MASUtilities.h" 11 | 12 | typedef NS_OPTIONS(NSInteger, MASAttribute) { 13 | MASAttributeLeft = 1 << NSLayoutAttributeLeft, 14 | MASAttributeRight = 1 << NSLayoutAttributeRight, 15 | MASAttributeTop = 1 << NSLayoutAttributeTop, 16 | MASAttributeBottom = 1 << NSLayoutAttributeBottom, 17 | MASAttributeLeading = 1 << NSLayoutAttributeLeading, 18 | MASAttributeTrailing = 1 << NSLayoutAttributeTrailing, 19 | MASAttributeWidth = 1 << NSLayoutAttributeWidth, 20 | MASAttributeHeight = 1 << NSLayoutAttributeHeight, 21 | MASAttributeCenterX = 1 << NSLayoutAttributeCenterX, 22 | MASAttributeCenterY = 1 << NSLayoutAttributeCenterY, 23 | MASAttributeBaseline = 1 << NSLayoutAttributeBaseline, 24 | 25 | #if TARGET_OS_IPHONE || TARGET_OS_TV 26 | 27 | MASAttributeLeftMargin = 1 << NSLayoutAttributeLeftMargin, 28 | MASAttributeRightMargin = 1 << NSLayoutAttributeRightMargin, 29 | MASAttributeTopMargin = 1 << NSLayoutAttributeTopMargin, 30 | MASAttributeBottomMargin = 1 << NSLayoutAttributeBottomMargin, 31 | MASAttributeLeadingMargin = 1 << NSLayoutAttributeLeadingMargin, 32 | MASAttributeTrailingMargin = 1 << NSLayoutAttributeTrailingMargin, 33 | MASAttributeCenterXWithinMargins = 1 << NSLayoutAttributeCenterXWithinMargins, 34 | MASAttributeCenterYWithinMargins = 1 << NSLayoutAttributeCenterYWithinMargins, 35 | 36 | #endif 37 | 38 | }; 39 | 40 | /** 41 | * Provides factory methods for creating MASConstraints. 42 | * Constraints are collected until they are ready to be installed 43 | * 44 | */ 45 | @interface MASConstraintMaker : NSObject 46 | 47 | /** 48 | * The following properties return a new MASViewConstraint 49 | * with the first item set to the makers associated view and the appropriate MASViewAttribute 50 | */ 51 | @property (nonatomic, strong, readonly) MASConstraint *left; 52 | @property (nonatomic, strong, readonly) MASConstraint *top; 53 | @property (nonatomic, strong, readonly) MASConstraint *right; 54 | @property (nonatomic, strong, readonly) MASConstraint *bottom; 55 | @property (nonatomic, strong, readonly) MASConstraint *leading; 56 | @property (nonatomic, strong, readonly) MASConstraint *trailing; 57 | @property (nonatomic, strong, readonly) MASConstraint *width; 58 | @property (nonatomic, strong, readonly) MASConstraint *height; 59 | @property (nonatomic, strong, readonly) MASConstraint *centerX; 60 | @property (nonatomic, strong, readonly) MASConstraint *centerY; 61 | @property (nonatomic, strong, readonly) MASConstraint *baseline; 62 | 63 | #if TARGET_OS_IPHONE || TARGET_OS_TV 64 | 65 | @property (nonatomic, strong, readonly) MASConstraint *leftMargin; 66 | @property (nonatomic, strong, readonly) MASConstraint *rightMargin; 67 | @property (nonatomic, strong, readonly) MASConstraint *topMargin; 68 | @property (nonatomic, strong, readonly) MASConstraint *bottomMargin; 69 | @property (nonatomic, strong, readonly) MASConstraint *leadingMargin; 70 | @property (nonatomic, strong, readonly) MASConstraint *trailingMargin; 71 | @property (nonatomic, strong, readonly) MASConstraint *centerXWithinMargins; 72 | @property (nonatomic, strong, readonly) MASConstraint *centerYWithinMargins; 73 | 74 | #endif 75 | 76 | /** 77 | * Returns a block which creates a new MASCompositeConstraint with the first item set 78 | * to the makers associated view and children corresponding to the set bits in the 79 | * MASAttribute parameter. Combine multiple attributes via binary-or. 80 | */ 81 | @property (nonatomic, strong, readonly) MASConstraint *(^attributes)(MASAttribute attrs); 82 | 83 | /** 84 | * Creates a MASCompositeConstraint with type MASCompositeConstraintTypeEdges 85 | * which generates the appropriate MASViewConstraint children (top, left, bottom, right) 86 | * with the first item set to the makers associated view 87 | */ 88 | @property (nonatomic, strong, readonly) MASConstraint *edges; 89 | 90 | /** 91 | * Creates a MASCompositeConstraint with type MASCompositeConstraintTypeSize 92 | * which generates the appropriate MASViewConstraint children (width, height) 93 | * with the first item set to the makers associated view 94 | */ 95 | @property (nonatomic, strong, readonly) MASConstraint *size; 96 | 97 | /** 98 | * Creates a MASCompositeConstraint with type MASCompositeConstraintTypeCenter 99 | * which generates the appropriate MASViewConstraint children (centerX, centerY) 100 | * with the first item set to the makers associated view 101 | */ 102 | @property (nonatomic, strong, readonly) MASConstraint *center; 103 | 104 | /** 105 | * Whether or not to check for an existing constraint instead of adding constraint 106 | */ 107 | @property (nonatomic, assign) BOOL updateExisting; 108 | 109 | /** 110 | * Whether or not to remove existing constraints prior to installing 111 | */ 112 | @property (nonatomic, assign) BOOL removeExisting; 113 | 114 | /** 115 | * initialises the maker with a default view 116 | * 117 | * @param view any MASConstrait are created with this view as the first item 118 | * 119 | * @return a new MASConstraintMaker 120 | */ 121 | - (id)initWithView:(MAS_VIEW *)view; 122 | 123 | /** 124 | * Calls install method on any MASConstraints which have been created by this maker 125 | * 126 | * @return an array of all the installed MASConstraints 127 | */ 128 | - (NSArray *)install; 129 | 130 | - (MASConstraint * (^)(dispatch_block_t))group; 131 | 132 | @end 133 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/View+MASAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+MASAdditions.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "View+MASAdditions.h" 10 | #import 11 | 12 | @implementation MAS_VIEW (MASAdditions) 13 | 14 | - (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block { 15 | self.translatesAutoresizingMaskIntoConstraints = NO; 16 | MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self]; 17 | block(constraintMaker); 18 | return [constraintMaker install]; 19 | } 20 | 21 | - (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *))block { 22 | self.translatesAutoresizingMaskIntoConstraints = NO; 23 | MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self]; 24 | constraintMaker.updateExisting = YES; 25 | block(constraintMaker); 26 | return [constraintMaker install]; 27 | } 28 | 29 | - (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block { 30 | self.translatesAutoresizingMaskIntoConstraints = NO; 31 | MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self]; 32 | constraintMaker.removeExisting = YES; 33 | block(constraintMaker); 34 | return [constraintMaker install]; 35 | } 36 | 37 | #pragma mark - NSLayoutAttribute properties 38 | 39 | - (MASViewAttribute *)mas_left { 40 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeft]; 41 | } 42 | 43 | - (MASViewAttribute *)mas_top { 44 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTop]; 45 | } 46 | 47 | - (MASViewAttribute *)mas_right { 48 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeRight]; 49 | } 50 | 51 | - (MASViewAttribute *)mas_bottom { 52 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBottom]; 53 | } 54 | 55 | - (MASViewAttribute *)mas_leading { 56 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeading]; 57 | } 58 | 59 | - (MASViewAttribute *)mas_trailing { 60 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTrailing]; 61 | } 62 | 63 | - (MASViewAttribute *)mas_width { 64 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeWidth]; 65 | } 66 | 67 | - (MASViewAttribute *)mas_height { 68 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeHeight]; 69 | } 70 | 71 | - (MASViewAttribute *)mas_centerX { 72 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterX]; 73 | } 74 | 75 | - (MASViewAttribute *)mas_centerY { 76 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterY]; 77 | } 78 | 79 | - (MASViewAttribute *)mas_baseline { 80 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBaseline]; 81 | } 82 | 83 | - (MASViewAttribute *(^)(NSLayoutAttribute))mas_attribute 84 | { 85 | return ^(NSLayoutAttribute attr) { 86 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:attr]; 87 | }; 88 | } 89 | 90 | #if TARGET_OS_IPHONE || TARGET_OS_TV 91 | 92 | - (MASViewAttribute *)mas_leftMargin { 93 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeftMargin]; 94 | } 95 | 96 | - (MASViewAttribute *)mas_rightMargin { 97 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeRightMargin]; 98 | } 99 | 100 | - (MASViewAttribute *)mas_topMargin { 101 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTopMargin]; 102 | } 103 | 104 | - (MASViewAttribute *)mas_bottomMargin { 105 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBottomMargin]; 106 | } 107 | 108 | - (MASViewAttribute *)mas_leadingMargin { 109 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeadingMargin]; 110 | } 111 | 112 | - (MASViewAttribute *)mas_trailingMargin { 113 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTrailingMargin]; 114 | } 115 | 116 | - (MASViewAttribute *)mas_centerXWithinMargins { 117 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterXWithinMargins]; 118 | } 119 | 120 | - (MASViewAttribute *)mas_centerYWithinMargins { 121 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterYWithinMargins]; 122 | } 123 | 124 | #endif 125 | 126 | #pragma mark - associated properties 127 | 128 | - (id)mas_key { 129 | return objc_getAssociatedObject(self, @selector(mas_key)); 130 | } 131 | 132 | - (void)setMas_key:(id)key { 133 | objc_setAssociatedObject(self, @selector(mas_key), key, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 134 | } 135 | 136 | #pragma mark - heirachy 137 | 138 | - (instancetype)mas_closestCommonSuperview:(MAS_VIEW *)view { 139 | MAS_VIEW *closestCommonSuperview = nil; 140 | 141 | MAS_VIEW *secondViewSuperview = view; 142 | while (!closestCommonSuperview && secondViewSuperview) { 143 | MAS_VIEW *firstViewSuperview = self; 144 | while (!closestCommonSuperview && firstViewSuperview) { 145 | if (secondViewSuperview == firstViewSuperview) { 146 | closestCommonSuperview = secondViewSuperview; 147 | } 148 | firstViewSuperview = firstViewSuperview.superview; 149 | } 150 | secondViewSuperview = secondViewSuperview.superview; 151 | } 152 | return closestCommonSuperview; 153 | } 154 | 155 | @end 156 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/NSLayoutConstraint+MASDebugAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSLayoutConstraint+MASDebugAdditions.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "NSLayoutConstraint+MASDebugAdditions.h" 10 | #import "MASConstraint.h" 11 | #import "MASLayoutConstraint.h" 12 | 13 | @implementation NSLayoutConstraint (MASDebugAdditions) 14 | 15 | #pragma mark - description maps 16 | 17 | + (NSDictionary *)layoutRelationDescriptionsByValue { 18 | static dispatch_once_t once; 19 | static NSDictionary *descriptionMap; 20 | dispatch_once(&once, ^{ 21 | descriptionMap = @{ 22 | @(NSLayoutRelationEqual) : @"==", 23 | @(NSLayoutRelationGreaterThanOrEqual) : @">=", 24 | @(NSLayoutRelationLessThanOrEqual) : @"<=", 25 | }; 26 | }); 27 | return descriptionMap; 28 | } 29 | 30 | + (NSDictionary *)layoutAttributeDescriptionsByValue { 31 | static dispatch_once_t once; 32 | static NSDictionary *descriptionMap; 33 | dispatch_once(&once, ^{ 34 | descriptionMap = @{ 35 | @(NSLayoutAttributeTop) : @"top", 36 | @(NSLayoutAttributeLeft) : @"left", 37 | @(NSLayoutAttributeBottom) : @"bottom", 38 | @(NSLayoutAttributeRight) : @"right", 39 | @(NSLayoutAttributeLeading) : @"leading", 40 | @(NSLayoutAttributeTrailing) : @"trailing", 41 | @(NSLayoutAttributeWidth) : @"width", 42 | @(NSLayoutAttributeHeight) : @"height", 43 | @(NSLayoutAttributeCenterX) : @"centerX", 44 | @(NSLayoutAttributeCenterY) : @"centerY", 45 | @(NSLayoutAttributeBaseline) : @"baseline", 46 | 47 | #if TARGET_OS_IPHONE || TARGET_OS_TV 48 | @(NSLayoutAttributeLeftMargin) : @"leftMargin", 49 | @(NSLayoutAttributeRightMargin) : @"rightMargin", 50 | @(NSLayoutAttributeTopMargin) : @"topMargin", 51 | @(NSLayoutAttributeBottomMargin) : @"bottomMargin", 52 | @(NSLayoutAttributeLeadingMargin) : @"leadingMargin", 53 | @(NSLayoutAttributeTrailingMargin) : @"trailingMargin", 54 | @(NSLayoutAttributeCenterXWithinMargins) : @"centerXWithinMargins", 55 | @(NSLayoutAttributeCenterYWithinMargins) : @"centerYWithinMargins", 56 | #endif 57 | 58 | }; 59 | 60 | }); 61 | return descriptionMap; 62 | } 63 | 64 | 65 | + (NSDictionary *)layoutPriorityDescriptionsByValue { 66 | static dispatch_once_t once; 67 | static NSDictionary *descriptionMap; 68 | dispatch_once(&once, ^{ 69 | #if TARGET_OS_IPHONE || TARGET_OS_TV 70 | descriptionMap = @{ 71 | @(MASLayoutPriorityDefaultHigh) : @"high", 72 | @(MASLayoutPriorityDefaultLow) : @"low", 73 | @(MASLayoutPriorityDefaultMedium) : @"medium", 74 | @(MASLayoutPriorityRequired) : @"required", 75 | @(MASLayoutPriorityFittingSizeLevel) : @"fitting size", 76 | }; 77 | #elif TARGET_OS_MAC 78 | descriptionMap = @{ 79 | @(MASLayoutPriorityDefaultHigh) : @"high", 80 | @(MASLayoutPriorityDragThatCanResizeWindow) : @"drag can resize window", 81 | @(MASLayoutPriorityDefaultMedium) : @"medium", 82 | @(MASLayoutPriorityWindowSizeStayPut) : @"window size stay put", 83 | @(MASLayoutPriorityDragThatCannotResizeWindow) : @"drag cannot resize window", 84 | @(MASLayoutPriorityDefaultLow) : @"low", 85 | @(MASLayoutPriorityFittingSizeCompression) : @"fitting size", 86 | @(MASLayoutPriorityRequired) : @"required", 87 | }; 88 | #endif 89 | }); 90 | return descriptionMap; 91 | } 92 | 93 | #pragma mark - description override 94 | 95 | + (NSString *)descriptionForObject:(id)obj { 96 | if ([obj respondsToSelector:@selector(mas_key)] && [obj mas_key]) { 97 | return [NSString stringWithFormat:@"%@:%@", [obj class], [obj mas_key]]; 98 | } 99 | return [NSString stringWithFormat:@"%@:%p", [obj class], obj]; 100 | } 101 | 102 | - (NSString *)description { 103 | NSMutableString *description = [[NSMutableString alloc] initWithString:@"<"]; 104 | 105 | [description appendString:[self.class descriptionForObject:self]]; 106 | 107 | [description appendFormat:@" %@", [self.class descriptionForObject:self.firstItem]]; 108 | if (self.firstAttribute != NSLayoutAttributeNotAnAttribute) { 109 | [description appendFormat:@".%@", self.class.layoutAttributeDescriptionsByValue[@(self.firstAttribute)]]; 110 | } 111 | 112 | [description appendFormat:@" %@", self.class.layoutRelationDescriptionsByValue[@(self.relation)]]; 113 | 114 | if (self.secondItem) { 115 | [description appendFormat:@" %@", [self.class descriptionForObject:self.secondItem]]; 116 | } 117 | if (self.secondAttribute != NSLayoutAttributeNotAnAttribute) { 118 | [description appendFormat:@".%@", self.class.layoutAttributeDescriptionsByValue[@(self.secondAttribute)]]; 119 | } 120 | 121 | if (self.multiplier != 1) { 122 | [description appendFormat:@" * %g", self.multiplier]; 123 | } 124 | 125 | if (self.secondAttribute == NSLayoutAttributeNotAnAttribute) { 126 | [description appendFormat:@" %g", self.constant]; 127 | } else { 128 | if (self.constant) { 129 | [description appendFormat:@" %@ %g", (self.constant < 0 ? @"-" : @"+"), ABS(self.constant)]; 130 | } 131 | } 132 | 133 | if (self.priority != MASLayoutPriorityRequired) { 134 | [description appendFormat:@" ^%@", self.class.layoutPriorityDescriptionsByValue[@(self.priority)] ?: [NSNumber numberWithDouble:self.priority]]; 135 | } 136 | 137 | [description appendString:@">"]; 138 | return description; 139 | } 140 | 141 | @end 142 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/MASUtilities.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASUtilities.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 19/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | 13 | #if TARGET_OS_IPHONE || TARGET_OS_TV 14 | 15 | #import 16 | #define MAS_VIEW UIView 17 | #define MAS_VIEW_CONTROLLER UIViewController 18 | #define MASEdgeInsets UIEdgeInsets 19 | 20 | typedef UILayoutPriority MASLayoutPriority; 21 | static const MASLayoutPriority MASLayoutPriorityRequired = UILayoutPriorityRequired; 22 | static const MASLayoutPriority MASLayoutPriorityDefaultHigh = UILayoutPriorityDefaultHigh; 23 | static const MASLayoutPriority MASLayoutPriorityDefaultMedium = 500; 24 | static const MASLayoutPriority MASLayoutPriorityDefaultLow = UILayoutPriorityDefaultLow; 25 | static const MASLayoutPriority MASLayoutPriorityFittingSizeLevel = UILayoutPriorityFittingSizeLevel; 26 | 27 | #elif TARGET_OS_MAC 28 | 29 | #import 30 | #define MAS_VIEW NSView 31 | #define MASEdgeInsets NSEdgeInsets 32 | 33 | typedef NSLayoutPriority MASLayoutPriority; 34 | static const MASLayoutPriority MASLayoutPriorityRequired = NSLayoutPriorityRequired; 35 | static const MASLayoutPriority MASLayoutPriorityDefaultHigh = NSLayoutPriorityDefaultHigh; 36 | static const MASLayoutPriority MASLayoutPriorityDragThatCanResizeWindow = NSLayoutPriorityDragThatCanResizeWindow; 37 | static const MASLayoutPriority MASLayoutPriorityDefaultMedium = 501; 38 | static const MASLayoutPriority MASLayoutPriorityWindowSizeStayPut = NSLayoutPriorityWindowSizeStayPut; 39 | static const MASLayoutPriority MASLayoutPriorityDragThatCannotResizeWindow = NSLayoutPriorityDragThatCannotResizeWindow; 40 | static const MASLayoutPriority MASLayoutPriorityDefaultLow = NSLayoutPriorityDefaultLow; 41 | static const MASLayoutPriority MASLayoutPriorityFittingSizeCompression = NSLayoutPriorityFittingSizeCompression; 42 | 43 | #endif 44 | 45 | /** 46 | * Allows you to attach keys to objects matching the variable names passed. 47 | * 48 | * view1.mas_key = @"view1", view2.mas_key = @"view2"; 49 | * 50 | * is equivalent to: 51 | * 52 | * MASAttachKeys(view1, view2); 53 | */ 54 | #define MASAttachKeys(...) \ 55 | { \ 56 | NSDictionary *keyPairs = NSDictionaryOfVariableBindings(__VA_ARGS__); \ 57 | for (id key in keyPairs.allKeys) { \ 58 | id obj = keyPairs[key]; \ 59 | NSAssert([obj respondsToSelector:@selector(setMas_key:)], \ 60 | @"Cannot attach mas_key to %@", obj); \ 61 | [obj setMas_key:key]; \ 62 | } \ 63 | } 64 | 65 | /** 66 | * Used to create object hashes 67 | * Based on http://www.mikeash.com/pyblog/friday-qa-2010-06-18-implementing-equality-and-hashing.html 68 | */ 69 | #define MAS_NSUINT_BIT (CHAR_BIT * sizeof(NSUInteger)) 70 | #define MAS_NSUINTROTATE(val, howmuch) ((((NSUInteger)val) << howmuch) | (((NSUInteger)val) >> (MAS_NSUINT_BIT - howmuch))) 71 | 72 | /** 73 | * Given a scalar or struct value, wraps it in NSValue 74 | * Based on EXPObjectify: https://github.com/specta/expecta 75 | */ 76 | static inline id _MASBoxValue(const char *type, ...) { 77 | va_list v; 78 | va_start(v, type); 79 | id obj = nil; 80 | if (strcmp(type, @encode(id)) == 0) { 81 | id actual = va_arg(v, id); 82 | obj = actual; 83 | } else if (strcmp(type, @encode(CGPoint)) == 0) { 84 | CGPoint actual = (CGPoint)va_arg(v, CGPoint); 85 | obj = [NSValue value:&actual withObjCType:type]; 86 | } else if (strcmp(type, @encode(CGSize)) == 0) { 87 | CGSize actual = (CGSize)va_arg(v, CGSize); 88 | obj = [NSValue value:&actual withObjCType:type]; 89 | } else if (strcmp(type, @encode(MASEdgeInsets)) == 0) { 90 | MASEdgeInsets actual = (MASEdgeInsets)va_arg(v, MASEdgeInsets); 91 | obj = [NSValue value:&actual withObjCType:type]; 92 | } else if (strcmp(type, @encode(double)) == 0) { 93 | double actual = (double)va_arg(v, double); 94 | obj = [NSNumber numberWithDouble:actual]; 95 | } else if (strcmp(type, @encode(float)) == 0) { 96 | float actual = (float)va_arg(v, double); 97 | obj = [NSNumber numberWithFloat:actual]; 98 | } else if (strcmp(type, @encode(int)) == 0) { 99 | int actual = (int)va_arg(v, int); 100 | obj = [NSNumber numberWithInt:actual]; 101 | } else if (strcmp(type, @encode(long)) == 0) { 102 | long actual = (long)va_arg(v, long); 103 | obj = [NSNumber numberWithLong:actual]; 104 | } else if (strcmp(type, @encode(long long)) == 0) { 105 | long long actual = (long long)va_arg(v, long long); 106 | obj = [NSNumber numberWithLongLong:actual]; 107 | } else if (strcmp(type, @encode(short)) == 0) { 108 | short actual = (short)va_arg(v, int); 109 | obj = [NSNumber numberWithShort:actual]; 110 | } else if (strcmp(type, @encode(char)) == 0) { 111 | char actual = (char)va_arg(v, int); 112 | obj = [NSNumber numberWithChar:actual]; 113 | } else if (strcmp(type, @encode(bool)) == 0) { 114 | bool actual = (bool)va_arg(v, int); 115 | obj = [NSNumber numberWithBool:actual]; 116 | } else if (strcmp(type, @encode(unsigned char)) == 0) { 117 | unsigned char actual = (unsigned char)va_arg(v, unsigned int); 118 | obj = [NSNumber numberWithUnsignedChar:actual]; 119 | } else if (strcmp(type, @encode(unsigned int)) == 0) { 120 | unsigned int actual = (unsigned int)va_arg(v, unsigned int); 121 | obj = [NSNumber numberWithUnsignedInt:actual]; 122 | } else if (strcmp(type, @encode(unsigned long)) == 0) { 123 | unsigned long actual = (unsigned long)va_arg(v, unsigned long); 124 | obj = [NSNumber numberWithUnsignedLong:actual]; 125 | } else if (strcmp(type, @encode(unsigned long long)) == 0) { 126 | unsigned long long actual = (unsigned long long)va_arg(v, unsigned long long); 127 | obj = [NSNumber numberWithUnsignedLongLong:actual]; 128 | } else if (strcmp(type, @encode(unsigned short)) == 0) { 129 | unsigned short actual = (unsigned short)va_arg(v, unsigned int); 130 | obj = [NSNumber numberWithUnsignedShort:actual]; 131 | } 132 | va_end(v); 133 | return obj; 134 | } 135 | 136 | #define MASBoxValue(value) _MASBoxValue(@encode(__typeof__((value))), (value)) 137 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/NSArray+MASAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+MASAdditions.m 3 | // 4 | // 5 | // Created by Daniel Hammond on 11/26/13. 6 | // 7 | // 8 | 9 | #import "NSArray+MASAdditions.h" 10 | #import "View+MASAdditions.h" 11 | 12 | @implementation NSArray (MASAdditions) 13 | 14 | - (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block { 15 | NSMutableArray *constraints = [NSMutableArray array]; 16 | for (MAS_VIEW *view in self) { 17 | NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views"); 18 | [constraints addObjectsFromArray:[view mas_makeConstraints:block]]; 19 | } 20 | return constraints; 21 | } 22 | 23 | - (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block { 24 | NSMutableArray *constraints = [NSMutableArray array]; 25 | for (MAS_VIEW *view in self) { 26 | NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views"); 27 | [constraints addObjectsFromArray:[view mas_updateConstraints:block]]; 28 | } 29 | return constraints; 30 | } 31 | 32 | - (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block { 33 | NSMutableArray *constraints = [NSMutableArray array]; 34 | for (MAS_VIEW *view in self) { 35 | NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views"); 36 | [constraints addObjectsFromArray:[view mas_remakeConstraints:block]]; 37 | } 38 | return constraints; 39 | } 40 | 41 | - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing { 42 | if (self.count < 2) { 43 | NSAssert(self.count>1,@"views to distribute need to bigger than one"); 44 | return; 45 | } 46 | 47 | MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews]; 48 | if (axisType == MASAxisTypeHorizontal) { 49 | MAS_VIEW *prev; 50 | for (int i = 0; i < self.count; i++) { 51 | MAS_VIEW *v = self[i]; 52 | [v mas_makeConstraints:^(MASConstraintMaker *make) { 53 | if (prev) { 54 | make.width.equalTo(prev); 55 | make.left.equalTo(prev.mas_right).offset(fixedSpacing); 56 | if (i == (CGFloat)self.count - 1) {//last one 57 | make.right.equalTo(tempSuperView).offset(-tailSpacing); 58 | } 59 | } 60 | else {//first one 61 | make.left.equalTo(tempSuperView).offset(leadSpacing); 62 | } 63 | 64 | }]; 65 | prev = v; 66 | } 67 | } 68 | else { 69 | MAS_VIEW *prev; 70 | for (int i = 0; i < self.count; i++) { 71 | MAS_VIEW *v = self[i]; 72 | [v mas_makeConstraints:^(MASConstraintMaker *make) { 73 | if (prev) { 74 | make.height.equalTo(prev); 75 | make.top.equalTo(prev.mas_bottom).offset(fixedSpacing); 76 | if (i == (CGFloat)self.count - 1) {//last one 77 | make.bottom.equalTo(tempSuperView).offset(-tailSpacing); 78 | } 79 | } 80 | else {//first one 81 | make.top.equalTo(tempSuperView).offset(leadSpacing); 82 | } 83 | 84 | }]; 85 | prev = v; 86 | } 87 | } 88 | } 89 | 90 | - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing { 91 | if (self.count < 2) { 92 | NSAssert(self.count>1,@"views to distribute need to bigger than one"); 93 | return; 94 | } 95 | 96 | MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews]; 97 | if (axisType == MASAxisTypeHorizontal) { 98 | MAS_VIEW *prev; 99 | for (int i = 0; i < self.count; i++) { 100 | MAS_VIEW *v = self[i]; 101 | [v mas_makeConstraints:^(MASConstraintMaker *make) { 102 | if (prev) { 103 | CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(fixedItemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1)); 104 | make.width.equalTo(@(fixedItemLength)); 105 | if (i == (CGFloat)self.count - 1) {//last one 106 | make.right.equalTo(tempSuperView).offset(-tailSpacing); 107 | } 108 | else { 109 | make.right.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset); 110 | } 111 | } 112 | else {//first one 113 | make.left.equalTo(tempSuperView).offset(leadSpacing); 114 | make.width.equalTo(@(fixedItemLength)); 115 | } 116 | }]; 117 | prev = v; 118 | } 119 | } 120 | else { 121 | MAS_VIEW *prev; 122 | for (int i = 0; i < self.count; i++) { 123 | MAS_VIEW *v = self[i]; 124 | [v mas_makeConstraints:^(MASConstraintMaker *make) { 125 | if (prev) { 126 | CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(fixedItemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1)); 127 | make.height.equalTo(@(fixedItemLength)); 128 | if (i == (CGFloat)self.count - 1) {//last one 129 | make.bottom.equalTo(tempSuperView).offset(-tailSpacing); 130 | } 131 | else { 132 | make.bottom.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset); 133 | } 134 | } 135 | else {//first one 136 | make.top.equalTo(tempSuperView).offset(leadSpacing); 137 | make.height.equalTo(@(fixedItemLength)); 138 | } 139 | }]; 140 | prev = v; 141 | } 142 | } 143 | } 144 | 145 | - (MAS_VIEW *)mas_commonSuperviewOfViews 146 | { 147 | MAS_VIEW *commonSuperview = nil; 148 | MAS_VIEW *previousView = nil; 149 | for (id object in self) { 150 | if ([object isKindOfClass:[MAS_VIEW class]]) { 151 | MAS_VIEW *view = (MAS_VIEW *)object; 152 | if (previousView) { 153 | commonSuperview = [view mas_closestCommonSuperview:commonSuperview]; 154 | } else { 155 | commonSuperview = view; 156 | } 157 | previousView = view; 158 | } 159 | } 160 | NSAssert(commonSuperview, @"Can't constrain views that do not share a common superview. Make sure that all the views in this array have been added into the same view hierarchy."); 161 | return commonSuperview; 162 | } 163 | 164 | @end 165 | -------------------------------------------------------------------------------- /LGAudioKit/Class/LGSoundPlayer/LGAudioPlayer.m: -------------------------------------------------------------------------------- 1 | // 2 | // LGAudioPlayer.m 3 | // 下载地址:https://github.com/gang544043963/LGAudioKit 4 | // 5 | // Created by ligang on 16/8/20. 6 | // Copyright © 2016年 LG. All rights reserved. 7 | // 8 | 9 | #import "LGAudioPlayer.h" 10 | #import 11 | #import 12 | #import 13 | #include "amrFileCodec.h" 14 | 15 | #pragma clang diagnostic ignored "-Wdeprecated" 16 | 17 | NSString *const kXMNAudioDataKey; 18 | 19 | @interface LGAudioPlayer() 20 | @property (nonatomic, strong) AVAudioPlayer *audioPlayer; 21 | @property (nonatomic, strong) NSOperationQueue *audioDataOperationQueue; 22 | @property (nonatomic, assign) LGAudioPlayerState audioPlayerState; 23 | 24 | @end 25 | 26 | @implementation LGAudioPlayer 27 | 28 | + (void)initialize { 29 | //配置播放器配置 30 | [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error: nil]; 31 | } 32 | 33 | - (instancetype)init { 34 | self = [super init]; 35 | if (self) { 36 | _audioDataOperationQueue = [[NSOperationQueue alloc] init]; 37 | _index = NSUIntegerMax; 38 | } 39 | return self; 40 | } 41 | 42 | + (instancetype)sharePlayer{ 43 | static dispatch_once_t onceToken; 44 | static id shareInstance; 45 | dispatch_once(&onceToken, ^{ 46 | shareInstance = [[self alloc] init]; 47 | }); 48 | return shareInstance; 49 | } 50 | 51 | #pragma mark - Public Methods 52 | 53 | - (void)playAudioWithURLString:(NSString *)URLString atIndex:(NSUInteger)index{ 54 | if (!URLString) { 55 | return; 56 | } 57 | //如果来自同一个URLString并且index相同,则直接取消 58 | if ([self.URLString isEqualToString:URLString] && self.index == index) { 59 | [self stopAudioPlayer]; 60 | [self setAudioPlayerState:LGAudioPlayerStateCancel]; 61 | return; 62 | } 63 | 64 | self.URLString = URLString; 65 | self.index = index; 66 | 67 | NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{ 68 | NSData *audioData = [self audioDataFromURLString:URLString atIndex:index]; 69 | if (!audioData) { 70 | [self setAudioPlayerState:LGAudioPlayerStateCancel]; 71 | return; 72 | } 73 | dispatch_async(dispatch_get_main_queue(), ^{ 74 | [self playAudioWithData:audioData]; 75 | }); 76 | }]; 77 | [_audioDataOperationQueue addOperation:blockOperation]; 78 | } 79 | 80 | - (void)stopAudioPlayer { 81 | if (_audioPlayer) { 82 | _audioPlayer.playing ? [_audioPlayer stop] : nil; 83 | _audioPlayer.delegate = nil; 84 | _audioPlayer = nil; 85 | [[LGAudioPlayer sharePlayer] setAudioPlayerState:LGAudioPlayerStateCancel]; 86 | [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategorySoloAmbient error:nil]; 87 | //恢复外部正在播放的音乐 88 | [[AVAudioSession sharedInstance] setActive:NO 89 | withFlags:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation 90 | error:nil]; 91 | } 92 | } 93 | 94 | - (void)playAudioOnlineWithContentsOfURL:(NSURL *)url{ 95 | [self stopAudioPlayer]; 96 | NSData * data = [[NSData alloc] initWithContentsOfURL:url]; 97 | _audioPlayer = [[AVAudioPlayer alloc] initWithData:data error:nil]; 98 | [_audioPlayer prepareToPlay]; 99 | [_audioPlayer play]; 100 | } 101 | 102 | #pragma mark - Private Methods 103 | - (NSData *)audioDataFromURLString:(NSString *)URLString atIndex:(NSUInteger)index{ 104 | NSData *audioData; 105 | 106 | if ([URLString hasSuffix:@".caf"] || [URLString hasSuffix:@".wav"] || [URLString hasSuffix:@".mp3"]) {//播放本机录制的文件 107 | audioData = [NSData dataWithContentsOfFile:URLString]; 108 | } else if ([URLString hasSuffix:@".amr"]) {//播放安卓发来的AMR文件 109 | audioData = DecodeAMRToWAVE([NSData dataWithContentsOfFile:URLString]); 110 | } else { 111 | NSLog(@"soundFile not support!"); 112 | } 113 | 114 | if (audioData) { 115 | objc_setAssociatedObject(audioData, &kXMNAudioDataKey, [NSString stringWithFormat:@"%@_%ld",URLString,index], OBJC_ASSOCIATION_COPY); 116 | } 117 | 118 | return audioData; 119 | } 120 | 121 | - (void)playAudioWithData:(NSData *)audioData { 122 | [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error: nil]; 123 | NSString *audioURLString = objc_getAssociatedObject(audioData, &kXMNAudioDataKey); 124 | if (![[NSString stringWithFormat:@"%@_%ld",self.URLString,self.index] isEqualToString:audioURLString]) { 125 | return; 126 | } 127 | 128 | NSError *audioPlayerError; 129 | _audioPlayer = [[AVAudioPlayer alloc] initWithData:audioData error:&audioPlayerError]; 130 | if (!_audioPlayer || !audioData) { 131 | [self setAudioPlayerState:LGAudioPlayerStateCancel]; 132 | return; 133 | } 134 | 135 | [[UIDevice currentDevice] setProximityMonitoringEnabled:YES]; 136 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(proximityStateChanged:) name:UIDeviceProximityStateDidChangeNotification object:nil]; 137 | 138 | _audioPlayer.volume = 1.0f; 139 | _audioPlayer.delegate = self; 140 | [_audioPlayer prepareToPlay]; 141 | [self setAudioPlayerState:LGAudioPlayerStatePlaying]; 142 | [_audioPlayer play]; 143 | } 144 | 145 | - (void)cancelOperation { 146 | for (NSOperation *operation in _audioDataOperationQueue.operations) { 147 | [operation cancel]; 148 | break; 149 | } 150 | } 151 | 152 | - (void)proximityStateChanged:(NSNotification *)notification { 153 | if ([[UIDevice currentDevice] proximityState] == YES) { 154 | [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; 155 | }else { 156 | [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; 157 | } 158 | } 159 | 160 | #pragma mark - Setters 161 | 162 | - (void)setURLString:(NSString *)URLString { 163 | if (_URLString) { 164 | //说明当前有正在播放,或者正在加载的视频,取消operation(如果没有在执行任务),停止播放 165 | [self cancelOperation]; 166 | [self stopAudioPlayer]; 167 | [self setAudioPlayerState:LGAudioPlayerStateCancel]; 168 | } 169 | _URLString = [URLString copy]; 170 | } 171 | 172 | - (void)setAudioPlayerState:(LGAudioPlayerState)audioPlayerState{ 173 | _audioPlayerState = audioPlayerState; 174 | if (self.delegate && [self.delegate respondsToSelector:@selector(audioPlayerStateDidChanged:forIndex:)]) { 175 | [self.delegate audioPlayerStateDidChanged:_audioPlayerState forIndex:self.index]; 176 | } 177 | if (_audioPlayerState == LGAudioPlayerStateCancel || _audioPlayerState == LGAudioPlayerStateNormal) { 178 | _URLString = nil; 179 | _index = NSUIntegerMax; 180 | } 181 | } 182 | 183 | #pragma mark - AVAudioPlayerDelegate 184 | 185 | - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag { 186 | [self setAudioPlayerState:LGAudioPlayerStateNormal]; 187 | 188 | //删除近距离事件监听 189 | [[UIDevice currentDevice] setProximityMonitoringEnabled:NO]; 190 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceProximityStateDidChangeNotification object:nil]; 191 | 192 | //延迟一秒将audioPlayer 释放 193 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, .2f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ 194 | [self stopAudioPlayer]; 195 | }); 196 | 197 | } 198 | 199 | @end 200 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/LGTableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // LGTableViewCell.m 3 | // 下载地址:https://github.com/gang544043963/LGAudioKit 4 | // 5 | // Created by ligang on 16/8/20. 6 | // Copyright © 2016年 LG. All rights reserved. 7 | // 8 | 9 | #import "LGTableViewCell.h" 10 | #import "LGCellContentView.h" 11 | #import "Masonry.h" 12 | 13 | @interface LGTableViewCell() 14 | 15 | 16 | @property (nonatomic, strong) UIImageView *headImageView; 17 | 18 | @property (nonatomic, strong) LGCellContentView *msgContentView; 19 | 20 | @property (nonatomic, strong) UIImageView *msgBackGoundImageView; 21 | 22 | @property (nonatomic, strong) UIImageView *messageVoiceStatusImageView; 23 | 24 | @property (nonatomic, strong) UILabel *messageVoiceSecondsLabel; 25 | 26 | 27 | @end 28 | 29 | @implementation LGTableViewCell 30 | 31 | #pragma mark - Override Methods 32 | 33 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 34 | if ([super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 35 | [self setup]; 36 | } 37 | return self; 38 | } 39 | 40 | - (void)updateConstraints { 41 | [self.headImageView mas_makeConstraints:^(MASConstraintMaker *make) { 42 | make.right.equalTo(self.contentView.mas_right).with.offset(-13); 43 | make.top.equalTo(self.contentView.mas_top).with.offset(13); 44 | make.width.equalTo(@40); 45 | make.height.equalTo(@40); 46 | }]; 47 | 48 | [self.msgContentView mas_makeConstraints:^(MASConstraintMaker *make) { 49 | make.right.equalTo(self.headImageView.mas_left).with.offset(-8); 50 | make.top.equalTo(self.headImageView.mas_top); 51 | make.width.lessThanOrEqualTo(@([UIApplication sharedApplication].keyWindow.frame.size.width/5*3)).priorityHigh(); 52 | make.bottom.equalTo(self.headImageView.mas_bottom); 53 | }]; 54 | 55 | [self.messageVoiceStatusImageView mas_makeConstraints:^(MASConstraintMaker *make) { 56 | make.right.equalTo(self.msgContentView.mas_right).with.offset(-20); 57 | make.centerY.equalTo(self.msgContentView.mas_centerY); 58 | make.top.equalTo(self.msgContentView.mas_top).with.offset(11); 59 | make.bottom.equalTo(self.msgContentView.mas_bottom).with.offset(-11); 60 | }]; 61 | 62 | [self.messageVoiceSecondsLabel mas_makeConstraints:^(MASConstraintMaker *make) { 63 | make.right.equalTo(self.msgContentView.mas_left).with.offset(-8); 64 | make.centerY.equalTo(self.msgContentView.mas_centerY); 65 | }]; 66 | 67 | [self.msgBackGoundImageView mas_makeConstraints:^(MASConstraintMaker *make) { 68 | make.edges.equalTo(self.msgContentView); 69 | }]; 70 | 71 | [self.msgContentView mas_updateConstraints:^(MASConstraintMaker *make) { 72 | make.width.equalTo(@(50 + self.soundSeconds * 2.5));//根据时长变化 73 | }]; 74 | 75 | [super updateConstraints]; 76 | } 77 | 78 | #pragma mark - Public Methods 79 | 80 | - (void)configureCellWithData:(LGMessageModel *)messageModel { 81 | self.soundSeconds = messageModel.seconds; 82 | self.messageVoiceSecondsLabel.text = [NSString stringWithFormat:@"%ld''",(long)self.soundSeconds]; 83 | [self setNeedsUpdateConstraints]; 84 | } 85 | 86 | #pragma mark - Private Methods 87 | 88 | - (void)setup { 89 | self.selectionStyle = UITableViewCellSelectionStyleNone; 90 | self.backgroundColor = [UIColor clearColor]; 91 | 92 | [self.contentView addSubview:self.headImageView]; 93 | [self.contentView addSubview:self.msgContentView]; 94 | [self.contentView addSubview:self.messageVoiceSecondsLabel]; 95 | [self.contentView addSubview:self.messageVoiceStatusImageView]; 96 | [self.msgBackGoundImageView setImage:[[UIImage imageNamed:@"bg_chat_me"] resizableImageWithCapInsets:UIEdgeInsetsMake(20, 20, 8, 20) resizingMode:UIImageResizingModeStretch]]; 97 | [self.msgBackGoundImageView setHighlightedImage:[[UIImage imageNamed:@"bg_chat_me"] resizableImageWithCapInsets:UIEdgeInsetsMake(20, 20, 8, 20) resizingMode:UIImageResizingModeStretch]]; 98 | self.msgContentView.layer.mask.contents = (__bridge id _Nullable)(self.msgBackGoundImageView.image.CGImage); 99 | [self.contentView insertSubview:self.msgBackGoundImageView belowSubview:self.msgContentView]; 100 | [self updateConstraintsIfNeeded]; 101 | UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]; 102 | [self.contentView addGestureRecognizer:tap]; 103 | } 104 | 105 | - (void)handleTap:(UITapGestureRecognizer *)tap { 106 | if (_delegate && [_delegate respondsToSelector:@selector(voiceMessageTaped:)]) { 107 | [_delegate voiceMessageTaped:self]; 108 | } 109 | } 110 | 111 | #pragma mark - Setters 112 | 113 | - (void)setVoicePlayState:(LGVoicePlayState)voicePlayState { 114 | if (_voicePlayState != voicePlayState) { 115 | _voicePlayState = voicePlayState; 116 | } 117 | self.messageVoiceSecondsLabel.hidden = NO; 118 | self.messageVoiceStatusImageView.hidden = NO; 119 | 120 | if (_voicePlayState == LGVoicePlayStatePlaying) { 121 | self.messageVoiceStatusImageView.highlighted = YES; 122 | [self.messageVoiceStatusImageView startAnimating]; 123 | }else if (_voicePlayState == LGVoicePlayStateDownloading) { 124 | self.messageVoiceSecondsLabel.hidden = YES; 125 | self.messageVoiceStatusImageView.hidden = YES; 126 | }else { 127 | self.messageVoiceStatusImageView.highlighted = NO; 128 | [self.messageVoiceStatusImageView stopAnimating]; 129 | } 130 | } 131 | 132 | #pragma mark - Getters 133 | 134 | - (UIImageView *)headImageView { 135 | if (!_headImageView) { 136 | _headImageView = [[UIImageView alloc] init]; 137 | _headImageView.layer.cornerRadius = 5.0f; 138 | _headImageView.layer.masksToBounds = YES; 139 | _headImageView.backgroundColor = [UIColor lightGrayColor]; 140 | _headImageView.image = [UIImage imageNamed:@"headImage"]; 141 | } 142 | return _headImageView; 143 | } 144 | 145 | - (LGCellContentView *)msgContentView { 146 | if (!_msgContentView) { 147 | _msgContentView = [[LGCellContentView alloc] init]; 148 | } 149 | return _msgContentView; 150 | } 151 | 152 | - (UIImageView *)msgBackGoundImageView { 153 | if (!_msgBackGoundImageView) { 154 | _msgBackGoundImageView = [[UIImageView alloc] init]; 155 | } 156 | return _msgBackGoundImageView; 157 | } 158 | 159 | - (UIImageView *)messageVoiceStatusImageView { 160 | if (!_messageVoiceStatusImageView) { 161 | _messageVoiceStatusImageView = [[UIImageView alloc] init]; 162 | _messageVoiceStatusImageView.image = [UIImage imageNamed:@"icon_voice_sender_3"] ; 163 | UIImage *image1 = [UIImage imageNamed:@"icon_voice_sender_1"]; 164 | UIImage *image2 = [UIImage imageNamed:@"icon_voice_sender_2"]; 165 | UIImage *image3 = [UIImage imageNamed:@"icon_voice_sender_3"]; 166 | _messageVoiceStatusImageView.highlightedAnimationImages = @[image1,image2,image3]; 167 | _messageVoiceStatusImageView.animationDuration = 1.5f; 168 | _messageVoiceStatusImageView.animationRepeatCount = NSUIntegerMax; 169 | } 170 | return _messageVoiceStatusImageView; 171 | } 172 | 173 | - (UILabel *)messageVoiceSecondsLabel { 174 | if (!_messageVoiceSecondsLabel) { 175 | _messageVoiceSecondsLabel = [[UILabel alloc] init]; 176 | _messageVoiceSecondsLabel.font = [UIFont systemFontOfSize:14.0f]; 177 | _messageVoiceSecondsLabel.text = @"0''"; 178 | } 179 | return _messageVoiceSecondsLabel; 180 | } 181 | 182 | @end 183 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/MASConstraint.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASConstraint.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 22/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | 11 | /** 12 | * Enables Constraints to be created with chainable syntax 13 | * Constraint can represent single NSLayoutConstraint (MASViewConstraint) 14 | * or a group of NSLayoutConstraints (MASComposisteConstraint) 15 | */ 16 | @interface MASConstraint : NSObject 17 | 18 | // Chaining Support 19 | 20 | /** 21 | * Modifies the NSLayoutConstraint constant, 22 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following 23 | * NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight 24 | */ 25 | - (MASConstraint * (^)(MASEdgeInsets insets))insets; 26 | 27 | /** 28 | * Modifies the NSLayoutConstraint constant, 29 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following 30 | * NSLayoutAttributeWidth, NSLayoutAttributeHeight 31 | */ 32 | - (MASConstraint * (^)(CGSize offset))sizeOffset; 33 | 34 | /** 35 | * Modifies the NSLayoutConstraint constant, 36 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following 37 | * NSLayoutAttributeCenterX, NSLayoutAttributeCenterY 38 | */ 39 | - (MASConstraint * (^)(CGPoint offset))centerOffset; 40 | 41 | /** 42 | * Modifies the NSLayoutConstraint constant 43 | */ 44 | - (MASConstraint * (^)(CGFloat offset))offset; 45 | 46 | /** 47 | * Modifies the NSLayoutConstraint constant based on a value type 48 | */ 49 | - (MASConstraint * (^)(NSValue *value))valueOffset; 50 | 51 | /** 52 | * Sets the NSLayoutConstraint multiplier property 53 | */ 54 | - (MASConstraint * (^)(CGFloat multiplier))multipliedBy; 55 | 56 | /** 57 | * Sets the NSLayoutConstraint multiplier to 1.0/dividedBy 58 | */ 59 | - (MASConstraint * (^)(CGFloat divider))dividedBy; 60 | 61 | /** 62 | * Sets the NSLayoutConstraint priority to a float or MASLayoutPriority 63 | */ 64 | - (MASConstraint * (^)(MASLayoutPriority priority))priority; 65 | 66 | /** 67 | * Sets the NSLayoutConstraint priority to MASLayoutPriorityLow 68 | */ 69 | - (MASConstraint * (^)())priorityLow; 70 | 71 | /** 72 | * Sets the NSLayoutConstraint priority to MASLayoutPriorityMedium 73 | */ 74 | - (MASConstraint * (^)())priorityMedium; 75 | 76 | /** 77 | * Sets the NSLayoutConstraint priority to MASLayoutPriorityHigh 78 | */ 79 | - (MASConstraint * (^)())priorityHigh; 80 | 81 | /** 82 | * Sets the constraint relation to NSLayoutRelationEqual 83 | * returns a block which accepts one of the following: 84 | * MASViewAttribute, UIView, NSValue, NSArray 85 | * see readme for more details. 86 | */ 87 | - (MASConstraint * (^)(id attr))equalTo; 88 | 89 | /** 90 | * Sets the constraint relation to NSLayoutRelationGreaterThanOrEqual 91 | * returns a block which accepts one of the following: 92 | * MASViewAttribute, UIView, NSValue, NSArray 93 | * see readme for more details. 94 | */ 95 | - (MASConstraint * (^)(id attr))greaterThanOrEqualTo; 96 | 97 | /** 98 | * Sets the constraint relation to NSLayoutRelationLessThanOrEqual 99 | * returns a block which accepts one of the following: 100 | * MASViewAttribute, UIView, NSValue, NSArray 101 | * see readme for more details. 102 | */ 103 | - (MASConstraint * (^)(id attr))lessThanOrEqualTo; 104 | 105 | /** 106 | * Optional semantic property which has no effect but improves the readability of constraint 107 | */ 108 | - (MASConstraint *)with; 109 | 110 | /** 111 | * Optional semantic property which has no effect but improves the readability of constraint 112 | */ 113 | - (MASConstraint *)and; 114 | 115 | /** 116 | * Creates a new MASCompositeConstraint with the called attribute and reciever 117 | */ 118 | - (MASConstraint *)left; 119 | - (MASConstraint *)top; 120 | - (MASConstraint *)right; 121 | - (MASConstraint *)bottom; 122 | - (MASConstraint *)leading; 123 | - (MASConstraint *)trailing; 124 | - (MASConstraint *)width; 125 | - (MASConstraint *)height; 126 | - (MASConstraint *)centerX; 127 | - (MASConstraint *)centerY; 128 | - (MASConstraint *)baseline; 129 | 130 | #if TARGET_OS_IPHONE || TARGET_OS_TV 131 | 132 | - (MASConstraint *)leftMargin; 133 | - (MASConstraint *)rightMargin; 134 | - (MASConstraint *)topMargin; 135 | - (MASConstraint *)bottomMargin; 136 | - (MASConstraint *)leadingMargin; 137 | - (MASConstraint *)trailingMargin; 138 | - (MASConstraint *)centerXWithinMargins; 139 | - (MASConstraint *)centerYWithinMargins; 140 | 141 | #endif 142 | 143 | 144 | /** 145 | * Sets the constraint debug name 146 | */ 147 | - (MASConstraint * (^)(id key))key; 148 | 149 | // NSLayoutConstraint constant Setters 150 | // for use outside of mas_updateConstraints/mas_makeConstraints blocks 151 | 152 | /** 153 | * Modifies the NSLayoutConstraint constant, 154 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following 155 | * NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight 156 | */ 157 | - (void)setInsets:(MASEdgeInsets)insets; 158 | 159 | /** 160 | * Modifies the NSLayoutConstraint constant, 161 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following 162 | * NSLayoutAttributeWidth, NSLayoutAttributeHeight 163 | */ 164 | - (void)setSizeOffset:(CGSize)sizeOffset; 165 | 166 | /** 167 | * Modifies the NSLayoutConstraint constant, 168 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following 169 | * NSLayoutAttributeCenterX, NSLayoutAttributeCenterY 170 | */ 171 | - (void)setCenterOffset:(CGPoint)centerOffset; 172 | 173 | /** 174 | * Modifies the NSLayoutConstraint constant 175 | */ 176 | - (void)setOffset:(CGFloat)offset; 177 | 178 | 179 | // NSLayoutConstraint Installation support 180 | 181 | #if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV) 182 | /** 183 | * Whether or not to go through the animator proxy when modifying the constraint 184 | */ 185 | @property (nonatomic, copy, readonly) MASConstraint *animator; 186 | #endif 187 | 188 | /** 189 | * Activates an NSLayoutConstraint if it's supported by an OS. 190 | * Invokes install otherwise. 191 | */ 192 | - (void)activate; 193 | 194 | /** 195 | * Deactivates previously installed/activated NSLayoutConstraint. 196 | */ 197 | - (void)deactivate; 198 | 199 | /** 200 | * Creates a NSLayoutConstraint and adds it to the appropriate view. 201 | */ 202 | - (void)install; 203 | 204 | /** 205 | * Removes previously installed NSLayoutConstraint 206 | */ 207 | - (void)uninstall; 208 | 209 | @end 210 | 211 | 212 | /** 213 | * Convenience auto-boxing macros for MASConstraint methods. 214 | * 215 | * Defining MAS_SHORTHAND_GLOBALS will turn on auto-boxing for default syntax. 216 | * A potential drawback of this is that the unprefixed macros will appear in global scope. 217 | */ 218 | #define mas_equalTo(...) equalTo(MASBoxValue((__VA_ARGS__))) 219 | #define mas_greaterThanOrEqualTo(...) greaterThanOrEqualTo(MASBoxValue((__VA_ARGS__))) 220 | #define mas_lessThanOrEqualTo(...) lessThanOrEqualTo(MASBoxValue((__VA_ARGS__))) 221 | 222 | #define mas_offset(...) valueOffset(MASBoxValue((__VA_ARGS__))) 223 | 224 | 225 | #ifdef MAS_SHORTHAND_GLOBALS 226 | 227 | #define equalTo(...) mas_equalTo(__VA_ARGS__) 228 | #define greaterThanOrEqualTo(...) mas_greaterThanOrEqualTo(__VA_ARGS__) 229 | #define lessThanOrEqualTo(...) mas_lessThanOrEqualTo(__VA_ARGS__) 230 | 231 | #define offset(...) mas_offset(__VA_ARGS__) 232 | 233 | #endif 234 | 235 | 236 | @interface MASConstraint (AutoboxingSupport) 237 | 238 | /** 239 | * Aliases to corresponding relation methods (for shorthand macros) 240 | * Also needed to aid autocompletion 241 | */ 242 | - (MASConstraint * (^)(id attr))mas_equalTo; 243 | - (MASConstraint * (^)(id attr))mas_greaterThanOrEqualTo; 244 | - (MASConstraint * (^)(id attr))mas_lessThanOrEqualTo; 245 | 246 | /** 247 | * A dummy method to aid autocompletion 248 | */ 249 | - (MASConstraint * (^)(id offset))mas_offset; 250 | 251 | @end 252 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/MASConstraint.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASConstraint.m 3 | // Masonry 4 | // 5 | // Created by Nick Tymchenko on 1/20/14. 6 | // 7 | 8 | #import "MASConstraint.h" 9 | #import "MASConstraint+Private.h" 10 | 11 | #define MASMethodNotImplemented() \ 12 | @throw [NSException exceptionWithName:NSInternalInconsistencyException \ 13 | reason:[NSString stringWithFormat:@"You must override %@ in a subclass.", NSStringFromSelector(_cmd)] \ 14 | userInfo:nil] 15 | 16 | @implementation MASConstraint 17 | 18 | #pragma mark - Init 19 | 20 | - (id)init { 21 | NSAssert(![self isMemberOfClass:[MASConstraint class]], @"MASConstraint is an abstract class, you should not instantiate it directly."); 22 | return [super init]; 23 | } 24 | 25 | #pragma mark - NSLayoutRelation proxies 26 | 27 | - (MASConstraint * (^)(id))equalTo { 28 | return ^id(id attribute) { 29 | return self.equalToWithRelation(attribute, NSLayoutRelationEqual); 30 | }; 31 | } 32 | 33 | - (MASConstraint * (^)(id))mas_equalTo { 34 | return ^id(id attribute) { 35 | return self.equalToWithRelation(attribute, NSLayoutRelationEqual); 36 | }; 37 | } 38 | 39 | - (MASConstraint * (^)(id))greaterThanOrEqualTo { 40 | return ^id(id attribute) { 41 | return self.equalToWithRelation(attribute, NSLayoutRelationGreaterThanOrEqual); 42 | }; 43 | } 44 | 45 | - (MASConstraint * (^)(id))mas_greaterThanOrEqualTo { 46 | return ^id(id attribute) { 47 | return self.equalToWithRelation(attribute, NSLayoutRelationGreaterThanOrEqual); 48 | }; 49 | } 50 | 51 | - (MASConstraint * (^)(id))lessThanOrEqualTo { 52 | return ^id(id attribute) { 53 | return self.equalToWithRelation(attribute, NSLayoutRelationLessThanOrEqual); 54 | }; 55 | } 56 | 57 | - (MASConstraint * (^)(id))mas_lessThanOrEqualTo { 58 | return ^id(id attribute) { 59 | return self.equalToWithRelation(attribute, NSLayoutRelationLessThanOrEqual); 60 | }; 61 | } 62 | 63 | #pragma mark - MASLayoutPriority proxies 64 | 65 | - (MASConstraint * (^)())priorityLow { 66 | return ^id{ 67 | self.priority(MASLayoutPriorityDefaultLow); 68 | return self; 69 | }; 70 | } 71 | 72 | - (MASConstraint * (^)())priorityMedium { 73 | return ^id{ 74 | self.priority(MASLayoutPriorityDefaultMedium); 75 | return self; 76 | }; 77 | } 78 | 79 | - (MASConstraint * (^)())priorityHigh { 80 | return ^id{ 81 | self.priority(MASLayoutPriorityDefaultHigh); 82 | return self; 83 | }; 84 | } 85 | 86 | #pragma mark - NSLayoutConstraint constant proxies 87 | 88 | - (MASConstraint * (^)(MASEdgeInsets))insets { 89 | return ^id(MASEdgeInsets insets){ 90 | self.insets = insets; 91 | return self; 92 | }; 93 | } 94 | 95 | - (MASConstraint * (^)(CGSize))sizeOffset { 96 | return ^id(CGSize offset) { 97 | self.sizeOffset = offset; 98 | return self; 99 | }; 100 | } 101 | 102 | - (MASConstraint * (^)(CGPoint))centerOffset { 103 | return ^id(CGPoint offset) { 104 | self.centerOffset = offset; 105 | return self; 106 | }; 107 | } 108 | 109 | - (MASConstraint * (^)(CGFloat))offset { 110 | return ^id(CGFloat offset){ 111 | self.offset = offset; 112 | return self; 113 | }; 114 | } 115 | 116 | - (MASConstraint * (^)(NSValue *value))valueOffset { 117 | return ^id(NSValue *offset) { 118 | NSAssert([offset isKindOfClass:NSValue.class], @"expected an NSValue offset, got: %@", offset); 119 | [self setLayoutConstantWithValue:offset]; 120 | return self; 121 | }; 122 | } 123 | 124 | - (MASConstraint * (^)(id offset))mas_offset { 125 | // Will never be called due to macro 126 | return nil; 127 | } 128 | 129 | #pragma mark - NSLayoutConstraint constant setter 130 | 131 | - (void)setLayoutConstantWithValue:(NSValue *)value { 132 | if ([value isKindOfClass:NSNumber.class]) { 133 | self.offset = [(NSNumber *)value doubleValue]; 134 | } else if (strcmp(value.objCType, @encode(CGPoint)) == 0) { 135 | CGPoint point; 136 | [value getValue:&point]; 137 | self.centerOffset = point; 138 | } else if (strcmp(value.objCType, @encode(CGSize)) == 0) { 139 | CGSize size; 140 | [value getValue:&size]; 141 | self.sizeOffset = size; 142 | } else if (strcmp(value.objCType, @encode(MASEdgeInsets)) == 0) { 143 | MASEdgeInsets insets; 144 | [value getValue:&insets]; 145 | self.insets = insets; 146 | } else { 147 | NSAssert(NO, @"attempting to set layout constant with unsupported value: %@", value); 148 | } 149 | } 150 | 151 | #pragma mark - Semantic properties 152 | 153 | - (MASConstraint *)with { 154 | return self; 155 | } 156 | 157 | - (MASConstraint *)and { 158 | return self; 159 | } 160 | 161 | #pragma mark - Chaining 162 | 163 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute __unused)layoutAttribute { 164 | MASMethodNotImplemented(); 165 | } 166 | 167 | - (MASConstraint *)left { 168 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft]; 169 | } 170 | 171 | - (MASConstraint *)top { 172 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTop]; 173 | } 174 | 175 | - (MASConstraint *)right { 176 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRight]; 177 | } 178 | 179 | - (MASConstraint *)bottom { 180 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottom]; 181 | } 182 | 183 | - (MASConstraint *)leading { 184 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeading]; 185 | } 186 | 187 | - (MASConstraint *)trailing { 188 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailing]; 189 | } 190 | 191 | - (MASConstraint *)width { 192 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeWidth]; 193 | } 194 | 195 | - (MASConstraint *)height { 196 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight]; 197 | } 198 | 199 | - (MASConstraint *)centerX { 200 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterX]; 201 | } 202 | 203 | - (MASConstraint *)centerY { 204 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterY]; 205 | } 206 | 207 | - (MASConstraint *)baseline { 208 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBaseline]; 209 | } 210 | 211 | #if TARGET_OS_IPHONE || TARGET_OS_TV 212 | 213 | - (MASConstraint *)leftMargin { 214 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeftMargin]; 215 | } 216 | 217 | - (MASConstraint *)rightMargin { 218 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRightMargin]; 219 | } 220 | 221 | - (MASConstraint *)topMargin { 222 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTopMargin]; 223 | } 224 | 225 | - (MASConstraint *)bottomMargin { 226 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottomMargin]; 227 | } 228 | 229 | - (MASConstraint *)leadingMargin { 230 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeadingMargin]; 231 | } 232 | 233 | - (MASConstraint *)trailingMargin { 234 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailingMargin]; 235 | } 236 | 237 | - (MASConstraint *)centerXWithinMargins { 238 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterXWithinMargins]; 239 | } 240 | 241 | - (MASConstraint *)centerYWithinMargins { 242 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterYWithinMargins]; 243 | } 244 | 245 | #endif 246 | 247 | #pragma mark - Abstract 248 | 249 | - (MASConstraint * (^)(CGFloat multiplier))multipliedBy { MASMethodNotImplemented(); } 250 | 251 | - (MASConstraint * (^)(CGFloat divider))dividedBy { MASMethodNotImplemented(); } 252 | 253 | - (MASConstraint * (^)(MASLayoutPriority priority))priority { MASMethodNotImplemented(); } 254 | 255 | - (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation { MASMethodNotImplemented(); } 256 | 257 | - (MASConstraint * (^)(id key))key { MASMethodNotImplemented(); } 258 | 259 | - (void)setInsets:(MASEdgeInsets __unused)insets { MASMethodNotImplemented(); } 260 | 261 | - (void)setSizeOffset:(CGSize __unused)sizeOffset { MASMethodNotImplemented(); } 262 | 263 | - (void)setCenterOffset:(CGPoint __unused)centerOffset { MASMethodNotImplemented(); } 264 | 265 | - (void)setOffset:(CGFloat __unused)offset { MASMethodNotImplemented(); } 266 | 267 | #if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV) 268 | 269 | - (MASConstraint *)animator { MASMethodNotImplemented(); } 270 | 271 | #endif 272 | 273 | - (void)activate { MASMethodNotImplemented(); } 274 | 275 | - (void)deactivate { MASMethodNotImplemented(); } 276 | 277 | - (void)install { MASMethodNotImplemented(); } 278 | 279 | - (void)uninstall { MASMethodNotImplemented(); } 280 | 281 | @end 282 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/MASConstraintMaker.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASConstraintBuilder.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASConstraintMaker.h" 10 | #import "MASViewConstraint.h" 11 | #import "MASCompositeConstraint.h" 12 | #import "MASConstraint+Private.h" 13 | #import "MASViewAttribute.h" 14 | #import "View+MASAdditions.h" 15 | 16 | @interface MASConstraintMaker () 17 | 18 | @property (nonatomic, weak) MAS_VIEW *view; 19 | @property (nonatomic, strong) NSMutableArray *constraints; 20 | 21 | @end 22 | 23 | @implementation MASConstraintMaker 24 | 25 | - (id)initWithView:(MAS_VIEW *)view { 26 | self = [super init]; 27 | if (!self) return nil; 28 | 29 | self.view = view; 30 | self.constraints = NSMutableArray.new; 31 | 32 | return self; 33 | } 34 | 35 | - (NSArray *)install { 36 | if (self.removeExisting) { 37 | NSArray *installedConstraints = [MASViewConstraint installedConstraintsForView:self.view]; 38 | for (MASConstraint *constraint in installedConstraints) { 39 | [constraint uninstall]; 40 | } 41 | } 42 | NSArray *constraints = self.constraints.copy; 43 | for (MASConstraint *constraint in constraints) { 44 | constraint.updateExisting = self.updateExisting; 45 | [constraint install]; 46 | } 47 | [self.constraints removeAllObjects]; 48 | return constraints; 49 | } 50 | 51 | #pragma mark - MASConstraintDelegate 52 | 53 | - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint { 54 | NSUInteger index = [self.constraints indexOfObject:constraint]; 55 | NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint); 56 | [self.constraints replaceObjectAtIndex:index withObject:replacementConstraint]; 57 | } 58 | 59 | - (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute { 60 | MASViewAttribute *viewAttribute = [[MASViewAttribute alloc] initWithView:self.view layoutAttribute:layoutAttribute]; 61 | MASViewConstraint *newConstraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:viewAttribute]; 62 | if ([constraint isKindOfClass:MASViewConstraint.class]) { 63 | //replace with composite constraint 64 | NSArray *children = @[constraint, newConstraint]; 65 | MASCompositeConstraint *compositeConstraint = [[MASCompositeConstraint alloc] initWithChildren:children]; 66 | compositeConstraint.delegate = self; 67 | [self constraint:constraint shouldBeReplacedWithConstraint:compositeConstraint]; 68 | return compositeConstraint; 69 | } 70 | if (!constraint) { 71 | newConstraint.delegate = self; 72 | [self.constraints addObject:newConstraint]; 73 | } 74 | return newConstraint; 75 | } 76 | 77 | - (MASConstraint *)addConstraintWithAttributes:(MASAttribute)attrs { 78 | __unused MASAttribute anyAttribute = (MASAttributeLeft | MASAttributeRight | MASAttributeTop | MASAttributeBottom | MASAttributeLeading 79 | | MASAttributeTrailing | MASAttributeWidth | MASAttributeHeight | MASAttributeCenterX 80 | | MASAttributeCenterY | MASAttributeBaseline 81 | #if TARGET_OS_IPHONE || TARGET_OS_TV 82 | | MASAttributeLeftMargin | MASAttributeRightMargin | MASAttributeTopMargin | MASAttributeBottomMargin 83 | | MASAttributeLeadingMargin | MASAttributeTrailingMargin | MASAttributeCenterXWithinMargins 84 | | MASAttributeCenterYWithinMargins 85 | #endif 86 | ); 87 | 88 | NSAssert((attrs & anyAttribute) != 0, @"You didn't pass any attribute to make.attributes(...)"); 89 | 90 | NSMutableArray *attributes = [NSMutableArray array]; 91 | 92 | if (attrs & MASAttributeLeft) [attributes addObject:self.view.mas_left]; 93 | if (attrs & MASAttributeRight) [attributes addObject:self.view.mas_right]; 94 | if (attrs & MASAttributeTop) [attributes addObject:self.view.mas_top]; 95 | if (attrs & MASAttributeBottom) [attributes addObject:self.view.mas_bottom]; 96 | if (attrs & MASAttributeLeading) [attributes addObject:self.view.mas_leading]; 97 | if (attrs & MASAttributeTrailing) [attributes addObject:self.view.mas_trailing]; 98 | if (attrs & MASAttributeWidth) [attributes addObject:self.view.mas_width]; 99 | if (attrs & MASAttributeHeight) [attributes addObject:self.view.mas_height]; 100 | if (attrs & MASAttributeCenterX) [attributes addObject:self.view.mas_centerX]; 101 | if (attrs & MASAttributeCenterY) [attributes addObject:self.view.mas_centerY]; 102 | if (attrs & MASAttributeBaseline) [attributes addObject:self.view.mas_baseline]; 103 | 104 | #if TARGET_OS_IPHONE || TARGET_OS_TV 105 | 106 | if (attrs & MASAttributeLeftMargin) [attributes addObject:self.view.mas_leftMargin]; 107 | if (attrs & MASAttributeRightMargin) [attributes addObject:self.view.mas_rightMargin]; 108 | if (attrs & MASAttributeTopMargin) [attributes addObject:self.view.mas_topMargin]; 109 | if (attrs & MASAttributeBottomMargin) [attributes addObject:self.view.mas_bottomMargin]; 110 | if (attrs & MASAttributeLeadingMargin) [attributes addObject:self.view.mas_leadingMargin]; 111 | if (attrs & MASAttributeTrailingMargin) [attributes addObject:self.view.mas_trailingMargin]; 112 | if (attrs & MASAttributeCenterXWithinMargins) [attributes addObject:self.view.mas_centerXWithinMargins]; 113 | if (attrs & MASAttributeCenterYWithinMargins) [attributes addObject:self.view.mas_centerYWithinMargins]; 114 | 115 | #endif 116 | 117 | NSMutableArray *children = [NSMutableArray arrayWithCapacity:attributes.count]; 118 | 119 | for (MASViewAttribute *a in attributes) { 120 | [children addObject:[[MASViewConstraint alloc] initWithFirstViewAttribute:a]]; 121 | } 122 | 123 | MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children]; 124 | constraint.delegate = self; 125 | [self.constraints addObject:constraint]; 126 | return constraint; 127 | } 128 | 129 | #pragma mark - standard Attributes 130 | 131 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute { 132 | return [self constraint:nil addConstraintWithLayoutAttribute:layoutAttribute]; 133 | } 134 | 135 | - (MASConstraint *)left { 136 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft]; 137 | } 138 | 139 | - (MASConstraint *)top { 140 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTop]; 141 | } 142 | 143 | - (MASConstraint *)right { 144 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRight]; 145 | } 146 | 147 | - (MASConstraint *)bottom { 148 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottom]; 149 | } 150 | 151 | - (MASConstraint *)leading { 152 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeading]; 153 | } 154 | 155 | - (MASConstraint *)trailing { 156 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailing]; 157 | } 158 | 159 | - (MASConstraint *)width { 160 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeWidth]; 161 | } 162 | 163 | - (MASConstraint *)height { 164 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight]; 165 | } 166 | 167 | - (MASConstraint *)centerX { 168 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterX]; 169 | } 170 | 171 | - (MASConstraint *)centerY { 172 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterY]; 173 | } 174 | 175 | - (MASConstraint *)baseline { 176 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBaseline]; 177 | } 178 | 179 | - (MASConstraint *(^)(MASAttribute))attributes { 180 | return ^(MASAttribute attrs){ 181 | return [self addConstraintWithAttributes:attrs]; 182 | }; 183 | } 184 | 185 | #if TARGET_OS_IPHONE || TARGET_OS_TV 186 | 187 | - (MASConstraint *)leftMargin { 188 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeftMargin]; 189 | } 190 | 191 | - (MASConstraint *)rightMargin { 192 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRightMargin]; 193 | } 194 | 195 | - (MASConstraint *)topMargin { 196 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTopMargin]; 197 | } 198 | 199 | - (MASConstraint *)bottomMargin { 200 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottomMargin]; 201 | } 202 | 203 | - (MASConstraint *)leadingMargin { 204 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeadingMargin]; 205 | } 206 | 207 | - (MASConstraint *)trailingMargin { 208 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailingMargin]; 209 | } 210 | 211 | - (MASConstraint *)centerXWithinMargins { 212 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterXWithinMargins]; 213 | } 214 | 215 | - (MASConstraint *)centerYWithinMargins { 216 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterYWithinMargins]; 217 | } 218 | 219 | #endif 220 | 221 | 222 | #pragma mark - composite Attributes 223 | 224 | - (MASConstraint *)edges { 225 | return [self addConstraintWithAttributes:MASAttributeTop | MASAttributeLeft | MASAttributeRight | MASAttributeBottom]; 226 | } 227 | 228 | - (MASConstraint *)size { 229 | return [self addConstraintWithAttributes:MASAttributeWidth | MASAttributeHeight]; 230 | } 231 | 232 | - (MASConstraint *)center { 233 | return [self addConstraintWithAttributes:MASAttributeCenterX | MASAttributeCenterY]; 234 | } 235 | 236 | #pragma mark - grouping 237 | 238 | - (MASConstraint *(^)(dispatch_block_t group))group { 239 | return ^id(dispatch_block_t group) { 240 | NSInteger previousCount = self.constraints.count; 241 | group(); 242 | 243 | NSArray *children = [self.constraints subarrayWithRange:NSMakeRange(previousCount, self.constraints.count - previousCount)]; 244 | MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children]; 245 | constraint.delegate = self; 246 | return constraint; 247 | }; 248 | } 249 | 250 | @end 251 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // 下载地址:https://github.com/gang544043963/LGAudioKit 4 | // 5 | // Created by ligang on 16/8/20. 6 | // Copyright © 2016年 LG. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "LGTableViewCell.h" 11 | #import "LGMessageModel.h" 12 | #import "LGAudioKit.h" 13 | #import "Masonry.h" 14 | 15 | #define SOUND_RECORD_LIMIT 60 16 | #define DocumentPath [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] 17 | 18 | @interface ViewController () 19 | 20 | @property (nonatomic, strong) UITableView *chatTableView; 21 | @property (nonatomic, strong) UIButton *recordButton; 22 | @property (nonatomic, weak) NSTimer *timerOf60Second; 23 | @property (nonatomic, strong) NSMutableArray *dataArray; 24 | 25 | @end 26 | 27 | @implementation ViewController 28 | 29 | #pragma mark - Life Circle 30 | 31 | - (void)viewDidLoad { 32 | [super viewDidLoad]; 33 | _dataArray = [NSMutableArray arrayWithCapacity:0]; 34 | [LGAudioPlayer sharePlayer].delegate = self; 35 | self.view.backgroundColor = [UIColor brownColor]; 36 | [self initTableView]; 37 | [self initButton]; 38 | } 39 | 40 | - (void)didReceiveMemoryWarning { 41 | [super didReceiveMemoryWarning]; 42 | // Dispose of any resources that can be recreated. 43 | } 44 | 45 | - (void)updateViewConstraints { 46 | [_chatTableView mas_makeConstraints:^(MASConstraintMaker *make) { 47 | make.top.equalTo(self.view.mas_top).with.offset(20); 48 | make.left.equalTo(self.view.mas_left).with.offset(10); 49 | make.right.equalTo(self.view.mas_right).with.offset(-10); 50 | make.bottom.equalTo(self.view.mas_bottom).with.offset(-70); 51 | }]; 52 | [super updateViewConstraints]; 53 | } 54 | 55 | #pragma mark - Initialize 56 | 57 | - (void)initTableView { 58 | _chatTableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain]; 59 | _chatTableView.separatorStyle = UITableViewCellSeparatorStyleNone; 60 | _chatTableView.delegate = self; 61 | _chatTableView.dataSource = self; 62 | _chatTableView.backgroundColor = [UIColor whiteColor]; 63 | _chatTableView.layer.cornerRadius = 5; 64 | _chatTableView.layer.masksToBounds = YES; 65 | _chatTableView.tableHeaderView = nil; 66 | [self.view addSubview:_chatTableView]; 67 | } 68 | 69 | - (void)initButton { 70 | _recordButton = [UIButton buttonWithType:UIButtonTypeCustom]; 71 | [_recordButton setBackgroundImage:[[UIImage imageNamed:@"btn_chatbar_press_normal" ] resizableImageWithCapInsets:UIEdgeInsetsMake(10, 10, 10, 10) resizingMode:UIImageResizingModeStretch] forState:UIControlStateNormal]; 72 | [_recordButton setBackgroundImage:[[UIImage imageNamed:@"btn_chatbar_press_selected"] resizableImageWithCapInsets:UIEdgeInsetsMake(10, 10, 10, 10) resizingMode:UIImageResizingModeStretch] forState:UIControlStateSelected]; 73 | _recordButton.titleLabel.font = [UIFont systemFontOfSize:14.0f]; 74 | [_recordButton setTitle:@"按住录音" forState:UIControlStateNormal]; 75 | [_recordButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; 76 | [_recordButton addTarget:self action:@selector(startRecordVoice) forControlEvents:UIControlEventTouchDown]; 77 | [_recordButton addTarget:self action:@selector(cancelRecordVoice) forControlEvents:UIControlEventTouchUpOutside]; 78 | [_recordButton addTarget:self action:@selector(confirmRecordVoice) forControlEvents:UIControlEventTouchUpInside]; 79 | [_recordButton addTarget:self action:@selector(updateCancelRecordVoice) forControlEvents:UIControlEventTouchDragExit]; 80 | [_recordButton addTarget:self action:@selector(updateContinueRecordVoice) forControlEvents:UIControlEventTouchDragEnter]; 81 | 82 | [_recordButton setFrame:CGRectMake(10, self.view.frame.size.height - 60, self.view.frame.size.width - 20, 50)]; 83 | [self.view addSubview:_recordButton]; 84 | } 85 | 86 | #pragma mark - Private Methods 87 | 88 | /** 89 | * 开始录音 90 | */ 91 | - (void)startRecordVoice{ 92 | __block BOOL isAllow = 0; 93 | AVAudioSession *audioSession = [AVAudioSession sharedInstance]; 94 | if ([audioSession respondsToSelector:@selector(requestRecordPermission:)]) { 95 | [audioSession performSelector:@selector(requestRecordPermission:) withObject:^(BOOL granted) { 96 | if (granted) { 97 | isAllow = 1; 98 | } else { 99 | isAllow = 0; 100 | } 101 | }]; 102 | } 103 | if (isAllow) { 104 | //停止播放 105 | [[LGAudioPlayer sharePlayer] stopAudioPlayer]; 106 | //开始录音 107 | [[LGSoundRecorder shareInstance] startSoundRecord:self.view recordPath:[self recordPath]]; 108 | //开启定时器 109 | if (_timerOf60Second) { 110 | [_timerOf60Second invalidate]; 111 | _timerOf60Second = nil; 112 | } 113 | _timerOf60Second = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(sixtyTimeStopAndSendVedio) userInfo:nil repeats:YES]; 114 | } else { 115 | 116 | } 117 | } 118 | 119 | /** 120 | * 录音结束 121 | */ 122 | - (void)confirmRecordVoice { 123 | if ([[LGSoundRecorder shareInstance] soundRecordTime] == 0) { 124 | [self cancelRecordVoice]; 125 | return;//60s自动发送后,松开手走这里 126 | } 127 | if ([[LGSoundRecorder shareInstance] soundRecordTime] < 1.0f) { 128 | if (_timerOf60Second) { 129 | [_timerOf60Second invalidate]; 130 | _timerOf60Second = nil; 131 | } 132 | [self showShotTimeSign]; 133 | return; 134 | } 135 | 136 | [self sendSound]; 137 | [[LGSoundRecorder shareInstance] stopSoundRecord:self.view]; 138 | 139 | if (_timerOf60Second) { 140 | [_timerOf60Second invalidate]; 141 | _timerOf60Second = nil; 142 | } 143 | } 144 | 145 | /** 146 | * 更新录音显示状态,手指向上滑动后 提示松开取消录音 147 | */ 148 | - (void)updateCancelRecordVoice { 149 | [[LGSoundRecorder shareInstance] readyCancelSound]; 150 | } 151 | 152 | /** 153 | * 更新录音状态,手指重新滑动到范围内,提示向上取消录音 154 | */ 155 | - (void)updateContinueRecordVoice { 156 | [[LGSoundRecorder shareInstance] resetNormalRecord]; 157 | } 158 | 159 | /** 160 | * 取消录音 161 | */ 162 | - (void)cancelRecordVoice { 163 | [[LGSoundRecorder shareInstance] soundRecordFailed:self.view]; 164 | } 165 | 166 | /** 167 | * 录音时间短 168 | */ 169 | - (void)showShotTimeSign { 170 | [[LGSoundRecorder shareInstance] showShotTimeSign:self.view]; 171 | } 172 | 173 | - (void)sixtyTimeStopAndSendVedio { 174 | int countDown = SOUND_RECORD_LIMIT - [[LGSoundRecorder shareInstance] soundRecordTime]; 175 | NSLog(@"countDown is %d soundRecordTime is %f",countDown,[[LGSoundRecorder shareInstance] soundRecordTime]); 176 | if (countDown <= 10) { 177 | [[LGSoundRecorder shareInstance] showCountdown:countDown]; 178 | } 179 | if ([[LGSoundRecorder shareInstance] soundRecordTime] >= SOUND_RECORD_LIMIT && [[LGSoundRecorder shareInstance] soundRecordTime] <= SOUND_RECORD_LIMIT + 1) { 180 | 181 | if (_timerOf60Second) { 182 | [_timerOf60Second invalidate]; 183 | _timerOf60Second = nil; 184 | } 185 | [self.recordButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 186 | } 187 | } 188 | 189 | /** 190 | * 语音文件存储路径 191 | * 192 | * @return 路径 193 | */ 194 | - (NSString *)recordPath { 195 | NSString *filePath = [DocumentPath stringByAppendingPathComponent:@"SoundFile"]; 196 | if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) { 197 | NSError *error = nil; 198 | [[NSFileManager defaultManager] createDirectoryAtPath:filePath withIntermediateDirectories:NO attributes:nil error:&error]; 199 | if (error) { 200 | NSLog(@"%@", error); 201 | } 202 | } 203 | return filePath; 204 | } 205 | 206 | - (void)sendSound { 207 | LGMessageModel *messageModel = [[LGMessageModel alloc] init]; 208 | messageModel.soundFilePath = [[LGSoundRecorder shareInstance] soundFilePath]; 209 | messageModel.seconds = [[LGSoundRecorder shareInstance] soundRecordTime]; 210 | [self.dataArray addObject:messageModel]; 211 | [self.chatTableView reloadData]; 212 | } 213 | 214 | #pragma mark - LGSoundRecorderDelegate 215 | 216 | - (void)showSoundRecordFailed{ 217 | // [[SoundRecorder shareInstance] soundRecordFailed:self]; 218 | if (_timerOf60Second) { 219 | [_timerOf60Second invalidate]; 220 | _timerOf60Second = nil; 221 | } 222 | } 223 | 224 | - (void)didStopSoundRecord { 225 | 226 | } 227 | 228 | #pragma mark - LGAudioPlayerDelegate 229 | 230 | - (void)audioPlayerStateDidChanged:(LGAudioPlayerState)audioPlayerState forIndex:(NSUInteger)index { 231 | NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0]; 232 | LGTableViewCell *voiceMessageCell = [_chatTableView cellForRowAtIndexPath:indexPath]; 233 | LGVoicePlayState voicePlayState; 234 | switch (audioPlayerState) { 235 | case LGAudioPlayerStateNormal: 236 | voicePlayState = LGVoicePlayStateNormal; 237 | break; 238 | case LGAudioPlayerStatePlaying: 239 | voicePlayState = LGVoicePlayStatePlaying; 240 | break; 241 | case LGAudioPlayerStateCancel: 242 | voicePlayState = LGVoicePlayStateCancel; 243 | break; 244 | 245 | default: 246 | break; 247 | } 248 | dispatch_async(dispatch_get_main_queue(), ^{ 249 | [voiceMessageCell setVoicePlayState:voicePlayState]; 250 | }); 251 | } 252 | 253 | #pragma mark - LGTableViewCellDelegate 254 | 255 | - (void)voiceMessageTaped:(LGTableViewCell *)cell { 256 | [cell setVoicePlayState:LGVoicePlayStatePlaying]; 257 | 258 | NSIndexPath *indexPath = [_chatTableView indexPathForCell:cell]; 259 | LGMessageModel *messageModel = [self.dataArray objectAtIndex:indexPath.row]; 260 | [[LGAudioPlayer sharePlayer] playAudioWithURLString:messageModel.soundFilePath atIndex:indexPath.row]; 261 | } 262 | 263 | #pragma mark - UITableViewDataSource 264 | 265 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 266 | return 1; 267 | } 268 | 269 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 270 | return self.dataArray.count; 271 | } 272 | 273 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 274 | LGTableViewCell *cell = [[LGTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil]; 275 | cell.delegate = self; 276 | LGMessageModel *messageModel = [self.dataArray objectAtIndex:indexPath.row]; 277 | [cell configureCellWithData:messageModel]; 278 | return cell; 279 | } 280 | 281 | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 282 | UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 60, self.view.frame.size.width, 60)]; 283 | textView.backgroundColor = [UIColor redColor]; 284 | textView.text = @"欢迎使用本框架\n\n如果在使用过程中遇到问题请及时提issue\n博客:http://blog.csdn.net/gang544043963"; 285 | textView.textAlignment = NSTextAlignmentCenter; 286 | textView.font = [UIFont fontWithName:@"MarkerFelt-Thin" size:14]; 287 | return textView; 288 | } 289 | 290 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 291 | return 100; 292 | } 293 | 294 | #pragma mark - UITableViewDelegate 295 | 296 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 297 | return 66; 298 | } 299 | 300 | @end 301 | -------------------------------------------------------------------------------- /LGAudioKit/Class/LGSoundRecorder/LGSoundRecorder.m: -------------------------------------------------------------------------------- 1 | // 2 | // LGSoundRecorder.m 3 | // 下载地址:https://github.com/gang544043963/LGAudioKit 4 | // 5 | // Created by ligang on 16/8/20. 6 | // Copyright © 2016年 LG. All rights reserved. 7 | // 8 | 9 | #import "LGSoundRecorder.h" 10 | #include "amrFileCodec.h" 11 | 12 | #pragma clang diagnostic ignored "-Wdeprecated" 13 | 14 | #define GetImage(imageName) [UIImage imageNamed:imageName] 15 | 16 | @interface LGSoundRecorder() 17 | 18 | @property (nonatomic, strong) UIView *HUD; 19 | @property (nonatomic, strong) NSString *recordPath; 20 | @property (nonatomic, strong) AVAudioRecorder *recorder; 21 | @property (nonatomic, strong) NSTimer *levelTimer; 22 | //Views 23 | @property (nonatomic, strong) UIImageView *imageViewAnimation; 24 | @property (nonatomic, strong) UIImageView *talkPhone; 25 | @property (nonatomic, strong) UIImageView *cancelTalk; 26 | @property (nonatomic, strong) UIImageView *shotTime; 27 | @property (nonatomic, strong) UILabel *textLable; 28 | @property (nonatomic, strong) UILabel *countDownLabel; 29 | 30 | @end 31 | 32 | @implementation LGSoundRecorder 33 | 34 | 35 | + (LGSoundRecorder *)shareInstance { 36 | static LGSoundRecorder *sharedInstance = nil; 37 | static dispatch_once_t oncePredicate; 38 | dispatch_once(&oncePredicate, ^{ 39 | if (sharedInstance == nil) { 40 | sharedInstance = [[LGSoundRecorder alloc] init]; 41 | } 42 | }); 43 | return sharedInstance; 44 | } 45 | 46 | #pragma mark - Public Methods 47 | 48 | - (void)startSoundRecord:(UIView *)view recordPath:(NSString *)path { 49 | self.recordPath = path; 50 | [self initHUBViewWithView:view]; 51 | [self startRecord]; 52 | } 53 | 54 | - (void)stopSoundRecord:(UIView *)view { 55 | if (self.levelTimer) { 56 | [self.levelTimer invalidate]; 57 | self.levelTimer = nil; 58 | } 59 | 60 | NSString *str = [NSString stringWithFormat:@"%f",_recorder.currentTime]; 61 | 62 | int times = [str intValue]; 63 | if (self.recorder) { 64 | [self.recorder stop]; 65 | } 66 | 67 | if (view == nil) { 68 | view = [[[UIApplication sharedApplication] windows] lastObject]; 69 | } 70 | if ([view isKindOfClass:[UIWindow class]]) { 71 | [view addSubview:_HUD]; 72 | } else { 73 | [view.window addSubview:_HUD]; 74 | } 75 | 76 | if (times >= 1) { 77 | if (_delegate&&[_delegate respondsToSelector:@selector(didStopSoundRecord)]) { 78 | [_delegate didStopSoundRecord]; 79 | } 80 | [self removeHUD]; 81 | } else { 82 | if (self.recorder) { 83 | [self.recorder deleteRecording]; 84 | } 85 | if ([_delegate respondsToSelector:@selector(showSoundRecordFailed)]) { 86 | [_delegate showSoundRecordFailed]; 87 | } 88 | [self performSelector:@selector(removeHUD) withObject:nil afterDelay:0.8f]; 89 | } 90 | [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategorySoloAmbient error:nil]; 91 | //恢复外部正在播放的音乐 92 | [[AVAudioSession sharedInstance] setActive:NO 93 | withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation 94 | error:nil]; 95 | } 96 | 97 | - (void)soundRecordFailed:(UIView *)view { 98 | if (self.levelTimer) { 99 | [self.levelTimer invalidate]; 100 | self.levelTimer = nil; 101 | } 102 | [self.recorder stop]; 103 | [self removeHUD]; 104 | [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategorySoloAmbient error:nil]; 105 | //恢复外部正在播放的音乐 106 | [[AVAudioSession sharedInstance] setActive:NO 107 | withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation 108 | error:nil]; 109 | } 110 | 111 | - (void)readyCancelSound { 112 | _imageViewAnimation.hidden = YES; 113 | _talkPhone.hidden = YES; 114 | _cancelTalk.hidden = NO; 115 | _shotTime.hidden = YES; 116 | _countDownLabel.hidden = YES; 117 | 118 | _textLable.frame = CGRectMake(0, CGRectGetMaxY(_imageViewAnimation.frame) + 20, 130, 25); 119 | _textLable.text = @"手指松开,取消发送"; 120 | _textLable.backgroundColor = [UIColor redColor]; 121 | _textLable.layer.masksToBounds = YES; 122 | _textLable.layer.cornerRadius = 3; 123 | } 124 | 125 | - (void)resetNormalRecord { 126 | _imageViewAnimation.hidden = NO; 127 | _talkPhone.hidden = NO; 128 | _cancelTalk.hidden = YES; 129 | _shotTime.hidden = YES; 130 | _countDownLabel.hidden = YES; 131 | _textLable.frame = CGRectMake(0, CGRectGetMaxY(_imageViewAnimation.frame) + 20, 130, 25); 132 | _textLable.text = @"手指上滑,取消发送"; 133 | _textLable.backgroundColor = [UIColor clearColor]; 134 | } 135 | 136 | - (void)showShotTimeSign:(UIView *)view { 137 | _imageViewAnimation.hidden = YES; 138 | _talkPhone.hidden = YES; 139 | _cancelTalk.hidden = YES; 140 | _shotTime.hidden = NO; 141 | _countDownLabel.hidden = YES; 142 | [_textLable setFrame:CGRectMake(0, 100, 130, 25)]; 143 | _textLable.text = @"说话时间太短"; 144 | _textLable.backgroundColor = [UIColor clearColor]; 145 | 146 | [self stopSoundRecord:view]; 147 | } 148 | 149 | - (void)showCountdown:(int)countDown{ 150 | _textLable.text = [NSString stringWithFormat:@"还可以说%d秒",countDown]; 151 | } 152 | 153 | - (NSTimeInterval)soundRecordTime { 154 | return _recorder.currentTime; 155 | } 156 | 157 | #pragma mark - Private Methods 158 | 159 | - (void)initHUBViewWithView:(UIView *)view { 160 | if (_HUD) { 161 | [_HUD removeFromSuperview]; 162 | _HUD = nil; 163 | } 164 | if (view == nil) { 165 | view = [[[UIApplication sharedApplication] windows] lastObject]; 166 | } 167 | if (_HUD == nil) { 168 | CGFloat hubWidth = 180; 169 | CGFloat hubHeight = 160; 170 | CGFloat hubX = (view.frame.size.width - hubWidth) / 2; 171 | CGFloat hubY = (view.frame.size.height - hubHeight) / 2; 172 | CGFloat cvWidth = 130; 173 | CGFloat cvHeight = 120; 174 | CGFloat cvX = (hubWidth - cvWidth) / 2; 175 | CGFloat cvY = (hubHeight - cvHeight) / 2; 176 | 177 | _HUD = [[UIView alloc] initWithFrame:CGRectMake(hubX, hubY, hubWidth, hubHeight)]; 178 | _HUD.backgroundColor = [[UIColor alloc] initWithRed:0 green:0 blue:0 alpha:0.38]; 179 | _HUD.layer.cornerRadius = 12; 180 | _HUD.layer.masksToBounds = true; 181 | 182 | CGFloat left = 22; 183 | CGFloat top = 0; 184 | top = 18; 185 | 186 | UIView *cv = [[UIView alloc] initWithFrame:CGRectMake(cvX, cvY, cvWidth, cvHeight)]; 187 | 188 | UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(left, top, 37, 70)]; 189 | _talkPhone = imageView; 190 | _talkPhone.image = GetImage(@"toast_microphone"); 191 | [cv addSubview:_talkPhone]; 192 | left += CGRectGetWidth(_talkPhone.frame) + 16; 193 | 194 | top+=7; 195 | imageView = [[UIImageView alloc] initWithFrame:CGRectMake(left, top, 29, 64)]; 196 | _imageViewAnimation = imageView; 197 | [cv addSubview:_imageViewAnimation]; 198 | 199 | imageView = [[UIImageView alloc] initWithFrame:CGRectMake(30, 24, 52, 61)]; 200 | _cancelTalk = imageView; 201 | _cancelTalk.image = GetImage(@"toast_cancelsend"); 202 | [cv addSubview:_cancelTalk]; 203 | _cancelTalk.hidden = YES; 204 | 205 | imageView = [[UIImageView alloc] initWithFrame:CGRectMake(56, 24, 18, 60)]; 206 | self.shotTime = imageView; 207 | _shotTime.image = GetImage(@"toast_timeshort"); 208 | [cv addSubview:_shotTime]; 209 | _shotTime.hidden = YES; 210 | 211 | UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(30, 14, 70, 71)]; 212 | self.countDownLabel = label; 213 | self.countDownLabel.backgroundColor = [UIColor clearColor]; 214 | self.countDownLabel.textColor = [UIColor whiteColor]; 215 | self.countDownLabel.textAlignment = NSTextAlignmentCenter; 216 | self.countDownLabel.font = [UIFont systemFontOfSize:60.0]; 217 | [cv addSubview:self.countDownLabel]; 218 | self.countDownLabel.hidden = YES; 219 | 220 | left = 0; 221 | top += CGRectGetHeight(_imageViewAnimation.frame) + 20; 222 | 223 | label = [[UILabel alloc] initWithFrame:CGRectMake(left, top, 130, 14)]; 224 | self.textLable = label; 225 | _textLable.backgroundColor = [UIColor clearColor]; 226 | _textLable.textColor = [UIColor whiteColor]; 227 | _textLable.textAlignment = NSTextAlignmentCenter; 228 | _textLable.font = [UIFont systemFontOfSize:14.0]; 229 | _textLable.text = @"手指上滑,取消发送"; 230 | [cv addSubview:_textLable]; 231 | 232 | [_HUD addSubview:cv]; 233 | } 234 | if ([view isKindOfClass:[UIWindow class]]) { 235 | [view addSubview:_HUD]; 236 | } else { 237 | [view.window addSubview:_HUD]; 238 | } 239 | } 240 | 241 | - (void)removeHUD { 242 | if (_HUD) { 243 | [_HUD removeFromSuperview]; 244 | _HUD = nil; 245 | } 246 | } 247 | 248 | - (void)startRecord { 249 | AVAudioSession *audioSession = [AVAudioSession sharedInstance]; 250 | NSError *err = nil; 251 | //设置AVAudioSession 252 | [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&err]; 253 | if(err) { 254 | [self soundRecordFailed:nil]; 255 | return; 256 | } 257 | 258 | //设置录音输入源 259 | UInt32 doChangeDefaultRoute = 1; 260 | AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof (doChangeDefaultRoute), &doChangeDefaultRoute); 261 | [audioSession setActive:YES error:&err]; 262 | if(err) { 263 | [self soundRecordFailed:nil]; 264 | return; 265 | } 266 | //设置文件保存路径和名称 267 | NSString *fileName = [NSString stringWithFormat:@"/voice-%5.2f.caf", [[NSDate date] timeIntervalSince1970] ]; 268 | self.recordPath = [self.recordPath stringByAppendingPathComponent:fileName]; 269 | NSURL *recordedFile = [NSURL fileURLWithPath:self.recordPath]; 270 | NSDictionary *dic = [self recordingSettings]; 271 | //初始化AVAudioRecorder 272 | err = nil; 273 | _recorder = [[AVAudioRecorder alloc] initWithURL:recordedFile settings:dic error:&err]; 274 | if(_recorder == nil) { 275 | [self soundRecordFailed:nil]; 276 | return; 277 | } 278 | //准备和开始录音 279 | [_recorder prepareToRecord]; 280 | self.recorder.meteringEnabled = YES; 281 | [self.recorder record]; 282 | [_recorder recordForDuration:0]; 283 | if (self.levelTimer) { 284 | [self.levelTimer invalidate]; 285 | self.levelTimer = nil; 286 | } 287 | self.levelTimer = [NSTimer scheduledTimerWithTimeInterval: 0.0001 target: self selector: @selector(levelTimerCallback:) userInfo: nil repeats: YES]; 288 | } 289 | 290 | - (void)levelTimerCallback:(NSTimer *)timer { 291 | if (_recorder&&_imageViewAnimation) { 292 | [_recorder updateMeters]; 293 | double ff = [_recorder averagePowerForChannel:0]; 294 | ff = ff+60; 295 | if (ff>0&&ff<=10) { 296 | [_imageViewAnimation setImage:GetImage(@"toast_vol_0")]; 297 | } else if (ff>10 && ff<20) { 298 | [_imageViewAnimation setImage:GetImage(@"toast_vol_1")]; 299 | } else if (ff >=20 &&ff<30) { 300 | [_imageViewAnimation setImage:GetImage(@"toast_vol_2")]; 301 | } else if (ff >=30 &&ff<40) { 302 | [_imageViewAnimation setImage:GetImage(@"toast_vol_3")]; 303 | } else if (ff >=40 &&ff<50) { 304 | [_imageViewAnimation setImage:GetImage(@"toast_vol_4")]; 305 | } else if (ff >= 50 && ff < 60) { 306 | [_imageViewAnimation setImage:GetImage(@"toast_vol_5")]; 307 | } else if (ff >= 60 && ff < 70) { 308 | [_imageViewAnimation setImage:GetImage(@"toast_vol_6")]; 309 | } else { 310 | [_imageViewAnimation setImage:GetImage(@"toast_vol_7")]; 311 | } 312 | } 313 | } 314 | 315 | #pragma mark - Getters 316 | 317 | - (NSDictionary *)recordingSettings 318 | { 319 | NSMutableDictionary *recordSetting =[NSMutableDictionary dictionaryWithCapacity:10]; 320 | [recordSetting setObject:[NSNumber numberWithInt: kAudioFormatLinearPCM] forKey: AVFormatIDKey]; 321 | //2 采样率 322 | [recordSetting setObject:[NSNumber numberWithFloat:8000.0] forKey: AVSampleRateKey]; 323 | //3 通道的数目 324 | [recordSetting setObject:[NSNumber numberWithInt:1]forKey:AVNumberOfChannelsKey]; 325 | //4 采样位数 默认 16 326 | [recordSetting setObject:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey]; 327 | return recordSetting; 328 | } 329 | 330 | - (NSString *)soundFilePath { 331 | return self.recordPath; 332 | } 333 | 334 | #pragma mark - amr转换方法 335 | 336 | - (NSData *)convertCAFtoAMR:(NSString *)fielPath { 337 | NSData *data = [NSData dataWithContentsOfFile:fielPath]; 338 | data = EncodeWAVEToAMR(data,1,16); 339 | return data; 340 | } 341 | 342 | @end 343 | 344 | -------------------------------------------------------------------------------- /LGAudioKit/Demo/Masonry/MASViewConstraint.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASConstraint.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASViewConstraint.h" 10 | #import "MASConstraint+Private.h" 11 | #import "MASCompositeConstraint.h" 12 | #import "MASLayoutConstraint.h" 13 | #import "View+MASAdditions.h" 14 | #import 15 | 16 | @interface MAS_VIEW (MASConstraints) 17 | 18 | @property (nonatomic, readonly) NSMutableSet *mas_installedConstraints; 19 | 20 | @end 21 | 22 | @implementation MAS_VIEW (MASConstraints) 23 | 24 | static char kInstalledConstraintsKey; 25 | 26 | - (NSMutableSet *)mas_installedConstraints { 27 | NSMutableSet *constraints = objc_getAssociatedObject(self, &kInstalledConstraintsKey); 28 | if (!constraints) { 29 | constraints = [NSMutableSet set]; 30 | objc_setAssociatedObject(self, &kInstalledConstraintsKey, constraints, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 31 | } 32 | return constraints; 33 | } 34 | 35 | @end 36 | 37 | 38 | @interface MASViewConstraint () 39 | 40 | @property (nonatomic, strong, readwrite) MASViewAttribute *secondViewAttribute; 41 | @property (nonatomic, weak) MAS_VIEW *installedView; 42 | @property (nonatomic, weak) MASLayoutConstraint *layoutConstraint; 43 | @property (nonatomic, assign) NSLayoutRelation layoutRelation; 44 | @property (nonatomic, assign) MASLayoutPriority layoutPriority; 45 | @property (nonatomic, assign) CGFloat layoutMultiplier; 46 | @property (nonatomic, assign) CGFloat layoutConstant; 47 | @property (nonatomic, assign) BOOL hasLayoutRelation; 48 | @property (nonatomic, strong) id mas_key; 49 | @property (nonatomic, assign) BOOL useAnimator; 50 | 51 | @end 52 | 53 | @implementation MASViewConstraint 54 | 55 | - (id)initWithFirstViewAttribute:(MASViewAttribute *)firstViewAttribute { 56 | self = [super init]; 57 | if (!self) return nil; 58 | 59 | _firstViewAttribute = firstViewAttribute; 60 | self.layoutPriority = MASLayoutPriorityRequired; 61 | self.layoutMultiplier = 1; 62 | 63 | return self; 64 | } 65 | 66 | #pragma mark - NSCoping 67 | 68 | - (id)copyWithZone:(NSZone __unused *)zone { 69 | MASViewConstraint *constraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:self.firstViewAttribute]; 70 | constraint.layoutConstant = self.layoutConstant; 71 | constraint.layoutRelation = self.layoutRelation; 72 | constraint.layoutPriority = self.layoutPriority; 73 | constraint.layoutMultiplier = self.layoutMultiplier; 74 | constraint.delegate = self.delegate; 75 | return constraint; 76 | } 77 | 78 | #pragma mark - Public 79 | 80 | + (NSArray *)installedConstraintsForView:(MAS_VIEW *)view { 81 | return [view.mas_installedConstraints allObjects]; 82 | } 83 | 84 | #pragma mark - Private 85 | 86 | - (void)setLayoutConstant:(CGFloat)layoutConstant { 87 | _layoutConstant = layoutConstant; 88 | 89 | #if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV) 90 | if (self.useAnimator) { 91 | [self.layoutConstraint.animator setConstant:layoutConstant]; 92 | } else { 93 | self.layoutConstraint.constant = layoutConstant; 94 | } 95 | #else 96 | self.layoutConstraint.constant = layoutConstant; 97 | #endif 98 | } 99 | 100 | - (void)setLayoutRelation:(NSLayoutRelation)layoutRelation { 101 | _layoutRelation = layoutRelation; 102 | self.hasLayoutRelation = YES; 103 | } 104 | 105 | - (BOOL)supportsActiveProperty { 106 | return [self.layoutConstraint respondsToSelector:@selector(isActive)]; 107 | } 108 | 109 | - (BOOL)isActive { 110 | BOOL active = YES; 111 | if ([self supportsActiveProperty]) { 112 | active = [self.layoutConstraint isActive]; 113 | } 114 | 115 | return active; 116 | } 117 | 118 | - (BOOL)hasBeenInstalled { 119 | return (self.layoutConstraint != nil) && [self isActive]; 120 | } 121 | 122 | - (void)setSecondViewAttribute:(id)secondViewAttribute { 123 | if ([secondViewAttribute isKindOfClass:NSValue.class]) { 124 | [self setLayoutConstantWithValue:secondViewAttribute]; 125 | } else if ([secondViewAttribute isKindOfClass:MAS_VIEW.class]) { 126 | _secondViewAttribute = [[MASViewAttribute alloc] initWithView:secondViewAttribute layoutAttribute:self.firstViewAttribute.layoutAttribute]; 127 | } else if ([secondViewAttribute isKindOfClass:MASViewAttribute.class]) { 128 | _secondViewAttribute = secondViewAttribute; 129 | } else { 130 | NSAssert(NO, @"attempting to add unsupported attribute: %@", secondViewAttribute); 131 | } 132 | } 133 | 134 | #pragma mark - NSLayoutConstraint multiplier proxies 135 | 136 | - (MASConstraint * (^)(CGFloat))multipliedBy { 137 | return ^id(CGFloat multiplier) { 138 | NSAssert(!self.hasBeenInstalled, 139 | @"Cannot modify constraint multiplier after it has been installed"); 140 | 141 | self.layoutMultiplier = multiplier; 142 | return self; 143 | }; 144 | } 145 | 146 | 147 | - (MASConstraint * (^)(CGFloat))dividedBy { 148 | return ^id(CGFloat divider) { 149 | NSAssert(!self.hasBeenInstalled, 150 | @"Cannot modify constraint multiplier after it has been installed"); 151 | 152 | self.layoutMultiplier = 1.0/divider; 153 | return self; 154 | }; 155 | } 156 | 157 | #pragma mark - MASLayoutPriority proxy 158 | 159 | - (MASConstraint * (^)(MASLayoutPriority))priority { 160 | return ^id(MASLayoutPriority priority) { 161 | NSAssert(!self.hasBeenInstalled, 162 | @"Cannot modify constraint priority after it has been installed"); 163 | 164 | self.layoutPriority = priority; 165 | return self; 166 | }; 167 | } 168 | 169 | #pragma mark - NSLayoutRelation proxy 170 | 171 | - (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation { 172 | return ^id(id attribute, NSLayoutRelation relation) { 173 | if ([attribute isKindOfClass:NSArray.class]) { 174 | NSAssert(!self.hasLayoutRelation, @"Redefinition of constraint relation"); 175 | NSMutableArray *children = NSMutableArray.new; 176 | for (id attr in attribute) { 177 | MASViewConstraint *viewConstraint = [self copy]; 178 | viewConstraint.secondViewAttribute = attr; 179 | [children addObject:viewConstraint]; 180 | } 181 | MASCompositeConstraint *compositeConstraint = [[MASCompositeConstraint alloc] initWithChildren:children]; 182 | compositeConstraint.delegate = self.delegate; 183 | [self.delegate constraint:self shouldBeReplacedWithConstraint:compositeConstraint]; 184 | return compositeConstraint; 185 | } else { 186 | NSAssert(!self.hasLayoutRelation || self.layoutRelation == relation && [attribute isKindOfClass:NSValue.class], @"Redefinition of constraint relation"); 187 | self.layoutRelation = relation; 188 | self.secondViewAttribute = attribute; 189 | return self; 190 | } 191 | }; 192 | } 193 | 194 | #pragma mark - Semantic properties 195 | 196 | - (MASConstraint *)with { 197 | return self; 198 | } 199 | 200 | - (MASConstraint *)and { 201 | return self; 202 | } 203 | 204 | #pragma mark - attribute chaining 205 | 206 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute { 207 | NSAssert(!self.hasLayoutRelation, @"Attributes should be chained before defining the constraint relation"); 208 | 209 | return [self.delegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute]; 210 | } 211 | 212 | #pragma mark - Animator proxy 213 | 214 | #if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV) 215 | 216 | - (MASConstraint *)animator { 217 | self.useAnimator = YES; 218 | return self; 219 | } 220 | 221 | #endif 222 | 223 | #pragma mark - debug helpers 224 | 225 | - (MASConstraint * (^)(id))key { 226 | return ^id(id key) { 227 | self.mas_key = key; 228 | return self; 229 | }; 230 | } 231 | 232 | #pragma mark - NSLayoutConstraint constant setters 233 | 234 | - (void)setInsets:(MASEdgeInsets)insets { 235 | NSLayoutAttribute layoutAttribute = self.firstViewAttribute.layoutAttribute; 236 | switch (layoutAttribute) { 237 | case NSLayoutAttributeLeft: 238 | case NSLayoutAttributeLeading: 239 | self.layoutConstant = insets.left; 240 | break; 241 | case NSLayoutAttributeTop: 242 | self.layoutConstant = insets.top; 243 | break; 244 | case NSLayoutAttributeBottom: 245 | self.layoutConstant = -insets.bottom; 246 | break; 247 | case NSLayoutAttributeRight: 248 | case NSLayoutAttributeTrailing: 249 | self.layoutConstant = -insets.right; 250 | break; 251 | default: 252 | break; 253 | } 254 | } 255 | 256 | - (void)setOffset:(CGFloat)offset { 257 | self.layoutConstant = offset; 258 | } 259 | 260 | - (void)setSizeOffset:(CGSize)sizeOffset { 261 | NSLayoutAttribute layoutAttribute = self.firstViewAttribute.layoutAttribute; 262 | switch (layoutAttribute) { 263 | case NSLayoutAttributeWidth: 264 | self.layoutConstant = sizeOffset.width; 265 | break; 266 | case NSLayoutAttributeHeight: 267 | self.layoutConstant = sizeOffset.height; 268 | break; 269 | default: 270 | break; 271 | } 272 | } 273 | 274 | - (void)setCenterOffset:(CGPoint)centerOffset { 275 | NSLayoutAttribute layoutAttribute = self.firstViewAttribute.layoutAttribute; 276 | switch (layoutAttribute) { 277 | case NSLayoutAttributeCenterX: 278 | self.layoutConstant = centerOffset.x; 279 | break; 280 | case NSLayoutAttributeCenterY: 281 | self.layoutConstant = centerOffset.y; 282 | break; 283 | default: 284 | break; 285 | } 286 | } 287 | 288 | #pragma mark - MASConstraint 289 | 290 | - (void)activate { 291 | if ([self supportsActiveProperty] && self.layoutConstraint) { 292 | if (self.hasBeenInstalled) { 293 | return; 294 | } 295 | self.layoutConstraint.active = YES; 296 | [self.firstViewAttribute.view.mas_installedConstraints addObject:self]; 297 | } else { 298 | [self install]; 299 | } 300 | } 301 | 302 | - (void)deactivate { 303 | if ([self supportsActiveProperty]) { 304 | self.layoutConstraint.active = NO; 305 | [self.firstViewAttribute.view.mas_installedConstraints removeObject:self]; 306 | } else { 307 | [self uninstall]; 308 | } 309 | } 310 | 311 | - (void)install { 312 | if (self.hasBeenInstalled) { 313 | return; 314 | } 315 | 316 | MAS_VIEW *firstLayoutItem = self.firstViewAttribute.item; 317 | NSLayoutAttribute firstLayoutAttribute = self.firstViewAttribute.layoutAttribute; 318 | MAS_VIEW *secondLayoutItem = self.secondViewAttribute.item; 319 | NSLayoutAttribute secondLayoutAttribute = self.secondViewAttribute.layoutAttribute; 320 | 321 | // alignment attributes must have a secondViewAttribute 322 | // therefore we assume that is refering to superview 323 | // eg make.left.equalTo(@10) 324 | if (!self.firstViewAttribute.isSizeAttribute && !self.secondViewAttribute) { 325 | secondLayoutItem = self.firstViewAttribute.view.superview; 326 | secondLayoutAttribute = firstLayoutAttribute; 327 | } 328 | 329 | MASLayoutConstraint *layoutConstraint 330 | = [MASLayoutConstraint constraintWithItem:firstLayoutItem 331 | attribute:firstLayoutAttribute 332 | relatedBy:self.layoutRelation 333 | toItem:secondLayoutItem 334 | attribute:secondLayoutAttribute 335 | multiplier:self.layoutMultiplier 336 | constant:self.layoutConstant]; 337 | 338 | layoutConstraint.priority = self.layoutPriority; 339 | layoutConstraint.mas_key = self.mas_key; 340 | 341 | if (self.secondViewAttribute.view) { 342 | MAS_VIEW *closestCommonSuperview = [self.firstViewAttribute.view mas_closestCommonSuperview:self.secondViewAttribute.view]; 343 | NSAssert(closestCommonSuperview, 344 | @"couldn't find a common superview for %@ and %@", 345 | self.firstViewAttribute.view, self.secondViewAttribute.view); 346 | self.installedView = closestCommonSuperview; 347 | } else if (self.firstViewAttribute.isSizeAttribute) { 348 | self.installedView = self.firstViewAttribute.view; 349 | } else { 350 | self.installedView = self.firstViewAttribute.view.superview; 351 | } 352 | 353 | 354 | MASLayoutConstraint *existingConstraint = nil; 355 | if (self.updateExisting) { 356 | existingConstraint = [self layoutConstraintSimilarTo:layoutConstraint]; 357 | } 358 | if (existingConstraint) { 359 | // just update the constant 360 | existingConstraint.constant = layoutConstraint.constant; 361 | self.layoutConstraint = existingConstraint; 362 | } else { 363 | [self.installedView addConstraint:layoutConstraint]; 364 | self.layoutConstraint = layoutConstraint; 365 | [firstLayoutItem.mas_installedConstraints addObject:self]; 366 | } 367 | } 368 | 369 | - (MASLayoutConstraint *)layoutConstraintSimilarTo:(MASLayoutConstraint *)layoutConstraint { 370 | // check if any constraints are the same apart from the only mutable property constant 371 | 372 | // go through constraints in reverse as we do not want to match auto-resizing or interface builder constraints 373 | // and they are likely to be added first. 374 | for (NSLayoutConstraint *existingConstraint in self.installedView.constraints.reverseObjectEnumerator) { 375 | if (![existingConstraint isKindOfClass:MASLayoutConstraint.class]) continue; 376 | if (existingConstraint.firstItem != layoutConstraint.firstItem) continue; 377 | if (existingConstraint.secondItem != layoutConstraint.secondItem) continue; 378 | if (existingConstraint.firstAttribute != layoutConstraint.firstAttribute) continue; 379 | if (existingConstraint.secondAttribute != layoutConstraint.secondAttribute) continue; 380 | if (existingConstraint.relation != layoutConstraint.relation) continue; 381 | if (existingConstraint.multiplier != layoutConstraint.multiplier) continue; 382 | if (existingConstraint.priority != layoutConstraint.priority) continue; 383 | 384 | return (id)existingConstraint; 385 | } 386 | return nil; 387 | } 388 | 389 | - (void)uninstall { 390 | [self.installedView removeConstraint:self.layoutConstraint]; 391 | self.layoutConstraint = nil; 392 | self.installedView = nil; 393 | 394 | [self.firstViewAttribute.view.mas_installedConstraints removeObject:self]; 395 | } 396 | 397 | @end 398 | -------------------------------------------------------------------------------- /LGAudioKit/Class/Vendor/AMR/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 | 11 | typedef unsigned long long u64; 12 | typedef long long s64; 13 | typedef unsigned int u32; 14 | typedef unsigned short u16; 15 | typedef unsigned char u8; 16 | int amrEncodeMode[] = {4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200}; // amr 编码方式 17 | 18 | u16 readUInt16(char* bis) { 19 | u16 result = 0; 20 | result += ((u16)(bis[0])) << 8; 21 | result += (u8)(bis[1]); 22 | return result; 23 | } 24 | 25 | u32 readUint32(char* bis) { 26 | u32 result = 0; 27 | result += ((u32) readUInt16(bis)) << 16; 28 | bis+=2; 29 | result += readUInt16(bis); 30 | return result; 31 | } 32 | 33 | s64 readSint64(char* bis) { 34 | s64 result = 0; 35 | result += ((u64) readUint32(bis)) << 32; 36 | bis+=4; 37 | result += readUint32(bis); 38 | return result; 39 | } 40 | 41 | NSData * fuckAndroid3GP(NSData *data) { 42 | //http://android.amberfog.com/?p=181 43 | u32 size = 0; 44 | u32 type =0; 45 | u32 boxSize =0; 46 | //char HEADER_TYPE[] = {'f', 't', 'y', 'p'}; 47 | 48 | char AMR_MAGIC_HEADER[6] = {0x23, 0x21, 0x41, 0x4d, 0x52, 0x0a}; 49 | 50 | u32 brand =0; 51 | u32 minorVersion=0; 52 | //u32 *compatibleBrands; 53 | 54 | if (data.length<50) { 55 | NSLog(@"not android 3gp"); 56 | return data; 57 | } 58 | char *bis = (char *)[data bytes]; 59 | 60 | size = readUint32(bis); 61 | boxSize += 4; 62 | bis+=4; 63 | type = readUint32(bis); 64 | boxSize += 4; 65 | bis+=4; 66 | if (type!=0x66747970) { 67 | NSLog(@"not android 3gp"); 68 | return data; 69 | } 70 | 71 | brand = readUint32(bis); 72 | boxSize += 4; 73 | bis+=4; 74 | minorVersion = readUint32(bis); 75 | boxSize += 4; 76 | bis+=4; 77 | int remainSize = (int)(size - boxSize); 78 | if (remainSize > 0) { 79 | //compatibleBrands = new u32[remainSize / 4]; 80 | for (int i = 0; i < remainSize / 4; i++) { 81 | //compatibleBrands[i] = 82 | readUint32(bis); 83 | bis+=4; 84 | } 85 | } 86 | 87 | boxSize = 0; 88 | size = readUint32(bis); 89 | boxSize += 4; 90 | bis+=4; 91 | type = readUint32(bis); 92 | boxSize += 4; 93 | bis+=4; 94 | 95 | int rawAmrDataLength=(size - boxSize); 96 | int fullAmrDataLength = 6 + rawAmrDataLength; 97 | //char* amrData = new char[fullAmrDataLength]; 98 | NSMutableData *amrData = [[NSMutableData alloc]initWithCapacity:fullAmrDataLength]; 99 | //memcpy(amrData,AMR_MAGIC_HEADER,6); 100 | //memcpy(amrData+6,bis,rawAmrDataLength); 101 | [amrData appendBytes:AMR_MAGIC_HEADER length:6]; 102 | [amrData appendBytes:bis length:rawAmrDataLength]; 103 | 104 | return amrData; 105 | } 106 | 107 | 108 | #pragma mark - Decode 109 | //decode 110 | 111 | const int myround(const double x) 112 | { 113 | return((int)(x+0.5)); 114 | } 115 | 116 | // 根据帧头计算当前帧大小 117 | int caclAMRFrameSize(unsigned char frameHeader) 118 | { 119 | int mode; 120 | int temp1 = 0; 121 | int temp2 = 0; 122 | int frameSize; 123 | 124 | temp1 = frameHeader; 125 | 126 | // 编码方式编号 = 帧头的3-6位 127 | temp1 &= 0x78; // 0111-1000 128 | temp1 >>= 3; 129 | 130 | mode = amrEncodeMode[temp1]; 131 | 132 | // 计算amr音频数据帧大小 133 | // 原理: amr 一帧对应20ms,那么一秒有50帧的音频数据 134 | temp2 = myround((double)(((double)mode / (double)AMR_FRAME_COUNT_PER_SECOND) / (double)8)); 135 | 136 | frameSize = myround((double)temp2 + 0.5); 137 | return frameSize; 138 | } 139 | 140 | // 读第一个帧 - (参考帧) 141 | // 返回值: 0-出错; 1-正确 142 | int ReadAMRFrameFirstData(char* fpamr,int pos,int maxLen, unsigned char frameBuffer[], int* stdFrameSize, unsigned char* stdFrameHeader) 143 | { 144 | int nPos = 0; 145 | memset(frameBuffer, 0, sizeof(frameBuffer)); 146 | 147 | // 先读帧头 148 | //fread(stdFrameHeader, 1, sizeof(unsigned char), fpamr); 149 | stdFrameHeader[0] = fpamr[pos];nPos++; 150 | if (pos+nPos >= maxLen) { 151 | return 0; 152 | } 153 | //if (feof(fpamr)) return 0; 154 | 155 | // 根据帧头计算帧大小 156 | *stdFrameSize = caclAMRFrameSize(*stdFrameHeader); 157 | 158 | // 读首帧 159 | frameBuffer[0] = *stdFrameHeader; 160 | if ((*stdFrameSize-1)*sizeof(unsigned char)<=0) { 161 | return 0; 162 | } 163 | 164 | memcpy(&(frameBuffer[1]), fpamr+pos+nPos, (*stdFrameSize-1)*sizeof(unsigned char)); 165 | //fread(&(frameBuffer[1]), 1, (*stdFrameSize-1)*sizeof(unsigned char), fpamr); 166 | //if (feof(fpamr)) return 0; 167 | nPos += (*stdFrameSize-1)*sizeof(unsigned char); 168 | if (pos+nPos >= maxLen) { 169 | return 0; 170 | } 171 | 172 | return nPos; 173 | } 174 | 175 | // 返回值: 0-出错; 1-正确 176 | int ReadAMRFrameData(char* fpamr,int pos,int maxLen, unsigned char frameBuffer[], int stdFrameSize, unsigned char stdFrameHeader) 177 | { 178 | int bytes = 0; 179 | int nPos = 0; 180 | unsigned char frameHeader; // 帧头 181 | 182 | memset(frameBuffer, 0, sizeof(frameBuffer)); 183 | 184 | // 读帧头 185 | // 如果是坏帧(不是标准帧头),则继续读下一个字节,直到读到标准帧头 186 | while(1) 187 | { 188 | //bytes = fread(&frameHeader, 1, sizeof(unsigned char), fpamr); 189 | //if (feof(fpamr)) return 0; 190 | if (pos+nPos >=maxLen) { 191 | return 0; 192 | } 193 | frameHeader = fpamr[pos+nPos]; nPos++; 194 | if (frameHeader == stdFrameHeader) break; 195 | } 196 | 197 | // 读该帧的语音数据(帧头已经读过) 198 | frameBuffer[0] = frameHeader; 199 | //bytes = fread(&(frameBuffer[1]), 1, (stdFrameSize-1)*sizeof(unsigned char), fpamr); 200 | //if (feof(fpamr)) return 0; 201 | if ((stdFrameSize-1)*sizeof(unsigned char)<=0) { 202 | return 0; 203 | } 204 | memcpy(&(frameBuffer[1]), fpamr+pos+nPos, (stdFrameSize-1)*sizeof(unsigned char)); 205 | nPos += (stdFrameSize-1)*sizeof(unsigned char); 206 | if (pos+nPos >= maxLen) { 207 | return 0; 208 | } 209 | 210 | return nPos; 211 | } 212 | 213 | void WriteWAVEHeader(NSMutableData* fpwave, int nFrame) 214 | { 215 | char tag[10] = ""; 216 | 217 | // 1. 写RIFF头 218 | RIFFHEADER riff; 219 | strcpy(tag, "RIFF"); 220 | memcpy(riff.chRiffID, tag, 4); 221 | riff.nRiffSize = 4 // WAVE 222 | + sizeof(XCHUNKHEADER) // fmt 223 | + sizeof(WAVEFORMATX) // WAVEFORMATX 224 | + sizeof(XCHUNKHEADER) // DATA 225 | + nFrame*160*sizeof(short); // 226 | strcpy(tag, "WAVE"); 227 | memcpy(riff.chRiffFormat, tag, 4); 228 | //fwrite(&riff, 1, sizeof(RIFFHEADER), fpwave); 229 | [fpwave appendBytes:&riff length:sizeof(RIFFHEADER)]; 230 | 231 | // 2. 写FMT块 232 | XCHUNKHEADER chunk; 233 | WAVEFORMATX wfx; 234 | strcpy(tag, "fmt "); 235 | memcpy(chunk.chChunkID, tag, 4); 236 | chunk.nChunkSize = sizeof(WAVEFORMATX); 237 | //fwrite(&chunk, 1, sizeof(XCHUNKHEADER), fpwave); 238 | [fpwave appendBytes:&chunk length:sizeof(XCHUNKHEADER)]; 239 | memset(&wfx, 0, sizeof(WAVEFORMATX)); 240 | wfx.nFormatTag = 1; 241 | wfx.nChannels = 1; // 单声道 242 | wfx.nSamplesPerSec = 8000; // 8khz 243 | wfx.nAvgBytesPerSec = 16000; 244 | wfx.nBlockAlign = 2; 245 | wfx.nBitsPerSample = 16; // 16位 246 | //fwrite(&wfx, 1, sizeof(WAVEFORMATX), fpwave); 247 | [fpwave appendBytes:&wfx length:sizeof(WAVEFORMATX)]; 248 | 249 | // 3. 写data块头 250 | strcpy(tag, "data"); 251 | memcpy(chunk.chChunkID, tag, 4); 252 | chunk.nChunkSize = nFrame*160*sizeof(short); 253 | //fwrite(&chunk, 1, sizeof(XCHUNKHEADER), fpwave); 254 | [fpwave appendBytes:&chunk length:sizeof(XCHUNKHEADER)]; 255 | 256 | } 257 | 258 | NSData* DecodeAMRToWAVE(NSData* data) { 259 | NSMutableData* fpwave = nil; 260 | void * destate; 261 | int nFrameCount = 0; 262 | int stdFrameSize; 263 | int nTemp; 264 | char bErr = 0; 265 | unsigned char stdFrameHeader; 266 | 267 | unsigned char amrFrame[MAX_AMR_FRAME_SIZE]; 268 | short pcmFrame[PCM_FRAME_SIZE]; 269 | 270 | if (data.length<=0) { 271 | return nil; 272 | } 273 | 274 | const char* rfile = [data bytes]; 275 | int maxLen = [data length]; 276 | int pos = 0; 277 | 278 | //有可能是android 3gp格式 279 | if (strncmp(rfile, AMR_MAGIC_NUMBER, strlen(AMR_MAGIC_NUMBER))) 280 | { 281 | data = fuckAndroid3GP(data); 282 | } 283 | 284 | rfile = [data bytes]; 285 | // 检查amr文件头 286 | if (strncmp(rfile, AMR_MAGIC_NUMBER, strlen(AMR_MAGIC_NUMBER))) 287 | { 288 | return nil; 289 | } 290 | 291 | pos += strlen(AMR_MAGIC_NUMBER); 292 | // 创建并初始化WAVE文件 293 | 294 | fpwave = [[NSMutableData alloc]init]; 295 | //WriteWAVEHeader(fpwave, nFrameCount); 296 | 297 | /* init decoder */ 298 | destate = Decoder_Interface_init(); 299 | 300 | // 读第一帧 - 作为参考帧 301 | memset(amrFrame, 0, sizeof(amrFrame)); 302 | memset(pcmFrame, 0, sizeof(pcmFrame)); 303 | //ReadAMRFrameFirst(fpamr, amrFrame, &stdFrameSize, &stdFrameHeader); 304 | 305 | nTemp = ReadAMRFrameFirstData(rfile,pos,maxLen, amrFrame, &stdFrameSize, &stdFrameHeader); 306 | if (nTemp==0) { 307 | Decoder_Interface_exit(destate); 308 | return data; 309 | } 310 | pos += nTemp; 311 | 312 | // 解码一个AMR音频帧成PCM数据 313 | Decoder_Interface_Decode(destate, amrFrame, pcmFrame, 0); 314 | nFrameCount++; 315 | //fwrite(pcmFrame, sizeof(short), PCM_FRAME_SIZE, fpwave); 316 | [fpwave appendBytes:pcmFrame length:PCM_FRAME_SIZE*sizeof(short)]; 317 | 318 | 319 | // 逐帧解码AMR并写到WAVE文件里 320 | while(1) 321 | { 322 | memset(amrFrame, 0, sizeof(amrFrame)); 323 | memset(pcmFrame, 0, sizeof(pcmFrame)); 324 | //if (!ReadAMRFrame(fpamr, amrFrame, stdFrameSize, stdFrameHeader)) break; 325 | nTemp = ReadAMRFrameData(rfile,pos,maxLen, amrFrame, stdFrameSize, stdFrameHeader); 326 | if (!nTemp) {bErr = 1;break;} 327 | pos += nTemp; 328 | 329 | // 解码一个AMR音频帧成PCM数据 (8k-16b-单声道) 330 | Decoder_Interface_Decode(destate, amrFrame, pcmFrame, 0); 331 | nFrameCount++; 332 | //fwrite(pcmFrame, sizeof(short), PCM_FRAME_SIZE, fpwave); 333 | [fpwave appendBytes:pcmFrame length:PCM_FRAME_SIZE*sizeof(short)]; 334 | } 335 | Decoder_Interface_exit(destate); 336 | 337 | //fclose(fpwave); 338 | 339 | // 重写WAVE文件头 340 | //fpwave = fopen([docFilePath cStringUsingEncoding:NSASCIIStringEncoding], "r+"); 341 | //if (!bErr) { 342 | 343 | NSMutableData *out = [[NSMutableData alloc]init]; 344 | WriteWAVEHeader(out, nFrameCount); 345 | [out appendData:fpwave]; 346 | //fclose(fpwave); 347 | return out; 348 | //} 349 | 350 | // return data; 351 | } 352 | 353 | 354 | #pragma mark Encode 355 | // 从WAVE文件读一个完整的PCM音频帧 356 | // 返回值: 0-错误 >0: 完整帧大小 357 | int ReadPCMFrameData(short speech[], char* fpwave, int nChannels, int nBitsPerSample) 358 | { 359 | int nRead = 0; 360 | int x = 0, y=0; 361 | 362 | // 原始PCM音频帧数据 363 | unsigned char pcmFrame_8b1[PCM_FRAME_SIZE]; 364 | unsigned char pcmFrame_8b2[PCM_FRAME_SIZE<<1]; 365 | unsigned short pcmFrame_16b1[PCM_FRAME_SIZE]; 366 | unsigned short pcmFrame_16b2[PCM_FRAME_SIZE<<1]; 367 | 368 | nRead = (nBitsPerSample/8) * PCM_FRAME_SIZE*nChannels; 369 | if (nBitsPerSample==8 && nChannels==1) 370 | { 371 | //nRead = fread(pcmFrame_8b1, (nBitsPerSample/8), PCM_FRAME_SIZE*nChannels, fpwave); 372 | memcpy(pcmFrame_8b1,fpwave,nRead); 373 | for(x=0; x> 1; 394 | //speech[y] = (short)((short)ush << 7); 395 | } 396 | } 397 | else 398 | if (nBitsPerSample==16 && nChannels==1) 399 | { 400 | //nRead = fread(pcmFrame_16b1, (nBitsPerSample/8), PCM_FRAME_SIZE*nChannels, fpwave); 401 | memcpy(pcmFrame_16b1,fpwave,nRead); 402 | 403 | for(x=0; x> 1; 418 | } 419 | } 420 | 421 | // 如果读到的数据不是一个完整的PCM帧, 就返回0 422 | return nRead; 423 | } 424 | 425 | // WAVE音频采样频率是8khz 426 | // 音频样本单元数 = 8000*0.02 = 160 (由采样频率决定) 427 | // 声道数 1 : 160 428 | // 2 : 160*2 = 320 429 | // bps决定样本(sample)大小 430 | // bps = 8 --> 8位 unsigned char 431 | // 16 --> 16位 unsigned short 432 | NSData* EncodePCMToAMR(char* data, int maxLen,int nChannels, int nBitsPerSample) 433 | { 434 | char* oldBuf = data; 435 | /* input speech vector */ 436 | short speech[160]; 437 | 438 | /* counters */ 439 | int byte_counter, frames = 0, bytes = 0; 440 | 441 | /* pointer to encoder state structure */ 442 | void *enstate; 443 | 444 | /* requested mode */ 445 | enum Mode req_mode = MR122; 446 | int dtx = 0; 447 | 448 | /* bitstream filetype */ 449 | unsigned char amrFrame[MAX_AMR_FRAME_SIZE]; 450 | 451 | NSMutableData* out = [[NSMutableData alloc]init]; 452 | /* write magic number to indicate single channel AMR file storage format */ 453 | //bytes = fwrite(AMR_MAGIC_NUMBER, sizeof(char), strlen(AMR_MAGIC_NUMBER), fpamr); 454 | [out appendBytes:AMR_MAGIC_NUMBER length:strlen(AMR_MAGIC_NUMBER)]; 455 | 456 | /* skip to pcm audio data*/ 457 | //SkipToPCMAudioData(fpwave); 458 | 459 | enstate = Encoder_Interface_init(dtx); 460 | 461 | while(1) 462 | { 463 | // read one pcm frame 464 | if ((data-oldBuf+320)>maxLen) { 465 | break; 466 | } 467 | int nRead = ReadPCMFrameData(speech, data, nChannels, nBitsPerSample); 468 | data += nRead; 469 | 470 | 471 | frames++; 472 | 473 | /* call encoder */ 474 | byte_counter = Encoder_Interface_Encode(enstate, req_mode, speech, amrFrame, 0); 475 | 476 | bytes += byte_counter; 477 | //fwrite(amrFrame, sizeof (unsigned char), byte_counter, fpamr ); 478 | [out appendBytes:amrFrame length:byte_counter]; 479 | } 480 | 481 | Encoder_Interface_exit(enstate); 482 | 483 | #ifdef DEBUG 484 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 485 | NSString *documentPath = [paths objectAtIndex:0]; 486 | NSString *wavFile = [documentPath stringByAppendingPathComponent:[NSString stringWithFormat:@"88.amr"]]; 487 | [out writeToFile:wavFile atomically:YES]; 488 | #endif 489 | 490 | return out; 491 | } 492 | 493 | //http://developer.apple.com/library/mac/#documentation/MusicAudio/Reference/CAFSpec/CAF_spec/CAF_spec.html#//apple_ref/doc/uid/TP40001862-CH210-SW1 494 | 495 | //struct CAFFileHeader { 496 | // UInt32 mFileType; 497 | // UInt16 mFileVersion; 498 | // UInt16 mFileFlags; 499 | //}; 500 | // 501 | //struct CAFChunkHeader { 502 | // UInt32 mChunkType; 503 | // SInt64 mChunkSize; 504 | //}; 505 | 506 | int SkipCaffHead(char* buf){ 507 | 508 | if (!buf) { 509 | return 0; 510 | } 511 | char* oldBuf = buf; 512 | u32 mFileType = readUint32(buf); 513 | if (0x63616666!=mFileType) { 514 | return 0; 515 | } 516 | buf+=4; 517 | buf+=2; 518 | buf+=2; 519 | 520 | //desc free data 521 | u32 magics[3] = {0x64657363,0x66726565,0x64617461}; 522 | for (int i=0; i<3; ++i) { 523 | u32 mChunkType = readUint32(buf);buf+=4; 524 | if (magics[i]!=mChunkType) { 525 | return 0; 526 | } 527 | 528 | u32 mChunkSize = readSint64(buf);buf+=8; 529 | if (mChunkSize<=0) { 530 | return 0; 531 | } 532 | if (i==2) { 533 | return buf-oldBuf; 534 | } 535 | buf += mChunkSize; 536 | 537 | } 538 | 539 | 540 | return 1; 541 | } 542 | 543 | 544 | //此处将一个录制的pcm直接转换为amr格式 545 | //调用方式为 EncodeWAVEToAMR(pcmData,1,16); 546 | NSData* EncodeWAVEToAMR(NSData* data, int nChannels, int nBitsPerSample) 547 | { 548 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 549 | NSString *documentPath = [paths objectAtIndex:0]; 550 | NSLog(@"documentPath=%@", documentPath); 551 | 552 | if (data==nil){ 553 | //data = [NSData dataWithContentsOfFile:wavFile]; 554 | return nil; 555 | } 556 | 557 | int nPos = 0; 558 | char* buf = [data bytes]; 559 | int maxLen = [data length]; 560 | 561 | 562 | nPos += SkipCaffHead(buf); 563 | if (nPos>=maxLen) { 564 | return nil; 565 | } 566 | 567 | //这时取出来的是纯pcm数据 568 | buf += nPos; 569 | 570 | return EncodePCMToAMR(buf,maxLen- nPos,nChannels,nBitsPerSample); 571 | } 572 | 573 | --------------------------------------------------------------------------------