├── 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 | []() [](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 |
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 |
--------------------------------------------------------------------------------