Jelajahi Sumber

新增16分音符

Steven 2 tahun lalu
induk
melakukan
30d8724991

TEMPAT SAMPAH
KulexiuForStudent/KulexiuForStudent.xcworkspace/xcuserdata/wangzhi.xcuserdatad/UserInterfaceState.xcuserstate


+ 9 - 244
KulexiuForStudent/KulexiuForStudent.xcworkspace/xcuserdata/wangzhi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -5,269 +5,34 @@
    version = "2.0">
    <Breakpoints>
       <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.ExceptionBreakpoint">
-         <BreakpointContent
-            uuid = "38D5EE30-90E1-4F47-9497-A24AA734118B"
-            shouldBeEnabled = "Yes"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            breakpointStackSelectionBehavior = "1"
-            scope = "1"
-            stopOnStyle = "1">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
-            uuid = "E855A530-0110-4534-B8B8-81C1B0CBB0FF"
+            uuid = "673B4C4D-71D2-482A-A772-4DAB5404CC51"
             shouldBeEnabled = "No"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
-            filePath = "KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "807"
-            endingLineNumber = "807"
-            landmarkName = "-updateVideoViewContainer"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "0700CAEF-2659-4E05-BAA4-46175D2BBA9F"
-            shouldBeEnabled = "No"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "KulexiuForStudent/Module/Home/NoticeCenter/Controller/NotiferMessageViewController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "41"
-            endingLineNumber = "41"
-            landmarkName = "-countUMEvent"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "5BD2E24B-2A99-4088-8AD0-14FCB36A6107"
-            shouldBeEnabled = "No"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "2035"
-            endingLineNumber = "2035"
-            landmarkName = "-bottomViewAction:"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "CD907819-11F3-402E-9636-9CA0E9A896CD"
-            shouldBeEnabled = "Yes"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "KulexiuForStudent/AppDelegate.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "833"
-            endingLineNumber = "833"
-            landmarkName = "-handleOutLink:"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "7288688C-9AB5-484B-AD89-EC8B94D6F3B9"
-            shouldBeEnabled = "Yes"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "KulexiuForStudent/AppDelegate.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "878"
-            endingLineNumber = "878"
-            landmarkName = "-handleOutLink:"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "7E3D7E31-190B-4138-9F69-90BF4F917F09"
-            shouldBeEnabled = "Yes"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "KulexiuForStudent/Module/Mine/Setting/Controller/ModifyNameViewController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "64"
-            endingLineNumber = "64"
-            landmarkName = "-rightBtnClick"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "1FA3F780-70E8-4301-AA05-1EF85B499D94"
-            shouldBeEnabled = "Yes"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "2045"
-            endingLineNumber = "2045"
-            landmarkName = "-showShareAlert"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "3C75B336-0D82-4D29-92A0-0CFDC3D0EA76"
-            shouldBeEnabled = "No"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "KulexiuForStudent/Module/Widget/View/WidgetSpeedView.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "89"
-            endingLineNumber = "89"
-            landmarkName = "-touchesMoved:withEvent:"
-            landmarkType = "7">
-            <Locations>
-               <Location
-                  uuid = "3C75B336-0D82-4D29-92A0-0CFDC3D0EA76 - 534285ee3e796a24"
-                  shouldBeEnabled = "Yes"
-                  ignoreCount = "0"
-                  continueAfterRunningActions = "No"
-                  symbolName = "-[WidgetSpeedView touchesMoved:withEvent:]"
-                  moduleName = "KulexiuForStudent"
-                  usesParentBreakpointCondition = "Yes"
-                  urlString = "file:///Users/wangzhi/DayaWorkspace/Klx_student/KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetSpeedView.m"
-                  startingColumnNumber = "9223372036854775807"
-                  endingColumnNumber = "9223372036854775807"
-                  startingLineNumber = "105"
-                  endingLineNumber = "105"
-                  offsetFromSymbolStart = "892">
-               </Location>
-               <Location
-                  uuid = "3C75B336-0D82-4D29-92A0-0CFDC3D0EA76 - 534285ee3e796a24"
-                  shouldBeEnabled = "Yes"
-                  ignoreCount = "0"
-                  continueAfterRunningActions = "No"
-                  symbolName = "-[WidgetSpeedView touchesMoved:withEvent:]"
-                  moduleName = "KulexiuForStudent"
-                  usesParentBreakpointCondition = "Yes"
-                  urlString = "file:///Users/wangzhi/DayaWorkspace/Klx_student/KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetSpeedView.m"
-                  startingColumnNumber = "9223372036854775807"
-                  endingColumnNumber = "9223372036854775807"
-                  startingLineNumber = "105"
-                  endingLineNumber = "105"
-                  offsetFromSymbolStart = "916">
-               </Location>
-               <Location
-                  uuid = "3C75B336-0D82-4D29-92A0-0CFDC3D0EA76 - 534285ee3e796a24"
-                  shouldBeEnabled = "Yes"
-                  ignoreCount = "0"
-                  continueAfterRunningActions = "No"
-                  symbolName = "-[WidgetSpeedView touchesMoved:withEvent:]"
-                  moduleName = "KulexiuForStudent"
-                  usesParentBreakpointCondition = "Yes"
-                  urlString = "file:///Users/wangzhi/DayaWorkspace/Klx_student/KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetSpeedView.m"
-                  startingColumnNumber = "9223372036854775807"
-                  endingColumnNumber = "9223372036854775807"
-                  startingLineNumber = "105"
-                  endingLineNumber = "105"
-                  offsetFromSymbolStart = "920">
-               </Location>
-            </Locations>
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "9FD1F991-9087-4B2C-B3B8-A0FF3487127F"
-            shouldBeEnabled = "Yes"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "KulexiuForStudent/Module/Chat/Controller/KSChatConversationViewController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "324"
-            endingLineNumber = "324"
-            landmarkName = "-refreshUserInfoOrGroupInfo"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "09F17A86-143A-4190-ABAB-B40FA8D70D5E"
-            shouldBeEnabled = "Yes"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "KulexiuForStudent/Module/Chat/Controller/KSChatConversationViewController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "326"
-            endingLineNumber = "326"
-            landmarkName = "-refreshUserInfoOrGroupInfo"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "086852AE-0ED1-44B0-B857-C822A4523D5A"
-            shouldBeEnabled = "Yes"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
             filePath = "KulexiuForStudent/Module/Widget/Model/KSMetronomePlayer.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "222"
-            endingLineNumber = "222"
-            landmarkName = "-stopDong"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "536400B0-83CF-4B41-93D4-D99F2FBB7F56"
-            shouldBeEnabled = "Yes"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "KulexiuForStudent/Module/Login/Model/UserInfoManager.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "379"
-            endingLineNumber = "379"
-            landmarkName = "-startUMCountAndLoginCount"
+            startingLineNumber = "161"
+            endingLineNumber = "161"
+            landmarkName = "-generateBuffer:metronomeType:"
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
-            uuid = "F766E8F7-995E-4457-ADEA-221DE2E627BE"
+            uuid = "432AEDB3-16C0-4CED-891C-3317C59AF2A8"
             shouldBeEnabled = "Yes"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
-            filePath = "KulexiuForStudent/AppDelegate.m"
+            filePath = "KulexiuForStudent/Module/Widget/Model/KSMetronomePlayer.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "392"
-            endingLineNumber = "392"
-            landmarkName = "-application:didRegisterForRemoteNotificationsWithDeviceToken:"
+            startingLineNumber = "60"
+            endingLineNumber = "60"
+            landmarkName = "-handleInterruption:"
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>

+ 14 - 14
KulexiuForStudent/KulexiuForStudent/Common/Define/PrefixHeader.pch

@@ -139,24 +139,24 @@ shouldPrevent = NO; \
 
 //#ifdef DEBUG
 
-//#define hostURL (@"https://dev.colexiu.com")
-//#define SEALCLASSHOST (@"https://dev.colexiu.com/api-classroom")
-//#define WEBHOST (@"https://dev.colexiu.com/student")
-//#define SOCKET_URL (@"wss://dev.colexiu.com/audioAnalysis")
-//#define JSPUSH_ENVIRONMENT (NO)
-//#define RCIM_KEY (@"0vnjpoad0jbdz")
-//#define SUBMIT_UUID (YES)
+#define hostURL (@"https://dev.colexiu.com")
+#define SEALCLASSHOST (@"https://dev.colexiu.com/api-classroom")
+#define WEBHOST (@"https://dev.colexiu.com/student")
+#define SOCKET_URL (@"wss://dev.colexiu.com/audioAnalysis")
+#define JSPUSH_ENVIRONMENT (NO)
+#define RCIM_KEY (@"0vnjpoad0jbdz")
+#define SUBMIT_UUID (YES)
 
 
 //#else
 
-#define hostURL (@"https://online.colexiu.com")
-#define SEALCLASSHOST (@"https://online.colexiu.com/api-classroom")
-#define WEBHOST (@"https://online.colexiu.com/student")
-#define SOCKET_URL (@"wss://online.colexiu.com/audioAnalysis")
-#define JSPUSH_ENVIRONMENT (YES)
-#define RCIM_KEY (@"e5t4ouvpe42pa")
-#define SUBMIT_UUID (YES)
+//#define hostURL (@"https://online.colexiu.com")
+//#define SEALCLASSHOST (@"https://online.colexiu.com/api-classroom")
+//#define WEBHOST (@"https://online.colexiu.com/student")
+//#define SOCKET_URL (@"wss://online.colexiu.com/audioAnalysis")
+//#define JSPUSH_ENVIRONMENT (YES)
+//#define RCIM_KEY (@"e5t4ouvpe42pa")
+//#define SUBMIT_UUID (YES)
 
 //#endif
 

+ 56 - 27
KulexiuForStudent/KulexiuForStudent/Module/Widget/Controller/WidgetViewController.m

@@ -15,7 +15,7 @@
 #import <AVFoundation/AVFoundation.h>
 #import "KSMetronomePlayer.h"
 
-@interface WidgetViewController ()<MetronomeControlViewDelegate,MetronomeFunctionDelegate>
+@interface WidgetViewController ()<MetronomeControlViewDelegate,MetronomeFunctionDelegate,KSMetronomePlayerDelegate>
 
 @property (nonatomic, strong) WidgetNavView *navView;
 
@@ -127,7 +127,7 @@
 - (void)clickChangeBeat {
     // 显示节拍选择弹窗
     MJWeakSelf;
-    self.pickerView = [[KSChoosePicker alloc] initWithTitle:@"节拍" sourceData:@[@"1/2",@"2/2",@"1/4",@"2/4",@"3/4",@"4/4",@"3/8",@"6/8"] chooseReturnWithBlock:^(NSString * _Nonnull returnValue, NSInteger chooseIndex) {
+    self.pickerView = [[KSChoosePicker alloc] initWithTitle:@"节拍" sourceData:@[@"1/2",@"2/2",@"1/4",@"2/4",@"3/4",@"4/4",@"3/8",@"6/8",@"8/16"] chooseReturnWithBlock:^(NSString * _Nonnull returnValue, NSInteger chooseIndex) {
         KSWidgeMetronomeType type = chooseIndex;
         weakSelf.metronomeType = type;
         [weakSelf changeBeat];
@@ -214,16 +214,18 @@
 
 - (void)playBeat {
     // 重置
-    self.currentNo = 0;
-    [self.nodePlayer playPrepareAction:self.speed];
-    // 开始播放
+    self.currentNo = -1;
+    int bpm = self.speed * [self getRate];
+    [self.nodePlayer playAction:bpm metronomeTyle:self.metronomeType];
+  // 开始播放
     [self.timer setFireDate:[NSDate distantPast]];
 }
 
 - (void)stopBeat {
     [self.timer setFireDate:[NSDate distantFuture]];//暂停计时器
-    self.currentNo = 0;
+    self.currentNo = -1;
     self.bottomView.isPlay = NO;
+    [self.nodePlayer stopPlay];
 }
 
 
@@ -231,6 +233,8 @@
     [self.dotView updateSpotView:self.metronomeType];
     self.functionView.currentMetronomeType = self.metronomeType;
     self.speedView.currentType = self.metronomeType;
+    self.timerLength = 60.0 / (1.0 * self.speed) / ([self getRate]);
+    [self resetTimerPlay];
     [self stopBeat];
 }
 
@@ -238,22 +242,55 @@
 - (void)setSpeed:(int)speed {
     _speed = speed;
     int rateFloat = speed;
-    self.timerLength = 1.0 / (rateFloat / 60.0);
+    self.timerLength = 60.0 / (1.0 * rateFloat) / ([self getRate]);
+    NSLog(@"---- %f",self.self.timerLength);
+    [self stopBeat];
     [self resetTimerPlay];
 }
 
+- (CGFloat)getRate {
+    switch (self.metronomeType) {
+        case KSWidgeMetronomeType1V2:
+        case KSWidgeMetronomeType2V2:
+            return 0.5f;
+        case KSWidgeMetronomeType1V4:
+        case KSWidgeMetronomeType2V4:
+        case KSWidgeMetronomeType3V4:
+        case KSWidgeMetronomeType4V4:
+            return 1.0f;
+        case KSWidgeMetronomeType3V8:
+        case KSWidgeMetronomeType6V8:
+            return 2.0f;
+        case KSWidgeMetronomeType8V16:
+            return 4.0f;
+        default:
+            return 1.0f;
+    }
+}
+
+
 - (KSMetronomePlayer *)nodePlayer {
     if (!_nodePlayer) {
         _nodePlayer = [[KSMetronomePlayer alloc] init];
+        _nodePlayer.delegate = self;
     }
     return _nodePlayer;
 }
 
+#pragma mark ---- delegate
+- (void)metronomePlayInterruption {
+    if (self.bottomView.isPlay) {
+        [self stopBeat];
+    }
+}
 
 - (void)resetTimerPlay {
     if (_timer) {
         [self resetTimer];
-        _timer = [NSTimer scheduledTimerWithTimeInterval:self.timerLength target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
+        MJWeakSelf;
+        _timer = [NSTimer scheduledTimerWithTimeInterval:self.timerLength repeats:YES block:^(NSTimer * _Nonnull timer) {
+            [weakSelf timerAction];
+        }];
         [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
         [_timer setFireDate:[NSDate distantFuture]];
     }
@@ -262,7 +299,10 @@
 - (NSTimer *)timer{
     
     if (!_timer) {
-        _timer = [NSTimer scheduledTimerWithTimeInterval:self.timerLength target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
+        MJWeakSelf;
+        _timer = [NSTimer scheduledTimerWithTimeInterval:self.timerLength repeats:YES block:^(NSTimer * _Nonnull timer) {
+            [weakSelf timerAction];
+        }];
         [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
         [_timer setFireDate:[NSDate distantFuture]];
     }
@@ -270,26 +310,15 @@
 }
 
 - (void)timerAction {
-        
-    if (_metronomeType == KSWidgeMetronomeType1V2 || _metronomeType == KSWidgeMetronomeType1V4) {
-        [self.nodePlayer playDing];
-    }
-    else {
-        if ((_metronomeType == KSWidgeMetronomeType2V2 || _metronomeType == KSWidgeMetronomeType2V4) && self.currentNo %2 == 0) {
-            [self.nodePlayer playDing];
-        }else if ((_metronomeType == KSWidgeMetronomeType3V4 || _metronomeType == KSWidgeMetronomeType3V8) && self.currentNo %3 == 0){
-            [self.nodePlayer playDing];
-        }else if (_metronomeType == KSWidgeMetronomeType4V4 && self.currentNo %4 == 0){
-            [self.nodePlayer playDing];
-        }else if (_metronomeType == KSWidgeMetronomeType6V8 && self.currentNo %6 == 0){
-            [self.nodePlayer playDing];
-        }else{
-            [self.nodePlayer playDong];
-        }
-    }
+    [self updateStep];
     
-    [self.dotView updateSpotViewHeightState:self.currentNo];
+}
+
+- (void)updateStep {
+    
+    NSLog(@"---- current no ------ %d ", self.currentNo);
     self.currentNo++;
+    [self.dotView updateSpotViewHeightState:self.currentNo];
 }
 
 

+ 10 - 8
KulexiuForStudent/KulexiuForStudent/Module/Widget/Model/KSMetronomePlayer.h

@@ -10,8 +10,18 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
+@protocol KSMetronomePlayerDelegate <NSObject>
+
+- (void)metronomePlayInterruption;
+
+@optional;
+- (void)resumeAudioSession;
+
+@end
+
 @interface KSMetronomePlayer : NSObject
 
+@property (nonatomic, assign) id <KSMetronomePlayerDelegate> delegate;
 @property(nonatomic, assign) BOOL isPlaying;
 
 @property (nonatomic, assign) float volume;
@@ -20,14 +30,6 @@ NS_ASSUME_NONNULL_BEGIN
 
 - (void)stopPlay;
 
-- (void)playPrepareAction:(int)bmp;
-
-
-- (void)playDing;
-- (void)stopDing;
-
-- (void)playDong;
-- (void)stopDong;
 @end
 
 NS_ASSUME_NONNULL_END

+ 67 - 43
KulexiuForStudent/KulexiuForStudent/Module/Widget/Model/KSMetronomePlayer.m

@@ -12,8 +12,6 @@
 
 @property (nonatomic, strong) AVAudioPlayerNode *playerNode;
 
-@property (nonatomic, strong) AVAudioPlayerNode *playDoNode;
-
 @property (nonatomic, strong) AVAudioEngine *audioEngine;
 
 @property (nonatomic, strong) AVAudioFile *audioDIFile;
@@ -25,6 +23,8 @@
 
 @property (nonatomic, strong) AVAudioPCMBuffer *dongBuffer;
 
+@property (nonatomic, assign) NSInteger playIndex;
+
 @end
 
 @implementation KSMetronomePlayer
@@ -37,8 +37,44 @@
     return self;
 }
 
+- (void)setupAudioSession {
+    
+    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
+    NSError *err = nil;
+    AVAudioSessionCategory category = AVAudioSessionCategoryPlayAndRecord;
+    if (@available(iOS 10.0, *)) {
+        [audioSession setCategory:category mode:AVAudioSessionModeDefault options:AVAudioSessionCategoryOptionAllowBluetooth|AVAudioSessionCategoryOptionAllowBluetoothA2DP|AVAudioSessionCategoryOptionDefaultToSpeaker|AVAudioSessionCategoryOptionMixWithOthers error:&err];
+    }
+    else {
+        [audioSession setCategory:category withOptions:AVAudioSessionCategoryOptionAllowBluetooth|AVAudioSessionCategoryOptionDefaultToSpeaker|AVAudioSessionCategoryOptionMixWithOthers error:&err];
+    }
+    [audioSession setActive:YES error:&err];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterruption:) name:AVAudioSessionInterruptionNotification object:audioSession];
+}
+
+// 打断处理
+- (void)handleInterruption:(NSNotification *)notification {
+    
+    NSDictionary *info = notification.userInfo;
+    AVAudioSessionInterruptionType type = [info[AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
+    if (type == AVAudioSessionInterruptionTypeBegan) {
+        //Handle InterruptionBegan
+        if (self.delegate && [self.delegate respondsToSelector:@selector(metronomePlayInterruption)]) {
+            [self.delegate metronomePlayInterruption];
+        }
+    }else{
+        AVAudioSessionInterruptionOptions options = [info[AVAudioSessionInterruptionOptionKey] unsignedIntegerValue];
+        if (options == AVAudioSessionInterruptionOptionShouldResume) {
+            //Handle Resume
+            if (self.delegate && [self.delegate respondsToSelector:@selector(resumeAudioSession)]) {
+                [self.delegate resumeAudioSession];
+            }
+        }
+    }
+}
 
 - (void)configEngine {
+    [self setupAudioSession];
     NSString *tickPath = [[NSBundle mainBundle]pathForResource:@"tick" ofType:@"wav"];
     NSURL *tickUrl = [NSURL fileURLWithPath:tickPath];
     self.audioDIFile = [[AVAudioFile alloc] initForReading:tickUrl error:nil];
@@ -47,31 +83,34 @@
     NSURL *tockUrl = [NSURL fileURLWithPath:tockPath];
     self.audioDongFile = [[AVAudioFile alloc] initForReading:tockUrl error:nil];
     self.playerNode = [[AVAudioPlayerNode alloc] init];
-    self.playDoNode = [[AVAudioPlayerNode alloc] init];
     self.audioEngine = [[AVAudioEngine alloc] init];
 
     [self.audioEngine attachNode:self.playerNode];
     [self.audioEngine connect:self.playerNode to:self.audioEngine.mainMixerNode format:self.audioDIFile.processingFormat];
     
-    [self.audioEngine attachNode:self.playDoNode];
-    [self.audioEngine connect:self.playDoNode to:self.audioEngine.mainMixerNode format:self.audioDongFile.processingFormat];
-    
     [self.audioEngine startAndReturnError:nil];
-    
+    self.audioEngine.autoShutdownEnabled = YES;
 }
 
-- (void)playPrepareAction:(int)bmp {
-    self.audioDIFile.framePosition = 0;
-    self.audioDongFile.framePosition = 0;
-    AVAudioFrameCount beatLength = self.audioDIFile.processingFormat.sampleRate * 60 / bmp;
-    self.dingBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:self.audioDIFile.processingFormat frameCapacity:beatLength];
-    [self.audioDIFile readIntoBuffer:self.dingBuffer error:nil];
-    self.dingBuffer.frameLength = beatLength;
-    
-    AVAudioFrameCount beatDoLength = self.audioDongFile.processingFormat.sampleRate * 60 / bmp;
-    self.dongBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:self.audioDongFile.processingFormat frameCapacity:beatDoLength];
-    [self.audioDongFile readIntoBuffer:self.dongBuffer error:nil];
-    self.dongBuffer.frameLength = beatDoLength;
+
+- (CGFloat)getRate:(KSWidgeMetronomeType)metronomeType {
+    switch (metronomeType) {
+        case KSWidgeMetronomeType1V2:
+        case KSWidgeMetronomeType2V2:
+            return 0.5f;
+        case KSWidgeMetronomeType1V4:
+        case KSWidgeMetronomeType2V4:
+        case KSWidgeMetronomeType3V4:
+        case KSWidgeMetronomeType4V4:
+            return 1.0f;
+        case KSWidgeMetronomeType3V8:
+        case KSWidgeMetronomeType6V8:
+            return 2.0f;
+        case KSWidgeMetronomeType8V16:
+            return 4.0f;
+        default:
+            return 1.0f;
+    }
 }
 
 - (AVAudioPCMBuffer *)generateBuffer:(int)bmp metronomeType:(KSWidgeMetronomeType)type {
@@ -140,6 +179,8 @@
             return 3;
         case KSWidgeMetronomeType6V8:
             return 6;
+        case KSWidgeMetronomeType8V16:
+            return 8;
         default:
             return 4;
             break;
@@ -168,9 +209,12 @@
     else if (type == KSWidgeMetronomeType3V8) {
         return 2;
     }
-    else {
+    else if (type == KSWidgeMetronomeType6V8) {
         return 5;
     }
+    else {
+        return 7;
+    }
 }
 
 - (void)playAction:(int)bpm metronomeTyle:(KSWidgeMetronomeType)type {
@@ -182,6 +226,7 @@
         [self.playerNode stop];
     }
     [self.playerNode play];
+    
     [self.playerNode scheduleBuffer:buffer atTime:nil options:AVAudioPlayerNodeBufferLoops completionHandler:nil];
 }
 
@@ -195,31 +240,10 @@
 
 - (void)setVolume:(float)volume {
     self.playerNode.volume = volume;
-    self.playDoNode.volume = volume;
-}
-
-- (void)playDing {
-    if (self.playerNode.isPlaying) {
-        [self.playerNode stop];
-    }
-    [self.playerNode play];
-    [self.playerNode scheduleBuffer:self.dingBuffer completionHandler:nil];
-}
-
-- (void)stopDing {
-    [self.playerNode stop];
-}
-
-- (void)playDong {
-    if (self.playDoNode.isPlaying) {
-        [self.playDoNode stop];
-    }
-    [self.playDoNode play];
-    [self.playDoNode scheduleBuffer:self.dongBuffer completionHandler:nil];
 }
 
-- (void)stopDong {
-    [self.playDoNode stop];
+- (void)dealloc {
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
 }
 
 @end

+ 3 - 2
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetDotView.h

@@ -16,8 +16,9 @@ typedef NS_ENUM(NSInteger, KSWidgeMetronomeType) {
     KSWidgeMetronomeType3V4,        // 3/4
     KSWidgeMetronomeType4V4,        // 4/4
     KSWidgeMetronomeType3V8,        // 3/8
-    KSWidgeMetronomeType6V8         // 6/8
-};
+    KSWidgeMetronomeType6V8,        // 6/8
+    KSWidgeMetronomeType8V16,       // 8/16
+ };
 
 
 

+ 82 - 4
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetDotView.m

@@ -28,17 +28,20 @@
     //    当前圆个数
     int spotNo;
     
-    if (self.currentMetronomeType == KSWidgeMetronomeType1V4) {
+    if (self.currentMetronomeType == KSWidgeMetronomeType1V4 || self.currentMetronomeType == KSWidgeMetronomeType1V2) {
         spotNo = 1;
-    }else if (self.currentMetronomeType == KSWidgeMetronomeType2V4){
+    }else if (self.currentMetronomeType == KSWidgeMetronomeType2V4 || self.currentMetronomeType == KSWidgeMetronomeType2V2){
         spotNo = 2;
-    }else if (self.currentMetronomeType == KSWidgeMetronomeType3V4){
+    }else if (self.currentMetronomeType == KSWidgeMetronomeType3V4 || self.currentMetronomeType == KSWidgeMetronomeType3V8){
         spotNo = 3;
     }else if (self.currentMetronomeType == KSWidgeMetronomeType4V4){
         spotNo = 4;
-    }else{
+    }else if (self.currentMetronomeType == KSWidgeMetronomeType6V8){
         spotNo = 6;
     }
+    else {
+        spotNo = 8;
+    }
     
     UIImageView *currentImageView = [self viewWithTag:currentTotalNo % spotNo +100];
     if (currentImageView) {
@@ -281,6 +284,81 @@
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
     }
+    else if (metronomeType == KSWidgeMetronomeType8V16) {
+        CGFloat xSpace = (KPortraitWidth - SPOT_WHDTH * 8 - dotSpace * 7) / 2;
+        UIImageView *spotView = [self creatSpotImageView];
+        spotView.tag = 100;
+        spotView.highlighted = YES;
+        [self addSubview:spotView];
+        [spotView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.mas_equalTo(self.mas_left).offset(xSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
+            make.width.height.mas_equalTo(SPOT_WHDTH);
+        }];
+        
+        UIImageView *spotView1 = [self createWhiteImageView];
+        spotView1.tag = 101;
+        [self addSubview:spotView1];
+        [spotView1 mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.mas_equalTo(spotView.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
+            make.width.height.mas_equalTo(SPOT_WHDTH);
+        }];
+        
+        UIImageView *spotView2 = [self createWhiteImageView];
+        spotView2.tag = 102;
+        [self addSubview:spotView2];
+        [spotView2 mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.mas_equalTo(spotView1.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
+            make.width.height.mas_equalTo(SPOT_WHDTH);
+        }];
+        
+        UIImageView *spotView3 = [self createWhiteImageView];
+        spotView3.tag = 103;
+        [self addSubview:spotView3];
+        [spotView3 mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.mas_equalTo(spotView2.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
+            make.width.height.mas_equalTo(SPOT_WHDTH);
+        }];
+        
+        UIImageView *spotView4 = [self createWhiteImageView];
+        spotView4.tag = 104;
+        [self addSubview:spotView4];
+        [spotView4 mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.mas_equalTo(spotView3.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
+            make.width.height.mas_equalTo(SPOT_WHDTH);
+        }];
+        
+        UIImageView *spotView5 = [self createWhiteImageView];
+        spotView5.tag = 105;
+        [self addSubview:spotView5];
+        [spotView5 mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.mas_equalTo(spotView4.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
+            make.width.height.mas_equalTo(SPOT_WHDTH);
+        }];
+        
+        UIImageView *spotView6 = [self createWhiteImageView];
+        spotView6.tag = 106;
+        [self addSubview:spotView6];
+        [spotView6 mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.mas_equalTo(spotView5.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
+            make.width.height.mas_equalTo(SPOT_WHDTH);
+        }];
+        
+        UIImageView *spotView7 = [self createWhiteImageView];
+        spotView7.tag = 107;
+        [self addSubview:spotView7];
+        [spotView7 mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.mas_equalTo(spotView6.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
+            make.width.height.mas_equalTo(SPOT_WHDTH);
+        }];
+    }
 }
 
 #pragma mark -- 创建大圆View

+ 5 - 0
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetFunctionView.m

@@ -114,6 +114,11 @@
             [self.signatureButton setTitle:@"6/8" forState:UIControlStateNormal];
         }
             break;
+        case KSWidgeMetronomeType8V16:
+        {
+            [self.signatureButton setTitle:@"8/16" forState:UIControlStateNormal];
+        }
+            break;
         default:
             break;
     }

+ 33 - 28
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetSpeedView.m

@@ -65,7 +65,7 @@
 
     UITouch *touch = [touches anyObject];
     CGPoint currentPoint = [touch locationInView:self];
-    CGPoint preLocation = [touch preciseLocationInView:self];
+//    CGPoint preLocation = [touch preciseLocationInView:self];
 
     
     //1.计算当前点相对于x轴的角度
@@ -102,33 +102,38 @@
 }
 
 
-- (void)setCurrentType:(KSWidgeMetronomeType)currentType {
-    _currentType = currentType;
-    switch (currentType) {
-        case KSWidgeMetronomeType1V2:
-        case KSWidgeMetronomeType2V2:
-        {
-            [self.nodeImage setImage:[UIImage imageNamed:@"half_node"]];
-        }
-            break;
-        case KSWidgeMetronomeType1V4:
-        case KSWidgeMetronomeType2V4:
-        case KSWidgeMetronomeType3V4:
-        case KSWidgeMetronomeType4V4:
-        {
-            [self.nodeImage setImage:[UIImage imageNamed:@"quarter_node"]];
-        }
-            break;
-        case KSWidgeMetronomeType3V8:
-        case KSWidgeMetronomeType6V8:
-        {
-            [self.nodeImage setImage:[UIImage imageNamed:@"eighth_node"]];
-        }
-            break;
-        default:
-            break;
-    }
-}
+//- (void)setCurrentType:(KSWidgeMetronomeType)currentType {
+//    _currentType = currentType;
+//    switch (currentType) {
+//        case KSWidgeMetronomeType1V2:
+//        case KSWidgeMetronomeType2V2:
+//        {
+//            [self.nodeImage setImage:[UIImage imageNamed:@"half_node"]];
+//        }
+//            break;
+//        case KSWidgeMetronomeType1V4:
+//        case KSWidgeMetronomeType2V4:
+//        case KSWidgeMetronomeType3V4:
+//        case KSWidgeMetronomeType4V4:
+//        {
+//            [self.nodeImage setImage:[UIImage imageNamed:@"quarter_node"]];
+//        }
+//            break;
+//        case KSWidgeMetronomeType3V8:
+//        case KSWidgeMetronomeType6V8:
+//        {
+//            [self.nodeImage setImage:[UIImage imageNamed:@"eighth_node"]];
+//        }
+//            break;
+//        case KSWidgeMetronomeType8V16:
+//        {
+//            [self.nodeImage setImage:[UIImage imageNamed:@"sixteenth_node"]];
+//        }
+//            break;
+//        default:
+//            break;
+//    }
+//}
 /*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.