Przeglądaj źródła

1.删除KSCloudViewController 本地云教练相关
2.权限申请相关功能优化。
3.作品合成播放器相关优化。

Steven 7 miesięcy temu
rodzic
commit
14ca7796e5
93 zmienionych plików z 1140 dodań i 15025 usunięć
  1. 28 310
      KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj
  2. 39 16
      KulexiuForStudent/KulexiuForStudent/Common/Base/AccompanyWebView/AudioEnginePlayer.m
  3. 92 49
      KulexiuForStudent/KulexiuForStudent/Common/Base/AccompanyWebView/KSAccompanyWebViewController.m
  4. 40 21
      KulexiuForStudent/KulexiuForStudent/Common/Base/AccompanyWebView/KSCloudWebManager.m
  5. 62 46
      KulexiuForStudent/KulexiuForStudent/Common/Base/WebView/KSBaseWKWebViewController.m
  6. 71 51
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSMergeAudioControlView.m
  7. 0 6
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSMergeAudioControlView.xib
  8. 8 0
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSPlayerSliderView.m
  9. 27 0
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/MergeAudioAnimation/KSRealtimeAnalyzer.h
  10. 256 0
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/MergeAudioAnimation/KSRealtimeAnalyzer.m
  11. 23 0
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/MergeAudioAnimation/KSSpectrumView.h
  12. 109 0
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/MergeAudioAnimation/KSSpectrumView.m
  13. 7 1
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/MergePlayer/KSMergeEnginePlayer.h
  14. 218 201
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/MergePlayer/KSMergeEnginePlayer.m
  15. 8 2
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/VideoPlayerView/KSVideoPlayerView.m
  16. 32 17
      KulexiuForStudent/KulexiuForStudent/Module/Chat/Controller/TXCustom/KSTXBaseChatViewController.m
  17. 0 85
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/BassMidiEngine.h
  18. 0 186
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/BassMidiEngine.m
  19. 0 1131
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bass.h
  20. 0 2272
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bass.txt
  21. 0 43
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bass.xcframework/Info.plist
  22. BIN
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bass.xcframework/ios-arm64_armv7_armv7s/libbass.a
  23. BIN
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bass.xcframework/ios-arm64_i386_x86_64-simulator/libbass.a
  24. 0 424
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bassmidi.h
  25. 0 689
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bassmidi.txt
  26. 0 43
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bassmidi.xcframework/Info.plist
  27. BIN
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bassmidi.xcframework/ios-arm64_armv7_armv7s/libbassmidi.a
  28. BIN
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bassmidi.xcframework/ios-arm64_i386_x86_64-simulator/libbassmidi.a
  29. 0 20
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Controller/KSCloudViewController.h
  30. 0 2219
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Controller/KSCloudViewController.m
  31. 0 33
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/CloudSongMessageModel.h
  32. 0 35
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/CloudSongMessageModel.m
  33. 0 1206
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/FingerList.plist
  34. 0 30
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/KSParseMessageModel.h
  35. 0 13
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/KSParseMessageModel.m
  36. 0 23
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/KSXMLInfoParse.h
  37. 0 324
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/KSXMLInfoParse.m
  38. 0 24
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/KYSourceParseManager.h
  39. 0 145
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/KYSourceParseManager.m
  40. 0 76
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/SubjectFinger.plist
  41. 0 211
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/TBXML.h
  42. 0 952
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/TBXML.m
  43. 0 25
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Channel/TrackChooseView.h
  44. 0 142
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Channel/TrackChooseView.m
  45. 0 113
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Channel/TrackChooseView.xib
  46. 0 23
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Help/CloudFeedbackView.h
  47. 0 126
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Help/CloudFeedbackView.m
  48. 0 325
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Help/CloudFeedbackView.xib
  49. 0 23
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Help/CloudHelpView.h
  50. 0 253
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Help/CloudHelpView.m
  51. 0 131
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Help/CloudHelpView.xib
  52. 0 29
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/JudgePageView.h
  53. 0 176
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/JudgePageView.m
  54. 0 157
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/JudgePageView.xib
  55. 0 36
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/KSCloudSettingView.h
  56. 0 139
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/KSCloudSettingView.m
  57. 0 135
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/KSCloudSettingView.xib
  58. 0 36
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/SettingPageView.h
  59. 0 155
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/SettingPageView.m
  60. 0 190
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/SettingPageView.xib
  61. 0 43
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SoundCheckView/SoundCheckView.h
  62. 0 153
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SoundCheckView/SoundCheckView.m
  63. 0 177
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SoundCheckView/SoundCheckView.xib
  64. 0 38
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SpeedSlider/KSSliderView.h
  65. 0 154
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SpeedSlider/KSSliderView.m
  66. 0 29
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SpeedSlider/KSTrackingSlider.h
  67. 0 70
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SpeedSlider/KSTrackingSlider.m
  68. 0 25
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/StaffView/CloudControlButton.h
  69. 0 132
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/StaffView/CloudControlButton.m
  70. 0 20
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/StaffView/ScoreAnimationView.h
  71. 0 76
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/StaffView/ScoreAnimationView.m
  72. 0 51
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/StaffView/StaffImageDisplayView.h
  73. 0 109
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/StaffView/StaffImageDisplayView.m
  74. 0 39
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/TipsAlert/EvaluateResultAlert.h
  75. 0 144
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/TipsAlert/EvaluateResultAlert.m
  76. 0 391
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/TipsAlert/EvaluateResultAlert.xib
  77. 0 22
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/TipsAlert/NoWiredTipsAlert.h
  78. 0 49
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/TipsAlert/NoWiredTipsAlert.m
  79. 0 121
      KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/TipsAlert/NoWiredTipsAlert.xib
  80. 28 16
      KulexiuForStudent/KulexiuForStudent/Module/Course/AccompanyCourse/Controller/AccompanyDetailViewController.m
  81. 28 17
      KulexiuForStudent/KulexiuForStudent/Module/Course/MusicRoom/Controller/MusicRoomDetailViewController.m
  82. 7 8
      KulexiuForStudent/KulexiuForStudent/Module/Home/Controller/HomeViewController.m
  83. 7 8
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Controller/MineViewController.m
  84. 6 8
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Scan/Controller/KSScanViewController.m
  85. BIN
      KulexiuForStudent/KulexiuForStudent/ToolKit/CloudAccompanyLibrary.framework/CloudAccompanyLibrary
  86. 34 0
      KulexiuForStudent/KulexiuForStudent/ToolKit/CloudAccompanyLibrary.framework/Headers/KSCloudWebViewController.h
  87. BIN
      KulexiuForStudent/KulexiuForStudent/ToolKit/CloudAccompanyLibrary.framework/_CodeSignature/CodeDirectory
  88. BIN
      KulexiuForStudent/KulexiuForStudent/ToolKit/CloudAccompanyLibrary.framework/_CodeSignature/CodeRequirements-1
  89. 3 3
      KulexiuForStudent/KulexiuForStudent/ToolKit/CloudAccompanyLibrary.framework/_CodeSignature/CodeResources
  90. BIN
      KulexiuForStudent/KulexiuForStudent/ToolKit/CloudAccompanyLibrary.framework/_CodeSignature/CodeSignature
  91. 0 1
      KulexiuForStudent/KulexiuForStudent/ToolKit/KSToolLibrary.framework/Headers/KSAQRecordManager.h
  92. 7 3
      KulexiuForStudent/KulexiuForStudent/ToolKit/KSToolLibrary.framework/Headers/RecordCheckManager.h
  93. BIN
      KulexiuForStudent/KulexiuForStudent/ToolKit/KSToolLibrary.framework/KSToolLibrary

+ 28 - 310
KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj

@@ -304,7 +304,6 @@
 		BC12639A28FF8E1700509E90 /* HomeNewMusicView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC12639928FF8E1700509E90 /* HomeNewMusicView.xib */; };
 		BC12639D28FF8E6D00509E90 /* HomeRecommendMusicView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC12639C28FF8E6D00509E90 /* HomeRecommendMusicView.m */; };
 		BC12639F28FF8E7400509E90 /* HomeRecommendMusicView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC12639E28FF8E7400509E90 /* HomeRecommendMusicView.xib */; };
-		BC1553792C4E73C300F6A151 /* KSToolLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC1553782C4E73C300F6A151 /* KSToolLibrary.framework */; };
 		BC1D02422C0490AB001F6A94 /* KSMuteTipsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC1D023F2C0490AB001F6A94 /* KSMuteTipsView.xib */; };
 		BC1D02432C0490AB001F6A94 /* KSMuteTipsView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC1D02402C0490AB001F6A94 /* KSMuteTipsView.m */; };
 		BC27A06E280FF56C00F91E27 /* AccompanyEvaluateCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC27A06A280FF56B00F91E27 /* AccompanyEvaluateCell.xib */; };
@@ -595,6 +594,10 @@
 		BC83A8402AD28AA60033D48B /* TenantNotiferNavView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC83A83F2AD28AA60033D48B /* TenantNotiferNavView.xib */; };
 		BC84183F2AC2D96600D8F90E /* PasswordCheckBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC84183E2AC2D96600D8F90E /* PasswordCheckBodyView.m */; };
 		BC8418412AC2D96C00D8F90E /* PasswordCheckBodyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC8418402AC2D96C00D8F90E /* PasswordCheckBodyView.xib */; };
+		BC85A9DF2C6B5268003C1ABE /* KSToolLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC85A9DD2C6B5268003C1ABE /* KSToolLibrary.framework */; };
+		BC85A9E02C6B5268003C1ABE /* CloudAccompanyLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC85A9DE2C6B5268003C1ABE /* CloudAccompanyLibrary.framework */; };
+		BC85A9E62C6B570E003C1ABE /* KSRealtimeAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = BC85A9E22C6B570E003C1ABE /* KSRealtimeAnalyzer.m */; };
+		BC85A9E72C6B570E003C1ABE /* KSSpectrumView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC85A9E42C6B570E003C1ABE /* KSSpectrumView.m */; };
 		BC89AC092AB0840E00B077AF /* TenantRecommendMusicView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC89AC082AB0840E00B077AF /* TenantRecommendMusicView.m */; };
 		BC89AC0B2AB0841400B077AF /* TenantRecommendMusicView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC89AC0A2AB0841400B077AF /* TenantRecommendMusicView.xib */; };
 		BC89AC0E2AB0842B00B077AF /* TenantNewMusicView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC89AC0D2AB0842B00B077AF /* TenantNewMusicView.m */; };
@@ -605,37 +608,6 @@
 		BC89AC1A2AB08FA100B077AF /* TenantMusicCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC89AC182AB08FA100B077AF /* TenantMusicCollectionViewCell.xib */; };
 		BC89AC1D2AB08FE700B077AF /* TenantMusicCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC89AC1C2AB08FE700B077AF /* TenantMusicCellView.m */; };
 		BC89AC1F2AB08FF500B077AF /* TenantMusicCellView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC89AC1E2AB08FF500B077AF /* TenantMusicCellView.xib */; };
-		BC8A4593283DC33400094BBB /* KSCloudViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A4548283DC33400094BBB /* KSCloudViewController.m */; };
-		BC8A4598283DC33400094BBB /* KYSourceParseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A4554283DC33400094BBB /* KYSourceParseManager.m */; };
-		BC8A4599283DC33400094BBB /* TBXML.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A4557283DC33400094BBB /* TBXML.m */; };
-		BC8A459A283DC33400094BBB /* SubjectFinger.plist in Resources */ = {isa = PBXBuildFile; fileRef = BC8A4558283DC33400094BBB /* SubjectFinger.plist */; };
-		BC8A459B283DC33400094BBB /* CloudSongMessageModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A4559283DC33400094BBB /* CloudSongMessageModel.m */; };
-		BC8A459C283DC33400094BBB /* KSXMLInfoParse.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A455A283DC33400094BBB /* KSXMLInfoParse.m */; };
-		BC8A459D283DC33400094BBB /* KSParseMessageModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A455C283DC33400094BBB /* KSParseMessageModel.m */; };
-		BC8A459E283DC33400094BBB /* FingerList.plist in Resources */ = {isa = PBXBuildFile; fileRef = BC8A455E283DC33400094BBB /* FingerList.plist */; };
-		BC8A459F283DC33400094BBB /* SettingPageView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC8A4563283DC33400094BBB /* SettingPageView.xib */; };
-		BC8A45A0283DC33400094BBB /* JudgePageView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC8A4564283DC33400094BBB /* JudgePageView.xib */; };
-		BC8A45A1283DC33400094BBB /* KSCloudSettingView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A4565283DC33400094BBB /* KSCloudSettingView.m */; };
-		BC8A45A2283DC33400094BBB /* SettingPageView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A4566283DC33400094BBB /* SettingPageView.m */; };
-		BC8A45A3283DC33400094BBB /* JudgePageView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A4567283DC33400094BBB /* JudgePageView.m */; };
-		BC8A45A4283DC33400094BBB /* KSCloudSettingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC8A4568283DC33400094BBB /* KSCloudSettingView.xib */; };
-		BC8A45A5283DC33400094BBB /* StaffImageDisplayView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A456E283DC33400094BBB /* StaffImageDisplayView.m */; };
-		BC8A45A6283DC33400094BBB /* ScoreAnimationView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A456F283DC33400094BBB /* ScoreAnimationView.m */; };
-		BC8A45A7283DC33400094BBB /* CloudControlButton.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A4570283DC33400094BBB /* CloudControlButton.m */; };
-		BC8A45AA283DC33400094BBB /* TrackChooseView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A4576283DC33400094BBB /* TrackChooseView.m */; };
-		BC8A45AB283DC33400094BBB /* TrackChooseView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC8A4577283DC33400094BBB /* TrackChooseView.xib */; };
-		BC8A45AC283DC33400094BBB /* KSSliderView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A457B283DC33400094BBB /* KSSliderView.m */; };
-		BC8A45AD283DC33400094BBB /* KSTrackingSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A457C283DC33400094BBB /* KSTrackingSlider.m */; };
-		BC8A45AE283DC33400094BBB /* SoundCheckView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A457F283DC33400094BBB /* SoundCheckView.m */; };
-		BC8A45AF283DC33400094BBB /* SoundCheckView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC8A4580283DC33400094BBB /* SoundCheckView.xib */; };
-		BC8A45B0283DC33400094BBB /* CloudHelpView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A4584283DC33400094BBB /* CloudHelpView.m */; };
-		BC8A45B1283DC33400094BBB /* CloudHelpView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC8A4585283DC33400094BBB /* CloudHelpView.xib */; };
-		BC8A45B2283DC33400094BBB /* CloudFeedbackView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A4586283DC33400094BBB /* CloudFeedbackView.m */; };
-		BC8A45B3283DC33400094BBB /* CloudFeedbackView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC8A4588283DC33400094BBB /* CloudFeedbackView.xib */; };
-		BC8A45B4283DC33400094BBB /* EvaluateResultAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC8A458A283DC33400094BBB /* EvaluateResultAlert.xib */; };
-		BC8A45B5283DC33400094BBB /* EvaluateResultAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A458D283DC33400094BBB /* EvaluateResultAlert.m */; };
-		BC8A45B6283DC33400094BBB /* NoWiredTipsAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC8A458E283DC33400094BBB /* NoWiredTipsAlert.xib */; };
-		BC8A45B7283DC33500094BBB /* NoWiredTipsAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A458F283DC33400094BBB /* NoWiredTipsAlert.m */; };
 		BC8A45C1283DDD7100094BBB /* synthgms.sf2 in Resources */ = {isa = PBXBuildFile; fileRef = BC8A45C0283DDD7100094BBB /* synthgms.sf2 */; };
 		BC8A45C3283DDE5C00094BBB /* CoreMIDI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC8A45C2283DDE5C00094BBB /* CoreMIDI.framework */; };
 		BC8A45C5283DDE6D00094BBB /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC8A45C4283DDE6D00094BBB /* AudioToolbox.framework */; };
@@ -672,11 +644,6 @@
 		BC9AA0DD2ABC434900CD954D /* KSHudLoagingManager.m in Sources */ = {isa = PBXBuildFile; fileRef = BC9AA0D92ABC434900CD954D /* KSHudLoagingManager.m */; };
 		BC9AA0DE2ABC434900CD954D /* KSCustomLoadingView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC9AA0DA2ABC434900CD954D /* KSCustomLoadingView.m */; };
 		BC9AA0DF2ABC434900CD954D /* KSCustomLoadingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC9AA0DB2ABC434900CD954D /* KSCustomLoadingView.xib */; };
-		BCA1135D28A3A2BB007FAFB9 /* bass.txt in Resources */ = {isa = PBXBuildFile; fileRef = BCA1135A28A3A2BB007FAFB9 /* bass.txt */; };
-		BCA1135E28A3A2BB007FAFB9 /* bass.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCA1135B28A3A2BB007FAFB9 /* bass.xcframework */; };
-		BCA1136228A3A2D0007FAFB9 /* bassmidi.txt in Resources */ = {isa = PBXBuildFile; fileRef = BCA1136028A3A2D0007FAFB9 /* bassmidi.txt */; };
-		BCA1136328A3A2D0007FAFB9 /* bassmidi.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCA1136128A3A2D0007FAFB9 /* bassmidi.xcframework */; };
-		BCA1136628A3A2EA007FAFB9 /* BassMidiEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA1136528A3A2EA007FAFB9 /* BassMidiEngine.m */; };
 		BCA1136828A3A5CF007FAFB9 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCA1136728A3A5CF007FAFB9 /* Accelerate.framework */; };
 		BCA193B8282B6094004A585D /* RecentCourseModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA193B7282B6094004A585D /* RecentCourseModel.m */; };
 		BCA353F12859BB2900377661 /* MusicRoomCourseCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCA353EF2859BB2700377661 /* MusicRoomCourseCell.xib */; };
@@ -916,7 +883,6 @@
 		BCF425F72AB991E600BCD942 /* TenantAlbumModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BCF425F62AB991E600BCD942 /* TenantAlbumModel.m */; };
 		BCF472E72AB019CD0032BE16 /* TenantDarkViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCF472E62AB019CD0032BE16 /* TenantDarkViewController.m */; };
 		BCF472EA2AB01AEB0032BE16 /* TenantMoreViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCF472E92AB01AEB0032BE16 /* TenantMoreViewController.m */; };
-		BCFC09CA2C47F6FF009A727F /* CloudAccompanyLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCFC09C92C47F6FF009A727F /* CloudAccompanyLibrary.framework */; };
 		BCFC09D12C48B3D7009A727F /* KSAccompanyDraftViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFC09D02C48B3D7009A727F /* KSAccompanyDraftViewController.m */; };
 		BCFC09DA2C48C8DE009A727F /* UserVip.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFC09D82C48C8DD009A727F /* UserVip.m */; };
 		BCFCE44E28DD5C000051FED8 /* Low.wav in Resources */ = {isa = PBXBuildFile; fileRef = BCFCE44C28DD5C000051FED8 /* Low.wav */; };
@@ -1538,7 +1504,6 @@
 		BC12639B28FF8E6D00509E90 /* HomeRecommendMusicView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeRecommendMusicView.h; sourceTree = "<group>"; };
 		BC12639C28FF8E6D00509E90 /* HomeRecommendMusicView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeRecommendMusicView.m; sourceTree = "<group>"; };
 		BC12639E28FF8E7400509E90 /* HomeRecommendMusicView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HomeRecommendMusicView.xib; sourceTree = "<group>"; };
-		BC1553782C4E73C300F6A151 /* KSToolLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = KSToolLibrary.framework; sourceTree = "<group>"; };
 		BC1D023F2C0490AB001F6A94 /* KSMuteTipsView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KSMuteTipsView.xib; sourceTree = "<group>"; };
 		BC1D02402C0490AB001F6A94 /* KSMuteTipsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSMuteTipsView.m; sourceTree = "<group>"; };
 		BC1D02412C0490AB001F6A94 /* KSMuteTipsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSMuteTipsView.h; sourceTree = "<group>"; };
@@ -1974,6 +1939,12 @@
 		BC84183D2AC2D96600D8F90E /* PasswordCheckBodyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PasswordCheckBodyView.h; sourceTree = "<group>"; };
 		BC84183E2AC2D96600D8F90E /* PasswordCheckBodyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PasswordCheckBodyView.m; sourceTree = "<group>"; };
 		BC8418402AC2D96C00D8F90E /* PasswordCheckBodyView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PasswordCheckBodyView.xib; sourceTree = "<group>"; };
+		BC85A9DD2C6B5268003C1ABE /* KSToolLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = KSToolLibrary.framework; sourceTree = "<group>"; };
+		BC85A9DE2C6B5268003C1ABE /* CloudAccompanyLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = CloudAccompanyLibrary.framework; sourceTree = "<group>"; };
+		BC85A9E12C6B570E003C1ABE /* KSRealtimeAnalyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSRealtimeAnalyzer.h; sourceTree = "<group>"; };
+		BC85A9E22C6B570E003C1ABE /* KSRealtimeAnalyzer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSRealtimeAnalyzer.m; sourceTree = "<group>"; };
+		BC85A9E32C6B570E003C1ABE /* KSSpectrumView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSSpectrumView.h; sourceTree = "<group>"; };
+		BC85A9E42C6B570E003C1ABE /* KSSpectrumView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSSpectrumView.m; sourceTree = "<group>"; };
 		BC89AC072AB0840E00B077AF /* TenantRecommendMusicView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TenantRecommendMusicView.h; sourceTree = "<group>"; };
 		BC89AC082AB0840E00B077AF /* TenantRecommendMusicView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TenantRecommendMusicView.m; sourceTree = "<group>"; };
 		BC89AC0A2AB0841400B077AF /* TenantRecommendMusicView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TenantRecommendMusicView.xib; sourceTree = "<group>"; };
@@ -1989,57 +1960,6 @@
 		BC89AC1B2AB08FE700B077AF /* TenantMusicCellView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TenantMusicCellView.h; sourceTree = "<group>"; };
 		BC89AC1C2AB08FE700B077AF /* TenantMusicCellView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TenantMusicCellView.m; sourceTree = "<group>"; };
 		BC89AC1E2AB08FF500B077AF /* TenantMusicCellView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TenantMusicCellView.xib; sourceTree = "<group>"; };
-		BC8A4547283DC33400094BBB /* KSCloudViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSCloudViewController.h; sourceTree = "<group>"; };
-		BC8A4548283DC33400094BBB /* KSCloudViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSCloudViewController.m; sourceTree = "<group>"; };
-		BC8A4553283DC33400094BBB /* KSXMLInfoParse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSXMLInfoParse.h; sourceTree = "<group>"; };
-		BC8A4554283DC33400094BBB /* KYSourceParseManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KYSourceParseManager.m; sourceTree = "<group>"; };
-		BC8A4555283DC33400094BBB /* CloudSongMessageModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CloudSongMessageModel.h; sourceTree = "<group>"; };
-		BC8A4556283DC33400094BBB /* KSParseMessageModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSParseMessageModel.h; sourceTree = "<group>"; };
-		BC8A4557283DC33400094BBB /* TBXML.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TBXML.m; sourceTree = "<group>"; };
-		BC8A4558283DC33400094BBB /* SubjectFinger.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = SubjectFinger.plist; sourceTree = "<group>"; };
-		BC8A4559283DC33400094BBB /* CloudSongMessageModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CloudSongMessageModel.m; sourceTree = "<group>"; };
-		BC8A455A283DC33400094BBB /* KSXMLInfoParse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSXMLInfoParse.m; sourceTree = "<group>"; };
-		BC8A455B283DC33400094BBB /* KYSourceParseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KYSourceParseManager.h; sourceTree = "<group>"; };
-		BC8A455C283DC33400094BBB /* KSParseMessageModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSParseMessageModel.m; sourceTree = "<group>"; };
-		BC8A455D283DC33400094BBB /* TBXML.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TBXML.h; sourceTree = "<group>"; };
-		BC8A455E283DC33400094BBB /* FingerList.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = FingerList.plist; sourceTree = "<group>"; };
-		BC8A4561283DC33400094BBB /* SettingPageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingPageView.h; sourceTree = "<group>"; };
-		BC8A4562283DC33400094BBB /* JudgePageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JudgePageView.h; sourceTree = "<group>"; };
-		BC8A4563283DC33400094BBB /* SettingPageView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingPageView.xib; sourceTree = "<group>"; };
-		BC8A4564283DC33400094BBB /* JudgePageView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = JudgePageView.xib; sourceTree = "<group>"; };
-		BC8A4565283DC33400094BBB /* KSCloudSettingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSCloudSettingView.m; sourceTree = "<group>"; };
-		BC8A4566283DC33400094BBB /* SettingPageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingPageView.m; sourceTree = "<group>"; };
-		BC8A4567283DC33400094BBB /* JudgePageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JudgePageView.m; sourceTree = "<group>"; };
-		BC8A4568283DC33400094BBB /* KSCloudSettingView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KSCloudSettingView.xib; sourceTree = "<group>"; };
-		BC8A4569283DC33400094BBB /* KSCloudSettingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSCloudSettingView.h; sourceTree = "<group>"; };
-		BC8A456B283DC33400094BBB /* ScoreAnimationView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScoreAnimationView.h; sourceTree = "<group>"; };
-		BC8A456C283DC33400094BBB /* StaffImageDisplayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaffImageDisplayView.h; sourceTree = "<group>"; };
-		BC8A456D283DC33400094BBB /* CloudControlButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CloudControlButton.h; sourceTree = "<group>"; };
-		BC8A456E283DC33400094BBB /* StaffImageDisplayView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StaffImageDisplayView.m; sourceTree = "<group>"; };
-		BC8A456F283DC33400094BBB /* ScoreAnimationView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScoreAnimationView.m; sourceTree = "<group>"; };
-		BC8A4570283DC33400094BBB /* CloudControlButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CloudControlButton.m; sourceTree = "<group>"; };
-		BC8A4576283DC33400094BBB /* TrackChooseView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TrackChooseView.m; sourceTree = "<group>"; };
-		BC8A4577283DC33400094BBB /* TrackChooseView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TrackChooseView.xib; sourceTree = "<group>"; };
-		BC8A4578283DC33400094BBB /* TrackChooseView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackChooseView.h; sourceTree = "<group>"; };
-		BC8A457A283DC33400094BBB /* KSTrackingSlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSTrackingSlider.h; sourceTree = "<group>"; };
-		BC8A457B283DC33400094BBB /* KSSliderView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSSliderView.m; sourceTree = "<group>"; };
-		BC8A457C283DC33400094BBB /* KSTrackingSlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSTrackingSlider.m; sourceTree = "<group>"; };
-		BC8A457D283DC33400094BBB /* KSSliderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSSliderView.h; sourceTree = "<group>"; };
-		BC8A457F283DC33400094BBB /* SoundCheckView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SoundCheckView.m; sourceTree = "<group>"; };
-		BC8A4580283DC33400094BBB /* SoundCheckView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SoundCheckView.xib; sourceTree = "<group>"; };
-		BC8A4581283DC33400094BBB /* SoundCheckView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SoundCheckView.h; sourceTree = "<group>"; };
-		BC8A4583283DC33400094BBB /* CloudFeedbackView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CloudFeedbackView.h; sourceTree = "<group>"; };
-		BC8A4584283DC33400094BBB /* CloudHelpView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CloudHelpView.m; sourceTree = "<group>"; };
-		BC8A4585283DC33400094BBB /* CloudHelpView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CloudHelpView.xib; sourceTree = "<group>"; };
-		BC8A4586283DC33400094BBB /* CloudFeedbackView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CloudFeedbackView.m; sourceTree = "<group>"; };
-		BC8A4587283DC33400094BBB /* CloudHelpView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CloudHelpView.h; sourceTree = "<group>"; };
-		BC8A4588283DC33400094BBB /* CloudFeedbackView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CloudFeedbackView.xib; sourceTree = "<group>"; };
-		BC8A458A283DC33400094BBB /* EvaluateResultAlert.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = EvaluateResultAlert.xib; sourceTree = "<group>"; };
-		BC8A458B283DC33400094BBB /* EvaluateResultAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EvaluateResultAlert.h; sourceTree = "<group>"; };
-		BC8A458C283DC33400094BBB /* NoWiredTipsAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NoWiredTipsAlert.h; sourceTree = "<group>"; };
-		BC8A458D283DC33400094BBB /* EvaluateResultAlert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EvaluateResultAlert.m; sourceTree = "<group>"; };
-		BC8A458E283DC33400094BBB /* NoWiredTipsAlert.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NoWiredTipsAlert.xib; sourceTree = "<group>"; };
-		BC8A458F283DC33400094BBB /* NoWiredTipsAlert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NoWiredTipsAlert.m; sourceTree = "<group>"; };
 		BC8A45C0283DDD7100094BBB /* synthgms.sf2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = synthgms.sf2; sourceTree = "<group>"; };
 		BC8A45C2283DDE5C00094BBB /* CoreMIDI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; };
 		BC8A45C4283DDE6D00094BBB /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
@@ -2094,14 +2014,6 @@
 		BC9AA0DA2ABC434900CD954D /* KSCustomLoadingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSCustomLoadingView.m; sourceTree = "<group>"; };
 		BC9AA0DB2ABC434900CD954D /* KSCustomLoadingView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KSCustomLoadingView.xib; sourceTree = "<group>"; };
 		BC9AA0DC2ABC434900CD954D /* KSHudLoagingManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSHudLoagingManager.h; sourceTree = "<group>"; };
-		BCA1135A28A3A2BB007FAFB9 /* bass.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = bass.txt; sourceTree = "<group>"; };
-		BCA1135B28A3A2BB007FAFB9 /* bass.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = bass.xcframework; sourceTree = "<group>"; };
-		BCA1135C28A3A2BB007FAFB9 /* bass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bass.h; sourceTree = "<group>"; };
-		BCA1135F28A3A2D0007FAFB9 /* bassmidi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bassmidi.h; sourceTree = "<group>"; };
-		BCA1136028A3A2D0007FAFB9 /* bassmidi.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = bassmidi.txt; sourceTree = "<group>"; };
-		BCA1136128A3A2D0007FAFB9 /* bassmidi.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = bassmidi.xcframework; sourceTree = "<group>"; };
-		BCA1136428A3A2EA007FAFB9 /* BassMidiEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BassMidiEngine.h; path = KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/BassMidiEngine.h; sourceTree = SOURCE_ROOT; };
-		BCA1136528A3A2EA007FAFB9 /* BassMidiEngine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BassMidiEngine.m; path = KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/BassMidiEngine.m; sourceTree = SOURCE_ROOT; };
 		BCA1136728A3A5CF007FAFB9 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
 		BCA193B6282B6094004A585D /* RecentCourseModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecentCourseModel.h; sourceTree = "<group>"; };
 		BCA193B7282B6094004A585D /* RecentCourseModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RecentCourseModel.m; sourceTree = "<group>"; };
@@ -2489,7 +2401,6 @@
 		BCF880DD2B91C4FA0007B8F0 /* Config-debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Config-debug.xcconfig"; sourceTree = "<group>"; };
 		BCF880DF2B91C5090007B8F0 /* Config-test.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Config-test.xcconfig"; sourceTree = "<group>"; };
 		BCF880E02B91C5150007B8F0 /* Config-release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Config-release.xcconfig"; sourceTree = "<group>"; };
-		BCFC09C92C47F6FF009A727F /* CloudAccompanyLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = CloudAccompanyLibrary.framework; sourceTree = "<group>"; };
 		BCFC09CF2C48B3D7009A727F /* KSAccompanyDraftViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSAccompanyDraftViewController.h; sourceTree = "<group>"; };
 		BCFC09D02C48B3D7009A727F /* KSAccompanyDraftViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSAccompanyDraftViewController.m; sourceTree = "<group>"; };
 		BCFC09D82C48C8DD009A727F /* UserVip.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserVip.m; sourceTree = "<group>"; };
@@ -2573,9 +2484,9 @@
 			files = (
 				BCA1136828A3A5CF007FAFB9 /* Accelerate.framework in Frameworks */,
 				BCFEE1932AD15C0E000E888F /* SoundpipeAudioKit in Frameworks */,
-				BCFC09CA2C47F6FF009A727F /* CloudAccompanyLibrary.framework in Frameworks */,
+				BC85A9E02C6B5268003C1ABE /* CloudAccompanyLibrary.framework in Frameworks */,
 				BCFEE18D2AD15BD4000E888F /* AudioKitEX in Frameworks */,
-				BC1553792C4E73C300F6A151 /* KSToolLibrary.framework in Frameworks */,
+				BC85A9DF2C6B5268003C1ABE /* KSToolLibrary.framework in Frameworks */,
 				BC8B6E152856E20800866917 /* WebKit.framework in Frameworks */,
 				BC8A45CB283DDEA100094BBB /* AVFoundation.framework in Frameworks */,
 				BCD9294F28F8FCA4006793E4 /* AudioKit in Frameworks */,
@@ -2585,7 +2496,6 @@
 				BC71D0F52881A2420010F14B /* UMAPM.framework in Frameworks */,
 				BC71D0F72881A2420010F14B /* UMCommon.framework in Frameworks */,
 				BC8A45C9283DDE9A00094BBB /* CoreMedia.framework in Frameworks */,
-				BCA1135E28A3A2BB007FAFB9 /* bass.xcframework in Frameworks */,
 				BC71D1012881A2420010F14B /* libSocialSina.a in Frameworks */,
 				BC71D1062881A2420010F14B /* TencentOpenAPI.framework in Frameworks */,
 				BC8B6E132856E1F600866917 /* CoreTelephony.framework in Frameworks */,
@@ -2593,7 +2503,6 @@
 				BC71D1032881A2420010F14B /* libWeiboSDK.a in Frameworks */,
 				BC8A45C7283DDE8E00094BBB /* VideoToolbox.framework in Frameworks */,
 				BC3A556E2BAA7B2D002E1616 /* KSTunerLibrary.framework in Frameworks */,
-				BCA1136328A3A2D0007FAFB9 /* bassmidi.xcframework in Frameworks */,
 				BC8B6E172856E21000866917 /* SystemConfiguration.framework in Frameworks */,
 				BC71D0FE2881A2420010F14B /* libSocialOfficialWeChat.a in Frameworks */,
 				BC71D1002881A2420010F14B /* libWeChatSDK.a in Frameworks */,
@@ -2861,7 +2770,6 @@
 				BC106BBE2A933688000759A9 /* TXLive */,
 				BCC0F5E52A8CD7A600C4EFA4 /* TXClassRoom */,
 				BC71D1342887CD470010F14B /* AnimationLaunch */,
-				BC8A4545283DC33400094BBB /* CloudEngine */,
 				BCB6340A27F6D29500ACFDCF /* Live */,
 				275FA1F127E7356A00CFEA2E /* Home */,
 				275FA1F727E7356A00CFEA2E /* Course */,
@@ -4454,6 +4362,7 @@
 		BC38C3D42AF893B300ABFCC2 /* AudioMerge */ = {
 			isa = PBXGroup;
 			children = (
+				BC85A9E52C6B570E003C1ABE /* MergeAudioAnimation */,
 				BCED0AF62C4651F800369AED /* MergePlayer */,
 				BC38C3DE2AF893B300ABFCC2 /* AudioPlayAnimationView */,
 				BC38C3D62AF893B300ABFCC2 /* KSAudioAnimationView.h */,
@@ -4671,9 +4580,9 @@
 			children = (
 				BC00A65F2BB58FDB00231B74 /* LLPhotoBrowse.bundle */,
 				BC00A6602BB58FDC00231B74 /* WMPlayer.bundle */,
-				BC1553782C4E73C300F6A151 /* KSToolLibrary.framework */,
 				BC3A55682BAA7B19002E1616 /* KSTunerLibrary.framework */,
-				BCFC09C92C47F6FF009A727F /* CloudAccompanyLibrary.framework */,
+				BC85A9DD2C6B5268003C1ABE /* KSToolLibrary.framework */,
+				BC85A9DE2C6B5268003C1ABE /* CloudAccompanyLibrary.framework */,
 				BC3BF62F2B9EAFC800831494 /* client.p12 */,
 			);
 			path = ToolKit;
@@ -5165,6 +5074,17 @@
 			path = HotLiveCourse;
 			sourceTree = "<group>";
 		};
+		BC85A9E52C6B570E003C1ABE /* MergeAudioAnimation */ = {
+			isa = PBXGroup;
+			children = (
+				BC85A9E12C6B570E003C1ABE /* KSRealtimeAnalyzer.h */,
+				BC85A9E22C6B570E003C1ABE /* KSRealtimeAnalyzer.m */,
+				BC85A9E32C6B570E003C1ABE /* KSSpectrumView.h */,
+				BC85A9E42C6B570E003C1ABE /* KSSpectrumView.m */,
+			);
+			path = MergeAudioAnimation;
+			sourceTree = "<group>";
+		};
 		BC89AC042AB083F500B077AF /* HotMusic */ = {
 			isa = PBXGroup;
 			children = (
@@ -5195,161 +5115,6 @@
 			path = RecommendMusic;
 			sourceTree = "<group>";
 		};
-		BC8A4545283DC33400094BBB /* CloudEngine */ = {
-			isa = PBXGroup;
-			children = (
-				BC8A4546283DC33400094BBB /* Controller */,
-				BC8A4552283DC33400094BBB /* Model */,
-				BC8A455F283DC33400094BBB /* View */,
-				BC8A4590283DC33400094BBB /* BASSMidiPlayer */,
-			);
-			path = CloudEngine;
-			sourceTree = "<group>";
-		};
-		BC8A4546283DC33400094BBB /* Controller */ = {
-			isa = PBXGroup;
-			children = (
-				BC8A4547283DC33400094BBB /* KSCloudViewController.h */,
-				BC8A4548283DC33400094BBB /* KSCloudViewController.m */,
-			);
-			path = Controller;
-			sourceTree = "<group>";
-		};
-		BC8A4552283DC33400094BBB /* Model */ = {
-			isa = PBXGroup;
-			children = (
-				BC8A4553283DC33400094BBB /* KSXMLInfoParse.h */,
-				BC8A4554283DC33400094BBB /* KYSourceParseManager.m */,
-				BC8A4555283DC33400094BBB /* CloudSongMessageModel.h */,
-				BC8A4556283DC33400094BBB /* KSParseMessageModel.h */,
-				BC8A4557283DC33400094BBB /* TBXML.m */,
-				BC8A4558283DC33400094BBB /* SubjectFinger.plist */,
-				BC8A4559283DC33400094BBB /* CloudSongMessageModel.m */,
-				BC8A455A283DC33400094BBB /* KSXMLInfoParse.m */,
-				BC8A455B283DC33400094BBB /* KYSourceParseManager.h */,
-				BC8A455C283DC33400094BBB /* KSParseMessageModel.m */,
-				BC8A455D283DC33400094BBB /* TBXML.h */,
-				BC8A455E283DC33400094BBB /* FingerList.plist */,
-			);
-			path = Model;
-			sourceTree = "<group>";
-		};
-		BC8A455F283DC33400094BBB /* View */ = {
-			isa = PBXGroup;
-			children = (
-				BC8A4571283DC33400094BBB /* beat */,
-				BC8A4575283DC33400094BBB /* Channel */,
-				BC8A4582283DC33400094BBB /* Help */,
-				BC8A4560283DC33400094BBB /* SettingView */,
-				BC8A457E283DC33400094BBB /* SoundCheckView */,
-				BC8A4579283DC33400094BBB /* SpeedSlider */,
-				BC8A456A283DC33400094BBB /* StaffView */,
-				BC8A4589283DC33400094BBB /* TipsAlert */,
-			);
-			path = View;
-			sourceTree = "<group>";
-		};
-		BC8A4560283DC33400094BBB /* SettingView */ = {
-			isa = PBXGroup;
-			children = (
-				BC8A4561283DC33400094BBB /* SettingPageView.h */,
-				BC8A4562283DC33400094BBB /* JudgePageView.h */,
-				BC8A4563283DC33400094BBB /* SettingPageView.xib */,
-				BC8A4564283DC33400094BBB /* JudgePageView.xib */,
-				BC8A4565283DC33400094BBB /* KSCloudSettingView.m */,
-				BC8A4566283DC33400094BBB /* SettingPageView.m */,
-				BC8A4567283DC33400094BBB /* JudgePageView.m */,
-				BC8A4568283DC33400094BBB /* KSCloudSettingView.xib */,
-				BC8A4569283DC33400094BBB /* KSCloudSettingView.h */,
-			);
-			path = SettingView;
-			sourceTree = "<group>";
-		};
-		BC8A456A283DC33400094BBB /* StaffView */ = {
-			isa = PBXGroup;
-			children = (
-				BC8A456D283DC33400094BBB /* CloudControlButton.h */,
-				BC8A4570283DC33400094BBB /* CloudControlButton.m */,
-				BC8A456B283DC33400094BBB /* ScoreAnimationView.h */,
-				BC8A456F283DC33400094BBB /* ScoreAnimationView.m */,
-				BC8A456C283DC33400094BBB /* StaffImageDisplayView.h */,
-				BC8A456E283DC33400094BBB /* StaffImageDisplayView.m */,
-			);
-			path = StaffView;
-			sourceTree = "<group>";
-		};
-		BC8A4571283DC33400094BBB /* beat */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			path = beat;
-			sourceTree = "<group>";
-		};
-		BC8A4575283DC33400094BBB /* Channel */ = {
-			isa = PBXGroup;
-			children = (
-				BC8A4576283DC33400094BBB /* TrackChooseView.m */,
-				BC8A4577283DC33400094BBB /* TrackChooseView.xib */,
-				BC8A4578283DC33400094BBB /* TrackChooseView.h */,
-			);
-			path = Channel;
-			sourceTree = "<group>";
-		};
-		BC8A4579283DC33400094BBB /* SpeedSlider */ = {
-			isa = PBXGroup;
-			children = (
-				BC8A457D283DC33400094BBB /* KSSliderView.h */,
-				BC8A457B283DC33400094BBB /* KSSliderView.m */,
-				BC8A457A283DC33400094BBB /* KSTrackingSlider.h */,
-				BC8A457C283DC33400094BBB /* KSTrackingSlider.m */,
-			);
-			path = SpeedSlider;
-			sourceTree = "<group>";
-		};
-		BC8A457E283DC33400094BBB /* SoundCheckView */ = {
-			isa = PBXGroup;
-			children = (
-				BC8A457F283DC33400094BBB /* SoundCheckView.m */,
-				BC8A4580283DC33400094BBB /* SoundCheckView.xib */,
-				BC8A4581283DC33400094BBB /* SoundCheckView.h */,
-			);
-			path = SoundCheckView;
-			sourceTree = "<group>";
-		};
-		BC8A4582283DC33400094BBB /* Help */ = {
-			isa = PBXGroup;
-			children = (
-				BC8A4583283DC33400094BBB /* CloudFeedbackView.h */,
-				BC8A4584283DC33400094BBB /* CloudHelpView.m */,
-				BC8A4585283DC33400094BBB /* CloudHelpView.xib */,
-				BC8A4586283DC33400094BBB /* CloudFeedbackView.m */,
-				BC8A4587283DC33400094BBB /* CloudHelpView.h */,
-				BC8A4588283DC33400094BBB /* CloudFeedbackView.xib */,
-			);
-			path = Help;
-			sourceTree = "<group>";
-		};
-		BC8A4589283DC33400094BBB /* TipsAlert */ = {
-			isa = PBXGroup;
-			children = (
-				BC8A458A283DC33400094BBB /* EvaluateResultAlert.xib */,
-				BC8A458B283DC33400094BBB /* EvaluateResultAlert.h */,
-				BC8A458C283DC33400094BBB /* NoWiredTipsAlert.h */,
-				BC8A458D283DC33400094BBB /* EvaluateResultAlert.m */,
-				BC8A458E283DC33400094BBB /* NoWiredTipsAlert.xib */,
-				BC8A458F283DC33400094BBB /* NoWiredTipsAlert.m */,
-			);
-			path = TipsAlert;
-			sourceTree = "<group>";
-		};
-		BC8A4590283DC33400094BBB /* BASSMidiPlayer */ = {
-			isa = PBXGroup;
-			children = (
-				BCA1135928A3A2B5007FAFB9 /* Source */,
-			);
-			path = BASSMidiPlayer;
-			sourceTree = "<group>";
-		};
 		BC8A45BF283DDD7100094BBB /* SoundFontFile */ = {
 			isa = PBXGroup;
 			children = (
@@ -5456,21 +5221,6 @@
 			path = LoadingManager;
 			sourceTree = "<group>";
 		};
-		BCA1135928A3A2B5007FAFB9 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				BCA1136428A3A2EA007FAFB9 /* BassMidiEngine.h */,
-				BCA1136528A3A2EA007FAFB9 /* BassMidiEngine.m */,
-				BCA1135F28A3A2D0007FAFB9 /* bassmidi.h */,
-				BCA1136028A3A2D0007FAFB9 /* bassmidi.txt */,
-				BCA1136128A3A2D0007FAFB9 /* bassmidi.xcframework */,
-				BCA1135C28A3A2BB007FAFB9 /* bass.h */,
-				BCA1135A28A3A2BB007FAFB9 /* bass.txt */,
-				BCA1135B28A3A2BB007FAFB9 /* bass.xcframework */,
-			);
-			path = Source;
-			sourceTree = "<group>";
-		};
 		BCB6340A27F6D29500ACFDCF /* Live */ = {
 			isa = PBXGroup;
 			children = (
@@ -6440,7 +6190,6 @@
 				BC106C3B2A9338A7000759A9 /* custom_loading.json in Resources */,
 				BC89AC1A2AB08FA100B077AF /* TenantMusicCollectionViewCell.xib in Resources */,
 				2723B63227F157D500E0B90B /* GroupSettingBodyView.xib in Resources */,
-				BCA1136228A3A2D0007FAFB9 /* bassmidi.txt in Resources */,
 				BCC0F65C2A8CD8F500C4EFA4 /* TxClassroomChatMineCell.xib in Resources */,
 				BC71D272288804CD0010F14B /* img_27.png in Resources */,
 				BCFE53F728128A9600AD6786 /* TeacherShowCell.xib in Resources */,
@@ -6480,7 +6229,6 @@
 				BCC583C028A9EC6400BAB4CF /* cloud_animation_15.png in Resources */,
 				BC119280280FB10900A716F7 /* AccompanyRemarkCell.xib in Resources */,
 				BCC409012AFCE6B500C60249 /* MusicPublicContentView.xib in Resources */,
-				BC8A45B6283DC33400094BBB /* NoWiredTipsAlert.xib in Resources */,
 				BC71D271288804CD0010F14B /* img_26.png in Resources */,
 				BC12639F28FF8E7400509E90 /* HomeRecommendMusicView.xib in Resources */,
 				BC00A6622BB58FDC00231B74 /* WMPlayer.bundle in Resources */,
@@ -6490,7 +6238,6 @@
 				BC11925A280FA85300A716F7 /* HomeworkSortView.xib in Resources */,
 				2723B62527F157D500E0B90B /* GroupNoticeCell.xib in Resources */,
 				BCC583D228A9EC6400BAB4CF /* cloud_animation.json in Resources */,
-				BC8A459E283DC33400094BBB /* FingerList.plist in Resources */,
 				275FA23D27E7356B00CFEA2E /* PasswordBodyView.xib in Resources */,
 				BC5367C4283F6D58008428E8 /* HomeLiveCourseView.xib in Resources */,
 				BC2DFF5D28C097DC0056105A /* styleAnimation.json in Resources */,
@@ -6524,7 +6271,6 @@
 				BCBFDF5228115DA40052AFE5 /* HomeIntroduceView.xib in Resources */,
 				BC71D277288804CD0010F14B /* img_36.png in Resources */,
 				BC71D250288804CD0010F14B /* img_6.png in Resources */,
-				BC8A45AF283DC33400094BBB /* SoundCheckView.xib in Resources */,
 				BCFDA63828BCA1C60022B497 /* HomeRecentCourseView.xib in Resources */,
 				BC119270280FAF7D00A716F7 /* AccompanyCourseInfoCell.xib in Resources */,
 				BC2DFF5828BE143A0056105A /* HomeTempLiveCell.xib in Resources */,
@@ -6542,7 +6288,6 @@
 				BC106C4C2A933E75000759A9 /* LiveRoomHeadView.xib in Resources */,
 				BCC583CF28A9EC6400BAB4CF /* cloud_animation_1.png in Resources */,
 				2723B5C427F157B100E0B90B /* KSChatListSearchView.xib in Resources */,
-				BC8A459A283DC33400094BBB /* SubjectFinger.plist in Resources */,
 				BC71D275288804CD0010F14B /* img_23.png in Resources */,
 				BC71D0F82881A2420010F14B /* iOS集成升级必读.pdf in Resources */,
 				BCC583CC28A9EC6400BAB4CF /* cloud_animation_5.png in Resources */,
@@ -6592,7 +6337,6 @@
 				BC42CAA42BEC8272001F076E /* RhythmView.xib in Resources */,
 				BC9AA0B72ABC1C2A00CD954D /* GroupQuitAlert.xib in Resources */,
 				BCB6348127F6D29600ACFDCF /* LiveSeatApplyCell.xib in Resources */,
-				BC8A45A4283DC33400094BBB /* KSCloudSettingView.xib in Resources */,
 				BC38C4602AFA095D00ABFCC2 /* MineWorksBottomView.xib in Resources */,
 				2723B62D27F157D500E0B90B /* GroupApplyMemberCell.xib in Resources */,
 				BCC0F6702A8CD8F500C4EFA4 /* MainToolButton.xib in Resources */,
@@ -6621,7 +6365,6 @@
 				BC27A076280FF61300F91E27 /* AccompanyDetailBottomView.xib in Resources */,
 				BCBFDF4D28115C7A0052AFE5 /* HomeHotCourseView.xib in Resources */,
 				BC71D2892888083B0010F14B /* tabbar5.json in Resources */,
-				BC8A45B4283DC33400094BBB /* EvaluateResultAlert.xib in Resources */,
 				BCC0F6B12A8CDD4000C4EFA4 /* class_stop.mp3 in Resources */,
 				BCBFDF3928110C6F0052AFE5 /* HomeNavView.xib in Resources */,
 				BC89AC0B2AB0841400B077AF /* TenantRecommendMusicView.xib in Resources */,
@@ -6650,7 +6393,6 @@
 				BC27A070280FF56C00F91E27 /* AccompanyStudentEvaCell.xib in Resources */,
 				2723B63927F157D500E0B90B /* GroupMemberListCell.xib in Resources */,
 				BCFCE44E28DD5C000051FED8 /* Low.wav in Resources */,
-				BC8A45A0283DC33400094BBB /* JudgePageView.xib in Resources */,
 				BC802D9428B897670079E350 /* LiveApplyingView.xib in Resources */,
 				BC71D244288804CD0010F14B /* img_10.png in Resources */,
 				BC0212F827FC4A080040569F /* SubjectImageCell.xib in Resources */,
@@ -6677,7 +6419,6 @@
 				BC119217280ED6A900A716F7 /* MyLessonSearchView.xib in Resources */,
 				BCC583BD28A9EC6400BAB4CF /* cloud_animation_25.png in Resources */,
 				BCC583BC28A9EC6400BAB4CF /* cloud_animation_19.png in Resources */,
-				BC8A459F283DC33400094BBB /* SettingPageView.xib in Resources */,
 				BC71D262288804CD0010F14B /* img_54.png in Resources */,
 				BC8C2C5A2823F57100FBA5D5 /* areainfo.json in Resources */,
 				BCFDA64E28BCA2000022B497 /* musicRoom_animation_3.png in Resources */,
@@ -6691,7 +6432,6 @@
 				BC71D24E288804CD0010F14B /* img_16.png in Resources */,
 				27F9033727E87C8B00C08A19 /* MineNavView.xib in Resources */,
 				BC38C4A32AFA4F6C00ABFCC2 /* TenantMineFunctionView.xib in Resources */,
-				BC8A45AB283DC33400094BBB /* TrackChooseView.xib in Resources */,
 				BCC0F6B32A8CDD4000C4EFA4 /* low_staff.png in Resources */,
 				BCB9FA47286EDCD7005D766B /* KSTipsAlert.xib in Resources */,
 				BCFDA64C28BCA2000022B497 /* live_animation_0.png in Resources */,
@@ -6715,11 +6455,9 @@
 				BC756CC828FE867000AA9ECB /* UserDetailBottomView.xib in Resources */,
 				BCFDA62628BC94480022B497 /* HomeNavSearchView.xib in Resources */,
 				BC71D0F42881A2420010F14B /* UMCommonLog.bundle in Resources */,
-				BCA1135D28A3A2BB007FAFB9 /* bass.txt in Resources */,
 				BC8A45C1283DDD7100094BBB /* synthgms.sf2 in Resources */,
 				BC71D24B288804CD0010F14B /* img_2.png in Resources */,
 				BC0D1F72281015B000C5D9E5 /* VideoCourseCell.xib in Resources */,
-				BC8A45B1283DC33400094BBB /* CloudHelpView.xib in Resources */,
 				BCECE24A2B3D670500C0D555 /* FeedbackSortView.xib in Resources */,
 				BCFDA64A28BCA2000022B497 /* accomapny_animation.json in Resources */,
 				BCECE2492B3D670500C0D555 /* FeedbackNavView.xib in Resources */,
@@ -6735,7 +6473,6 @@
 				BCCE95C92AB0363100AB6385 /* TenantDarkSearhView.xib in Resources */,
 				BC40B9FF281177BD00DEC0D1 /* HomeInformationCell.xib in Resources */,
 				BC31BF2E2B21925700F7D538 /* WidgetDotView.xib in Resources */,
-				BC8A45B3283DC33400094BBB /* CloudFeedbackView.xib in Resources */,
 				BCFDA65228BCA2000022B497 /* musicRoom_animation_0.png in Resources */,
 				BCC0F66B2A8CD8F500C4EFA4 /* ClassRoomTitleButton.xib in Resources */,
 				BC31BF1B2B21925700F7D538 /* TuningNavView.xib in Resources */,
@@ -6932,7 +6669,6 @@
 				BCB6347727F6D29600ACFDCF /* LiveRoomLikeLayer.m in Sources */,
 				BCC0F6532A8CD8F500C4EFA4 /* TXClassroomVideoListView.m in Sources */,
 				BC40B9F82811767A00DEC0D1 /* HotInformationHeadView.m in Sources */,
-				BC8A45AD283DC33400094BBB /* KSTrackingSlider.m in Sources */,
 				BC7663152827E49900C91A1D /* NotiferHeadView.m in Sources */,
 				2723B67F27F15D3D00E0B90B /* AboutUsViewController.m in Sources */,
 				2779356127E324A70010E277 /* KSAudioRecordManager.m in Sources */,
@@ -6943,7 +6679,6 @@
 				BC38C3EC2AF893B400ABFCC2 /* KSAudioPlayAnimationView.m in Sources */,
 				BCECE24E2B3D670500C0D555 /* CourseFileDisplayView.m in Sources */,
 				BCCE95CC2AB03BE200AB6385 /* TenantDragView.m in Sources */,
-				BC8A459C283DC33400094BBB /* KSXMLInfoParse.m in Sources */,
 				BC31BF2A2B21925700F7D538 /* WidgetBottomButtonView.m in Sources */,
 				BC106C392A9338A7000759A9 /* TXLiveVideoView.m in Sources */,
 				2779356527E324A70010E277 /* KSMediaManager.m in Sources */,
@@ -6960,16 +6695,13 @@
 				BC0078712BCD17ED0076CD22 /* GroupAlbumModel.m in Sources */,
 				BC43CAC92A88C9570011EB5D /* KSTXGroupChatViewController.m in Sources */,
 				275FA1DA27E7351900CFEA2E /* KSNetworkingManager.m in Sources */,
-				BC8A45B0283DC33400094BBB /* CloudHelpView.m in Sources */,
 				BCC0F6B62A8CDD4000C4EFA4 /* LocalRenderManager.m in Sources */,
 				BC106C042A933829000759A9 /* TXLiveMessageMemberUp.m in Sources */,
 				BCC0F6542A8CD8F500C4EFA4 /* TXChatBottomView.m in Sources */,
 				BCFC09DA2C48C8DE009A727F /* UserVip.m in Sources */,
 				BC02381928685087005560CA /* LiveAnimationView.m in Sources */,
 				BCC0F6122A8CD89400C4EFA4 /* TXClassroomViewController.m in Sources */,
-				BC8A45AA283DC33400094BBB /* TrackChooseView.m in Sources */,
 				BC106C3A2A9338A7000759A9 /* TXSeatContainerView.m in Sources */,
-				BC8A45B2283DC33400094BBB /* CloudFeedbackView.m in Sources */,
 				BC31BF322B21925700F7D538 /* WidgetSpeedView.m in Sources */,
 				BCC409062AFCE6B500C60249 /* VideoCropImageViewCell.m in Sources */,
 				BC60E3CD287D552800B05441 /* DeleteAccountBodyView.m in Sources */,
@@ -7005,10 +6737,10 @@
 				BCECE2552B3D670500C0D555 /* FeedbackNavView.m in Sources */,
 				BCC0F6042A8CD86C00C4EFA4 /* TXRTCService.m in Sources */,
 				BCB6347327F6D29600ACFDCF /* KSChatEmojiCollectionCell.m in Sources */,
-				BC8A4593283DC33400094BBB /* KSCloudViewController.m in Sources */,
 				BCFDA65C28BCAEB10022B497 /* HomePageBodyView.m in Sources */,
 				2723B62327F157D500E0B90B /* LFPopupMenuDefaultConfig.m in Sources */,
 				BC31BF2F2B21925700F7D538 /* IACircularSliderTrackLayer.m in Sources */,
+				BC85A9E62C6B570E003C1ABE /* KSRealtimeAnalyzer.m in Sources */,
 				BCB9091728530E9C00F5FF69 /* KSShopCardView.m in Sources */,
 				BCCDB4332AB1C03A003C8E5F /* TenantTicketAlert.m in Sources */,
 				BC27A071280FF56C00F91E27 /* AccompanyEvaluateCell.m in Sources */,
@@ -7059,11 +6791,9 @@
 				BC40BA1B281251ED00DEC0D1 /* HomeMessageModel.m in Sources */,
 				277935BD27E324A90010E277 /* FSCalendarConstants.m in Sources */,
 				BCB6347027F6D29600ACFDCF /* LiveSeatMember.m in Sources */,
-				BC8A45AC283DC33400094BBB /* KSSliderView.m in Sources */,
 				2723B62927F157D500E0B90B /* KSChatComplainController.m in Sources */,
 				BC2933002AAEFC810024D98E /* INSSettingViewController.m in Sources */,
 				BCB5B2D12ABAFE8E005BF25D /* HomeMusicSheetLayout.m in Sources */,
-				BC8A4599283DC33400094BBB /* TBXML.m in Sources */,
 				BC31BF0D2B21925700F7D538 /* WidgetViewController.m in Sources */,
 				BC542E4B28409E9F00633781 /* InstrumentChooseViewController.m in Sources */,
 				BC9AA0DE2ABC434900CD954D /* KSCustomLoadingView.m in Sources */,
@@ -7073,7 +6803,6 @@
 				BC38C3F82AF8B3E000ABFCC2 /* KSNewAlertView.m in Sources */,
 				275FA23527E7356B00CFEA2E /* UserInfoManager.m in Sources */,
 				BC106C132A933829000759A9 /* TXControlMemberMic.m in Sources */,
-				BC8A45AE283DC33400094BBB /* SoundCheckView.m in Sources */,
 				BC71D13A2887CEB70010F14B /* LaunchAnimationViewController.m in Sources */,
 				2723B67E27F15D3D00E0B90B /* ModifyPhoneCheckController.m in Sources */,
 				BC542E5D2840A60100633781 /* UserSettingViewController.m in Sources */,
@@ -7082,15 +6811,12 @@
 				BC31BF262B21925700F7D538 /* WMGaugeView.m in Sources */,
 				BCB9FA35286D7C2F005D766B /* GuideListView.m in Sources */,
 				BCC0F60E2A8CD86C00C4EFA4 /* TXSongSyncMessage.m in Sources */,
-				BC8A45A3283DC33400094BBB /* JudgePageView.m in Sources */,
 				2779355E27E324A70010E277 /* KSAudioRecordFileManager.m in Sources */,
 				BC119234280ED97C00A716F7 /* CourseForLiveCell.m in Sources */,
 				BC106C382A9338A7000759A9 /* LiveRoomConfirmAlert.m in Sources */,
 				BCFE53E72812765600AD6786 /* HomeHotAlbumCell.m in Sources */,
 				BC1D02432C0490AB001F6A94 /* KSMuteTipsView.m in Sources */,
 				BC89AC092AB0840E00B077AF /* TenantRecommendMusicView.m in Sources */,
-				BC8A459B283DC33400094BBB /* CloudSongMessageModel.m in Sources */,
-				BC8A45B7283DC33500094BBB /* NoWiredTipsAlert.m in Sources */,
 				BCC0F6722A8CD8F500C4EFA4 /* MainToolButton.m in Sources */,
 				277935B427E324A90010E277 /* FSCalendarDelegationProxy.m in Sources */,
 				BCC0F6CA2A8CDDFE00C4EFA4 /* ClassroomService.m in Sources */,
@@ -7180,7 +6906,6 @@
 				BC43CACB2A88C9570011EB5D /* KSTXBaseChatViewController.m in Sources */,
 				BC542E612840A60E00633781 /* UseBodyView.m in Sources */,
 				BCC0F6C22A8CDDEB00C4EFA4 /* Whiteboard.m in Sources */,
-				BC8A45A6283DC33400094BBB /* ScoreAnimationView.m in Sources */,
 				BCFC09D12C48B3D7009A727F /* KSAccompanyDraftViewController.m in Sources */,
 				BC2DFF4E28BE068D0056105A /* TeacherStyleFlowLayout.m in Sources */,
 				BC38C4582AFA095D00ABFCC2 /* MineWorksOpenDisplayCell.m in Sources */,
@@ -7193,7 +6918,6 @@
 				BCCE95ED2AB05ECB00AB6385 /* TenantHotAlbumView.m in Sources */,
 				275FA1E827E7351900CFEA2E /* CustomNavViewController.m in Sources */,
 				BCCE95C72AB0362A00AB6385 /* TenantDarkSearhView.m in Sources */,
-				BC8A45B5283DC33400094BBB /* EvaluateResultAlert.m in Sources */,
 				275FA24327E73DF600CFEA2E /* InstrumentDescView.m in Sources */,
 				BC28887C2A8102890064B773 /* KSConversationListController.m in Sources */,
 				275FA1ED27E7351900CFEA2E /* KSUpdateManager.m in Sources */,
@@ -7291,10 +7015,10 @@
 				BCC0F6642A8CD8F500C4EFA4 /* TXDanBottomView.m in Sources */,
 				BC119259280FA85300A716F7 /* HomeworkListCell.m in Sources */,
 				BC38C45E2AFA095D00ABFCC2 /* MineWorksBodyView.m in Sources */,
-				BCA1136628A3A2EA007FAFB9 /* BassMidiEngine.m in Sources */,
 				BCC0F6592A8CD8F500C4EFA4 /* TXChatAreaView.m in Sources */,
 				2723B5CD27F157BE00E0B90B /* GroupListModel.m in Sources */,
 				2723B63327F157D500E0B90B /* ChatComplainBodyView.m in Sources */,
+				BC85A9E72C6B570E003C1ABE /* KSSpectrumView.m in Sources */,
 				2779357927E324A70010E277 /* KSImageButton.m in Sources */,
 				BCC0F6E52A8CE24400C4EFA4 /* KSNewWhiteBoard.m in Sources */,
 				BCD959CC28DB0BAB00B70314 /* KSImageShareViewController.m in Sources */,
@@ -7312,7 +7036,6 @@
 				BC2888752A8101C80064B773 /* KSSearchResultListController.m in Sources */,
 				2723B66D27F15CFC00E0B90B /* ModifyNameBodyView.m in Sources */,
 				BC0D95262AC2AA0900E54D3F /* NewPwdModifyViewController.m in Sources */,
-				BC8A459D283DC33400094BBB /* KSParseMessageModel.m in Sources */,
 				BC31BF242B21925700F7D538 /* WMGaugeViewStyleFlatThin.m in Sources */,
 				BC9AA0BA2ABC288000CD954D /* ChatComplainBottomView.m in Sources */,
 				275FA23327E7356B00CFEA2E /* VefiCodeLoginController.m in Sources */,
@@ -7366,10 +7089,8 @@
 				BCC0F6712A8CD8F500C4EFA4 /* TXMainToolView.m in Sources */,
 				BC38C3F02AF893B400ABFCC2 /* KSMergeAudioControlView.m in Sources */,
 				BC7663172827E49900C91A1D /* NotiferMessageCell.m in Sources */,
-				BC8A45A7283DC33400094BBB /* CloudControlButton.m in Sources */,
 				BCC0F6C32A8CDDEB00C4EFA4 /* RoomMember.m in Sources */,
 				BC60E3D3287D592800B05441 /* KSPublicAlertView.m in Sources */,
-				BC8A4598283DC33400094BBB /* KYSourceParseManager.m in Sources */,
 				2779353527E324A60010E277 /* NSObject+ReadDocument.m in Sources */,
 				BC9AA0DD2ABC434900CD954D /* KSHudLoagingManager.m in Sources */,
 				2723B63427F157D500E0B90B /* GroupApplyMemberCell.m in Sources */,
@@ -7393,12 +7114,10 @@
 				BC802D9728BC4FC40079E350 /* HomeHotMusicView.m in Sources */,
 				275FA1E527E7351900CFEA2E /* KSAccompanyWebViewController.m in Sources */,
 				BC756CB628FE4E5D00AA9ECB /* KSChatTagView.m in Sources */,
-				BC8A45A5283DC33400094BBB /* StaffImageDisplayView.m in Sources */,
 				BC11923A280ED98E00A716F7 /* AccompanyCourseCell.m in Sources */,
 				BCFDA62F28BC99410022B497 /* HomeBannerView.m in Sources */,
 				BC119264280FA90100A716F7 /* HomeworkListModel.m in Sources */,
 				2723B5A327F1578300E0B90B /* KSChatListViewController.m in Sources */,
-				BC8A45A1283DC33400094BBB /* KSCloudSettingView.m in Sources */,
 				BC119271280FAF7D00A716F7 /* AccompanyCourseInfoCell.m in Sources */,
 				BC2DFF5728BE143A0056105A /* HomeTempLiveCell.m in Sources */,
 				BC8C2C592823F57100FBA5D5 /* AddressListModel.m in Sources */,
@@ -7410,7 +7129,6 @@
 				275FA22D27E7356B00CFEA2E /* ChatViewController.m in Sources */,
 				BCC0F6E22A8CE24400C4EFA4 /* KSWhiteboardRefreshView.m in Sources */,
 				BC802DB828BC8C780079E350 /* HomeHotVideoCourseView.m in Sources */,
-				BC8A45A2283DC33400094BBB /* SettingPageView.m in Sources */,
 				2723B62627F157D500E0B90B /* GroupApplyViewController.m in Sources */,
 				BC31BF302B21925700F7D538 /* IACircularSlider.m in Sources */,
 				BC119293280FBC1100A716F7 /* HomeworkAddView.m in Sources */,

+ 39 - 16
KulexiuForStudent/KulexiuForStudent/Common/Base/AccompanyWebView/AudioEnginePlayer.m

@@ -22,10 +22,14 @@
 
 @property (nonatomic, strong) AVAudioFormat *audioFormat;
 
+@property (nonatomic, strong) dispatch_queue_t sourceQueue;
+
 @property (nonatomic, assign) NSTimeInterval totalDuration;
 
 @property (nonatomic, assign) AVAudioFramePosition startPosition; // 开始位置
 
+@property (nonatomic, assign) BOOL isPlayEnd;  // 是否播放完成
+
 @property (nonatomic, assign) BOOL isInterrupt; // 是否被打断
 
 @end
@@ -148,24 +152,26 @@
 }
 
 - (void)prepareNativeSongWithUrl:(NSURL *)nativeMusicUrl {
-    [self loadAudioFile:nativeMusicUrl];
-    
-    if (self.audioFile && self.audioFormat) {
-        [self configEngine];
-        // connect node
-        [self.audioEngine connect:self.bgPlayer to:self.timePitchUnit format:self.audioFormat];
-        [self.audioEngine connect:self.timePitchUnit to:self.audioEngine.mainMixerNode format:self.audioFormat];
-        
-        [self.audioEngine prepare];
-        
-        [self startEngine];
-        if (self.audioEngine && self.audioEngine.isRunning) {
-            if (self.delegate && [self.delegate respondsToSelector:@selector(enginePlayerIsReadyPlay:)]) {
-                [self.delegate enginePlayerIsReadyPlay:self];
+    dispatch_async(self.sourceQueue, ^{
+        [self loadAudioFile:nativeMusicUrl];
+        if (self.audioFile && self.audioFormat) {
+            [self configEngine];
+            // connect node
+            [self.audioEngine connect:self.bgPlayer to:self.timePitchUnit format:self.audioFormat];
+            [self.audioEngine connect:self.timePitchUnit to:self.audioEngine.mainMixerNode format:self.audioFormat];
+            
+            [self.audioEngine prepare];
+            
+            [self startEngine];
+            if (self.audioEngine && self.audioEngine.isRunning) {
+                dispatch_main_async_safe(^{
+                    if (self.delegate && [self.delegate respondsToSelector:@selector(enginePlayerIsReadyPlay:)]) {
+                        [self.delegate enginePlayerIsReadyPlay:self];
+                    }
+                });
             }
         }
-    }
-        
+    });
 }
 
 - (void)startEngine {
@@ -259,6 +265,8 @@
 
 
 - (void)startTimer {
+    NSLog(@"----- start timer ");
+    self.isPlayEnd = NO;
     [self.timer setFireDate:[NSDate distantPast]];
 }
 
@@ -290,6 +298,15 @@
     if (self.delegate && [self.delegate respondsToSelector:@selector(updatePlayProgress:andTotalTime:andProgress:currentInterval:inPlayer:)]) {
         [self.delegate updatePlayProgress:currentTime andTotalTime:self.totalDuration andProgress:progress currentInterval:inteveral*1000 inPlayer:self];
     }
+//    NSLog(@"------- current progress %f", progress);
+    if (progress >= 1 && self.isPlayEnd == NO) {
+        self.isPlayEnd = YES;
+        NSLog(@"0---isPlayEnd--------");
+        // 播放完成
+        if (self.delegate && [self.delegate respondsToSelector:@selector(enginePlayFinished:)]) {
+            [self.delegate enginePlayFinished:self];
+        }
+    }
 }
 
 - (void)setRate:(float)rate {
@@ -350,4 +367,10 @@
     return NO;
 }
 
+- (dispatch_queue_t)sourceQueue {
+    if (!_sourceQueue) {
+        _sourceQueue = dispatch_queue_create("KSAudioEnginePlayer_queue", DISPATCH_QUEUE_SERIAL);
+    }
+    return _sourceQueue;
+}
 @end

+ 92 - 49
KulexiuForStudent/KulexiuForStudent/Common/Base/AccompanyWebView/KSAccompanyWebViewController.m

@@ -458,7 +458,6 @@
     if (isBack) { // 页面销毁才删除
         if (_AQManager) {
             [_AQManager freeAudioQueue];
-            _AQManager = nil;
         }
         // 如果退出评测页面 清除 playerEngine
         if (self.playerEngine) {
@@ -507,27 +506,26 @@
             else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"startEvaluating"]) { // 开始评测
                 [self configRecordManager];
                 self.hasSendStartMessage = NO;
-                PREMISSIONTYPE isOk = [RecordCheckManager checkMicPermissionAvaiable];
-                if (isOk == PREMISSIONTYPE_YES) {
-                    self.evaluatParm = [NSMutableDictionary dictionaryWithDictionary:parm];
-                    // 如果socket 连上了
-                    if (self.socketManager.socketReadyState == SR_OPEN) {
-                        NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
-                        NSString *sendData = [self configDataCommond:@"musicXml" body:content type:@"SOUND_COMPARE"];
-                        [self sendDataToSocketService:sendData];
-                        [self postMessage:parm];
-                        self.hasSendStartMessage = YES;
+                [RecordCheckManager checkMicPermissionAvaiableCallback:^(PREMISSIONTYPE type) {
+                    if (type == PREMISSIONTYPE_YES) {
+                        self.evaluatParm = [NSMutableDictionary dictionaryWithDictionary:parm];
+                        // 如果socket 连上了
+                        if (self.socketManager.socketReadyState == SR_OPEN) {
+                            NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
+                            NSString *sendData = [self configDataCommond:@"musicXml" body:content type:@"SOUND_COMPARE"];
+                            [self sendDataToSocketService:sendData];
+                            [self postMessage:parm];
+                            self.hasSendStartMessage = YES;
+                        }
+                        else {
+                            [self connectSocketService];
+                        }
                     }
                     else {
-                        [self connectSocketService];
+                        [self responseMessage:@"storageUnable" desc:@"没有麦克风访问权限" parm:parm];
+                        [self showAlertWithMessage:@"请开启麦克风访问权限" type:CHECKDEVICETYPE_MIC];
                     }
-                }
-                else {
-                    NSDictionary *postParm = @{@"api" : @"cancelEvaluating",
-                                               @"content" : @{@"reson":@"没有麦克风权限"}
-                    };
-                    [self postMessage:postParm];
-                }
+                }];
             }
             else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"endEvaluating"]) {// 停止评测
                 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
@@ -597,18 +595,9 @@
                 [self sendDataToSocketService:sendData];
             }
             else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"openCamera"]) { // 开启摄像头
-                PREMISSIONTYPE canOpenCamera = [RecordCheckManager checkCameraPremissionAvaiable];
-                PREMISSIONTYPE albumEnable = [RecordCheckManager checkPhotoLibraryPremissionAvaiable];
-
-                if (canOpenCamera == PREMISSIONTYPE_YES) {
-                    self.isCameraOpen = YES;
-                    [self.videoRecordManager setIgnoreAudio:YES];
-                    [self.videoRecordManager configSessiondisplayInView:self.viewContainer];
-                    [self postMessage:parm];
-                }
-                if (albumEnable == PREMISSIONTYPE_NO) {
-                    [self showAlertWithMessage:@"请开启相册访问权限" type:CHECKDEVICETYPE_CAMREA];
-                }
+                [RecordCheckManager checkCameraPremissionAvaiableCallback:^(PREMISSIONTYPE type) {
+                    [self afterCheckCameraCheckAlbum:type parm:parm];
+                }];
                 
             }
             else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"closeCamera"]) { // 关闭摄像头
@@ -619,14 +608,18 @@
                 [self postMessage:parm];
             }
             else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"startCapture"]) { // 开始录制
-                PREMISSIONTYPE isOk = [RecordCheckManager checkPhotoLibraryPremissionAvaiable];
-                if (isOk == PREMISSIONTYPE_YES) {
-                    
-                    [self.videoRecordManager setIgnoreAudio:YES];
-                    self.videoRecordManager.audioUrl = self.AQManager.audioUrl;
-                    [self.videoRecordManager startRecord];
-                    [self postMessage:parm];
-                }
+                [RecordCheckManager checkPhotoLibraryPremissionAvaiableCallback:^(PREMISSIONTYPE type) {
+                    if (type == PREMISSIONTYPE_YES) {
+                        [self.videoRecordManager setIgnoreAudio:YES];
+                        self.videoRecordManager.audioUrl = self.AQManager.audioUrl;
+                        [self.videoRecordManager startRecord];
+                        [self postMessage:parm];
+                    }
+                    else {
+//                        [self responseMessage:@"storageUnable" desc:@"没有相册存储权限" parm:parm];
+//                        [self showAlertWithMessage:@"开启相册存储" type:CHECKDEVICETYPE_CAMREA];
+                    }
+                }];
             }
             else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"endCapture"]) { // 结束录制
                 if (self->_videoRecordManager) {
@@ -919,16 +912,25 @@
                 }
             }
             // 跟音
-            else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"cloudToggleFollow"]) {
-                NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
-                NSString *status = [content ks_stringValueForKey:@"state"];
-                if ([status isEqualToString:@"start"]) { // 开始
-                    [self configAudioSession];
-                    [self startTuner];
-                }
-                else if ([status isEqualToString:@"end"]) { // 结束
-                    [self stopTuner];
-                }
+            else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"cloudToggleFollow"]) { // 跟音
+                [RecordCheckManager checkMicPermissionAvaiableCallback:^(PREMISSIONTYPE type) {
+                    if (type == PREMISSIONTYPE_YES) {
+                        NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
+                        NSString *status = [content ks_stringValueForKey:@"state"];
+                        if ([status isEqualToString:@"start"]) { // 开始
+                            [self configAudioSession];
+                            [self startTuner];
+                        }
+                        else if ([status isEqualToString:@"end"]) { // 结束
+                            [self stopTuner];
+                        }
+                        [self postMessage:parm];
+                    }
+                    else {
+                        [self responseMessage:@"storageUnable" desc:@"没有麦克风权限" parm:parm];
+                        [self showAlertWithMessage:@"请开启麦克风访问权限" type:CHECKDEVICETYPE_MIC];
+                    }
+                }];
             }
             else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"cloudAccompanyMessage"]) { // 获取伴奏 废弃⚠️
                 
@@ -1003,6 +1005,47 @@
     }
 }
 
+- (void)afterCheckCameraCheckAlbum:(PREMISSIONTYPE)cameraType parm:(NSDictionary *)sourceParm {
+    
+    [RecordCheckManager checkPhotoLibraryPremissionAvaiableCallback:^(PREMISSIONTYPE type) {
+        if (type == PREMISSIONTYPE_YES && cameraType == PREMISSIONTYPE_YES) {
+            self.isCameraOpen = YES;
+            [self.videoRecordManager setIgnoreAudio:YES];
+            [self.videoRecordManager configSessiondisplayInView:self.viewContainer];
+            [self postMessage:sourceParm];
+        }
+        else { //
+            
+            NSString *content = @"";
+            NSString *des = @"";;
+            if (cameraType == PREMISSIONTYPE_NO && type == PREMISSIONTYPE_NO) {
+                des = @"没有相机和相册访问权限";
+                content = @"请开启相机和相册访问权限";
+            }
+            else if (cameraType == PREMISSIONTYPE_NO && type == PREMISSIONTYPE_YES) {
+                des = @"没有相机访问权限";
+                content = @"请开启相机访问权限";
+            }
+            else if (cameraType == PREMISSIONTYPE_YES && type == PREMISSIONTYPE_NO) {
+                des = @"没有相册访问权限";
+                content = @"请开启相册访问权限";
+            }
+            [self responseMessage:@"storageUnable" desc:des parm:sourceParm];
+            [self showAlertWithMessage:content type:CHECKDEVICETYPE_CAMREA];
+
+        }
+    }];
+}
+
+- (void)responseMessage:(NSString *)reson desc:(NSString *)desc parm:(NSDictionary *)parm {
+    NSMutableDictionary *sendContent = [NSMutableDictionary dictionaryWithDictionary:[parm ks_dictionaryValueForKey:@"content"]];
+    [sendContent setValue:reson forKey:@"reson"];
+    [sendContent setValue:desc forKey:@"des"];
+    NSMutableDictionary *sendParm = [NSMutableDictionary dictionaryWithDictionary:parm];
+    [sendParm setValue:sendContent forKey:@"content"];
+    [self postMessage:sendParm];
+}
+
 - (void)musicPublishCallBack:(NSDictionary *)content {
     NSMutableDictionary *parm = [NSMutableDictionary dictionary];
     [parm setValue:@"hideComplexButton" forKey:@"api"];

+ 40 - 21
KulexiuForStudent/KulexiuForStudent/Common/Base/AccompanyWebView/KSCloudWebManager.m

@@ -53,29 +53,48 @@
 }
 
 - (void)showWebView:(NSDictionary *)parm fromController:(CustomNavViewController *)navCtrl {
-    PREMISSIONTYPE micEnable = [RecordCheckManager checkMicPermissionAvaiable];
-    PREMISSIONTYPE cameraEnable = [RecordCheckManager checkCameraPremissionAvaiable];
-    if (micEnable == PREMISSIONTYPE_YES && cameraEnable == PREMISSIONTYPE_YES) { //
-        KSCloudWebViewController *ctrl = [[KSCloudWebViewController alloc] init];
-        ctrl.webViewDelegate = self;
-        ctrl.url = [parm ks_stringValueForKey:@"url"];
-        ctrl.parmDic = parm;
-        NSInteger orientation = [parm ks_integerValueForKey:@"orientation"];
-        BOOL isLandScape = orientation == 0 ? YES : NO;
-        ctrl.ks_landScape = isLandScape;
-        [navCtrl pushViewController:ctrl animated:YES];
-    }
-    else {
-        if (micEnable == PREMISSIONTYPE_NO && cameraEnable == PREMISSIONTYPE_NO) { // 如果麦克风权限和摄像头权限都没有
-            [self showAlertWithMessage:@"请开启相机和麦克风访问权限" type:CHECKDEVICETYPE_BOTH];
-        }
-        else if (micEnable == PREMISSIONTYPE_NO) { // 如果没有麦克风权限
-            [self showAlertWithMessage:@"请开启麦克风访问权限" type:CHECKDEVICETYPE_MIC];
+    // 先检测相机 再检测麦克风
+    [RecordCheckManager checkCameraPremissionAvaiableCallback:^(PREMISSIONTYPE type) {
+        
+        [self afterCheckCameraCheckMic:type parm:parm fromController:navCtrl];
+    }];
+}
+
+- (void)afterCheckCameraCheckMic:(PREMISSIONTYPE)cameraType parm:(NSDictionary *)sourceParm fromController:(CustomNavViewController *)navCtrl {
+    
+    [RecordCheckManager checkMicPermissionAvaiableCallback:^(PREMISSIONTYPE type) {
+        if (type == PREMISSIONTYPE_YES && cameraType == PREMISSIONTYPE_YES) {
+            NSDictionary *valueDic = [sourceParm ks_dictionaryValueForKey:@"content"];
+            
+            KSCloudWebViewController *ctrl = [[KSCloudWebViewController alloc] init];
+            ctrl.webViewDelegate = self;
+            ctrl.url = [valueDic ks_stringValueForKey:@"url"];
+            ctrl.parmDic = valueDic;
+            NSInteger orientation = [valueDic ks_integerValueForKey:@"orientation"];
+            BOOL isLandScape = orientation == 0 ? YES : NO;
+            ctrl.ks_landScape = isLandScape;
+            [navCtrl pushViewController:ctrl animated:YES];
         }
-        else if (cameraEnable == PREMISSIONTYPE_NO) { // 如果没有摄像头权限
-            [self showAlertWithMessage:@"请开启相机访问权限" type:CHECKDEVICETYPE_CAMREA];
+        else { //
+            
+            NSString *content = @"";
+            CHECKDEVICETYPE checkType = CHECKDEVICETYPE_BOTH;
+            if (cameraType == PREMISSIONTYPE_NO && type == PREMISSIONTYPE_NO) {
+                content = @"请开启相机和麦克风访问权限";
+                checkType = CHECKDEVICETYPE_BOTH;
+            }
+            else if (cameraType == PREMISSIONTYPE_NO && type == PREMISSIONTYPE_YES) {
+                content = @"请开启相机访问权限";
+                checkType = CHECKDEVICETYPE_CAMREA;
+            }
+            else if (cameraType == PREMISSIONTYPE_YES && type == PREMISSIONTYPE_NO) {
+                content = @"请开启麦克风访问权限";
+                checkType = CHECKDEVICETYPE_MIC;
+            }
+            [self showAlertWithMessage:content type:checkType];
+
         }
-    }
+    }];
 }
 
 - (void)showAlertWithMessage:(NSString *)message type:(CHECKDEVICETYPE)deviceType {

+ 62 - 46
KulexiuForStudent/KulexiuForStudent/Common/Base/WebView/KSBaseWKWebViewController.m

@@ -395,37 +395,19 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
     }
     
     else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"openAccompanyWebView"]) { // 打开伴奏
-        PREMISSIONTYPE micEnable = [RecordCheckManager checkMicPermissionAvaiable];
-        PREMISSIONTYPE cameraEnable = [RecordCheckManager checkCameraPremissionAvaiable];
-        if (micEnable == PREMISSIONTYPE_YES && cameraEnable == PREMISSIONTYPE_YES) { // 如果麦克风和摄像头权限都有
-            NSDictionary *valueDic = [parm ks_dictionaryValueForKey:@"content"];
-            KSAccompanyWebViewController *detailCtrl = [[KSAccompanyWebViewController alloc] init];
-            detailCtrl.url = [valueDic ks_stringValueForKey:@"url"];
-            detailCtrl.parmDic = valueDic;
-            NSInteger orientation = [valueDic ks_integerValueForKey:@"orientation"];
-            BOOL isLandScape = orientation == 0 ? YES : NO;
-            detailCtrl.ks_landScape = isLandScape;
-            [self postMessage:parm];
-            [self.navigationController pushViewController:detailCtrl animated:YES];
-        }
-        else {
-            if (micEnable == PREMISSIONTYPE_NO && cameraEnable == PREMISSIONTYPE_NO) { // 如果麦克风权限和摄像头权限都没有
-                [self showAlertWithMessage:@"请开启相机和麦克风访问权限" type:CHECKDEVICETYPE_BOTH];
-            }
-            else if (micEnable == PREMISSIONTYPE_NO) { // 如果没有麦克风权限
-                [self showAlertWithMessage:@"请开启麦克风访问权限" type:CHECKDEVICETYPE_MIC];
-            }
-            else if (cameraEnable == PREMISSIONTYPE_NO) { // 如果没有摄像头权限
-                [self showAlertWithMessage:@"请开启相机访问权限" type:CHECKDEVICETYPE_CAMREA];
-            }
-        }
+        [RecordCheckManager checkCameraPremissionAvaiableCallback:^(PREMISSIONTYPE type) {
+            [self afterCheckCameraCheckMic:type parm:parm];
+        }];
     }
     else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"checkAlbum"]) { // 判断权限
-        [self postMessage:parm];
-        PREMISSIONTYPE albumEnable = [RecordCheckManager checkPhotoLibraryPremissionAvaiable];
-        if (albumEnable == PREMISSIONTYPE_NO) {
-            [self showAlertWithMessage:@"请开启相册访问权限" type:CHECKDEVICETYPE_CAMREA];
-        }
+        [RecordCheckManager checkPhotoLibraryPremissionAvaiableCallback:^(PREMISSIONTYPE type) {
+            if (type == PREMISSIONTYPE_YES) {
+                [self postMessage:parm];
+            }
+            else {
+                [self showAlertWithMessage:@"请开启相册访问权限" type:CHECKDEVICETYPE_CAMREA];
+            }
+        }];
     }
     else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"shareAchievements"]) { // 分享
         //
@@ -496,25 +478,24 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
     }
     else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"savePicture"]) { // 保存图片到相册
         // 判断相册权限
-        PREMISSIONTYPE albumEnable = [RecordCheckManager checkPhotoLibraryPremissionAvaiable];
-        if (albumEnable == PREMISSIONTYPE_YES) { // 如果有权限
-            NSDictionary *valueDic = [parm ks_dictionaryValueForKey:@"content"];
-            NSString *base64String = [valueDic ks_stringValueForKey:@"base64"];
-            UIImage *saveImage = [self imageWithBase64String:base64String];
-            [[TZImageManager manager] savePhotoWithImage:saveImage completion:^(PHAsset *asset, NSError *error) {
-                if (!error) {
-                    [self savePicCallback:[valueDic ks_stringValueForKey:@"uuid"] isSuccess:YES];
-                }
-                else {
-                    [self savePicCallback:[valueDic ks_stringValueForKey:@"uuid"] isSuccess:NO];
-                }
-            }];
-        }
-        else {
-            if (albumEnable == PREMISSIONTYPE_NO) {
+        [RecordCheckManager checkPhotoLibraryPremissionAvaiableCallback:^(PREMISSIONTYPE type) {
+            if (type == PREMISSIONTYPE_YES) {
+                NSDictionary *valueDic = [parm ks_dictionaryValueForKey:@"content"];
+                NSString *base64String = [valueDic ks_stringValueForKey:@"base64"];
+                UIImage *saveImage = [self imageWithBase64String:base64String];
+                [[TZImageManager manager] savePhotoWithImage:saveImage completion:^(PHAsset *asset, NSError *error) {
+                    if (!error) {
+                        [self savePicCallback:[valueDic ks_stringValueForKey:@"uuid"] isSuccess:YES];
+                    }
+                    else {
+                        [self savePicCallback:[valueDic ks_stringValueForKey:@"uuid"] isSuccess:NO];
+                    }
+                }];
+            }
+            else {
                 [self showAlertWithMessage:@"请开启相册访问权限" type:CHECKDEVICETYPE_CAMREA];
             }
-        }
+        }];
     }
     else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"getVersion"]) {
         NSDictionary *valueDic = [parm ks_dictionaryValueForKey:@"content"];
@@ -728,6 +709,41 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
     
 }
 
+- (void)afterCheckCameraCheckMic:(PREMISSIONTYPE)cameraType parm:(NSDictionary *)sourceParm {
+    
+    [RecordCheckManager checkMicPermissionAvaiableCallback:^(PREMISSIONTYPE type) {
+        if (type == PREMISSIONTYPE_YES && cameraType == PREMISSIONTYPE_YES) {
+            NSDictionary *valueDic = [sourceParm ks_dictionaryValueForKey:@"content"];
+            KSAccompanyWebViewController *detailCtrl = [[KSAccompanyWebViewController alloc] init];
+            detailCtrl.url = [valueDic ks_stringValueForKey:@"url"];
+            detailCtrl.parmDic = valueDic;
+            NSInteger orientation = [valueDic ks_integerValueForKey:@"orientation"];
+            BOOL isLandScape = orientation == 0 ? YES : NO;
+            detailCtrl.ks_landScape = isLandScape;
+            [self postMessage:sourceParm];
+            [self.navigationController pushViewController:detailCtrl animated:YES];
+        }
+        else { //
+            
+            NSString *content = @"";
+            CHECKDEVICETYPE checkType = CHECKDEVICETYPE_BOTH;
+            if (cameraType == PREMISSIONTYPE_NO && type == PREMISSIONTYPE_NO) {
+                content = @"请开启相机和麦克风访问权限";
+                checkType = CHECKDEVICETYPE_BOTH;
+            }
+            else if (cameraType == PREMISSIONTYPE_NO && type == PREMISSIONTYPE_YES) {
+                content =  @"请开启相机访问权限";
+                checkType = CHECKDEVICETYPE_CAMREA;
+            }
+            else if (cameraType == PREMISSIONTYPE_YES && type == PREMISSIONTYPE_NO) {
+                content = @"请开启麦克风访问权限";
+                checkType = CHECKDEVICETYPE_MIC;
+            }
+            [self showAlertWithMessage:content type:checkType];
+        }
+    }];
+}
+
 - (void)downloadWithParm:(NSDictionary *)parm {
     MJWeakSelf;
     [COURSEWARE_MANAGER downloadCourseWithParm:parm callback:^(NSDictionary * _Nonnull sendParm) {

+ 71 - 51
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSMergeAudioControlView.m

@@ -9,7 +9,7 @@
 #import "UIView+KSCovertImage.h"
 #define MAX_OFFSET (600)
 
-@interface KSMergeAudioControlView ()<UIGestureRecognizerDelegate>
+@interface KSMergeAudioControlView ()
 
 @property (weak, nonatomic) IBOutlet UIView *bgView;
 
@@ -123,15 +123,6 @@
 }
 
 #pragma mark ----- 音量控制
-- (IBAction)changeRecordVolume:(UISlider *)sender {
-//    [self configRecordVolumeValue:sender.value];
-    
-}
-
-- (IBAction)changeBgVolume:(UISlider *)sender {
-//    [self configBgVolumeValue:sender.value];
-    
-}
 
 - (void)configRecordVolumeValue:(NSInteger)volume {
     self.recordVolume = volume;
@@ -146,9 +137,6 @@
             self.recordBubble.hidden = NO;
         }
     }];
-    if (self.callback) {
-        self.callback(MERGEACTION_MODIFY, self.recordVolume, self.bgVolume, self.offsetTime);
-    }
 }
 
 - (void)configBgVolumeValue:(NSInteger)volume {
@@ -162,9 +150,6 @@
             self.bgBubble.hidden =NO;
         }
     }];
-    if (self.callback) {
-        self.callback(MERGEACTION_MODIFY, self.recordVolume, self.bgVolume, self.offsetTime);
-    }
 }
 
 - (IBAction)cancleMerge:(id)sender {
@@ -196,9 +181,6 @@
 }
 
 - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
-    if (![[(UITouch *)touches.anyObject view] isEqual:self.sliderView] && ![[(UITouch *)touches.anyObject view] isEqual:self.recordGestureView] && ![[(UITouch *)touches.anyObject view] isEqual:self.bgGestureView] && ![[(UITouch *)touches.anyObject view] isEqual:self]) {
-        return;
-    }
     [super touchesMoved:touches withEvent:event];
     if ([[(UITouch *)touches.anyObject view] isEqual:self.sliderView]) {
         CGPoint tempPoint = [touches.anyObject locationInView:self.sliderView];
@@ -228,7 +210,6 @@
             xPosition = width;
         }
         NSInteger value =  (xPosition / width) * 100;
-         NSLog(@"---- record volume ---- %zd", value);
         [self.recordSlider setValue:value animated:YES];
         [self configRecordVolumeValue:value];
     }
@@ -243,34 +224,90 @@
             xPosition = width;
         }
         NSInteger value =  (xPosition / width) * 100;
-         NSLog(@"---- bg volume ---- %zd", value);
         [self.bgSlider setValue:value animated:YES];
         [self configBgVolumeValue:value];
     }
 }
 
 - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
+    [super touchesEnded:touches withEvent:event];
     if ([[(UITouch *)touches.anyObject view] isEqual:self.recordGestureView]) {
-        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(500 * NSEC_PER_MSEC)), dispatch_get_main_queue(), ^{
-            self.recordBubble.hidden = YES;
-        });
-        return;
+        CGPoint tempPoint = [touches.anyObject locationInView:self.recordGestureView];
+        CGFloat xPosition = tempPoint.x;
+        CGFloat width = self.recordGestureView.frame.size.width;
+        if (xPosition < 0) {
+            xPosition = 0;
+        }
+        else if (xPosition > width) {
+            xPosition = width;
+        }
+        NSInteger value =  (xPosition / width) * 100;
+        [self refreshRecordValue:value];
     }
     else if ([[(UITouch *)touches.anyObject view] isEqual:self.bgGestureView]) {
-        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(500 * NSEC_PER_MSEC)), dispatch_get_main_queue(), ^{
-            self.bgBubble.hidden = YES;
-        });
-        return;
+        
+        CGPoint tempPoint = [touches.anyObject locationInView:self.bgGestureView];
+        CGFloat xPosition = tempPoint.x;
+        CGFloat width = self.recordGestureView.frame.size.width;
+        if (xPosition < 0) {
+            xPosition = 0;
+        }
+        else if (xPosition > width) {
+            xPosition = width;
+        }
+        NSInteger value =  (xPosition / width) * 100;
+        [self refreshBgValue:value];
+        
     }
-    if (![[(UITouch *)touches.anyObject view] isEqual:self.sliderView] && ![[(UITouch *)touches.anyObject view] isEqual:self]) {
-        return;
+    else if ([[(UITouch *)touches.anyObject view] isEqual:self.sliderView]) {
+        CGPoint tempPoint = [touches.anyObject locationInView:self.sliderView];
+        if (tempPoint.x <= 90.5) {
+            NSInteger offset = (NSInteger)(tempPoint.x - 90.5) / 3 * 10 * 2;
+            if (offset < -MAX_OFFSET) {
+                offset = -MAX_OFFSET;
+            }
+            self.offsetTime = offset;
+        }
+        else if (tempPoint.x > 90.5) {
+            NSInteger offset = (NSInteger)(tempPoint.x - 90.5) / 3 * 10 * 2;
+            if (offset > MAX_OFFSET) {
+                offset = MAX_OFFSET;
+            }
+            self.offsetTime = offset;
+        }
+        NSLog(@"---- offset - %zd", self.offsetTime);
+        if (self.callback) {
+            self.callback(MERGEACTION_DELAY, self.recordVolume, self.bgVolume, self.offsetTime);
+        }
     }
-    [super touchesEnded:touches withEvent:event];
+}
 
+- (void)refreshRecordValue:(NSInteger)value {
+    NSLog(@"---- record volume ---- %zd", value);
+    [self.recordSlider setValue:value animated:NO];
+    [self configRecordVolumeValue:value];
     if (self.callback) {
-        self.callback(MERGEACTION_DELAY, self.recordVolume, self.bgVolume, self.offsetTime);
+        self.callback(MERGEACTION_MODIFY, self.recordVolume, self.bgVolume, self.offsetTime);
     }
-    
+    @weakObj(self);
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(500 * NSEC_PER_MSEC)), dispatch_get_main_queue(), ^{
+        @strongObj(self);
+        self.recordBubble.hidden = YES;
+    });
+}
+
+- (void)refreshBgValue:(NSInteger)value {
+    NSLog(@"---- bg volume ---- %zd", value);
+    [self.bgSlider setValue:value animated:NO];
+    [self configBgVolumeValue:value];
+    if (self.callback) {
+        self.callback(MERGEACTION_MODIFY, self.recordVolume, self.bgVolume, self.offsetTime);
+    }
+    @weakObj(self);
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(500 * NSEC_PER_MSEC)), dispatch_get_main_queue(), ^{
+        @strongObj(self);
+        self.bgBubble.hidden = YES;
+    });
 }
 
 - (IBAction)leftAction:(id)sender {
@@ -301,23 +338,6 @@
     }
 }
 
-//进度条的点击事件
-- (void)actionTapGesture:(UITapGestureRecognizer *)gesture {
-    if (gesture.view == self.recordGestureView) {
-        CGPoint touchLocation = [gesture locationInView:self.recordGestureView];
-        CGFloat value = (self.recordSlider.maximumValue - self.recordSlider.minimumValue) * (touchLocation.x/self.recordSlider.frame.size.width);
-        [self.recordSlider setValue:value animated:YES];
-        [self configRecordVolumeValue:value];
-    }
-    else {
-        CGPoint touchLocation = [gesture locationInView:self.bgGestureView];
-        CGFloat value = (self.bgSlider.maximumValue - self.bgSlider.minimumValue) * (touchLocation.x/self.bgSlider.frame.size.width);
-        [self.bgSlider setValue:value animated:YES];
-        [self configBgVolumeValue:value];
-    }
-    
-}
-
 #pragma mark ------ lazying
 - (void)setOffsetTime:(NSInteger)offsetTime {
     _offsetTime = offsetTime;

+ 0 - 6
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSMergeAudioControlView.xib

@@ -44,9 +44,6 @@
                             <color key="minimumTrackTintColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                             <color key="maximumTrackTintColor" red="0.90980392156862744" green="0.92549019607843142" blue="0.94509803921568625" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                             <color key="thumbTintColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <connections>
-                                <action selector="changeRecordVolume:" destination="iN0-l3-epB" eventType="valueChanged" id="WcD-V3-Jqt"/>
-                            </connections>
                         </slider>
                         <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="伴奏音量" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="if2-R5-Tul">
                             <rect key="frame" x="26" y="145" width="58" height="17"/>
@@ -59,9 +56,6 @@
                             <color key="minimumTrackTintColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                             <color key="maximumTrackTintColor" red="0.90980392156862744" green="0.92549019607843142" blue="0.94509803921568625" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                             <color key="thumbTintColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <connections>
-                                <action selector="changeBgVolume:" destination="iN0-l3-epB" eventType="valueChanged" id="vwy-ge-2aE"/>
-                            </connections>
                         </slider>
                         <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="DAF-iV-Mgw">
                             <rect key="frame" x="26" y="173" width="247" height="40"/>

+ 8 - 0
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSPlayerSliderView.m

@@ -77,6 +77,13 @@
     self.progressTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(actionTapGesture:)];
     self.progressTap.delegate = self;
     [self.progressSlider addGestureRecognizer:self.progressTap];
+    // 获取 UISlider 内部的 panGestureRecognizer 并设置优先级
+    for (UIGestureRecognizer *gestureRecognizer in self.progressSlider.gestureRecognizers) {
+        if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
+            [self.progressTap requireGestureRecognizerToFail:gestureRecognizer];
+            break;
+        }
+    }
 }
 
 
@@ -125,6 +132,7 @@
 
 //视频进度条的点击事件
 - (void)actionTapGesture:(UITapGestureRecognizer *)sender {
+    self.isDragingSlider = NO;
     CGPoint touchLocation = [sender locationInView:self.progressSlider];
     CGFloat value = (self.progressSlider.maximumValue - self.progressSlider.minimumValue) * (touchLocation.x/self.progressSlider.frame.size.width);
     [self.progressSlider setValue:value animated:YES];

+ 27 - 0
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/MergeAudioAnimation/KSRealtimeAnalyzer.h

@@ -0,0 +1,27 @@
+//
+//  KSRealtimeAnalyzer.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2024/7/29.
+//
+
+#import <Foundation/Foundation.h>
+#import <AVFoundation/AVFoundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSRealtimeAnalyzer : NSObject
+
+@property (nonatomic, assign) BOOL isAnalise; // 是否正在分析中
+
+@property (nonatomic, assign) NSInteger frequencyBands; // 频带数量
+@property (nonatomic, assign) float startFrequency; // 起始频率
+@property (nonatomic, assign) float endFrequency; // 截止频率
+@property (nonatomic, assign) float spectrumSmooth; // 频谱平滑
+
+- (instancetype)initWithFFTSize:(NSInteger)fftSize;
+- (NSArray<NSArray<NSNumber *> *> *)analyseWithBuffer:(AVAudioPCMBuffer *)buffer;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 256 - 0
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/MergeAudioAnimation/KSRealtimeAnalyzer.m

@@ -0,0 +1,256 @@
+//
+//  KSRealtimeAnalyzer.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2024/7/29.
+//
+
+#import "KSRealtimeAnalyzer.h"
+#import <Accelerate/Accelerate.h>
+
+@interface KSRealtimeAnalyzer ()
+
+@property (nonatomic, assign) NSInteger fftSize;
+@property (nonatomic, assign) FFTSetup fftSetup;
+@property (nonatomic, strong) NSArray<NSArray<NSNumber *> *> *bands;
+@property (nonatomic, strong) NSMutableArray<NSMutableArray<NSNumber *> *> *spectrumBuffer;
+
+@property (nonatomic, assign) float *realp;
+@property (nonatomic, assign) float *imagp;
+
+@property (nonatomic, strong) NSArray<NSNumber *> *cachedFrequencyWeights;
+
+@end
+
+@implementation KSRealtimeAnalyzer
+
+- (instancetype)initWithFFTSize:(NSInteger)fftSize {
+    self = [super init];
+    if (self) {
+        _fftSize = fftSize;
+        _fftSetup = vDSP_create_fftsetup(log2(_fftSize), FFT_RADIX2);
+        _realp = (float *)calloc(_fftSize / 2, sizeof(float));
+        _imagp = (float *)calloc(_fftSize / 2, sizeof(float));
+        _frequencyBands = 80;
+        _startFrequency = 100.0;
+        _endFrequency = 18000.0;
+        _spectrumSmooth = 0.5;
+        _spectrumBuffer = [NSMutableArray array];
+        [self setupBands];
+        _cachedFrequencyWeights = [self createFrequencyWeights];
+    }
+    return self;
+}
+
+- (void)dealloc {
+    vDSP_destroy_fftsetup(_fftSetup);
+    free(_realp);
+    free(_imagp);
+    NSLog(@"-------KSRealtimeAnalyzer dealloc");
+}
+
+- (void)setupBands {
+    NSMutableArray *bands = [NSMutableArray array];
+    float n = log2(self.endFrequency / self.startFrequency) / self.frequencyBands;
+    float lowerFrequency = self.startFrequency;
+
+    for (NSInteger i = 0; i < self.frequencyBands; i++) {
+        float upperFrequency = (i == self.frequencyBands - 1) ? self.endFrequency : lowerFrequency * powf(2, n);
+        [bands addObject:@{@"lowerFrequency": @(lowerFrequency), @"upperFrequency": @(upperFrequency)}];
+        lowerFrequency = upperFrequency;
+    }
+    
+    self.bands = [bands copy];
+}
+
+- (NSArray<NSArray<NSNumber *> *> *)analyseWithBuffer:(AVAudioPCMBuffer *)buffer {
+    self.isAnalise = YES;
+    NSArray<NSArray<NSNumber *> *> *channelsAmplitudes = [self fftWithBuffer:buffer];
+    NSArray<NSNumber *> *aWeights = self.cachedFrequencyWeights;
+    if (self.spectrumBuffer.count == 0) {
+        for (NSInteger i = 0; i < channelsAmplitudes.count; i++) {
+            [self.spectrumBuffer addObject:[self emptyArrayOfCount:self.bands.count]];
+        }
+    }
+    
+    NSMutableArray<NSArray<NSNumber *> *> *result = [NSMutableArray arrayWithArray:self.spectrumBuffer];
+    // 放大倍数
+    CGFloat amplificationFactor = 40.0; // 调整为所需的放大倍数
+    dispatch_apply(channelsAmplitudes.count, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t index) {
+        NSArray<NSNumber *> *amplitudes = channelsAmplitudes[index];
+        NSMutableArray<NSNumber *> *weightedAmplitudes = [NSMutableArray arrayWithCapacity:amplitudes.count];
+        
+        for (NSInteger i = 0; i < amplitudes.count; i++) {
+            weightedAmplitudes[i] = @(amplitudes[i].floatValue * aWeights[i].floatValue);
+        }
+        
+        NSMutableArray<NSNumber *> *spectrum = [NSMutableArray arrayWithCapacity:self.bands.count];
+        
+        for (NSDictionary *band in self.bands) {
+            float bandWidth = (float)buffer.format.sampleRate / self.fftSize;
+            [spectrum addObject:@([self findMaxAmplitudeForBand:band inAmplitudes:weightedAmplitudes withBandWidth:bandWidth] * amplificationFactor)];
+        }
+        
+        spectrum = [self highlightWaveform:spectrum];
+        
+        NSMutableArray<NSNumber *> *previousSpectrum = [self.spectrumBuffer[index] mutableCopy];
+        NSMutableArray<NSNumber *> *newSpectrum = [NSMutableArray arrayWithCapacity:spectrum.count];
+        
+        for (NSInteger i = 0; i < spectrum.count; i++) {
+            float smoothedValue = ([previousSpectrum[i] floatValue] * self.spectrumSmooth) + (spectrum[i].floatValue * (1 - self.spectrumSmooth));
+            newSpectrum[i] = @(smoothedValue);
+        }
+        
+        result[index] = [newSpectrum copy];
+        self.spectrumBuffer[index] = [newSpectrum copy];
+    });
+    self.isAnalise = NO;
+    return [result copy];
+}
+
+
+- (NSArray<NSArray<NSNumber *> *> *)fftWithBuffer:(AVAudioPCMBuffer *)buffer {
+    NSMutableArray<NSMutableArray<NSNumber *> *> *amplitudes = [NSMutableArray array];
+    float *const _Nonnull *floatChannelData = buffer.floatChannelData;
+    NSInteger channelCount = buffer.format.channelCount;
+    BOOL isInterleaved = buffer.format.isInterleaved;
+
+    float **tempFloatChannelData = NULL;
+    
+    if (isInterleaved) {
+        NSMutableArray<NSMutableData *> *channelsTemp = [NSMutableArray array];
+        float *interleavedData = floatChannelData[0];
+        for (NSInteger i = 0; i < channelCount; i++) {
+            NSMutableData *channelData = [NSMutableData dataWithLength:self.fftSize * sizeof(float)];
+            float *channelDataPtr = (float *)channelData.mutableBytes;
+            for (NSInteger j = i; j < self.fftSize * channelCount; j += channelCount) {
+                channelDataPtr[j / channelCount] = interleavedData[j];
+            }
+            [channelsTemp addObject:channelData];
+        }
+        
+        tempFloatChannelData = (float **)malloc(channelCount * sizeof(float *));
+        for (NSInteger i = 0; i < channelCount; i++) {
+            tempFloatChannelData[i] = (float *)[channelsTemp[i] mutableBytes];
+        }
+        
+        floatChannelData = (float *const _Nonnull *)tempFloatChannelData;
+    }
+    
+    for (NSInteger i = 0; i < channelCount; i++) {
+        float *channel = floatChannelData[i];
+        NSMutableData *windowData = [NSMutableData dataWithLength:self.fftSize * sizeof(float)];
+        float *window = windowData.mutableBytes;
+        vDSP_hann_window(window, self.fftSize, vDSP_HANN_NORM);
+        vDSP_vmul(channel, 1, window, 1, channel, 1, self.fftSize);
+        
+        DSPSplitComplex fftInOut;
+        fftInOut.realp = self.realp;
+        fftInOut.imagp = self.imagp;
+        
+        vDSP_ctoz((DSPComplex *)channel, 2, &fftInOut, 1, self.fftSize / 2);
+        vDSP_fft_zrip(self.fftSetup, &fftInOut, 1, log2(self.fftSize), FFT_FORWARD);
+        
+        fftInOut.imagp[0] = 0;
+        float fftNormFactor = 1.0 / self.fftSize;
+        vDSP_vsmul(fftInOut.realp, 1, &fftNormFactor, fftInOut.realp, 1, self.fftSize / 2);
+        vDSP_vsmul(fftInOut.imagp, 1, &fftNormFactor, fftInOut.imagp, 1, self.fftSize / 2);
+        
+        NSMutableArray<NSNumber *> *channelAmplitudes = [NSMutableArray arrayWithCapacity:self.fftSize / 2];
+        float *amplitudesArray = (float *)calloc(self.fftSize / 2, sizeof(float));
+        vDSP_zvabs(&fftInOut, 1, amplitudesArray, 1, self.fftSize / 2);
+        amplitudesArray[0] /= 2;
+        
+        for (NSInteger j = 0; j < self.fftSize / 2; j++) {
+            channelAmplitudes[j] = @(amplitudesArray[j]);
+        }
+        
+        [amplitudes addObject:[channelAmplitudes copy]];
+//        free(fftInOut.realp);
+//        free(fftInOut.imagp);
+        free(amplitudesArray);
+    }
+    
+    if (isInterleaved) {
+        free(tempFloatChannelData);
+    }
+    
+    return [amplitudes copy];
+}
+
+- (float)findMaxAmplitudeForBand:(NSDictionary *)band inAmplitudes:(NSArray<NSNumber *> *)amplitudes withBandWidth:(float)bandWidth {
+    NSInteger startIndex = round([band[@"lowerFrequency"] floatValue] / bandWidth);
+    NSInteger endIndex = MIN(round([band[@"upperFrequency"] floatValue] / bandWidth), amplitudes.count - 1);
+    float maxAmplitude = -FLT_MAX;
+    for (NSInteger i = startIndex; i <= endIndex; i++) {
+        float amplitude = [amplitudes[i] floatValue];
+        if (amplitude > maxAmplitude) {
+            maxAmplitude = amplitude;
+        }
+    }
+    return maxAmplitude;
+}
+
+- (NSArray<NSNumber *> *)createFrequencyWeights {
+    float sampleRate = 44100.0;
+    NSInteger fftSize = self.fftSize;
+    float deltaFrequency = sampleRate / fftSize;
+    NSInteger bins = fftSize / 2;
+
+    // 预先计算常量
+    float c1 = powf(12194.217, 2.0);
+    float c2 = powf(20.598997, 2.0);
+    float c3 = powf(107.65265, 2.0);
+    float c4 = powf(737.86223, 2.0);
+
+    NSMutableArray<NSNumber *> *frequencies = [NSMutableArray arrayWithCapacity:bins];
+    NSMutableArray<NSNumber *> *weights = [NSMutableArray arrayWithCapacity:bins];
+
+    for (NSInteger i = 0; i < bins; i++) {
+        float frequency = i * deltaFrequency;
+        [frequencies addObject:@(frequency)];
+    }
+
+    for (NSInteger i = 0; i < bins; i++) {
+        float frequencySquared = [frequencies[i] floatValue] * [frequencies[i] floatValue];
+
+        float numerator = c1 * frequencySquared * frequencySquared;
+        float denominator = (frequencySquared + c2) * sqrtf((frequencySquared + c3) * (frequencySquared + c4)) * (frequencySquared + c1);
+
+        float weight = 1.2589 * numerator / denominator;
+        [weights addObject:@(weight)];
+    }
+
+    return [weights copy];
+}
+
+- (NSMutableArray<NSNumber *> *)highlightWaveform:(NSArray<NSNumber *> *)spectrum {
+    float weights[] = {1, 2, 3, 5, 3, 2, 1};
+    float totalWeights = 17.0; // 1 + 2 + 3 + 5 + 3 + 2 + 1
+    NSInteger weightsCount = sizeof(weights) / sizeof(weights[0]);
+    NSInteger startIndex = weightsCount / 2;
+    NSMutableArray<NSNumber *> *averagedSpectrum = [NSMutableArray arrayWithArray:[spectrum subarrayWithRange:NSMakeRange(0, startIndex)]];
+    // 直接复制开始部分
+    [averagedSpectrum addObjectsFromArray:[spectrum subarrayWithRange:NSMakeRange(0, startIndex)]];
+    // 使用 vDSP 函数来加权平滑
+    for (NSInteger i = startIndex; i < spectrum.count - startIndex; i++) {
+        float result = 0;
+        for (NSInteger j = 0; j < weightsCount; j++) {
+            result += [spectrum[i - startIndex + j] floatValue] * weights[j];
+        }
+        [averagedSpectrum addObject:@(result / totalWeights)];
+    }
+    // 复制结束部分
+    [averagedSpectrum addObjectsFromArray:[spectrum subarrayWithRange:NSMakeRange(spectrum.count - startIndex, startIndex)]];
+    return [averagedSpectrum mutableCopy];
+}
+
+- (NSMutableArray<NSNumber *> *)emptyArrayOfCount:(NSUInteger)count {
+    NSMutableArray<NSNumber *> *array = [NSMutableArray arrayWithCapacity:count];
+    for (NSUInteger i = 0; i < count; i++) {
+        [array addObject:@(0.0)];
+    }
+    return array;
+}
+
+@end

+ 23 - 0
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/MergeAudioAnimation/KSSpectrumView.h

@@ -0,0 +1,23 @@
+//
+//  KSSpectrumView.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2024/7/29.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSSpectrumView : UIView
+
+@property (nonatomic, assign) CGFloat barWidth;
+@property (nonatomic, assign) CGFloat space;
+
+@property (nonatomic, strong) NSArray<NSArray<NSNumber *> *> *spectra;
+
+- (void)resetLayer;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 109 - 0
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/MergeAudioAnimation/KSSpectrumView.m

@@ -0,0 +1,109 @@
+//
+//  KSSpectrumView.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2024/7/29.
+//
+
+#import "KSSpectrumView.h"
+
+@interface KSSpectrumView ()
+
+@property (nonatomic, strong) CAGradientLayer *combinedGradientLayer;
+
+@end
+
+@implementation KSSpectrumView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    if (self) {
+        [self setupView];
+    }
+    return self;
+}
+
+
+- (instancetype)initWithCoder:(NSCoder *)aDecoder {
+    self = [super initWithCoder:aDecoder];
+    if (self) {
+        [self setupView];
+    }
+    return self;
+}
+
+- (void)setupView {
+    self.barWidth = 3.0;
+    self.space = 1.0;
+
+    self.combinedGradientLayer = [CAGradientLayer layer];
+    self.combinedGradientLayer.colors = @[
+        (__bridge id)HexRGBAlpha(0xffffff, 0.32f).CGColor,
+        (__bridge id)HexRGBAlpha(0xffffff, 0.32f).CGColor
+    ];
+    self.combinedGradientLayer.locations = @[@0.6, @1.0];
+    [self.layer addSublayer:self.combinedGradientLayer];
+}
+
+- (void)resetLayer {
+    self.spectra = [NSArray array];
+}
+
+- (void)setSpectra:(NSArray<NSArray<NSNumber *> *> *)spectra {
+    _spectra = spectra;
+    if (spectra) {
+        NSUInteger spectraCount = [spectra[0] count];
+        NSMutableArray<NSNumber *> *combinedSpectrum = [NSMutableArray arrayWithCapacity:spectraCount];
+        // 取两个声道数据中的最大值
+        for (NSUInteger i = 0; i < spectraCount; i++) {
+            NSNumber *leftAmplitude = spectra[0][i];
+            NSNumber *rightAmplitude = spectra.count > 1 ? spectra[1][i] : @0;
+            CGFloat maxAmplitude = MAX(leftAmplitude.floatValue, rightAmplitude.floatValue);
+            [combinedSpectrum addObject:@(maxAmplitude)];
+        }
+        
+        CGFloat viewHeight = self.bounds.size.height;
+        CGFloat viewWidth = self.bounds.size.width;
+        CGFloat middleY = viewHeight / 2.0;
+        CGFloat barHeight = (viewHeight) / 2.0;
+        CGFloat cornerRadius = viewWidth / 2.0f;
+        CGFloat xIncrement = self.barWidth + self.space;
+        UIBezierPath *combinedPath = [UIBezierPath bezierPath];
+
+        // Left channel
+        for (NSUInteger i = 0; i < spectraCount; i++) {
+            CGFloat x = i * xIncrement + self.space;
+            CGFloat amplitudeValue = combinedSpectrum[i].floatValue;
+            CGFloat height = amplitudeValue * barHeight;
+            CGFloat y = middleY - height/2.0; // Centered vertically
+            
+            CGRect rect = CGRectMake(x, y, self.barWidth, height);
+            UIBezierPath *barPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:cornerRadius];
+            [combinedPath appendPath:barPath];
+        }
+        
+        CAShapeLayer *combinedMaskLayer = [CAShapeLayer layer];
+        combinedMaskLayer.path = combinedPath.CGPath;
+        self.combinedGradientLayer.frame = CGRectMake(0, 0, viewWidth, viewHeight);
+        self.combinedGradientLayer.mask = combinedMaskLayer;
+
+    }
+}
+
+- (CGFloat)translateAmplitudeToYPosition:(float)amplitude {
+    CGFloat barHeight = amplitude * self.bounds.size.height;
+    return self.bounds.size.height - barHeight;
+}
+
+- (void)dealloc {
+    NSLog(@"---- KSSpectrumView dealloc");
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 7 - 1
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/MergePlayer/KSMergeEnginePlayer.h

@@ -6,6 +6,7 @@
 //
 
 #import <Foundation/Foundation.h>
+#import "KSRealtimeAnalyzer.h"
 
 @class KSMergeEnginePlayer;
 
@@ -26,7 +27,10 @@
 
 - (void)enginePlayerIsReadyPlay:(KSMergeEnginePlayer *_Nonnull)player;
 
-- (void)enginePlayerDidError:(KSMergeEnginePlayer *_Nonnull)player error:(NSError *_Nullable)error;
+- (void)enginePlayerDidError:(KSMergeEnginePlayer *_Nonnull)player error:(NSError *_Nonnull)error;
+
+// 动效相关
+- (void)player:(KSMergeEnginePlayer *_Nonnull)player didGenerateSpectrum:(NSArray<NSArray<NSNumber *> *> *_Nonnull)spectra;
 
 @end
 
@@ -34,6 +38,8 @@ NS_ASSUME_NONNULL_BEGIN
 
 @interface KSMergeEnginePlayer : NSObject
 
+@property (nonatomic, strong) KSRealtimeAnalyzer *analyzer;
+
 @property (nonatomic, weak) id <KSMergeEnginePlayerDelegate>delegate;
 
 @property (nonatomic, assign) BOOL isReady;

+ 218 - 201
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/MergePlayer/KSMergeEnginePlayer.m

@@ -7,8 +7,11 @@
 
 #import "KSMergeEnginePlayer.h"
 #import <AVFoundation/AVFoundation.h>
+#import <Accelerate/Accelerate.h>
 
+#define READ_FILE_LENGTH (8192)
 
+#define BUFFER_SIZE (2048)
 
 @interface KSMergeEnginePlayer ()
 /** 定时器 */
@@ -34,24 +37,14 @@
 
 @property (nonatomic, strong) AVAudioPCMBuffer *mixBuffer;
 
-@property (nonatomic, strong) AVAudioPCMBuffer *bgBuffer;
-
-@property (nonatomic, strong) AVAudioPCMBuffer *recordBuffer;
-
 @property (nonatomic, assign) AVAudioFramePosition currentFrame;
 
 @property (nonatomic, assign) double sampleRate;
 
-@property (nonatomic, assign) BOOL stopMix; // 是否停止mix
-
-@property (nonatomic, strong) dispatch_semaphore_t mixChangeSemaphore; // mix信号量
-
-@property (nonatomic, assign) BOOL stopChangeVolume; // 是否停止音量修改循环
-
-@property (nonatomic, strong) dispatch_semaphore_t volumeChangeSemaphore;
-
 @property (nonatomic, assign) BOOL isInterrupt; // 是否被打断
 
+@property (nonatomic, assign) NSInteger timeCount;
+
 @end
 
 
@@ -68,8 +61,6 @@
 - (void)configDefault {
     self.recordVolume = 1.0f;
     self.bgVolume = 1.0f;
-    self.mixChangeSemaphore = dispatch_semaphore_create(1); // 初始化信号量
-    self.volumeChangeSemaphore = dispatch_semaphore_create(1); // 初始化信号量,初始值为1
 }
 
 - (void)configEngine {
@@ -111,225 +102,235 @@
         if (error) {
             self.audioEngine = nil;
             // 错误回调
-            [self sendInterruptError:error];
+            if (self.delegate && [self.delegate respondsToSelector:@selector(enginePlayerDidError:error:)]) {
+                [self.delegate enginePlayerDidError:self error:error];
+            }
         }
     }
 }
 
 - (void)prepareNativeSongWithUrl:(NSURL *)recordAudioUrl bgMusic:(NSURL *)bgMusicUrl {
-    [self loadAuidoFile:recordAudioUrl isBgm:NO];
-    [self loadAuidoFile:bgMusicUrl isBgm:YES];
-    self.sampleRate = self.audioFile.fileFormat.sampleRate;
-    [self configEngine];
-    
-    AVAudioFormat *outputFormat = [self.audioEngine.mainMixerNode outputFormatForBus:0];
-    [self.audioEngine connect:self.nodePlayer to:self.audioEngine.mainMixerNode format:outputFormat];
-    [self startEngine];
-    
-    if (self.audioEngine && self.audioEngine.isRunning) {
-        dispatch_async(self.sourceQueue, ^{
+    dispatch_async(self.sourceQueue, ^{
+        
+        [self loadAuidoFile:recordAudioUrl isBgm:NO];
+        [self loadAuidoFile:bgMusicUrl isBgm:YES];
+        self.sampleRate = self.audioFile.fileFormat.sampleRate;
+        [self configEngine];
+        
+        AVAudioFormat *outputFormat = [self.audioEngine.mainMixerNode outputFormatForBus:0];
+        [self.audioEngine connect:self.nodePlayer to:self.audioEngine.mainMixerNode format:outputFormat];
+//        [self addTapBus];
+        [self startEngine];
+        
+        if (self.audioEngine && self.audioEngine.isRunning) {
             [self prepareBufferFrame];
-        });
-    }
+        }
+    });
 }
 
+- (void)addTapBus {
+    BOOL delegateRespondsToDidGenerateSpectrum = [self.delegate respondsToSelector:@selector(player:didGenerateSpectrum:)];
+    self.analyzer = [[KSRealtimeAnalyzer alloc] initWithFFTSize:BUFFER_SIZE];
+    AVAudioFormat *outputFormat = [self.audioEngine.mainMixerNode outputFormatForBus:0];
+    @weakObj(self);
+    [self.audioEngine.mainMixerNode removeTapOnBus:0];
+    [self.audioEngine.mainMixerNode installTapOnBus:0 bufferSize:BUFFER_SIZE format:outputFormat block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) {
+        @strongObj(self);
+        if (!self || !self.nodePlayer.isPlaying) {
+            return;
+        }
+        // 将频谱分析任务提交到后台队列
+            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
+                if (self.analyzer.isAnalise == NO) {
+                    // 分析音频缓冲区
+                    NSArray<NSArray<NSNumber *> *> *spectra = [self.analyzer analyseWithBuffer:buffer];
+                    
+                    // 回到主线程更新 UI 或调用委托方法
+                    dispatch_async(dispatch_get_main_queue(), ^{
+                        if (delegateRespondsToDidGenerateSpectrum) {
+                            [self.delegate player:self didGenerateSpectrum:spectra];
+                        }
+                    });
+                }
+            });
+    }];
+}
 
 - (void)loadAuidoFile:(NSURL *)audioFileUrl isBgm:(BOOL)isBgm {
-    dispatch_sync(self.sourceQueue, ^{
-        NSError *error = nil;
-        AVAudioFile *audioFile = nil;
-        AVAudioFormat *audioFormat = nil;
-        @try {
-            audioFile = [[AVAudioFile alloc] initForReading:audioFileUrl error:&error];
-            audioFormat = audioFile.processingFormat;
-            
-        } @catch (NSException *exception) {
-            audioFile = nil;
-            audioFormat = nil;
-        } @finally {
-            if (error) {
-                // 错误回调
+    NSError *error = nil;
+    AVAudioFile *audioFile = nil;
+    AVAudioFormat *audioFormat = nil;
+    @try {
+        audioFile = [[AVAudioFile alloc] initForReading:audioFileUrl error:&error];
+        audioFormat = audioFile.processingFormat;
+        
+    } @catch (NSException *exception) {
+        audioFile = nil;
+        audioFormat = nil;
+    } @finally {
+        if (error) {
+            // 错误回调
+        }
+        else { // 加载成功
+            if (isBgm) {
+                self.bgAudioFile = audioFile;
+                self.bgAudioFormat = audioFormat;
             }
-            else { // 加载成功
-                if (isBgm) {
-                    self.bgAudioFile = audioFile;
-                    self.bgAudioFormat = audioFormat;
-                }
-                else {
-                    self.audioFile = audioFile;
-                    self.audioFormat = audioFormat;
-                }
+            else {
+                self.audioFile = audioFile;
+                self.audioFormat = audioFormat;
             }
         }
-    });
+    }
 }
 
-- (void)prepareBufferFrame {
+- (void)resetMixBuffer {
     AVAudioFrameCount minFrameCount = (AVAudioFrameCount)MIN(self.bgAudioFile.length, self.audioFile.length);
     // mixBuffer
     AVAudioFormat *outputFormat = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:self.bgAudioFormat.sampleRate channels:2];
     self.mixBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:outputFormat frameCapacity:minFrameCount];
     self.mixBuffer.frameLength = minFrameCount;
-    
-    self.bgBuffer = [self loadAudioSegment:self.bgAudioFile startFrame:0 frameCount:minFrameCount];
-    self.recordBuffer = [self loadAudioSegment:self.audioFile startFrame:0 frameCount:minFrameCount];
-    
-    if (self.delegate && [self.delegate respondsToSelector:@selector(enginePlayerIsReadyPlay:)]) {
-        self.isReady = YES;
-        [self.delegate enginePlayerIsReadyPlay:self];
-    }
 }
 
-- (AVAudioPCMBuffer *)loadAudioSegment:(AVAudioFile *)audioFile startFrame:(AVAudioFramePosition)startFrame frameCount:(AVAudioFrameCount)frameCount {
-    AVAudioFormat *audioFromat = audioFile.processingFormat;
-    AVAudioFrameCount frameToRead = (AVAudioFrameCount)MIN(frameCount, (AVAudioFrameCount)audioFile.length - startFrame);
-    if (startFrame > audioFile.length) {
-        return nil;
-    }
-    AVAudioPCMBuffer *buffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:audioFromat frameCapacity:frameToRead];
-    buffer.frameLength = frameToRead;
-    
-    audioFile.framePosition = startFrame;
-    if (frameToRead > 0) {
-        @try {
-            [audioFile readIntoBuffer:buffer frameCount:frameToRead error:nil];
-        } @catch (NSException *exception) {
-            
-        } @finally {
-            
+- (void)prepareBufferFrame {
+    [self resetMixBuffer];
+    dispatch_main_async_safe(^{
+        if (self.delegate && [self.delegate respondsToSelector:@selector(enginePlayerIsReadyPlay:)]) {
+            self.isReady = YES;
+            [self.delegate enginePlayerIsReadyPlay:self];
         }
-    }
-    return buffer;
+    });
 }
 
-
-- (void)mixBuffers:(AVAudioPCMBuffer *)bgBuffer bgBufferVolume:(float)bgBufferVolume withRecordBuffer:(AVAudioPCMBuffer *)recordBuffer recordVolume:(float)recordVolume offset:(NSInteger)offsetTime startPosition:(AVAudioFrameCount)startPosition {
-    if (!bgBuffer && !recordBuffer) {
-        return;
-    }
-    NSLog(@"------- start");
-    
-    AVAudioFrameCount minFrameCount = MIN(bgBuffer.frameLength, recordBuffer.frameLength);
-    AVAudioFrameCount offsetFrame = labs(offsetTime)/1000.0 * recordBuffer.format.sampleRate;
+// 预计加载buffer
+- (void)prepareBuffer:(AVAudioFramePosition)startPosition offset:(NSInteger)offsetTime mixStart:(AVAudioFramePosition)mixStartPosition {
     
-    float *bgLeftChannel = bgBuffer.floatChannelData[0];
-    float *bgRightChannel = bgBuffer.floatChannelData[1];
-    // 录音文件未单声道
-    float *recordLeftChannel = recordBuffer.floatChannelData[0];
-    
-    float *mixLeftChannel = self.mixBuffer.floatChannelData[0];
-    float *mixRightChannel = self.mixBuffer.floatChannelData[1];
-    
-    for (int frame = 0; frame < minFrameCount; frame++) {
-        if (self.stopMix) {
-            NSLog(@"------- stop mix");
-            dispatch_semaphore_signal(self.mixChangeSemaphore); // 释放信号量
+    dispatch_async(self.sourceQueue, ^{
+        if (!self.bgAudioFile || !self.audioFile) {
             return;
         }
-        int bgFrame = frame+startPosition;
-        float leftChannel = (bgFrame < bgBuffer.frameLength) ? bgLeftChannel[bgFrame] : 0;
-        float rightChannel = (bgFrame < bgBuffer.frameLength) ? bgRightChannel[bgFrame] : 0;
-        
-        int recordFrame = (offsetTime < 0) ? (bgFrame - offsetFrame) : (bgFrame + offsetFrame);
-        
-        float recordData = (recordFrame >= 0 && recordFrame < recordBuffer.frameLength) ? recordLeftChannel[recordFrame] : 0;
-        
-        
-        float mixLeftData = [self mixChannelData:leftChannel bgVolume:bgBufferVolume recordData:recordData recordVolume:recordVolume];
-        float mixRightData = [self mixChannelData:rightChannel bgVolume:bgBufferVolume recordData:recordData recordVolume:recordVolume];
+        AVAudioFramePosition minFrameCount = (AVAudioFramePosition)MIN(self.bgAudioFile.length, self.audioFile.length);
+        AVAudioFrameCount offsetFrame = labs(offsetTime)/1000.0 * self.audioFile.processingFormat.sampleRate;
+        if (minFrameCount <= startPosition) {
+            return;
+        }
+        AVAudioFrameCount frameToRead = minFrameCount - startPosition > READ_FILE_LENGTH ? READ_FILE_LENGTH : (AVAudioFrameCount)(minFrameCount - startPosition);
         
-        mixLeftChannel[frame] = MAX(-1.0, MIN(1.0, mixLeftData));
-        mixRightChannel[frame] = MAX(-1.0, MIN(1.0, mixRightData));
-    }
-    NSLog(@"---------finish");
-    
-}
-
-- (float)mixChannelData:(float)bgData bgVolume:(float)bgVolume recordData:(float)recordData recordVolume:(float)recordVolume {
-    return (bgData * bgVolume + recordData * recordVolume) / 2;
-}
-
-- (void)changeVolume:(float)bgVolume recordVolume:(float)recordVolume {
-    
-    NSLog(@"bg volume ---- %f,  record volume ---- %f", bgVolume, recordVolume);
-    self.bgVolume = bgVolume;
-    self.recordVolume = recordVolume;
-    if (self.bgBuffer && self.recordBuffer) {
-        self.stopChangeVolume = YES;
-        // 停止上一次修改音量
-        dispatch_async(self.sourceQueue, ^{
-            // 等待上一次的操作完成
-            dispatch_semaphore_wait(self.volumeChangeSemaphore, DISPATCH_TIME_FOREVER);
-            self.stopChangeVolume = NO;
-            // 开始新的音量修改操作
-            AVAudioFramePosition startFrame = self.currentFrame;
-            NSLog(@"----- current frame -----%lld", startFrame);
-            [self modifyMixBuffer:self.bgBuffer bgBufferVolume:bgVolume withRecordBuffer:self.recordBuffer recordVolume:recordVolume offset:self.offsetTime startPosition:startFrame tagIndex:0];
-            // 释放信号量,标记音量修改操作完成
-            dispatch_semaphore_signal(self.volumeChangeSemaphore);
-        });
-    }
-}
-
-
-- (void)modifyMixBuffer:(AVAudioPCMBuffer *)bgBuffer bgBufferVolume:(float)bgBufferVolume withRecordBuffer:(AVAudioPCMBuffer *)recordBuffer recordVolume:(float)recordVolume offset:(NSInteger)offsetTime startPosition:(AVAudioFramePosition)startFrame tagIndex:(NSInteger)tagIndex {
-    
-    AVAudioFrameCount minFrameCount = MIN(bgBuffer.frameLength, recordBuffer.frameLength);
-    AVAudioFrameCount offsetFrame = labs(offsetTime)/1000.0 * recordBuffer.format.sampleRate;
-    
-    float *bgLeftChannel = bgBuffer.floatChannelData[0];
-    float *bgRightChannel = bgBuffer.floatChannelData[1];
-    // 录音文件未单声道
-    float *recordLeftChannel = recordBuffer.floatChannelData[0];
-    
-    float *mixLeftChannel = self.mixBuffer.floatChannelData[0];
-    float *mixRightChannel = self.mixBuffer.floatChannelData[1];
-    
-    // 先处理后续播放的buffer
-    NSLog(@"------- volume change start");
-    for (int frame = (int)startFrame; frame < minFrameCount; frame++) {
-        if (self.stopChangeVolume) {
-            NSLog(@"------- stop volume change");
-            dispatch_semaphore_signal(self.volumeChangeSemaphore); // 释放信号量
+        self.bgAudioFile.framePosition = startPosition;
+        AVAudioPCMBuffer *bgBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:self.bgAudioFile.processingFormat frameCapacity:frameToRead];
+        bgBuffer.frameLength = frameToRead;
+        BOOL readSuccess = [self.bgAudioFile readIntoBuffer:bgBuffer frameCount:frameToRead error:nil];
+        if (!readSuccess) {
             return;
         }
+        AVAudioPCMBuffer *recordBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:self.audioFile.processingFormat frameCapacity:frameToRead];
+        recordBuffer.frameLength = frameToRead;
         
-        float leftChannel = bgLeftChannel[frame];
-        float rightChannel = bgRightChannel[frame];
+        if (offsetTime >= 0) { // 演奏需要提前
+            self.audioFile.framePosition = startPosition + offsetFrame;
+            AVAudioFrameCount audioReadFrame = frameToRead;
+            if (startPosition + offsetFrame + frameToRead > minFrameCount) { // 如果超出
+                audioReadFrame = (AVAudioFrameCount)(minFrameCount - startPosition - offsetFrame);
+            }
+            if (audioReadFrame <= frameToRead) {
+                BOOL isSuccess = [self.audioFile readIntoBuffer:recordBuffer frameCount:audioReadFrame error:nil];
+                if (!isSuccess) {
+                    return;
+                }
+            }
+        }
+        else { // 演奏需要延后
+            AVAudioFramePosition audioFramePosition = startPosition - offsetFrame;
+            if (audioFramePosition > 0) {
+                self.audioFile.framePosition = audioFramePosition;
+                AVAudioFrameCount audioReadFrame = frameToRead;
+                if (audioFramePosition + frameToRead > minFrameCount) { // 如果超出
+                    audioReadFrame = (AVAudioFrameCount)(minFrameCount - audioFramePosition);
+                }
+                // AVAudioFrameCount 无符号整型 uint32_t
+                if (audioReadFrame <= frameToRead) {
+                    BOOL isSuccess = [self.audioFile readIntoBuffer:recordBuffer frameCount:audioReadFrame error:nil];
+                    if (!isSuccess) {
+                        return;
+                    }
+                }
+            }
+            else {
+                self.audioFile.framePosition = 0;
+                // 需要读取部分数据
+                if (offsetFrame - startPosition < frameToRead) {
+                    AVAudioFrameCount readCount = (AVAudioFrameCount)(offsetFrame - startPosition);
+//                    NSLog(@"----need readCount --%u", readCount);
+                    AVAudioPCMBuffer *tempBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:self.audioFile.processingFormat frameCapacity:readCount];
+                    tempBuffer.frameLength = readCount;
+                    BOOL isSuccess = [self.audioFile readIntoBuffer:tempBuffer error:nil];
+                    if (!isSuccess) {
+                        return;
+                    }
+                    float *tempData = tempBuffer.floatChannelData[0];
+                    float *recordData = recordBuffer.floatChannelData[0];
+                    // 复制数据到 recordBuffer
+                    AVAudioFrameCount startFrame = frameToRead - readCount;
+                    for (AVAudioFrameCount i = 0; i < readCount; i++) {
+                        recordData[startFrame + i] = tempData[i];
+                    }
+                }
+            }
+        }
         
-        int recordFrame = (offsetTime < 0) ? (frame - offsetFrame) : (frame + offsetFrame);
-        float recordData = (recordFrame >= 0 && recordFrame < recordBuffer.frameLength) ? recordLeftChannel[recordFrame] : 0;
+        float *bgLeftChannel = bgBuffer.floatChannelData[0];
+        float *bgRightChannel = bgBuffer.floatChannelData[1];
+        if (bgBuffer.format.channelCount == 1) {
+            bgRightChannel = bgBuffer.floatChannelData[0];
+        }
+        // 录音文件未单声道
+        float *recordLeftChannel = recordBuffer.floatChannelData[0];
         
-        float mixLeftData = [self mixChannelData:leftChannel bgVolume:bgBufferVolume recordData:recordData recordVolume:recordVolume];
-        float mixRightData = [self mixChannelData:rightChannel bgVolume:bgBufferVolume recordData:recordData recordVolume:recordVolume];
+        float *mixLeftChannel = self.mixBuffer.floatChannelData[0];
+        float *mixRightChannel = self.mixBuffer.floatChannelData[1];
         
-        mixLeftChannel[frame-self.startPosition] = MAX(-1.0, MIN(1.0, mixLeftData));
-        mixRightChannel[frame-self.startPosition] = MAX(-1.0, MIN(1.0, mixRightData));
-    }
-    NSLog(@"------- volume change end");
+        for (int frame = 0; frame < frameToRead; frame++) {
+            
+            AVAudioFramePosition mixIndex = frame + startPosition - mixStartPosition;
+            float leftChannel = (frame < bgBuffer.frameLength) ? bgLeftChannel[frame] : 0;
+            float rightChannel = (frame < bgBuffer.frameLength) ? bgRightChannel[frame] : 0;
+            
+            float recordData = (frame < recordBuffer.frameLength) ? recordLeftChannel[frame] : 0;
+            
+            float mixLeftData = [self mixChannelData:leftChannel bgVolume:self.bgVolume recordData:recordData recordVolume:self.recordVolume];
+            float mixRightData = [self mixChannelData:rightChannel bgVolume:self.bgVolume recordData:recordData recordVolume:self.recordVolume];
+            
+            // 防止数组越界
+            if (mixIndex >= 0 && mixIndex < self.mixBuffer.frameLength) {
+                mixLeftChannel[mixIndex] = fminf(fmaxf(mixLeftData, -1.0f), 1.0f);
+                mixRightChannel[mixIndex] = fminf(fmaxf(mixRightData, -1.0f), 1.0f);
+            }
+        }
+    });
 }
 
 - (void)scheduleBufferFromPosition:(AVAudioFramePosition)startPosition {
-    
-    self.stopMix = YES;
+    [self resetMixBuffer];
     self.startPosition = startPosition;
-    dispatch_async(self.sourceQueue, ^{
-        // 等待上一次的操作完成
-        dispatch_semaphore_wait(self.mixChangeSemaphore, DISPATCH_TIME_FOREVER);
-        self.stopMix = NO;
+    [self prepareBuffer:startPosition offset:self.offsetTime mixStart:startPosition];
+    // 加载缓冲区
+    [self.nodePlayer scheduleBuffer:self.mixBuffer atTime:nil options:AVAudioPlayerNodeBufferInterruptsAtLoop completionHandler:^{
         
-        [self mixBuffers:self.bgBuffer bgBufferVolume:self.bgVolume withRecordBuffer:self.recordBuffer recordVolume:self.recordVolume offset:self.offsetTime startPosition:(AVAudioFrameCount)startPosition];
-        // 释放信号量,标记修改操作完成
-        dispatch_semaphore_signal(self.mixChangeSemaphore);
-        // 加载缓冲区
-        [self.nodePlayer scheduleBuffer:self.mixBuffer atTime:nil options:AVAudioPlayerNodeBufferInterruptsAtLoop completionHandler:^{
-            
-        }];
-    });
+    }];
 }
 
 
 
+- (float)mixChannelData:(float)bgData bgVolume:(float)bgVolume recordData:(float)recordData recordVolume:(float)recordVolume {
+    return (bgData * bgVolume + recordData * recordVolume) / 2;
+}
+
+- (void)changeVolume:(float)bgVolume recordVolume:(float)recordVolume {
+//    NSLog(@"bg volume ---- %f,  record volume ---- %f", bgVolume, recordVolume);
+    self.bgVolume = bgVolume;
+    self.recordVolume = recordVolume;
+}
+
 // 打断处理
 - (void)handleInterruption:(NSNotification *)notification {
     NSDictionary *info = notification.userInfo;
@@ -386,6 +387,7 @@
         [self.delegate enginePlayerDidError:self error:error];
     }
 }
+
 #pragma mark ------ play action
 
 - (void)changeRecordDelay:(NSInteger)delayMs {
@@ -406,8 +408,7 @@
 }
 
 - (void)stopPlay {
-    self.stopMix = YES;
-    self.stopChangeVolume = YES;
+
     if (self.nodePlayer.isPlaying) {
         [self.nodePlayer stop];
     }
@@ -437,9 +438,6 @@
         }
     }
     
-    // 停止修改音量循环
-    self.stopChangeVolume = YES;
-    
     AVAudioFramePosition startFrame = startTime / 1000.0 * self.audioFormat.sampleRate;
     // 跳转进度
     self.currentFrame = startFrame;
@@ -459,15 +457,17 @@
 }
 
 - (void)freePlayer {
-    
-    if (self.nodePlayer.isPlaying) {
-        [self stopPlay];
-    }
+    [self stopPlay];
     [self.audioEngine stop];
+    // 停止并清理定时器
+    if (_timer) {
+        [_timer invalidate];
+        _timer = nil;
+    }
 }
 
 - (void)startTimer {
-    
+    self.timeCount = 0;
     [self.timer setFireDate:[NSDate distantPast]];
 }
 
@@ -488,7 +488,7 @@
     
     if (!_timer) {
         __weak typeof(self)weakSelf = self;
-        _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 repeats:YES block:^(NSTimer * _Nonnull timer) {
+        _timer = [NSTimer scheduledTimerWithTimeInterval:0.01 repeats:YES block:^(NSTimer * _Nonnull timer) {
             [weakSelf timeFunction];
         }];
         [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
@@ -503,12 +503,18 @@
     float progress = currentTime/self.totalDuration;
     NSDate *date = [NSDate date];
     NSTimeInterval inteveral = [date timeIntervalSince1970];
-    if (currentTime > self.totalDuration) {
+    if (currentTime >= self.totalDuration) {
         if (self.delegate && [self.delegate respondsToSelector:@selector(enginePlayFinished:)]) {
             [self.delegate enginePlayFinished:self];
         }
     }
     else {
+        // 定时器10ms出触发一次 buffer每100ms执行一次
+        if (self.timeCount % 10 == 0) {
+            [self scheduleMixBuffer];
+        }
+        self.timeCount++;
+
         if (self.delegate && [self.delegate respondsToSelector:@selector(updatePlayProgress:andTotalTime:andProgress:currentInterval:inPlayer:)]) {
             [self.delegate updatePlayProgress:currentTime andTotalTime:self.totalDuration andProgress:progress currentInterval:inteveral*1000 inPlayer:self];
         }
@@ -516,6 +522,11 @@
     
 }
 
+- (void)scheduleMixBuffer {
+    if (self.nodePlayer.isPlaying) {
+        [self prepareBuffer:self.currentFrame offset:self.offsetTime mixStart:self.startPosition];
+    }
+}
 
 - (NSTimeInterval)getCurrentPlayTime {
     AVAudioTime *nodeTime = [self.nodePlayer lastRenderTime];
@@ -557,4 +568,10 @@
     }
     return NO;
 }
+
+- (void)dealloc {
+    NSLog(@"---- KSMergeEnginePlayer dealloc");
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
 @end

+ 8 - 2
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/VideoPlayerView/KSVideoPlayerView.m

@@ -9,7 +9,6 @@
 #import <AVFoundation/AVFoundation.h>
 #import <CloudAccompanyLibrary/AVPlayer+KSSeekSmoothly.h>
 
-
 @interface KSVideoPlayerView ()
 
 @property (nonatomic, strong) AVPlayer *videoPlayer;
@@ -24,6 +23,8 @@
 
 @property (nonatomic, assign) BOOL hasFreeObserver;
 
+@property (nonatomic, assign) BOOL needResume; // 是否需要恢复播放
+
 @end
 
 @implementation KSVideoPlayerView
@@ -116,6 +117,7 @@
 }
 
 - (void)puasePlay {
+    self.needResume = NO;
     if (_isPlaying) {
         _isPlaying = NO;
         [_videoPlayer pause];
@@ -157,13 +159,17 @@
 - (void)seekOffsetTime:(NSInteger)offsetTime {
     CMTime newTime = CMTimeMake(offsetTime, 1000);
     CMTime toleranceTime = CMTimeMake(1, 1000);
+    if (self.isPlaying) {
+        self.needResume = YES;
+    }
     [self.videoPlayer pause];
     @weakObj(self);
     [self.videoPlayer ss_seekToTime:newTime toleranceBefore:toleranceTime toleranceAfter:toleranceTime completionHandler:^(BOOL finished) {
         @strongObj(self);
-        if (self.isPlaying) {
+        if (self.needResume) {
             [self.videoPlayer play];
         }
+        self.needResume = NO;
     }];
 }
 

+ 32 - 17
KulexiuForStudent/KulexiuForStudent/Module/Chat/Controller/TXCustom/KSTXBaseChatViewController.m

@@ -125,25 +125,40 @@ static UIView *gCustomTopView;
     }];
 }
 - (void)showMusic:(NSString *)songId {
-    PREMISSIONTYPE micEnable = [RecordCheckManager checkMicPermissionAvaiable];
-    PREMISSIONTYPE cameraEnable = [RecordCheckManager checkCameraPremissionAvaiable];
-    if (micEnable == PREMISSIONTYPE_YES && cameraEnable == PREMISSIONTYPE_YES) {
-        KSAccompanyWebViewController *detailCtrl = [[KSAccompanyWebViewController alloc] init];
-        detailCtrl.url = [NSString stringWithFormat:@"%@/accompany?id=%@",hostURL, songId];
-        detailCtrl.parmDic = @{@"isOpenLight" : @(YES), @"orientation" : @(0),@"isHideTitle" : @(YES)};
-        [self.navigationController pushViewController:detailCtrl animated:YES];
-    }
-    else {
-        if (micEnable == PREMISSIONTYPE_NO && cameraEnable == PREMISSIONTYPE_NO) { // 如果麦克风权限和摄像头权限都没有
-            [self showAlertWithMessage:@"请开启相机和麦克风访问权限" type:CHECKDEVICETYPE_BOTH];
-        }
-        else if (micEnable == PREMISSIONTYPE_NO) { // 如果没有麦克风权限
-            [self showAlertWithMessage:@"请开启麦克风访问权限" type:CHECKDEVICETYPE_MIC];
+    
+    [RecordCheckManager checkCameraPremissionAvaiableCallback:^(PREMISSIONTYPE type) {
+        [self afterCheckCameraCheckMic:type songId:songId];
+    }];
+}
+
+- (void)afterCheckCameraCheckMic:(PREMISSIONTYPE)cameraType songId:(NSString *)songId {
+    
+    [RecordCheckManager checkMicPermissionAvaiableCallback:^(PREMISSIONTYPE type) {
+        if (type == PREMISSIONTYPE_YES && cameraType == PREMISSIONTYPE_YES) {
+            KSAccompanyWebViewController *detailCtrl = [[KSAccompanyWebViewController alloc] init];
+            detailCtrl.url = [NSString stringWithFormat:@"%@/accompany?id=%@",hostURL, songId];
+            detailCtrl.parmDic = @{@"isOpenLight" : @(YES), @"orientation" : @(0),@"isHideTitle" : @(YES)};
+            [self.navigationController pushViewController:detailCtrl animated:YES];
         }
-        else if (cameraEnable == PREMISSIONTYPE_NO) { // 如果没有摄像头权限
-            [self showAlertWithMessage:@"请开启相机访问权限" type:CHECKDEVICETYPE_CAMREA];
+        else { //
+            
+            NSString *content = @"";
+            CHECKDEVICETYPE checkType = CHECKDEVICETYPE_BOTH;
+            if (cameraType == PREMISSIONTYPE_NO && type == PREMISSIONTYPE_NO) {
+                content = @"请开启相机和麦克风访问权限";
+                checkType = CHECKDEVICETYPE_BOTH;
+            }
+            else if (cameraType == PREMISSIONTYPE_NO && type == PREMISSIONTYPE_YES) {
+                content =  @"请开启相机访问权限";
+                checkType = CHECKDEVICETYPE_CAMREA;
+            }
+            else if (cameraType == PREMISSIONTYPE_YES && type == PREMISSIONTYPE_NO) {
+                content = @"请开启麦克风访问权限";
+                checkType = CHECKDEVICETYPE_MIC;
+            }
+            [self showAlertWithMessage:content type:checkType];
         }
-    }
+    }];
 }
 
 - (void)showAlertWithMessage:(NSString *)message type:(CHECKDEVICETYPE)deviceType {

+ 0 - 85
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/BassMidiEngine.h

@@ -1,85 +0,0 @@
-//
-//  BassMidiEngine.h
-//  StudentDaya
-//
-//  Created by Kyle on 2022/3/8.
-//  Copyright © 2022 DayaMusic. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-#import <AudioToolbox/AudioToolbox.h>
-#import <KSToolLibrary/CAudioUnit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@protocol BassMidiEngineDelegate <NSObject>
-
-/// 加载成功回调
-- (void)initEngineSuccess:(float)totalTime;
-
-/*    范围:[0,1],每10ms更新一次   */
-- (void)progressUpdated:(float)progress currentTime:(float)currentTime;
-
-/* 播放结束回调 */
-- (void)midiplayEnd;
-
-- (void)getMusicTotalTime:(float)totalTime;
-
-@end
-
-
-@interface BassMidiEngine : NSObject
-
-// 定义汇报进度频率 默认10ms
-@property (nonatomic, assign) NSInteger reportTime;
-// 每个track 对应的名称
-@property (nonatomic, strong) NSMutableArray *instrumentTrackNameArray;
-
-// 播放状态
-@property (nonatomic, assign) BOOL isPlaying;
-
-/* 选段播放控制 */
-
-// 选段的开始时间
-@property (nonatomic, assign) float startTime;
-// 选段的结束时间
-@property (nonatomic, assign) float endTime;
-
-/// 播放器回调delegate
-@property (nonatomic,weak)id<BassMidiEngineDelegate> delegate;
-
-
-- (void)configSoundFilePath:(NSString *)filePath;
-
-/*  加载MIDI文件  */
-- (BOOL)loadMIDIFileWithString:(NSString *)filePath;
-
-/* 播放器当前状态 */
-- (BOOL)isPlayingFile;
-/// 开始播放
-- (void)startPlay;
-/// 停止播放
-- (void)stopPlay;
-
-/// 释放引擎
-- (void)freeEngine;
-
-/*  设置播放速度,快播:(1,+∞),慢放:(0,1)   */
-- (BOOL)setMusicPlayerSpeed:(float)speed;
-
-/* 设置播放的进度开始时间  */
-- (void)setProgressTime:(MusicTimeStamp)startTime;
-
-/*  調節某一軌的音量  範圍:[0,1] */
-- (void)volume:(float)volume WithTrack:(UInt32)trackNum;
-
-#pragma mark ------ 变调 调整hz
-// 转成442HZ播放
-- (void)transformTo442Hz;
-
-// hz调整 440 - 442。。。。。。。
-- (void)adjustPitchByHZ:(float)newHZ;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 186
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/BassMidiEngine.m

@@ -1,186 +0,0 @@
-//
-//  BassMidiEngine.m
-//  StudentDaya
-//
-//  Created by Kyle on 2022/3/8.
-//  Copyright © 2022 DayaMusic. All rights reserved.
-//
-
-#import "BassMidiEngine.h"
-#import "bass.h"
-#import "bassmidi.h"
-#import <AVFoundation/AVFoundation.h>
-#import <KSToolLibrary/GCDTimer.h>
-
-@interface BassMidiEngine ()
-{
-    HSTREAM _stream;
-}
-@property (nonatomic, strong) NSString *soundFileUrl;
-
-@property (nonatomic, strong) NSString *midFilePath;
-
-
-
-@end
-
-@implementation BassMidiEngine
-
-- (instancetype)init {
-    self = [super init];
-    if (self) {
-        [self configDefault];
-    }
-    return self;
-}
-
-- (void)configDefault {
-    self.soundFileUrl = [[NSBundle mainBundle]
-                         pathForResource:@"synthgms" ofType:@"sf2"];
-    [self setupAudioSession];
-}
-
-- (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];
-}
-
-- (void)configSoundFilePath:(NSString *)filePath {
-    self.soundFileUrl = filePath;
-}
-
-- (BOOL)setupEngineWithFile:(NSString *)filePath {
-    //BASS init
-    BASS_Init(-1, 44100, 0, 0, NULL);
-    _stream = BASS_MIDI_StreamCreateFile(FALSE, [filePath UTF8String], 0, 0, 0, 44100);
-    if (BASS_ErrorGetCode()) {
-        NSLog(@"Bass error: %i", BASS_ErrorGetCode());
-        return NO;
-    }
-    // set font
-    BASS_MIDI_FONT font = [self getBassMidiFont];
-    BASS_MIDI_StreamSetFonts(_stream, &font, 1);
-    
-    return YES;
-}
-
-- (BASS_MIDI_FONT)getBassMidiFont {
-    BASS_MIDI_FONT midiFont;
-    midiFont.font = BASS_MIDI_FontInit([self.soundFileUrl UTF8String], 0);
-    midiFont.preset = -1;
-    midiFont.bank = 0;
-    return midiFont;
-}
-
-- (BOOL)loadMIDIFileWithString:(NSString *)filePath {
-    // 判断文件是否存在
-    BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
-    if (isExist) {
-        return [self setupEngineWithFile:filePath];
-    }
-    else {
-        NSLog(@"文件不存在 !!!");
-        return NO;
-    }
-}
-
-
-- (BOOL)isPlayingFile {
-    if (_stream == 0) {
-        return NO;
-    }
-    //    0 - BASS_ACTIVE_STOPPED   The channel is not active, or handle is not a valid channel.
-    //    1 - BASS_ACTIVE_PLAYING   The channel is playing (or recording).
-    //    2 - BASS_ACTIVE_PAUSED    The channel is paused.
-    //    3 - BASS_ACTIVE_STALLED   Playback of the stream has been stalled due to a lack of sample data.
-    //                              The playback will automatically resume once there is sufficient data to do so.
-    int status = BASS_ChannelIsActive(_stream);
-    switch (status) {
-        case BASS_ACTIVE_STOPPED: // 停止
-        {
-            
-        }
-            break;
-        case BASS_ACTIVE_PLAYING: // 播放中
-        {
-            
-        }
-            break;
-        case BASS_ACTIVE_PAUSED:
-        case BASS_ACTIVE_STALLED:
-        {
-            
-        }
-            break;
-        default:
-            break;
-    }
-    if (status == 1) {
-        return YES;
-    }
-    else {
-        return NO;
-    }
-}
-
-- (void)startPlay {
-    if (_stream == 0) {
-        // 未初始化stream
-        return;
-    }
-    if (self.isPlaying) {
-        [self stopPlay];
-    }
-    
-    BASS_ChannelPlay(_stream, 0);
-    self.isPlaying = YES;
-    NSLog(@"testMidiFile complete");
-    __weak typeof(self) weakSelf = self;
-    dispatch_queue_t queue = dispatch_queue_create("BassPlayerTimer", DISPATCH_QUEUE_SERIAL);
-    [[GCDTimer shared] scheduleGCDTimerWithName:@"BassMusicPlayerTimer" Interval:self.reportTime Queue:queue Repeats:YES Action:^{
-            
-        // 获取当前进度
-        
-    }];
-    
-}
-
-- (void)stopPlay {
-    BASS_ChannelStop(_stream);
-    self.isPlaying = NO;
-    [[GCDTimer shared] cancelAllTimer];
-}
-
-- (BOOL)setMusicPlayerSpeed:(float)speed {
-    BOOL isSuccess = BASS_ChannelSetAttribute(_stream, BASS_ATTRIB_MIDI_SPEED, speed);
-    return isSuccess;
-}
-
-/// 释放引擎
-- (void)freeEngine {
-    if (_stream) {
-        BASS_ChannelFree(_stream);
-    }
-}
-
-#pragma mark ------ 变调 调整hz
-// 转成442HZ播放
-- (void)transformTo442Hz {
-    
-}
-
-// hz调整 440 - 442。。。。。。。
-- (void)adjustPitchByHZ:(float)newHZ {
-    
-}
-
-@end

+ 0 - 1131
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bass.h

@@ -1,1131 +0,0 @@
-/*
-	BASS 2.4 C/C++ header file
-	Copyright (c) 1999-2021 Un4seen Developments Ltd.
-
-	See the BASS.CHM file for more detailed documentation
-*/
-
-#ifndef BASS_H
-#define BASS_H
-
-#ifdef _WIN32
-#ifdef WINAPI_FAMILY
-#include <winapifamily.h>
-#endif
-#include <wtypes.h>
-typedef unsigned __int64 QWORD;
-#else
-#include <stdint.h>
-#define WINAPI
-#define CALLBACK
-typedef uint8_t BYTE;
-typedef uint16_t WORD;
-typedef uint32_t DWORD;
-typedef uint64_t QWORD;
-#ifdef __OBJC__
-typedef int BOOL32;
-#define BOOL BOOL32 // override objc's BOOL
-#else
-typedef int BOOL;
-#endif
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
-#define LOBYTE(a) (BYTE)(a)
-#define HIBYTE(a) (BYTE)((a)>>8)
-#define LOWORD(a) (WORD)(a)
-#define HIWORD(a) (WORD)((a)>>16)
-#define MAKEWORD(a,b) (WORD)(((a)&0xff)|((b)<<8))
-#define MAKELONG(a,b) (DWORD)(((a)&0xffff)|((b)<<16))
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define BASSVERSION			0x204	// API version
-#define BASSVERSIONTEXT		"2.4"
-
-#ifndef BASSDEF
-#define BASSDEF(f) WINAPI f
-#else
-#define NOBASSOVERLOADS
-#endif
-
-typedef DWORD HMUSIC;		// MOD music handle
-typedef DWORD HSAMPLE;		// sample handle
-typedef DWORD HCHANNEL;		// sample playback handle
-typedef DWORD HSTREAM;		// sample stream handle
-typedef DWORD HRECORD;		// recording handle
-typedef DWORD HSYNC;		// synchronizer handle
-typedef DWORD HDSP;			// DSP handle
-typedef DWORD HFX;			// effect handle
-typedef DWORD HPLUGIN;		// plugin handle
-
-// Error codes returned by BASS_ErrorGetCode
-#define BASS_OK				0	// all is OK
-#define BASS_ERROR_MEM		1	// memory error
-#define BASS_ERROR_FILEOPEN	2	// can't open the file
-#define BASS_ERROR_DRIVER	3	// can't find a free/valid driver
-#define BASS_ERROR_BUFLOST	4	// the sample buffer was lost
-#define BASS_ERROR_HANDLE	5	// invalid handle
-#define BASS_ERROR_FORMAT	6	// unsupported sample format
-#define BASS_ERROR_POSITION	7	// invalid position
-#define BASS_ERROR_INIT		8	// BASS_Init has not been successfully called
-#define BASS_ERROR_START	9	// BASS_Start has not been successfully called
-#define BASS_ERROR_SSL		10	// SSL/HTTPS support isn't available
-#define BASS_ERROR_REINIT	11	// device needs to be reinitialized
-#define BASS_ERROR_ALREADY	14	// already initialized/paused/whatever
-#define BASS_ERROR_NOTAUDIO	17	// file does not contain audio
-#define BASS_ERROR_NOCHAN	18	// can't get a free channel
-#define BASS_ERROR_ILLTYPE	19	// an illegal type was specified
-#define BASS_ERROR_ILLPARAM	20	// an illegal parameter was specified
-#define BASS_ERROR_NO3D		21	// no 3D support
-#define BASS_ERROR_NOEAX	22	// no EAX support
-#define BASS_ERROR_DEVICE	23	// illegal device number
-#define BASS_ERROR_NOPLAY	24	// not playing
-#define BASS_ERROR_FREQ		25	// illegal sample rate
-#define BASS_ERROR_NOTFILE	27	// the stream is not a file stream
-#define BASS_ERROR_NOHW		29	// no hardware voices available
-#define BASS_ERROR_EMPTY	31	// the MOD music has no sequence data
-#define BASS_ERROR_NONET	32	// no internet connection could be opened
-#define BASS_ERROR_CREATE	33	// couldn't create the file
-#define BASS_ERROR_NOFX		34	// effects are not available
-#define BASS_ERROR_NOTAVAIL	37	// requested data/action is not available
-#define BASS_ERROR_DECODE	38	// the channel is/isn't a "decoding channel"
-#define BASS_ERROR_DX		39	// a sufficient DirectX version is not installed
-#define BASS_ERROR_TIMEOUT	40	// connection timedout
-#define BASS_ERROR_FILEFORM	41	// unsupported file format
-#define BASS_ERROR_SPEAKER	42	// unavailable speaker
-#define BASS_ERROR_VERSION	43	// invalid BASS version (used by add-ons)
-#define BASS_ERROR_CODEC	44	// codec is not available/supported
-#define BASS_ERROR_ENDED	45	// the channel/file has ended
-#define BASS_ERROR_BUSY		46	// the device is busy
-#define BASS_ERROR_UNSTREAMABLE	47	// unstreamable file
-#define BASS_ERROR_PROTOCOL	48	// unsupported protocol
-#define BASS_ERROR_UNKNOWN	-1	// some other mystery problem
-
-// BASS_SetConfig options
-#define BASS_CONFIG_BUFFER			0
-#define BASS_CONFIG_UPDATEPERIOD	1
-#define BASS_CONFIG_GVOL_SAMPLE		4
-#define BASS_CONFIG_GVOL_STREAM		5
-#define BASS_CONFIG_GVOL_MUSIC		6
-#define BASS_CONFIG_CURVE_VOL		7
-#define BASS_CONFIG_CURVE_PAN		8
-#define BASS_CONFIG_FLOATDSP		9
-#define BASS_CONFIG_3DALGORITHM		10
-#define BASS_CONFIG_NET_TIMEOUT		11
-#define BASS_CONFIG_NET_BUFFER		12
-#define BASS_CONFIG_PAUSE_NOPLAY	13
-#define BASS_CONFIG_NET_PREBUF		15
-#define BASS_CONFIG_NET_PASSIVE		18
-#define BASS_CONFIG_REC_BUFFER		19
-#define BASS_CONFIG_NET_PLAYLIST	21
-#define BASS_CONFIG_MUSIC_VIRTUAL	22
-#define BASS_CONFIG_VERIFY			23
-#define BASS_CONFIG_UPDATETHREADS	24
-#define BASS_CONFIG_DEV_BUFFER		27
-#define BASS_CONFIG_REC_LOOPBACK	28
-#define BASS_CONFIG_VISTA_TRUEPOS	30
-#define BASS_CONFIG_IOS_SESSION		34
-#define BASS_CONFIG_IOS_MIXAUDIO	34
-#define BASS_CONFIG_DEV_DEFAULT		36
-#define BASS_CONFIG_NET_READTIMEOUT	37
-#define BASS_CONFIG_VISTA_SPEAKERS	38
-#define BASS_CONFIG_IOS_SPEAKER		39
-#define BASS_CONFIG_MF_DISABLE		40
-#define BASS_CONFIG_HANDLES			41
-#define BASS_CONFIG_UNICODE			42
-#define BASS_CONFIG_SRC				43
-#define BASS_CONFIG_SRC_SAMPLE		44
-#define BASS_CONFIG_ASYNCFILE_BUFFER 45
-#define BASS_CONFIG_OGG_PRESCAN		47
-#define BASS_CONFIG_MF_VIDEO		48
-#define BASS_CONFIG_AIRPLAY			49
-#define BASS_CONFIG_DEV_NONSTOP		50
-#define BASS_CONFIG_IOS_NOCATEGORY	51
-#define BASS_CONFIG_VERIFY_NET		52
-#define BASS_CONFIG_DEV_PERIOD		53
-#define BASS_CONFIG_FLOAT			54
-#define BASS_CONFIG_NET_SEEK		56
-#define BASS_CONFIG_AM_DISABLE		58
-#define BASS_CONFIG_NET_PLAYLIST_DEPTH	59
-#define BASS_CONFIG_NET_PREBUF_WAIT	60
-#define BASS_CONFIG_ANDROID_SESSIONID	62
-#define BASS_CONFIG_WASAPI_PERSIST	65
-#define BASS_CONFIG_REC_WASAPI		66
-#define BASS_CONFIG_ANDROID_AAUDIO	67
-#define BASS_CONFIG_SAMPLE_ONEHANDLE	69
-#define BASS_CONFIG_DEV_TIMEOUT		70
-#define BASS_CONFIG_NET_META		71
-#define BASS_CONFIG_NET_RESTRATE	72
-
-// BASS_SetConfigPtr options
-#define BASS_CONFIG_NET_AGENT		16
-#define BASS_CONFIG_NET_PROXY		17
-#define BASS_CONFIG_IOS_NOTIFY		46
-#define BASS_CONFIG_LIBSSL			64
-
-#define BASS_CONFIG_THREAD			0x40000000 // flag: thread-specific setting
-
-// BASS_CONFIG_IOS_SESSION flags
-#define BASS_IOS_SESSION_MIX		1
-#define BASS_IOS_SESSION_DUCK		2
-#define BASS_IOS_SESSION_AMBIENT	4
-#define BASS_IOS_SESSION_SPEAKER	8
-#define BASS_IOS_SESSION_DISABLE	16
-
-// BASS_Init flags
-#define BASS_DEVICE_8BITS		1		// unused
-#define BASS_DEVICE_MONO		2		// mono
-#define BASS_DEVICE_3D			4		// unused
-#define BASS_DEVICE_16BITS		8		// limit output to 16-bit
-#define BASS_DEVICE_REINIT		128		// reinitialize
-#define BASS_DEVICE_LATENCY		0x100	// unused
-#define BASS_DEVICE_CPSPEAKERS	0x400	// unused
-#define BASS_DEVICE_SPEAKERS	0x800	// force enabling of speaker assignment
-#define BASS_DEVICE_NOSPEAKER	0x1000	// ignore speaker arrangement
-#define BASS_DEVICE_DMIX		0x2000	// use ALSA "dmix" plugin
-#define BASS_DEVICE_FREQ		0x4000	// set device sample rate
-#define BASS_DEVICE_STEREO		0x8000	// limit output to stereo
-#define BASS_DEVICE_HOG			0x10000	// hog/exclusive mode
-#define BASS_DEVICE_AUDIOTRACK	0x20000	// use AudioTrack output
-#define BASS_DEVICE_DSOUND		0x40000	// use DirectSound output
-#define BASS_DEVICE_SOFTWARE	0x80000	// disable hardware/fastpath output
-
-// DirectSound interfaces (for use with BASS_GetDSoundObject)
-#define BASS_OBJECT_DS		1	// IDirectSound
-#define BASS_OBJECT_DS3DL	2	// IDirectSound3DListener
-
-// Device info structure
-typedef struct {
-#if defined(_WIN32_WCE) || (defined(WINAPI_FAMILY) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)
-	const wchar_t *name;	// description
-	const wchar_t *driver;	// driver
-#else
-	const char *name;	// description
-	const char *driver;	// driver
-#endif
-	DWORD flags;
-} BASS_DEVICEINFO;
-
-// BASS_DEVICEINFO flags
-#define BASS_DEVICE_ENABLED		1
-#define BASS_DEVICE_DEFAULT		2
-#define BASS_DEVICE_INIT		4
-#define BASS_DEVICE_LOOPBACK	8
-#define BASS_DEVICE_DEFAULTCOM	128
-
-#define BASS_DEVICE_TYPE_MASK			0xff000000
-#define BASS_DEVICE_TYPE_NETWORK		0x01000000
-#define BASS_DEVICE_TYPE_SPEAKERS		0x02000000
-#define BASS_DEVICE_TYPE_LINE			0x03000000
-#define BASS_DEVICE_TYPE_HEADPHONES		0x04000000
-#define BASS_DEVICE_TYPE_MICROPHONE		0x05000000
-#define BASS_DEVICE_TYPE_HEADSET		0x06000000
-#define BASS_DEVICE_TYPE_HANDSET		0x07000000
-#define BASS_DEVICE_TYPE_DIGITAL		0x08000000
-#define BASS_DEVICE_TYPE_SPDIF			0x09000000
-#define BASS_DEVICE_TYPE_HDMI			0x0a000000
-#define BASS_DEVICE_TYPE_DISPLAYPORT	0x40000000
-
-// BASS_GetDeviceInfo flags
-#define BASS_DEVICES_AIRPLAY	0x1000000
-
-typedef struct {
-	DWORD flags;	// device capabilities (DSCAPS_xxx flags)
-	DWORD hwsize;	// unused
-	DWORD hwfree;	// unused
-	DWORD freesam;	// unused
-	DWORD free3d;	// unused
-	DWORD minrate;	// unused
-	DWORD maxrate;	// unused
-	BOOL eax;		// unused
-	DWORD minbuf;	// recommended minimum buffer length in ms
-	DWORD dsver;	// DirectSound version
-	DWORD latency;	// average delay (in ms) before start of playback
-	DWORD initflags; // BASS_Init "flags" parameter
-	DWORD speakers; // number of speakers available
-	DWORD freq;		// current output rate
-} BASS_INFO;
-
-// BASS_INFO flags (from DSOUND.H)
-#define DSCAPS_EMULDRIVER		0x00000020	// device does not have hardware DirectSound support
-#define DSCAPS_CERTIFIED		0x00000040	// device driver has been certified by Microsoft
-
-#define DSCAPS_HARDWARE			0x80000000	// hardware mixed
-
-// Recording device info structure
-typedef struct {
-	DWORD flags;	// device capabilities (DSCCAPS_xxx flags)
-	DWORD formats;	// supported standard formats (WAVE_FORMAT_xxx flags)
-	DWORD inputs;	// number of inputs
-	BOOL singlein;	// TRUE = only 1 input can be set at a time
-	DWORD freq;		// current input rate
-} BASS_RECORDINFO;
-
-// BASS_RECORDINFO flags (from DSOUND.H)
-#define DSCCAPS_EMULDRIVER		DSCAPS_EMULDRIVER	// device does not have hardware DirectSound recording support
-#define DSCCAPS_CERTIFIED		DSCAPS_CERTIFIED	// device driver has been certified by Microsoft
-
-// defines for formats field of BASS_RECORDINFO (from MMSYSTEM.H)
-#ifndef WAVE_FORMAT_1M08
-#define WAVE_FORMAT_1M08       0x00000001       /* 11.025 kHz, Mono,   8-bit  */
-#define WAVE_FORMAT_1S08       0x00000002       /* 11.025 kHz, Stereo, 8-bit  */
-#define WAVE_FORMAT_1M16       0x00000004       /* 11.025 kHz, Mono,   16-bit */
-#define WAVE_FORMAT_1S16       0x00000008       /* 11.025 kHz, Stereo, 16-bit */
-#define WAVE_FORMAT_2M08       0x00000010       /* 22.05  kHz, Mono,   8-bit  */
-#define WAVE_FORMAT_2S08       0x00000020       /* 22.05  kHz, Stereo, 8-bit  */
-#define WAVE_FORMAT_2M16       0x00000040       /* 22.05  kHz, Mono,   16-bit */
-#define WAVE_FORMAT_2S16       0x00000080       /* 22.05  kHz, Stereo, 16-bit */
-#define WAVE_FORMAT_4M08       0x00000100       /* 44.1   kHz, Mono,   8-bit  */
-#define WAVE_FORMAT_4S08       0x00000200       /* 44.1   kHz, Stereo, 8-bit  */
-#define WAVE_FORMAT_4M16       0x00000400       /* 44.1   kHz, Mono,   16-bit */
-#define WAVE_FORMAT_4S16       0x00000800       /* 44.1   kHz, Stereo, 16-bit */
-#endif
-
-// Sample info structure
-typedef struct {
-	DWORD freq;		// default playback rate
-	float volume;	// default volume (0-1)
-	float pan;		// default pan (-1=left, 0=middle, 1=right)
-	DWORD flags;	// BASS_SAMPLE_xxx flags
-	DWORD length;	// length (in bytes)
-	DWORD max;		// maximum simultaneous playbacks
-	DWORD origres;	// original resolution
-	DWORD chans;	// number of channels
-	DWORD mingap;	// minimum gap (ms) between creating channels
-	DWORD mode3d;	// BASS_3DMODE_xxx mode
-	float mindist;	// minimum distance
-	float maxdist;	// maximum distance
-	DWORD iangle;	// angle of inside projection cone
-	DWORD oangle;	// angle of outside projection cone
-	float outvol;	// delta-volume outside the projection cone
-	DWORD vam;		// unused
-	DWORD priority;	// unused
-} BASS_SAMPLE;
-
-#define BASS_SAMPLE_8BITS		1	// 8 bit
-#define BASS_SAMPLE_FLOAT		256	// 32 bit floating-point
-#define BASS_SAMPLE_MONO		2	// mono
-#define BASS_SAMPLE_LOOP		4	// looped
-#define BASS_SAMPLE_3D			8	// 3D functionality
-#define BASS_SAMPLE_SOFTWARE	16	// unused
-#define BASS_SAMPLE_MUTEMAX		32	// mute at max distance (3D only)
-#define BASS_SAMPLE_VAM			64	// unused
-#define BASS_SAMPLE_FX			128	// unused
-#define BASS_SAMPLE_OVER_VOL	0x10000	// override lowest volume
-#define BASS_SAMPLE_OVER_POS	0x20000	// override longest playing
-#define BASS_SAMPLE_OVER_DIST	0x30000 // override furthest from listener (3D only)
-
-#define BASS_STREAM_PRESCAN		0x20000 // scan file for accurate seeking and length
-#define BASS_STREAM_AUTOFREE	0x40000	// automatically free the stream when it stops/ends
-#define BASS_STREAM_RESTRATE	0x80000	// restrict the download rate of internet file stream
-#define BASS_STREAM_BLOCK		0x100000 // download internet file stream in small blocks
-#define BASS_STREAM_DECODE		0x200000 // don't play the stream, only decode
-#define BASS_STREAM_STATUS		0x800000 // give server status info (HTTP/ICY tags) in DOWNLOADPROC
-
-#define BASS_MP3_IGNOREDELAY	0x200 // ignore LAME/Xing/VBRI/iTunes delay & padding info
-#define BASS_MP3_SETPOS			BASS_STREAM_PRESCAN
-
-#define BASS_MUSIC_FLOAT		BASS_SAMPLE_FLOAT
-#define BASS_MUSIC_MONO			BASS_SAMPLE_MONO
-#define BASS_MUSIC_LOOP			BASS_SAMPLE_LOOP
-#define BASS_MUSIC_3D			BASS_SAMPLE_3D
-#define BASS_MUSIC_FX			BASS_SAMPLE_FX
-#define BASS_MUSIC_AUTOFREE		BASS_STREAM_AUTOFREE
-#define BASS_MUSIC_DECODE		BASS_STREAM_DECODE
-#define BASS_MUSIC_PRESCAN		BASS_STREAM_PRESCAN	// calculate playback length
-#define BASS_MUSIC_CALCLEN		BASS_MUSIC_PRESCAN
-#define BASS_MUSIC_RAMP			0x200	// normal ramping
-#define BASS_MUSIC_RAMPS		0x400	// sensitive ramping
-#define BASS_MUSIC_SURROUND		0x800	// surround sound
-#define BASS_MUSIC_SURROUND2	0x1000	// surround sound (mode 2)
-#define BASS_MUSIC_FT2PAN		0x2000	// apply FastTracker 2 panning to XM files
-#define BASS_MUSIC_FT2MOD		0x2000	// play .MOD as FastTracker 2 does
-#define BASS_MUSIC_PT1MOD		0x4000	// play .MOD as ProTracker 1 does
-#define BASS_MUSIC_NONINTER		0x10000	// non-interpolated sample mixing
-#define BASS_MUSIC_SINCINTER	0x800000 // sinc interpolated sample mixing
-#define BASS_MUSIC_POSRESET		0x8000	// stop all notes when moving position
-#define BASS_MUSIC_POSRESETEX	0x400000 // stop all notes and reset bmp/etc when moving position
-#define BASS_MUSIC_STOPBACK		0x80000	// stop the music on a backwards jump effect
-#define BASS_MUSIC_NOSAMPLE		0x100000 // don't load the samples
-
-// Speaker assignment flags
-#define BASS_SPEAKER_FRONT	0x1000000	// front speakers
-#define BASS_SPEAKER_REAR	0x2000000	// rear/side speakers
-#define BASS_SPEAKER_CENLFE	0x3000000	// center & LFE speakers (5.1)
-#define BASS_SPEAKER_REAR2	0x4000000	// rear center speakers (7.1)
-#define BASS_SPEAKER_N(n)	((n)<<24)	// n'th pair of speakers (max 15)
-#define BASS_SPEAKER_LEFT	0x10000000	// modifier: left
-#define BASS_SPEAKER_RIGHT	0x20000000	// modifier: right
-#define BASS_SPEAKER_FRONTLEFT	BASS_SPEAKER_FRONT|BASS_SPEAKER_LEFT
-#define BASS_SPEAKER_FRONTRIGHT	BASS_SPEAKER_FRONT|BASS_SPEAKER_RIGHT
-#define BASS_SPEAKER_REARLEFT	BASS_SPEAKER_REAR|BASS_SPEAKER_LEFT
-#define BASS_SPEAKER_REARRIGHT	BASS_SPEAKER_REAR|BASS_SPEAKER_RIGHT
-#define BASS_SPEAKER_CENTER		BASS_SPEAKER_CENLFE|BASS_SPEAKER_LEFT
-#define BASS_SPEAKER_LFE		BASS_SPEAKER_CENLFE|BASS_SPEAKER_RIGHT
-#define BASS_SPEAKER_REAR2LEFT	BASS_SPEAKER_REAR2|BASS_SPEAKER_LEFT
-#define BASS_SPEAKER_REAR2RIGHT	BASS_SPEAKER_REAR2|BASS_SPEAKER_RIGHT
-
-#define BASS_ASYNCFILE			0x40000000	// read file asynchronously
-#define BASS_UNICODE			0x80000000	// UTF-16
-
-#define BASS_RECORD_PAUSE		0x8000	// start recording paused
-#define BASS_RECORD_ECHOCANCEL	0x2000
-#define BASS_RECORD_AGC			0x4000
-
-// DX7 voice allocation & management flags
-#define BASS_VAM_HARDWARE		1
-#define BASS_VAM_SOFTWARE		2
-#define BASS_VAM_TERM_TIME		4
-#define BASS_VAM_TERM_DIST		8
-#define BASS_VAM_TERM_PRIO		16
-
-// Channel info structure
-typedef struct {
-	DWORD freq;		// default playback rate
-	DWORD chans;	// channels
-	DWORD flags;
-	DWORD ctype;	// type of channel
-	DWORD origres;	// original resolution
-	HPLUGIN plugin;
-	HSAMPLE sample;
-	const char *filename;
-} BASS_CHANNELINFO;
-
-#define BASS_ORIGRES_FLOAT		0x10000
-
-// BASS_CHANNELINFO types
-#define BASS_CTYPE_SAMPLE		1
-#define BASS_CTYPE_RECORD		2
-#define BASS_CTYPE_STREAM		0x10000
-#define BASS_CTYPE_STREAM_VORBIS	0x10002
-#define BASS_CTYPE_STREAM_OGG	0x10002
-#define BASS_CTYPE_STREAM_MP1	0x10003
-#define BASS_CTYPE_STREAM_MP2	0x10004
-#define BASS_CTYPE_STREAM_MP3	0x10005
-#define BASS_CTYPE_STREAM_AIFF	0x10006
-#define BASS_CTYPE_STREAM_CA	0x10007
-#define BASS_CTYPE_STREAM_MF	0x10008
-#define BASS_CTYPE_STREAM_AM	0x10009
-#define BASS_CTYPE_STREAM_SAMPLE	0x1000a
-#define BASS_CTYPE_STREAM_DUMMY		0x18000
-#define BASS_CTYPE_STREAM_DEVICE	0x18001
-#define BASS_CTYPE_STREAM_WAV	0x40000 // WAVE flag (LOWORD=codec)
-#define BASS_CTYPE_STREAM_WAV_PCM	0x50001
-#define BASS_CTYPE_STREAM_WAV_FLOAT	0x50003
-#define BASS_CTYPE_MUSIC_MOD	0x20000
-#define BASS_CTYPE_MUSIC_MTM	0x20001
-#define BASS_CTYPE_MUSIC_S3M	0x20002
-#define BASS_CTYPE_MUSIC_XM		0x20003
-#define BASS_CTYPE_MUSIC_IT		0x20004
-#define BASS_CTYPE_MUSIC_MO3	0x00100 // MO3 flag
-
-typedef struct {
-	DWORD ctype;		// channel type
-#if defined(_WIN32_WCE) || (defined(WINAPI_FAMILY) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)
-	const wchar_t *name;	// format description
-	const wchar_t *exts;	// file extension filter (*.ext1;*.ext2;etc...)
-#else
-	const char *name;	// format description
-	const char *exts;	// file extension filter (*.ext1;*.ext2;etc...)
-#endif
-} BASS_PLUGINFORM;
-
-typedef struct {
-	DWORD version;					// version (same form as BASS_GetVersion)
-	DWORD formatc;					// number of formats
-	const BASS_PLUGINFORM *formats;	// the array of formats
-} BASS_PLUGININFO;
-
-// 3D vector (for 3D positions/velocities/orientations)
-typedef struct BASS_3DVECTOR {
-#ifdef __cplusplus
-	BASS_3DVECTOR() {};
-	BASS_3DVECTOR(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {};
-#endif
-	float x;	// +=right, -=left
-	float y;	// +=up, -=down
-	float z;	// +=front, -=behind
-} BASS_3DVECTOR;
-
-// 3D channel modes
-#define BASS_3DMODE_NORMAL		0	// normal 3D processing
-#define BASS_3DMODE_RELATIVE	1	// position is relative to the listener
-#define BASS_3DMODE_OFF			2	// no 3D processing
-
-// software 3D mixing algorithms (used with BASS_CONFIG_3DALGORITHM)
-#define BASS_3DALG_DEFAULT	0
-#define BASS_3DALG_OFF		1
-#define BASS_3DALG_FULL		2
-#define BASS_3DALG_LIGHT	3
-
-// BASS_SampleGetChannel flags
-#define BASS_SAMCHAN_NEW		1	// get a new playback channel
-#define BASS_SAMCHAN_STREAM		2	// create a stream
-
-typedef DWORD (CALLBACK STREAMPROC)(HSTREAM handle, void *buffer, DWORD length, void *user);
-/* User stream callback function.
-handle : The stream that needs writing
-buffer : Buffer to write the samples in
-length : Number of bytes to write
-user   : The 'user' parameter value given when calling BASS_StreamCreate
-RETURN : Number of bytes written. Set the BASS_STREAMPROC_END flag to end the stream. */
-
-#define BASS_STREAMPROC_END		0x80000000	// end of user stream flag
-
-// Special STREAMPROCs
-#define STREAMPROC_DUMMY		(STREAMPROC*)0		// "dummy" stream
-#define STREAMPROC_PUSH			(STREAMPROC*)-1		// push stream
-#define STREAMPROC_DEVICE		(STREAMPROC*)-2		// device mix stream
-#define STREAMPROC_DEVICE_3D	(STREAMPROC*)-3		// device 3D mix stream
-
-// BASS_StreamCreateFileUser file systems
-#define STREAMFILE_NOBUFFER		0
-#define STREAMFILE_BUFFER		1
-#define STREAMFILE_BUFFERPUSH	2
-
-// User file stream callback functions
-typedef void (CALLBACK FILECLOSEPROC)(void *user);
-typedef QWORD (CALLBACK FILELENPROC)(void *user);
-typedef DWORD (CALLBACK FILEREADPROC)(void *buffer, DWORD length, void *user);
-typedef BOOL (CALLBACK FILESEEKPROC)(QWORD offset, void *user);
-
-typedef struct {
-	FILECLOSEPROC *close;
-	FILELENPROC *length;
-	FILEREADPROC *read;
-	FILESEEKPROC *seek;
-} BASS_FILEPROCS;
-
-// BASS_StreamPutFileData options
-#define BASS_FILEDATA_END		0	// end & close the file
-
-// BASS_StreamGetFilePosition modes
-#define BASS_FILEPOS_CURRENT	0
-#define BASS_FILEPOS_DECODE		BASS_FILEPOS_CURRENT
-#define BASS_FILEPOS_DOWNLOAD	1
-#define BASS_FILEPOS_END		2
-#define BASS_FILEPOS_START		3
-#define BASS_FILEPOS_CONNECTED	4
-#define BASS_FILEPOS_BUFFER		5
-#define BASS_FILEPOS_SOCKET		6
-#define BASS_FILEPOS_ASYNCBUF	7
-#define BASS_FILEPOS_SIZE		8
-#define BASS_FILEPOS_BUFFERING	9
-#define BASS_FILEPOS_AVAILABLE	10
-
-typedef void (CALLBACK DOWNLOADPROC)(const void *buffer, DWORD length, void *user);
-/* Internet stream download callback function.
-buffer : Buffer containing the downloaded data... NULL=end of download
-length : Number of bytes in the buffer
-user   : The 'user' parameter value given when calling BASS_StreamCreateURL */
-
-// BASS_ChannelSetSync types
-#define BASS_SYNC_POS			0
-#define BASS_SYNC_END			2
-#define BASS_SYNC_META			4
-#define BASS_SYNC_SLIDE			5
-#define BASS_SYNC_STALL			6
-#define BASS_SYNC_DOWNLOAD		7
-#define BASS_SYNC_FREE			8
-#define BASS_SYNC_SETPOS		11
-#define BASS_SYNC_MUSICPOS		10
-#define BASS_SYNC_MUSICINST		1
-#define BASS_SYNC_MUSICFX		3
-#define BASS_SYNC_OGG_CHANGE	12
-#define BASS_SYNC_DEV_FAIL		14
-#define BASS_SYNC_DEV_FORMAT	15
-#define BASS_SYNC_THREAD		0x20000000	// flag: call sync in other thread
-#define BASS_SYNC_MIXTIME		0x40000000	// flag: sync at mixtime, else at playtime
-#define BASS_SYNC_ONETIME		0x80000000	// flag: sync only once, else continuously
-
-typedef void (CALLBACK SYNCPROC)(HSYNC handle, DWORD channel, DWORD data, void *user);
-/* Sync callback function.
-handle : The sync that has occured
-channel: Channel that the sync occured in
-data   : Additional data associated with the sync's occurance
-user   : The 'user' parameter given when calling BASS_ChannelSetSync */
-
-typedef void (CALLBACK DSPPROC)(HDSP handle, DWORD channel, void *buffer, DWORD length, void *user);
-/* DSP callback function.
-handle : The DSP handle
-channel: Channel that the DSP is being applied to
-buffer : Buffer to apply the DSP to
-length : Number of bytes in the buffer
-user   : The 'user' parameter given when calling BASS_ChannelSetDSP */
-
-typedef BOOL (CALLBACK RECORDPROC)(HRECORD handle, const void *buffer, DWORD length, void *user);
-/* Recording callback function.
-handle : The recording handle
-buffer : Buffer containing the recorded sample data
-length : Number of bytes
-user   : The 'user' parameter value given when calling BASS_RecordStart
-RETURN : TRUE = continue recording, FALSE = stop */
-
-// BASS_ChannelIsActive return values
-#define BASS_ACTIVE_STOPPED			0
-#define BASS_ACTIVE_PLAYING			1
-#define BASS_ACTIVE_STALLED			2
-#define BASS_ACTIVE_PAUSED			3
-#define BASS_ACTIVE_PAUSED_DEVICE	4
-
-// Channel attributes
-#define BASS_ATTRIB_FREQ			1
-#define BASS_ATTRIB_VOL				2
-#define BASS_ATTRIB_PAN				3
-#define BASS_ATTRIB_EAXMIX			4
-#define BASS_ATTRIB_NOBUFFER		5
-#define BASS_ATTRIB_VBR				6
-#define BASS_ATTRIB_CPU				7
-#define BASS_ATTRIB_SRC				8
-#define BASS_ATTRIB_NET_RESUME		9
-#define BASS_ATTRIB_SCANINFO		10
-#define BASS_ATTRIB_NORAMP			11
-#define BASS_ATTRIB_BITRATE			12
-#define BASS_ATTRIB_BUFFER			13
-#define BASS_ATTRIB_GRANULE			14
-#define BASS_ATTRIB_USER			15
-#define BASS_ATTRIB_TAIL			16
-#define BASS_ATTRIB_PUSH_LIMIT		17
-#define BASS_ATTRIB_MUSIC_AMPLIFY	0x100
-#define BASS_ATTRIB_MUSIC_PANSEP	0x101
-#define BASS_ATTRIB_MUSIC_PSCALER	0x102
-#define BASS_ATTRIB_MUSIC_BPM		0x103
-#define BASS_ATTRIB_MUSIC_SPEED		0x104
-#define BASS_ATTRIB_MUSIC_VOL_GLOBAL 0x105
-#define BASS_ATTRIB_MUSIC_ACTIVE	0x106
-#define BASS_ATTRIB_MUSIC_VOL_CHAN	0x200 // + channel #
-#define BASS_ATTRIB_MUSIC_VOL_INST	0x300 // + instrument #
-
-// BASS_ChannelSlideAttribute flags
-#define BASS_SLIDE_LOG				0x1000000
-
-// BASS_ChannelGetData flags
-#define BASS_DATA_AVAILABLE	0			// query how much data is buffered
-#define BASS_DATA_NOREMOVE	0x10000000	// flag: don't remove data from recording buffer
-#define BASS_DATA_FIXED		0x20000000	// flag: return 8.24 fixed-point data
-#define BASS_DATA_FLOAT		0x40000000	// flag: return floating-point sample data
-#define BASS_DATA_FFT256	0x80000000	// 256 sample FFT
-#define BASS_DATA_FFT512	0x80000001	// 512 FFT
-#define BASS_DATA_FFT1024	0x80000002	// 1024 FFT
-#define BASS_DATA_FFT2048	0x80000003	// 2048 FFT
-#define BASS_DATA_FFT4096	0x80000004	// 4096 FFT
-#define BASS_DATA_FFT8192	0x80000005	// 8192 FFT
-#define BASS_DATA_FFT16384	0x80000006	// 16384 FFT
-#define BASS_DATA_FFT32768	0x80000007	// 32768 FFT
-#define BASS_DATA_FFT_INDIVIDUAL 0x10	// FFT flag: FFT for each channel, else all combined
-#define BASS_DATA_FFT_NOWINDOW	0x20	// FFT flag: no Hanning window
-#define BASS_DATA_FFT_REMOVEDC	0x40	// FFT flag: pre-remove DC bias
-#define BASS_DATA_FFT_COMPLEX	0x80	// FFT flag: return complex data
-#define BASS_DATA_FFT_NYQUIST	0x100	// FFT flag: return extra Nyquist value
-
-// BASS_ChannelGetLevelEx flags
-#define BASS_LEVEL_MONO		1	// get mono level
-#define BASS_LEVEL_STEREO	2	// get stereo level
-#define BASS_LEVEL_RMS		4	// get RMS levels
-#define BASS_LEVEL_VOLPAN	8	// apply VOL/PAN attributes to the levels
-#define BASS_LEVEL_NOREMOVE	16	// don't remove data from recording buffer
-
-// BASS_ChannelGetTags types : what's returned
-#define BASS_TAG_ID3		0	// ID3v1 tags : TAG_ID3 structure
-#define BASS_TAG_ID3V2		1	// ID3v2 tags : variable length block
-#define BASS_TAG_OGG		2	// OGG comments : series of null-terminated UTF-8 strings
-#define BASS_TAG_HTTP		3	// HTTP headers : series of null-terminated ASCII strings
-#define BASS_TAG_ICY		4	// ICY headers : series of null-terminated ANSI strings
-#define BASS_TAG_META		5	// ICY metadata : ANSI string
-#define BASS_TAG_APE		6	// APE tags : series of null-terminated UTF-8 strings
-#define BASS_TAG_MP4 		7	// MP4/iTunes metadata : series of null-terminated UTF-8 strings
-#define BASS_TAG_WMA		8	// WMA tags : series of null-terminated UTF-8 strings
-#define BASS_TAG_VENDOR		9	// OGG encoder : UTF-8 string
-#define BASS_TAG_LYRICS3	10	// Lyric3v2 tag : ASCII string
-#define BASS_TAG_CA_CODEC	11	// CoreAudio codec info : TAG_CA_CODEC structure
-#define BASS_TAG_MF			13	// Media Foundation tags : series of null-terminated UTF-8 strings
-#define BASS_TAG_WAVEFORMAT	14	// WAVE format : WAVEFORMATEEX structure
-#define BASS_TAG_AM_NAME	16	// Android Media codec name : ASCII string
-#define BASS_TAG_ID3V2_2	17	// ID3v2 tags (2nd block) : variable length block
-#define BASS_TAG_AM_MIME	18	// Android Media MIME type : ASCII string
-#define BASS_TAG_LOCATION	19	// redirected URL : ASCII string
-#define BASS_TAG_RIFF_INFO	0x100 // RIFF "INFO" tags : series of null-terminated ANSI strings
-#define BASS_TAG_RIFF_BEXT	0x101 // RIFF/BWF "bext" tags : TAG_BEXT structure
-#define BASS_TAG_RIFF_CART	0x102 // RIFF/BWF "cart" tags : TAG_CART structure
-#define BASS_TAG_RIFF_DISP	0x103 // RIFF "DISP" text tag : ANSI string
-#define BASS_TAG_RIFF_CUE	0x104 // RIFF "cue " chunk : TAG_CUE structure
-#define BASS_TAG_RIFF_SMPL	0x105 // RIFF "smpl" chunk : TAG_SMPL structure
-#define BASS_TAG_APE_BINARY	0x1000	// + index #, binary APE tag : TAG_APE_BINARY structure
-#define BASS_TAG_MUSIC_NAME		0x10000	// MOD music name : ANSI string
-#define BASS_TAG_MUSIC_MESSAGE	0x10001	// MOD message : ANSI string
-#define BASS_TAG_MUSIC_ORDERS	0x10002	// MOD order list : BYTE array of pattern numbers
-#define BASS_TAG_MUSIC_AUTH		0x10003	// MOD author : UTF-8 string
-#define BASS_TAG_MUSIC_INST		0x10100	// + instrument #, MOD instrument name : ANSI string
-#define BASS_TAG_MUSIC_CHAN		0x10200	// + channel #, MOD channel name : ANSI string
-#define BASS_TAG_MUSIC_SAMPLE	0x10300	// + sample #, MOD sample name : ANSI string
-
-// ID3v1 tag structure
-typedef struct {
-	char id[3];
-	char title[30];
-	char artist[30];
-	char album[30];
-	char year[4];
-	char comment[30];
-	BYTE genre;
-} TAG_ID3;
-
-// Binary APE tag structure
-typedef struct {
-	const char *key;
-	const void *data;
-	DWORD length;
-} TAG_APE_BINARY;
-
-// BWF "bext" tag structure
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4200)
-#endif
-#pragma pack(push,1)
-typedef struct {
-	char Description[256];			// description
-	char Originator[32];			// name of the originator
-	char OriginatorReference[32];	// reference of the originator
-	char OriginationDate[10];		// date of creation (yyyy-mm-dd)
-	char OriginationTime[8];		// time of creation (hh-mm-ss)
-	QWORD TimeReference;			// first sample count since midnight (little-endian)
-	WORD Version;					// BWF version (little-endian)
-	BYTE UMID[64];					// SMPTE UMID
-	BYTE Reserved[190];
-#if defined(__GNUC__) && __GNUC__<3
-	char CodingHistory[0];			// history
-#elif 1 // change to 0 if compiler fails the following line
-	char CodingHistory[];			// history
-#else
-	char CodingHistory[1];			// history
-#endif
-} TAG_BEXT;
-#pragma pack(pop)
-
-// BWF "cart" tag structures
-typedef struct
-{
-	DWORD dwUsage;					// FOURCC timer usage ID
-	DWORD dwValue;					// timer value in samples from head
-} TAG_CART_TIMER;
-
-typedef struct
-{
-	char Version[4];				// version of the data structure
-	char Title[64];					// title of cart audio sequence
-	char Artist[64];				// artist or creator name
-	char CutID[64];					// cut number identification
-	char ClientID[64];				// client identification
-	char Category[64];				// category ID, PSA, NEWS, etc
-	char Classification[64];		// classification or auxiliary key
-	char OutCue[64];				// out cue text
-	char StartDate[10];				// yyyy-mm-dd
-	char StartTime[8];				// hh:mm:ss
-	char EndDate[10];				// yyyy-mm-dd
-	char EndTime[8];				// hh:mm:ss
-	char ProducerAppID[64];			// name of vendor or application
-	char ProducerAppVersion[64];	// version of producer application
-	char UserDef[64];				// user defined text
-	DWORD dwLevelReference;			// sample value for 0 dB reference
-	TAG_CART_TIMER PostTimer[8];	// 8 time markers after head
-	char Reserved[276];
-	char URL[1024];					// uniform resource locator
-#if defined(__GNUC__) && __GNUC__<3
-	char TagText[0];				// free form text for scripts or tags
-#elif 1 // change to 0 if compiler fails the following line
-	char TagText[];					// free form text for scripts or tags
-#else
-	char TagText[1];				// free form text for scripts or tags
-#endif
-} TAG_CART;
-
-// RIFF "cue " tag structures
-typedef struct
-{
-	DWORD dwName;
-	DWORD dwPosition;
-	DWORD fccChunk;
-	DWORD dwChunkStart;
-	DWORD dwBlockStart;
-	DWORD dwSampleOffset;
-} TAG_CUE_POINT;
-
-typedef struct
-{
-	DWORD dwCuePoints;
-#if defined(__GNUC__) && __GNUC__<3
-	TAG_CUE_POINT CuePoints[0];
-#elif 1 // change to 0 if compiler fails the following line
-	TAG_CUE_POINT CuePoints[];
-#else
-	TAG_CUE_POINT CuePoints[1];
-#endif
-} TAG_CUE;
-
-// RIFF "smpl" tag structures
-typedef struct
-{
-	DWORD dwIdentifier;
-	DWORD dwType;
-	DWORD dwStart;
-	DWORD dwEnd;
-	DWORD dwFraction;
-	DWORD dwPlayCount;
-} TAG_SMPL_LOOP;
-
-typedef struct
-{
-	DWORD dwManufacturer;
-	DWORD dwProduct;
-	DWORD dwSamplePeriod;
-	DWORD dwMIDIUnityNote;
-	DWORD dwMIDIPitchFraction;
-	DWORD dwSMPTEFormat;
-	DWORD dwSMPTEOffset;
-	DWORD cSampleLoops;
-	DWORD cbSamplerData;
-#if defined(__GNUC__) && __GNUC__<3
-	TAG_SMPL_LOOP SampleLoops[0];
-#elif 1 // change to 0 if compiler fails the following line
-	TAG_SMPL_LOOP SampleLoops[];
-#else
-	TAG_SMPL_LOOP SampleLoops[1];
-#endif
-} TAG_SMPL;
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-// CoreAudio codec info structure
-typedef struct {
-	DWORD ftype;					// file format
-	DWORD atype;					// audio format
-	const char *name;				// description
-} TAG_CA_CODEC;
-
-#ifndef _WAVEFORMATEX_
-#define _WAVEFORMATEX_
-#pragma pack(push,1)
-typedef struct tWAVEFORMATEX
-{
-	WORD wFormatTag;
-	WORD nChannels;
-	DWORD nSamplesPerSec;
-	DWORD nAvgBytesPerSec;
-	WORD nBlockAlign;
-	WORD wBitsPerSample;
-	WORD cbSize;
-} WAVEFORMATEX, *PWAVEFORMATEX, *LPWAVEFORMATEX;
-typedef const WAVEFORMATEX *LPCWAVEFORMATEX;
-#pragma pack(pop)
-#endif
-
-// BASS_ChannelGetLength/GetPosition/SetPosition modes
-#define BASS_POS_BYTE			0		// byte position
-#define BASS_POS_MUSIC_ORDER	1		// order.row position, MAKELONG(order,row)
-#define BASS_POS_OGG			3		// OGG bitstream number
-#define BASS_POS_END			0x10	// trimmed end position
-#define BASS_POS_LOOP			0x11	// loop start positiom
-#define BASS_POS_FLUSH			0x1000000 // flag: flush decoder/FX buffers
-#define BASS_POS_RESET			0x2000000 // flag: reset user file buffers
-#define BASS_POS_RELATIVE		0x4000000 // flag: seek relative to the current position
-#define BASS_POS_INEXACT		0x8000000 // flag: allow seeking to inexact position
-#define BASS_POS_DECODE			0x10000000 // flag: get the decoding (not playing) position
-#define BASS_POS_DECODETO		0x20000000 // flag: decode to the position instead of seeking
-#define BASS_POS_SCAN			0x40000000 // flag: scan to the position
-
-// BASS_ChannelSetDevice/GetDevice option
-#define BASS_NODEVICE		0x20000
-
-// BASS_RecordSetInput flags
-#define BASS_INPUT_OFF		0x10000
-#define BASS_INPUT_ON		0x20000
-
-#define BASS_INPUT_TYPE_MASK		0xff000000
-#define BASS_INPUT_TYPE_UNDEF		0x00000000
-#define BASS_INPUT_TYPE_DIGITAL		0x01000000
-#define BASS_INPUT_TYPE_LINE		0x02000000
-#define BASS_INPUT_TYPE_MIC			0x03000000
-#define BASS_INPUT_TYPE_SYNTH		0x04000000
-#define BASS_INPUT_TYPE_CD			0x05000000
-#define BASS_INPUT_TYPE_PHONE		0x06000000
-#define BASS_INPUT_TYPE_SPEAKER		0x07000000
-#define BASS_INPUT_TYPE_WAVE		0x08000000
-#define BASS_INPUT_TYPE_AUX			0x09000000
-#define BASS_INPUT_TYPE_ANALOG		0x0a000000
-
-// BASS_ChannelSetFX effect types
-#define BASS_FX_DX8_CHORUS			0
-#define BASS_FX_DX8_COMPRESSOR		1
-#define BASS_FX_DX8_DISTORTION		2
-#define BASS_FX_DX8_ECHO			3
-#define BASS_FX_DX8_FLANGER			4
-#define BASS_FX_DX8_GARGLE			5
-#define BASS_FX_DX8_I3DL2REVERB		6
-#define BASS_FX_DX8_PARAMEQ			7
-#define BASS_FX_DX8_REVERB			8
-#define BASS_FX_VOLUME				9
-
-typedef struct {
-	float       fWetDryMix;
-	float       fDepth;
-	float       fFeedback;
-	float       fFrequency;
-	DWORD       lWaveform;	// 0=triangle, 1=sine
-	float       fDelay;
-	DWORD       lPhase;		// BASS_DX8_PHASE_xxx
-} BASS_DX8_CHORUS;
-
-typedef struct {
-	float   fGain;
-	float   fAttack;
-	float   fRelease;
-	float   fThreshold;
-	float   fRatio;
-	float   fPredelay;
-} BASS_DX8_COMPRESSOR;
-
-typedef struct {
-	float   fGain;
-	float   fEdge;
-	float   fPostEQCenterFrequency;
-	float   fPostEQBandwidth;
-	float   fPreLowpassCutoff;
-} BASS_DX8_DISTORTION;
-
-typedef struct {
-	float   fWetDryMix;
-	float   fFeedback;
-	float   fLeftDelay;
-	float   fRightDelay;
-	BOOL    lPanDelay;
-} BASS_DX8_ECHO;
-
-typedef struct {
-	float       fWetDryMix;
-	float       fDepth;
-	float       fFeedback;
-	float       fFrequency;
-	DWORD       lWaveform;	// 0=triangle, 1=sine
-	float       fDelay;
-	DWORD       lPhase;		// BASS_DX8_PHASE_xxx
-} BASS_DX8_FLANGER;
-
-typedef struct {
-	DWORD       dwRateHz;               // Rate of modulation in hz
-	DWORD       dwWaveShape;            // 0=triangle, 1=square
-} BASS_DX8_GARGLE;
-
-typedef struct {
-	int     lRoom;                  // [-10000, 0]      default: -1000 mB
-	int     lRoomHF;                // [-10000, 0]      default: 0 mB
-	float   flRoomRolloffFactor;    // [0.0, 10.0]      default: 0.0
-	float   flDecayTime;            // [0.1, 20.0]      default: 1.49s
-	float   flDecayHFRatio;         // [0.1, 2.0]       default: 0.83
-	int     lReflections;           // [-10000, 1000]   default: -2602 mB
-	float   flReflectionsDelay;     // [0.0, 0.3]       default: 0.007 s
-	int     lReverb;                // [-10000, 2000]   default: 200 mB
-	float   flReverbDelay;          // [0.0, 0.1]       default: 0.011 s
-	float   flDiffusion;            // [0.0, 100.0]     default: 100.0 %
-	float   flDensity;              // [0.0, 100.0]     default: 100.0 %
-	float   flHFReference;          // [20.0, 20000.0]  default: 5000.0 Hz
-} BASS_DX8_I3DL2REVERB;
-
-typedef struct {
-	float   fCenter;
-	float   fBandwidth;
-	float   fGain;
-} BASS_DX8_PARAMEQ;
-
-typedef struct {
-	float   fInGain;                // [-96.0,0.0]            default: 0.0 dB
-	float   fReverbMix;             // [-96.0,0.0]            default: 0.0 db
-	float   fReverbTime;            // [0.001,3000.0]         default: 1000.0 ms
-	float   fHighFreqRTRatio;       // [0.001,0.999]          default: 0.001
-} BASS_DX8_REVERB;
-
-#define BASS_DX8_PHASE_NEG_180        0
-#define BASS_DX8_PHASE_NEG_90         1
-#define BASS_DX8_PHASE_ZERO           2
-#define BASS_DX8_PHASE_90             3
-#define BASS_DX8_PHASE_180            4
-
-typedef struct {
-	float fTarget;
-	float fCurrent;
-	float fTime;
-	DWORD lCurve;
-} BASS_FX_VOLUME_PARAM;
-
-typedef void (CALLBACK IOSNOTIFYPROC)(DWORD status);
-/* iOS notification callback function.
-status : The notification (BASS_IOSNOTIFY_xxx) */
-
-#define BASS_IOSNOTIFY_INTERRUPT		1	// interruption started
-#define BASS_IOSNOTIFY_INTERRUPT_END	2	// interruption ended
-
-BOOL BASSDEF(BASS_SetConfig)(DWORD option, DWORD value);
-DWORD BASSDEF(BASS_GetConfig)(DWORD option);
-BOOL BASSDEF(BASS_SetConfigPtr)(DWORD option, const void *value);
-const void *BASSDEF(BASS_GetConfigPtr)(DWORD option);
-DWORD BASSDEF(BASS_GetVersion)(void);
-int BASSDEF(BASS_ErrorGetCode)(void);
-
-BOOL BASSDEF(BASS_GetDeviceInfo)(DWORD device, BASS_DEVICEINFO *info);
-#if defined(_WIN32) && !defined(_WIN32_WCE) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)
-BOOL BASSDEF(BASS_Init)(int device, DWORD freq, DWORD flags, HWND win, const void *dsguid);
-#else
-BOOL BASSDEF(BASS_Init)(int device, DWORD freq, DWORD flags, void *win, const void *dsguid);
-#endif
-BOOL BASSDEF(BASS_Free)(void);
-BOOL BASSDEF(BASS_SetDevice)(DWORD device);
-DWORD BASSDEF(BASS_GetDevice)(void);
-BOOL BASSDEF(BASS_GetInfo)(BASS_INFO *info);
-BOOL BASSDEF(BASS_Start)(void);
-BOOL BASSDEF(BASS_Stop)(void);
-BOOL BASSDEF(BASS_Pause)(void);
-DWORD BASSDEF(BASS_IsStarted)(void);
-BOOL BASSDEF(BASS_Update)(DWORD length);
-float BASSDEF(BASS_GetCPU)(void);
-BOOL BASSDEF(BASS_SetVolume)(float volume);
-float BASSDEF(BASS_GetVolume)(void);
-#if defined(_WIN32) && !defined(_WIN32_WCE) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)
-void *BASSDEF(BASS_GetDSoundObject)(DWORD object);
-#endif
-
-BOOL BASSDEF(BASS_Set3DFactors)(float distf, float rollf, float doppf);
-BOOL BASSDEF(BASS_Get3DFactors)(float *distf, float *rollf, float *doppf);
-BOOL BASSDEF(BASS_Set3DPosition)(const BASS_3DVECTOR *pos, const BASS_3DVECTOR *vel, const BASS_3DVECTOR *front, const BASS_3DVECTOR *top);
-BOOL BASSDEF(BASS_Get3DPosition)(BASS_3DVECTOR *pos, BASS_3DVECTOR *vel, BASS_3DVECTOR *front, BASS_3DVECTOR *top);
-void BASSDEF(BASS_Apply3D)(void);
-
-HPLUGIN BASSDEF(BASS_PluginLoad)(const char *file, DWORD flags);
-BOOL BASSDEF(BASS_PluginFree)(HPLUGIN handle);
-BOOL BASSDEF(BASS_PluginEnable)(HPLUGIN handle, BOOL enable);
-const BASS_PLUGININFO *BASSDEF(BASS_PluginGetInfo)(HPLUGIN handle);
-
-HSAMPLE BASSDEF(BASS_SampleLoad)(BOOL mem, const void *file, QWORD offset, DWORD length, DWORD max, DWORD flags);
-HSAMPLE BASSDEF(BASS_SampleCreate)(DWORD length, DWORD freq, DWORD chans, DWORD max, DWORD flags);
-BOOL BASSDEF(BASS_SampleFree)(HSAMPLE handle);
-BOOL BASSDEF(BASS_SampleSetData)(HSAMPLE handle, const void *buffer);
-BOOL BASSDEF(BASS_SampleGetData)(HSAMPLE handle, void *buffer);
-BOOL BASSDEF(BASS_SampleGetInfo)(HSAMPLE handle, BASS_SAMPLE *info);
-BOOL BASSDEF(BASS_SampleSetInfo)(HSAMPLE handle, const BASS_SAMPLE *info);
-DWORD BASSDEF(BASS_SampleGetChannel)(HSAMPLE handle, DWORD flags);
-DWORD BASSDEF(BASS_SampleGetChannels)(HSAMPLE handle, HCHANNEL *channels);
-BOOL BASSDEF(BASS_SampleStop)(HSAMPLE handle);
-
-HSTREAM BASSDEF(BASS_StreamCreate)(DWORD freq, DWORD chans, DWORD flags, STREAMPROC *proc, void *user);
-HSTREAM BASSDEF(BASS_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags);
-HSTREAM BASSDEF(BASS_StreamCreateURL)(const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user);
-HSTREAM BASSDEF(BASS_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *proc, void *user);
-BOOL BASSDEF(BASS_StreamFree)(HSTREAM handle);
-QWORD BASSDEF(BASS_StreamGetFilePosition)(HSTREAM handle, DWORD mode);
-DWORD BASSDEF(BASS_StreamPutData)(HSTREAM handle, const void *buffer, DWORD length);
-DWORD BASSDEF(BASS_StreamPutFileData)(HSTREAM handle, const void *buffer, DWORD length);
-
-HMUSIC BASSDEF(BASS_MusicLoad)(BOOL mem, const void *file, QWORD offset, DWORD length, DWORD flags, DWORD freq);
-BOOL BASSDEF(BASS_MusicFree)(HMUSIC handle);
-
-BOOL BASSDEF(BASS_RecordGetDeviceInfo)(DWORD device, BASS_DEVICEINFO *info);
-BOOL BASSDEF(BASS_RecordInit)(int device);
-BOOL BASSDEF(BASS_RecordFree)(void);
-BOOL BASSDEF(BASS_RecordSetDevice)(DWORD device);
-DWORD BASSDEF(BASS_RecordGetDevice)(void);
-BOOL BASSDEF(BASS_RecordGetInfo)(BASS_RECORDINFO *info);
-const char *BASSDEF(BASS_RecordGetInputName)(int input);
-BOOL BASSDEF(BASS_RecordSetInput)(int input, DWORD flags, float volume);
-DWORD BASSDEF(BASS_RecordGetInput)(int input, float *volume);
-HRECORD BASSDEF(BASS_RecordStart)(DWORD freq, DWORD chans, DWORD flags, RECORDPROC *proc, void *user);
-
-double BASSDEF(BASS_ChannelBytes2Seconds)(DWORD handle, QWORD pos);
-QWORD BASSDEF(BASS_ChannelSeconds2Bytes)(DWORD handle, double pos);
-DWORD BASSDEF(BASS_ChannelGetDevice)(DWORD handle);
-BOOL BASSDEF(BASS_ChannelSetDevice)(DWORD handle, DWORD device);
-DWORD BASSDEF(BASS_ChannelIsActive)(DWORD handle);
-BOOL BASSDEF(BASS_ChannelGetInfo)(DWORD handle, BASS_CHANNELINFO *info);
-const char *BASSDEF(BASS_ChannelGetTags)(DWORD handle, DWORD tags);
-DWORD BASSDEF(BASS_ChannelFlags)(DWORD handle, DWORD flags, DWORD mask);
-BOOL BASSDEF(BASS_ChannelLock)(DWORD handle, BOOL lock);
-BOOL BASSDEF(BASS_ChannelFree)(DWORD handle);
-BOOL BASSDEF(BASS_ChannelPlay)(DWORD handle, BOOL restart);
-BOOL BASSDEF(BASS_ChannelStop)(DWORD handle);
-BOOL BASSDEF(BASS_ChannelPause)(DWORD handle);
-BOOL BASSDEF(BASS_ChannelUpdate)(DWORD handle, DWORD length);
-BOOL BASSDEF(BASS_ChannelSetAttribute)(DWORD handle, DWORD attrib, float value);
-BOOL BASSDEF(BASS_ChannelGetAttribute)(DWORD handle, DWORD attrib, float *value);
-BOOL BASSDEF(BASS_ChannelSlideAttribute)(DWORD handle, DWORD attrib, float value, DWORD time);
-BOOL BASSDEF(BASS_ChannelIsSliding)(DWORD handle, DWORD attrib);
-BOOL BASSDEF(BASS_ChannelSetAttributeEx)(DWORD handle, DWORD attrib, void *value, DWORD size);
-DWORD BASSDEF(BASS_ChannelGetAttributeEx)(DWORD handle, DWORD attrib, void *value, DWORD size);
-BOOL BASSDEF(BASS_ChannelSet3DAttributes)(DWORD handle, int mode, float min, float max, int iangle, int oangle, float outvol);
-BOOL BASSDEF(BASS_ChannelGet3DAttributes)(DWORD handle, DWORD *mode, float *min, float *max, DWORD *iangle, DWORD *oangle, float *outvol);
-BOOL BASSDEF(BASS_ChannelSet3DPosition)(DWORD handle, const BASS_3DVECTOR *pos, const BASS_3DVECTOR *orient, const BASS_3DVECTOR *vel);
-BOOL BASSDEF(BASS_ChannelGet3DPosition)(DWORD handle, BASS_3DVECTOR *pos, BASS_3DVECTOR *orient, BASS_3DVECTOR *vel);
-QWORD BASSDEF(BASS_ChannelGetLength)(DWORD handle, DWORD mode);
-BOOL BASSDEF(BASS_ChannelSetPosition)(DWORD handle, QWORD pos, DWORD mode);
-QWORD BASSDEF(BASS_ChannelGetPosition)(DWORD handle, DWORD mode);
-DWORD BASSDEF(BASS_ChannelGetLevel)(DWORD handle);
-BOOL BASSDEF(BASS_ChannelGetLevelEx)(DWORD handle, float *levels, float length, DWORD flags);
-DWORD BASSDEF(BASS_ChannelGetData)(DWORD handle, void *buffer, DWORD length);
-HSYNC BASSDEF(BASS_ChannelSetSync)(DWORD handle, DWORD type, QWORD param, SYNCPROC *proc, void *user);
-BOOL BASSDEF(BASS_ChannelRemoveSync)(DWORD handle, HSYNC sync);
-BOOL BASSDEF(BASS_ChannelSetLink)(DWORD handle, DWORD chan);
-BOOL BASSDEF(BASS_ChannelRemoveLink)(DWORD handle, DWORD chan);
-HDSP BASSDEF(BASS_ChannelSetDSP)(DWORD handle, DSPPROC *proc, void *user, int priority);
-BOOL BASSDEF(BASS_ChannelRemoveDSP)(DWORD handle, HDSP dsp);
-HFX BASSDEF(BASS_ChannelSetFX)(DWORD handle, DWORD type, int priority);
-BOOL BASSDEF(BASS_ChannelRemoveFX)(DWORD handle, HFX fx);
-
-BOOL BASSDEF(BASS_FXSetParameters)(HFX handle, const void *params);
-BOOL BASSDEF(BASS_FXGetParameters)(HFX handle, void *params);
-BOOL BASSDEF(BASS_FXSetPriority)(HFX handle, int priority);
-BOOL BASSDEF(BASS_FXReset)(DWORD handle);
-
-#ifdef __cplusplus
-}
-
-#if defined(_WIN32) && !defined(NOBASSOVERLOADS)
-static inline HPLUGIN BASS_PluginLoad(const WCHAR *file, DWORD flags)
-{
-	return BASS_PluginLoad((const char*)file, flags | BASS_UNICODE);
-}
-
-static inline HMUSIC BASS_MusicLoad(BOOL mem, const WCHAR *file, QWORD offset, DWORD length, DWORD flags, DWORD freq)
-{
-	return BASS_MusicLoad(mem, (const void*)file, offset, length, flags | BASS_UNICODE, freq);
-}
-
-static inline HSAMPLE BASS_SampleLoad(BOOL mem, const WCHAR *file, QWORD offset, DWORD length, DWORD max, DWORD flags)
-{
-	return BASS_SampleLoad(mem, (const void*)file, offset, length, max, flags | BASS_UNICODE);
-}
-
-static inline HSTREAM BASS_StreamCreateFile(BOOL mem, const WCHAR *file, QWORD offset, QWORD length, DWORD flags)
-{
-	return BASS_StreamCreateFile(mem, (const void*)file, offset, length, flags | BASS_UNICODE);
-}
-
-static inline HSTREAM BASS_StreamCreateURL(const WCHAR *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user)
-{
-	return BASS_StreamCreateURL((const char*)url, offset, flags | BASS_UNICODE, proc, user);
-}
-
-static inline BOOL BASS_SetConfigPtr(DWORD option, const WCHAR *value)
-{
-	return BASS_SetConfigPtr(option | BASS_UNICODE, (const void*)value);
-}
-#endif
-#endif
-
-#ifdef __OBJC__
-#undef BOOL
-#endif
-
-#endif

+ 0 - 2272
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bass.txt

@@ -1,2272 +0,0 @@
-BASS 2.4
-Copyright (c) 1999-2021 Un4seen Developments Ltd. All rights reserved.
-
-Files that you should have found in the BASS package
-====================================================
-Win32 version
--------------
-BASS.TXT        This file
-BASS.DLL        BASS module
-BASS.CHM        BASS documentation
-X64\
-  BASS.DLL        64-bit BASS module
-C\              C/C++ API and examples...
-  BASS.H          BASS C/C++ header file
-  BASS.LIB        BASS import library
-  BASS.SLN        Visual Studio solution for examples
-  MAKEFILE        Makefile for examples
-  MAKEFILE.IN     Makefile helper macros
-  X64\
-    BASS.LIB        64-bit BASS import library
-  3DTEST\         3D example
-    ...
-  BASSTEST\       Simple playback example
-    ...
-  CONTEST\        Console example
-    ...
-  CUSTLOOP\       Custom looping example
-    ...
-  DEVLIST\        Device list example
-    ...
-  DSPTEST\        DSP example
-    ...
-  FXTEST\         Effects example
-    ...
-  LIVEFX\         Full-duplex example
-    ...
-  LIVESPEC\       Live version of spectrum analyser example
-    ...
-  MODTEST\        MOD music example
-    ...
-  MULTI\          Multiple device example
-    ...
-  NETRADIO\       Internet streaming example
-    ...
-  PLUGINS\        Plugins example
-    ...
-  RECTEST\        Recording example
-    ...
-  SPEAKERS\       Multi-speaker example
-    ...
-  SPECTRUM\       Spectrum analyser example
-    ...
-  SYNTH\          Low latency custom streaming example
-    ...
-  WRITEWAV\       WAVE writer example
-    ...
-  BIN\            Precompiled examples
-    3DTEST.EXE
-    BASSTEST.EXE
-    CONTEST.EXE
-    CUSTLOOP.EXE
-    DEVLIST.EXE
-    DSPTEST.EXE
-    FXTEST.EXE
-    LIVEFX.EXE
-    LIVESPEC.EXE
-    MODTEST.EXE
-    MULTI.EXE
-    NETRADIO.EXE
-    RECTEST.EXE
-    SPEAKERS.EXE
-    SPECTRUM.EXE
-    SYNTH.EXE
-    WRITEWAV.EXE
-DELPHI\         Delphi API and examples...
-  BASS.PAS        BASS Delphi unit
-  3DTEST\         3D example
-    ...
-  BASSTEST\       Simple playback example
-    ...
-  CONTEST\        Console example
-    ...
-  CUSTLOOP\       Custom looping example
-    ...
-  DSPTEST\        DSP example
-    ...
-  FXTEST\         Effects example
-    ...
-  LIVEFX\         Full-duplex example
-    ...
-  LIVESPEC\       Live version of spectrum analyser example
-    ...
-  MULTI\          Multiple device example
-    ...
-  NETRADIO\       Internet streaming example
-    ...
-  PLUGINS\        Plugins example
-    ...
-  RECTEST\        Recording example
-    ...
-  SAMPLEVIS\      Visualisation example
-    ...
-  SPEAKERS\       Multi-speaker example
-    ...
-  SPECTRUM\       Spectrum analyser example
-    ...
-  STREAMTEST\     User stream example
-    ...
-  WRITEWAV\       WAVE writer example
-    ...
-VB\             Visual Basic API and examples...
-  BASS.BAS        BASS Visual Basic module
-  3DTEST\         3D example
-    ...
-  BASSTEST\       Simple playback example
-    ...
-  CUSTLOOP\       Custom looping example
-    ...
-  DSPTEST\        DSP example
-    ...
-  FXTEST\         Effects example
-    ...
-  LIVEFX\         Full-duplex example
-    ...
-  LIVESPEC\       Live version of spectrum analyser example
-    ...
-  MULTI\          Multiple device example
-    ...
-  NETRADIO\       Internet streaming example
-    ...
-  PLUGINS\        Plugins example
-    ...
-  RECTEST\        Recording example
-    ...
-  SPEAKERS\       Multi-speaker example
-    ...
-  SPECTRUM\       Spectrum analyser example
-    ...
-  SYNTH\          Low latency custom streaming example
-    ...
-  WRITEWAV\       WAVE writer example
-    ...
-  MEMORY\         Playing from memory example by Jobnik
-    ...
-
-NOTE: You may need to "Unblock" the BASS.CHM file in its "Properties" to view
-      it on Windows 7. The documentation can also be viewed online at the BASS
-      website.
-
-NOTE: The Delphi and VB examples may not always be up to date with the C
-      examples, so the latter should be preferred as references if possible.
-
-NOTE: To run the example EXEs, first you will need to copy BASS.DLL into the
-      same directory as them.
-
-macOS version
--------------
-BASS.TXT        This file
-LIBBASS.DYLIB   BASS module
-BASS.CHM        BASS documentation
-CHMOX.APP       CHM file viewer
-BASS.H          BASS C/C++ header file
-BASS.XCODEPROJ  Xcode project for examples
-MAKEFILE        Makefile for specific architectures
-CONTEST\        Console example
-  ...
-DEVLIST\        Device list example
-  ...
-DSPTEST\        DSP example
-  ...
-FXTEST\         Effects example
-  ...
-LIVESPEC\       Live version of spectrum analyser example
-  ...
-MULTI\          Multiple device example
-  ...
-NETRADIO\       Internet streaming example
-  ...
-PLUGINS\        Plugins example
-  ...
-RECTEST\        Recording example
-  ...
-SPEAKERS\       Multi-speaker example
-  ...
-SPECTRUM\       Spectrum analyser example
-  ...
-SYNTH\          Low latency custom streaming example
-  ...
-WRITEWAV\       WAVE writer example
-  ...
-
-NOTE: To view the documentation, you will need a CHM viewer, such as the
-      included CHMOX. The documentation can also be viewed online at the BASS
-      website.
-
-Linux version
--------------
-BASS.TXT        This file
-LIBBASS.SO      BASS module
-BASS.CHM        BASS documentation
-BASS.H          BASS C/C++ header file
-MAKEFILE        Makefile for examples
-MAKEFILE.IN     Makefile helper macros
-X64\
-  LIBBASS.SO      64-bit BASS module
-PASCAL\
-  BASS.PAS        BASS Delphi/Pascal unit
-3DTEST\         3D example
-  ...
-BASSTEST\       Simple playback example
-  ...
-CONTEST\        Console example
-  ...
-CUSTLOOP\       Custom looping example
-  ...
-DEVLIST\        Device list example
-  ...
-DSPTEST\        DSP example
-  ...
-FXTEST\         Effects example
-  ...
-LIVESPEC\       Live version of spectrum analyser example
-  ...
-MODTEST\        MOD music example
-  ...
-MULTI\          Multiple device example
-  ...
-NETRADIO\       Internet streaming example
-  ...
-PLUGINS\        Plugins example
-  ...
-RECTEST\        Recording example
-  ...
-SPEAKERS\       Multi-speaker example
-  ...
-SPECTRUM\       Spectrum analyser example
-  ...
-SYNTH\          Low latency custom streaming example
-  ...
-WRITEWAV\       WAVE writer example
-  ...
-
-NOTE: To view the documentation, you will need a CHM viewer. The documentation
-      can also be viewed online at the BASS website.
-
-Android version
----------------
-BASS.TXT        This file
-BASS.CHM        BASS documentation
-LIBS\           BASS modules
-  ...
-C\              C/C++ API...
-  BASS.H          BASS C/C++ header file
-JAVA\COM\UN4SEEN\BASS\
-  BASS.JAVA       BASS Java class
-EXAMPLES\       Java examples
-  BUILD.GRADLE    Android Studio build script for examples
-  SETTINGS.GRADLE
-  PROGUARD-BASS.PRO
-  DSPTEST\        DSP example
-    ...
-  FXTEST\         Effects example
-    ...
-  LIVESPEC\       Live version of spectrum analyser example
-    ...
-  NETRADIO\       Internet streaming example
-    ...
-  PLUGINS\        Plugins example
-    ...
-  RECTEST\        Recording example
-    ...
-  SPECTRUM\       Spectrum analyser example
-    ...
-
-NOTE: To view the documentation, you will need a CHM viewer. The documentation
-      can also be viewed online at the BASS website.
-
-iOS version
------------
-BASS.TXT        This file
-BASS.CHM        BASS documentation
-BASS.H          BASS C/C++ header file
-BASS.XCFRAMEWORK  BASS framework
-
-NOTE: To view the documentation, you will need a CHM viewer. The documentation
-      can also be viewed online at the BASS website.
-
-
-What's the point?
-=================
-BASS is an audio library for use in software on several platforms. Its purpose
-is to provide developers with powerful and efficient sample, stream, MOD music,
-and recording functions. All in a compact DLL that won't bloat your software.
-
-See the documentation for descriptions of all the BASS functions. Also check
-the included example source-codes for some examples of how to use BASS in your
-own programs.
-
-
-Requirements
-============
-Win32 version
--------------
-BASS requires WASAPI or DirectSound for playback and recording, but decoding
-and silent playback on the "No sound" device is still possible without them.
-DirectSound has been included with all Windows versions since Windows 98. On
-Windows Vista and above, the default is to use WASAPI instead of DirectSound.
-32-bit and 64-bit Windows are supported.
-
-macOS version
--------------
-macOS 10.5 or above is required. BASS uses CoreAudio for playback and recording,
-so there are no special library/driver requirements. x86_64 / arm64 / i386
-architectures are supported in a single universal library.
-
-Linux version
--------------
-BASS requires ALSA for playback and recording, but decoding and silent playback
-on the "No sound" device is still possible without it. 32-bit (i386) and 64-bit
-(x86-64) architectures are supported. ARM support is also available as a
-separate download from the website.
-
-Android version
----------------
-Android 2.3 or above is required. BASS can use AAudio, OpenSL ES, or AudioTrack
-for playback (OpenSL ES is used for recording). AAudio is the default on Android
-8.1 and above, and OpenSL ES is on older Android versions. The armeabi-v7a /
-arm64-v8a / x86 / x86_64 architectures are supported.
-
-iOS version
------------
-iOS 6 or above is required. BASS uses CoreAudio for playback and recording,
-so there are no special library/driver requirements. armv7 / armv7s / arm64
-"device" builds and i386 / x86_64 / arm64 "simulator" builds are supported
-in a single universal framework.
-
-
-Main Features
-=============
-* Samples
-  supports WAV/AIFF/MP3/MP2/MP1/OGG and custom generated samples
-
-* Sample streams
-  stream any sample data in 8/16/32 bit, with both "push" and "pull" systems
-
-* File streams
-  MP3/MP2/MP1/OGG/WAV/AIFF file streaming
-
-* Internet file streaming
-  stream files from the internet, including Shout/Icecast
-
-* User file streaming
-  stream files from anywhere using any delivery method
-
-* OS codecs
-  ACM, Media Foundation and CoreAudio codec support for additional audio formats
-
-* Multi-channel streaming
-  support for more than plain stereo, including multi-channel OGG/WAV/AIFF files
-
-* MOD music
-  uses the same engine as XMPlay = best accuracy, speed, and quality
-
-* MO3 music
-  MP3/OGG compressed MOD music
-
-* Add-on system
-  support for more formats is available via add-ons (aka plugins)
-
-* Multiple outputs
-  simultaneously use multiple soundcards, and move channels between them
-
-* Recording
-  flexible recording system, with support for multiple devices
-
-* Decode without playback
-  streams and MOD musics can be outputted in any way you want
-
-* Speaker assignment
-  assign streams and MOD musics to specific speakers
-
-* High precision synchronization
-  synchronize events in your software to the streams and MOD musics
-
-* Effects
-  chorus/compressor/distortion/echo/flanger/gargle/parameq/reverb
-
-* User-defined DSP functions
-  custom effects may be applied to individual streams or the final output mix
-
-* 32 bit floating-point decoding and processing
-  floating-point stream/music decoding, DSP/FX, and recording
-
-* 3D sound
-  play samples/streams/musics in any 3D position
-
-
-Using BASS
-==========
-There is no guarantee that all future BASS versions will be compatible
-with all previous versions, so your program should use BASS_GetVersion
-to check the version that is loaded. This also means that you should
-put the BASS module in the same directory as your executable (not just
-somewhere in the path), to avoid the possibility of a wrong version being
-loaded.
-
-If you are updating your software from a previous BASS version, then
-you should check the "History" section (below), to see if any of the
-functions that you are using have been affected by a change.
-
-Win32 version
--------------
-C/C++, Delphi, and Visual Basic APIs and example projects are provided. To
-use BASS with another language you will first have to convert the header
-file. Or, as a last resort, you could use LoadLibrary and GetProcAddress.
-
-The downside is that you have to manually import each function that you
-use, with the GetProcAddress function. But it has been made a lot simpler
-to import BASS this way by the use of the BASSDEF #define. Here's a small
-example:
-
-#define BASSDEF(f) (WINAPI *f) // define the functions as pointers
-#include "bass.h"
-...
-HINSTANCE bass=LoadLibrary("BASS.DLL"); // load BASS
-BASS_Init=GetProcAddress(bass,"BASS_Init"); // get BASS_Init
-BASS_Init(-1,44100,0,hWnd,NULL); // call BASS_Init
-
-To use BASS with Borland C++ Builder, you will first have to create a
-Borland C++ Builder import library for it. This is done by using the
-IMPLIB tool that comes with Borland C++ Builder. Simply execute this:
-
-	IMPLIB BASSBCB.LIB BASS.DLL
-
-... and then use BASSBCB.LIB in your projects to import BASS.
-
-To use BASS with LCC-Win32, you will first have to create a compatible
-import library for it. This is done by using the PEDUMP and BUILDLIB
-tools that come with LCC-Win32. Run these 2 commands:
-
-	PEDUMP /EXP BASS.LIB > BASSLCC.EXP
-	BUILDLIB BASSLCC.EXP BASSLCC.LIB
-
-... and then use BASSLCC.LIB in your projects to import BASS.
-
-For the BASS functions that return strings (char*), VB users should use
-the VBStrFromAnsiPtr function to convert the returned pointer into a VB
-string.
-
-macOS version
--------------
-See the example Xcode project.
-
-NOTE: The LIBBASS.DYLIB file must be put in the same directory as the
-      executable, it can't just be somewhere in the path.
-
-LIBBASS.DYLIB is a universal binary with support for the x86_64 / arm64 / i386
-architectures. If not all of those architectures are needed, the included
-makefile can be used to extract the wanted one(s). Type "make x86_64" or
-"make arm64" or "make i386" to extract a particular architecture. "make 64bit"
-can be used to extract the x86_64 and arm64 architectures (exclude i386), and
-"make intel" to extract the x86_64 and i386 architectures (exclude arm64). Any
-BASS add-ons placed in the same directory will also be processed.
-
-Linux version
--------------
-The LIBBASS.SO file needs to be in the OS's library search path for it to
-be found; simply placing it in the same directory as the executable won't
-necessarily work as it does on other platforms. The BASS libraries should
-also not be placed in the standard library directories to avoid version
-conflicts. To meet those competing requirements, a wrapper script could be
-used to set the "LD_LIBRARY_PATH" environment variable before loading the
-executable. Another option is to set the "rpath" in the executable, to tell
-it where to look for libraries. That is what the example makefiles do.
-
-When building both 32-bit and 64-bit executables, it is possible to simply
-try linking with both LIBBASS.SO versions, and the linker will use the
-appropriate version and ignore the other.
-
-Android version
----------------
-The BASS library includes support for use in Java and native code. The
-BASS.JAVA file mirrors BASS.H as much as possible, but there are some
-unavoidable differences, mainly in parameter/return types.
-
-When using ProGuard to obfuscate your Java code, the BASS classes should be
-left alone (see PROGUARD-BASS.PRO).
-
-See the example Android Studio project.
-
-iOS version
------------
-The BASS XCFramework should be added to the "Link Binary With Libraries" build
-phase in Xcode. If you're using an old Xcode version without XCFramework
-support then you can link directly with the library inside the XCFramework
-instead. Also add the following frameworks: Accelerate, AudioToolbox,
-AVFoundation, CFNetwork, SystemConfiguration. BASS does not include bitcode, so
-the "Enable Bitcode" option should be set to "No".
-
-
-Latest Version
-==============
-The latest version of BASS can always be found at the BASS website:
-
-	www.un4seen.com
-
-
-Licence
-=======
-BASS is free for non-commercial use. If you are a non-commercial entity
-(eg. an individual) and you are not making any money from your product
-(through sales/advertising/etc), then you can use BASS in it for free.
-If you wish to use BASS in commercial products, then please also see the
-next section.
-
-TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, BASS IS PROVIDED
-"AS IS", WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
-INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY
-AND/OR FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS SHALL NOT BE HELD
-LIABLE FOR ANY DAMAGE THAT MAY RESULT FROM THE USE OF BASS. YOU USE
-BASS ENTIRELY AT YOUR OWN RISK.
-
-Usage of BASS indicates that you agree to the above conditions.
-
-All trademarks and other registered names contained in the BASS
-package are the property of their respective owners.
-
-Commercial licensing
---------------------
-BASS is available for use in your commercial products. The licence
-types available are as follows:
-
-SHAREWARE: Allows the usage of BASS in an unlimited number of your
-shareware ("try before you buy") products, which must sell for no more
-than 40 Euros each. Non-shareware products are also permitted, but the
-product price limit is 10 Euros in that case. The price limit can be
-raised by purchasing duplicate licences, eg. 2 licences doubles it. If
-you are an individual (not a corporation) making and selling your own
-software, this is the licence for you. 
-
-SINGLE COMMERCIAL: Allows the usage of BASS in one commercial product.
-
-UNLIMITED COMMERCIAL: Allows the usage of BASS in an unlimited number
-of your commercial products. This licence is on a per-site basis, eg.
-if you are creating products with BASS at 2 sites/locations, then 2
-licences are required.
-
-Please note the products must be end-user products, eg. not components
-used by other products. 
-
-These licences only cover your own software, not the publishing of
-other's software. If you publish other's software, its developers (or
-the software itself) will need to be licensed to use BASS.
-
-These licences are on a per-platform basis, with reductions available
-when licensing for multiple platforms. In all cases there are no royalties
-to pay, and you can use future BASS updates without further cost.
-
-These licences do not allow reselling/sublicensing of BASS. For example,
-if a product is a development system, the users of said product are not
-licensed to use BASS in their productions; they will need their own
-licences.
-
-If the standard licences do not meet your requirements, or if you have
-any questions, please get in touch (email: bass@un4seen.com).
-
-Visit the BASS website for the latest pricing:
-
-	www.un4seen.com
-
-
-Credits
-=======
-Ogg Vorbis decoding is based on libogg/vorbis,
-Copyright (c) 2002-2020 Xiph.org Foundation
-
-CHMOX is (c) 2004 Stéphane Boisson, http://chmox.sourceforge.net/
-
-API/Sample contributors
------------------------
-Delphi: Titus Miloi, Rogier Timmermans, Alessandro Cappellozza,
-        Jesse Naranjo, Chris Troesken, Evgeny Melnikov
-Visual Basic: Adam Hoult, Hendrik Knaepen, Arthur Aminov,
-              Peter Hebels
-
-
-History
-=======
-These are the major (and not so major) changes at each version stage.
-There are of course bug fixes and other little improvements made along
-the way too! To make upgrading simpler, all functions affected by a
-change to the BASS interface are listed.
-
-2.4.16 - 24/6/2021
-------------------
-* DirectSound output mix is now generated by BASS (as with WASAPI output and
-  on other platforms), losing support for DirectSound-specific features but
-  gaining support for all BASS features
-	BASS_DEVICE_DSOUND (BASS_Init flag)
-* Length trimming
-	BASS_POS_END (BASS_ChannelSetPosition mode)
-	BASS_SYNC_END (BASS_ChannelSetSync type)
-	CUSTLOOP example updated
-* Custom loop start positions
-	BASS_POS_LOOP (BASS_ChannelSetPosition mode)
-	CUSTLOOP example updated
-* Length extending
-	BASS_ATTRIB_TAIL
-	BASS_SYNC_END (BASS_ChannelSetSync type)
-* Device reinitialization while retaining BASS channels and 3D settings
-	BASS_DEVICE_REINIT (BASS_Init flag)
-* Retrieval of a device's activity status
-	BASS_IsStarted
-* BASS_DEVICE_3D flag is no longer needed to enable 3D support
-	BASS_Init
-* The "Default" device is now enabled by default on Windows and macOS
-	BASS_CONFIG_DEV_DEFAULT (BASS_SetConfig option)
-* Default communications device indicator on Windows
-	BASS_DEVICE_DEFAULTCOM (BASS_DEVICEINFO flag)
-* Sample channel "newonly" option changed to a flag
-	BASS_SAMCHAN_NEW (BASS_SampleGetChannel flag)
-* Sample playback streams
-	BASS_SAMCHAN_STREAM (BASS_SampleGetChannel flag)
-	BASS_CTYPE_STREAM_SAMPLE
-* Speaker assignment support for samples
-	BASS_SampleGetChannel
-	BASS_ChannelFlags
-* Overriding of default flags during sample channel creation
-	BASS_SampleGetChannel
-* Same sample channel handle when max=1 is now optional
-	BASS_CONFIG_SAMPLE_ONEHANDLE (BASS_SetConfig option)
-* 3D max distance muting can now be toggled
-	BASS_SAMPLE_MUTEMAX (BASS_ChannelFlags flag)
-* Plugin disabling without affecting existing streams
-	BASS_PluginEnable
-* WASAPI recording on Windows (DirectSound is fallback/optional)
-	BASS_CONFIG_REC_WASAPI (BASS_SetConfig option)
-	BASS_RecordInit
-* Minimum recording buffer reduced to 10ms
-	BASS_CONFIG_REC_BUFFER (BASS_SetConfig option)
-* Recording data/level retrieval without removing from buffer when not using a RECORDPROC
-	BASS_DATA_NOREMOVE (BASS_ChannelGetData flag)
-	BASS_LEVEL_NOREMOVE (BASS_ChannelGetLevelEx flag)
-* Support for level measurements longer than 1s from decoding channels
-	BASS_ChannelGetLevelEx
-* Configurable restricted download rate
-	BASS_CONFIG_NET_RESTRATE (BASS_SetConfig option)
-* Thread-specific internet stream timeout options
-	BASS_CONFIG_THREAD (BASS_SetConfig option)
-	BASS_CONFIG_NET_TIMEOUT (BASS_SetConfig option)
-	BASS_CONFIG_NET_READTIMEOUT (BASS_SetConfig option)
-	BASS_StreamCreateURL
-* Configured "User-Agent" header can be overridden in custom request headers
-	BASS_StreamCreateURL
-* Multiple IPs will be tried when available on Linux/Android (already on other platforms)
-	BASS_StreamCreateURL
-* BASS_STREAM_BLOCK applied automatically on files larger than 2GB
-	BASS_StreamCreateURL/FileUser
-* Redirected URL retrieval
-	BASS_TAG_LOCATION (BASS_ChannelGetTags type)
-* Shoutcast metadata is now optional
-	BASS_CONFIG_NET_META (BASS_SetConfig option)
-	BASS_TAG_META (BASS_ChannelGetTags type)
-* Support for a 2nd ID3v2 tag block
-	BASS_TAG_ID3V2_2 (BASS_ChannelGetTags type)
-* OpenMPT channel name retrieval
-	BASS_TAG_MUSIC_CHAN (BASS_ChannelGetTags type)
-* Delayed OGG file scanning when prescanning is disabled/impossible
-	BASS_ChannelGetLength
-	BASS_ChannelSetPosition
-	BASS_CONFIG_OGG_PRESCAN (BASS_SetConfig option)
-* Faster seeking in large OGG files
-	BASS_ChannelSetPosition
-* Unified freeing function for all channel types
-	BASS_ChannelFree
-* User-defined attribute
-	BASS_ATTRIB_USER (BASS_ChannelSetAttributeEx option)
-* Push stream buffer size limiting
-	BASS_ATTRIB_PUSH_LIMIT (BASS_ChannelSetAttribute option)
-* Retrieval of a stream's available file data amount
-	BASS_FILEPOS_AVAILABLE (BASS_StreamGetFilePosition mode)
-* Error code for unsupported URL protocols
-	BASS_ERROR_PROTOCOL (BASS_StreamCreateURL error code)
-* BASS_ERROR_ALREADY error changed to success in some functions
-	BASS_ChannelPause
-	BASS_ChannelSetDevice
-	BASS_ChannelSetLink
-* Support for custom file streaming with Android Media codecs
-	BASS_StreamCreateFileUser
-* Switch to using native APIs for Android Media codecs (Android 5 or above required now)
-	BASS_StreamCreateFile/User/URL
-* BASS_TAG_AM_MIME value changed to fix conflict on Android
-	BASS_TAG_AM_MIME (BASS_ChannelGetTags type)
-* Improved support for single active input recording devices on Linux
-	BASS_RecordGetInputName
-	BASS_RecordGetInput
-	BASS_RecordSetInput
-* Automatic resumption of recordings after an interruption on iOS
-* Fix for Media Foundation AAC streaming with Windows 10 20H1
-	BASS_StreamCreateURL
-	BASS_StreamCreateFileUser
-* Fix for freeze when freeing a stream after BASS_ChannelSetLink failed with BASS_ERROR_ALREADY on it
-	BASS_ChannelSetLink
-* macOS examples rewritten in Objective-C/Cocoa
-* "MP3-FREE" version removed (MP3 patents expired)
-* armv5 (armeabi) architecture support dropped on Android
-
-2.4.15 - 17/12/2019
--------------------
-* Channel processing granularity option
-	BASS_ATTRIB_GRANULE (BASS_ChannelSetAttribute option)
-* Asynchronous mixtime sync callbacks
-	BASS_SYNC_THREAD (BASS_ChannelSetSync flag)
-* Output device update period can be set in samples
-	BASS_CONFIG_DEV_PERIOD (BASS_SetConfig option)
-* Continuous output when nothing is playing is now optional on macOS/iOS too
-	BASS_CONFIG_DEV_NONSTOP (BASS_SetConfig option)
-* AAudio output support on Android
-	BASS_Init
-	BASS_CONFIG_ANDROID_AAUDIO (BASS_SetConfig option)
-* Support for audio session IDs on Android
-	BASS_CONFIG_ANDROID_SESSIONID (BASS_SetConfig option)
-* ParcelFileDescriptor support on Android
-	BASS_StreamCreateFile
-	BASS_SampleLoad
-	BASS_MusicLoad
-* FloatValue Java class added to receive floating-point values on Android 10
-	BASS_Get3DFactors
-	BASS_RecordGetInput
-	BASS_ChannelGetAttribute
-	BASS_ChannelGet3DAttributes
-* Audio session configuration option on iOS
-	BASS_CONFIG_IOS_SESSION (BASS_SetConfig option)
-* OGG channel type constant renamed/duplicated to VORBIS
-	BASS_CTYPE_STREAM_VORBIS
-* Error code for recognised file formats without audio
-	BASS_ERROR_NOTAUDIO (BASS_StreamCreateFile/User/URL error code)
-* Error code for unstreamable MP4 files due to atom order
-	BASS_ERROR_UNSTREAMABLE (BASS_StreamCreateFileUser/URL error code)
-* Fix for AAC streaming with BASS_STREAM_BLOCK on macOS 10.15 and iOS 13
-	BASS_StreamCreateURL/FileUser
-* Fix for playback rate changing bug when using DirectSound
-	BASS_ATTRIB_FREQ (BASS_ChannelSetAttribute option)
-* armv6 architecture support dropped on iOS
-
-2.4.14 - 16/1/2019
-------------------
-* Support for playback on the "No sound" device
-	BASS_Init
-	BASS_StreamCreateFile/User/URL
-	BASS_SampleLoad/Create
-	BASS_ChannelPlay
-* Improved sample rate conversion quality, including 64 point option
-	BASS_ATTRIB_SRC (BASS_ChannelSetAttribute option)
-	BASS_CONFIG_SRC/_SAMPLE (BASS_SetConfig options)
-* Loopback (output device) recording on Windows Vista and above
-	BASS_RecordInit
-	BASS_RecordGetDeviceInfo
-	BASS_DEVICE_LOOPBACK (BASS_DEVICEINFO flag)
-	DEVLIST and RECTEST examples updated
-* Native format recording option
-	BASS_RecordStart
-* Access to the 3D output mix for applying DSP/FX
-	STREAMPROC_DEVICE_3D (BASS_StreamCreate option)
-* Retrieval of a device's started/stopped status
-	BASS_IsStarted
-* Sync for when a device stops unexpectedly
-	BASS_SYNC_DEV_FAIL (BASS_ChannelSetSync type)
-* New channel playback state for a paused device
-	BASS_ACTIVE_PAUSED_DEVICE (BASS_ChannelIsActive)
-* Sync for when a device's sample format changes
-	BASS_SYNC_DEV_FORMAT (BASS_ChannelSetSync type)
-* Adjustable output device update period
-	BASS_CONFIG_DEV_PERIOD (BASS_SetConfig option)
-* Nyquist FFT option
-	BASS_DATA_FFT_NYQUIST (BASS_ChannelGetData flag)
-* Plugin-specific flags are ignored in standard stream creation functions
-	BASS_StreamCreateFile/User/URL
-* Pre-buffering during stream creation is now disabled by default
-	BASS_CONFIG_NET_PREBUF_WAIT (BASS_SetConfig option)
-	BASS_StreamCreateURL/FileUser
-* Existing internet streams are unaffected by read timeout config changes
-	BASS_CONFIG_NET_READTIMEOUT (BASS_SetConfig option)
-* Retrieval of the number of existing handles
-	BASS_CONFIG_HANDLES (BASS_GetConfig option)
-* Windows mixer settings are retained by default and optionally not
-	BASS_CONFIG_WASAPI_PERSIST (BASS_SetConfig option)
-* Configurable OpenSSL library filename on Linux/Android
-	BASS_CONFIG_LIBSSL (BASS_SetConfigPtr option)
-* Files can be deleted/renamed while streaming on Windows (already true on other platforms)
-	BASS_StreamCreateFile
-* Fix for bug in playback buffering disabling option
-	BASS_ATTRIB_NOBUFFER (BASS_ChannelSetAttribute option)
-* Fix to support long logarithmic curves in volume effects
-	BASS_FX_VOLUME (BASS_ChannelSetFX type)
-
-2.4.13.8 - 6/2/2018
--------------------
-* Indication of a file's original sample format being floating-point
-	BASS_ORIGRES_FLOAT (BASS_CHANNELINFO/SAMPLE flag)
-* Some extra sample data is retained to account for device latency in data retrieval
-	BASS_ChannelGetData
-* FFT window is shortened to match amount of available data when less than FFT size
-	BASS_ChannelGetData
-* FFT level adjusted to be approx the same regardless of amount of available data
-	BASS_ChannelGetData
-* Fix for crash when decoding channels are dissociated from a device
-	BASS_NODEVICE (BASS_ChannelSetDevice option)
-
-2.4.13 - 19/12/2017
--------------------
-* WASAPI output on Windows (DirectSound is fallback/optional)
-	BASS_DEVICE_DSOUND (BASS_Init flag)
-	BASS_CONFIG_DEV_BUFFER/NONSTOP (BASS_SetConfig options)
-	BASS_CONFIG_SRC/_SAMPLE (BASS_SetConfig options)
-	BASS_ATTRIB_SRC/NORAMP (BASS_ChannelSetAttribute options)
-* Default output device following support extended to Windows Vista and macOS
-	BASS_CONFIG_DEV_DEFAULT (BASS_SetConfig option)
-* Seamless playback buffer length changing
-	BASS_ATTRIB_BUFFER (BASS_ChannelSetAttribute option)
-	SYNTH example updated
-* Access to the final output mix for applying DSP/FX
-	STREAMPROC_DEVICE (BASS_StreamCreate option)
-	BASS_CTYPE_STREAM_DEVICE
-	FXTEST example updated
-* Dissociating of decoding channels from a device
-	BASS_NODEVICE (BASS_ChannelSetDevice option)
-* Volume attribute levels above 1.0 for amplification
-	BASS_ATTRIB_VOL (BASS_ChannelSetAttribute option)
-* Logarithmic attribute slides
-	BASS_SLIDE_LOG (BASS_ChannelSlideAttribute flag)
-* Volume & panning attribute affected level retrieval
-	BASS_LEVEL_VOLPAN (BASS_ChannelGetLevelEx flag)
-* Volume level adjustment effect
-	BASS_FX_VOLUME (BASS_ChannelSetFX type)
-	BASS_FX_VOLUME_PARAM structure
-* Asynchronous pre-buffering
-	BASS_CONFIG_NET_PREBUF_WAIT (BASS_SetConfig option)
-	BASS_StreamCreateURL/FileUser
-	CONTEST and NETRADIO examples updated
-* Decoding channels can be dissociated from a device
-	BASS_ChannelSetDevice
-* Resetting of user file streams/decoders
-	BASS_POS_RESET (BASS_ChannelSetPosition flag)
-* Relative seeking
-	BASS_POS_RELATIVE (BASS_ChannelSetPosition flag)
-* RIFF cue points chunk retrieval
-	BASS_TAG_RIFF_CUE (BASS_ChannelGetTags type)
-	TAG_CUE structure
-* RIFF sample chunk retrieval
-	BASS_TAG_RIFF_SMPL (BASS_ChannelGetTags type)
-	TAG_SMPL structure
-* Support for Category/Description/Grouping/Keywords/Lyrics MP4 tags
-	BASS_TAG_MP4 (BASS_ChannelGetTags type)
-* Separate channel type for dummy streams
-	BASS_CTYPE_STREAM_DUMMY
-* Stalled internet stream buffering progress retrieval
-	BASS_FILEPOS_BUFFERING (BASS_StreamGetFilePosition mode)
-	CONTEST and NETRADIO examples updated
-* Playlist recursion depth config option
-	BASS_CONFIG_NET_PLAYLIST_DEPTH (BASS_SetConfig options)
-* Push file system read functions can now return 0 without ending the file
-	STREAMFILE_BUFFERPUSH (BASS_StreamCreateFileUser system)
-	FILEREADPROC
-* 16 point SRC is used by default when SSE is available
-	BASS_CONFIG_SRC (BASS_SetConfig option)
-* Mono downmixing for all file formats in sample loading
-	BASS_SAMPLE_MONO (BASS_SampleLoad flag)
-* Mono OGG stream downmixing
-	BASS_SAMPLE_MONO (BASS_StreamCreateFile/User/URL flag)
-* Media Foundation availability detection
-	BASS_CONFIG_MF_DISABLE (BASS_GetConfig option)
-	PLUGINS example updated
-* AudioTrack output on Android
-	BASS_DEVICE_AUDIOTRACK (BASS_Init flag)
-* Support for Android Media codecs
-	BASS_StreamCreateFile/User/URL
-	BASS_TAG_AM_MIME/NAME (BASS_ChannelGetTags type)
-	BASS_CONFIG_AM_DISABLE (BASS_SetConfig option)
-* Panning fix for MOD files created with ScreamTracker 3
-	BASS_MusicLoad
-* Fix for compressor and distotion DX8 effects with floating-point data on Windows
-	BASS_FX_DX8_COMPRESSOR/DISTORTION (BASS_ChannelSetFX types)
-* Fix for plugin freeing issue on 64-bit platforms (HPLUGIN is not library address any more)
-	BASS_PluginLoad
-	BASS_PluginFree
-
-2.4.12 - 10/3/2016
-------------------
-* DSP/FX chain order modification
-	BASS_FXSetPriority
-* Average bitrate retrieval
-	BASS_ATTRIB_BITRATE
-* Ramping-out when stopping/pausing playback
-	BASS_ChannelStop
-	BASS_ChannelPause
-* Disabling of playback ramping
-	BASS_ATTRIB_NORAMP (BASS_ChannelSetAttribute option)
-* Pre-buffering when playback buffering is disabled
-	BASS_ChannelUpdate
-	BASS_ATTRIB_NOBUFFER (BASS_ChannelSetAttribute option)
-* Net agent and proxy config options now make a copy of the provided string
-	BASS_CONFIG_NET_AGENT/PROXY (BASS_SetConfigPtr options)
-	NETRADIO example updated
-* Unicode net agent and proxy config options on Windows
-	BASS_CONFIG_NET_AGENT/PROXY (BASS_SetConfigPtr options)
-* 32768 sample FFT
-	BASS_DATA_FFT32768 (BASS_ChannelGetData flag)
-* Support for iTunes gapless info in MP3 files
-	BASS_StreamCreateFile/User
-* 529 sample delay removed from start of MP3 files without delay info
-	BASS_StreamCreateFile/User/URL
-* Support for numerical MP4 genre (gnre) tags
-	BASS_TAG_MP4 (BASS_ChannelGetTags type)
-* Support for BASSWMA's tag option when using Media Foundation WMA codec
-	BASS_TAG_WMA (BASS_ChannelGetTags type)
-* OpenMPT author tag retrieval
-	BASS_TAG_MUSIC_AUTH (BASS_ChannelGetTags type)
-* FastTracker2 panning for XM files
-	BASS_MUSIC_FT2PAN (BASS_MusicLoad flag)
-* Support for longer device names on Windows
-	BASS_DEVICEINFO (name member)
-* Checking for floating-point support on platforms that might not have it
-	BASS_CONFIG_FLOAT (BASS_GetConfig option)
-* Attribute size retrieval fix
-	BASS_ChannelGetAttributeEx
-* Fix for missing LC_VERSION_MIN issue with Xcode 7 on OSX, ppc architecture (PowerPC) support dropped
-* LIST example renamed to DEVLIST
-
-2.4.11 - 22/12/2014
--------------------
-* Support for custom HTTP request headers
-	BASS_StreamCreateURL
-* HTTPS support on Linux/Android
-	BASS_StreamCreateURL
-* Redirection HTTP headers provided during connection
-	BASS_STREAM_STATUS (BASS_StreamCreateURL flag)
-	DOWNLOADPROC
-* Adjustable stalled internet stream resumption buffer level
-	BASS_ATTRIB_NET_RESUME (BASS_ChannelSetAttribute option)
-* Extended level retrieval inc. multi-channel and RMS options
-	BASS_ChannelGetLevelEx
-* Inexact/faster seeking
-	BASS_POS_INEXACT (BASS_ChannelSetPosition flag)
-* Post-stream creation scanning (seek table building)
-	BASS_POS_SCAN (BASS_ChannelSetPosition flag)
-* Extended attribute support
-	BASS_ChannelGet/SetAttributeEx
-* Scanned info retrieval and setting
-	BASS_ATTRIB_SCANINFO (BASS_ChannelGet/SetAttributeEx option)
-* Built-in ADPCM WAVE file support on Linux/Android/WinCE
-	BASS_StreamCreateFile/User/URL
-	BASS_SampleLoad
-* Active MOD channel count retrieval
-	BASS_ATTRIB_MUSIC_ACTIVE (BASS_ChannelGetAttribute option)
-* Fractional sample rates
-	BASS_ATTRIB_FREQ (BASS_ChannelSetAttribute option)
-* Device type information
-	BASS_DEVICE_TYPE_xxx (BASS_DEVICEINFO flags)
-* Unicode support for recording input names
-	BASS_CONFIG_UNICODE (BASS_SetConfig option)
-	BASS_RecordGetInputName
-* File size retrieval
-	BASS_FILEPOS_SIZE (BASS_StreamGetFilePosition mode)
-* Asynchronous file reading buffer level retrieval
-	BASS_FILEPOS_ASYNCBUF (BASS_StreamGetFilePosition mode)
-* MPEG data search limit raised to 1MB
-	BASS_CONFIG_VERIFY (BASS_SetConfig option)
-* Separate MPEG data search limit for internet/buffered streams
-	BASS_CONFIG_VERIFY_NET (BASS_SetConfig option)
-* Support for iTunes gapless info with Media Foundation and CoreAudio codecs
-	BASS_StreamCreateFile/User
-* Airplay receiver enumeration and selection on OSX
-	BASS_DEVICES_AIRPLAY (BASS_GetDeviceInfo flag)
-	BASS_CONFIG_AIRPLAY (BASS_SetConfig option)
-* Media Foundation playback of audio from videos is now optional
-	BASS_CONFIG_MF_VIDEO (BASS_SetConfig option)
-* Optional floating-point or fixed-point data retrieval on Android/WinCE
-	BASS_DATA_FLOAT/FIXED (BASS_ChannelGetData flags)
-* Continuous output when nothing is playing on Linux/Android/WinCE
-	BASS_CONFIG_DEV_NONSTOP (BASS_SetConfig option)
-* Fix for decoding channels being ended when stopping the output device
-	BASS_Stop
-* Fix for Media Foundation internet/buffered streaming on Windows 8
-	BASS_StreamCreateURL
-	BASS_StreamCreateFileUser
-* Improved compatibility with recent PulseAudio versions on Linux
-* LIST and MODTEST examples added
-* MASM API and examples removed (available as separate download)
-
-2.4.10 - 16/2/2013
-------------------
-* Asynchronous file reading/buffering
-	BASS_ASYNCFILE (BASS_StreamCreateFile/User flag)
-	BASS_CONFIG_ASYNCFILE_BUFFER (BASS_SetConfig option)
-* Support for chained OGG files (multiple logical bitstreams)
-	BASS_StreamCreateFile/User
-	BASS_CONFIG_OGG_PRESCAN (BASS_SetConfig option)
-	BASS_POS_OGG (BASS_ChannelSetPosition/ChannelGetLength mode)
-* OGG logical bitstream syncs are no longer automatically "mixtime"
-	BASS_SYNC_OGG_CHANGE (BASS_ChannelSetSync type)
-* Support for Soundtracker MOD files
-	BASS_MusicLoad
-* Complex FFT data
-	BASS_DATA_FFT_COMPLEX (BASS_ChannelGetData flag)
-* Volume levels above 1.0 for decoding channels
-	BASS_ATTRIB_VOL (BASS_ChannelSetAttribute option)
-* Recording device channel count retrieval on Windows/OSX/iOS
-	BASS_RECORDINFO (formats member)
-* Minimum recording period reduced to 5ms
-	BASS_RecordStart
-* Recording device period adjustment on OSX
-	BASS_RecordStart
-* Device UID retrieval on OSX
-	BASS_DEVICEINFO (driver member)
-* The desktop window handle is used when none is provided
-	BASS_Init
-
-2.4.9 - 3/5/2012
-----------------
-* Improved and adjustable sample rate conversion quality
-	BASS_ATTRIB_SRC (BASS_ChannelSetAttribute option)
-	BASS_CONFIG_SRC/_SAMPLE (BASS_SetConfig options)
-* Support for buffered file & internet streams with CoreAudio codecs on OSX/iOS
-	BASS_StreamCreateURL
-	BASS_StreamCreateUser
-* Data and level retrieval from sample channels
-	BASS_ChannelGetData
-	BASS_ChannelGetLevel
-* Oldest sample channel will be overridden when there are multiple candidates
-	BASS_SampleGetChannel
-* Use of the device's output rate with MODs
-	BASS_MusicLoad
-* Optional device output rate setting on OSX/iOS
-	BASS_DEVICE_FREQ (BASS_Init flag)
-* UTF-8 device information on Windows
-	BASS_CONFIG_UNICODE (BASS_SetConfig option)
-* Speaker assignment with panning/balance control on Windows Vista/7
-	BASS_CONFIG_VISTA_SPEAKERS (BASS_SetConfig option)
-	BASS_ATTRIB_PAN (BASS_ChannelGet/Set/SlideAttribute option)
-* Push stream queue level can be checked after using BASS_STREAMPROC_END
-	BASS_StreamPutData
-* Support for ALSA subdevices on Linux
-	BASS_Init
-	BASS_GetDeviceInfo
-	BASS_RecordInit
-	BASS_RecordGetDeviceInfo
-* Device list fix on 64-bit OSX
-	BASS_GetDeviceInfo
-	BASS_RecordGetDeviceInfo
-* BASS_UNICODE support fix on Linux
-	BASS_PluginLoad
-* Internet streaming tweaks/fixes on Windows
-* SYNTH example updated to use device output rate
-* RECTEST example updated (C version) for better Windows Vista/7 support
-* Documentation updated with platform-specific info for Android
-
-2.4.8 - 29/8/2011
------------------
-* Support for Media Foundation codecs on Windows 7 and updated Vista
-	BASS_StreamCreateFile/User/URL
-	BASS_TAG_MF (BASS_ChannelGetTags type)
-	PLUGINS example updated
-* Built-in support for MP4 tags on Win32/OSX/iOS (for Media Foundation & CoreAudio AAC/ALAC codecs)
-	BASS_TAG_MP4 (BASS_ChannelGetTags type)
-* WAVE format chunk retrieval
-	BASS_TAG_WAVEFORMAT (BASS_ChannelGetTags type)
-* Adjustable sample channel limit
-	BASS_SampleSetInfo
-* Per-channel CPU usage monitoring
-	BASS_ATTRIB_CPU (BASS_ChannelGetAttribute option)
-* Pre-allocation of push stream queue space
-	BASS_StreamPutData
-* Support for AIFF files with the data chunk before the format info chunk
-	BASS_StreamCreateFile/User/URL
-* Ramping-in disabled for all but the XM format (and MODs in FT2 mode) in "normal" ramping mode
-	BASS_MUSIC_RAMP (BASS_MusicLoad flag)
-* RIFF "INFO" tag reading fix
-	BASS_TAG_RIFF_INFO (BASS_ChannelGetTags type)
-* OSX 10.7 compatibility fix
-* x86_64 architecture support on OSX
-* Delphi dynamic loading unit removed (now available as separate download)
-
-2.4.7 - 30/11/2010
-------------------
-* Decode-to-position seeking
-	BASS_POS_DECODETO (BASS_ChannelSetPosition flag)
-* Support for RIFF "DISP" text tags
-	BASS_TAG_RIFF_DISP (BASS_ChannelGetTags type)
-* Support for APEv1 tags
-	BASS_TAG_APE (BASS_ChannelGetTags type)
-	BASS_TAG_APE_BINARY (BASS_ChannelGetTags type)
-* 16384 sample FFT
-	BASS_DATA_FFT16384 (BASS_ChannelGetData flag)
-* Support for AIFF files larger than 4GB
-	BASS_StreamCreateFile/User/URL
-* Acceptance of self-signed and invalid certificates
-	BASS_StreamCreateURL
-* Internet stream reading timeout
-	BASS_CONFIG_NET_READTIMEOUT (BASS_SetConfig option)
-* Support for removing a DSP within its DSPPROC
-	BASS_ChannelRemoveDSP
-* Buffer bypassing for lower latency output (not available on Windows)
-	BASS_ATTRIB_NOBUFFER (BASS_ChannelSetAttribute option)
-	SYNTH example added (OSX)
-* A "Default" device that follows default device changes on Windows 7
-	BASS_CONFIG_DEV_DEFAULT (BASS_SetConfig option)
-* Xcode examples project added for OSX
-* Documentation updated with platform-specific info for iOS/Linux/WinCE
-
-2.4.6 - 17/6/2010
------------------
-* Support for APEv2 tags, including binary
-	BASS_TAG_APE (BASS_ChannelGetTags type)
-	BASS_TAG_APE_BINARY (BASS_ChannelGetTags type)
-* Unicode/IDN URL support
-	BASS_StreamCreateURL
-* Decoding position retrieval
-	BASS_POS_DECODE (BASS_ChannelGetPosition flag)
-* Support for OGG 6/7.1 channel configs
-	BASS_StreamCreateFile/User/URL
-* Support for setting syncs within mixtime SYNCPROCs
-	BASS_ChannelSetSync
-* Support for setting additional DSP/FX within DSPPROCs
-	BASS_ChannelSetDSP/FX
-* DC bias removal in FFT processing
-	BASS_DATA_FFT_REMOVEDC (BASS_ChannelGetData flag)
-* Fix for incorrect (2x) return value when getting FFT data from a 16-bit channel
-	BASS_ChannelGetData
-* Fix for incorrect (STOPPED instead of PAUSED) channel status following BASS_Pause
-	BASS_ChannelIsActive
-
-2.4.5 - 18/12/2009
-------------------
-* Support for little-endian AIFF files
-	BASS_StreamCreateFile/User/URL
-	BASS_SampleLoad
-* Support for 64-bit floating-point WAVE/AIFF files
-	BASS_StreamCreateFile/User/URL
-	BASS_SampleLoad
-* Input volume retrieval failure results in a reading of -1 instead of 1
-	BASS_RecordGetInput
-	RECTEST example updated
-* Input volume support on OSX
-	BASS_RecordSetInput
-	BASS_RecordGetInput
-	RECTEST example updated
-* Fix for deferred input settings on Vista
-	BASS_RecordSetInput
-* Windows MP3 codec given preference over other installed MP3 codecs (MP3-FREE version)
-	BASS_StreamCreateFile/User/URL
-	BASS_SampleLoad
-
-2.4.4 - 13/10/2009
-------------------
-* RIFF/BWF "radio traffic" tag retrieval
-	BASS_TAG_RIFF_CART (BASS_ChannelGetTags type)
-	TAG_CART structure
-* Support for ID3v2 tags in RIFF/WAVE/AIFF files ("ID3 " chunk)
-	BASS_TAG_ID3V2 (BASS_ChannelGetTags type)
-* Pushed fractional samples are refused rather than discarded
-	BASS_StreamPutData
-* DX8 effect emulation on OSX
-	BASS_FX_DX8_CHORUS/DISTORTION/ECHO/FLANGER/PARAMEQ/REVERB (BASS_ChannelSetFX types)
-	FXTEST example added
-* UTF-16 support on OSX
-	BASS_UNICODE (BASS_StreamCreateFile/SampleLoad/MusicLoad/PluginLoad flag)
-
-2.4.3 - 8/5/2009
-----------------
-* MOD order list retrieval
-	BASS_TAG_MUSIC_ORDERS (BASS_ChannelGetTags type)
-* Support for ID3v2 tags in RIFF/WAVE files ("id3 " chunk)
-	BASS_TAG_ID3V2 (BASS_ChannelGetTags type)
-* Improved position reporting precision on Vista
-	BASS_ChannelGetPosition
-* Length retrieval when streaming in blocks (BASS_STREAM_BLOCK)
-	BASS_ChannelGetLength
-* Support for CoreAudio codecs on OSX
-	BASS_StreamCreateFile/User
-	BASS_SampleLoad
-	BASS_TAG_CA_CODEC (BASS_ChannelGetTags type)
-	TAG_CA_CODEC structure
-* 3D algorithm option support on OSX
-	BASS_CONFIG_3DALGORITHM (BASS_SetConfig option)
-
-2.4.2 - 18/9/2008
------------------
-* RF64 support
-	BASS_StreamCreateFile/User
-* RIFF/BWF "Broadcast Audio Extension" tag retrieval
-	BASS_TAG_RIFF_BEXT (BASS_ChannelGetTags type)
-	TAG_BEXT structure
-* ID3v1 tag structure
-	TAG_ID3 structure
-* Multiple simultaneous recordings per device on Vista & OSX (as on XP)
-	BASS_RecordStart
-* DX8 effect parameter defaults updated/corrected in documentation
-
-2.4 - 2/4/2008
---------------
-* "Push" streaming
-	STREAMPROC_PUSH (BASS_StreamCreate option)
-	BASS_StreamPutData
-	LIVEFX and MULTI examples updated
-* "Push" buffered file streaming
-	STREAMFILE_BUFFERPUSH (BASS_StreamCreateFileUser system)
-	BASS_StreamPutFileData
-* STREAMFILEPROC replaced by table of callbacks for each file operation
-	BASS_FILEPROCS (FILECLOSEPROC/FILELENPROC/FILEREADPROC/FILESEEKPROC)
-	STREAMFILEPROC *removed*
-* 64-bit file positioning
-	BASS_SampleLoad
-	BASS_MusicLoad
-	BASS_StreamCreateFile
-	BASS_StreamGetFilePosition
-* File buffer level retrieval
-	BASS_FILEPOS_BUFFER (BASS_StreamGetFilePosition mode)
-* Sinc interpolated MOD music mixing
-	BASS_MUSIC_SINCINTER (BASS_MusicLoad flag)
-* MO3 2.4 support
-	BASS_MusicLoad
-* MOD orders positioning incorporated into channel functions
-	BASS_ChannelGetLength
-	BASS_ChannelSetPosition
-	BASS_ChannelGetPosition
-	BASS_MusicGetOrderPosition *removed*
-	BASS_MusicGetOrders *removed*
-* Channel attribute functions consolidated
-	BASS_ChannelSetAttribute
-	BASS_ChannelGetAttribute
-	BASS_ChannelSlideAttribute
-	BASS_ChannelIsSliding
-	BASS_ChannelSetAttributes *removed*
-	BASS_ChannelGetAttributes *removed*
-	BASS_ChannelSlideAttributes *removed*
-	BASS_ChannelSetEAXMix *removed*
-	BASS_ChannelGetEAXMix *removed*
-	BASS_MusicSetAttribute *removed*
-	BASS_MusicGetAttribute *removed*
-* Floating-point volume and panning
-	BASS_SetVolume
-	BASS_GetVolume
-	BASS_RecordSetInput
-	BASS_RecordGetInput
-	BASS_ATTRIB_PAN/VOL (BASS_ChannelGet/Set/SlideAttribute options)
-	BASS_ATTRIB_MUSIC_VOL_CHAN/INST (BASS_ChannelGet/Set/SlideAttribute options)
-	BASS_SAMPLE (volume/pan/outvol members)
-	BASS_CONFIG_MAXVOL *removed*
-	BASSTEST and RECTEST examples updated
-* Output device volume control on Vista (as on other OS)
-	BASS_SetVolume
-	BASS_GetVolume
-* Multiple update threads
-	BASS_CONFIG_UPDATETHREADS (BASS_SetConfig option)
-	BASSTEST example updated
-* Global volume range increased to 10000
-	BASS_CONFIG_GVOL_SAMPLE/STREAM/MUSIC (BASS_SetConfig options)
-	BASSTEST example updated
-* Setting and retrieving of a sample's data
-	BASS_SampleSetData
-	BASS_SampleGetData
-	BASS_SampleCreate
-	BASS_SampleCreateDone *removed*
-* Channel flag setting mask
-	BASS_ChannelFlags
-	BASS_ChannelSetFlags *removed*
-	SPEAKERS example updated
-* 256 sample FFT
-	BASS_DATA_FFT256 (BASS_ChannelGetData flag)
-* Channel locking to prevent access by other threads
-	BASS_ChannelLock
-* Manual channel buffer updating
-	BASS_ChannelUpdate
-	BASS_ChannelPreBuf *removed*
-* Configurable manual update length
-	BASS_Update
-* Extended device information retrieval and detection of new/removed devices
-	BASS_GetDeviceInfo
-	BASS_RecordGetDeviceInfo
-	BASS_DEVICEINFO structure
-	BASS_GetDeviceDescription *removed*
-	BASS_RecordGetDeviceDescription *removed*
-	BASS_INFO (driver member) *removed*
-	BASS_RECORDINFO (driver member) *removed*
-	MULTI example updated
-* Default device change tracking on Windows (as on OSX)
-	BASS_Init
-	BASS_RecordInit
-* Speaker detection from Windows control panel
-	BASS_DEVICE_CPSPEAKERS (BASS_Init flag)
-* Channel automatically stopped & resumed for DX8 effects
-	BASS_ChannelSetFX
-	BASS_ChannelRemoveFX
-* "double" precision position conversion
-	BASS_ChannelBytes2Seconds
-	BASS_ChannelSeconds2Bytes
-* Separate config functions for pointers
-	BASS_SetConfigPtr
-	BASS_GetConfigPtr
-	BASS_CONFIG_NET_AGENT/PROXY (BASS_SetConfigPtr options)
-* Configurable file format verification length
-	BASS_CONFIG_VERIFY (BASS_SetConfig option)
-* Stream filename retrieval
-	BASS_CHANNELINFO (file member)
-* Channel sample retrieval
-	BASS_CHANNELINFO (sample member)
-* META syncs no longer receive metadata in the "data" parameter
-	BASS_SYNC_META (BASS_ChannelSetSync type)
-* Separate sync for OGG logical bitstream changes (instead of BASS_SYNC_META)
-	BASS_SYNC_OGG_CHANGE (BASS_ChannelSetSync type)
-	NETRADIO example updated (C version)
-* Message syncing removed (use PostMessage instead)
-	BASS_SYNC_MESSAGE (BASS_ChannelSetSync flag) *removed*
-* Data retrieval from stopped/paused channels
-	BASS_ChannelGetData
-* Callback "user" parameters changed to pointers
-	BASS_StreamCreate / STREAMPROC
-	BASS_StreamCreateFileUser
-	BASS_StreamCreateURL / DOWNLOADPROC
-	BASS_RecordStart / RECORDPROC
-	BASS_ChannelSetDSP / DSPPROC
-	BASS_ChannelSetSync / SYNCPROC
-
-2.3.0.3 - 30/7/2007
--------------------
-* FX state resetting
-	BASS_FXReset
-* PLS/M3U playlist URL processing
-	BASS_CONFIG_NET_PLAYLIST (BASS_SetConfig option)
-	NETRADIO example updated
-* Internet stream connection status retrieval
-	BASS_FILEPOS_CONNECTED (BASS_StreamGetFilePosition mode)
-* Lyrics3v2 tags
-	BASS_TAG_LYRICS3 (BASS_ChannelGetTags type)
-* IT virtual channel configuration
-	BASS_CONFIG_MUSIC_VIRTUAL (BASS_SetConfig option)
-* Accurate speaker detection on Vista
-	BASS_INFO (speakers member)
-* Device output/input rate retrieval on Vista
-	BASS_INFO (freq member)
-	BASS_RECORDINFO (freq member)
-* Syncing upon position changes
-	BASS_SYNC_SETPOS (BASS_ChannelSetSync type)
-* Improved stall handling
-	BASS_SYNC_STALL
-* Invalid decoding channel flags produce an error instead of being ignored
-	BASS_StreamCreate/File/User/URL
-	BASS_MusicLoad
-
-2.3.0.2 - 22/1/2007
--------------------
-* Retrieval of a sample's existing channel handles
-	BASS_SampleGetChannels
-* 8192 sample FFT
-	BASS_DATA_FFT8192 (BASS_ChannelGetData flag)
-* Adjustable recording buffer
-	BASS_CONFIG_REC_BUFFER (BASS_SetConfig option)
-* Stopping decoding channels before the end
-	BASS_ChannelStop
-* Sample channels created paused to prevent overriding before playback
-	BASS_SampleGetChannel
-* Separate "MP3-FREE" version using the OS's MP3 decoder
-	BASS_CONFIG_MP3_CODEC *removed*
-
-2.3.0.1 - 12/6/2006
--------------------
-* Ability to move a channel to another device
-	BASS_ChannelSetDevice
-	MULTI example updated
-* Support for ID3v2.4 tags at end of file
-	BASS_TAG_ID3V2 (BASS_ChannelGetTags type)
-
-2.3 - 21/5/2006
----------------
-* MOD message/instrument/sample text retrieval, merged with stream tag retrieval function
-	BASS_ChannelGetTags
-	BASS_TAG_MUSIC_NAME/MESSAGE/INST/SAMPLE (BASS_ChannelGetTags types)
-	BASS_MusicGetName *removed*
-	BASS_StreamGetTags *removed*
-* Plugin information retrieval
-	BASS_PluginGetInfo
-	BASS_PLUGININFO/FORM structures
-	BASS_CHANNELINFO (plugin member)
-	PLUGINS example updated
-* RIFF/WAVE "INFO" tag retrieval
-	BASS_TAG_RIFF_INFO (BASS_StreamGetTags type)
-* More specific WAVE format information
-	BASS_CTYPE_STREAM_WAV_PCM/FLOAT (channel types)
-	BASS_CTYPE_STREAM_WAV (channel type flag)
-* Proxy server configuration
-	BASS_CONFIG_NET_PROXY (BASS_SetConfig option)
-	BASS_CONFIG_NET_NOPROXY *removed*
-	NETRADIO example updated
-* Passive FTP mode
-	BASS_CONFIG_NET_PASSIVE (BASS_SetConfig option)
-* Agent changes take immediate effect
-	BASS_CONFIG_NET_AGENT (BASS_SetConfig option)
-* Minimum time gap between creating new sample channels
-	BASS_SAMPLE (mingap member)
-	BASS_SampleGetChannel
-* Support for Unicode plugin filenames
-	BASS_PluginLoad
-* Device output/input rate retrieval (MacOSX only)
-	BASS_INFO (freq member)
-	BASS_RECORDINFO (freq member)
-* Extended version info (minor revision)
-	BASS_GetVersion
-* Unsupported codec error code
-	BASS_ERROR_CODEC
-* Optional use of the Windows MP3 codec
-	BASS_CONFIG_MP3_CODEC (BASS_SetConfig option)
-* 3D support for MacOSX
-	BASS_Set3DFactors
-	BASS_Get3DFactors
-	BASS_Set3DPosition
-	BASS_Get3DPosition
-	BASS_Apply3D
-	BASS_ChannelSet3DAttributes
-	BASS_ChannelGet3DAttributes
-	BASS_ChannelSet3DPosition
-	BASS_ChannelGet3DPosition
-	3DTEST example added (Win32 example also updated)
-* VB version of SYNTH example added
-
-2.2 - 2/10/2005
----------------
-* Add-on plugin system
-	BASS_PluginLoad
-	BASS_PluginFree
-	BASS_StreamCreateFile/User/URL
-	BASS_SampleLoad
-	PLUGINS example added
-* MOD position & syncing in bytes
-	BASS_ChannelSetPosition
-	BASS_ChannelGetPosition
-	BASS_MusicGetOrderPosition added for orders position
-	BASS_SYNC_MUSICPOS added for orders syncing
-	MAKEMUSICPOS macro/define
-	CUSTLOOP example updated
-* Stream/MOD "length" functions combined (also works with samples), new MOD orders length function
-	BASS_ChannelGetLength
-	BASS_MusicGetOrders
-	BASS_StreamGetLength *removed*
-	BASS_MusicGetLength *removed*
-* Support for AIFF files
-	BASS_StreamCreateFile/User/URL
-	BASS_SampleLoad
-* Support for 24 and 32-bit (integer) WAV files
-	BASS_StreamCreateFile/User/URL
-	BASS_SampleLoad
-* WAV files are no longer converted to the "device" resolution
-	BASS_StreamCreateFile/User/URL
-* Recording master control
-	BASS_RecordGetInput
-	BASS_RecordSetInput
-* Adjustable pre-buffering
-	BASS_ChannelPreBuf
-* Floating-point data retrieval
-	BASS_DATA_FLOAT (BASS_ChannelGetData flag)
-* Support for floating-point samples
-	BASS_SampleLoad
-	BASS_SampleCreate
-* Multi-channel samples
-	BASS_SampleLoad/Create
-	BASS_SAMPLE (chans member)
-* Sample lengths given in bytes
-	BASS_SampleCreate
-	BASS_SAMPLE (length member)
-* MOD music 8-bit resolution option
-	BASS_MusicLoad
-* OGG vendor tag retrieval
-	BASS_TAG_VENDOR (BASS_StreamGetTags type)
-* Configurable "User-Agent" header for internet streams
-	BASS_CONFIG_NET_AGENT (BASS_SetConfig option)
-* Shoutcast metadata is now requested automatically
-	BASS_STREAM_META flag *removed*
-* Download callbacks receive all data from start of file/stream (including any non-audio data)
-	DOWNLOADPROC
-* Length when streaming in blocks is unavailable (BASS_ERROR_NOTAVAIL, not just 0)
-	BASS_ChannelGetLength
-* Support for growing custom file streams
-	BASS_FILE_LEN (STREAMFILEPROC action)
-* Query file action removed
-	BASS_FILE_QUERY *removed*
-* Recording channel syncing
-	BASS_ChannelSetSync
-* Info structure "size" members removed
-	BASS_INFO structure
-	BASS_RECORDINFO structure
-* Little bit of flag reshuffling
-	BASS_MP3_SETPOS renamed to BASS_STREAM_PRESCAN
-	BASS_MUSIC_CALCLEN value changed and renamed to BASS_MUSIC_PRESCAN
-	BASS_MUSIC_POSRESET value changed
-* Add-on API enhancements
-* MacOSX port introduced
-
-2.1 - 28/11/2004
-----------------
-* Improved "mixtime" sync system, allowing custom looping
-	SYNCPROC
-	CUSTLOOP example added
-* FX can now be in the DSP chain, so can be prioritized and applied in floating-point
-	BASS_ChannelSetFX
-	BASS_CONFIG_FLOATDSP (BASS_SetConfig option)
-* Ability to set channel flags (eg. looping) independent of playback
-	BASS_ChannelSetFlags
-	SPEAKERS example updated
-* Stream/MOD "play" and channel "resume" functions combined
-	BASS_ChannelPlay
-	BASS_StreamPlay *removed*
-	BASS_MusicPlay *removed*
-	BASS_MusicPlayEx *removed*
-	BASS_ChannelResume *removed*
-* Stream/MOD pre-buffering functions combined
-	BASS_ChannelPreBuf
-	BASS_StreamPreBuf *removed*
-	BASS_MusicPreBuf *removed*
-* MOD attribute functions combined, with added BPM/speed/globalvolume options
-	BASS_MusicSetAttribute
-	BASS_MusicGetAttribute
-	BASS_MUSIC_ATTRIB_AMPLIFY
-	BASS_MUSIC_ATTRIB_PANSEP
-	BASS_MUSIC_ATTRIB_PSCALER
-	BASS_MUSIC_ATTRIB_BPM
-	BASS_MUSIC_ATTRIB_SPEED
-	BASS_MUSIC_ATTRIB_VOL_GLOBAL
-	BASS_MUSIC_ATTRIB_VOL_CHAN
-	BASS_MUSIC_ATTRIB_VOL_INST
-	BASS_MusicSetAmplify *removed*
-	BASS_MusicSetPanSep *removed*
-	BASS_MusicSetPositionScaler *removed*
-	BASS_MusicSetVolume *removed*
-	BASS_MusicGetVolume *removed*
-* Flag to reset bpm/etc as well as notes when seeking in MOD musics
-	BASS_MUSIC_POSRESETEX (BASS_MusicLoad & BASS_ChannelSetFlags flag)
-* More flexible and concise sample channel creation system
-	BASS_SampleGetChannel
-	BASS_SamplePlay *removed*
-	BASS_SamplePlayEx *removed*
-	BASS_SamplePlay3D *removed*
-	BASS_SamplePlay3DEx *removed*
-* Support for up to 30 speakers
-	BASS_SPEAKER_N macro/define
-* More precise level measurement
-	BASS_ChannelGetLevel
-* Level can now be retrieved from decoding channels
-	BASS_ChannelGetLevel
-* Retrieval of a sample/channel's original sample resolution
-	BASS_SAMPLE (origres member)
-	BASS_CHANNELINFO (origres member)
-* Support for streaming WAV files in "blocks"
-	BASS_StreamCreateURL
-	BASS_StreamCreateFileUser
-* Status info (HTTP/ICY tags) available during connection to server
-	BASS_STREAM_STATUS (BASS_StreamCreateURL flag)
-	DOWNLOADPROC
-	NETRADIO example updated (Delphi version also added)
-* Adjustable internet stream pre-buffering
-	BASS_CONFIG_NET_PREBUF (BASS_SetConfig option)
-* Option to bypass proxy server
-	BASS_CONFIG_NET_NOPROXY (BASS_SetConfig option)
-* Option whether to allow channels to be played after BASS_Pause
-	BASS_CONFIG_PAUSE_NOPLAY (BASS_SetConfig option)
-* Recording channel count now a separate parameter
-	BASS_RecordStart (chans parameter)
-* Synchronizer for when a channel is freed
-	BASS_SYNC_FREE (BASS_ChannelSetSync type)
-* Data start file position retrieval
-	BASS_FILEPOS_START (BASS_StreamGetFilePosition mode)
-* Performance improvements
-	MP2 decoding ~20% faster
-	MP3/MP1 decoding & FFT processing all up to 10% faster
-	OGG decoding ~3% faster
-* C/C++ examples reorganised, with makefiles & VC++ projects
-* Add-on API enhancements
-* More DLL shrinkage :)
-
-2.0 - 31/10/2003
-----------------
-* Multiple output device support
-	BASS_Init (device number changes)
-	BASS_SetDevice
-	BASS_GetDevice
-	BASS_ChannelGetDevice
-	MULTI example updated (VB version also added)
-* Multiple recording device support
-	BASS_RecordSetDevice
-	BASS_RecordGetDevice
-	BASS_RecordStart
-	BASS_ChannelGetDevice
-	HRECORD handle
-	RECORDPROC (handle parameter)
-* Recording with DSP/FX
-	BASS_ChannelSetDSP
-	BASS_ChannelSetFX
-* Recording position retrieval
-	BASS_ChannelGetPosition
-* Start recording paused
-	BASS_RECORD_PAUSE (BASS_RecordStart flag)
-* Multi-channel streams, inc. support for multichannel OGG & WAV files
-	BASS_StreamCreate
-	BASS_StreamCreateFile/User/URL
-* FFT for individual channels, inc. multi-channel streams
-	BASS_DATA_FFT_INDIVIDUAL (BASS_ChannelGetData flag)
-	BASS_DATA_FFT512S/1024S/2048S/4096S *removed*
-* DSP prioritizing
-	BASS_ChannelSetDSP
-	DSPTEST example updated
-* Seeking in internet streamed files
-	BASS_ChannelSetPosition
-* Enhanced custom file stream systems
-	BASS_StreamCreateFileUser
-	BASS_FILE_SEEK (STREAMFILEPROC action)
-	BASS_STREAM_FILEPROC flag *removed*
-* Enhanced custom stream system with automatic stalling/resuming
-	STREAMPROC
-	BASS_STREAMPROC_END (STREAMPROC flag)
-* Synchronizer for stalled/resumed playback 
-	BASS_SYNC_STALL (BASS_ChannelSetSync type)
-* Synchronizer for completed download
-	BASS_SYNC_DOWNLOAD (BASS_ChannelSetSync type)
-* End sync support for custom streams
-	BASS_SYNC_END (BASS_ChannelSetSync type)
-* Synchronizer support for decoding channels
-	BASS_ChannelSetSync
-* Unified configuration function
-	BASS_SetConfig
-	BASS_GetConfig
-	BASS_SetBufferLength *removed*
-	BASS_SetNetConfig *removed*
-	BASS_SetGlobalVolumes *removed*
-	BASS_GetGlobalVolumes *removed*
-	BASS_SetLogCurves *removed*
-	BASS_Set3DAlgorithm *removed*
-	BASS_DEVICE_FLOATDSP flag *removed*
-* Internet stream saving to disk replaced by more flexible callback
-	BASS_StreamCreateURL
-	DOWNLOADPROC
-	VB NETRADIO example updated
-* Buffer length retrieval when "streaming in blocks"
-	BASS_FILEPOS_END (BASS_StreamGetFilePosition mode)
-* Individual sample rate setting for MOD musics
-	BASS_MusicLoad
-* Channel type and default sample rate retrieval
-	BASS_ChannelGetInfo (replaces BASS_ChannelGetFlags)
-	BASS_CHANNELINFO
-* MOD music flag retrieval
-	BASS_CHANNELINFO (flags member)
-* Adjustable instrument volumes in MOD musics
-	BASS_MusicSetVolume (replaces BASS_MusicSetChannelVol)
-	BASS_MusicGetVolume (replaces BASS_MusicGetChannelVol)
-* Automatically free a MOD music when it stops or ends
-	BASS_MUSIC_AUTOFREE (BASS_MusicLoad flag)
-* Class GUID added to initialization parameters
-	BASS_Init
-	BASS_SetCLSID *removed*
-* Update period adjustable at any time
-	BASS_CONFIG_UPDATEPERIOD (BASS_SetConfig option)
-	BASS_DEVICE_NOTHREAD flag *removed*
-* Customizable maximum volume setting
-	BASS_CONFIG_MAXVOL (BASS_SetConfig option)
-	BASS_DEVICE_VOL1000 flag *removed*
-* Device volume is now always left as it is during init/freeing
-	BASS_DEVICE_LEAVEVOL flag *removed*
-* Device driver name retrieval
-	BASS_INFO (driver member)
-	BASS_RECORDINFO (driver member)
-* Error codes are local to the current thread
-	BASS_ErrorGetCode
-* Performance improvements
-	MP2 decoding 15-20% faster
-	MP3 decoding ~5% faster
-* Built-in CD functions removed (replaced in BASSCD)
-	BASS_CDDoor *removed*
-	BASS_CDFree *removed*
-	BASS_CDGetID *removed*
-	BASS_CDGetTrackLength *removed*
-	BASS_CDGetTracks *removed*
-	BASS_CDInDrive *removed*
-	BASS_CDInit *removed*
-	BASS_CDPlay *removed*
-* Force channels to use software mixing
-	BASS_SAMPLE_SOFTWARE (BASS_StreamCreate/File/User/URL & BASS_MusicLoad flag)
-* Support for high-pass filter and forward/reverse (S9E/F) IT/MPT effects
-* BASS_MUSIC flags rearranged to mirror BASS_SAMPLE/STREAM counterparts
-* Output automatically started during initialization
-* BASS_ChannelGetData once again accepts any "length" param
-* All function comments have been removed from the API headers to avoid
-  outdated/incorrect information - the documentation should be used.
-* TMT Pascal API removed from main distribution - now available on the website
-* A few more 'K' knocked off the DLL size :)
-
-1.8a - 18/6/2003
-----------------
-* Tweaks 'n' fixes, including...
-	Fixed seeking bug on 32-bit OGG streams
-	Fixed seeking on a decoding channel after it has reached the end
-	Low FPU precision (eg. when using Direct3D) issue addressed
-	Improved speakers (BASS_INFO) detection
-	BASS_ChannelSeconds2Bytes return value is rounded down to nearest sample
-	BASS_ChannelGetData "length" param must equal a whole number of samples
-	Slide syncs are triggered by "-2" volume slides on "autofree" streams
-* Support for Unicode filenames
-	BASS_UNICODE (BASS_SampleLoad/BASS_StreamCreateFile/BASS_MusicLoad flag)
-* 4096 sample FFT
-	BASS_DATA_FFT4096/S (BASS_ChannelGetData flags)
-* Another 'K' knocked off the DLL size
-
-1.8 - 9/3/2003
---------------
-* 32-bit floating-point channels
-	BASS_SAMPLE_FLOAT (BASS_StreamCreate/File/URL flag)
-	BASS_MUSIC_FLOAT (BASS_MusicLoad flag)
-	BASS_SAMPLE_FLOAT (BASS_RecordStart flag)
-	BASS_DEVICE_FLOATDSP (BASS_Init flag)
-	DSPTEST example updated
-* Support for 32-bit floating-point (type 3) WAV files
-	BASS_StreamCreateFile/URL
-	BASS_SampleLoad
-* Channel speaker assignment
-	BASS_SPEAKER_FRONT (BASS_MusicLoad/BASS_StreamCreate/File/URL flag)
-	BASS_SPEAKER_REAR                       "
-	BASS_SPEAKER_CENLFE                     "
-	BASS_SPEAKER_REAR2                      "
-	BASS_SPEAKER_FRONTLEFT                  "
-	BASS_SPEAKER_FRONTRIGHT                 "
-	BASS_SPEAKER_REARLEFT                   "
-	BASS_SPEAKER_REARRIGHT                  "
-	BASS_SPEAKER_CENTER                     "
-	BASS_SPEAKER_LFE                        "
-	BASS_SPEAKER_REAR2LEFT                  "
-	BASS_SPEAKER_REAR2RIGHT                 "
-	BASS_INFO (speakers member)
-	BASS_DEVICE_SPEAKERS (BASS_Init flag)
-	4SPEAKER example replaced by SPEAKERS example
-* Recording input type retrieval
-	BASS_INPUT_TYPE_xxx (BASS_RecordGetInput)
-	RECTEST example updated
-* Non-interpolated MOD mixing
-	BASS_MUSIC_NONINTER (BASS_MusicLoad/PlayEx flag)
-* Performance improvements
-	FFT up to 100% faster!
-	MP3(MPEG2/2.5) decoding up to 60% faster
-	MMX mixers 5-10% faster
-	MP3(MPEG1)/MP2/MP1/OGG decoding all ~5% faster
-* Optional disabling of FFT windowing
-	BASS_DATA_FFT_NOWINDOW (BASS_ChannelGetData flag)
-* BASS_ERROR_FILEFORM - error code to distinguish between file and sample format
-	BASS_MusicLoad
-	BASS_SampleLoad
-	BASS_StreamCreate/File/URL
-* BASS_StreamGetFilePosition mode flags added
-	BASS_FILEPOS_DECODE/DOWNLOAD/END
-* DirectSound 9 detection
-	BASS_INFO (dsver member)
-* Initialization flags retrieval
-	BASS_INFO (initflags member)
-* Half-rate MP3 playback option removed
-	BASS_MP3_HALFRATE flag *removed*
-* New internal "plugin" system - BASSWMA is further integrated as a result
-* Improved documentation - integrated with BASSWMA, search option added
-* VB version of DSPTEST example added
-* Delphi RECORDTEST example added
-* Guess what... reduced DLL size again :)
-
-1.7 - 27/10/2002
-----------------
-* New alternative DX8 (DMO) effects implementation
-	BASS_StreamCreate/File/URL
-	BASS_MusicLoad
-	BASS_ChannelSetFX
-	SYNTH example updated
-* User file streaming
-	BASS_STREAM_FILEPROC (BASS_StreamCreate flag)
-	STREAMFILEPROC
-* DSP & FX support for decoding channels
-	BASS_ChannelSetDSP
-	BASS_ChannelSetFX
-* Support for DX8 (DMO) effects in IT/XM/MO3 files
-	BASS_MusicLoad
-* Support for chained OGG streaming (and syncing)
-	BASS_StreamCreateURL
-	BASS_SYNC_META (BASS_ChannelSetSync type)
-* Attribute (volume/frequency/pan) sliding
-	BASS_ChannelSlideAttributes
-	BASS_ChannelIsSliding
-	BASS_SYNC_SLIDE (BASS_ChannelSetSync type)
-* Recording without a callback function
-	BASS_RecordStart
-	LIVEFX example added
-* Query a channel's buffered data
-	BASS_DATA_AVAILABLE (BASS_ChannelGetData flag)
-* Discard data from the recording buffer
-	BASS_ChannelGetData
-* Adjustable internet stream config (timeout/buffer lengths)
-	BASS_SetNetConfig
-* Recommended minimum buffer length
-	BASS_INFO (minbuf member)
-* MOD music flags adjustment without changing playback position
-	BASS_MusicPlayEx
-	PLAYER (MASM) example updated
-* More functions are now useable in MOD music "mixtime" syncs
-	SYNCPROC
-	BASS_ChannelSetPosition
-	BASS_MusicPlayEx
-	BASS_MusicSetAmplify
-	BASS_MusicSetPanSep
-* Maximum buffer length increased to 5 seconds
-	BASS_SetBufferLength
-* Support for extended filter range in IT files
-	BASS_MusicLoad
-* Speedier MOD music file verification
-	BASS_MusicLoad
-* Delphi 3DTEST example fixed
-* Magically reduced DLL size again :)
-
-1.6a - 25/8/2002
-----------------
-* OGG support updated to 1.0
-* Stereo FFT
-	BASS_DATA_FFT512S/1024S/2048S (BASS_ChannelGetData flags)
-* Support for "Invert Loop" (EFx) MOD effect
-* Reduced DLL size
-* New Delphi examples
-	WRITEWAV - WAVE writer example
-	SAMPLEVIS - Visualisation example
-
-1.6 - 13/6/2002
----------------
-* 64-bit stream lengths and positions
-	BASS_StreamGetLength
-	BASS_ChannelBytes2Seconds
-	BASS_ChannelSeconds2Bytes
-	BASS_ChannelGetPosition
-	BASS_ChannelSetPosition
-	BASS_ChannelSetSync
-* Recording input selection
-	BASS_RECORDINFO (inputs & singlein members)
-	BASS_RecordGetInputName
-	BASS_RecordGetInput
-	BASS_RecordSetInput
-* Adjustable recording update period
-	BASS_RecordStart
-* Load OGG files as samples
-	BASS_SampleLoad
-* CD drive door opening & closing
-	BASS_CDDoor
-* CDDB2 ID retrieval
-	BASS_CDID_CDDB2 (BASS_CDGetID flag)
-* Streaming beyond initial file length
-	BASS_StreamCreateFile
-* Recording position bytes<->seconds translation
-	BASS_ChannelBytes2Seconds
-	BASS_ChannelSeconds2Bytes
-* Improved multi-threaded support (play from any thread)
-	BASS_MusicPlay/Ex
-	BASS_SamplePlay/3D/Ex
-	BASS_StreamPlay
-	BASS_DEVICE_NOSYNC flag *removed*
-* Paused channel status
-	BASS_ACTIVE_PAUSED (BASS_ChannelIsActive)
-* Integrated WMA stream freeing
-	BASS_StreamFree
-	BASS_Free
-* Pin-point accurate OGG seeking without BASS_MP3_SETPOS flag
-* Win2k DS buffer bug fix
-
-1.5a - 14/4/2002
-----------------
-* NT4 fix (also enables "nosound" device without DX installed)
-	BASS_ERROR_DX error code
-* MOD music loading without the samples
-	BASS_MUSIC_NOSAMPLE (BASS_MusicLoad flag)
-* Custom decoding channels
-	BASS_STREAM_DECODE (BASS_StreamCreate flag)
-* 5 second HTTP connection timeout
-	BASS_ERROR_TIMEOUT (BASS_StreamCreateURL error code)
-
-1.5 - 31/3/2002
----------------
-* Improved performance
-	MMX mixers lot faster (over 50% faster in some cases!)
-	OGG decoding 15-20% faster
-	MP3 decoding 5-10% faster
-* Recording
-	BASS_RecordGetDeviceDescription
-	BASS_RecordInit
-	BASS_RecordFree
-	BASS_RecordGetInfo
-	BASS_RecordStart
-* OGG support built-in (OGG/VORBIS DLLs not required)
-	BASS_DEVICE_OGG flag *removed*
-* MOD music seeking in seconds
-	BASS_MusicPlayEx
-	BASS_ChannelSetPosition
-* Shoutcast metadata retrieval
-	BASS_STREAM_META (BASS_StreamCreateURL flag)
-	BASS_TAG_META (BASS_StreamGetTags type)
-	BASS_SYNC_META (BASS_ChannelSetSync type)
-* 1000 volume levels
-	BASS_DEVICE_VOL1000 (BASS_Init/CDInit flag)
-* CDDB ID retrieval
-	BASS_CDID_CDDB (BASS_CDGetID flag)
-* Leave the CD volume as it is during init/closing
-	BASS_DEVICE_LEAVEVOL (BASS_CDInit flag)
-* FFT enabled on decoding channels
-	BASS_ChannelGetData
-* Left level duplicated on right for mono channels
-	BASS_ChannelGetLevel
-* Improved MPEG length estimation without BASS_MP3_SETPOS flag
-	BASS_StreamGetLength
-* Support for Modplug/ADPCM compressed files
-	BASS_MusicLoad
-* Device description function parameter change
-	BASS_GetDeviceDescription
-* MASM API
-
-1.4 - 30/1/2002
----------------
-* Channel decoding without playback
-	BASS_MUSIC_DECODE (BASS_MusicLoad flag)
-	BASS_STREAM_DECODE (BASS_StreamCreateFile/URL flag)
-	BASS_ChannelGetData
-* Windows message sync callbacks
-	BASS_SYNC_MESSAGE (BASS_ChannelSetSync flag)
-* Adjustable channel volumes in MOD musics
-	BASS_MusicSetChannelVol
-	BASS_MusicGetChannelVol
-* Customizable DirectSound initialization object
-	BASS_SetCLSID
-* Retrieve HMUSIC/HSTREAM/HCHANNEL IDirectSoundBuffer interfaces
-	BASS_GetDSoundObject
-* A3D functions removed (use BASS_SetCLSID/BASS_GetDSoundObject to access A3D)
-	BASS_DEVICE_A3D (BASS_Init flag)
-	BASS_SetA3DResManager
-	BASS_GetA3DResManager
-	BASS_SetA3DHFAbsorbtion
-	BASS_GetA3DHFAbsorbtion
-* Callback functions now work in VB6
-	DSPPROC
-	STREAMPROC
-	SYNCPROC
-* Improved PCM WAVE streaming performance
-	BASS_StreamCreateFile
-	BASS_StreamCreateURL
-* OGG modules updated to RC3
-* Stereo sample support in MO3 format
-* MO3 encoder now distributed separately from BASS
-
-1.3 - 17/11/2001
-----------------
-* Manual buffer updating
-	BASS_DEVICE_NOTHREAD (BASS_Init flag)
-	BASS_Update
-* Adjustable buffer update period (allows small buffer sizes)
-	BASS_Init
-* Output device latency retrieval
-	BASS_INFO (latency member)
-* MPEG/OGG seeking without BASS_MP3_SETPOS flag
-	BASS_ChannelSetPosition
-* Internet file streaming from offsets
-	BASS_StreamCreateURL
-* File stream tag/comment retrieval (ID3/ID3v2/OGG/HTTP/ICY tags)
-	BASS_StreamGetTags
-* Byte<->time position translation
-	BASS_ChannelBytes2Seconds
-	BASS_ChannelSeconds2Bytes
-* UMX (Unreal/Tournament music package) format support
-	BASS_MusicLoad
-* S3M/IT sync fx changed to S2x (S0x conflicted with S00)
-	BASS_SYNC_MUSICFX
-* Stereo sample support in IT/XM/S3M formats
-* MO3: OGG compression supported
-
-1.2 - 25/9/2001
----------------
-* OGG (Ogg Vorbis) stream support
-	BASS_DEVICE_OGG (BASS_Init flag)
-	BASS_StreamCreateFile
-	BASS_StreamCreateURL
-* Channel linking (start/stop/pause/resume channels together)
-	BASS_ChannelSetLink
-	BASS_ChannelRemoveLink
-* MOD music playback length calculation
-	BASS_MUSIC_CALCLEN (BASS_MusicLoad flag)
-	BASS_MusicGetLength
-* Pre-buffering
-	BASS_MusicPreBuf
-	BASS_StreamPreBuf
-* Samples with single simultaneous playbacks have same HSAMPLE/HCHANNEL handle
-	BASS_SamplePlay/Ex
-* Stopping a custom stream flushes its buffer contents
-	BASS_ChannelStop
-
-1.1a - 31/8/2001
-----------------
-* NT4 bug fixed
-* XM Wxx effect syncing
-	BASS_SYNC_MUSICFX
-* MP3/2/1 rewinding without BASS_MP3_SETPOS
-	BASS_ChannelSetPosition
-
-1.1 - 11/8/2001
----------------
-* DX8 (DMO) effects
-	BASS_SAMPLE_FX (BASS_StreamCreate/File/URL flag)
-	BASS_MUSIC_FX (BASS_MusicLoad flag)
-	BASS_ChannelSetFX
-	BASS_ChannelRemoveFX
-	BASS_FXSetParameters
-	BASS_FXGetParameters
-	BASS_FXCHORUS structure
-	BASS_FXCOMPRESSOR structure
-	BASS_FXDISTORTION structure
-	BASS_FXECHO structure
-	BASS_FXFLANGER structure
-	BASS_FXGARGLE structure
-	BASS_FXI3DL2REVERB structure
-	BASS_FXPARAMEQ structure
-	BASS_FXREVERB structure
-* Internet file streaming in blocks (inc. Shoutcast/Icecast stream support)
-	BASS_STREAM_BLOCK (BASS_StreamCreateURL flag)
-* 512/1024/2048 sample FFT
-	BASS_DATA_FFT512/1024/2048 (BASS_ChannelGetData flags)
-* CD identification
-	BASS_CDGetID
-* Improved DX version detection
-	BASS_INFO (dsver member)
-
-1.0 - 20/6/2001
----------------
-* Load MP3/MP2/MP1 files as samples
-	BASS_SampleLoad
-* Internet file streaming from FTP servers
-	BASS_StreamCreateURL
-* Save a local copy of internet file streams
-	BASS_StreamCreateURL
-* Sample accurate file stream seeking
-	BASS_ChannelSetPosition
-	BASS_StreamGetBlockLength *removed*
-* Stream position synchronizer
-	BASS_SYNC_POS
-* Increased synchronizer precision
-* Improved MPEG file detection and error detection
-* Stop MOD musics on a backwards jump effect
-	BASS_MUSIC_STOPBACK (BASS_MusicLoad/PlayEx flag)
-* Leave the volume as it is during closing (as well as initialization)
-	BASS_DEVICE_LEAVEVOL (BASS_Init flag)
-* Optional automatic use of foreground window handle during initialization
-	BASS_Init
-* Reduced DLL size
-* VB API fixes
-
-0.9 - 18/4/2001
----------------
-* Internet file streaming
-	BASS_StreamCreateURL
-* MP1 & MP2 (MPEG layer 1 & 2) support
-	BASS_StreamCreateFile/URL
-* MPEG 2.5 support (12000/11025/8000hz sample rates)
-	BASS_StreamCreateFile/URL
-* Decoding/download/end file stream position retrieval
-	BASS_StreamGetFilePosition
-* XMPlay surround sound for MOD musics
-	BASS_MUSIC_SURROUND (BASS_MusicLoad/PlayEx flag)
-	BASS_MUSIC_SURROUND2 (BASS_MusicLoad/PlayEx flag)
-* Restrict the download rate of internet file streams
-	BASS_STREAM_RESTRATE (BASS_StreamCreateURL flag)
-* Check if an internet file stream is stalled
-	BASS_ChannelIsActive
-* Automatically free a stream when it stops or ends
-	BASS_STREAM_AUTOFREE (BASS_StreamCreate/File/URL flag)
-* Leave the volume as it is during initialization
-	BASS_DEVICE_LEAVEVOL (BASS_Init flag)
-* Number of CD tracks retrieval
-	BASS_CDGetTracks
-* CD track length retrieval
-	BASS_CDGetTrackLength
-* Exact stream length set after whole file is streamed
-	BASS_StreamGetLength
-* TMT Pascal API and samples
-* Dynamic-loading Delphi API
-
-0.8a - 28/2/2000
-----------------
-* Updated Delphi API and samples
-
-0.8 - 24/1/2000
----------------
-* Improved MP3 performance on P2/K6 and above CPUs
-* User DSP functions on streams and MOD musics
-	BASS_ChannelSetDSP
-	BASS_ChannelRemoveDSP
-* DX7 voice allocation & management
-	BASS_SAMPLE_VAM (BASS_SampleLoad/Create flag)
-	BASS_VAM_xxx flags
-	BASS_SAMPLE (vam & priority members)
-* DX7 software 3D algorithm selection
-	BASS_Set3DAlgorithm
-* DirectSound interface retrieval
-	BASS_GetDSoundObject
-* Log/linear volume & panning curves
-	BASS_SetLogCurves
-* User data passed to callback functions
-	STREAMPROC - BASS_StreamCreate
-	SYNCPROC - BASS_ChannelSetSync
-* New synchronizer
-	BASS_SYNC_MUSICFX
-* New synchronizer flag
-	BASS_SYNC_MIXTIME
-* Disable synchronizers option - saves a little CPU time
-	BASS_DEVICE_NOSYNC (BASS_Init flag)
-* Hi-res floating-point CPU usage monitoring
-	BASS_GetCPU
-* Wait for playback to start when playing a CD
-	BASS_CDPlay
-* DirectSound (dsound.dll) version retrieval
-	BASS_INFO (dsver member)
-* Removed volume sliding functions (they were fairly pointless)
-	BASS_SlideVolume
-	BASS_IsSliding
-* MO3: read/write encoder settings
-* MO3: remove inst/samp/message texts now optional
-* MO3: LAME encoder settings
-
-0.7 - 3/10/1999
----------------
-* MO3 (MP3 compressed MODs)
-* A3D functions
-	BASS_DEVICE_A3D (BASS_Init flag)
-	BASS_INFO (a3d member)
-	BASS_SetA3DResManager
-	BASS_GetA3DResManager
-	BASS_SetA3DHFAbsorbtion
-	BASS_GetA3DHFAbsorbtion
-* Music/stream immediate sample data retrieval
-	BASS_ChannelGetData
-* File stream (WAV/MP3) length retrieval
-	BASS_StreamGetLength
-	BASS_StreamGetBlockLength
-* File stream seeking
-	BASS_ChannelSetPosition
-* Mono MP3 option (lower CPU usage)
-	BASS_StreamCreateFile
-* Music length retrieval
-	BASS_MusicGetLength
-* Music name retrieval
-	BASS_MusicGetName
-* Stop notes when moving MOD music position
-	BASS_MUSIC_POSRESET (BASS_MusicLoad/BASS_MusicPlayEx flag)
-* BASS_ERROR_FREQ - invalid sample rate error code
-	BASS_SampleCreate
-	BASS_SamplePlayEx
-	BASS_SamplePlay3DEx
-	BASS_StreamCreate
-	BASS_ChannelSetAttributes
-* Delphi and VB APIs
-
-0.6a - 26/7/1999
-----------------
-* Half rate MP3 option (lower CPU usage)
-	BASS_MP3_HALFRATE
-* Loading/streaming from file offsets
-	BASS_MusicLoad
-	BASS_SampleLoad
-	BASS_StreamCreateFile
-* Global music/sample/stream volume levels
-	BASS_SetGlobalVolumes
-	BASS_GetGlobalVolumes
-* Other new function
-	BASS_SampleStop
-* New synchronizer
-	BASS_SYNC_END
-* New sample overrider
-	BASS_SAMPLE_OVER_DIST
-* LoadLibrary/GetProcAddress instructions and example
-
-0.5 - 4/7/1999
---------------
-* Documentation!
-* File streaming (MP3 and WAV)
-	BASS_StreamCreateFile
-* Custom generated samples
-	BASS_SampleCreate
-	BASS_SampleCreateDone
-* Other new function
-	BASS_MusicSetPositionScaler
-* Renamed function
-	BASS_ChannelClearSync -> BASS_ChannelRemoveSync
-* Alterations made to
-	BASS_ChannelGetPosition
-	BASS_SampleLoad
-	BASS_StreamPlay
-
-0.4 - 30/3/1999
----------------
-* Compressed WAV samples support (using audio CODECs)
-* Updated CD volume handling - now works with SB Live
-* More linear channel volume/pan scales (were slightly off before)
-* "No sound" device option
-* 3D sound functions
-	BASS_Set3DFactors
-	BASS_Get3DFactors
-	BASS_Set3DPosition
-	BASS_Get3DPosition
-	BASS_Apply3D
-	BASS_SamplePlay3D
-	BASS_SamplePlay3DEx
-	BASS_ChannelSet3DAttributes
-	BASS_ChannelGet3DAttributes
-	BASS_ChannelSet3DPosition
-	BASS_ChannelGet3DPosition
-* EAX functions
-	BASS_SetEAXParameters
-	BASS_GetEAXParameters
-	BASS_ChannelSetEAXMix
-	BASS_ChannelGetEAXMix
-* Other new functions
-	BASS_GetDeviceDescription
-	BASS_SetBufferLen
-	BASS_ChannelGetFlags
-	BASS_ChannelPause
-	BASS_ChannelResume
-	BASS_ChannelSetPosition
-* Replaced function
-	BASS_CDResume -> BASS_ChannelResume
-* Alterations made to
-	BASS_Init
-	BASS_CDInit
-	BASS_SampleLoad
-	BASS_StreamPlay
-	BASS_INFO structure
-	BASS_SAMPLE structure
-	BASS_DEVICE_xxx flags
-	BASS_SAMPLE_xxx flags
-
-0.3 - 8/3/1999
---------------
-* Synchronization functions
-	BASS_ChannelSetSync
-	BASS_ChannelClearSync
-* Other new functions
-	BASS_GetVersion
-	BASS_ChannelGetPosition
-	BASS_ChannelGetLevel
-	BASS_ChannelGetAttributes
-	BASS_ChannelSetAttributes
-* Replaced functions
-	BASS_MusicStop -> BASS_ChannelStop
-	BASS_MusicSetVolume -> BASS_ChannelSetAttributes
-	BASS_CDStop -> BASS_ChannelStop
-	BASS_CDSetVolume -> BASS_ChannelSetAttributes
-	BASS_CDGetVolume -> BASS_ChannelGetAttributes
-	BASS_ChannelUpdate -> BASS_ChannelSetAttributes
-* Alterations made to
-	BASS_MusicPlayEx
-	BASS_StreamPlay
-	BASS_INFO structure
-
-0.2 - 28/2/1999
----------------
-* First public release
-
-
-Bug reports, Suggestions, Comments, Enquiries, etc
-==================================================
-If you have any of the aforementioned please visit the BASS forum at the
-website. If you can't find an answer there, you can also email:
-
-	bass@un4seen.com
-

+ 0 - 43
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bass.xcframework/Info.plist

@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>AvailableLibraries</key>
-	<array>
-		<dict>
-			<key>LibraryIdentifier</key>
-			<string>ios-arm64_armv7_armv7s</string>
-			<key>LibraryPath</key>
-			<string>libbass.a</string>
-			<key>SupportedArchitectures</key>
-			<array>
-				<string>arm64</string>
-				<string>armv7</string>
-				<string>armv7s</string>
-			</array>
-			<key>SupportedPlatform</key>
-			<string>ios</string>
-		</dict>
-		<dict>
-			<key>LibraryIdentifier</key>
-			<string>ios-arm64_i386_x86_64-simulator</string>
-			<key>LibraryPath</key>
-			<string>libbass.a</string>
-			<key>SupportedArchitectures</key>
-			<array>
-				<string>arm64</string>
-				<string>i386</string>
-				<string>x86_64</string>
-			</array>
-			<key>SupportedPlatform</key>
-			<string>ios</string>
-			<key>SupportedPlatformVariant</key>
-			<string>simulator</string>
-		</dict>
-	</array>
-	<key>CFBundlePackageType</key>
-	<string>XFWK</string>
-	<key>XCFrameworkFormatVersion</key>
-	<string>1.0</string>
-</dict>
-</plist>

BIN
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bass.xcframework/ios-arm64_armv7_armv7s/libbass.a


BIN
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bass.xcframework/ios-arm64_i386_x86_64-simulator/libbass.a


+ 0 - 424
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bassmidi.h

@@ -1,424 +0,0 @@
-/*
-	BASSMIDI 2.4 C/C++ header file
-	Copyright (c) 2006-2022 Un4seen Developments Ltd.
-
-	See the BASSMIDI.CHM file for more detailed documentation
-*/
-
-#ifndef BASSMIDI_H
-#define BASSMIDI_H
-
-#include "bass.h"
-
-#if BASSVERSION!=0x204
-#error conflicting BASS and BASSMIDI versions
-#endif
-
-#ifdef __OBJC__
-typedef int BOOL32;
-#define BOOL BOOL32 // override objc's BOOL
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef BASSMIDIDEF
-#define BASSMIDIDEF(f) WINAPI f
-#endif
-
-typedef DWORD HSOUNDFONT;	// soundfont handle
-
-// Additional error codes returned by BASS_ErrorGetCode
-#define BASS_ERROR_MIDI_INCLUDE		7000	// SFZ include file could not be opened
-
-// Additional BASS_SetConfig options
-#define BASS_CONFIG_MIDI_COMPACT	0x10400
-#define BASS_CONFIG_MIDI_VOICES		0x10401
-#define BASS_CONFIG_MIDI_AUTOFONT	0x10402
-#define BASS_CONFIG_MIDI_IN_PORTS	0x10404
-#define BASS_CONFIG_MIDI_SAMPLETHREADS 0x10406
-#define BASS_CONFIG_MIDI_SAMPLEMEM	0x10407
-#define BASS_CONFIG_MIDI_SAMPLEREAD	0x10408
-#define BASS_CONFIG_MIDI_SAMPLELOADING	0x1040a
-
-// Additional BASS_SetConfigPtr options
-#define BASS_CONFIG_MIDI_DEFFONT	0x10403
-#define BASS_CONFIG_MIDI_SFZHEAD	0x10409
-
-// Additional sync types
-#define BASS_SYNC_MIDI_MARK		0x10000
-#define BASS_SYNC_MIDI_MARKER	0x10000
-#define BASS_SYNC_MIDI_CUE		0x10001
-#define BASS_SYNC_MIDI_LYRIC	0x10002
-#define BASS_SYNC_MIDI_TEXT		0x10003
-#define BASS_SYNC_MIDI_EVENT	0x10004
-#define BASS_SYNC_MIDI_TICK		0x10005
-#define BASS_SYNC_MIDI_TIMESIG	0x10006
-#define BASS_SYNC_MIDI_KEYSIG	0x10007
-
-// Additional BASS_MIDI_StreamCreateFile/etc flags
-#define BASS_MIDI_NODRUMPARAM	0x400
-#define BASS_MIDI_NOSYSRESET	0x800
-#define BASS_MIDI_DECAYEND		0x1000
-#define BASS_MIDI_NOFX			0x2000
-#define BASS_MIDI_DECAYSEEK		0x4000
-#define BASS_MIDI_NOCROP		0x8000
-#define BASS_MIDI_NOTEOFF1		0x10000
-#define BASS_MIDI_ASYNC			0x400000
-#define BASS_MIDI_SINCINTER		0x800000
-
-// BASS_MIDI_FontInit flags
-#define BASS_MIDI_FONT_MEM		0x10000
-#define BASS_MIDI_FONT_MMAP		0x20000
-#define BASS_MIDI_FONT_XGDRUMS	0x40000
-#define BASS_MIDI_FONT_NOFX		0x80000
-#define BASS_MIDI_FONT_LINATTMOD	0x100000
-#define BASS_MIDI_FONT_LINDECVOL	0x200000
-#define BASS_MIDI_FONT_NORAMPIN		0x400000
-#define BASS_MIDI_FONT_NOLIMITS		0x800000
-#define BASS_MIDI_FONT_MINFX		0x1000000
-
-typedef struct {
-	HSOUNDFONT font;	// soundfont
-	int preset;			// preset number (-1=all)
-	int bank;
-} BASS_MIDI_FONT;
-
-typedef struct {
-	HSOUNDFONT font;	// soundfont
-	int spreset;		// source preset number
-	int sbank;			// source bank number
-	int dpreset;		// destination preset/program number
-	int dbank;			// destination bank number
-	int dbanklsb;		// destination bank number LSB
-} BASS_MIDI_FONTEX;
-
-typedef struct {
-	HSOUNDFONT font;	// soundfont
-	int spreset;		// source preset number
-	int sbank;			// source bank number
-	int dpreset;		// destination preset/program number
-	int dbank;			// destination bank number
-	int dbanklsb;		// destination bank number LSB
-	DWORD minchan;		// minimum channel number
-	DWORD numchan;		// number of channels from minchan
-} BASS_MIDI_FONTEX2;
-
-// BASS_MIDI_StreamSet/GetFonts flag
-#define BASS_MIDI_FONT_EX		0x1000000	// BASS_MIDI_FONTEX
-#define BASS_MIDI_FONT_EX2		0x2000000	// BASS_MIDI_FONTEX2
-
-typedef struct {
-	const char *name;
-	const char *copyright;
-	const char *comment;
-	DWORD presets;		// number of presets/instruments
-	DWORD samsize;		// total size (in bytes) of the sample data
-	DWORD samload;		// amount of sample data currently loaded
-	DWORD samtype;		// sample format (CTYPE) if packed
-} BASS_MIDI_FONTINFO;
-
-typedef struct {
-	DWORD track;		// track containing marker
-	DWORD pos;			// marker position
-	const char *text;	// marker text
-} BASS_MIDI_MARK;
-
-// Marker types
-#define BASS_MIDI_MARK_MARKER	0	// marker
-#define BASS_MIDI_MARK_CUE		1	// cue point
-#define BASS_MIDI_MARK_LYRIC	2	// lyric
-#define BASS_MIDI_MARK_TEXT		3	// text
-#define BASS_MIDI_MARK_TIMESIG	4	// time signature
-#define BASS_MIDI_MARK_KEYSIG	5	// key signature
-#define BASS_MIDI_MARK_COPY		6	// copyright notice
-#define BASS_MIDI_MARK_TRACK	7	// track name
-#define BASS_MIDI_MARK_INST		8	// instrument name
-#define BASS_MIDI_MARK_TRACKSTART	9	// track start (SMF2)
-#define BASS_MIDI_MARK_TICK		0x10000 // flag: get position in ticks (otherwise bytes)
-
-// MIDI events
-#define MIDI_EVENT_NOTE				1
-#define MIDI_EVENT_PROGRAM			2
-#define MIDI_EVENT_CHANPRES			3
-#define MIDI_EVENT_PITCH			4
-#define MIDI_EVENT_PITCHRANGE		5
-#define MIDI_EVENT_DRUMS			6
-#define MIDI_EVENT_FINETUNE			7
-#define MIDI_EVENT_COARSETUNE		8
-#define MIDI_EVENT_MASTERVOL		9
-#define MIDI_EVENT_BANK				10
-#define MIDI_EVENT_MODULATION		11
-#define MIDI_EVENT_VOLUME			12
-#define MIDI_EVENT_PAN				13
-#define MIDI_EVENT_EXPRESSION		14
-#define MIDI_EVENT_SUSTAIN			15
-#define MIDI_EVENT_SOUNDOFF			16
-#define MIDI_EVENT_RESET			17
-#define MIDI_EVENT_NOTESOFF			18
-#define MIDI_EVENT_PORTAMENTO		19
-#define MIDI_EVENT_PORTATIME		20
-#define MIDI_EVENT_PORTANOTE		21
-#define MIDI_EVENT_MODE				22
-#define MIDI_EVENT_REVERB			23
-#define MIDI_EVENT_CHORUS			24
-#define MIDI_EVENT_CUTOFF			25
-#define MIDI_EVENT_RESONANCE		26
-#define MIDI_EVENT_RELEASE			27
-#define MIDI_EVENT_ATTACK			28
-#define MIDI_EVENT_DECAY			29
-#define MIDI_EVENT_REVERB_MACRO		30
-#define MIDI_EVENT_CHORUS_MACRO		31
-#define MIDI_EVENT_REVERB_TIME		32
-#define MIDI_EVENT_REVERB_DELAY		33
-#define MIDI_EVENT_REVERB_LOCUTOFF	34
-#define MIDI_EVENT_REVERB_HICUTOFF	35
-#define MIDI_EVENT_REVERB_LEVEL		36
-#define MIDI_EVENT_CHORUS_DELAY		37
-#define MIDI_EVENT_CHORUS_DEPTH		38
-#define MIDI_EVENT_CHORUS_RATE		39
-#define MIDI_EVENT_CHORUS_FEEDBACK	40
-#define MIDI_EVENT_CHORUS_LEVEL		41
-#define MIDI_EVENT_CHORUS_REVERB	42
-#define MIDI_EVENT_USERFX			43
-#define MIDI_EVENT_USERFX_LEVEL		44
-#define MIDI_EVENT_USERFX_REVERB	45
-#define MIDI_EVENT_USERFX_CHORUS	46
-#define MIDI_EVENT_DRUM_FINETUNE	50
-#define MIDI_EVENT_DRUM_COARSETUNE	51
-#define MIDI_EVENT_DRUM_PAN			52
-#define MIDI_EVENT_DRUM_REVERB		53
-#define MIDI_EVENT_DRUM_CHORUS		54
-#define MIDI_EVENT_DRUM_CUTOFF		55
-#define MIDI_EVENT_DRUM_RESONANCE	56
-#define MIDI_EVENT_DRUM_LEVEL		57
-#define MIDI_EVENT_DRUM_USERFX		58
-#define MIDI_EVENT_SOFT				60
-#define MIDI_EVENT_SYSTEM			61
-#define MIDI_EVENT_TEMPO			62
-#define MIDI_EVENT_SCALETUNING		63
-#define MIDI_EVENT_CONTROL			64
-#define MIDI_EVENT_CHANPRES_VIBRATO	65
-#define MIDI_EVENT_CHANPRES_PITCH	66
-#define MIDI_EVENT_CHANPRES_FILTER	67
-#define MIDI_EVENT_CHANPRES_VOLUME	68
-#define MIDI_EVENT_MOD_VIBRATO		69
-#define MIDI_EVENT_MODRANGE			69
-#define MIDI_EVENT_BANK_LSB			70
-#define MIDI_EVENT_KEYPRES			71
-#define MIDI_EVENT_KEYPRES_VIBRATO	72
-#define MIDI_EVENT_KEYPRES_PITCH	73
-#define MIDI_EVENT_KEYPRES_FILTER	74
-#define MIDI_EVENT_KEYPRES_VOLUME	75
-#define MIDI_EVENT_SOSTENUTO		76
-#define MIDI_EVENT_MOD_PITCH		77
-#define MIDI_EVENT_MOD_FILTER		78
-#define MIDI_EVENT_MOD_VOLUME		79
-#define MIDI_EVENT_VIBRATO_RATE		80
-#define MIDI_EVENT_VIBRATO_DEPTH	81
-#define MIDI_EVENT_VIBRATO_DELAY	82
-#define MIDI_EVENT_MASTER_FINETUNE	83
-#define MIDI_EVENT_MASTER_COARSETUNE	84
-#define MIDI_EVENT_MIXLEVEL			0x10000
-#define MIDI_EVENT_TRANSPOSE		0x10001
-#define MIDI_EVENT_SYSTEMEX			0x10002
-#define MIDI_EVENT_SPEED			0x10004
-#define MIDI_EVENT_DEFDRUMS			0x10006
-
-#define MIDI_EVENT_END				0
-#define MIDI_EVENT_END_TRACK		0x10003
-
-#define MIDI_EVENT_NOTES			0x20000
-#define MIDI_EVENT_VOICES			0x20001
-
-#define MIDI_SYSTEM_DEFAULT			0
-#define MIDI_SYSTEM_GM1				1
-#define MIDI_SYSTEM_GM2				2
-#define MIDI_SYSTEM_XG				3
-#define MIDI_SYSTEM_GS				4
-
-typedef struct {
-	DWORD event;		// MIDI_EVENT_xxx
-	DWORD param;
-	DWORD chan;
-	DWORD tick;			// event position (ticks)
-	DWORD pos;			// event position (bytes)
-} BASS_MIDI_EVENT;
-
-// BASS_MIDI_StreamEvents modes
-#define BASS_MIDI_EVENTS_STRUCT		0 // BASS_MIDI_EVENT structures
-#define BASS_MIDI_EVENTS_RAW		0x10000 // raw MIDI event data
-#define BASS_MIDI_EVENTS_SYNC		0x1000000 // flag: trigger event syncs
-#define BASS_MIDI_EVENTS_NORSTATUS	0x2000000 // flag: no running status
-#define BASS_MIDI_EVENTS_CANCEL		0x4000000 // flag: cancel pending events
-#define BASS_MIDI_EVENTS_TIME		0x8000000 // flag: delta-time info is present
-#define BASS_MIDI_EVENTS_ABSTIME	0x10000000 // flag: absolute time info is present
-#define BASS_MIDI_EVENTS_ASYNC		0x20000000 // flag: process asynchronously
-#define BASS_MIDI_EVENTS_FILTER		0x40000000 // flag: apply filtering
-#define BASS_MIDI_EVENTS_FLUSH		0x80000000 // flag: flush async events
-
-// BASS_MIDI_StreamGetChannel special channels
-#define BASS_MIDI_CHAN_CHORUS		(DWORD)-1
-#define BASS_MIDI_CHAN_REVERB		(DWORD)-2
-#define BASS_MIDI_CHAN_USERFX		(DWORD)-3
-
-// BASS_CHANNELINFO type
-#define BASS_CTYPE_STREAM_MIDI	0x10d00
-
-// Additional attributes
-#define BASS_ATTRIB_MIDI_PPQN		0x12000
-#define BASS_ATTRIB_MIDI_CPU		0x12001
-#define BASS_ATTRIB_MIDI_CHANS		0x12002
-#define BASS_ATTRIB_MIDI_VOICES		0x12003
-#define BASS_ATTRIB_MIDI_VOICES_ACTIVE 0x12004
-#define BASS_ATTRIB_MIDI_STATE		0x12005
-#define BASS_ATTRIB_MIDI_SRC		0x12006
-#define BASS_ATTRIB_MIDI_KILL		0x12007
-#define BASS_ATTRIB_MIDI_SPEED		0x12008
-#define BASS_ATTRIB_MIDI_REVERB		0x12009
-#define BASS_ATTRIB_MIDI_VOL		0x1200a
-#define BASS_ATTRIB_MIDI_TRACK_VOL	0x12100 // + track #
-
-// Additional tag type
-#define BASS_TAG_MIDI_TRACK	0x11000	// + track #, track text : array of null-terminated ANSI strings
-
-// BASS_ChannelGetLength/GetPosition/SetPosition mode
-#define BASS_POS_MIDI_TICK		2		// tick position
-
-typedef BOOL (CALLBACK MIDIFILTERPROC)(HSTREAM handle, int track, BASS_MIDI_EVENT *event, BOOL seeking, void *user);
-/* Event filtering callback function.
-handle : MIDI stream handle
-track  : Track containing the event
-event  : The event
-seeking: TRUE = the event is being processed while seeking, FALSE = it is being played
-user   : The 'user' parameter value given when calling BASS_MIDI_StreamSetFilter
-RETURN : TRUE = process the event, FALSE = drop the event */
-
-// BASS_MIDI_FontLoadEx flags
-#define BASS_MIDI_FONTLOAD_NOWAIT	1	// don't want for the samples to load
-#define BASS_MIDI_FONTLOAD_COMPACT	2	// compact samples
-#define BASS_MIDI_FONTLOAD_NOLOAD	4	// don't load (only compact)
-#define BASS_MIDI_FONTLOAD_TIME		8	// length is in milliseconds
-#define BASS_MIDI_FONTLOAD_KEEPDEC	16	// keep decoders
-
-// BASS_MIDI_FontPack flags
-#define BASS_MIDI_PACK_NOHEAD		1	// don't send a WAV header to the encoder
-#define BASS_MIDI_PACK_16BIT		2	// discard low 8 bits of 24-bit sample data
-#define BASS_MIDI_PACK_48KHZ		4	// set encoding rate to 48000 Hz (else 44100 Hz)
-
-typedef struct {
-	const char *name;	// description
-	DWORD id;
-	DWORD flags;
-} BASS_MIDI_DEVICEINFO;
-
-typedef void (CALLBACK MIDIINPROC)(DWORD device, double time, const BYTE *buffer, DWORD length, void *user);
-/* MIDI input callback function.
-device : MIDI input device
-time   : Timestamp
-buffer : Buffer containing MIDI data
-length : Number of bytes of data
-user   : The 'user' parameter value given when calling BASS_MIDI_InInit */
-
-DWORD BASSMIDIDEF(BASS_MIDI_GetVersion)(void);
-
-HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreate)(DWORD channels, DWORD flags, DWORD freq);
-HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags, DWORD freq);
-HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateURL)(const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user, DWORD freq);
-HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *procs, void *user, DWORD freq);
-HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateEvents)(const BASS_MIDI_EVENT *events, DWORD ppqn, DWORD flags, DWORD freq);
-BOOL BASSMIDIDEF(BASS_MIDI_StreamGetMark)(HSTREAM handle, DWORD type, DWORD index, BASS_MIDI_MARK *mark);
-DWORD BASSMIDIDEF(BASS_MIDI_StreamGetMarks)(HSTREAM handle, int track, DWORD type, BASS_MIDI_MARK *marks);
-BOOL BASSMIDIDEF(BASS_MIDI_StreamSetFonts)(HSTREAM handle, const void *fonts, DWORD count);
-DWORD BASSMIDIDEF(BASS_MIDI_StreamGetFonts)(HSTREAM handle, void *fonts, DWORD count);
-BOOL BASSMIDIDEF(BASS_MIDI_StreamLoadSamples)(HSTREAM handle);
-BOOL BASSMIDIDEF(BASS_MIDI_StreamEvent)(HSTREAM handle, DWORD chan, DWORD event, DWORD param);
-DWORD BASSMIDIDEF(BASS_MIDI_StreamEvents)(HSTREAM handle, DWORD mode, const void *events, DWORD length);
-DWORD BASSMIDIDEF(BASS_MIDI_StreamGetEvent)(HSTREAM handle, DWORD chan, DWORD event);
-DWORD BASSMIDIDEF(BASS_MIDI_StreamGetEvents)(HSTREAM handle, int track, DWORD filter, BASS_MIDI_EVENT *events);
-DWORD BASSMIDIDEF(BASS_MIDI_StreamGetEventsEx)(HSTREAM handle, int track, DWORD filter, BASS_MIDI_EVENT *events, DWORD start, DWORD count);
-BOOL BASSMIDIDEF(BASS_MIDI_StreamGetPreset)(HSTREAM handle, DWORD chan, BASS_MIDI_FONT *font);
-HSTREAM BASSMIDIDEF(BASS_MIDI_StreamGetChannel)(HSTREAM handle, DWORD chan);
-BOOL BASSMIDIDEF(BASS_MIDI_StreamSetFilter)(HSTREAM handle, BOOL seeking, MIDIFILTERPROC *proc, void *user);
-
-HSOUNDFONT BASSMIDIDEF(BASS_MIDI_FontInit)(const void *file, DWORD flags);
-HSOUNDFONT BASSMIDIDEF(BASS_MIDI_FontInitUser)(const BASS_FILEPROCS *procs, void *user, DWORD flags);
-BOOL BASSMIDIDEF(BASS_MIDI_FontFree)(HSOUNDFONT handle);
-BOOL BASSMIDIDEF(BASS_MIDI_FontGetInfo)(HSOUNDFONT handle, BASS_MIDI_FONTINFO *info);
-BOOL BASSMIDIDEF(BASS_MIDI_FontGetPresets)(HSOUNDFONT handle, DWORD *presets);
-const char *BASSMIDIDEF(BASS_MIDI_FontGetPreset)(HSOUNDFONT handle, int preset, int bank);
-BOOL BASSMIDIDEF(BASS_MIDI_FontLoad)(HSOUNDFONT handle, int preset, int bank);
-BOOL BASSMIDIDEF(BASS_MIDI_FontLoadEx)(HSOUNDFONT handle, int preset, int bank, DWORD length, DWORD flags);
-BOOL BASSMIDIDEF(BASS_MIDI_FontUnload)(HSOUNDFONT handle, int preset, int bank);
-BOOL BASSMIDIDEF(BASS_MIDI_FontCompact)(HSOUNDFONT handle);
-BOOL BASSMIDIDEF(BASS_MIDI_FontPack)(HSOUNDFONT handle, const void *outfile, const void *encoder, DWORD flags);
-BOOL BASSMIDIDEF(BASS_MIDI_FontUnpack)(HSOUNDFONT handle, const void *outfile, DWORD flags);
-DWORD BASSMIDIDEF(BASS_MIDI_FontFlags)(HSOUNDFONT handle, DWORD flags, DWORD mask);
-BOOL BASSMIDIDEF(BASS_MIDI_FontSetVolume)(HSOUNDFONT handle, float volume);
-float BASSMIDIDEF(BASS_MIDI_FontGetVolume)(HSOUNDFONT handle);
-
-DWORD BASSMIDIDEF(BASS_MIDI_ConvertEvents)(const BYTE *data, DWORD length, BASS_MIDI_EVENT *events, DWORD count, DWORD flags);
-
-BOOL BASSMIDIDEF(BASS_MIDI_InGetDeviceInfo)(DWORD device, BASS_MIDI_DEVICEINFO *info);
-BOOL BASSMIDIDEF(BASS_MIDI_InInit)(DWORD device, MIDIINPROC *proc, void *user);
-BOOL BASSMIDIDEF(BASS_MIDI_InFree)(DWORD device);
-BOOL BASSMIDIDEF(BASS_MIDI_InStart)(DWORD device);
-BOOL BASSMIDIDEF(BASS_MIDI_InStop)(DWORD device);
-
-#ifdef __cplusplus
-}
-
-static inline BOOL BASS_MIDI_StreamSetFonts(HSTREAM handle, const BASS_MIDI_FONTEX *fonts, DWORD count)
-{
-	return BASS_MIDI_StreamSetFonts(handle, (const void*)fonts, count | BASS_MIDI_FONT_EX);
-}
-
-static inline BOOL BASS_MIDI_StreamSetFonts(HSTREAM handle, const BASS_MIDI_FONTEX2 *fonts, DWORD count)
-{
-	return BASS_MIDI_StreamSetFonts(handle, (const void*)fonts, count | BASS_MIDI_FONT_EX2);
-}
-
-static inline DWORD BASS_MIDI_StreamGetFonts(HSTREAM handle, BASS_MIDI_FONTEX *fonts, DWORD count)
-{
-	return BASS_MIDI_StreamGetFonts(handle, (void*)fonts, count | BASS_MIDI_FONT_EX);
-}
-
-static inline DWORD BASS_MIDI_StreamGetFonts(HSTREAM handle, BASS_MIDI_FONTEX2 *fonts, DWORD count)
-{
-	return BASS_MIDI_StreamGetFonts(handle, (void*)fonts, count | BASS_MIDI_FONT_EX2);
-}
-
-#ifdef _WIN32
-static inline HSTREAM BASS_MIDI_StreamCreateFile(BOOL mem, const WCHAR *file, QWORD offset, QWORD length, DWORD flags, DWORD freq)
-{
-	return BASS_MIDI_StreamCreateFile(mem, (const void*)file, offset, length, flags | BASS_UNICODE, freq);
-}
-
-static inline HSTREAM BASS_MIDI_StreamCreateURL(const WCHAR *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user, DWORD freq)
-{
-	return BASS_MIDI_StreamCreateURL((const char*)url, offset, flags | BASS_UNICODE, proc, user, freq);
-}
-
-static inline HSOUNDFONT BASS_MIDI_FontInit(const WCHAR *file, DWORD flags)
-{
-	return BASS_MIDI_FontInit((const void*)file, flags|BASS_UNICODE);
-}
-
-static inline BOOL BASS_MIDI_FontPack(HSOUNDFONT handle, const WCHAR *outfile, const WCHAR *encoder, DWORD flags)
-{
-	return BASS_MIDI_FontPack(handle, (const void*)outfile, (const void*)encoder, flags | BASS_UNICODE);
-}
-
-static inline BOOL BASS_MIDI_FontUnpack(HSOUNDFONT handle, const WCHAR *outfile, DWORD flags)
-{
-	return BASS_MIDI_FontUnpack(handle, (const void*)outfile, flags | BASS_UNICODE);
-}
-#endif
-#endif
-
-#ifdef __OBJC__
-#undef BOOL
-#endif
-
-#endif

+ 0 - 689
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bassmidi.txt

@@ -1,689 +0,0 @@
-BASSMIDI 2.4
-Copyright (c) 2006-2022 Un4seen Developments Ltd. All rights reserved.
-
-Files that you should have found in the BASSMIDI package
-========================================================
-Win32 version
--------------
-BASSMIDI.TXT    This file
-BASSMIDI.DLL    BASSMIDI module
-BASSMIDI.CHM    BASSMIDI documentation
-X64\
-  BASSMIDI.DLL    64-bit BASSMIDI module
-C\              C/C++ API and examples...
-  BASSMIDI.H      BASSMIDI C/C++ header file
-  BASSMIDI.LIB    BASSMIDI import library
-  BASSMIDI.SLN    Visual Studio solution for examples
-  MAKEFILE        Makefile for examples
-  MAKEFILE.IN     Makefile helper macros
-  X64\
-    BASSMIDI.LIB    64-bit BASSMIDI import library
-  MIDITEST\       MIDI playback example
-    ...
-  SF2PACK\        Soundfont packer
-    ...
-  SYNTH\          Real-time MIDI example
-    ...
-  BIN\            Precompiled examples
-    MIDITEST.EXE
-    SF2PACK.EXE
-    SYNTH.EXE
-VB\             Visual Basic API and examples...
-  BASSMIDI.BAS    BASSMIDI Visual Basic module
-  MIDITEST\       MIDI playback example
-    ...
-DELPHI\         Delphi API and examples...
-  BASSMIDI.PAS    BASSMIDI Delphi unit
-  MIDITEST\       MIDI playback example
-    ...
-  SYNTH\          Real-time MIDI example
-    ...
-
-NOTE: You may need to "Unblock" the BASSMIDI.CHM file in its "Properties" to
-      view it on Windows 7. The documentation can also be viewed online at
-      the BASS website.
-
-NOTE: To run the example EXEs, first you will have to copy BASSMIDI.DLL and
-      BASS.DLL into the same directory as them.
-
-NOTE: To build the examples, you will need to copy the BASS API into the
-      same directory as the BASSMIDI API.
-
-NOTE: The Delphi and VB examples may not always be up to date with the C
-      examples, so the latter should be preferred as references if possible.
-
-macOS version
--------------
-BASSMIDI.TXT    This file
-LIBBASSMIDI.DYLIB  BASSMIDI module
-BASSMIDI.CHM    BASSMIDI documentation
-BASSMIDI.H      BASSMIDI C/C++ header file
-BASSMIDI.XCODEPROJ  Xcode project for examples
-MIDITEST\       MIDI playback example
-  ...
-SF2PACK\        Soundfont packer
-  ...
-SYNTH\          Real-time MIDI example
-  ...
-
-NOTE: To build the examples, you will need to copy the BASS API into the
-      same directory as the BASSMIDI API.
-
-Linux version
--------------
-BASSMIDI.TXT    This file
-LIBBASSMIDI.SO  BASSMIDI module
-BASSMIDI.CHM    BASSMIDI documentation
-BASSMIDI.H      BASSMIDI C/C++ header file
-MAKEFILE        Makefile for examples
-MAKEFILE.IN     Makefile helper macros
-X64\
-  LIBBASSMIDI.SO  64-bit BASSMIDI module
-MIDITEST\       MIDI playback example
-  ...
-SF2PACK\        Soundfont packer
-  ...
-SYNTH\          Real-time MIDI example
-  ...
-
-NOTE: To build the examples, you will need to copy the BASS API into the
-      same directory as the BASSMIDI API.
-
-Android version
----------------
-BASSMIDI.TXT    This file
-BASSMIDI.CHM    BASSMIDI documentation
-LIBS\           BASSMIDI modules
-  ...
-C\              C/C++ API...
-  BASSMIDI.H      BASSMIDI C/C++ header file
-JAVA\COM\UN4SEEN\BASS\
-  BASSMIDI.JAVA   BASSMIDI Java class
-EXAMPLES\       Java examples
-  BUILD.GRADLE    Android Studio build script for examples
-  SETTINGS.GRADLE
-  PROGUARD-BASS.PRO
-  MIDITEST\       MIDI playback example
-    ...
-
-NOTE: To build the examples, you will need to copy the BASS API into the
-      same directory as the BASSMIDI API.
-
-iOS version
------------
-BASSMIDI.TXT    This file
-BASSMIDI.XCFRAMEWORK  BASSMIDI framework
-BASSMIDI.CHM    BASSMIDI documentation
-BASSMIDI.H      BASSMIDI C/C++ header file
-
-
-What's the point?
-=================
-BASSMIDI is an extension to the BASS audio library, enabling the playing of
-MIDI files and custom event sequences, using SF2 (including SF2PACK and SF3)
-and/or SFZ soundfonts to provide the sounds. MIDI input is also supported.
-
-
-Requirements
-============
-BASS 2.4 is required.
-
-
-Using BASSMIDI
-==============
-The MIDI format is used in very much the same way as any of the built-in BASS
-stream formats; simply call the MIDI stream creation function instead of the
-BASS built-in functions. The BASS plugin system (see BASS_PluginLoad) is also
-supported.
-
-SF2 and SFZ soundfonts are used to provide the sounds. There are several
-soundfonts available on the internet, including a couple on the BASS webpage.
-On Windows, the Creative 28MB (28MBGM.SF2), 8MB (CT8MGM.SF2), 4MB (CT4MGM.SF2),
-or 2MB (CT2MGM.SF2) soundfont will be used by default when present in the
-Windows system directory.
-
-The usage information in the BASS.TXT file (from the BASS package) is also
-applicable to BASSMIDI and other add-ons.
-
-TIP: The BASSMIDI.CHM file should be put in the same directory as the BASS.CHM
-     file, so that the BASSMIDI documentation can be accessed from within the
-     BASS documentation.
-
-iOS version
------------
-The CoreMIDI framework is required for MIDI input, so that should be added to
-the "Link Binary With Libraries" build phase in Xcode.
-
-
-Latest Version
-==============
-The latest versions of BASSMIDI & BASS can be found at the BASS website:
-
-	www.un4seen.com
-
-
-Licence
-=======
-BASSMIDI is free to use with BASS.
-
-TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, BASSMIDI IS PROVIDED
-"AS IS", WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
-INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY
-AND/OR FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS SHALL NOT BE HELD
-LIABLE FOR ANY DAMAGE THAT MAY RESULT FROM THE USE OF BASSMIDI. YOU USE
-BASSMIDI ENTIRELY AT YOUR OWN RISK.
-
-Usage of BASSMIDI indicates that you agree to the above conditions.
-
-All trademarks and other registered names contained in the BASSMIDI
-package are the property of their respective owners.
-
-
-History
-=======
-These are the major (and not so major) changes at each version stage.
-There are of course bug fixes and other little improvements made along
-the way too! To make upgrading simpler, all functions affected by a
-change to the BASSMIDI interface are listed.
-
-2.4.14 - 3/5/2022
------------------
-* Support for Key On Velocity to startAddrsOffset/modEnvToFilterFc and CC21-24 to initialFilterFc/
-  initialAttenuation/attackVolEnv/decayVolEnv/releaseVolEnv/releaseModEnv/modEnvToFilterFc SF2 modulators
-	BASS_MIDI_FontInit/User
-* Support for all Key On Velocity to initialAttenuation SF2 modulator curve types
-	BASS_MIDI_FontInit/User
-* Support for SF3 (compressed SF2) soundfonts
-	BASS_MIDI_FontInit/User
-* Soundfont flag setting/retrieval
-	BASS_MIDI_FontFlags
-* Retrieval of currently loading samples
-	BASS_CONFIG_MIDI_SAMPLELOADING (BASS_GetConfig option)
-* Channel-specific soundfont configuration
-	BASS_MIDI_FONT_EX2 (BASS_MIDI_StreamSetFonts/GetFonts flag)
-	BASS_MIDI_FONTEX2 structure
-* MIDI port meta-event support (for more than 16 channels)
-	BASS_MIDI_StreamCreateFile/User/URL
-	BASS_MIDI_StreamEvents
-	BASS_MIDI_ConvertEvents
-* Asynchronous processing of live events
-	BASS_MIDI_ASYNC (BASS_MIDI_StreamCreate/Events/File/User/URL flag)
-	BASS_MIDI_EVENTS_ASYNC (BASS_MIDI_StreamEvents flag)
-	BASS_MIDI_EVENTS_FLUSH (BASS_MIDI_StreamEvents flag)
-	SYNTH example updated
-* Filtering of live events
-	BASS_MIDI_EVENTS_FILTER (BASS_MIDI_StreamEvents flag)
-* Improved reverb effect
-* Reverb/chorus levels raised (closer to Roland/Yamaha levels)
-* Current reverb/chorus type retrieval
-	MIDI_EVENT_REVERB_MACRO (BASS_MIDI_StreamGetEvent)
-	MIDI_EVENT_CHORUS_MACRO (BASS_MIDI_StreamGetEvent)
-* Treat soundfont reverb/chorus levels as minimums
-	BASS_MIDI_FONT_MINFX (BASS_MIDI_FontInit/User/Flags flag)
-* Default per-drum reverb/chorus levels now apply in all modes and can be disabled
-	BASS_MIDI_NODRUMPARAM (BASS_MIDI_StreamCreate/Events/File/User/URL flag)
-* Default drum channel configuration
-	BASS_EVENT_DEFDRUMS (BASS_MIDI_StreamEvent/s and BASS_MIDI_StreamCreateEvents)
-* Support for master tuning
-	MIDI_EVENT_MASTER_FINETUNE/COARSETUNE (BASS_MIDI_StreamEvent/s)
-* Omni-on/off (CC124/125) are treated as all-notes-off (CC123)
-	BASS_MIDI_StreamCreateFile/User/URL
-	BASS_MIDI_StreamEvents
-	BASS_MIDI_ConvertEvents
-* 16 point sinc interpolation support on ARM platforms with NEON
-	BASS_ATTRIB_MIDI_SRC (BASS_ChannelSetAttribute option)
-* Version number retrieval
-	BASS_MIDI_GetVersion
-* BASS_CONFIG_MIDI_SFZHEAD value changed (was same as BASS_CONFIG_MIDI_SAMPLEREAD)
-	BASS_CONFIG_MIDI_SFZHEAD (BASS_SetConfigPtr option)
-* MIDI implementation chart added to documentation
-
-2.4.13 - 16/9/2020
-------------------
-* Vibrato rate/depth/delay adjustment
-	MIDI_EVENT_VIBRATO_RATE/DEPTH/DELAY (BASS_MIDI_StreamEvent/s)
-* Support for Key Number to initialAttenuation/initialFilterFc/pan and Key On Velocity
-  to decayVolEnv/releaseVolEnv SF2 modulators
-	BASS_MIDI_FontInit/User
-* Support for amp_keycenter/amp_keytrack/ampeg_vel2release/delay_beats/fil_keycenter/
-  fil_keytrack/locc67/hicc67/pan_keycenter/pan_keytrack/sw_default/sw_last/sw_lokey/
-  sw_lolast/sw_hikey/sw_hilast SFZ opcodes
-	BASS_MIDI_FontInit/User
-* Support for global and master headers and #define directive in SFZ files
-	BASS_MIDI_FontInit/User
-* SFZ files share memory for common sample files
-	BASS_MIDI_FontInit/User
-* Partial sample loading and unloading
-	BASS_MIDI_FontLoadEx
-	SYNTH example updated
-* Non-interpolated resampling option
-	BASS_ATTRIB_MIDI_SRC (BASS_ChannelSetAttribute option)
-* Tempo modification attribute
-	BASS_ATTRIB_MIDI_SPEED (BASS_ChannelSetAttribute option)
-	MIDITEST example updated
-* Mix level control
-	BASS_ATTRIB_MIDI_VOL (BASS_ChannelSetAttribute option)
-* Reverb level modification
-	BASS_ATTRIB_MIDI_REVERB (BASS_ChannelSetAttribute option)
-* Global SFZ headers
-	BASS_CONFIG_MIDI_SFZHEAD (BASS_SetConfigPtr option)
-* Linear volume envelopes option
-	BASS_MIDI_FONT_LINDECVOL (BASS_MIDI_FontInit/User flag)
-* Disabling of sample ramping-in
-	BASS_MIDI_FONT_NORAMPIN (BASS_MIDI_FontInit/User flag)
-* Disabling of Creative/SoundBlaster hardware limit emulation
-	BASS_MIDI_FONT_NOLIMITS	(BASS_MIDI_FontInit flag)
-* Duplicate soundfonts will be reloaded instead of shared if modified in the meantime
-	BASS_MIDI_FontInit
-* Memory-mapped support for default soundfont option
-	BASS_CONFIG_MIDI_DEFFONT
-* Retrieval of total memory usage for sample data
-	BASS_CONFIG_MIDI_SAMPLEMEM (BASS_GetConfig option)
-* Total sample data size available for SFZ files
-	BASS_MIDI_FontGetInfo
-* Adjustable asynchronous sample loading chunks
-	BASS_CONFIG_MIDI_SAMPLEREAD (BASS_SetConfig option)
-* CPU usage limiting is enabled by default during playback
-	BASS_MIDI_StreamCreate/Events/File/User/URL
-	BASS_ATTRIB_MIDI_CPU (BASS_ChannelSetAttribute option)
-* Option to limit sample loading waiting without killing voices
-	BASS_ATTRIB_MIDI_CPU (BASS_ChannelSetAttribute option)
-* Tick-based timing for realtime event streams
-	BASS_MIDI_StreamCreate
-	BASS_MIDI_StreamEvents
-	BASS_ATTRIB_MIDI_PPQN (BASS_ChannelSetAttribute option)
-* 48000 Hz soundfont data encoding option
-	BASS_MIDI_PACK_48KHZ (BASS_MIDI_FontPack flag)
-* macOS examples rewritten in Objective-C/Cocoa
-
-2.4.12 - 9/11/2018
-------------------
-* Support for more than 16 MIDI channels in custom event sequences
-	BASS_MIDI_StreamCreateEvents
-* Absolute timing option for custom events
-	BASS_MIDI_EVENTS_ABSTIME (BASS_MIDI_StreamEvents flag)
-* Retrieval of note-on events
-	MIDI_EVENT_NOTES (BASS_MIDI_StreamGetEvents/Ex filter)
-* Soundfont config can be modified without stopping currently playing notes
-	BASS_MIDI_StreamSetFonts
-* Memory-mapped soundfonts can be preloaded/mapped
-	BASS_MIDI_FontLoad
-* Support for Key On Velocity to initialAttenuation SF2 modulators
-	BASS_MIDI_FontInit/User
-* Linear attack phase option for SF2 modulation envelopes
-	BASS_MIDI_FONT_LINATTMOD (BASS_MIDI_FontInit/User flag)
-* The attack phase of SFZ pitch/filter envelopes is now linear instead of convex
-* Support for trigger/rt_decay/delay/amplfo_fade/fillfo_fade/pitchlfo_fade/pitch_random/
-  xfin_lokey/xfin_hikey/xfout_lokey/xfout_hikey/xf_keycurve/xfin_lovel/xfin_hivel/
-  xfout_lovel/xfout_hivel/xf_velcurve SFZ opcodes
-	BASS_MIDI_FontInit/User
-* Support for separate amplifier/filter/pitch LFOs in SFZ
-	BASS_MIDI_FontInit/User
-* Support for UTF-8 sample SFZ opcodes on Windows (already on other platforms)
-	BASS_MIDI_FontInit/User
-* Support for #include directive in SFZ files
-	BASS_MIDI_FontInit
-* SFZ files are no longer kept open/locked after being loaded
-	BASS_MIDI_FontInit
-* Samples given more time to load asynchronously when CPU usage is low
-	BASS_ATTRIB_MIDI_CPU (BASS_ChannelSetAttribute option)
-* BASS_MIDI_SINCINTER flag deprecated in favour of BASS_ATTRIB_MIDI_SRC attribute
-	BASS_MIDI_StreamCreate/Events/File/User/URL
-* Smoother low-pass filter activation and deactivation
-* Fix for transpose/tune SFZ opcodes with encoded samples
-
-2.4.11 - 30/3/2017
-------------------
-* Event modification/filtering
-	BASS_MIDI_StreamSetFilter
-	MIDIFILTERPROC
-* Simpler tempo modification
-	MIDI_EVENT_SPEED (BASS_MIDI_StreamEvent)
-	MIDITEST example updated
-* Checking whether individual notes are playing
-	MIDI_EVENT_NOTE (BASS_MIDI_StreamGetEvent)
-* Retrieval of total number of notes playing in a channel
-	MIDI_EVENT_NOTES (BASS_MIDI_StreamGetEvent)
-* Retrieval of currently active voices in a channel
-	MIDI_EVENT_VOICES (BASS_MIDI_StreamGetEvent)
-* Retrieval of currently in use presets
-	BASS_MIDI_StreamGetPreset
-* SFZ filenames are used as preset names
-	BASS_MIDI_FontGetPreset
-* Support for loop info in FLAC samples used with SFZ (requires BASSFLAC 2.4.3)
-* Faster loading of very large MIDI files
-	BASS_MIDI_StreamCreateFile/User/URL
-* Faster unfiltered event counting
-	BASS_MIDI_StreamGetEvents/Ex
-	BASS_MIDI_ConvertEvents
-* 24-bit paramater passed to MIDI_EVENT_TEMPO event sync callbacks
-	BASS_SYNC_MIDI_EVENT (BASS_ChannelSetSync type)
-* When getting the number of events, only those in the specified range are counted
-	BASS_MIDI_StreamGetEventsEx
-* Invalid event types in custom sequences will give an error instead of being ignored
-	BASS_MIDI_StreamCreateEvents
-
-2.4.10 - 8/12/2016
-------------------
-* 16 point sinc interpolation option
-	BASS_ATTRIB_MIDI_SRC (BASS_ChannelSetAttribute option)
-* Support for lorand/hirand/locc1/hicc1/locc64/hicc64/off_mode/default_path SFZ opcodes
-	BASS_MIDI_FontInit/User
-* Support for Key On Velocity to initialFilterFc/attackVolEnv SF2 modulators
-	BASS_MIDI_FontInit/User
-* Conversion of raw MIDI data to BASS_MIDI_EVENT
-	BASS_MIDI_ConvertEvents
-* Modulation (CC1) destination control
-	MIDI_EVENT_MOD_VIBRATO/PITCH/FILTER/VOLUME (BASS_MIDI_StreamEvent/s)
-	MIDI_EVENT_MODRANGE superseded by MIDI_EVENT_MOD_VIBRATO
-* Sostenuto
-	MIDI_EVENT_SOSTENUTO (BASS_MIDI_StreamEvent/s)
-* Legato channel mode
-	MIDI_EVENT_MODE (BASS_MIDI_StreamEvent)
-* Partial retrieval of events
-	BASS_MIDI_StreamGetEventsEx
-* Bulk MIDI state retrieval/setting
-	BASS_ATTRIB_MIDI_STATE (BASS_ChannelGet/SetAttributeEx option)
-* Support for delaying custom events, including delta-time info in raw MIDI data
-	BASS_MIDI_EVENTS_TIME (BASS_MIDI_StreamEvents flag)
-* Cancellation of pending custom events
-	BASS_MIDI_EVENTS_CANCEL (BASS_MIDI_StreamEvents flag)
-* Marker for the start of each track in SMF2 files
-	BASS_MIDI_MARK_TRACKSTART (BASS_MIDI_StreamGetMark type)
-* Ignoring of soundfont effect levels
-	BASS_MIDI_FONT_NOFX (BASS_MIDI_FontInit/Ex flag)
-* Maximum voice limit increased to 100000
-	BASS_CONFIG_MIDI_VOICES (BASS_SetConfig option)
-	BASS_ATTRIB_MIDI_VOICES (BASS_ChannelSetAttribute option)
-* Unicode support for default soundfont option on Windows
-	BASS_CONFIG_MIDI_DEFFONT
-* BASS_CONFIG_UNICODE option support for input device names
-	BASS_MIDI_InGetDeviceInfo
-* Improved seeking with MIDI files that have events for a channel in multiple tracks
-	BASS_ChannelSetPosition
-* Fix for 2GB size limit when unpacking a soundfont on Windows
-	BASS_MIDI_FontUnpack
-
-2.4.9 - 4/12/2014
------------------
-* SFZ soundfont support
-	BASS_MIDI_FontInit/User
-* Support for XG drums in bank 127 of SF2 soundfonts
-	BASS_MIDI_FONT_XGDRUMS (BASS_MIDI_FontInit/Ex flag)
-* Key pressure/aftertouch support
-	MIDI_EVENT_KEYPRES (BASS_MIDI_StreamEvent/s)
-	MIDI_EVENT_KEYPRES_VIBRATO/PITCH/FILTER/VOLUME (BASS_MIDI_StreamEvent/s)
-* 3rd effect path for custom processing
-	BASS_MIDI_CHAN_USERFX (BASS_MIDI_StreamGetChannel option)
-	MIDI_EVENT_USERFX (BASS_MIDI_StreamEvent/s)
-	MIDI_EVENT_USERFX_LEVEL (BASS_MIDI_StreamEvent/s)
-	MIDI_EVENT_USERFX_REVERB (BASS_MIDI_StreamEvent/s)
-	MIDI_EVENT_USERFX_CHORUS (BASS_MIDI_StreamEvent/s)
-* Custom reverb/chorus effect processing
-	BASS_MIDI_CHAN_CHORUS/REVERB (BASS_MIDI_StreamGetChannel options)
-* Custom channel processing output routed to reverb/chorus/custom effects
-	BASS_MIDI_StreamGetChannel
-* Default drum reverb/chorus levels set to XG spec in XG mode (GS/GM modes too)
-	MIDI_EVENT_DRUM_REVERB/CHORUS (BASS_MIDI_StreamEvent/s)
-* Decay time event
-	MIDI_EVENT_DECAY (BASS_MIDI_StreamEvent/s)
-* Support for up to 65536 presets per bank
-	BASS_MIDI_StreamSetFonts
-	MIDI_EVENT_PROGRAM (BASS_MIDI_StreamEvent/s)
-* Input ports to receive MIDI data from other software on Linux
-	BASS_MIDI_InInit
-	BASS_CONFIG_MIDI_IN_PORTS (BASS_SetConfig option)
-	SYNTH example updated
-* Single note releasing when there are overlapping instances of the same note
-	BASS_MIDI_NOTEOFF1 (BASS_MIDI_StreamCreateFile/User/URL flag)
-* Ignoring of system resets with unchanged mode
-	BASS_MIDI_NOSYSRESET (BASS_MIDI_StreamCreateFile/User/URL flag)
-	MIDI_EVENT_SYSTEM (BASS_MIDI_StreamEvent/s)
-* Disabling of running status
-	BASS_MIDI_EVENTS_NORSTATUS (BASS_MIDI_StreamEvents flag)
-* Maximum voice limit increased to 1000
-	BASS_CONFIG_MIDI_VOICES (BASS_SetConfig option)
-	BASS_ATTRIB_MIDI_VOICES (BASS_ChannelSetAttribute option)
-* Reduction of 24-bit data to 16-bit when packing soundfont samples
-	BASS_MIDI_PACK_16BIT (BASS_MIDI_FontPack flag)
-* Support for remaining SF2 generators: fixed key, fixed velocity, key to vol/mod envelope hold/decay
-* Fix for multi-track custom event sequence stream creation
-	BASS_MIDI_StreamCreateEvents
-
-2.4.8 - 2/5/2013
-----------------
-* User file soundfont loading
-	BASS_MIDI_FontInitUser
-* Retrieval of all of a soundfont's preset numbers
-	BASS_MIDI_FontGetPresets
-* More flexible soundfont preset mapping
-	BASS_MIDI_FONT_EX (BASS_MIDI_StreamSetFonts/GetFonts flag)
-	BASS_MIDI_FONTEX structure
-* Bank LSB controller support
-	MIDI_EVENT_BANK_LSB (BASS_MIDI_StreamEvent/s)
-	BASS_MIDI_FONTEX structure
-* Modulation depth range control
-	MIDI_EVENT_MODRANGE (BASS_MIDI_StreamEvent/s)
-* Channel pressure destination control
-	MIDI_EVENT_CHANPRES_VIBRATO/PITCH/FILTER/VOLUME (BASS_MIDI_StreamEvent/s)
-* Unhandled controller event
-	MIDI_EVENT_CONTROL (BASS_MIDI_StreamEvent/s)
-* Reverb send level default changed to 40 (was 0)
-	MIDI_EVENT_REVERB (BASS_MIDI_StreamEvent/s)
-* Retrieval of events from all tracks at once
-	BASS_MIDI_StreamGetEvents
-* Copyright/instrument/track name markers
-	BASS_MIDI_MARK_COPY (BASS_MIDI_StreamGetMark type)
-	BASS_MIDI_MARK_INST (BASS_MIDI_StreamGetMark type)
-	BASS_MIDI_MARK_TRACK (BASS_MIDI_StreamGetMark type)
-* Retrieval of all markers at once
-	BASS_MIDI_StreamGetMarks
-* New sync type that supports all marker types
-	BASS_SYNC_MIDI_MARK (BASS_ChannelSetSync type)
-* Non-removal of empty space at the end of a MIDI file
-	BASS_MIDI_NOCROP (BASS_MIDI_StreamCreateFile/User/URL flag)
-* Omission of a WAVE header when packing soundfont samples
-	BASS_MIDI_PACK_NOHEAD (BASS_MIDI_FontPack flag)
-* Streams created via the plugin system use the output device's sample rate
-	BASS_StreamCreateFile/etc
-* Automatic BASS_UNICODE flag use in C++ and Delphi
-	BASS_MIDI_StreamCreateFile/URL
-	BASS_MIDI_FontInit/Pack/Unpack
-
-2.4.7 - 29/6/2012
------------------
-* Custom event sequence streams
-	BASS_MIDI_StreamCreateEvents	
-* Sinc interpolated sample mixing
-	BASS_MIDI_SINCINTER (BASS_MIDI_StreamCreate/Events/File/User/URL flag)
-* Asynchronous sample loading
-	BASS_ATTRIB_MIDI_CPU (BASS_ChannelSetAttribute option)
-* Preset unloading
-	BASS_MIDI_FontUnload
-* Note stopping without sustain/decay
-	BASS_EVENT_NOTE (BASS_MIDI_StreamEvent/s)
-* Syncing on all event types
-	BASS_SYNC_MIDI_EVENT (BASS_ChannelSetSync type)
-* Marker tick position retrieval
-	BASS_MIDI_MARK_TICK (BASS_MIDI_StreamGetMark flag)
-* Maximum voice limit increased to 500
-	BASS_CONFIG_MIDI_VOICES (BASS_SetConfig option)
-	BASS_ATTRIB_MIDI_VOICES (BASS_ChannelSetAttribute option)
-* Default voice limit raised to 40 on Android/iOS
-	BASS_CONFIG_MIDI_VOICES (BASS_SetConfig option)
-* Active voice count retrieval
-	BASS_ATTRIB_MIDI_VOICES_ACTIVE (BASS_ChannelGetAttribute option)
-* Use of the device's current output rate
-	BASS_MIDI_StreamCreate/Events/File/User/URL
-* Memory-mapped soundfont loading
-	BASS_MIDI_FONT_MMAP (BASS_MIDI_FontInit flag)
-* Fix for applying multiple events in BASS_MIDI_EVENTS_STRUCT mode
-	BASS_MIDI_StreamEvents
-* Marker sync compatibility (with mixer/splitter/tempo/reverse streams) fix
-	BASS_SYNC_MIDI_MARKER/CUE/LYRIC (BASS_ChannelSetSync types)
-* MIDI sysex input compatibility fix for some drivers on Windows
-	MIDIINPROC
-
-2.4.6 - 30/3/2011
------------------
-* MIDI input device support
-	BASS_MIDI_InGetDeviceInfo
-	BASS_MIDI_InInit
-	BASS_MIDI_InFree
-	BASS_MIDI_InStart
-	BASS_MIDI_InStop
-	MIDIINPROC
-	SYNTH example updated
-* Multiple event processing including support for raw MIDI data
-	BASS_MIDI_StreamEvents
-* CPU usage limiting
-	BASS_ATTRIB_MIDI_CPU (BASS_ChannelSetAttribute option)
-* Scale/octave tuning
-	MIDI_EVENT_SCALETUNING (BASS_MIDI_StreamEvent/s)
-* Soft pedal event
-	MIDI_EVENT_SOFT (BASS_MIDI_StreamEvent/s)
-* Random panning
-	MIDI_EVENT_PAN (BASS_MIDI_StreamEvent/s)
-* System reset event
-	MIDI_EVENT_SYSTEM/EX (BASS_MIDI_StreamEvent/s)
-* Resetting of overridden drum key pan/reverb/chorus back to normal
-	MIDI_EVENT_DRUM_PAN/REVERB/CHORUS (BASS_MIDI_StreamEvent)
-* Retrieval of drum key event values
-	BASS_MIDI_StreamGetEvent
-* All events initialized to a MIDI file's 1st tick values
-	BASS_MIDI_StreamGetEvent
-* Adjustable MIDI channel count
-	BASS_ATTRIB_MIDI_CHANS (BASS_ChannelSetAttribute option)
-* Adjustable voice limit
-	BASS_ATTRIB_MIDI_VOICES (BASS_ChannelSetAttribute option)
-* Preloaded presets are not automatically compacted
-	BASS_MIDI_FontLoad
-	BASS_CONFIG_MIDI_COMPACT (BASS_SetConfig option)
-* Multiple instances of a soundfont
-	BASS_MIDI_FontInit
-* Xcode examples project added for OSX
-
-2.4.5 - 8/2/2010
-----------------
-* Key signature retrieval
-	BASS_MIDI_MARK_KEYSIG (BASS_MIDI_StreamGetMark type)
-	BASS_SYNC_MIDI_KEYSIG (BASS_ChannelSetSync type)
-* Tempo event initialized to MIDI file's 1st tick value
-	MIDI_EVENT_TEMPO (BASS_MIDI_StreamGetEvent)
-* UTF-16 support on OSX
-	BASS_UNICODE (BASS_MIDI_StreamCreateFile/BASS_MIDI_FontInit/Pack/Unpack flag)
-
-2.4.4 - 24/8/2009
------------------
-* Attack & release time events
-	MIDI_EVENT_ATTACK/RELEASE (BASS_MIDI_StreamEvent)
-* Drum key level NRPN event
-	MIDI_EVENT_DRUM_LEVEL (BASS_MIDI_StreamEvent)
-* MIDI file event retrieval
-	BASS_MIDI_StreamGetEvents
-* Time signature retrieval
-	BASS_MIDI_MARK_TIMESIG (BASS_MIDI_StreamGetMark type)
-	BASS_SYNC_MIDI_TIMESIG (BASS_ChannelSetSync type)
-* Default soundfont configuration
-	BASS_CONFIG_MIDI_DEFFONT (BASS_SetConfig option)
-
-2.4.3 - 19/3/2009
------------------
-* Possibility of applying DSP/FX to individual MIDI channels
-	BASS_MIDI_StreamGetChannel
-* Per-track volume control
-	BASS_ATTRIB_MIDI_TRACK_VOL (BASS_ChannelSetAttribute option)
-* Support for all tracks in format 2 MIDI files
-	BASS_MIDI_StreamCreateFile/User/URL
-
-2.4.2 - 28/10/2008
-------------------
-* Decaying of old sound when seeking
-	BASS_MIDI_DECAYSEEK (BASS_MIDI_StreamCreateFile/User/URL flag)
-	MIDITEST example updated (C version)
-* End decaying now also applies when looping
-	BASS_MIDI_DECAYEND (BASS_MIDI_StreamCreateFile/User/URL flag)
-* Support for 28MBGM.SF2 and CT8MGM.SF2 as default soundfonts
-
-2.4.1 - 9/7/2008
-----------------
-* Ticks-per-beat retrieval
-	BASS_ATTRIB_MIDI_PPQN (BASS_ChannelGetAttribute option)
-
-2.4 - 2/4/2008
---------------
-* Tick-based positioning
-	BASS_POS_MIDI_TICK (BASS_ChannelGetLength/GetPosition/SetPosition mode)
-	BASS_SYNC_MIDI_TICK (BASS_ChannelSetSync type)
-* Preset name retrieval
-	BASS_MIDI_FontGetPreset
-* Text markers
-	BASS_MIDI_MARK_TEXT (BASS_MIDI_StreamGetMark type)
-	BASS_SYNC_MIDI_TEXT (BASS_ChannelSetSync type)
-* Individual marker retrieval
-	BASS_MIDI_StreamGetMark
-	BASS_MIDI_StreamGetMarks *removed*
-* Marker index passed to marker sync callbacks
-	BASS_SYNC_MIDI_MARKER/CUE/LYRIC
-* Use of BASS_Init sample rate
-	BASS_MIDI_StreamCreate/File/User/URL
-* Support for updated user file stream system
-	BASS_MIDI_StreamCreateFileUser
-* 64-bit file positioning
-	BASS_MIDI_StreamCreateFile
-* Callback "user" parameters changed to pointers
-	BASS_MIDI_StreamCreateURL
-	BASS_MIDI_StreamCreateFileUser
-
-2.3.0.3 - 10/7/2007
--------------------
-* Syncing on events
-	BASS_SYNC_MIDI_EVENT (BASS_ChannelSetSync type)
-
-2.3.0.2 - 26/2/2007
--------------------
-* Reverb and chorus
-	MIDI_EVENT_REVERB/CHORUS (BASS_MIDI_StreamEvent)
-	MIDI_EVENT_REVERB_TIME/DELAY/LOCUTOFF/HICUTOFF/LEVEL (BASS_MIDI_StreamEvent)
-	MIDI_EVENT_CHORUS_DELAY/DEPTH/RATE/FEEDBACK/LEVEL/REVERB (BASS_MIDI_StreamEvent)
-	BASS_MIDI_NOFX (BASS_MIDI_StreamCreate/File/User/URL flag)
-* Resonant low-pass filters
-	MIDI_EVENT_CUTOFF/RESONANCE (BASS_MIDI_StreamEvent)
-* Portamento
-	MIDI_EVENT_PORTAMENTO/TIME/NOTE (BASS_MIDI_StreamEvent)
-* Fine-tuning
-	MIDI_EVENT_FINETUNE/COARSETUNE (BASS_MIDI_StreamEvent)
-* Drum key specific parameters
-	MIDI_EVENT_DRUM_FINETUNE/COARSETUNE/PAN/REVERB/CHORUS/CUTOFF/RESONANCE (BASS_MIDI_StreamEvent)
-* Support for mono channel mode
-	MIDI_EVENT_MODE (BASS_MIDI_StreamEvent)
-* Support for master volume
-	MIDI_EVENT_MASTERVOL (BASS_MIDI_StreamEvent)
-* Channel level control
-	MIDI_EVENT_MIXLEVEL (BASS_MIDI_StreamEvent)
-* Channel transposing
-	MIDI_EVENT_TRANSPOSE (BASS_MIDI_StreamEvent)
-* Retrieval of current event values
-	BASS_MIDI_StreamGetEvent
-* Soundfont volume control
-	BASS_MIDI_FontSetVolume/GetVolume
-* Track number added to markers and syncs
-	BASS_MIDI_MARK (track member)
-	BASS_SYNC_MIDI_MARKER/CUE/LYRIC
-
-2.3.0.1 - 1/12/2006
--------------------
-* Optionally apply matching soundfonts to all banks
-	BASS_CONFIG_MIDI_AUTOFONT (BASS_SetConfig option)
-* Support for 0 length notes
-
-2.3 - 14/11/2006
-----------------
-* First release
-
-
-Bug reports, Suggestions, Comments, Enquiries, etc
-==================================================
-If you have any of the aforementioned please visit the BASS forum at the
-website.
-

+ 0 - 43
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bassmidi.xcframework/Info.plist

@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>AvailableLibraries</key>
-	<array>
-		<dict>
-			<key>LibraryIdentifier</key>
-			<string>ios-arm64_i386_x86_64-simulator</string>
-			<key>LibraryPath</key>
-			<string>libbassmidi.a</string>
-			<key>SupportedArchitectures</key>
-			<array>
-				<string>arm64</string>
-				<string>i386</string>
-				<string>x86_64</string>
-			</array>
-			<key>SupportedPlatform</key>
-			<string>ios</string>
-			<key>SupportedPlatformVariant</key>
-			<string>simulator</string>
-		</dict>
-		<dict>
-			<key>LibraryIdentifier</key>
-			<string>ios-arm64_armv7_armv7s</string>
-			<key>LibraryPath</key>
-			<string>libbassmidi.a</string>
-			<key>SupportedArchitectures</key>
-			<array>
-				<string>arm64</string>
-				<string>armv7</string>
-				<string>armv7s</string>
-			</array>
-			<key>SupportedPlatform</key>
-			<string>ios</string>
-		</dict>
-	</array>
-	<key>CFBundlePackageType</key>
-	<string>XFWK</string>
-	<key>XCFrameworkFormatVersion</key>
-	<string>1.0</string>
-</dict>
-</plist>

BIN
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bassmidi.xcframework/ios-arm64_armv7_armv7s/libbassmidi.a


BIN
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/BASSMidiPlayer/Source/bassmidi.xcframework/ios-arm64_i386_x86_64-simulator/libbassmidi.a


+ 0 - 20
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Controller/KSCloudViewController.h

@@ -1,20 +0,0 @@
-//
-//  KSCloudViewController.h
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/8.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import "BaseViewController.h"
-#import "CloudSongMessageModel.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface KSCloudViewController : BaseViewController
-
-- (void)configMessage:(CloudSongMessageModel *)songMessage;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 2219
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Controller/KSCloudViewController.m

@@ -1,2219 +0,0 @@
-//
-//  KSCloudViewController.m
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/8.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import "KSCloudViewController.h"
-#import <KSToolLibrary/UIDevice+TFDevice.h>
-#import "AppDelegate.h"
-#import "StaffImageDisplayView.h"
-#import "KYSourceParseManager.h"
-#import <KSToolLibrary/MidiPlayerEngine.h>
-
-#import "CloudControlButton.h"
-#import "KSCloudSettingView.h"
-#import "KSXMLInfoParse.h"
-#import "ScoreAnimationView.h"
-#import "EvaluateResultAlert.h"
-#import "NoWiredTipsAlert.h"
-#import "LFPopupMenu.h"
-#import "KSSliderView.h"
-#import "SoundCheckView.h"
-#import "KSBaseWKWebViewController.h"
-#import <SSZipArchive/SSZipArchive.h>
-#import "CloudHelpView.h"
-#import "CloudFeedbackView.h"
-#import <KSToolLibrary/KSAudioSessionManager.h>
-#import <CloudAccompanyLibrary/KSCloudBeatView.h>
-
-#import <KSToolLibrary/RecordCheckManager.h>
-#import <KSToolLibrary/KSAQRecordManager.h>
-#import <KSToolLibrary/KSWebSocketManager.h>
-#import <CloudAccompanyLibrary/KSVideoRecordManager.h>
-
-#import "TrackChooseView.h"
-
-#define PositionRate (12)    // 图片上点的位置和位置文件的系数
-
-#define Left_Space (37)
-#define Button_Width (34)
-#define Button_Height (60)
-#define Button_Space (20)
-
-#define BACKVIEW_ALPHA (0.6f)
-typedef NS_ENUM(NSInteger, BUTTON_TAG) {
-    BUTTON_TAG_EVALUATING = 1000, // 评测
-    BUTTON_TAG_SELECT,  // 选段
-    BUTTON_TAG_PLAY,    // 播放
-    BUTTON_TAG_SWITCH,  // 切换
-    BUTTON_TAG_REPEAT,  // 重播
-    BUTTON_TAG_SPEED,   // 调速
-    BUTTON_TAG_SETTING, // 设置
-};
-
-typedef NS_ENUM(NSInteger,COLOR_DISPLAYTYPE) {
-    COLOR_DISPLAYTYPE_NOMAL,
-    COLOR_DISPLAYTYPE_PROTECT,
-};
-
-@interface KSCloudViewController ()<PlayerEngineDelegate,KSAQRecordManagerDelegate,KSSliderDelegate,KSAudioSessionManagerDelegate>
-
-@property (nonatomic, strong) KSAudioSessionManager *audioSessionManager;
-
-@property (nonatomic, assign) MetronomeType beatType;
-
-@property (nonatomic, assign) BOOL keepOrientation;
-
-@property (nonatomic, strong) UIView *backView;
-
-@property (nonatomic, strong) UIView *bgColorView; // 容器颜色视图
-
-@property (nonatomic, assign) COLOR_DISPLAYTYPE bgColorType; // 容器颜色类型
-
-@property (nonatomic, strong) UIScrollView *displayScrollView;
-
-@property (nonatomic, strong) UIButton *helpButton; // 帮助按钮
-
-@property (nonatomic, strong) KSSliderView *sliderView;
-
-@property (nonatomic, assign) BOOL scorllEnable;  // 是否能滑动
-
-@property (nonatomic, strong) NSMutableArray *pageArray;
-
-@property (nonatomic, strong) KYSourceParseManager *manager;
-
-@property (nonatomic, assign) CGFloat scaleRate;
-
-@property (nonatomic, assign) CGFloat pageViewHeight;
-
-@property (nonatomic, assign) BOOL isChooseMeasure; // 是否小节选择模式
-
-@property (nonatomic, assign) NSInteger startMeasure;
-
-@property (nonatomic, assign) NSInteger endMeasure;
-
-@property (nonatomic, strong) UIView *cursorView;  // 光标
-
-@property (nonatomic, strong) UIButton *evaluateButton; // 评测按钮
-
-@property (nonatomic, assign) BOOL isEvaluating;  // 是否开启评测模式
-
-@property (nonatomic, strong) MidiPlayerEngine *playerEngine; // player
-
-@property (nonatomic, strong) UIView *headView;
-
-@property (nonatomic, assign) NSInteger lastPlayNodeIndex; // 上次播放的音符序号
-
-@property (nonatomic, strong) NSString *songPath; // 音频文件路径
-
-@property (nonatomic, strong) NSString *songName;  // 曲目名称
-
-@property (nonatomic, assign) BOOL isPlaying; // 是否正在播放的状态
-
-@property (nonatomic, assign) BOOL isNeedRepeat; // 是否需要重复
-
-@property (nonatomic, assign) BOOL soundCheckOn; // 是否校音
-
-@property (nonatomic, assign) BOOL showFinger;   // 显示指法开关
-
-@property (nonatomic, assign) BOOL needShowFinger;   // 是否需要显示指法
-
-@property (nonatomic, assign) BOOL cameraOn;     // 是否开启摄像头
-
-@property (nonatomic, assign) BOOL eyeShieldOn;   // 护眼模式是否开启
-
-@property (nonatomic, assign) BOOL saveVideo;     // 是否保存视频
-
-@property (nonatomic, strong) NSString *level;   // 评测级别
-
-@property (nonatomic, assign) BOOL accompanyOn;   // 是否开启伴奏
-
-@property (nonatomic, assign) NSInteger currentSpeed; // 当前速度
-// 是否发送了musicXML信息
-@property (nonatomic, assign) BOOL hasSendStartMessage;
-
-@property (nonatomic, strong) KSAQRecordManager *AQManager;
-
-@property (nonatomic, strong) KSWebSocketManager *socketManager;
-
-@property (nonatomic, strong) NSMutableDictionary *evaluatParm;
-
-// 评测开始时发送recordStart消息的标识
-@property (nonatomic, assign) BOOL isCompareStart;
-// 校音开始时发送 checkStart消息标识
-@property (nonatomic, assign) BOOL isSoundCheckStart;
-
-// 自定义UI控件容器
-@property (nonatomic, strong) UIView *viewContainer;
-
-@property (nonatomic, strong) KSVideoRecordManager *videoRecordManager;
-
-@property (nonatomic, strong) NSMutableArray *nodeArray;
-
-@property (nonatomic, assign) NSInteger recordId;
-
-@property (nonatomic, strong) EvaluateResultAlert *resultAlert;
-
-@property (nonatomic, strong) NoWiredTipsAlert *wiredAlert;
-
-@property (nonatomic, assign) NSInteger checkPitch;
-
-@property (nonatomic, assign) long long correctTimeInterval;
-
-@property (nonatomic, strong) SoundCheckView *checkView;
-
-@property (nonatomic, strong) CloudSongMessageModel *songMessageSource;
-
-@property (nonatomic, assign) BOOL isVertical;
-
-@property (nonatomic, strong) NSDictionary *fingerImageDic;
-
-@property (nonatomic, strong) NSString *fullDicImage;
-
-@property (nonatomic, strong) UIView *fingerDisplayView;
-
-@property (nonatomic, strong) UIView *fingerContentView;
-
-@property (nonatomic, assign) CGRect defaultFrame;
-
-@property (nonatomic, assign) CGRect resizeFrame;
-
-@property (nonatomic, strong) NSMutableArray *zipFileArray;
-
-@property (nonatomic, strong) CloudFeedbackView *feedbackView;
-
-@property (nonatomic, strong) TrackChooseView *trackChooseView;
-
-@end
-
-@implementation KSCloudViewController
-
-- (NSString *)getSaveZipPath {
-    //  在Documents目录下创建一个名为AudioSpeedFile的文件夹
-    NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"AudioZipFile"];
-    NSLog(@"%@",path);
-    
-    NSFileManager *fileManager = [NSFileManager defaultManager];
-    BOOL isDir = FALSE;
-    BOOL isDirExist = [fileManager fileExistsAtPath:path isDirectory:&isDir];
-    if(!(isDirExist && isDir)) {
-        BOOL bCreateDir = [fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
-        if(!bCreateDir){
-            NSLog(@"创建文件夹失败!");
-        }
-        NSLog(@"创建文件夹成功,文件路径%@",path);
-    }
-    
-    NSLog(@"file path:%@",path);
-    return path;
-}
-
-
-#pragma mark ----- life cycle
-- (void)viewDidLoad {
-    [super viewDidLoad];
-    // Do any additional setup after loading the view.
-    self.ks_prefersNavigationBarHidden = YES;
-    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appEnterBackground) name:@"appEnterBackground" object:nil];
-    self.view.backgroundColor = UIColor.whiteColor;
-    [self displayBaseConfig];
-}
-
-- (void)viewWillAppear:(BOOL)animated {
-    [super viewWillAppear:animated];
-    [self connectSocketService];
-    // 切换到横屏
-    [self changeOrientation:YES];
-    [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
-}
-
-- (void)viewDidAppear:(BOOL)animated {
-    [super viewDidAppear:animated];
-    if (self.songMessageSource != nil) {
-        NSString *filePath = [self getSaveZipPath];
-        NSString *floderName = [[[self.songMessageSource.zipUrl getUrlFileName] componentsSeparatedByString:@"."] firstObject];
-        filePath = [NSString stringWithFormat:@"%@/%@",filePath,floderName];
-        NSError *error = nil;
-        NSArray *folderContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:filePath error:&error];
-        if (folderContents.count == 0) {
-            [self downloadZipFileWithFloderName:floderName];
-        }
-        else {
-            [self configUnZipFilePathWithFloderName:floderName];
-        }
-    }
-}
-
-- (void)viewWillDisappear:(BOOL)animated {
-    [super viewWillDisappear:animated];
-    [[UIApplication sharedApplication] setIdleTimerDisabled:NO];
-    if (_AQManager) {
-        [_AQManager freeAudioQueue];
-        _AQManager = nil;
-    }
-    if (_socketManager) {
-        [self.socketManager SRWebSocketClose];
-        _socketManager = nil;
-    }
-    [self stopSession];
-
-    if (self.keepOrientation == NO) {
-        [self changeOrientation:NO];
-        // 如果退出评测页面 清除 playerEngine
-        if (self.playerEngine) {
-            [self.playerEngine cleanup];
-            self.playerEngine = nil;
-        }
-    }
-    self.keepOrientation = NO;
-}
-
-- (void)changeOrientation:(BOOL)isLandScape {
-    if (isLandScape) {
-        // 切换到横屏
-        AppDelegate* delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
-        delegate.allowAutoRotate = YES;
-        [UIDevice switchNewOrientation:UIInterfaceOrientationLandscapeRight inController:self];
-    }
-    else {
-        AppDelegate* delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
-        delegate.allowAutoRotate = NO;
-        [UIDevice switchNewOrientation:UIInterfaceOrientationPortrait inController:self];
-    }
-}
-
-
-#pragma mark ---- 获取和配置曲目相关参数
-- (void)configMessage:(CloudSongMessageModel *)songMessage {
-    self.songMessageSource = songMessage;
-    self.songName = songMessage.examSongName;
-}
-
-- (void)configUnZipFilePathWithFloderName:(NSString *)name {
-    self.zipFileArray = [NSMutableArray array];
-    NSString *filePath = [self getSaveZipPath];
-    filePath = [NSString stringWithFormat:@"%@/%@",filePath,name];
-    NSError *error = nil;
-    NSArray *folderContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:filePath error:&error];
-    for (NSString *fileName in folderContents) {
-        NSString *path = [NSString stringWithFormat:@"%@/%@", filePath, fileName];
-        [self.zipFileArray addObject:path];
-    }
-    NSLog(@"------%@",name);
-    [self querySourceMessage];
-}
-
-- (void)downloadZipFileWithFloderName:(NSString *)name {
-    
-    [LOADING_MANAGER showHUD];
-    [KSNetworkingManager downloadFileRequestWithFileUrl:self.songMessageSource.zipUrl progress:^(int64_t bytesRead, int64_t totalBytes) {
-        
-    } success:^(NSURL * _Nonnull fileUrl) {
-
-        // 解压zip包
-        NSString *filePath = [self getSaveZipPath];
-        BOOL success = [SSZipArchive unzipFileAtPath:fileUrl.path toDestination:filePath];
-        NSLog(@"%d", success);
-        if (success) {
-            [LOADING_MANAGER removeHUD];
-            [self configUnZipFilePathWithFloderName:name];
-        }
-        else {
-            [LOADING_MANAGER removeHUD];
-            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"资源解压失败"];
-        }
-    } faliure:^(NSError * _Nonnull error) {
-        [LOADING_MANAGER removeHUD];
-        [LOADING_MANAGER MBShowAUTOHidingInWindow:@"下载配置资源失败"];
-    }];
-}
-
-- (void)displayBaseConfig {
-    self.beatType = MetronomeType4V4;
-    NSString *savePath = [CloudSongMessageModel getSaveSpeedPath];
-    NSDictionary *speedDic = [NSMutableDictionary dictionaryWithContentsOfFile:savePath];
-    NSInteger speed = [speedDic ks_integerValueForKey:self.songMessageSource.examSongId];
-    if (speed != 0) {
-        self.currentSpeed = speed;
-    }
-    [self queryFingerConfig];
-    [self queryCloudConfig];
-}
-
-- (void)queryFingerConfig {
-    
-    NSDictionary *fingerSubjectDic = [NSMutableDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"SubjectFinger" ofType:@"plist"]];
-    
-    NSDictionary *imageDict = [NSMutableDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"FingerList" ofType:@"plist"]];
-    // 根据当前声部获取对应的音高对应图片
-    NSString *subjectId = self.songMessageSource.subjectId;
-    
-    NSDictionary *subjectDic = [fingerSubjectDic ks_dictionaryValueForKey:subjectId];
-    if (subjectDic) {
-        NSString *subjectName = [subjectDic ks_stringValueForKey:@"name"];
-        BOOL isVertical = [subjectDic ks_boolValueForKey:@"vertical"];
-        self.isVertical = isVertical;
-        
-        NSDictionary *fingerSource = [imageDict ks_dictionaryValueForKey:subjectName];
-        self.fingerImageDic = [NSDictionary dictionaryWithDictionary:fingerSource];
-        
-        NSString *fullImageName = [NSString stringWithFormat:@"%@full",subjectName];
-        UIImage *bgImage = [UIImage imageNamed:fullImageName];
-        
-        CGRect frame = CGRectZero;
-        CGFloat width = bgImage.size.width;
-        CGFloat height = bgImage.size.height;
-        if (isVertical) {
-            CGFloat contentHeight = CGRectGetHeight(self.defaultFrame);
-            if (height > contentHeight) {
-                width = contentHeight / height * width;
-                height = contentHeight;
-            }
-            frame = CGRectMake(CGRectGetWidth(self.defaultFrame) - width, (CGRectGetHeight(self.defaultFrame) - height) / 2.0f, width, height);
-            self.resizeFrame = CGRectMake(0, 0, CGRectGetWidth(self.defaultFrame)-width, CGRectGetHeight(self.defaultFrame));
-        }
-        else {
-            CGFloat contentWidth = CGRectGetWidth(self.defaultFrame);
-            if (width > contentWidth) {
-                height = width / contentWidth * height;
-                width = contentWidth;
-            }
-            
-            frame = CGRectMake((CGRectGetWidth(self.defaultFrame) - width) / 2.0f, CGRectGetHeight(self.defaultFrame) - height, width, height);
-            
-            self.resizeFrame = CGRectMake(0, 0, CGRectGetWidth(self.defaultFrame), CGRectGetHeight(self.defaultFrame) - height);
-        }
-        self.fingerDisplayView = [[UIView alloc] initWithFrame:frame];
-        self.fingerDisplayView.backgroundColor = [UIColor clearColor];
-        UIImageView *bgImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
-        [bgImageView setImage:bgImage];
-        [self.fingerDisplayView addSubview:bgImageView];
-        
-        self.fingerContentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
-        self.fingerContentView.backgroundColor = [UIColor clearColor];
-        [self.fingerDisplayView addSubview:self.fingerContentView];
-    }
-}
-
-- (void)setShowFinger:(BOOL)showFinger {
-    _showFinger = showFinger;
-    if (showFinger && self.fingerImageDic != nil) {
-        self.needShowFinger = YES;
-    }
-    else {
-        self.needShowFinger = NO;
-    }
-}
-
-- (void)queryCloudConfig {
-    NSDictionary *config = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"cloudConfig"];
-    if (config == nil || config.allKeys.count == 0) {
-        NSMutableDictionary *newConfig = [NSMutableDictionary dictionary];
-        [newConfig setValue:@(NO) forKey:@"eyeshield"];
-        [newConfig setValue:@(NO) forKey:@"soundCheck"];
-        [newConfig setValue:@(NO) forKey:@"cameraOn"];
-        [newConfig setValue:@(YES) forKey:@"repeatOn"];
-        [newConfig setValue:@(YES) forKey:@"showFinger"];
-        [newConfig setValue:@"ADVANCED" forKey:@"level"];
-        [newConfig setValue:@(YES) forKey:@"accompanyOn"];
-        [newConfig setValue:@(NO) forKey:@"save"];
-        [newConfig setValue:self.songMessageSource.behaviorId forKey:@"behaviorId"];
-        [newConfig setValue:@"" forKey:@"tips-status"];
-        [[NSUserDefaults standardUserDefaults] setObject:newConfig forKey:@"cloudConfig"];
-        [[NSUserDefaults standardUserDefaults] synchronize];
-        config = [NSDictionary dictionaryWithDictionary:newConfig];
-    }
-    
-    self.eyeShieldOn = [config ks_boolValueForKey:@"eyeshield"];
-    self.soundCheckOn = [config ks_boolValueForKey:@"soundCheck"];
-    self.cameraOn = [config ks_boolValueForKey:@"cameraOn"];
-    self.isNeedRepeat = [config ks_boolValueForKey:@"repeatOn"];
-    self.showFinger = [config ks_boolValueForKey:@"showFinger"];
-    self.level = [config ks_stringValueForKey:@"level"];
-    self.saveVideo = [config ks_boolValueForKey:@"save"];
-    self.accompanyOn = [config ks_boolValueForKey:@"accompanyOn"];
-    
-    NSMutableDictionary *saveConfig = [NSMutableDictionary dictionaryWithDictionary:config];
-    [saveConfig setValue:self.songMessageSource.behaviorId forKey:@"behaviorId"];
-    [[NSUserDefaults standardUserDefaults] setObject:saveConfig forKey:@"cloudConfig"];
-    [[NSUserDefaults standardUserDefaults] synchronize];
-    
-}
-
-- (void)querySourceMessage {
-    
-    dispatch_async(dispatch_queue_create("CloudSource", DISPATCH_QUEUE_SERIAL), ^{
-        // 未选择小节设置为-1;
-        self.startMeasure = -1;
-        self.endMeasure = -1;
-        NSString *measurePath = @"";
-        NSString *nodeSourePath = @"";
-        NSString *xmlFile = @"";
-        NSString *songPath = @"";
-        for (NSString *filePath in self.zipFileArray) {
-            if ([filePath containsString:@".mpos"]) {
-                measurePath = filePath;
-            }
-            else if ([filePath containsString:@".spos"]) {
-                nodeSourePath = filePath;
-            }
-            else if ([filePath containsString:@".musicxml"] || [filePath containsString:@".xml"]) {
-                xmlFile = filePath;
-            }
-            else if ([filePath containsString:@".mid"]) {
-                songPath = filePath;
-                self.songPath = songPath;
-            }
-        }
-        
-//        measurePath = [[NSBundle mainBundle] pathForResource:@"mus" ofType:@"mpos"];
-//        nodeSourePath = [[NSBundle mainBundle] pathForResource:@"mus" ofType:@"spos"];
-//        xmlFile = [[NSBundle mainBundle] pathForResource:@"Danza_Del_Fuego" ofType:@"xml"];
-//        songPath = [[NSBundle mainBundle] pathForResource:@"Danza_Del_Fuego" ofType:@"mid"];
-        
-        NSDictionary *xmlParm = [KSXMLInfoParse getInfoFromXMLMusicFile:xmlFile];
-        self.nodeArray = [NSMutableArray arrayWithArray:[xmlParm ks_arrayValueForKey:@"noteInfo"]];
-        self.beatType = [self getBeatTypeFromString:[xmlParm ks_stringValueForKey:@"beatType"]];
-        self.manager = [[KYSourceParseManager alloc] init];
-        [self.manager parseMessageSource:measurePath nodeSource:nodeSourePath];
-        
-        [self configAudioSession];
-        // 预加载mid文件
-        [self configPlayerEngineWithSong:songPath];
-        dispatch_main_async_safe(^{
-            [self displayView];
-        });
-        
-    });
-}
-
-- (MetronomeType)getBeatTypeFromString:(NSString *)typeString {
-    if ([typeString isEqualToString:@"1/4"]) {
-        return MetronomeType1V4;
-    }
-    else if ([typeString isEqualToString:@"2/4"]) {
-        return MetronomeType2V4;
-    }
-    else if ([typeString isEqualToString:@"3/4"]) {
-        return MetronomeType3V4;
-    }
-    else if ([typeString isEqualToString:@"4/4"]) {
-        return MetronomeType4V4;
-    }
-    else if ([typeString isEqualToString:@"3/8"]) {
-        return MetronomeType3V8;
-    }
-    else if ([typeString isEqualToString:@"6/8"]) {
-        return MetronomeType6V8;
-    }
-    else {
-        return MetronomeType4V4;
-    }
-}
-
-- (void)configAudioSession {
-    self.audioSessionManager = [[KSAudioSessionManager alloc] init];
-    self.audioSessionManager.delegate = self;
-    [self.audioSessionManager configAudioSession:AUDIOCONFIG_PLAYANDRECORD];
-}
-
-#pragma mark ----- 音频打断相关处理
-
-- (void)handerAudioInterruption {
-    // 处理
-    if (_isEvaluating) { // 如果是评测就停止评测
-        [self cancelEvaluating];
-        // 页面重置
-    }
-    else if (_isPlaying) { // 如果是播放就停止播放
-        [self stopPlayAction];
-    }
-}
-- (void)resumeAudioSession {
-    self.lastPlayNodeIndex = 0;
-    [self.playerEngine resumeAUGraph];
-}
-// 退到后台
-- (void)appEnterBackground {
-    [self handerAudioInterruption];
-}
-
-// 打断处理
-- (void)audioInterruption {
-    if (_videoRecordManager) {
-        [self.videoRecordManager resetSession];
-    }
-    [self handerAudioInterruption];
-}
-
-- (void)stopSession {
-    if (_videoRecordManager) {
-        [self.videoRecordManager stopSession];
-    }
-}
-
-
-#pragma mark ----- socket 相关处理
-
-- (void)connectSocketService {
-    
-    MJWeakSelf;
-    self.socketManager.didReceiveMessage = ^(id  _Nonnull message) {
-        dispatch_async(dispatch_get_main_queue(), ^{
-            // api
-            NSMutableDictionary *sendMessage = [NSMutableDictionary dictionary];
-            [sendMessage setValue:@"sendResult" forKey:@"api"];
-            [sendMessage setValue:message forKey:@"content"];
-            NSLog(@"receive message -----%@",message);
-            // 处理服务端返回的数据
-            NSDictionary *messageDic = [weakSelf convertJsonStringToNSDictionary:message];
-            [weakSelf dealWithMessage:messageDic];
-        });
-    };
-    self.socketManager.connectionStatus = ^(BOOL isSuccess) {
-        dispatch_async(dispatch_get_main_queue(), ^{
-            
-            if (!isSuccess) {
-                NSLog(@"-----连接失败");
-                if (weakSelf.hasSendStartMessage) {
-                    if (weakSelf.AQManager.isRunning) {
-                        [weakSelf cancelEvaluating];
-                        [weakSelf showErrorMessage:@"服务异常,请重试"];
-                        // 处理断连事件
-                        [weakSelf stopRecordService];
-                        weakSelf.isCompareStart = NO;
-                        weakSelf.isSoundCheckStart = NO;
-                    }
-                }
-                else if (weakSelf.evaluatParm) {
-                    // 处理断连事件
-                    [weakSelf cancelEvaluating];
-                    [weakSelf showErrorMessage:@"服务异常,请重试"];
-                    weakSelf.hasSendStartMessage = YES;
-                    weakSelf.isCompareStart = NO;
-                    weakSelf.isSoundCheckStart = NO;
-                }
-                else { // 其他断开
-                    if (weakSelf.AQManager.isRunning) {
-
-                        // 处理断连事件 停止评测
-                        [weakSelf cancelEvaluating];
-                        [weakSelf showErrorMessage:@"服务异常,请重试"];
-                        
-                        [weakSelf stopRecordService];
-                        weakSelf.isCompareStart = NO;
-                        weakSelf.isSoundCheckStart = NO;
-                    }
-                }
-            }
-            else {
-                NSLog(@"-----连接成功");
-                if (weakSelf.hasSendStartMessage == NO && weakSelf.evaluatParm) {
-                    NSDictionary *content = weakSelf.evaluatParm;
-                    NSString *sendData = [weakSelf configDataCommond:@"musicXml" body:content type:@"SOUND_COMPARE"];
-                    [weakSelf sendDataToSocketService:sendData];
-                    [weakSelf showBeatBeforeEvaluating];
-                    weakSelf.hasSendStartMessage = YES;
-                    NSLog(@"---- send musicXML message");
-                }
-            }
-        });
-    };
-    [self.socketManager SRWebSocketOpen];
-}
-
-- (NSDictionary *)convertJsonStringToNSDictionary:(NSString *)jsonString {
-    if (jsonString == nil) {
-        return nil;
-    }
-    NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
-    NSError *error;
-    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
-    if (error) {
-        NSLog(@"jsonString解析失败:%@", error);
-        return nil;
-    }
-    return json;
-}
-
-- (void)sendDataToSocketService:(id)data {
-    if (_socketManager) {
-        [self.socketManager sendData:data];
-    }
-}
-
-// 处理socket返回数据
-- (void)dealWithMessage:(NSDictionary *)messageDic {
-    if (_isEvaluating == NO) { // 非评测状态下不处理
-        return;
-    }
-    NSString *commond = [[messageDic ks_dictionaryValueForKey:@"header"] ks_stringValueForKey:@"commond"];
-    if ([commond isEqualToString:@"measureScore"]) { // 评测返回数据
-        NSDictionary *body = [messageDic ks_dictionaryValueForKey:@"body"];
-        NSInteger score = [body ks_integerValueForKey:@"score"];
-        NSInteger measureIndex = [body ks_integerValueForKey:@"measureIndex"];
-        [self displayScore:score measureIndex:measureIndex];
-    }
-    else if ([commond isEqualToString:@"overall"]) { // 弹窗结果
-        NSDictionary *body = [messageDic ks_dictionaryValueForKey:@"body"];
-        self.recordId = [body ks_integerValueForKey:@"recordId"];
-        NSInteger score = [body ks_integerValueForKey:@"score"];
-        NSInteger intonation = [body ks_integerValueForKey:@"intonation"];
-        NSInteger integrity = [body ks_integerValueForKey:@"integrity"];
-        NSInteger cadence = [body ks_integerValueForKey:@"cadence"];
-        self.resultAlert = [EvaluateResultAlert shareInstance];
-        self.resultAlert.frame = CGRectMake(0, 0, KLandscapeWidth, KLandscapeHeight);
-        [self.resultAlert configWithScore:score intonation:intonation cadence:cadence integrity:integrity];
-        MJWeakSelf;
-        [self.resultAlert resultCallback:^(EVALUATE_RESULT_ACTION action) {
-            [weakSelf resulteAlertAction:action];
-        }];
-        [self.view addSubview:self.resultAlert];
-    }
-    else if ([commond isEqualToString:@"checking"]) { // 校音
-        NSTimeInterval interval = [[NSDate date] timeIntervalSince1970];
-        long long currentMilliseconds = interval * 1000;
-        
-        NSDictionary *body = [messageDic ks_dictionaryValueForKey:@"body"];
-        float frequency = [body ks_doubleValueForKey:@"frequency"];
-        float baseFrequency = [KSXMLInfoParse parsePitchToHZ:self.checkPitch];
-        if (frequency - baseFrequency > 5.0) { // 高了
-            self.correctTimeInterval = 0.0f;
-            [self.checkView showLightDisplay:LIGHTDISPLAY_HIGH];
-        }
-        else if (frequency - baseFrequency < -5.0f) { // 低了
-            self.correctTimeInterval = 0.0f;
-            [self.checkView showLightDisplay:LIGHTDISPLAY_LOW];
-        }
-        else {
-            if (self.correctTimeInterval == 0.0f) {
-                self.correctTimeInterval = currentMilliseconds;
-            }
-            else { // 如果一直持续超过1s
-                long long duration = currentMilliseconds - self.correctTimeInterval;
-                if (duration >= 1000) {
-                    if (self.checkView) {
-                        self.correctTimeInterval = 0.0;
-                        [self.checkView showSuccessCheckEnd];
-                    }
-                }
-            }
-            [self.checkView showLightDisplay:LIGHTDISPLAY_RIGHT];
-        }
-    }
-}
-
-- (NSString *)configDataCommond:(NSString *)commond body:(id)bodyMessage type:(NSString *)dataType {
-    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
-    if (bodyMessage) {
-        [parm setValue:bodyMessage forKey:@"body"];
-    }
-    NSMutableDictionary *headerParm = [NSMutableDictionary dictionary];
-    if ([NSString isEmptyString:commond]) {
-        [headerParm setValue:@"" forKey:@"commond"];
-    }
-    else {
-        [headerParm setValue:commond forKey:@"commond"];
-    }
-    if (![NSString isEmptyString:dataType]) {
-        [headerParm setValue:dataType forKey:@"type"];
-    }
-    [headerParm setValue:@(200) forKey:@"status"];
-    [parm setValue:headerParm forKey:@"header"];
-    return [parm mj_JSONString];
-}
-
-- (void)sendEndMessage {
-    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
-        // 上传停止的信息 发送给服务端
-        NSString *endMessage = @"recordEnd";
-        NSString *endData = [self configDataCommond:endMessage body:nil type:@"SOUND_COMPARE"];
-        [self sendDataToSocketService:endData];
-        self.isCompareStart = NO;
-        NSLog(@"---- send end message");
-    });
-}
-
-
-
-#pragma mark ------ 谱面相关
-// 将displayScroll view 显示的当前音符移动到显示的中间位置
-- (void)moveDisplayViewDisplay {
-    
-    KSParseMessageModel *currentNode = self.manager.nodeMessageArray[self.lastPlayNodeIndex];
-    
-    CGFloat positionY = (currentNode.positionY  + currentNode.elementHeight / 2.0f) / PositionRate * self.scaleRate + currentNode.pageIndex * self.pageViewHeight;
-    CGFloat offsetY = 0.0f;
-    if (positionY < CGRectGetHeight(self.displayScrollView.frame) / 2.0f) {
-        offsetY = 0.0f;
-    }
-    else {
-        offsetY = positionY - CGRectGetHeight(self.displayScrollView.frame) / 2.0f;
-    }
-    [self.displayScrollView setContentOffset:CGPointMake(0, offsetY)];
-}
-
-// 渲染当前小节和评分
-- (void)displayScore:(NSInteger)score measureIndex:(NSInteger)measureIndex {
-    for (KSParseMessageModel *model in self.manager.measureMessageArray) {
-        if (model.elementIndex == measureIndex) {
-            KSMeasureLocationModel *measureLocation = [[KSMeasureLocationModel alloc] init];
-            measureLocation.positionX = model.positionX / PositionRate * self.scaleRate;
-            measureLocation.positionY = model.positionY / PositionRate * self.scaleRate;
-            measureLocation.measureWidth = model.elementWidth / PositionRate * self.scaleRate;
-            measureLocation.measureHeight = model.elementHeight / PositionRate * self.scaleRate;
-            measureLocation.pageIndex = model.pageIndex;
-            
-            measureLocation.fillColor = [self getDisplayColorWithScore:score sourceLocation:measureLocation];
-            
-            NSInteger index = model.pageIndex;
-            StaffImageDisplayView *view = self.pageArray[index];
-            [view addColorView:measureLocation];
-            break;
-        }
-    }
-}
-
-- (UIColor *)getDisplayColorWithScore:(NSInteger)score sourceLocation:(KSMeasureLocationModel *)model {
-    UIColor *measureBgColor;
-    UIColor *titleColor;
-    NSString *imageName = @"";
-    
-    if (score >= 90) { // perfect
-        measureBgColor = HexRGBAlpha(0xffd4c0, 0.47f);
-        
-        titleColor = HexRGB(0x516AFF);
-        imageName = @"score_perfect";
-    }
-    else if (score >= 70) { // great
-        measureBgColor = HexRGBAlpha(0xffb252, 0.48f);
-        titleColor = HexRGB(0xFF8E5A);
-        imageName = @"score_great";
-    }
-    else if (score >= 40) { // good
-        measureBgColor = HexRGBAlpha(0x2dc7aa, 0.17f);
-        titleColor = HexRGB(0xFF958B);
-        imageName = @"score_good";
-    }
-    else { // bad
-        measureBgColor = HexRGBAlpha(0xff8e8e, 0.32f);
-        titleColor = HexRGB(0xEE4C6A);
-        imageName = @"score_bad";
-    }
-    CGFloat viewHeight = 40.0f;
-    CGRect viewFrame = CGRectMake(model.positionX, model.positionY+viewHeight, model.measureWidth, viewHeight);
-    [self showScoreViewInPage:model.pageIndex frame:viewFrame titleColor:titleColor score:score imageName:imageName];
-    
-    return measureBgColor;
-}
-
-- (void)showScoreViewInPage:(NSInteger)pageIndex frame:(CGRect)frame titleColor:(UIColor *)titleColor score:(NSInteger)score imageName:(NSString *)imageName {
-    CGFloat distanceY = 20.0f;
-    ScoreAnimationView *view = [[ScoreAnimationView alloc] initWithFrame:frame animitionDistance:distanceY score:score titleColor:titleColor imageName:imageName];
-    
-    StaffImageDisplayView *pageView = self.pageArray[pageIndex];
-    [view showInView:pageView];
-}
-
-
-#pragma mark ------ 评测结果处理
-- (void)showReportView {
-
-    KSBaseWKWebViewController *reportCtrl = [[KSBaseWKWebViewController alloc] init];
-    reportCtrl.url = [NSString stringWithFormat:@"%@/accompany/#/report/%zd",WEBHOST,self.recordId];
-    self.keepOrientation = YES;
-    reportCtrl.keepOrientation = YES;
-    [self.navigationController pushViewController:reportCtrl animated:YES];
-}
-
-- (void)resulteAlertAction:(EVALUATE_RESULT_ACTION)action {
-    switch (action) {
-        case EVALUATE_RESULT_ACTION_CANCLE: // 退出评测模式
-        {
-            [self.resultAlert removeFromSuperview];
-            [self quitEvaluatingMode];
-        }
-            break;
-        case EVALUATE_RESULT_ACTION_SHARE:  // 分享
-        {
-            // share function
-            
-        }
-            break;
-        case EVALUATE_RESULT_ACTION_SUBMIT: // 上传到云端
-        {
-            if (self.cameraOn && self.saveVideo) { // 上传视频到云端
-                [self videoUpdate];
-            }
-            else { // 直接发送消息显示音频
-                [self sendUploadMessage:nil];
-            }
-        }
-            break;
-        case EVALUATE_RESULT_ACTION_PRACTICE:  // 练习
-        {
-            [self.resultAlert removeFromSuperview];
-            [self quitEvaluatingMode];
-        }
-            break;
-        case EVALUATE_RESULT_ACTION_TAYAGAIN:  // 再试一次
-        {
-            [self.resultAlert removeFromSuperview];
-            [self clearAllColorDisplayView];
-        }
-            break;
-        case EVALUATE_RESULT_ACTION_REPORT:   // 报告
-        {
-            [self showReportView];
-        }
-            break;
-        default:
-            break;
-    }
-}
-
-#pragma mark ------ recorder
-// 初始化录制引擎
-- (void)configRecordManager {
-    if (self.AQManager.isRunning) {
-        [self.AQManager stopRecord];
-    }
-    self.AQManager = [[KSAQRecordManager alloc] init];
-    self.AQManager.delegate = self;
-}
-// 开始录制
-- (void)startRecordService {
-    if (self.AQManager.isRunning) {
-        [self.AQManager stopRecord];
-    }
-    [self.AQManager startRecord];
-}
-// 停止录制
-- (void)stopRecordService {
-    if (self.AQManager.isRunning) {
-        [self.AQManager stopRecord];
-    }
-}
-
-
-#pragma mark-------- KSAQRecordManagerDelegate
-- (void)recordInterruption {
-
-    [self cancelEvaluating];
-    [self showErrorMessage:@"录制错误,请重试"];
-}
-
-- (void)audioRouteChange:(AUDIODEVICE_TYPE)type {
-    NSString *valueStr = @"";
-    BOOL checkIsWired = NO;
-    switch (type) {
-        case AUDIODEVICE_TYPE_HEADPHONE:
-        {
-            valueStr = @"有线耳机";
-            checkIsWired = YES;
-        }
-            break;
-        case AUDIODEVICE_TYPE_BLUETOOTH:
-        {
-            valueStr = @"蓝牙耳机";
-            checkIsWired = YES;
-        }
-            break;
-        case AUDIODEVICE_TYPE_NONE:
-        {
-            valueStr = @"";
-            checkIsWired = NO;
-        }
-            break;
-        default:
-            break;
-    }
-    
-    if (checkIsWired == NO) {
-        [self showNoWiredTipsAlertCallback:^{
-            
-        }];
-    }
-
-}
-
-- (void)audioRecord:(KSAQRecordManager *)audioRecord didRecordAudioData:(void *)data length:(UInt32)length {
-    
-    if (self.socketManager.socketReadyState != SR_OPEN) {
-        return;
-    }
-    NSData *pushData = [[NSData alloc] initWithBytes:data length:length];
-    if (self.isCompareStart) { // 发送评测开始消息
-        NSLog(@"--------- send start message");
-        _isCompareStart = NO;
-        NSString *startMessage = @"recordStart";
-        NSString *startString = [self configDataCommond:startMessage body:nil type:@"SOUND_COMPARE"];
-        [self sendDataToSocketService:startString];
-    }
-    else if (self.isSoundCheckStart) { // 校音开始
-        
-        NSLog(@"--------- send check start message");
-        _isSoundCheckStart = NO;
-        NSString *checkStartMessage = @"start";
-        NSString *startString = [self configDataCommond:checkStartMessage body:nil type:@"PITCH_DETECTION"];
-        [self sendDataToSocketService:startString];
-    }
-    [self sendDataToSocketService:pushData];
-}
-
-
-#pragma mark ---  player 播放引擎 播放和停止播放UI
-// 初始化播放引擎
-- (void)configPlayerEngineWithSong:(NSString *)songPath {
-    [LOADING_MANAGER showHUD];
-    self.playerEngine = [[MidiPlayerEngine alloc] init];
-    self.playerEngine.accompanyVolume = 0.3f;
-    self.playerEngine.reportTime = 10;
-    self.playerEngine.delegate = self;
-    [self.playerEngine configSoundFilePath:[[NSBundle mainBundle]
-                                            pathForResource:@"synthgms" ofType:@"sf2"]];
-    // 获取当前主声部对应的乐器id
-    self.playerEngine.instrumentId = 73;
-    [self.playerEngine loadMIDIFileWithString:songPath];
-    
-    
-    NSLog(@"--------- instanment track --- %d", self.playerEngine.baseInstrumentTrack);
-//    [self.playerEngine volumeOtherTrackExcept:self.playerEngine.baseInstrumentTrack withVolume:0];
-    if (self.currentSpeed == 0) {
-        self.currentSpeed = self.playerEngine.baseRate;
-    }
-    dispatch_async(dispatch_get_main_queue(), ^{
-        [LOADING_MANAGER MBShowAUTOHidingInWindow:@"加载完成"];
-        [LOADING_MANAGER removeHUD];
-        CloudControlButton *speedButton = [self.headView viewWithTag:BUTTON_TAG_SPEED];
-        [speedButton showSpeed:self.currentSpeed];
-    });
-}
-
-/* 播放时,显示光标 曲谱不可手动滑动,根据播放进度自动移动位置
-   停止播放时,隐藏光标,光标回到初始位置,曲谱滑动禁用关闭。
- */
-- (void)playAction {  // 播放
-    CloudControlButton *playButton = [self.headView viewWithTag:BUTTON_TAG_PLAY];
-    playButton.isSelected = YES;
-    self.isPlaying = YES;
-    self.displayScrollView.scrollEnabled = NO;
-    [self showCursor];
-    if ([self.playerEngine isPlayingFile]) {
-        [self.playerEngine stopPlayingMIDIFile];
-    }
-    
-    // 将displayScroll view 显示的当前音符移动到显示的中间位置
-    [self moveDisplayViewDisplay];
-    
-    if (self.startMeasure != -1) {
-
-        [self.playerEngine setProgressTime:self.playerEngine.startTime];
-        [self.playerEngine playMIDIFile];
-    }
-    else {
-        [self.playerEngine playMIDIFile];
-    }
-}
-
-- (void)stopPlayAction { // 停止播放
-    self.isPlaying = NO;
-    [self hideCursor];
-    self.displayScrollView.scrollEnabled = YES;
-    if ([self.playerEngine isPlayingFile]) {
-        [self.playerEngine stopPlayingMIDIFile];
-    }
-    CloudControlButton *playButton = [self.headView viewWithTag:BUTTON_TAG_PLAY];
-    playButton.isSelected = NO;
-}
-
-#pragma mark ---- PlayerEngineDelegate
-- (void)ProgressUpdated:(float)progress currentTime:(MusicTimeStamp)currentTime {
-    
-    // 如果是最后一个节点
-    if (self.lastPlayNodeIndex == self.manager.nodeMessageArray.count - 1) {
-        return;
-    }
-    KSParseMessageModel *nextNode = self.manager.nodeMessageArray[self.lastPlayNodeIndex+1];
-    if (nextNode.elementTimePosition <= currentTime*1000) {
-        KSParseMessageModel *currentNode = self.manager.nodeMessageArray[self.lastPlayNodeIndex];
-        
-        self.lastPlayNodeIndex +=1;
-        [self moveCursorViewWithNode:nextNode];
-        // 如果换行或者到下一页
-        if (currentNode.positionY < nextNode.positionY || currentNode.pageIndex < nextNode.pageIndex) {
-            [self moveDisplayViewDisplay];
-        }
-    }
-}
-    
-- (void)playEnd {
-    // 判断是否需要重播
-    if (_isNeedRepeat && _isPlaying && _isEvaluating == NO) {
-        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
-            [self stopPlayAction];
-            self.lastPlayNodeIndex = 0;
-            [self showBeatBeforePlay];
-        });
-    }
-    else {
-        if (_isEvaluating) { // 如果在评测状态下
-            [self endEvaluating];
-        }
-        [self resetPlayButtonStatus];
-    }
-}
-
-- (void)resetPlayButtonStatus {
-    [self.playerEngine setProgressTime:0.0f];
-    CloudControlButton *playButton = [self.headView viewWithTag:BUTTON_TAG_PLAY];
-    playButton.isSelected = NO;
-    self.lastPlayNodeIndex = 0;
-    [self hideCursor];
-    self.displayScrollView.scrollEnabled = YES;
-}
-
-
-- (void)GetMusicTotalTime:(float)time {
-    
-}
-
-
-- (void)quitEvaluatingMode {
-    self.isEvaluating = NO;
-    [self clearAllColorDisplayView];
-    CloudControlButton *evaluateButton = [self.headView viewWithTag:BUTTON_TAG_EVALUATING];
-    evaluateButton.isSelected = NO;
-}
-
-
-- (void)showErrorMessage:(NSString *)message {
-    [LOADING_MANAGER MBShowAUTOHidingInWindow:message];
-}
-
-
-- (void)displayView {
-    [self.view addSubview:self.viewContainer];
-    _backView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KLandscapeWidth, KLandscapeHeight)];
-    _backView.backgroundColor = THEMECOLOR;
-    [self.view addSubview:_backView];
-    _bgColorView = [[UIView alloc] initWithFrame:self.defaultFrame];
-    _bgColorView.layer.cornerRadius = 14.0f;
-    [self.backView addSubview:_bgColorView];
-    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
-        if (self.cameraOn) {
-            self.backView.alpha = BACKVIEW_ALPHA;
-            [self.videoRecordManager configSessiondisplayInView:self.viewContainer];
-        }
-    });
-    _headView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KLandscapeWidth, 78)];
-    _headView.backgroundColor = [UIColor clearColor];
-    [self.backView addSubview:_headView];
-    // 配置顶部按钮
-    [self configButtonInView:_headView];
-    
-    // 创建右侧帮助按钮
-    [self createHelpButton];
-
-    // 创建scorll view 容器添加图片
-    [self createDisplayScrollView];
-}
-
-
-
-- (void)createHelpButton {
-    self.helpButton = [UIButton buttonWithType:UIButtonTypeCustom];
-    self.helpButton.frame = CGRectMake(KLandscapeWidth - 46, (KLandscapeHeight - 86) /2.0f, 46, 86);
-    [self.helpButton setImage:[UIImage imageNamed:@"cloud_help"] forState:UIControlStateNormal];
-    [self.helpButton addTarget:self action:@selector(helpAction) forControlEvents:UIControlEventTouchUpInside];
-    [self.view addSubview:self.helpButton];
-}
-
-- (void)helpAction {
-    CloudHelpView *helpView = [CloudHelpView shareInstance];
-    helpView.frame = CGRectMake(0, 0, KLandscapeWidth, KLandscapeHeight);
-    MJWeakSelf;
-    [helpView feedbackCallback:^{
-        [weakSelf showFeedbackUI];
-    }];
-    [self.view addSubview:helpView];
-}
-
-- (void)showFeedbackUI {
-    MJWeakSelf;
-    self.feedbackView = [CloudFeedbackView shareInstance];
-    self.feedbackView.frame = CGRectMake(0, 0, KLandscapeWidth, KLandscapeHeight);
-    [self.feedbackView submitCallback:^(NSString * _Nonnull content, NSString * _Nonnull type) {
-        [weakSelf submitFeedbackAction:content type:type];
-    }];
-    [self.view addSubview:self.feedbackView];
-}
-
-- (void)submitFeedbackAction:(NSString *)content type:(NSString *)type {
-    [LOADING_MANAGER showHUD];
-    [KSNetworkingManager cloudFeedbackRequest:KS_POST content:content type:type success:^(NSDictionary * _Nonnull dic) {
-        [LOADING_MANAGER removeHUD];
-        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
-            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"反馈成功"];
-            [self.feedbackView removeFromSuperview];
-        }
-        else {
-            [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
-        }
-    } faliure:^(NSError * _Nonnull error) {
-        [LOADING_MANAGER removeHUD];
-    }];
-}
-
-- (void)createDisplayScrollView {
-    [self.pageArray removeAllObjects];
-    if (self.needShowFinger) {
-        self.displayScrollView.frame = CGRectMake(0, 0, CGRectGetWidth(self.resizeFrame), CGRectGetHeight(self.resizeFrame));
-    }
-    else {
-        self.displayScrollView.frame = CGRectMake(0, 0, CGRectGetWidth(self.defaultFrame), CGRectGetHeight(self.defaultFrame));
-    }
-    [self.bgColorView addSubview:self.displayScrollView];
-    // 获取当前文件夹中所有图片
-    NSMutableArray *imgArray = [NSMutableArray array];
-    for (NSString *filePath in self.zipFileArray) {
-        if ([filePath containsString:@".png"]) {
-            [imgArray addObject:filePath];
-        }
-    }
-    
-//    NSLog(@"%@", imgArray.description);
-//    for (int i = 1; i < 6; i++) {
-//        NSString *name = [NSString stringWithFormat:@"mus-%d",i];
-//        [imgArray addObject:[[NSBundle mainBundle] pathForResource:name ofType:@"png"]];
-//    }
-    
-    
-
-    UIImage *img = [UIImage imageNamed:imgArray[0]];
-    CGFloat width = img.size.width;
-    CGFloat height = img.size.height;
-    CGFloat displayWidth = CGRectGetWidth(self.displayScrollView.frame);
-    
-    self.scaleRate = displayWidth / width;
-    CGFloat viewHeight = self.scaleRate * height;
-    self.pageViewHeight = viewHeight;
-    
-    self.bgColorType = self.eyeShieldOn ? COLOR_DISPLAYTYPE_PROTECT : COLOR_DISPLAYTYPE_NOMAL;
-    
-    for (NSInteger i = 0; i < imgArray.count; i++) { // 创建 StaffImageDisplayView
-        
-        StaffImageDisplayView *displayView = [[StaffImageDisplayView alloc] initWithImage:imgArray[i] pageIndex:i frame:CGRectMake(0, i * viewHeight, displayWidth, viewHeight)];
-        displayView.tag = 1000 + i;
-        MJWeakSelf;
-        [displayView viewTapActionCallback:^(CGFloat positionX, CGFloat positionY, NSInteger pageIndex) {
-            [weakSelf dealWithPositionX:positionX positionY:positionY pageIndex:pageIndex];
-        }];
-        [self.pageArray addObject:displayView];
-        [self.displayScrollView addSubview:displayView];
-    }
-    CGFloat contentHeight = viewHeight * imgArray.count;
-    if (contentHeight < self.displayScrollView.bounds.size.height) {
-        contentHeight = self.displayScrollView.bounds.size.height;
-    }
-    self.displayScrollView.contentSize = CGSizeMake(displayWidth, contentHeight);
-    
-    if (self.needShowFinger) {
-        [self.bgColorView addSubview:self.fingerDisplayView];
-    }
-    if (self.isPlaying) {
-        self.displayScrollView.scrollEnabled = NO;
-        [self.displayScrollView addSubview:self.cursorView];
-    }
-    else {
-        self.displayScrollView.scrollEnabled = YES;
-    }
-}
-
-
-
-- (void)configButtonInView:(UIView *)displayView {
-    UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
-    backButton.frame = CGRectMake(21, 19, 32, 32);
-    backButton.layer.cornerRadius = 16.0f;
-    [backButton setImage:[UIImage imageNamed:@"cloud_back"] forState:UIControlStateNormal];
-    [backButton setTitleColor:HexRGB(0x000000) forState:UIControlStateNormal];
-    backButton.backgroundColor = [UIColor whiteColor];
-    [backButton addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside];
-    [displayView addSubview:backButton];
-    
-    if (![NSString isEmptyString:self.songName]) {
-        UIView *songNameView = [[UIView alloc] initWithFrame:CGRectMake(70, 17, 180, 40)];
-        songNameView.backgroundColor = [UIColor whiteColor];
-        songNameView.layer.cornerRadius = 20.0f;
-        [displayView addSubview:songNameView];
-        
-        UIImageView *logoImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cloudSong_logo"]];
-        logoImage.frame = CGRectMake(7, 5, 28, 28);
-        [songNameView addSubview:logoImage];
-        
-        UIImageView *nextImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cloudSong_next"]];
-        nextImage.frame = CGRectMake(CGRectGetWidth(songNameView.frame) - 9 - 14, 14, 9, 12);
-        [songNameView addSubview:nextImage];
-        
-        UILabel *songLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(logoImage.frame) + 6, 0, CGRectGetMinX(nextImage.frame) - 5 - CGRectGetMaxX(logoImage.frame) - 6, 40)];
-        songLabel.textAlignment = NSTextAlignmentLeft;
-        songLabel.textColor = HexRGB(0x000000);
-        songLabel.font = [UIFont systemFontOfSize:16.0f weight:UIFontWeightMedium];
-        songLabel.text = self.songName;
-        [songNameView addSubview:songLabel];
-    }
-    
-    NSArray *imageArray = @[@"evaluate_nomal",@"select_normal",@"play_play",@"switch_nomal",@"cloud_playback",@"cloud_speed",@"cloud_setting"];
-    NSArray *selectImageArray = @[@"evaluate_selected",@"select_choose",@"play_pause",@"switch_accompany",@"cloud_playback",@"cloud_speed",@"cloud_setting"];
-    NSArray *titleArray = @[@"评测",@"选段",@"播放",@"原声",@"重播",@"速度",@"设置"];
-    NSArray *selectTitleArray = @[@"评测",@"选段",@"暂停",@"伴奏",@"重播",@"速度",@"设置"];
-    
-    for (NSInteger i = imageArray.count - 1; i >= 0; i--) {
-        CGRect frame = CGRectMake((KLandscapeWidth - 46) - (imageArray.count - i) * Button_Width - (imageArray.count - 1 - i)*Button_Space, 9, 34, 60);
-        MJWeakSelf;
-        CloudControlButton *button = [CloudControlButton createButtonWithImage:imageArray[i] selectImage:selectImageArray[i] buttonTitle:titleArray[i] selectTitle:selectTitleArray[i] tag:1000+i frame:frame callback:^(CloudControlButton * _Nonnull sender, BOOL isSelected) {
-            [weakSelf buttonClickAction:sender isSelected:isSelected];
-        }];
-        if (i == 5 && self.currentSpeed != 0) {
-            [button showSpeed:self.currentSpeed];
-        }
-        [displayView addSubview:button];
-    }
-}
-
-- (void)buttonClickAction:(CloudControlButton *)sender isSelected:(BOOL)isSelected {
-    BUTTON_TAG type = sender.tag;
-    switch (type) {
-        case BUTTON_TAG_EVALUATING:  // 评测开关
-        {
-            if (isSelected) { // 开启时设置其他按钮禁用 重新布局曲谱页面
-                self.isEvaluating = YES;
-                
-                MJWeakSelf;
-                [self checkIsWiredHeadsetOnCallback:^{
-                    if (weakSelf.soundCheckOn && ![weakSelf.songMessageSource.subjectId isEqualToString:@"23"]) { // 如果是打击乐跳过
-                        [weakSelf startSoundCheck];
-                    }
-                }];
-            }
-            else { // 恢复按钮 重新恢复曲谱布局
-                self.isEvaluating = NO;
-            }
-        }
-            break;
-        case BUTTON_TAG_SELECT:
-        {
-            if (isSelected) {
-                self.isChooseMeasure = YES;
-            }
-            else {
-                [self stopPlayAction];
-                self.isChooseMeasure = NO;
-                // 清理全部
-                self.startMeasure = -1;
-                self.endMeasure = -1;
-                self.lastPlayNodeIndex = 0;
-                self.playerEngine.startTime = 0.0f;
-                self.playerEngine.endTime = 0.0f;
-                [self.playerEngine setProgressTime:self.playerEngine.startTime];
-                [self clearAllColorDisplayView];
-            }
-        }
-            break;
-        case BUTTON_TAG_PLAY:
-        {
-            if (isSelected) { // 播放
-
-                CGFloat rate = self.currentSpeed / self.playerEngine.baseRate;
-                [self.playerEngine setMusicPlayerSpeed:rate];
-                [self showBeatBeforePlay];
-            }
-            else { // 暂停
-                [self stopPlayAction];
-            }
-            
-        }
-            break;
-        case BUTTON_TAG_SWITCH:
-        {
-            [self.trackChooseView showInView:self.view];
-//            if (isSelected) { // 切换成伴奏
-//                [self.playerEngine muteTrack:YES WithTrack:self.playerEngine.baseInstrumentArray];
-//            }
-//            else { // 切换成原声
-//                [self.playerEngine muteTrack:NO WithTrack:self.playerEngine.baseInstrumentArray];
-//            }
-
-        }
-            break;
-        case BUTTON_TAG_REPEAT: // 从头开始播放
-        {
-            [self.playerEngine setProgressTime:0.0f];
-            [self displayCourseToFirstNode];
-            CloudControlButton *playButton = [self.headView viewWithTag:BUTTON_TAG_PLAY];
-            playButton.isSelected = YES;
-            [self showBeatBeforePlay];
-        }
-            break;
-        case BUTTON_TAG_SPEED: // 调速
-        {
-            // 显示调速控件
-            [self showSpeedView];
-        }
-            break;
-        case BUTTON_TAG_SETTING: // 设置
-        {
-            [self showSettingView];
-        }
-            break;
-        default:
-            break;
-    }
-}
-
-- (void)showSpeedView {
-    LFPopupMenu *popView = [[LFPopupMenu alloc] init];
-    popView.needBorder = YES;
-    popView.minWidth = 80;
-    [popView configWithCustomView:self.sliderView];
-    
-    CloudControlButton *playButton = [self.headView viewWithTag:BUTTON_TAG_SPEED];
-    [popView showArrowToView:playButton];
-}
-
-- (void)showSettingView {
-    KSCloudSettingView *settingView = [KSCloudSettingView shareInstance];
-    settingView.frame = CGRectMake(0, 0, KLandscapeWidth, KLandscapeHeight);
-    // 设置回调
-    MJWeakSelf;
-    [settingView settingCallback:^(CLOUDSETTING_TYPE type, BOOL isOn, NSString * _Nonnull level) {
-        [weakSelf configViewDisplayType:type isOn:isOn level:level];
-    }];
-    [self.view addSubview:settingView];
-}
-
-- (void)setBgColorType:(COLOR_DISPLAYTYPE)bgColorType {
-    _bgColorType = bgColorType;
-    if (bgColorType == COLOR_DISPLAYTYPE_PROTECT) {
-        self.bgColorView.backgroundColor = HexRGB(0xfff4e1);
-    }
-    else {
-        self.bgColorView.backgroundColor = [UIColor whiteColor];
-    }
-}
-
-
-- (void)configViewDisplayType:(CLOUDSETTING_TYPE)type isOn:(BOOL)isOn level:(NSString *)level {
-    switch (type) {
-        case CLOUDSETTING_TYPE_EYESHIELD: // 护眼模式
-        {
-            self.eyeShieldOn = isOn;
-            self.bgColorType = isOn ? COLOR_DISPLAYTYPE_PROTECT : COLOR_DISPLAYTYPE_NOMAL;
-        }
-            break;
-        case CLOUDSETTING_TYPE_SOUNDCHECK:
-        {
-            self.soundCheckOn = isOn;
-        }
-            break;
-        case CLOUDSETTING_TYPE_CAMERA:
-        {
-            self.backView.alpha = isOn ? BACKVIEW_ALPHA : 1.0f;
-            self.cameraOn = isOn;
-            [self openCamera:isOn];
-        }
-            break;
-        case CLOUDSETTING_TYPE_REPEAT:
-        {
-            self.isNeedRepeat = isOn;
-        }
-            break;
-        case CLOUDSETTING_TYPE_FINGER:
-        {
-            self.showFinger = isOn;
-            // 刷新页面布局
-            [self displayFingerView];
-        }
-            break;
-        case CLOUDSETTING_TYPE_LEVEL:
-        {
-            self.level = level;
-        }
-            break;
-        case CLOUDSETTING_TYPE_SAVEVIDEO:
-        {
-            self.saveVideo = isOn;
-        }
-            break;
-        case CLOUDSETTING_TYPE_ACCOMPANY:
-        {
-            self.accompanyOn = isOn;
-        }
-            break;
-        default:
-            break;
-    }
-}
-
-- (void)displayFingerView {
-    if (self.needShowFinger) {
-        [self.displayScrollView removeFromSuperview];
-        _displayScrollView = nil;
-        [self createDisplayScrollView];
-    }
-    else {
-        [self.fingerDisplayView removeFromSuperview];
-        [self.displayScrollView removeFromSuperview];
-        _displayScrollView = nil;
-        [self createDisplayScrollView];
-    }
-}
-
-- (void)openCamera:(BOOL)isOpen {
-    if (isOpen) { // 开启摄像头
-        PREMISSIONTYPE canOpenCamera = [RecordCheckManager checkCameraPremissionAvaiable];
-        if (canOpenCamera == PREMISSIONTYPE_YES) {
-            [self.videoRecordManager configSessiondisplayInView:self.viewContainer];
-        }
-    }
-    else {
-        if (self->_videoRecordManager) {
-            [self.videoRecordManager removeDisplay];
-        }
-    }
-}
-
-- (void)dealWithPositionX:(CGFloat)positionX positionY:(CGFloat)positionY pageIndex:(NSInteger)pageIndex {
-    //  如果不是选段模式 不计算
-    if (!self.isChooseMeasure) {
-        return;
-    }
-    
-    // 找到当前选择的小节
-    // 获取当前图片上对应的x,y所对应的位置文件中的 点
-    CGFloat locationX = positionX / self.scaleRate * PositionRate;
-    CGFloat locationY = positionY / self.scaleRate * PositionRate;
-    
-    for (KSParseMessageModel *model in self.manager.measureMessageArray) {
-        
-        if (model.pageIndex == pageIndex) { // 先找到当前的page数据
-            // 判断是否落在小节X轴范围区间
-            BOOL isLocationInX = (model.positionX < locationX && (model.positionX + model.elementWidth) >= locationX);
-            // 判断是否落在小节Y轴范围区间
-            BOOL isLocationInY = (model.positionY < locationY && (model.positionY + model.elementHeight) >= locationY);
-            if (isLocationInX && isLocationInY) { // 认为当前小节是被选中小节
-                NSInteger chooseMeasure = model.elementIndex;
-                [self evaluateChooseMeasure:chooseMeasure];
-                break;
-            }
-        }
-    }
-}
-
-- (void)evaluateChooseMeasure:(NSInteger)chooseMeasure {
-    if (self.startMeasure == -1 && self.endMeasure == -1) {
-        self.startMeasure = chooseMeasure;
-        self.endMeasure = chooseMeasure;
-    }
-    if (self.startMeasure > chooseMeasure) {
-        self.startMeasure = chooseMeasure;
-    }
-    else if (self.startMeasure < chooseMeasure) {
-        self.endMeasure = chooseMeasure;
-    }
-    // 获取选段时间
-    NSInteger index = self.startMeasure;
-    BOOL chooseEndMeasure = NO;
-    if (self.endMeasure == self.manager.measureMessageArray.count-1) {
-        chooseEndMeasure = YES;
-    }
-    NSInteger endIndex = chooseEndMeasure ? self.endMeasure : self.endMeasure+1;
-    // 1.根据小节找到小节开始的时值
-    for (KSParseMessageModel *model in self.manager.measureMessageArray) {
-        if (index == model.elementIndex) {
-            self.playerEngine.startTime = model.elementTimePosition / 1000;
-        }
-        else if (chooseEndMeasure) { // 如果结束是最后一小节
-            self.playerEngine.endTime = 0.0f;
-        }
-        // 如果不是最后一个小节
-        else if (!chooseEndMeasure && endIndex == model.elementIndex) {
-            self.playerEngine.endTime = model.elementTimePosition / 1000;
-        }
-    }
-    
-    // 重新绘制layer颜色
-    NSMutableArray *colorViewArray = [NSMutableArray array];
-    
-    for (KSParseMessageModel *model in self.manager.measureMessageArray) {
-        if (model.elementIndex >= self.startMeasure && model.elementIndex <= self.endMeasure) {
-            
-            KSMeasureLocationModel *measureLocation = [[KSMeasureLocationModel alloc] init];
-            measureLocation.positionX = model.positionX / PositionRate * self.scaleRate;
-            measureLocation.positionY = model.positionY / PositionRate * self.scaleRate;
-            measureLocation.measureWidth = model.elementWidth / PositionRate * self.scaleRate;
-            measureLocation.measureHeight = model.elementHeight / PositionRate * self.scaleRate;
-            measureLocation.pageIndex = model.pageIndex;
-            measureLocation.fillColor = HexRGB(0xffe7bd);
-            [colorViewArray addObject:measureLocation];
-        }
-    }
-    // 先清除全部color
-    [self clearAllColorDisplayView];
-    // 添加
-    for (KSMeasureLocationModel *model in colorViewArray) {
-        NSInteger index = model.pageIndex;
-        StaffImageDisplayView *view = self.pageArray[index];
-        [view addColorView:model];
-    }
-}
-
-- (void)clearAllColorDisplayView {
-    
-    for (StaffImageDisplayView *view in self.pageArray) {
-        [view clearAllColorView];
-    }
-}
-
-- (NSMutableArray *)getAllImageFile:(NSString *)path {
-    NSMutableArray *filePathArray = [NSMutableArray array];
-    NSFileManager *fileManger = [NSFileManager defaultManager];
-    BOOL isDir = NO;
-    BOOL isExist = [fileManger fileExistsAtPath:path isDirectory:&isDir];
-    if (isExist) {
-        if (isDir) {
-            NSArray * dirArray = [fileManger contentsOfDirectoryAtPath:path error:nil];
-            NSString * subPath = nil;
-            for (NSString * str in dirArray) {
-                subPath  = [path stringByAppendingPathComponent:str];
-                BOOL issubDir = NO;
-                [fileManger fileExistsAtPath:subPath isDirectory:&issubDir];
-                [self getAllImageFile:subPath];
-            }
-        }else{
-            NSString *fileName = [path getUrlFileName];
-            if ([fileName hasSuffix:@".png"]) {
-                //do anything you want
-                [filePathArray addObject:path];
-            }
-        }
-    }else{
-        NSLog(@"this path is not exist!");
-    }
-    return filePathArray;
-}
-
-- (void)backAction {
-    [self dismissViewControllerAnimated:YES completion:nil];
-}
-
-
-- (void)showFingerView {
-    
-    if (self.needShowFinger && self.fingerImageDic != nil) {
-        
-        NSMutableDictionary *parm  = self.nodeArray[self.lastPlayNodeIndex];
-        NSInteger noteValue = [parm ks_integerValueForKey:@"note_value"];
-
-        NSArray *noteFingerArray = [self.fingerImageDic ks_arrayValueForKey:[NSString stringWithFormat:@"%zd",noteValue]];
-        // 剔除
-        [self.fingerContentView removeAllSubViews];
-        
-        if (noteFingerArray.count) {
-            NSString *imgStr = [noteFingerArray firstObject];
-            NSArray *imgArray = [imgStr componentsSeparatedByString:@","];
-            
-            for (NSString *imgName in imgArray) {
-                UIImageView *fingerView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.fingerContentView.frame), CGRectGetHeight(self.fingerContentView.frame))];
-                [fingerView setImage:[UIImage imageNamed:imgName]];
-                [self.fingerContentView addSubview:fingerView];
-            }
-        }
-    }
-}
-
-
-- (void)showCursor {  // 显示光标
-    // 获取当前播放位置
-    [self.displayScrollView addSubview:self.cursorView];
-    if (self.startMeasure == -1) {
-        if (self.lastPlayNodeIndex == 0) {
-            [self displayCourseToFirstNode];
-        }
-    }
-    else {  // 获取当前选择小节
-        
-        NSInteger index = self.startMeasure;
-        Float64 timePosition = 0;
-        
-        // 1.根据小节找到小节开始的时值
-        for (KSParseMessageModel *model in self.manager.measureMessageArray) {
-            if (index == model.elementIndex) {
-                timePosition = model.elementTimePosition;
-                break;
-            }
-        }
-        // 2.根据时值获取对应音符位置
-        for (KSParseMessageModel *nodeModel in self.manager.nodeMessageArray) {
-            
-            if (nodeModel.elementTimePosition == timePosition) {
-                
-                [self moveCursorViewWithNode:nodeModel];
-                break;
-            }
-        }
-    }
-    self.cursorView.hidden = NO;
-}
-
-- (void)hideCursor {  // 隐藏光标
-    // 重置播放位置
-    self.cursorView.hidden = YES;
-    [self.cursorView removeFromSuperview];
-}
-
-- (void)displayCourseToFirstNode {
-    // 获取第一个音符位置
-    KSParseMessageModel *firstNode = self.manager.nodeMessageArray[0];
-    [self moveCursorViewWithNode:firstNode];
-}
-
-- (void)moveCursorViewWithNode:(KSParseMessageModel *)nodeModel {
-    self.lastPlayNodeIndex = nodeModel.elementIndex;
-    CGFloat positionX = nodeModel.positionX / PositionRate * self.scaleRate;
-    CGFloat positionY = nodeModel.positionY / PositionRate * self.scaleRate + self.pageViewHeight*(nodeModel.pageIndex);
-    CGFloat cursorWidth = nodeModel.elementWidth / PositionRate * self.scaleRate;
-    CGFloat cursorHeight = nodeModel.elementHeight / PositionRate * self.scaleRate;
-    self.cursorView.frame = CGRectMake(positionX, positionY, cursorWidth, cursorHeight);
-    
-    // 指法同步
-    [self showFingerView];
-}
-
-
-
-#pragma mark -------- lazying
-- (CGRect)defaultFrame {
-    return CGRectMake(Left_Space, 78, KLandscapeWidth - Left_Space*2, KLandscapeHeight - 78 - 10);
-}
-- (UIView *)cursorView {
-    if (!_cursorView) {
-        _cursorView = [[UIView alloc] initWithFrame:CGRectZero];
-        _cursorView.hidden = YES;
-        _cursorView.backgroundColor = HexRGBAlpha(0xff5a25, 0.4f);
-    }
-    return _cursorView;
-}
-- (UIScrollView *)displayScrollView {
-    if (!_displayScrollView) {
-        _displayScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.defaultFrame), CGRectGetHeight(self.defaultFrame))];
-        _displayScrollView.backgroundColor = [UIColor clearColor];
-        _displayScrollView.scrollEnabled = YES;
-        _displayScrollView.showsHorizontalScrollIndicator = NO;
-        _displayScrollView.showsVerticalScrollIndicator = NO;
-        _displayScrollView.bounces = NO;
-    }
-    return _displayScrollView;
-}
-
-- (NSMutableArray *)pageArray {
-    if (!_pageArray) {
-        _pageArray = [NSMutableArray array];
-    }
-    return _pageArray;
-}
-
-
-- (KSWebSocketManager *)socketManager {
-    if (!_socketManager) {
-        _socketManager = [[KSWebSocketManager alloc] init];
-    }
-    return _socketManager;
-}
-
-- (KSSliderView *)sliderView {
-    if (!_sliderView) {
-        _sliderView = [[KSSliderView alloc] initWithFrame:CGRectMake(0, 0, 50, 250)];
-        _sliderView.backgroundColor = [UIColor clearColor];
-        _sliderView.rateValue = self.currentSpeed;
-        _sliderView.isVertical = YES;
-        _sliderView.delegate = self;
-    }
-    return _sliderView;
-}
-
-- (NoWiredTipsAlert *)wiredAlert {
-    if (!_wiredAlert) {
-        _wiredAlert = [NoWiredTipsAlert shareInstance];
-        _wiredAlert.frame = CGRectMake(0, 0, KLandscapeWidth, KLandscapeHeight);
-    }
-    return _wiredAlert;
-}
-- (UIView *)viewContainer {
-    if (!_viewContainer) {
-        _viewContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KLandscapeWidth, KLandscapeHeight)];
-    }
-    return _viewContainer;
-}
-
-- (KSVideoRecordManager *)videoRecordManager {
-    if (!_videoRecordManager) {
-        MJWeakSelf;
-        _videoRecordManager = [[KSVideoRecordManager alloc] initSessionRecordCallback:^(BOOL isSuccess, NSString * _Nullable message) {
-            if (isSuccess) {
-                [weakSelf showSuccessMessage:message];
-            }
-            else {
-                if (![NSString isEmptyString:message]) {
-                    [LOADING_MANAGER MBShowAUTOHidingInWindow:message];
-                }
-            }
-        }];
-    }
-    return _videoRecordManager;
-}
-
-- (UIButton *)evaluateButton {
-    if (!_evaluateButton) {
-        _evaluateButton = [UIButton buttonWithType:UIButtonTypeCustom];
-        _evaluateButton.layer.cornerRadius = 22.0f;
-        [_evaluateButton setBackgroundColor:THEMECOLOR];
-        _evaluateButton.frame = CGRectMake((KLandscapeWidth - 150)/2.0f, KLandscapeHeight - 44 - 20, 150, 44);
-        [_evaluateButton.titleLabel setFont:[UIFont systemFontOfSize:18.0f weight:UIFontWeightMedium]];
-        [_evaluateButton setTitle:@"开始演奏" forState:UIControlStateNormal];
-        [_evaluateButton setTitle:@"√结束演奏" forState:UIControlStateSelected];
-        [_evaluateButton addTarget:self action:@selector(evaluateButtonAction:) forControlEvents:UIControlEventTouchUpInside];
-    }
-    return _evaluateButton;
-}
-
-- (void)evaluateButtonAction:(UIButton *)sender {
-    sender.selected = !sender.selected;
-    if (sender.isSelected) {
-        [self startEvaluateing];
-    }
-    else {
-        [self endEvaluating];
-    }
-}
-
-- (void)showSuccessMessage:(NSString *)message {
-    [LOADING_MANAGER MBShowAUTOHidingInWindow:message];
-}
-
-#pragma mark ----- KSSliderView delegate
-- (void)rateChangeAction:(NSInteger)rate {
-    self.currentSpeed = rate;
-    CloudControlButton *playButton = [self.headView viewWithTag:BUTTON_TAG_SPEED];
-    [playButton showSpeed:rate];
-    
-    // 速度写入本地文件中
-    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
-        
-        NSString *filePath = [CloudSongMessageModel getSaveSpeedPath];
-        NSDictionary *speedDic = [NSMutableDictionary dictionaryWithContentsOfFile:filePath];
-        NSMutableDictionary *saveDic = [NSMutableDictionary dictionaryWithDictionary:speedDic];
-        [saveDic setValue:@(rate) forKey:self.songMessageSource.examSongId];
-        NSError *err = nil;
-        if (@available(iOS 11.0, *)) {
-            [saveDic writeToURL:[NSURL fileURLWithPath:filePath] error:&err];
-        } else {
-            // Fallback on earlier versions
-            [saveDic writeToURL:[NSURL fileURLWithPath:filePath] atomically:YES];
-        }
-    });
-    
-    
-    double playRate = rate / self.playerEngine.baseRate;
-    [self.playerEngine setMusicPlayerSpeed:playRate];
-}
-
-#pragma mark ------ cloud function
-// 点击开始评测按钮
-- (void)startEvaluateing {
-    [self configRecordManager];
-    self.hasSendStartMessage = NO;
-    PREMISSIONTYPE isOk = [RecordCheckManager checkMicPermissionAvaiable];
-    if (isOk == PREMISSIONTYPE_YES) {
-        [self configXMLInfo];
-        // 如果socket 连上了
-        if (self.socketManager.socketReadyState == SR_OPEN) {
-            NSDictionary *content = self.evaluatParm;
-            NSString *sendData = [self configDataCommond:@"musicXml" body:content type:@"SOUND_COMPARE"];
-            [self sendDataToSocketService:sendData];
-            NSLog(@"------ send music xml info");
-            self.hasSendStartMessage = YES;
-            // 开始评测
-            [self showBeatBeforeEvaluating];
-        }
-        else {
-            [self connectSocketService];
-        }
-    }
-    else {
-        // 停止评测功能
-        [self cancelEvaluating];
-        [self showErrorMessage:@"没有麦克风权限"];
-    }
-}
-
-- (void)setIsEvaluating:(BOOL)isEvaluating {
-    _isEvaluating = isEvaluating;
-    if (isEvaluating) {
-        if (self.isPlaying) {
-            [self stopPlayAction];
-            
-        }
-        if (self.needShowFinger == YES) {
-            self.needShowFinger = NO;
-            [self displayFingerView];
-        }
-        [self.view addSubview:self.evaluateButton];
-        [self ForbiddenButton:YES];
-    }
-    else {
-        // 重置页面数据
-        if (_isPlaying) { // 如果在评测状态下
-            [self stopPlayAction];
-            [self endEvaluating];
-        }
-        [self displayCourseToFirstNode];
-        [self.playerEngine setProgressTime:0.0f];
-        [self.evaluateButton removeFromSuperview];
-        [self ForbiddenButton:NO];
-        if (self.showFinger == YES && self.fingerImageDic != nil) {
-            self.needShowFinger = YES;
-            [self displayFingerView];
-        }
-    }
-}
-
-- (void)ForbiddenButton:(BOOL)isForbidden {
-    for (NSInteger indexTag = 1001; indexTag < 1007; indexTag++) {
-        CloudControlButton *button = [self.headView viewWithTag:indexTag];
-        button.userInteractionEnabled = !isForbidden;
-        button.alpha =  isForbidden ? 0.6f : 1.0f;
-    }
-}
-
-
-#pragma mark ----- 节拍
-- (void)showBeatBeforePlay {
-    KSCloudBeatView *beatView = [KSCloudBeatView shareInstanceWithBeatType:self.beatType speed:self.currentSpeed repeatCount:1 supplement:0];
-    MJWeakSelf;
-    [beatView startPlayWithEndCallback:^(BOOL isCancle) {
-        if (isCancle) { // 取消
-            [weakSelf resetPlayButtonStatus];
-        }
-        else { // 开始播放
-            [weakSelf playAction];
-        }
-    }];
-    [self.view addSubview:beatView];
-}
-
-- (void)showBeatBeforeEvaluating {
-    KSCloudBeatView *beatView = [KSCloudBeatView shareInstanceWithBeatType:self.beatType speed:self.currentSpeed repeatCount:1 supplement:0];
-    MJWeakSelf;
-    [beatView startPlayWithEndCallback:^(BOOL isCancle) {
-        if (isCancle) { // 取消
-            [weakSelf cancelEvaluating];
-        }
-        else { // 开始播放
-            [weakSelf startPlayAndRecord];
-        }
-    }];
-    [self.view addSubview:beatView];
-}
-
-#pragma mark ---- 评测功能
-
-- (void)startPlayAndRecord {
-    if (self.cameraOn && self.saveVideo) {
-        [self startCapture];
-    }
-    if (self.isChooseMeasure) { // 重置选段
-        [self resetChooseMeasureStatus];
-    }
-    [self clearAllColorDisplayView];
-    CGFloat rate = self.currentSpeed / self.playerEngine.baseRate;
-    [self.playerEngine setMusicPlayerSpeed:rate];
-    [self.playerEngine setProgressTime:0.0f];
-    [self displayCourseToFirstNode];
-    [self playAction];
-    [self startRecording];
-    
-    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
-        // 发送时间校准消息
-        NSDictionary *bodyParm = @{
-            @"offsetTime" :@(0.000),
-        };
-        NSString *realStartTime = @"audioPlayStart";
-        NSString *realStart = [self configDataCommond:realStartTime body:bodyParm type:@"SOUND_COMPARE"];
-        [self sendDataToSocketService:realStart];
-        NSLog(@"--------- send check time message");
-    });
-}
-
-- (void)resetChooseMeasureStatus {
-    self.isChooseMeasure = NO;
-    // 清理全部
-    self.startMeasure = -1;
-    self.endMeasure = -1;
-    self.lastPlayNodeIndex = 0;
-    self.playerEngine.startTime = 0.0f;
-    self.playerEngine.endTime = 0.0f;
-    CloudControlButton *button = [self.headView viewWithTag:BUTTON_TAG_SELECT];
-    button.isSelected = NO;
-}
-
-- (void)configXMLInfo {
-    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
-    [dic setValue:@(0) forKey:@"beatLength"];
-    [dic setValue:@"IOS" forKey:@"platform"];
-    
-    [dic setValue:self.songMessageSource.behaviorId forKey:@"behaviorId"];
-    [dic setValue:@"1638175609911244308" forKey:@"uuid"];
-    [dic setValue:self.songMessageSource.detailId forKey:@"detailId"];
-    [dic setValue:self.songMessageSource.examSongId forKey:@"examSongId"];
-    [dic setValue:self.songMessageSource.subjectId forKey:@"subjectId"];
-    [dic setValue:self.songMessageSource.examSongId forKey:@"id"];
-    [dic setValue:self.songMessageSource.xmlUrl forKey:@"xmlUrl"];
-    // head level
-    [dic setValue:self.level forKey:@"heardLevel"];
-    
-    // 设置速度
-    [dic setValue:@(self.currentSpeed) forKey:@"speed"];
-    NSMutableArray *newNodeArray = [self configNodeArrayWithSpeed:self.currentSpeed];
-    [dic setValue:newNodeArray forKey:@"musicXmlInfos"];
-    
-    self.evaluatParm = dic;
-}
-
-- (NSMutableArray *)configNodeArrayWithSpeed:(NSInteger)speed {
-    NSMutableArray *sourceArray = [NSMutableArray array];
-    if (speed == 120) {
-        sourceArray = [NSMutableArray arrayWithArray:self.nodeArray];
-        return sourceArray;
-    }
-    for (NSMutableDictionary *parm in self.nodeArray) {
-        NSMutableDictionary *node = [parm mutableCopy];
-        float timeSapmle = [node ks_floatValueForKey:@"timeStamp"];
-        float duration = [node ks_floatValueForKey:@"duration"];
-        timeSapmle = timeSapmle * (120.0 / speed);
-        duration = duration * (120.0 / speed);
-        [node setValue:@(timeSapmle) forKey:@"timeStamp"];
-        [node setValue:@(duration) forKey:@"duration"];
-        [sourceArray addObject:node];
-    }
-    return sourceArray;
-}
-
-/* 停止评测功能 */
-- (void)endEvaluating {
-    [self stopPlayAction];
-    self.evaluateButton.selected = NO;
-    self.evaluatParm = nil;
-    [self stopRecordService];
-    [self sendEndMessage];
-    [self stopCapatureVideo];
-}
-
-/* 取消评测*/
-- (void)cancelEvaluating {
-    [self stopPlayAction];
-    self.evaluateButton.selected = NO;
-    self.evaluatParm = nil;
-    [self stopRecordService];
-    [self sendEndMessage];
-    [self stopCapatureVideo];
-}
-
-// 如果开启了保存相册和摄像头 结束评测时停止录制
-- (void)stopCapatureVideo {
-    if (self.cameraOn && self.saveVideo) {
-        [self endCapture];
-    }
-}
-
-// 是否带耳机检测
-- (void)checkIsWiredHeadsetOnCallback:(void(^)(void))callback {
-    AUDIODEVICE_TYPE type = [KSAQRecordManager queryAudioOutputDeviceType];
-    NSString *valueStr = @"";
-    BOOL checkIsWired = NO;
-    switch (type) {
-        case AUDIODEVICE_TYPE_HEADPHONE:
-        {
-            valueStr = @"有线耳机";
-            checkIsWired = YES;
-        }
-            break;
-        case AUDIODEVICE_TYPE_BLUETOOTH:
-        {
-            valueStr = @"蓝牙耳机";
-            checkIsWired = YES;
-        }
-            break;
-        case AUDIODEVICE_TYPE_NONE:
-        {
-            valueStr = @"";
-            checkIsWired = NO;
-        }
-            break;
-        default:
-            break;
-    }
-    
-    if (checkIsWired == NO) { // 未带耳机弹窗提示
-        [self showNoWiredTipsAlertCallback:^{
-            callback();
-        }];
-    }
-    
-}
-
-- (void)showNoWiredTipsAlertCallback:(void(^)(void))callback {
-    if (![self.view.subviews containsObject:self.wiredAlert]) {
-        [self.wiredAlert showAlertInView:self.view callback:^{
-            callback();
-        }];
-    }
-}
-
-/* 开始录音*/
-- (void)startRecording {
-    self.isCompareStart = YES;
-    [self startRecordService];
-}
-
-/* 停止录音*/
-- (void)endRecording {
-    [self stopRecordService];
-}
-
-/* 开始录制*/
-- (void)startCapture {
-    // 评测的时候 生成video时会合成声轨
-    BOOL isIgnoreAudio = self.isEvaluating;
-    [self.videoRecordManager setIgnoreAudio:isIgnoreAudio];
-    [RecordCheckManager checkPhotoLibraryPremissionAvaiable];
-    self.videoRecordManager.audioUrl = self.AQManager.audioUrl;
-    [self.videoRecordManager startRecord];
-}
-
-/* 结束录制*/
-- (void)endCapture {
-    if (self->_videoRecordManager) {
-        [self.videoRecordManager stopRecord];
-    }
-}
-/* 开始校音*/
-- (void)startSoundCheck {
-    [self showSoundCheckView];
-    
-    [self configRecordManager];
-    self.isCompareStart = NO;
-    self.isSoundCheckStart = YES;
-    [self startRecordService];
-}
-
-- (void)showSoundCheckView {
-    self.checkView = [SoundCheckView shareInstance];
-    MJWeakSelf;
-    [self.checkView configSoundCheckWithSubjectId:self.songMessageSource.subjectId callback:^(CLOSEACTION action) {
-        if (action == CLOSEACTION_SUCCESS) {
-            [weakSelf showSuccessMessage:@"校音成功"];
-        }
-        else if (action == CLOSEACTION_CLOSECHECK) { // 关闭校音
-            weakSelf.soundCheckOn = NO;
-            NSDictionary *config = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"cloudConfig"];
-            NSMutableDictionary *configDict = [NSMutableDictionary dictionaryWithDictionary:config];
-            [configDict setValue:@(NO) forKey:@"soundCheck"];
-            [[NSUserDefaults standardUserDefaults] setObject:configDict forKey:@"cloudConfig"];
-            [[NSUserDefaults standardUserDefaults] synchronize];
-        }
-        [weakSelf endSoundCheck];
-    }];
-    self.checkPitch = self.checkView.pitch;
-    self.checkView.frame = CGRectMake(0, 0, KLandscapeWidth, KLandscapeHeight);
-    [self.view addSubview:self.checkView];
-}
-
-/* 结束校音*/
-- (void)endSoundCheck {
-    // 结束校音
-    self.isSoundCheckStart = NO;
-    [self stopRecordService];
-}
-
-/* 上传视频*/
-- (void)videoUpdate {
-    
-    if (self.videoRecordManager) {
-//        MJWeakSelf;
-//        [self.videoRecordManager uploadRecordVideoSuccess:^(NSString * _Nonnull videoUrl) {
-//            if (videoUrl) {
-//                [weakSelf sendUploadMessage:videoUrl];
-//            }
-//        } failure:^(NSString * _Nonnull desc) {
-//            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"视频上传失败"];
-//        }];
-    }
-}
-
-- (void)sendUploadMessage:(NSString *)videoUrl {
-    NSDictionary *header = @{@"commond" : @"videoUpdate",
-                             @"type" : @"SOUND_COMPARE",
-                             @"status" : @(200),
-    };
-    NSMutableDictionary *body = [NSMutableDictionary dictionary];
-    [body setValue:@(self.recordId) forKey:@"recordId"];
-    if ([NSString isEmptyString:videoUrl]) {
-        [body setValue:@(self.recordId) forKey:@"recordId"];
-    }
-        
-    NSMutableDictionary *content = [NSMutableDictionary dictionary];
-    [content setValue:header forKey:@"header"];
-    [content setValue:body forKey:@"body"];
-    [content setValue:@"1638175609911244308" forKey:@"uuid"];
-    
-    NSString *sendData = [content mj_JSONString];
-    [self sendDataToSocketService:sendData];
-    [LOADING_MANAGER MBShowAUTOHidingInWindow:@"上传成功"];
-}
-
-- (void)dealloc {
-    [[NSNotificationCenter defaultCenter] removeObserver:self];
-    NSLog(@"------- cloud dealloc");
-}
-
-- (TrackChooseView *)trackChooseView {
-    if (!_trackChooseView) {
-        _trackChooseView = [TrackChooseView shareInstanceWithFullTrackArray:self.playerEngine.instrumentTrackNameArray];
-        MJWeakSelf;
-        [_trackChooseView chooseTrackCallback:^(NSMutableArray * _Nullable trackNameArray) {
-            [weakSelf operationWithTrackNameArray:trackNameArray];
-        }];
-    }
-    return _trackChooseView;
-}
-
-- (void)operationWithTrackNameArray:(NSMutableArray *)trackNameArray {
-    [self.playerEngine muteTrackWithTrackNameExclude:trackNameArray];
-}
-
-/*
-#pragma mark - Navigation
-
-// In a storyboard-based application, you will often want to do a little preparation before navigation
-- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
-    // Get the new view controller using [segue destinationViewController].
-    // Pass the selected object to the new view controller.
-}
-*/
-
-@end

+ 0 - 33
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/CloudSongMessageModel.h

@@ -1,33 +0,0 @@
-//
-//  CloudSongMessageModel.h
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/9.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface CloudSongMessageModel : NSObject
-
-@property (nonatomic, strong) NSString *detailId;  // 返回的id
-
-@property (nonatomic, strong) NSString *subjectId;     // 声部id
-
-@property (nonatomic, strong) NSString *examSongId;    // 曲目id
-
-@property (nonatomic, strong) NSString *examSongName;  // 曲目名称
-
-@property (nonatomic, strong) NSString *zipUrl;
-
-@property (nonatomic, strong) NSString *xmlUrl;
-
-@property (nonatomic, strong) NSString *behaviorId; // 统计批次ID
-
-+ (NSString *)getSaveSpeedPath;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 35
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/CloudSongMessageModel.m

@@ -1,35 +0,0 @@
-//
-//  CloudSongMessageModel.m
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/9.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import "CloudSongMessageModel.h"
-
-@implementation CloudSongMessageModel
-
-+ (NSString *)getSaveSpeedPath {
-    //  在Documents目录下创建一个名为AudioSpeedFile的文件夹
-    NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"AudioSpeedFile"];
-    NSLog(@"%@",path);
-    
-    NSFileManager *fileManager = [NSFileManager defaultManager];
-    BOOL isDir = FALSE;
-    BOOL isDirExist = [fileManager fileExistsAtPath:path isDirectory:&isDir];
-    if(!(isDirExist && isDir)) {
-        BOOL bCreateDir = [fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
-        if(!bCreateDir){
-            NSLog(@"创建文件夹失败!");
-        }
-        NSLog(@"创建文件夹成功,文件路径%@",path);
-    }
-    
-    path = [path stringByAppendingPathComponent:@"songSpeed.plist"];
-    NSLog(@"file path:%@",path);
-    return path;
-}
-
-
-@end

+ 0 - 1206
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/FingerList.plist

@@ -1,1206 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>flute</key>
-	<dict>
-		<key>60</key>
-		<array>
-			<string>flute13,flute12,flute11,flute1,flute10,flute8,flute3,flute6</string>
-		</array>
-		<key>61</key>
-		<array>
-			<string>flute13,flute12,flute11,flute1,flute10,flute8,flute3,flute7</string>
-		</array>
-		<key>62</key>
-		<array>
-			<string>flute13,flute12,flute11,flute1,flute10,flute8,flute3</string>
-		</array>
-		<key>63</key>
-		<array>
-			<string>flute13,flute12,flute11,flute1,flute10,flute8,flute3,flute5</string>
-		</array>
-		<key>64</key>
-		<array>
-			<string>flute13,flute12,flute11,flute1,flute10,flute8,flute5</string>
-		</array>
-		<key>65</key>
-		<array>
-			<string>flute13,flute12,flute11,flute1,flute10,flute5</string>
-		</array>
-		<key>66</key>
-		<array>
-			<string>flute13,flute12,flute11,flute1,flute3,flute5</string>
-		</array>
-		<key>67</key>
-		<array>
-			<string>flute13,flute12,flute11,flute1,flute5</string>
-		</array>
-		<key>68</key>
-		<array>
-			<string>flute13,flute12,flute11,flute1,flute4,flute5</string>
-		</array>
-		<key>69</key>
-		<array>
-			<string>flute13,flute12,flute1,flute5</string>
-		</array>
-		<key>70</key>
-		<array>
-			<string>flute13,flute0,flute5</string>
-			<string>flute13,flute10,flute1,flute5</string>
-		</array>
-		<key>71</key>
-		<array>
-			<string>flute13,flute1,flute5</string>
-		</array>
-		<key>72</key>
-		<array>
-			<string>flute13,flute5</string>
-		</array>
-		<key>73</key>
-		<array>
-			<string>flute5</string>
-		</array>
-		<key>74</key>
-		<array>
-			<string>flute12,flute11,flute10,flute8,flute3,flute1</string>
-		</array>
-		<key>75</key>
-		<array>
-			<string>flute12,flute11,flute10,flute8,flute3,flute5,flute1</string>
-		</array>
-		<key>76</key>
-		<array>
-			<string>flute13,flute12,flute11,flute1,flute10,flute8,flute5</string>
-		</array>
-		<key>77</key>
-		<array>
-			<string>flute13,flute12,flute11,flute1,flute10,flute5</string>
-		</array>
-		<key>78</key>
-		<array>
-			<string>flute13,flute12,flute11,flute1,flute3,flute5</string>
-		</array>
-		<key>79</key>
-		<array>
-			<string>flute13,flute12,flute11,flute1,flute5</string>
-		</array>
-		<key>80</key>
-		<array>
-			<string>flute13,flute12,flute11,flute1,flute4,flute5</string>
-		</array>
-		<key>81</key>
-		<array>
-			<string>flute13,flute12,flute1,flute5</string>
-		</array>
-		<key>82</key>
-		<array>
-			<string>flute13,flute0,flute5</string>
-			<string>flute13,flute10,flute1,flute5</string>
-		</array>
-		<key>83</key>
-		<array>
-			<string>flute13,flute1,flute5</string>
-		</array>
-		<key>84</key>
-		<array>
-			<string>flute13,flute5</string>
-		</array>
-		<key>85</key>
-		<array>
-			<string>flute5</string>
-		</array>
-		<key>86</key>
-		<array>
-			<string>flute12,flute11,flute1,flute5</string>
-		</array>
-		<key>87</key>
-		<array>
-			<string>flute13,flute12,flute11,flute1,flute10,flute8,flute3,flute5</string>
-		</array>
-		<key>88</key>
-		<array>
-			<string>flute13,flute12,flute1,flute10,flute8,flute5</string>
-		</array>
-		<key>89</key>
-		<array>
-			<string>flute13,flute11,flute1,flute5</string>
-		</array>
-	</dict>
-	<key>clarinet</key>
-	<dict>
-		<key>52</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet13,clarinet17,clarinet19</string>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet13,clarinet19</string>
-		</array>
-		<key>53</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet11,clarinet19</string>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet17,clarinet19</string>
-		</array>
-		<key>54</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet12,clarinet17,clarinet19</string>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet12,clarinet19</string>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet14</string>
-		</array>
-		<key>55</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet19</string>
-		</array>
-		<key>56</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet15,clarinet19</string>
-		</array>
-		<key>57</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet19</string>
-		</array>
-		<key>58</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet19</string>
-		</array>
-		<key>59</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet8,clarinet19</string>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet9,clarinet19</string>
-		</array>
-		<key>60</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet9</string>
-		</array>
-		<key>61</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet6,clarinet19</string>
-		</array>
-		<key>62</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet19</string>
-		</array>
-		<key>63</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet19,clarinet23</string>
-			<string>clarinet2,clarinet3,clarinet4,clarinet19</string>
-			<string>clarinet2,clarinet7,clarinet19</string>
-		</array>
-		<key>64</key>
-		<array>
-			<string>clarinet2,clarinet19</string>
-		</array>
-		<key>65</key>
-		<array>
-			<string>clarinet19</string>
-		</array>
-		<key>66</key>
-		<array>
-			<string>clarinet2</string>
-			<string>clarinet19,clarinet22,clarinet23</string>
-		</array>
-		<key>67</key>
-		<array>
-			<string></string>
-		</array>
-		<key>68</key>
-		<array>
-			<string>clarinet1</string>
-		</array>
-		<key>69</key>
-		<array>
-			<string>clarinet0</string>
-		</array>
-		<key>70</key>
-		<array>
-			<string>clarinet0,clarinet18</string>
-		</array>
-		<key>71</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet13,clarinet17,clarinet18,clarinet19</string>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet13,clarinet18,clarinet19</string>
-		</array>
-		<key>72</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet12,clarinet18,clarinet19</string>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet17,clarinet18,clarinet19</string>
-		</array>
-		<key>73</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet12,clarinet18,clarinet19</string>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet12,clarinet17,clarinet18,clarinet19</string>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet14,clarinet18,clarinet19</string>
-		</array>
-		<key>74</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet18,clarinet19</string>
-		</array>
-		<key>75</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet10,clarinet15,clarinet18,clarinet19</string>
-		</array>
-		<key>76</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet8,clarinet18,clarinet19</string>
-		</array>
-		<key>77</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet18,clarinet19</string>
-		</array>
-		<key>78</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet8,clarinet18,clarinet19</string>
-			<string>clarinet2,clarinet3,clarinet5,clarinet7,clarinet9,clarinet18,clarinet19</string>
-		</array>
-		<key>79</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet18,clarinet19</string>
-		</array>
-		<key>80</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet5,clarinet6,clarinet18,clarinet19</string>
-		</array>
-		<key>81</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet18,clarinet19</string>
-		</array>
-		<key>82</key>
-		<array>
-			<string>clarinet2,clarinet3,clarinet18,clarinet19,clarinet23</string>
-			<string>clarinet2,clarinet3,clarinet4,clarinet18,clarinet19</string>
-			<string>clarinet2,clarinet3,clarinet7,clarinet18,clarinet19</string>
-		</array>
-		<key>83</key>
-		<array>
-			<string>clarinet2,clarinet18,clarinet19</string>
-		</array>
-		<key>84</key>
-		<array>
-			<string>clarinet18,clarinet19</string>
-		</array>
-		<key>85</key>
-		<array>
-			<string>clarinet3,clarinet5,clarinet7,clarinet8,clarinet18,clarinet19</string>
-		</array>
-		<key>86</key>
-		<array>
-			<string>clarinet3,clarinet5,clarinet7,clarinet15,clarinet18,clarinet19</string>
-		</array>
-		<key>87</key>
-		<array>
-			<string>clarinet3,clarinet5,clarinet7,clarinet9,clarinet15,clarinet18,clarinet19</string>
-			<string>clarinet3,clarinet5,clarinet8,clarinet15,clarinet18,clarinet19</string>
-		</array>
-		<key>88</key>
-		<array>
-			<string>clarinet3,clarinet5,clarinet15,clarinet18,clarinet19</string>
-		</array>
-		<key>89</key>
-		<array>
-			<string>clarinet3,clarinet5,clarinet6,clarinet15,clarinet18,clarinet19</string>
-		</array>
-	</dict>
-	<key>trumpet</key>
-	<dict>
-		<key>0</key>
-		<array>
-			<string>trumpet0,trumpet1,trumpet2</string>
-		</array>
-		<key>54</key>
-		<array>
-			<string>trumpet3,trumpet4,trumpet5</string>
-		</array>
-		<key>55</key>
-		<array>
-			<string>trumpet3,trumpet1,trumpet5</string>
-		</array>
-		<key>56</key>
-		<array>
-			<string>trumpet0,trumpet4,trumpet5</string>
-		</array>
-		<key>57</key>
-		<array>
-			<string>trumpet3,trumpet4,trumpet2</string>
-		</array>
-		<key>58</key>
-		<array>
-			<string>trumpet3,trumpet1,trumpet2</string>
-		</array>
-		<key>59</key>
-		<array>
-			<string>trumpet0,trumpet4,trumpet2</string>
-		</array>
-		<key>60</key>
-		<array>
-			<string>trumpet0,trumpet1,trumpet2</string>
-		</array>
-		<key>61</key>
-		<array>
-			<string>trumpet3,trumpet4,trumpet5</string>
-		</array>
-		<key>62</key>
-		<array>
-			<string>trumpet3,trumpet1,trumpet5</string>
-		</array>
-		<key>63</key>
-		<array>
-			<string>trumpet0,trumpet4,trumpet5</string>
-		</array>
-		<key>64</key>
-		<array>
-			<string>trumpet3,trumpet4,trumpet2</string>
-		</array>
-		<key>65</key>
-		<array>
-			<string>trumpet3,trumpet1,trumpet2</string>
-		</array>
-		<key>66</key>
-		<array>
-			<string>trumpet0,trumpet4,trumpet2</string>
-		</array>
-		<key>67</key>
-		<array>
-			<string>trumpet0,trumpet1,trumpet2</string>
-		</array>
-		<key>68</key>
-		<array>
-			<string>trumpet0,trumpet4,trumpet5</string>
-		</array>
-		<key>69</key>
-		<array>
-			<string>trumpet3,trumpet4,trumpet2</string>
-		</array>
-		<key>70</key>
-		<array>
-			<string>trumpet3,trumpet1,trumpet2</string>
-		</array>
-		<key>71</key>
-		<array>
-			<string>trumpet0,trumpet4,trumpet2</string>
-		</array>
-		<key>72</key>
-		<array>
-			<string>trumpet0,trumpet1,trumpet2</string>
-		</array>
-		<key>73</key>
-		<array>
-			<string>trumpet3,trumpet4,trumpet2</string>
-		</array>
-		<key>74</key>
-		<array>
-			<string>trumpet3,trumpet1,trumpet2</string>
-		</array>
-		<key>75</key>
-		<array>
-			<string>trumpet0,trumpet4,trumpet2</string>
-		</array>
-		<key>76</key>
-		<array>
-			<string>trumpet0,trumpet1,trumpet2</string>
-		</array>
-		<key>77</key>
-		<array>
-			<string>trumpet3,trumpet1,trumpet2</string>
-		</array>
-		<key>78</key>
-		<array>
-			<string>trumpet0,trumpet3,trumpet2</string>
-		</array>
-		<key>79</key>
-		<array>
-			<string>trumpet0,trumpet1,trumpet2</string>
-		</array>
-		<key>80</key>
-		<array>
-			<string>trumpet0,trumpet4,trumpet5</string>
-		</array>
-		<key>81</key>
-		<array>
-			<string>trumpet3,trumpet4,trumpet2</string>
-		</array>
-		<key>82</key>
-		<array>
-			<string>trumpet3,trumpet1,trumpet2</string>
-		</array>
-		<key>83</key>
-		<array>
-			<string>trumpet0,trumpet4,trumpet2</string>
-		</array>
-		<key>84</key>
-		<array>
-			<string>trumpet0,trumpet1,trumpet2</string>
-		</array>
-	</dict>
-	<key>horn</key>
-	<dict>
-		<key>53</key>
-		<array>
-			<string>horn1</string>
-		</array>
-		<key>54</key>
-		<array>
-			<string>horn2</string>
-		</array>
-		<key>55</key>
-		<array>
-			<string></string>
-		</array>
-		<key>56</key>
-		<array>
-			<string>horn2,horn3</string>
-		</array>
-		<key>57</key>
-		<array>
-			<string>horn1,horn2</string>
-		</array>
-		<key>58</key>
-		<array>
-			<string>horn1</string>
-		</array>
-		<key>59</key>
-		<array>
-			<string>horn2</string>
-		</array>
-		<key>60</key>
-		<array>
-			<string></string>
-		</array>
-		<key>61</key>
-		<array>
-			<string>horn1,horn2</string>
-		</array>
-		<key>62</key>
-		<array>
-			<string>horn1</string>
-		</array>
-		<key>63</key>
-		<array>
-			<string></string>
-		</array>
-		<key>65</key>
-		<array>
-			<string>horn1</string>
-		</array>
-		<key>66</key>
-		<array>
-			<string>horn2</string>
-		</array>
-		<key>67</key>
-		<array>
-			<string></string>
-		</array>
-		<key>68</key>
-		<array>
-			<string>horn0,horn2,horn3</string>
-		</array>
-		<key>69</key>
-		<array>
-			<string>horn0,horn1,horn2</string>
-		</array>
-		<key>70</key>
-		<array>
-			<string>horn0,horn1</string>
-		</array>
-		<key>71</key>
-		<array>
-			<string>horn0,horn2</string>
-		</array>
-		<key>72</key>
-		<array>
-			<string>horn0</string>
-		</array>
-		<key>73</key>
-		<array>
-			<string>horn0,horn2,horn3</string>
-		</array>
-		<key>74</key>
-		<array>
-			<string>horn0,horn1,horn2</string>
-		</array>
-		<key>75</key>
-		<array>
-			<string>horn0,horn1</string>
-		</array>
-		<key>76</key>
-		<array>
-			<string>horn0,horn2</string>
-		</array>
-		<key>77</key>
-		<array>
-			<string>horn0</string>
-		</array>
-		<key>78</key>
-		<array>
-			<string>horn0,horn2</string>
-		</array>
-		<key>79</key>
-		<array>
-			<string>horn0</string>
-		</array>
-		<key>80</key>
-		<array>
-			<string>horn0,horn2,horn3</string>
-		</array>
-		<key>81</key>
-		<array>
-			<string>horn0,horn1,horn3</string>
-		</array>
-		<key>82</key>
-		<array>
-			<string>horn0,horn1</string>
-		</array>
-		<key>83</key>
-		<array>
-			<string>horn0,horn2</string>
-		</array>
-		<key>84</key>
-		<array>
-			<string>horn0</string>
-		</array>
-	</dict>
-	<key>up-bass-horn</key>
-	<dict>
-		<key>0</key>
-		<array>
-			<string>up-bass-horn0,up-bass-horn1,up-bass-horn2</string>
-		</array>
-		<key>40</key>
-		<array>
-			<string>up-bass-horn3,up-bass-horn4,up-bass-horn5</string>
-		</array>
-		<key>41</key>
-		<array>
-			<string>up-bass-horn3,up-bass-horn1,up-bass-horn5</string>
-		</array>
-		<key>42</key>
-		<array>
-			<string>up-bass-horn0,up-bass-horn4,up-bass-horn5</string>
-		</array>
-		<key>43</key>
-		<array>
-			<string>up-bass-horn3,up-bass-horn4,up-bass-horn2</string>
-		</array>
-		<key>44</key>
-		<array>
-			<string>up-bass-horn3,up-bass-horn1,up-bass-horn2</string>
-		</array>
-		<key>45</key>
-		<array>
-			<string>up-bass-horn0,up-bass-horn4,up-bass-horn2</string>
-		</array>
-		<key>46</key>
-		<array>
-			<string>up-bass-horn0,up-bass-horn1,up-bass-horn2</string>
-		</array>
-		<key>47</key>
-		<array>
-			<string>up-bass-horn3,up-bass-horn4,up-bass-horn5</string>
-		</array>
-		<key>48</key>
-		<array>
-			<string>up-bass-horn3,up-bass-horn1,up-bass-horn5</string>
-		</array>
-		<key>49</key>
-		<array>
-			<string>up-bass-horn0,up-bass-horn4,up-bass-horn5</string>
-		</array>
-		<key>50</key>
-		<array>
-			<string>up-bass-horn3,up-bass-horn4,up-bass-horn2</string>
-		</array>
-		<key>51</key>
-		<array>
-			<string>up-bass-horn3,up-bass-horn1,up-bass-horn2</string>
-		</array>
-		<key>52</key>
-		<array>
-			<string>up-bass-horn0,up-bass-horn4,up-bass-horn2</string>
-		</array>
-		<key>53</key>
-		<array>
-			<string>up-bass-horn0,up-bass-horn1,up-bass-horn2</string>
-		</array>
-		<key>54</key>
-		<array>
-			<string>up-bass-horn0,up-bass-horn4,up-bass-horn5</string>
-		</array>
-		<key>55</key>
-		<array>
-			<string>up-bass-horn3,up-bass-horn4,up-bass-horn2</string>
-		</array>
-		<key>56</key>
-		<array>
-			<string>up-bass-horn3,up-bass-horn1,up-bass-horn2</string>
-		</array>
-		<key>57</key>
-		<array>
-			<string>up-bass-horn0,up-bass-horn4,up-bass-horn2</string>
-		</array>
-		<key>58</key>
-		<array>
-			<string>up-bass-horn0,up-bass-horn1,up-bass-horn2</string>
-		</array>
-		<key>59</key>
-		<array>
-			<string>up-bass-horn3,up-bass-horn4,up-bass-horn2</string>
-		</array>
-		<key>60</key>
-		<array>
-			<string>up-bass-horn3,up-bass-horn1,up-bass-horn2</string>
-		</array>
-		<key>61</key>
-		<array>
-			<string>up-bass-horn0,up-bass-horn4,up-bass-horn2</string>
-		</array>
-		<key>62</key>
-		<array>
-			<string>up-bass-horn0,up-bass-horn1,up-bass-horn2</string>
-		</array>
-		<key>63</key>
-		<array>
-			<string>up-bass-horn3,up-bass-horn1,up-bass-horn2</string>
-		</array>
-		<key>64</key>
-		<array>
-			<string>up-bass-horn0,up-bass-horn4,up-bass-horn2</string>
-		</array>
-		<key>65</key>
-		<array>
-			<string>up-bass-horn0,up-bass-horn1,up-bass-horn2</string>
-		</array>
-		<key>66</key>
-		<array>
-			<string>up-bass-horn0,up-bass-horn4,up-bass-horn5</string>
-		</array>
-		<key>67</key>
-		<array>
-			<string>up-bass-horn3,up-bass-horn4,up-bass-horn2</string>
-		</array>
-		<key>68</key>
-		<array>
-			<string>up-bass-horn3,up-bass-horn1,up-bass-horn2</string>
-		</array>
-		<key>69</key>
-		<array>
-			<string>up-bass-horn0,up-bass-horn4,up-bass-horn2</string>
-		</array>
-		<key>70</key>
-		<array>
-			<string>up-bass-horn0,up-bass-horn1,up-bass-horn2</string>
-		</array>
-	</dict>
-	<key>trombone</key>
-	<dict>
-		<key>0</key>
-		<array>
-			<string>trombone0</string>
-		</array>
-        <key>40</key>
-        <array>
-            <string>trombone6</string>
-        </array>
-        <key>41</key>
-        <array>
-            <string>trombone5</string>
-        </array>
-        <key>42</key>
-        <array>
-            <string>trombone4</string>
-        </array>
-        <key>43</key>
-        <array>
-            <string>trombone3</string>
-        </array>
-        <key>44</key>
-        <array>
-            <string>trombone2</string>
-        </array>
-        <key>45</key>
-        <array>
-            <string>trombone1</string>
-        </array>
-        <key>46</key>
-        <array>
-            <string>trombone0</string>
-        </array>
-        <key>47</key>
-        <array>
-            <string>trombone6</string>
-        </array>
-        <key>48</key>
-        <array>
-            <string>trombone5</string>
-        </array>
-        <key>49</key>
-        <array>
-            <string>trombone4</string>
-        </array>
-        <key>50</key>
-        <array>
-            <string>trombone3</string>
-        </array>
-        <key>51</key>
-        <array>
-            <string>trombone2</string>
-        </array>
-        <key>52</key>
-        <array>
-            <string>trombone1</string>
-        </array>
-        <key>53</key>
-        <array>
-            <string>trombone0</string>
-        </array>
-        <key>54</key>
-        <array>
-            <string>trombone4</string>
-        </array>
-        <key>55</key>
-        <array>
-            <string>trombone3</string>
-        </array>
-        <key>56</key>
-        <array>
-            <string>trombone2</string>
-        </array>
-        <key>57</key>
-        <array>
-            <string>trombone1</string>
-        </array>
-        <key>58</key>
-        <array>
-            <string>trombone0</string>
-        </array>
-        <key>59</key>
-        <array>
-            <string>trombone3</string>
-        </array>
-        <key>60</key>
-        <array>
-            <string>trombone2</string>
-        </array>
-        <key>61</key>
-        <array>
-            <string>trombone1</string>
-        </array>
-        <key>62</key>
-        <array>
-            <string>trombone0</string>
-        </array>
-        <key>63</key>
-        <array>
-            <string>trombone2</string>
-        </array>
-        <key>64</key>
-        <array>
-            <string>trombone1</string>
-        </array>
-        <key>65</key>
-        <array>
-            <string>trombone0</string>
-        </array>
-        <key>66</key>
-        <array>
-            <string>trombone2</string>
-        </array>
-        <key>67</key>
-        <array>
-            <string>trombone1</string>
-        </array>
-        <key>68</key>
-        <array>
-            <string>trombone2</string>
-        </array>
-        <key>69</key>
-        <array>
-            <string>trombone1</string>
-        </array>
-        <key>70</key>
-        <array>
-            <string>trombone0</string>
-        </array>
-	</dict>
-    <key>saxophone</key>
-    <dict>
-        <key>58</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4,saxophone12,saxophone16,saxophone17,saxophone18,saxophone22</string>
-        </array>
-        <key>59</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4,saxophone10,saxophone16,saxophone17,saxophone18,saxophone22</string>
-        </array>
-        <key>60</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4,saxophone16,saxophone17,saxophone18,saxophone22</string>
-        </array>
-        <key>61</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4,saxophone16,saxophone17,saxophone18,saxophone22</string>
-        </array>
-        <key>62</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4,saxophone16,saxophone17,saxophone18</string>
-        </array>
-        <key>63</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4,saxophone16,saxophone17,saxophone18,saxophone21</string>
-        </array>
-        <key>64</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4,saxophone16,saxophone17</string>
-        </array>
-        <key>65</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4,saxophone16</string>
-        </array>
-        <key>66</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4,saxophone17</string>
-            <string>saxophone1,saxophone3,saxophone4,saxophone16,saxophone20</string>
-        </array>
-        <key>67</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4</string>
-        </array>
-        <key>68</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4,saxophone9</string>
-        </array>
-        <key>69</key>
-        <array>
-            <string>saxophone1,saxophone3</string>
-        </array>
-        <key>70</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone15</string>
-            <string>saxophone1,saxophone16</string>
-            <string>saxophone1,saxophone2</string>
-        </array>
-        <key>71</key>
-        <array>
-            <string>saxophone1</string>
-        </array>
-        <key>72</key>
-        <array>
-            <string>saxophone3</string>
-        </array>
-        <key>73</key>
-        <array>
-            <string></string>
-        </array>
-        <key>74</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4,saxophone5,saxophone16,saxophone17,saxophone18</string>
-        </array>
-        <key>75</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4,saxophone5,saxophone16,saxophone17,saxophone18,saxophone21</string>
-        </array>
-        <key>76</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4,saxophone5,saxophone16,saxophone17</string>
-        </array>
-        <key>77</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4,saxophone5,saxophone16</string>
-        </array>
-        <key>78</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4,saxophone5,saxophone17</string>
-            <string>saxophone1,saxophone3,saxophone4,saxophone5,saxophone16,saxophone20</string>
-        </array>
-        <key>79</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4,saxophone5</string>
-        </array>
-        <key>80</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone4,saxophone5,saxophone9</string>
-        </array>
-        <key>81</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone5</string>
-        </array>
-        <key>82</key>
-        <array>
-            <string>saxophone1,saxophone3,saxophone5,saxophone15</string>
-            <string>saxophone1,saxophone5,saxophone16</string>
-            <string>saxophone1,saxophone2,saxophone5</string>
-        </array>
-        <key>83</key>
-        <array>
-            <string>saxophone1,saxophone5</string>
-        </array>
-        <key>84</key>
-        <array>
-            <string>saxophone3,saxophone5</string>
-            <string>saxophone1,saxophone5,saxophone14</string>
-        </array>
-        <key>85</key>
-        <array>
-            <string>saxophone5</string>
-        </array>
-        <key>86</key>
-        <array>
-            <string>saxophone5,saxophone8</string>
-        </array>
-        <key>87</key>
-        <array>
-            <string>saxophone5,saxophone6,saxophone7</string>
-        </array>
-        <key>88</key>
-        <array>
-            <string>saxophone5,saxophone7,saxophone8,saxophone13</string>
-        </array>
-        <key>89</key>
-        <array>
-            <string>saxophone5,saxophone6,saxophone7,saxophone8,saxophone13</string>
-            <string>saxophone0,saxophone3,saxophone5</string>
-        </array>
-    </dict>
-    <key>tuba</key>
-    <dict>
-        <key>0</key>
-        <array>
-            <string>tuba0,tuba1,tuba2</string>
-        </array>
-        <key>28</key>
-        <array>
-            <string>tuba3,tuba4,tuba5</string>
-        </array>
-        <key>29</key>
-        <array>
-            <string>tuba3,tuba1,tuba5</string>
-        </array>
-        <key>30</key>
-        <array>
-            <string>tuba0,tuba4,tuba5</string>
-        </array>
-        <key>31</key>
-        <array>
-            <string>tuba3,tuba4,tuba2</string>
-        </array>
-        <key>32</key>
-        <array>
-            <string>tuba3,tuba1,tuba2</string>
-        </array>
-        <key>33</key>
-        <array>
-            <string>tuba3,tuba1,tuba5</string>
-        </array>
-        <key>34</key>
-        <array>
-            <string>tuba0,tuba1,tuba2</string>
-        </array>
-        <key>35</key>
-        <array>
-            <string>tuba3,tuba4,tuba5</string>
-        </array>
-        <key>36</key>
-        <array>
-            <string>tuba3,tuba1,tuba5</string>
-        </array>
-        <key>37</key>
-        <array>
-            <string>tuba0,tuba4,tuba5</string>
-        </array>
-        <key>38</key>
-        <array>
-            <string>tuba3,tuba4,tuba2</string>
-        </array>
-        <key>39</key>
-        <array>
-            <string>tuba3,tuba1,tuba2</string>
-        </array>
-        <key>40</key>
-        <array>
-            <string>tuba0,tuba4,tuba2</string>
-        </array>
-        <key>41</key>
-        <array>
-            <string>tuba0,tuba1,tuba2</string>
-        </array>
-        <key>42</key>
-        <array>
-            <string>tuba0,tuba4,tuba5</string>
-        </array>
-        <key>43</key>
-        <array>
-            <string>tuba3,tuba4,tuba2</string>
-        </array>
-        <key>44</key>
-        <array>
-            <string>tuba3,tuba1,tuba2</string>
-        </array>
-        <key>45</key>
-        <array>
-            <string>tuba0,tuba4,tuba2</string>
-        </array>
-        <key>46</key>
-        <array>
-            <string>tuba0,tuba1,tuba2</string>
-        </array>
-        <key>47</key>
-        <array>
-            <string>tuba3,tuba4,tuba2</string>
-        </array>
-        <key>48</key>
-        <array>
-            <string>tuba3,tuba1,tuba2</string>
-        </array>
-        <key>49</key>
-        <array>
-            <string>tuba0,tuba4,tuba2</string>
-        </array>
-        <key>50</key>
-        <array>
-            <string>tuba0,tuba1,tuba2</string>
-        </array>
-        <key>51</key>
-        <array>
-            <string>tuba3,tuba1,tuba2</string>
-        </array>
-        <key>52</key>
-        <array>
-            <string>tuba0,tuba4,tuba2</string>
-        </array>
-        <key>53</key>
-        <array>
-            <string>tuba0,tuba1,tuba2</string>
-        </array>
-        <key>54</key>
-        <array>
-            <string>tuba0,tuba4,tuba5</string>
-        </array>
-        <key>55</key>
-        <array>
-            <string>tuba3,tuba4,tuba2</string>
-        </array>
-        <key>56</key>
-        <array>
-            <string>tuba3,tuba1,tuba2</string>
-        </array>
-        <key>57</key>
-        <array>
-            <string>tuba0,tuba4,tuba2</string>
-        </array>
-        <key>58</key>
-        <array>
-            <string>tuba0,tuba1,tuba2</string>
-        </array>
-    </dict>
-    <key>piccolo</key>
-    <dict>
-        <key>72</key>
-        <array>
-            <string>piccolo8,piccolo1,piccolo9,piccolo3,piccolo4,piccolo5,piccolo6,piccolo7</string>
-        </array>
-        <key>73</key>
-        <array>
-            <string>piccolo8,piccolo1,piccolo9,piccolo3,piccolo4,piccolo5,piccolo6,piccolo11</string>
-        </array>
-        <key>74</key>
-        <array>
-            <string>piccolo8,piccolo1,piccolo9,piccolo3,piccolo4,piccolo5,piccolo10</string>
-        </array>
-        <key>75</key>
-        <array>
-            <string>piccolo8,piccolo1,piccolo9,piccolo3,piccolo4,piccolo5,piccolo6</string>
-        </array>
-        <key>76</key>
-        <array>
-            <string>piccolo8,piccolo1,piccolo9,piccolo3,piccolo4,piccolo5</string>
-        </array>
-        <key>77</key>
-        <array>
-            <string>piccolo8,piccolo1,piccolo9,piccolo3,piccolo4,piccolo6,piccolo7</string>
-        </array>
-        <key>78</key>
-        <array>
-            <string>piccolo8,piccolo1,piccolo9,piccolo3,piccolo5,piccolo6</string>
-        </array>
-        <key>79</key>
-        <array>
-            <string>piccolo8,piccolo1,piccolo9,piccolo3</string>
-        </array>
-        <key>80</key>
-        <array>
-            <string>piccolo8,piccolo1,piccolo9,piccolo4,piccolo5,piccolo10</string>
-        </array>
-        <key>81</key>
-        <array>
-            <string>piccolo8,piccolo1,piccolo9</string>
-        </array>
-        <key>82</key>
-        <array>
-            <string>piccolo8,piccolo1,piccolo3,piccolo4</string>
-            <string>piccolo8,piccolo2,piccolo3,piccolo4</string>
-        </array>
-        <key>83</key>
-        <array>
-            <string>piccolo8,piccolo1</string>
-            <string>piccolo8,piccolo9,piccolo3</string>
-        </array>
-        <key>84</key>
-        <array>
-            <string>piccolo8,piccolo9</string>
-        </array>
-        <key>85</key>
-        <array>
-            <string>piccolo1,piccolo9</string>
-            <string>piccolo8</string>
-        </array>
-        <key>86</key>
-        <array>
-            <string>piccolo9</string>
-        </array>
-        <key>87</key>
-        <array>
-            <string>piccolo9,piccolo3,piccolo4,piccolo5,piccolo10</string>
-        </array>
-        <key>88</key>
-        <array>
-            <string>piccolo0,piccolo1,piccolo9,piccolo3,piccolo4,piccolo5</string>
-        </array>
-        <key>89</key>
-        <array>
-            <string>piccolo0,piccolo1,piccolo9,piccolo3,piccolo4,piccolo10</string>
-        </array>
-        <key>90</key>
-        <array>
-            <string>piccolo0,piccolo1,piccolo9,piccolo3,piccolo5</string>
-        </array>
-        <key>91</key>
-        <array>
-            <string>piccolo0,piccolo1,piccolo9,piccolo3</string>
-        </array>
-        <key>92</key>
-        <array>
-            <string>piccolo0,piccolo1,piccolo9,piccolo4</string>
-        </array>
-        <key>93</key>
-        <array>
-            <string>piccolo0,piccolo1,piccolo9</string>
-        </array>
-        <key>94</key>
-        <array>
-            <string>piccolo0,piccolo1,piccolo9,piccolo4,piccolo5,piccolo10</string>
-        </array>
-        <key>95</key>
-        <array>
-            <string>piccolo0,piccolo1,piccolo9,piccolo4,piccolo5</string>
-        </array>
-        <key>96</key>
-        <array>
-            <string>piccolo0,piccolo1,piccolo4,piccolo5</string>
-        </array>
-        <key>97</key>
-        <array>
-            <string>piccolo0,piccolo1,piccolo2,piccolo3,piccolo4,piccolo10,piccolo11</string>
-        </array>
-        <key>98</key>
-        <array>
-            <string>piccolo0,piccolo1,piccolo3,piccolo4,piccolo10,piccolo7</string>
-        </array>        
-    </dict>
-</dict>
-</plist>

+ 0 - 30
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/KSParseMessageModel.h

@@ -1,30 +0,0 @@
-//
-//  KSParseMessageModel.h
-//  MidiPlayer
-//
-//  Created by Kyle on 2021/12/2.
-//
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface KSParseMessageModel : NSObject
-
-@property (nonatomic, assign) NSInteger elementIndex;
-
-@property (nonatomic, assign) NSInteger pageIndex;
-
-@property (nonatomic, assign) double elementTimePosition;
-
-@property (nonatomic, assign) double positionX;
-
-@property (nonatomic, assign) double positionY;
-
-@property (nonatomic, assign) double elementWidth;
-
-@property (nonatomic, assign) double elementHeight;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 13
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/KSParseMessageModel.m

@@ -1,13 +0,0 @@
-//
-//  KSParseMessageModel.m
-//  MidiPlayer
-//
-//  Created by Kyle on 2021/12/2.
-//
-
-#import "KSParseMessageModel.h"
-
-@implementation KSParseMessageModel
-
-
-@end

+ 0 - 23
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/KSXMLInfoParse.h

@@ -1,23 +0,0 @@
-//
-//  KSXMLInfoParse.h
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/8.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface KSXMLInfoParse : NSObject
-
-+ (NSMutableDictionary *)getInfoFromXMLMusicFile:(NSString *)filePath;
-
-+ (double)parsePitchToHZ:(double)pitch;
-
-+ (int)ParseHZToPitch:(double)hz;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 324
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/KSXMLInfoParse.m

@@ -1,324 +0,0 @@
-//
-//  KSXMLInfoParse.m
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/8.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import "KSXMLInfoParse.h"
-#import "TBXML.h"
-
-#define GET_SUB_INT(var, sub, parent_elem)  \
-{                               \
-if(parent_elem){    \
-TBXMLElement *divisions_elem = [TBXML childElementNamed:sub parentElement:parent_elem]; \
-if (divisions_elem!=nil) {      \
-var = [[TBXML textForElement:divisions_elem] intValue];   \
-}                             \
-}   \
-}
-
-#define GET_SUB_STR(var, sub, parent_elem)  \
-{                           \
-if(parent_elem){        \
-TBXMLElement *temp_elem = [TBXML childElementNamed:sub parentElement:parent_elem]; \
-if (temp_elem!=nil) {  \
-var = [TBXML textForElement:temp_elem];   \
-}else{var=nil;}                    \
-}   \
-}
-
-#define DEFAULT_TEMPO (120)
-#define QUARTER_TICK (480) // 一个四分音符tick时钟数
-@implementation KSXMLInfoParse
-
-+ (NSMutableDictionary *)getInfoFromXMLMusicFile:(NSString *)filePath {
-    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
-    
-    NSMutableArray *infoArray = [NSMutableArray array];
-    
-    NSFileManager *fileManager = [NSFileManager defaultManager];
-    BOOL isDirExist = [fileManager fileExistsAtPath:filePath];
-    if (isDirExist == NO) {
-        // 当前文件不存在
-        return nil;
-    }
-    NSData *xml_data = [NSData dataWithContentsOfFile:filePath];
-    TBXMLElement *element;
-    NSError *error;
-    TBXML *tbxml = [[TBXML alloc] initWithXMLData:xml_data error:&error];
-    element = [tbxml rootXMLElement];
-    if (element == NULL) {
-        NSLog(@"Fail to parse xml file. error=%@", error);
-        return nil;
-    }
-    
-    NSString *name = [TBXML elementName:element];
-    if (![name isEqualToString:@"score-partwise"]) {
-        NSLog(@"this is not a MusicXML %@",name);
-        return nil;
-    }
-//    NSMutableArray *parts = [[NSMutableArray alloc] init];
-    int max_measures = 0;
-    element = element->firstChild;
-    NSInteger partIndex = 0;
-    do {
-        name = [TBXML elementName:element];
-        if ([name isEqualToString:@"part"]) {
-            NSString *part_id = [TBXML valueOfAttributeNamed:@"id" forElement:element];
-            if ([part_id isEqualToString:@"1"]) {
-                
-            }
-            int measure_index = 0;
-            int note_index = 0;
-            TBXMLElement *measure_elem = element->firstChild;
-            NSMutableArray *partNodeArray = [NSMutableArray array];
-            float tick = 0;
-            do {
-                // 解析小节信息
-               NSMutableArray *nodeArray =  [self parseMeasure:measure_elem measureIndex:&measure_index nodeIndex:&note_index tick:&tick];
-                if (nodeArray.count) {
-                    [partNodeArray addObjectsFromArray:nodeArray];
-                }
-                measure_elem = measure_elem->nextSibling;
-                measure_index++;
-                if (measure_elem==nil) {
-                    break;
-                }
-            } while (true);
-            
-            // 获取最大小节数
-            if (max_measures < measure_index) {
-                max_measures = measure_index;
-            }
-            if (partIndex == 0) {
-                infoArray = [NSMutableArray arrayWithArray:partNodeArray];
-            }
-            partIndex++;
-        }
-        element = element->nextSibling;
-        if (element==nil) {
-            break;
-        }
-    } while (true);
-    
-    [parm setValue:infoArray forKey:@"noteInfo"];
-    NSString *beat = [NSString stringWithFormat:@"%d/%d", last_numerator, last_denominator];
-    [parm setValue:beat forKey:@"beatType"];
-    return parm;
-}
-
-+ (NSMutableArray *)parseMeasure:(TBXMLElement *)measure_elem measureIndex:(int *)measureIndex nodeIndex:(int *)nodeIndex tick:(float *)tick {
-    NSMutableArray *array = [NSMutableArray array];
-    NSString *name = [TBXML elementName:measure_elem];
-    if ([name isEqualToString:@"measure"]) {
-        //notes
-        TBXMLElement *note_elem = measure_elem->firstChild;
-        do {
-            name = [TBXML elementName:note_elem];
-            if ([name isEqualToString:@"note"]) {
-               NSMutableDictionary *parm = [self parseNote:note_elem tick:tick measureIndex:measureIndex nodeIndex:nodeIndex];
-                if (parm != nil) {
-                    *nodeIndex = *nodeIndex + 1;
-                    [array addObject:parm];
-                }
-            }
-            else if ([name isEqualToString:@"attributes"]) {
-                //divisions
-                TBXMLElement *divisions_elem = [TBXML childElementNamed:@"divisions" parentElement:note_elem];
-                if (divisions_elem != nil) {
-                    last_divisions = [[TBXML textForElement:divisions_elem] intValue];
-                }
-                
-                //time
-                TBXMLElement *time_elem = [TBXML childElementNamed:@"time" parentElement:note_elem];
-                if(time_elem != nil)
-                {
-                    //beats
-                    GET_SUB_INT(last_numerator, @"beats", time_elem);
-                    //beat-type
-                    GET_SUB_INT(last_denominator, @"beat-type", time_elem);
-                }
-            }
-            note_elem = note_elem->nextSibling;
-            
-            if (note_elem==nil) {
-                break;
-            }
-        } while (true);
-    }
-    else {
-        NSLog(@"error unknow element:%@", name);
-    }
-    return array;
-}
-
-+ (NSMutableDictionary *)parseNote:(TBXMLElement *)note_elem tick:(float *)tick measureIndex:(int *)measureIndex nodeIndex:(int *)nodeIndex {
-    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
-    NSString *name = [TBXML elementName:note_elem];
-    if (note_elem==nil) {
-        return nil;
-    }
-    if ([name isEqualToString:@"note"]) {
-        BOOL isChord = NO, isRest = NO;
-        BOOL isListen = NO;
-        int duration=0;
-        int pitch_step = 0,pitch_octave = 0,pitch_alter = 0,note_value = 0;
-        NSInteger noteDenominator = 1;
-        TBXMLElement *elem = note_elem->firstChild;
-        while (elem) {
-            name = [TBXML elementName:elem];
-            if ([name isEqualToString:@"duration"]) { // 时值
-                int nodeDuration = [[TBXML textForElement:elem] intValue];
-                duration = nodeDuration * 1.0 / last_divisions * QUARTER_TICK;
-            }
-            else if ([name isEqualToString:@"type"]) { // 音符类型
-                NSString* type = nil;           //256th, 128th, 64th, 32nd, 16th, eighth, quarter, half, whole, breve, and long
-                GET_SUB_STR(type, @"type", note_elem);
-                noteDenominator = [self noteType:type];
-            }
-            else if ([name isEqualToString:@"chord"]) {
-                isChord = YES;
-            }
-            else if ([name isEqualToString:@"rest"]) { // 休息
-                isRest = YES;
-            }
-            else if ([name isEqualToString:@"pitch"]) { // 音阶
-                NSString *step=nil;
-                GET_SUB_STR(step, @"step", elem);
-                if (step) {
-                    if ([step isEqualToString:@"C"])pitch_step=1;
-                    else if ([step isEqualToString:@"D"])pitch_step=2;
-                    else if ([step isEqualToString:@"E"])pitch_step=3;
-                    else if ([step isEqualToString:@"F"])pitch_step=4;
-                    else if ([step isEqualToString:@"G"])pitch_step=5;
-                    else if ([step isEqualToString:@"A"])pitch_step=6;
-                    else if ([step isEqualToString:@"B"])pitch_step=7;
-                    else NSLog(@"Error: unknow pitch step=%@",step);
-                }
-                GET_SUB_INT(pitch_alter, @"alter", elem);
-                GET_SUB_INT(pitch_octave, @"octave", elem);
-                note_value = [self noteValueForStep:pitch_step octave:pitch_octave alter:pitch_alter];
-            }
-            else if ([name isEqualToString:@"unpitched"]) { // 休息
-//                isRest = YES;
-                NSString *step=nil;
-                GET_SUB_STR(step, @"step", elem);
-                if (step) {
-                    if ([step isEqualToString:@"C"])pitch_step=1;
-                    else if ([step isEqualToString:@"D"])pitch_step=2;
-                    else if ([step isEqualToString:@"E"])pitch_step=3;
-                    else if ([step isEqualToString:@"F"])pitch_step=4;
-                    else if ([step isEqualToString:@"G"])pitch_step=5;
-                    else if ([step isEqualToString:@"A"])pitch_step=6;
-                    else if ([step isEqualToString:@"B"])pitch_step=7;
-                    else NSLog(@"Error: unknow pitch step=%@",step);
-                }
-                GET_SUB_INT(pitch_alter, @"alter", elem);
-                GET_SUB_INT(pitch_octave, @"octave", elem);
-                note_value = [self noteValueForStep:pitch_step octave:pitch_octave alter:pitch_alter];
-            }
-            else if ([name isEqualToString:@"lyric"]) { // 歌词  获取listen play
-                NSString *text = @"";
-                GET_SUB_STR(text, @"text", elem);
-                if ([text containsString:@"listen"] || [text containsString:@"Listen"]) {
-                    isListen = YES;
-                }
-            }
-            elem = elem->nextSibling;
-        }
-        // 解析
-        if (isRest) {
-            *tick = *tick + duration;
-            return nil;
-        }
-        else if (isChord) {
-            return nil;
-        }
-        else {
-            
-            // timeStamp duration frequency nextFrequency measureIndex dontEvaluating musicalNotesIndex
-            // tick 转 时间
-            // 一拍时常 beatDuration
-            double beatDuration = 60.0f / DEFAULT_TEMPO;
-            // tick 时常
-            // 获取一个四分音符时常
-            double quaterDuartion = beatDuration * last_denominator / 4;
-            double tickDuration =  quaterDuartion / QUARTER_TICK * 1000;
-            // 计算频率
-            float timeStamp = *tick * tickDuration;
-            float durationStamp = duration * tickDuration;
-            float frequency =  [self parsePitchToHZ:note_value];
-            float nextFrequency =  [self parsePitchToHZ:note_value+1];
-            
-            [parm setValue:@(timeStamp) forKey:@"timeStamp"];
-            [parm setValue:@(durationStamp) forKey:@"duration"];
-            [parm setValue:@(frequency) forKey:@"frequency"];
-            [parm setValue:@(nextFrequency) forKey:@"nextFrequency"];
-            [parm setValue:@(isListen) forKey:@"dontEvaluating"];
-            [parm setValue:@(*measureIndex) forKey:@"measureIndex"];
-            [parm setValue:@(*nodeIndex) forKey:@"musicalNotesIndex"];
-            [parm setValue:@(noteDenominator) forKey:@"denominator"];
-            [parm setValue:@(note_value) forKey:@"note_value"];
-            *tick = *tick + duration;
-        }
-    }
-    
-    return parm;
-}
-
-+ (double)parsePitchToHZ:(double)pitch {
-    return pow(2, (pitch - 69)/12)*442;
-}
-
-+ (int)ParseHZToPitch:(double)hz {
-    return log2(hz);
-}
-
-
-//pitch_step:1..7
-//pitch_alter:-1,0,+1
-+ (int)noteValueForStep:(int)pitch_step octave:(int)pitch_octave alter:(int)pitch_alter {
-    int note_value=(1+pitch_octave)*12+pitch_alter;
-    if (pitch_step==2) { //D
-        note_value+=2;
-    }else if (pitch_step==3) { //E
-        note_value+=4;
-    }else if (pitch_step==4) { //F
-        note_value+=5;
-    }else if (pitch_step==5) { //G
-        note_value+=7;
-    }else if (pitch_step==6) { //A
-        note_value+=9;
-    }else if (pitch_step==7) { //B
-        note_value+=11;
-    }
-    return note_value;
-}
-
-
-+ (NSInteger)noteType:(NSString *)type{
-    NSInteger noteDenominator = 0;
-    if ([NSString isEmptyString:type]) {
-        noteDenominator = 1;
-    }
-    else if ([type isEqualToString:@"whole"]) {
-        noteDenominator = 1;
-    }else if ([type isEqualToString:@"half"]) {
-        noteDenominator = 2;
-    }else if ([type isEqualToString:@"quarter"]) {
-        noteDenominator = 4;
-    }else if ([type isEqualToString:@"eighth"]) {
-        noteDenominator = 8;
-    }else if ([type isEqualToString:@"16th"]) {
-        noteDenominator = 16;
-    }else {
-        noteDenominator = 32;
-    }
-    return noteDenominator;
-}
-
-static int last_divisions = 0; // 四分音符标准时常
-static int last_numerator = 4, last_denominator = 4;
-@end

+ 0 - 24
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/KYSourceParseManager.h

@@ -1,24 +0,0 @@
-//
-//  KYSourceParseManager.h
-//  MidiPlayer
-//
-//  Created by Kyle on 2021/12/2.
-//
-
-#import <Foundation/Foundation.h>
-#import "KSParseMessageModel.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface KYSourceParseManager : NSObject
-
-@property (nonatomic, strong) NSMutableArray *measureMessageArray;
-
-@property (nonatomic, strong) NSMutableArray *nodeMessageArray;
-
-
-- (BOOL)parseMessageSource:(NSString *)measureSourcePath nodeSource:(NSString *)nodeSourcePath;
- 
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 145
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/KYSourceParseManager.m

@@ -1,145 +0,0 @@
-//
-//  KYSourceParseManager.m
-//  MidiPlayer
-//
-//  Created by Kyle on 2021/12/2.
-//
-
-#import "KYSourceParseManager.h"
-#import "TBXML.h"
-
-
-@implementation KYSourceParseManager
-
-- (BOOL)parseMessageSource:(NSString *)measureSourcePath nodeSource:(NSString *)nodeSourcePath {
-    NSFileManager *fileManager = [NSFileManager defaultManager];
-    BOOL measureFileExist = [fileManager fileExistsAtPath:measureSourcePath];
-    BOOL nodeFileExist = [fileManager fileExistsAtPath:nodeSourcePath];
-    if (measureFileExist == NO || nodeFileExist == NO) {
-        NSLog(@"文件不存在");
-        return NO;
-    }
-    TBXMLElement *element;
-    NSError *error;
-    NSData *measureData = [NSData dataWithContentsOfFile:measureSourcePath];
-    TBXML *tbxml = [[TBXML alloc] initWithXMLData:measureData error:&error];
-    if (error) {
-        NSLog(@"%@", error.description);
-        return NO;
-    }
-    element = [tbxml rootXMLElement];
-    if (element == nil) {
-        NSLog(@"Fail to parse xml file. error=%@", error);
-        return NO;
-    }
-    NSString *name = [TBXML elementName:element];
-    
-    if ([name isEqualToString:@"score"]) {
-        self.measureMessageArray = [self parseScoreWithSource:element];
-    }
-    
-    NSData *nodeData = [NSData dataWithContentsOfFile:nodeSourcePath];
-    TBXML *nodeTbxml = [[TBXML alloc] initWithXMLData:nodeData error:&error];
-    if (error) {
-        NSLog(@"%@", error.description);
-        return NO;
-    }
-    TBXMLElement *nodeElement = [nodeTbxml rootXMLElement];
-    if (nodeElement == nil) {
-        NSLog(@"Fail to parse xml file. error=%@", error);
-        return NO;
-    }
-    NSString *nodeName = [TBXML elementName:nodeElement];
-    if ([nodeName isEqualToString:@"score"]) {
-        self.nodeMessageArray = [self parseScoreWithSource:nodeElement];
-    }
-    return YES;
-}
-
-- (NSMutableArray *)parseScoreWithSource:(TBXMLElement *)element {
-    NSMutableArray *sourceArray = [NSMutableArray array];
-    NSMutableArray *positionArray = [NSMutableArray array];
-    NSMutableArray *timeArray = [NSMutableArray array];
-    TBXMLElement *temp_elem = element->firstChild;
-    do {
-        NSString *name = [TBXML elementName:temp_elem];
-        if ([name isEqualToString:@"elements"]) { // 位置信息
-            positionArray = [self getDetailSourceWithElement:temp_elem];
-        }
-        else if ([name isEqualToString:@"events"]) { // 时间信息
-            timeArray = [self getDetailSourceWithElement:temp_elem];
-        }
-        
-        temp_elem = temp_elem->nextSibling;
-        if (temp_elem == nil) {
-            break;
-        }
-    } while (YES);
-    
-    // 赋值
-    if (positionArray.count != timeArray.count) {
-        return nil;
-    }
-    for (NSInteger i = 0; i < positionArray.count; i++) {
-        KSParseMessageModel *model = [[KSParseMessageModel alloc] init];
-        NSDictionary *positionDic = [positionArray objectAtIndex:i];
-        model.elementIndex = [[positionDic valueForKey:@"id"] integerValue];
-        model.positionX = [[positionDic valueForKey:@"x"] doubleValue];
-        model.positionY = [[positionDic valueForKey:@"y"] doubleValue];
-        double width = [[positionDic valueForKey:@"sx"] doubleValue];
-        if (width == 0) {
-            width = 700.0f;
-        }
-        model.elementWidth = width;
-        model.elementHeight = [[positionDic valueForKey:@"sy"] doubleValue];
-        model.pageIndex = [[positionDic valueForKey:@"page"] integerValue];
-        NSDictionary *timeDic = [timeArray objectAtIndex:i];
-        model.elementTimePosition = [[timeDic valueForKey:@"position"] integerValue];
-        [sourceArray addObject:model];
-    }
-    return sourceArray;
-}
-
-- (NSMutableArray *)getDetailSourceWithElement:(TBXMLElement *)elements {
-    NSMutableArray *messageArray = [NSMutableArray array];
-    TBXMLElement *sub_elem = elements->firstChild;
-    NSString *name = [TBXML elementName:sub_elem];
-    BOOL isElement = [name isEqualToString:@"element"];
-    
-    do {
-        
-        NSMutableDictionary *valueDic = [NSMutableDictionary dictionary];
-        if (isElement) {
-            NSString *elemId = [TBXML valueOfAttributeNamed:@"id" forElement:sub_elem];
-            [valueDic setValue:elemId forKey:@"id"];
-            
-            double positionX = [[TBXML valueOfAttributeNamed:@"x" forElement:sub_elem] doubleValue];
-            [valueDic setValue:@(positionX) forKey:@"x"];
-            double positionY = [[TBXML valueOfAttributeNamed:@"y" forElement:sub_elem] doubleValue];
-            [valueDic setValue:@(positionY) forKey:@"y"];
-            
-            double width = [[TBXML valueOfAttributeNamed:@"sx" forElement:sub_elem] doubleValue];
-            [valueDic setValue:@(width) forKey:@"sx"];
-            double height = [[TBXML valueOfAttributeNamed:@"sy" forElement:sub_elem] doubleValue];
-            [valueDic setValue:@(height) forKey:@"sy"];
-            
-            NSInteger pageIndex = [[TBXML valueOfAttributeNamed:@"page" forElement:sub_elem] doubleValue];
-            [valueDic setValue:@(pageIndex) forKey:@"page"];
-        }
-        else {
-            NSInteger position = [[TBXML valueOfAttributeNamed:@"position" forElement:sub_elem] integerValue];
-            [valueDic setValue:@(position) forKey:@"position"];
-        }
-        [messageArray addObject:valueDic];
-        
-        sub_elem = sub_elem->nextSibling;
-        if (sub_elem == nil) {
-            break;
-        }
-    } while (YES);
-    
-    return messageArray;
-}
-
-
-@end

+ 0 - 76
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/SubjectFinger.plist

@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>2</key>
-	<dict>
-		<key>vertical</key>
-		<false/>
-		<key>name</key>
-		<string>flute</string>
-	</dict>
-	<key>4</key>
-	<dict>
-		<key>vertical</key>
-		<true/>
-		<key>name</key>
-		<string>clarinet</string>
-	</dict>
-	<key>5</key>
-	<dict>
-		<key>vertical</key>
-		<true/>
-		<key>name</key>
-		<string>saxophone</string>
-	</dict>
-	<key>6</key>
-	<dict>
-		<key>vertical</key>
-		<true/>
-		<key>name</key>
-		<string>saxophone</string>
-	</dict>
-	<key>12</key>
-	<dict>
-		<key>vertical</key>
-		<false/>
-		<key>name</key>
-		<string>trumpet</string>
-	</dict>
-	<key>13</key>
-	<dict>
-		<key>vertical</key>
-		<true/>
-		<key>name</key>
-		<string>horn</string>
-	</dict>
-	<key>14</key>
-	<dict>
-		<key>vertical</key>
-		<false/>
-		<key>name</key>
-		<string>trombone</string>
-	</dict>
-	<key>15</key>
-	<dict>
-		<key>vertical</key>
-		<true/>
-		<key>name</key>
-		<string>up-bass-horn</string>
-	</dict>
-	<key>17</key>
-	<dict>
-		<key>vertical</key>
-		<true/>
-		<key>name</key>
-		<string>tuba</string>
-	</dict>
-	<key>120</key>
-	<dict>
-		<key>vertical</key>
-		<true/>
-		<key>name</key>
-		<string>piccolo</string>
-	</dict>
-</dict>
-</plist>

+ 0 - 211
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/TBXML.h

@@ -1,211 +0,0 @@
-// ================================================================================================
-//  TBXML.h
-//  Fast processing of XML files
-//
-// ================================================================================================
-//  Created by Tom Bradley on 21/10/2009.
-//  Version 1.5
-//  
-//  Copyright 2012 71Squared All rights reserved.b
-//  
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//  
-//  The above copyright notice and this permission notice shall be included in
-//  all copies or substantial portions of the Software.
-//  
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-//  THE SOFTWARE.
-// ================================================================================================
-#import <Foundation/Foundation.h>
-
-@class TBXML;
-
-
-// ================================================================================================
-//  Error Codes
-// ================================================================================================
-enum TBXMLErrorCodes {
-    D_TBXML_SUCCESS = 0,
-
-    D_TBXML_DATA_NIL,
-    D_TBXML_DECODE_FAILURE,
-    D_TBXML_MEMORY_ALLOC_FAILURE,
-    D_TBXML_FILE_NOT_FOUND_IN_BUNDLE,
-    
-    D_TBXML_ELEMENT_IS_NIL,
-    D_TBXML_ELEMENT_NAME_IS_NIL,
-    D_TBXML_ELEMENT_NOT_FOUND,
-    D_TBXML_ELEMENT_TEXT_IS_NIL,
-    D_TBXML_ATTRIBUTE_IS_NIL,
-    D_TBXML_ATTRIBUTE_NAME_IS_NIL,
-    D_TBXML_ATTRIBUTE_NOT_FOUND,
-    D_TBXML_PARAM_NAME_IS_NIL
-};
-
-
-// ================================================================================================
-//  Defines
-// ================================================================================================
-#define D_TBXML_DOMAIN @"com.71squared.tbxml"
-
-#define MAX_ELEMENTS 100
-#define MAX_ATTRIBUTES 100
-
-#define TBXML_ATTRIBUTE_NAME_START 0
-#define TBXML_ATTRIBUTE_NAME_END 1
-#define TBXML_ATTRIBUTE_VALUE_START 2
-#define TBXML_ATTRIBUTE_VALUE_END 3
-#define TBXML_ATTRIBUTE_CDATA_END 4
-
-// ================================================================================================
-//  Structures
-// ================================================================================================
-
-/** The TBXMLAttribute structure holds information about a single XML attribute. The structure holds the attribute name, value and next sibling attribute. This structure allows us to create a linked list of attributes belonging to a specific element.
- */
-typedef struct _TBXMLAttribute {
-	char * name;
-	char * value;
-	struct _TBXMLAttribute * next;
-} TBXMLAttribute;
-
-
-
-/** The TBXMLElement structure holds information about a single XML element. The structure holds the element name & text along with pointers to the first attribute, parent element, first child element and first sibling element. Using this structure, we can create a linked list of TBXMLElements to map out an entire XML file.
- */
-typedef struct _TBXMLElement {
-	char * name;
-	char * text;
-	
-	TBXMLAttribute * firstAttribute;
-	
-	struct _TBXMLElement * parentElement;
-	
-	struct _TBXMLElement * firstChild;
-	struct _TBXMLElement * currentChild;
-	
-	struct _TBXMLElement * nextSibling;
-	struct _TBXMLElement * previousSibling;
-	
-} TBXMLElement;
-
-/** The TBXMLElementBuffer is a structure that holds a buffer of TBXMLElements. When the buffer of elements is used, an additional buffer is created and linked to the previous one. This allows for efficient memory allocation/deallocation elements.
- */
-typedef struct _TBXMLElementBuffer {
-	TBXMLElement * elements;
-	struct _TBXMLElementBuffer * next;
-	struct _TBXMLElementBuffer * previous;
-} TBXMLElementBuffer;
-
-
-
-/** The TBXMLAttributeBuffer is a structure that holds a buffer of TBXMLAttributes. When the buffer of attributes is used, an additional buffer is created and linked to the previous one. This allows for efficient memeory allocation/deallocation of attributes.
- */
-typedef struct _TBXMLAttributeBuffer {
-	TBXMLAttribute * attributes;
-	struct _TBXMLAttributeBuffer * next;
-	struct _TBXMLAttributeBuffer * previous;
-} TBXMLAttributeBuffer;
-
-
-// ================================================================================================
-//  Block Callbacks
-// ================================================================================================
-typedef void (^TBXMLSuccessBlock)(TBXML *tbxml);
-typedef void (^TBXMLFailureBlock)(TBXML *tbxml, NSError *error);
-typedef void (^TBXMLIterateBlock)(TBXMLElement *element);
-typedef void (^TBXMLIterateAttributeBlock)(TBXMLAttribute *attribute, NSString *attributeName, NSString *attributeValue);
-
-
-// ================================================================================================
-//  TBXML Public Interface
-// ================================================================================================
-
-@interface TBXML : NSObject {
-	
-@private
-	TBXMLElement * rootXMLElement;
-	
-	TBXMLElementBuffer * currentElementBuffer;
-	TBXMLAttributeBuffer * currentAttributeBuffer;
-	
-	long currentElement;
-	long currentAttribute;
-	
-	char * bytes;
-	long bytesLength;
-}
-
-
-@property (nonatomic, readonly) TBXMLElement * rootXMLElement;
-
-+ (id)newTBXMLWithXMLString:(NSString*)aXMLString error:(NSError **)error;
-+ (id)newTBXMLWithXMLData:(NSData*)aData error:(NSError **)error;
-+ (id)newTBXMLWithXMLFile:(NSString*)aXMLFile error:(NSError **)error;
-+ (id)newTBXMLWithXMLFile:(NSString*)aXMLFile fileExtension:(NSString*)aFileExtension error:(NSError **)error;
-
-+ (id)newTBXMLWithXMLString:(NSString*)aXMLString __attribute__((deprecated));
-+ (id)newTBXMLWithXMLData:(NSData*)aData __attribute__((deprecated));
-+ (id)newTBXMLWithXMLFile:(NSString*)aXMLFile __attribute__((deprecated));
-+ (id)newTBXMLWithXMLFile:(NSString*)aXMLFile fileExtension:(NSString*)aFileExtension __attribute__((deprecated));
-
-
-- (id)initWithXMLString:(NSString*)aXMLString error:(NSError **)error;
-- (id)initWithXMLData:(NSData*)aData error:(NSError **)error;
-- (id)initWithXMLFile:(NSString*)aXMLFile error:(NSError **)error;
-- (id)initWithXMLFile:(NSString*)aXMLFile fileExtension:(NSString*)aFileExtension error:(NSError **)error;
-
-- (id)initWithXMLString:(NSString*)aXMLString __attribute__((deprecated));
-- (id)initWithXMLData:(NSData*)aData __attribute__((deprecated));
-- (id)initWithXMLFile:(NSString*)aXMLFile __attribute__((deprecated));
-- (id)initWithXMLFile:(NSString*)aXMLFile fileExtension:(NSString*)aFileExtension __attribute__((deprecated));
-
-
-- (int) decodeData:(NSData*)data;
-- (int) decodeData:(NSData*)data withError:(NSError **)error;
-
-@end
-
-// ================================================================================================
-//  TBXML Static Functions Interface
-// ================================================================================================
-
-@interface TBXML (StaticFunctions)
-
-+ (NSString*) elementName:(TBXMLElement*)aXMLElement;
-+ (NSString*) elementName:(TBXMLElement*)aXMLElement error:(NSError **)error;
-+ (NSString*) textForElement:(TBXMLElement*)aXMLElement;
-+ (NSString*) textForElement:(TBXMLElement*)aXMLElement error:(NSError **)error;
-+ (NSString*) valueOfAttributeNamed:(NSString *)aName forElement:(TBXMLElement*)aXMLElement;
-+ (NSString*) valueOfAttributeNamed:(NSString *)aName forElement:(TBXMLElement*)aXMLElement error:(NSError **)error;
-
-+ (NSString*) attributeName:(TBXMLAttribute*)aXMLAttribute;
-+ (NSString*) attributeName:(TBXMLAttribute*)aXMLAttribute error:(NSError **)error;
-+ (NSString*) attributeValue:(TBXMLAttribute*)aXMLAttribute;
-+ (NSString*) attributeValue:(TBXMLAttribute*)aXMLAttribute error:(NSError **)error;
-
-+ (TBXMLElement*) nextSiblingNamed:(NSString*)aName searchFromElement:(TBXMLElement*)aXMLElement;
-+ (TBXMLElement*) childElementNamed:(NSString*)aName parentElement:(TBXMLElement*)aParentXMLElement;
-
-+ (TBXMLElement*) nextSiblingNamed:(NSString*)aName searchFromElement:(TBXMLElement*)aXMLElement error:(NSError **)error;
-+ (TBXMLElement*) childElementNamed:(NSString*)aName parentElement:(TBXMLElement*)aParentXMLElement error:(NSError **)error;
-
-/** Iterate through all elements found using query.
- 
- Inspiration taken from John Blanco's RaptureXML https://github.com/ZaBlanc/RaptureXML
- */
-+ (void)iterateElementsForQuery:(NSString *)query fromElement:(TBXMLElement *)anElement withBlock:(TBXMLIterateBlock)iterateBlock;
-+ (void)iterateAttributesOfElement:(TBXMLElement *)anElement withBlock:(TBXMLIterateAttributeBlock)iterateBlock;
-
-
-@end

+ 0 - 952
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/Model/TBXML.m

@@ -1,952 +0,0 @@
-// ================================================================================================
-//  TBXML.m
-//  Fast processing of XML files
-//
-// ================================================================================================
-//  Created by Tom Bradley on 21/10/2009.
-//  Version 1.5
-//  
-//  Copyright 2012 71Squared All rights reserved.
-//  
-//  Permission is hereby granted, free of charge, to any person obtaining a copy
-//  of this software and associated documentation files (the "Software"), to deal
-//  in the Software without restriction, including without limitation the rights
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//  copies of the Software, and to permit persons to whom the Software is
-//  furnished to do so, subject to the following conditions:
-//  
-//  The above copyright notice and this permission notice shall be included in
-//  all copies or substantial portions of the Software.
-//  
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-//  THE SOFTWARE.
-// ================================================================================================
-#import "TBXML.h"
-
-// ================================================================================================
-// Private methods
-// ================================================================================================
-@interface TBXML (Private)
-+ (NSString *) errorTextForCode:(int)code;
-+ (NSError *) errorWithCode:(int)code;
-+ (NSError *) errorWithCode:(int)code userInfo:(NSDictionary *)userInfo;
-- (void) decodeBytes;
-- (int) allocateBytesOfLength:(long)length error:(NSError **)error;
-- (TBXMLElement*) nextAvailableElement;
-- (TBXMLAttribute*) nextAvailableAttribute;
-@end
-
-// ================================================================================================
-// Public Implementation
-// ================================================================================================
-@implementation TBXML
-
-@synthesize rootXMLElement;
-
-+ (id)newTBXMLWithXMLString:(NSString*)aXMLString {
-	return [[TBXML alloc] initWithXMLString:aXMLString];
-}
-
-+ (id)newTBXMLWithXMLString:(NSString*)aXMLString error:(NSError *__autoreleasing *)error {
-	return [[TBXML alloc] initWithXMLString:aXMLString error:error];
-}
-
-+ (id)newTBXMLWithXMLData:(NSData*)aData {
-	return [[TBXML alloc] initWithXMLData:aData];
-}
-
-+ (id)newTBXMLWithXMLData:(NSData*)aData error:(NSError *__autoreleasing *)error {
-	return [[TBXML alloc] initWithXMLData:aData error:error];
-}
-
-+ (id)newTBXMLWithXMLFile:(NSString*)aXMLFile {
-	return [[TBXML alloc] initWithXMLFile:aXMLFile];
-}
-
-+ (id)newTBXMLWithXMLFile:(NSString*)aXMLFile error:(NSError *__autoreleasing *)error {
-	return [[TBXML alloc] initWithXMLFile:aXMLFile error:error];
-}
-
-+ (id)newTBXMLWithXMLFile:(NSString*)aXMLFile fileExtension:(NSString*)aFileExtension {
-	return [[TBXML alloc] initWithXMLFile:aXMLFile fileExtension:aFileExtension];
-}
-
-+ (id)newTBXMLWithXMLFile:(NSString*)aXMLFile fileExtension:(NSString*)aFileExtension error:(NSError *__autoreleasing *)error {
-	return [[TBXML alloc] initWithXMLFile:aXMLFile fileExtension:aFileExtension error:error];
-}
-
-- (id)init {
-	self = [super init];
-	if (self != nil) {
-		rootXMLElement = nil;
-		
-		currentElementBuffer = 0;
-		currentAttributeBuffer = 0;
-		
-		currentElement = 0;
-		currentAttribute = 0;		
-		
-		bytes = 0;
-		bytesLength = 0;
-	}
-	return self;
-}
-- (id)initWithXMLString:(NSString*)aXMLString {
-    NSError *error = nil;
-    return [self initWithXMLString:aXMLString error:&error];
-}
-
-- (id)initWithXMLString:(NSString*)aXMLString error:(NSError *__autoreleasing *)error {
-	self = [self init];
-	if (self != nil) {
-		
-        
-        // allocate memory for byte array
-        int result = [self allocateBytesOfLength:[aXMLString lengthOfBytesUsingEncoding:NSUTF8StringEncoding] error:error];
-        
-        // if an error occured, return
-        if (result != D_TBXML_SUCCESS) 
-            return self;
-        
-		// copy string to byte array
-		[aXMLString getBytes:bytes maxLength:bytesLength usedLength:0 encoding:NSUTF8StringEncoding options:NSStringEncodingConversionAllowLossy range:NSMakeRange(0, bytesLength) remainingRange:nil];
-		
-		// set null terminator at end of byte array
-		bytes[bytesLength] = 0;
-		
-		// decode xml data
-		[self decodeBytes];
-        
-        // Check for root element
-        if (error && !*error && !self.rootXMLElement) {
-            *error = [TBXML errorWithCode:D_TBXML_DECODE_FAILURE];
-        }
-	}
-	return self;
-}
-
-- (id)initWithXMLData:(NSData*)aData {
-    NSError *error = nil;
-    return [self initWithXMLData:aData error:&error];
-}
-
-- (id)initWithXMLData:(NSData*)aData error:(NSError **)error {
-    self = [self init];
-    if (self != nil) {
-		// decode aData
-		[self decodeData:aData withError:error];
-    }
-    
-    return self;
-}
-
-- (id)initWithXMLFile:(NSString*)aXMLFile {
-    NSError *error = nil;
-    return [self initWithXMLFile:aXMLFile error:&error];
-}
-
-- (id)initWithXMLFile:(NSString*)aXMLFile error:(NSError **)error {
-    NSString * filename = [aXMLFile stringByDeletingPathExtension];
-    NSString * extension = [aXMLFile pathExtension];
-    
-    self = [self initWithXMLFile:filename fileExtension:extension error:error];
-	if (self != nil) {
-        
-	}
-	return self;
-}
-
-- (id)initWithXMLFile:(NSString*)aXMLFile fileExtension:(NSString*)aFileExtension {
-    NSError *error = nil;
-    return [self initWithXMLFile:aXMLFile fileExtension:aFileExtension error:&error];
-}
-
-- (id)initWithXMLFile:(NSString*)aXMLFile fileExtension:(NSString*)aFileExtension error:(NSError **)error {
-	self = [self init];
-	if (self != nil) {
-        
-        NSData * data;
-        
-        // Get the bundle that this class resides in. This allows to load resources from the app bundle when running unit tests.
-        NSString * bundlePath = [[NSBundle bundleForClass:[self class]] pathForResource:aXMLFile ofType:aFileExtension];
-
-        if (!bundlePath) {
-            if (error) {
-                NSDictionary * userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[aXMLFile stringByAppendingPathExtension:aFileExtension], NSFilePathErrorKey, nil];
-                *error = [TBXML errorWithCode:D_TBXML_FILE_NOT_FOUND_IN_BUNDLE userInfo:userInfo];
-            }
-        } else {
-            SEL dataWithUncompressedContentsOfFile = NSSelectorFromString(@"dataWithUncompressedContentsOfFile:");
-            
-            // Get uncompressed file contents if TBXML+Compression has been included
-            if ([[NSData class] respondsToSelector:dataWithUncompressedContentsOfFile]) {
-                
-                #pragma clang diagnostic push
-                #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
-                data = [[NSData class] performSelector:dataWithUncompressedContentsOfFile withObject:bundlePath];
-                #pragma clang diagnostic pop   
-
-            } else {
-                data = [NSData dataWithContentsOfFile:bundlePath];
-            }
-            
-            // decode data
-            [self decodeData:data withError:error];
-            
-            // Check for root element
-            if (error && !*error && !self.rootXMLElement) {
-                *error = [TBXML errorWithCode:D_TBXML_DECODE_FAILURE];
-            }
-        }
-	}
-	return self;
-}
-
-- (int) decodeData:(NSData*)data {
-    NSError *error = nil;
-    return [self decodeData:data withError:&error];
-}
-
-- (int) decodeData:(NSData*)data withError:(NSError **)error {
-    
-    NSError *localError = nil;
-    
-    // allocate memory for byte array
-    int result = [self allocateBytesOfLength:[data length] error:&localError];
-
-    // ensure no errors during allocation
-    if (result == D_TBXML_SUCCESS) {
-        
-        // copy data to byte array
-        [data getBytes:bytes length:bytesLength];
-        
-        // set null terminator at end of byte array
-        bytes[bytesLength] = 0;
-        
-        // decode xml data
-        [self decodeBytes];
-        
-        if (!self.rootXMLElement) {
-            localError = [TBXML errorWithCode:D_TBXML_DECODE_FAILURE];
-        }
-    }
-
-    // assign local error to pointer
-    if (error) *error = localError;
-    
-    // return success or error code
-    return localError == nil ? D_TBXML_SUCCESS : [localError code];
-}
-
-@end
-
-
-// ================================================================================================
-// Static Functions Implementation
-// ================================================================================================
-
-#pragma mark -
-#pragma mark Static Functions implementation
-
-@implementation TBXML (StaticFunctions)
-
-+ (NSString*) elementName:(TBXMLElement*)aXMLElement {
-	if (nil == aXMLElement->name) return @"";
-	return [NSString stringWithCString:&aXMLElement->name[0] encoding:NSUTF8StringEncoding];
-}
-
-+ (NSString*) elementName:(TBXMLElement*)aXMLElement error:(NSError **)error {
-    // check for nil element
-    if (nil == aXMLElement) {
-        if (error) *error = [TBXML errorWithCode:D_TBXML_ELEMENT_IS_NIL];
-        return @"";
-    }
-    
-    // check for nil element name
-    if (nil == aXMLElement->name || strlen(aXMLElement->name) == 0) {
-        if (error) *error = [TBXML errorWithCode:D_TBXML_ELEMENT_NAME_IS_NIL];
-        return @"";
-    }
-    
-	return [NSString stringWithCString:&aXMLElement->name[0] encoding:NSUTF8StringEncoding];
-}
-
-+ (NSString*) attributeName:(TBXMLAttribute*)aXMLAttribute {
-	if (nil == aXMLAttribute->name) return @"";
-	return [NSString stringWithCString:&aXMLAttribute->name[0] encoding:NSUTF8StringEncoding];
-}
-
-+ (NSString*) attributeName:(TBXMLAttribute*)aXMLAttribute error:(NSError **)error {
-    // check for nil attribute
-    if (nil == aXMLAttribute) {
-        if (error) *error = [TBXML errorWithCode:D_TBXML_ATTRIBUTE_IS_NIL];
-        return @"";
-    }
-    
-    // check for nil attribute name
-    if (nil == aXMLAttribute->name) {
-        if (error) *error = [TBXML errorWithCode:D_TBXML_ATTRIBUTE_NAME_IS_NIL];
-        return @"";
-    }
-    
-	return [NSString stringWithCString:&aXMLAttribute->name[0] encoding:NSUTF8StringEncoding];
-}
-
-
-+ (NSString*) attributeValue:(TBXMLAttribute*)aXMLAttribute {
-	if (nil == aXMLAttribute->value) return @"";
-	return [NSString stringWithCString:&aXMLAttribute->value[0] encoding:NSUTF8StringEncoding];
-}
-
-+ (NSString*) attributeValue:(TBXMLAttribute*)aXMLAttribute error:(NSError **)error {
-    // check for nil attribute
-    if (nil == aXMLAttribute) {
-        if (error) *error = [TBXML errorWithCode:D_TBXML_ATTRIBUTE_IS_NIL];
-        return @"";
-    }
-    
-	return [NSString stringWithCString:&aXMLAttribute->value[0] encoding:NSUTF8StringEncoding];
-}
-
-+ (NSString*) textForElement:(TBXMLElement*)aXMLElement {
-	if (nil == aXMLElement->text) return @"";
-	return [NSString stringWithCString:&aXMLElement->text[0] encoding:NSUTF8StringEncoding];
-}
-
-+ (NSString*) textForElement:(TBXMLElement*)aXMLElement error:(NSError **)error {
-    // check for nil element
-    if (nil == aXMLElement) {
-        if (error) *error = [TBXML errorWithCode:D_TBXML_ELEMENT_IS_NIL];
-        return @"";
-    }
-    
-    // check for nil text value
-    if (nil == aXMLElement->text || strlen(aXMLElement->text) == 0) {
-        if (error) *error = [TBXML errorWithCode:D_TBXML_ELEMENT_TEXT_IS_NIL];
-        return @"";
-    }
-    
-	return [NSString stringWithCString:&aXMLElement->text[0] encoding:NSUTF8StringEncoding];
-}
-
-+ (NSString*) valueOfAttributeNamed:(NSString *)aName forElement:(TBXMLElement*)aXMLElement {
-	const char * name = [aName cStringUsingEncoding:NSUTF8StringEncoding];
-	NSString * value = nil;
-	TBXMLAttribute * attribute = aXMLElement->firstAttribute;
-	while (attribute) {
-		if (strlen(attribute->name) == strlen(name) && memcmp(attribute->name,name,strlen(name)) == 0) {
-			value = [NSString stringWithCString:&attribute->value[0] encoding:NSUTF8StringEncoding];
-			break;
-		}
-		attribute = attribute->next;
-	}
-	return value;
-}
-
-+ (NSString*) valueOfAttributeNamed:(NSString *)aName forElement:(TBXMLElement*)aXMLElement error:(NSError **)error {
-    // check for nil element
-    if (nil == aXMLElement) {
-        if (error) *error = [TBXML errorWithCode:D_TBXML_ELEMENT_IS_NIL];
-        return @"";
-    }
-    
-    // check for nil name parameter
-    if (nil == aName) {
-        if (error) *error = [TBXML errorWithCode:D_TBXML_ATTRIBUTE_NAME_IS_NIL];
-        return @"";
-    }
-    
-	const char * name = [aName cStringUsingEncoding:NSUTF8StringEncoding];
-	NSString * value = nil;
-    
-	TBXMLAttribute * attribute = aXMLElement->firstAttribute;
-	while (attribute) {
-		if (strlen(attribute->name) == strlen(name) && memcmp(attribute->name,name,strlen(name)) == 0) {
-            if (attribute->value[0])
-                value = [NSString stringWithCString:&attribute->value[0] encoding:NSUTF8StringEncoding];
-            else
-                value = [NSString stringWithString:@""];
-            
-			break;
-		}
-		attribute = attribute->next;
-	}
-    
-    // check for attribute not found
-    if (!value) {
-        if (error) *error = [TBXML errorWithCode:D_TBXML_ATTRIBUTE_NOT_FOUND];
-        return @"";
-    }
-    
-	return value;
-}
-
-+ (TBXMLElement*) childElementNamed:(NSString*)aName parentElement:(TBXMLElement*)aParentXMLElement{
-    
-	TBXMLElement * xmlElement = aParentXMLElement->firstChild;
-	const char * name = [aName cStringUsingEncoding:NSUTF8StringEncoding];
-	while (xmlElement) {
-		if (strlen(xmlElement->name) == strlen(name) && memcmp(xmlElement->name,name,strlen(name)) == 0) {
-			return xmlElement;
-		}
-		xmlElement = xmlElement->nextSibling;
-	}
-	return nil;
-}
-
-+ (TBXMLElement*) childElementNamed:(NSString*)aName parentElement:(TBXMLElement*)aParentXMLElement error:(NSError **)error {
-    // check for nil element
-    if (nil == aParentXMLElement) {
-        if (error) *error = [TBXML errorWithCode:D_TBXML_ELEMENT_IS_NIL];
-        return nil;
-    }
-    
-    // check for nil name parameter
-    if (nil == aName) {
-        if (error) *error = [TBXML errorWithCode:D_TBXML_PARAM_NAME_IS_NIL];
-        return nil;
-    }
-    
-	TBXMLElement * xmlElement = aParentXMLElement->firstChild;
-	const char * name = [aName cStringUsingEncoding:NSUTF8StringEncoding];
-	while (xmlElement) {
-		if (strlen(xmlElement->name) == strlen(name) && memcmp(xmlElement->name,name,strlen(name)) == 0) {
-			return xmlElement;
-		}
-		xmlElement = xmlElement->nextSibling;
-	}
-    
-    if (error) *error = [TBXML errorWithCode:D_TBXML_ELEMENT_NOT_FOUND];
-    
-	return nil;
-}
-
-+ (TBXMLElement*) nextSiblingNamed:(NSString*)aName searchFromElement:(TBXMLElement*)aXMLElement{
-	TBXMLElement * xmlElement = aXMLElement->nextSibling;
-	const char * name = [aName cStringUsingEncoding:NSUTF8StringEncoding];
-	while (xmlElement) {
-		if (strlen(xmlElement->name) == strlen(name) && memcmp(xmlElement->name,name,strlen(name)) == 0) {
-			return xmlElement;
-		}
-		xmlElement = xmlElement->nextSibling;
-	}
-	return nil;
-}
-
-+ (TBXMLElement*) nextSiblingNamed:(NSString*)aName searchFromElement:(TBXMLElement*)aXMLElement error:(NSError **)error {
-    // check for nil element
-    if (nil == aXMLElement) {
-        if (error) *error = [TBXML errorWithCode:D_TBXML_ELEMENT_IS_NIL];
-        return nil;
-    }
-    
-    // check for nil name parameter
-    if (nil == aName) {
-        if (error) *error = [TBXML errorWithCode:D_TBXML_PARAM_NAME_IS_NIL];
-        return nil;
-    }
-    
-	TBXMLElement * xmlElement = aXMLElement->nextSibling;
-	const char * name = [aName cStringUsingEncoding:NSUTF8StringEncoding];
-	while (xmlElement) {
-		if (strlen(xmlElement->name) == strlen(name) && memcmp(xmlElement->name,name,strlen(name)) == 0) {
-			return xmlElement;
-		}
-		xmlElement = xmlElement->nextSibling;
-	}
-    
-    if (error) *error = [TBXML errorWithCode:D_TBXML_ELEMENT_NOT_FOUND];
-    
-	return nil;
-}
-
-+ (void)iterateElementsForQuery:(NSString *)query fromElement:(TBXMLElement *)anElement withBlock:(TBXMLIterateBlock)iterateBlock {
-    
-    NSArray *components = [query componentsSeparatedByString:@"."];
-    TBXMLElement *currTBXMLElement = anElement;
-    
-    // navigate down
-    for (NSInteger i=0; i < components.count; ++i) {
-        NSString *iTagName = [components objectAtIndex:i];
-        
-        if ([iTagName isEqualToString:@"*"]) {
-            currTBXMLElement = currTBXMLElement->firstChild;
-            
-            // different behavior depending on if this is the end of the query or midstream
-            if (i < (components.count - 1)) {
-                // midstream
-                do {
-                    NSString *restOfQuery = [[components subarrayWithRange:NSMakeRange(i + 1, components.count - i - 1)] componentsJoinedByString:@"."];
-                    [TBXML iterateElementsForQuery:restOfQuery fromElement:currTBXMLElement withBlock:iterateBlock];
-                } while ((currTBXMLElement = currTBXMLElement->nextSibling));
-                
-            }
-        } else {
-            currTBXMLElement = [TBXML childElementNamed:iTagName parentElement:currTBXMLElement];            
-        }
-        
-        if (!currTBXMLElement) {
-            break;
-        }
-    }
-    
-    if (currTBXMLElement) {
-        // enumerate
-        NSString *childTagName = [components lastObject];
-        
-        if ([childTagName isEqualToString:@"*"]) {
-            childTagName = nil;
-        }
-        
-        do {
-            iterateBlock(currTBXMLElement);
-        } while (childTagName ? (currTBXMLElement = [TBXML nextSiblingNamed:childTagName searchFromElement:currTBXMLElement]) : (currTBXMLElement = currTBXMLElement->nextSibling));
-    }
-}
-
-+ (void)iterateAttributesOfElement:(TBXMLElement *)anElement withBlock:(TBXMLIterateAttributeBlock)iterateAttributeBlock {
-
-    // Obtain first attribute from element
-    TBXMLAttribute * attribute = anElement->firstAttribute;
-    
-    // if attribute is valid
-    
-    while (attribute) {
-        // Call the iterateAttributeBlock with the attribute, it's name and value
-        iterateAttributeBlock(attribute, [TBXML attributeName:attribute], [TBXML attributeValue:attribute]);
-        
-        // Obtain the next attribute
-        attribute = attribute->next;
-    }
-}
-
-@end
-
-
-// ================================================================================================
-// Private Implementation
-// ================================================================================================
-
-#pragma mark -
-#pragma mark Private implementation
-
-@implementation TBXML (Private)
-
-+ (NSString *) errorTextForCode:(int)code {
-    NSString * codeText = @"";
-    
-    switch (code) {
-        case D_TBXML_DATA_NIL:                  codeText = @"Data is nil";                          break;
-        case D_TBXML_DECODE_FAILURE:            codeText = @"Decode failure";                       break;
-        case D_TBXML_MEMORY_ALLOC_FAILURE:      codeText = @"Unable to allocate memory";            break;
-        case D_TBXML_FILE_NOT_FOUND_IN_BUNDLE:  codeText = @"File not found in bundle";             break;
-            
-        case D_TBXML_ELEMENT_IS_NIL:            codeText = @"Element is nil";                       break;
-        case D_TBXML_ELEMENT_NAME_IS_NIL:       codeText = @"Element name is nil";                  break;
-        case D_TBXML_ATTRIBUTE_IS_NIL:          codeText = @"Attribute is nil";                     break;
-        case D_TBXML_ATTRIBUTE_NAME_IS_NIL:     codeText = @"Attribute name is nil";                break;
-        case D_TBXML_ELEMENT_TEXT_IS_NIL:       codeText = @"Element text is nil";                  break;
-        case D_TBXML_PARAM_NAME_IS_NIL:         codeText = @"Parameter name is nil";                break;
-        case D_TBXML_ATTRIBUTE_NOT_FOUND:       codeText = @"Attribute not found";                  break;
-        case D_TBXML_ELEMENT_NOT_FOUND:         codeText = @"Element not found";                    break;
-            
-        default: codeText = @"No Error Description!"; break;
-    }
-    
-    return codeText;
-}
-
-+ (NSError *) errorWithCode:(int)code {
-    
-    NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[TBXML errorTextForCode:code], NSLocalizedDescriptionKey, nil];
-    
-    return [NSError errorWithDomain:D_TBXML_DOMAIN 
-                               code:code 
-                           userInfo:userInfo];
-}
-
-+ (NSError *) errorWithCode:(int)code userInfo:(NSMutableDictionary *)someUserInfo {
-    
-    NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:someUserInfo];
-    [userInfo setValue:[TBXML errorTextForCode:code] forKey:NSLocalizedDescriptionKey];
-    
-    return [NSError errorWithDomain:D_TBXML_DOMAIN 
-                               code:code 
-                           userInfo:userInfo];
-}
-
-- (int) allocateBytesOfLength:(long)length error:(NSError **)error {
-    bytesLength = length;
-    
-    NSError *localError = nil;
-    
-    if(!length) {
-        localError = [TBXML errorWithCode:D_TBXML_DATA_NIL];
-    }
-    
-	bytes = malloc(bytesLength+1);
-    
-    if(!bytes) {
-        localError = [TBXML errorWithCode:D_TBXML_MEMORY_ALLOC_FAILURE];
-    }
-    
-    if (error) *error = localError;
-        
-    return localError == nil ? D_TBXML_SUCCESS : [localError code];
-}
-
-- (void) decodeBytes {
-	
-	// -----------------------------------------------------------------------------
-	// Process xml
-	// -----------------------------------------------------------------------------
-	
-	// set elementStart pointer to the start of our xml
-	char * elementStart=bytes;
-	
-	// set parent element to nil
-	TBXMLElement * parentXMLElement = nil;
-	
-	// find next element start
-	while ((elementStart = strstr(elementStart,"<"))) {
-		
-		// detect comment section
-		if (strncmp(elementStart,"<!--",4) == 0) {
-			elementStart = strstr(elementStart,"-->") + 3;
-			continue;
-		}
-
-		// detect cdata section within element text
-		int isCDATA = strncmp(elementStart,"<![CDATA[",9);
-		
-		// if cdata section found, skip data within cdata section and remove cdata tags
-		if (isCDATA==0) {
-			
-			// find end of cdata section
-			char * CDATAEnd = strstr(elementStart,"]]>");
-			
-			// find start of next element skipping any cdata sections within text
-			char * elementEnd = CDATAEnd;
-			
-			// find next open tag
-			elementEnd = strstr(elementEnd,"<");
-			// if open tag is a cdata section
-			while (strncmp(elementEnd,"<![CDATA[",9) == 0) {
-				// find end of cdata section
-				elementEnd = strstr(elementEnd,"]]>");
-				// find next open tag
-				elementEnd = strstr(elementEnd,"<");
-			}
-			
-			// calculate length of cdata content
-			long CDATALength = CDATAEnd-elementStart;
-			
-			// calculate total length of text
-			long textLength = elementEnd-elementStart;
-			
-			// remove begining cdata section tag
-			memcpy(elementStart, elementStart+9, CDATAEnd-elementStart-9);
-
-			// remove ending cdata section tag
-			memcpy(CDATAEnd-9, CDATAEnd+3, textLength-CDATALength-3);
-			
-			// blank out end of text
-			memset(elementStart+textLength-12,' ',12);
-			
-			// set new search start position 
-			elementStart = CDATAEnd-9;
-			continue;
-		}
-		
-		
-		// find element end, skipping any cdata sections within attributes
-		char * elementEnd = elementStart+1;		
-		while ((elementEnd = strpbrk(elementEnd, "<>"))) {
-			if (strncmp(elementEnd,"<![CDATA[",9) == 0) {
-				elementEnd = strstr(elementEnd,"]]>")+3;
-			} else {
-				break;
-			}
-		}
-		
-        if (!elementEnd) break;
-		
-		// null terminate element end
-		if (elementEnd) *elementEnd = 0;
-		
-		// null terminate element start so previous element text doesnt overrun
-		*elementStart = 0;
-		
-		// get element name start
-		char * elementNameStart = elementStart+1;
-		
-		// ignore tags that start with ? or ! unless cdata "<![CDATA"
-		if (*elementNameStart == '?' || (*elementNameStart == '!' && isCDATA != 0)) {
-			elementStart = elementEnd+1;
-			continue;
-		}
-		
-		// ignore attributes/text if this is a closing element
-		if (*elementNameStart == '/') {
-			elementStart = elementEnd+1;
-			if (parentXMLElement) {
-
-				if (parentXMLElement->text) {
-					// trim whitespace from start of text
-					while (isspace(*parentXMLElement->text)) 
-						parentXMLElement->text++;
-					
-					// trim whitespace from end of text
-					char * end = parentXMLElement->text + strlen(parentXMLElement->text)-1;
-					while (end > parentXMLElement->text && isspace(*end)) 
-						*end--=0;
-				}
-				
-				parentXMLElement = parentXMLElement->parentElement;
-				
-				// if parent element has children clear text
-				if (parentXMLElement && parentXMLElement->firstChild)
-					parentXMLElement->text = 0;
-				
-			}
-			continue;
-		}
-		
-		
-		// is this element opening and closing
-		BOOL selfClosingElement = NO;
-		if (*(elementEnd-1) == '/') {
-			selfClosingElement = YES;
-		}
-		
-		
-		// create new xmlElement struct
-		TBXMLElement * xmlElement = [self nextAvailableElement];
-		
-		// set element name
-		xmlElement->name = elementNameStart;
-		
-		// if there is a parent element
-		if (parentXMLElement) {
-			
-			// if this is first child of parent element
-			if (parentXMLElement->currentChild) {
-				// set next child element in list
-				parentXMLElement->currentChild->nextSibling = xmlElement;
-				xmlElement->previousSibling = parentXMLElement->currentChild;
-				
-				parentXMLElement->currentChild = xmlElement;
-				
-				
-			} else {
-				// set first child element
-				parentXMLElement->currentChild = xmlElement;
-				parentXMLElement->firstChild = xmlElement;
-			}
-			
-			xmlElement->parentElement = parentXMLElement;
-		}
-		
-		
-		// in the following xml the ">" is replaced with \0 by elementEnd. 
-		// element may contain no atributes and would return nil while looking for element name end
-		// <tile> 
-		// find end of element name
-		char * elementNameEnd = strpbrk(xmlElement->name," /\n");
-		
-		
-		// if end was found check for attributes
-		if (elementNameEnd) {
-			
-			// null terminate end of elemenet name
-			*elementNameEnd = 0;
-			
-			char * chr = elementNameEnd;
-			char * name = nil;
-			char * value = nil;
-			char * CDATAStart = nil;
-			char * CDATAEnd = nil;
-			TBXMLAttribute * lastXMLAttribute = nil;
-			TBXMLAttribute * xmlAttribute = nil;
-			BOOL singleQuote = NO;
-			
-			int mode = TBXML_ATTRIBUTE_NAME_START;
-			
-			// loop through all characters within element
-			while (chr++ < elementEnd) {
-				
-				switch (mode) {
-					// look for start of attribute name
-					case TBXML_ATTRIBUTE_NAME_START:
-						if (isspace(*chr)) continue;
-						name = chr;
-						mode = TBXML_ATTRIBUTE_NAME_END;
-						break;
-					// look for end of attribute name
-					case TBXML_ATTRIBUTE_NAME_END:
-						if (isspace(*chr) || *chr == '=') {
-							*chr = 0;
-							mode = TBXML_ATTRIBUTE_VALUE_START;
-						}
-						break;
-					// look for start of attribute value
-					case TBXML_ATTRIBUTE_VALUE_START:
-						if (isspace(*chr)) continue;
-						if (*chr == '"' || *chr == '\'') {
-							value = chr+1;
-							mode = TBXML_ATTRIBUTE_VALUE_END;
-							if (*chr == '\'') 
-								singleQuote = YES;
-							else
-								singleQuote = NO;
-						}
-						break;
-					// look for end of attribute value
-					case TBXML_ATTRIBUTE_VALUE_END:
-						if (*chr == '<' && strncmp(chr, "<![CDATA[", 9) == 0) {
-							mode = TBXML_ATTRIBUTE_CDATA_END;
-						}else if ((*chr == '"' && singleQuote == NO) || (*chr == '\'' && singleQuote == YES)) {
-							*chr = 0;
-							
-							// remove cdata section tags
-							while ((CDATAStart = strstr(value, "<![CDATA["))) {
-								
-								// remove begin cdata tag
-								memcpy(CDATAStart, CDATAStart+9, strlen(CDATAStart)-8);
-								
-								// search for end cdata
-								CDATAEnd = strstr(CDATAStart,"]]>");
-								
-								// remove end cdata tag
-								memcpy(CDATAEnd, CDATAEnd+3, strlen(CDATAEnd)-2);
-							}
-							
-							
-							// create new attribute
-							xmlAttribute = [self nextAvailableAttribute];
-							
-							// if this is the first attribute found, set pointer to this attribute on element
-							if (!xmlElement->firstAttribute) xmlElement->firstAttribute = xmlAttribute;
-							// if previous attribute found, link this attribute to previous one
-							if (lastXMLAttribute) lastXMLAttribute->next = xmlAttribute;
-							// set last attribute to this attribute
-							lastXMLAttribute = xmlAttribute;
-
-							// set attribute name & value
-							xmlAttribute->name = name;
-							xmlAttribute->value = value;
-							
-							// clear name and value pointers
-							name = nil;
-							value = nil;
-							
-							// start looking for next attribute
-							mode = TBXML_ATTRIBUTE_NAME_START;
-						}
-						break;
-						// look for end of cdata
-					case TBXML_ATTRIBUTE_CDATA_END:
-						if (*chr == ']') {
-							if (strncmp(chr, "]]>", 3) == 0) {
-								mode = TBXML_ATTRIBUTE_VALUE_END;
-							}
-						}
-						break;						
-					default:
-						break;
-				}
-			}
-		}
-		
-		// if tag is not self closing, set parent to current element
-		if (!selfClosingElement) {
-			// set text on element to element end+1
-			if (*(elementEnd+1) != '>')
-				xmlElement->text = elementEnd+1;
-			
-			parentXMLElement = xmlElement;
-		}
-		
-		// start looking for next element after end of current element
-		elementStart = elementEnd+1;
-	}
-}
-
-// Deallocate used memory
-- (void) dealloc {
-    
-	if (bytes) {
-		free(bytes);
-		bytes = nil;
-	}
-	
-	while (currentElementBuffer) {
-		if (currentElementBuffer->elements)
-			free(currentElementBuffer->elements);
-		
-		if (currentElementBuffer->previous) {
-			currentElementBuffer = currentElementBuffer->previous;
-			free(currentElementBuffer->next);
-		} else {
-			free(currentElementBuffer);
-			currentElementBuffer = 0;
-		}
-	}
-	
-	while (currentAttributeBuffer) {
-		if (currentAttributeBuffer->attributes)
-			free(currentAttributeBuffer->attributes);
-		
-		if (currentAttributeBuffer->previous) {
-			currentAttributeBuffer = currentAttributeBuffer->previous;
-			free(currentAttributeBuffer->next);
-		} else {
-			free(currentAttributeBuffer);
-			currentAttributeBuffer = 0;
-		}
-	}
-}
-
-- (TBXMLElement*) nextAvailableElement {
-	currentElement++;
-	
-	if (!currentElementBuffer) {
-		currentElementBuffer = calloc(1, sizeof(TBXMLElementBuffer));
-		currentElementBuffer->elements = (TBXMLElement*)calloc(1,sizeof(TBXMLElement)*MAX_ELEMENTS);
-		currentElement = 0;
-		rootXMLElement = &currentElementBuffer->elements[currentElement];
-	} else if (currentElement >= MAX_ELEMENTS) {
-		currentElementBuffer->next = calloc(1, sizeof(TBXMLElementBuffer));
-		currentElementBuffer->next->previous = currentElementBuffer;
-		currentElementBuffer = currentElementBuffer->next;
-		currentElementBuffer->elements = (TBXMLElement*)calloc(1,sizeof(TBXMLElement)*MAX_ELEMENTS);
-		currentElement = 0;
-	}
-	
-	return &currentElementBuffer->elements[currentElement];
-}
-
-- (TBXMLAttribute*) nextAvailableAttribute {
-	currentAttribute++;
-	
-	if (!currentAttributeBuffer) {
-		currentAttributeBuffer = calloc(1, sizeof(TBXMLAttributeBuffer));
-		currentAttributeBuffer->attributes = (TBXMLAttribute*)calloc(MAX_ATTRIBUTES,sizeof(TBXMLAttribute));
-		currentAttribute = 0;
-	} else if (currentAttribute >= MAX_ATTRIBUTES) {
-		currentAttributeBuffer->next = calloc(1, sizeof(TBXMLAttributeBuffer));
-		currentAttributeBuffer->next->previous = currentAttributeBuffer;
-		currentAttributeBuffer = currentAttributeBuffer->next;
-		currentAttributeBuffer->attributes = (TBXMLAttribute*)calloc(MAX_ATTRIBUTES,sizeof(TBXMLAttribute));
-		currentAttribute = 0;
-	}
-	
-	return &currentAttributeBuffer->attributes[currentAttribute];
-}
-
-@end

+ 0 - 25
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Channel/TrackChooseView.h

@@ -1,25 +0,0 @@
-//
-//  TrackChooseView.h
-//  StudentDaya
-//
-//  Created by Kyle on 2022/1/21.
-//  Copyright © 2022 DayaMusic. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
-typedef void(^ChooseTrackCallback)(NSMutableArray * _Nullable trackNameArray);
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface TrackChooseView : UIView
-
-+ (instancetype)shareInstanceWithFullTrackArray:(NSMutableArray *)trackNameArray;
-
-- (void)chooseTrackCallback:(ChooseTrackCallback)callback;
-
-- (void)showInView:(UIView *)displayView;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 142
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Channel/TrackChooseView.m

@@ -1,142 +0,0 @@
-//
-//  TrackChooseView.m
-//  StudentDaya
-//
-//  Created by Kyle on 2022/1/21.
-//  Copyright © 2022 DayaMusic. All rights reserved.
-//
-
-#import "TrackChooseView.h"
-
-@interface TrackChooseView ()
-
-@property (nonatomic, strong) NSMutableArray *trackNameArray;
-
-@property (nonatomic, strong) NSMutableArray *chooseTrackArray;
-
-@property (nonatomic, strong) NSMutableArray *tempoArray;
-
-@property (nonatomic, strong) UIScrollView *baseScroll;
-
-@property (weak, nonatomic) IBOutlet UIView *contentView;
-
-@property (nonatomic, copy) ChooseTrackCallback callback;
-
-@end
-
-
-@implementation TrackChooseView
-
-+ (instancetype)shareInstanceWithFullTrackArray:(NSMutableArray *)trackNameArray {
-    TrackChooseView *view = [[[NSBundle mainBundle] loadNibNamed:@"TrackChooseView" owner:nil options:nil] firstObject];
-    view.trackNameArray = trackNameArray;
-    view.frame = CGRectMake(0, 0, KLandscapeWidth, KLandscapeHeight);
-    view.backgroundColor = HexRGBAlpha(0x000000, 0.5f);
-    [view displayView];
-    return view;
-}
-
-
-- (void)displayView {
-    self.tempoArray = [NSMutableArray array];
-    self.baseScroll = [[UIScrollView alloc] init];
-    [self addSubview:self.baseScroll];
-    [self.baseScroll mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.left.right.bottom.top.mas_equalTo(self.contentView);
-    }];
-    CGFloat width = 300.0f;
-    CGFloat height = KLandscapeHeight - 64 - 50 - 40;
-    CGFloat space = 10;
-    CGFloat buttonHeight = 30;
-    CGFloat buttonWidth = (width - space * 4) / 3.0f;
-    CGFloat maxHeight = 0;
-    for (NSInteger i = 0; i < self.trackNameArray.count; i++) {
-        CGRect frame = CGRectMake(space + (i % 3) * (buttonWidth + space), (i / 3) * (buttonHeight + space), buttonWidth, buttonHeight);
-        UIButton *button =  [self createButtonWithName:self.trackNameArray[i] frame:frame tag:i+1000];
-        if (i == 0) {
-            button.selected = YES;
-            button.layer.borderColor = THEMECOLOR.CGColor;
-        }
-        [self.baseScroll addSubview:button];
-        maxHeight = (i / 3) * (buttonHeight + space) + buttonHeight + space;
-    }
-    if (height < maxHeight) {
-        height = maxHeight;
-    }
-    self.baseScroll.contentSize = CGSizeMake(width, height);
-    // 默认选择第一个
-    [self.chooseTrackArray addObject:self.trackNameArray[0]];
-    [self.tempoArray addObject:self.trackNameArray[0]];
-}
-
-
-- (UIButton *)createButtonWithName:(NSString *)name frame:(CGRect)frame tag:(NSInteger)tag {
-    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
-    button.frame = frame;
-    button.tag = 1000 + tag;
-    [button setTitle:name forState:UIControlStateNormal];
-    [button addTarget:self action:@selector(buttonClickAction:) forControlEvents:UIControlEventTouchUpInside];
-    button.layer.cornerRadius = 5.0f;
-    button.layer.borderColor = HexRGB(0xf5f5f5).CGColor;
-    button.layer.borderWidth = 1.0f;
-    [button.titleLabel setFont:[UIFont systemFontOfSize:12.0f]];
-    [button setTitleColor:HexRGB(0x333333) forState:UIControlStateNormal];
-    [button setTitleColor:THEMECOLOR forState:UIControlStateSelected];
-    return button;
-}
-
-- (void)buttonClickAction:(UIButton *)sender {
-    sender.selected = !sender.selected;
-    BOOL isSelected = sender.isSelected;
-    NSString *trackName = sender.titleLabel.text;
-    if (isSelected) {
-        sender.layer.borderColor = THEMECOLOR.CGColor;
-        [self chooseTrackWithName:trackName];
-    }
-    else {
-        sender.layer.borderColor = HexRGB(0xf5f5f5).CGColor;
-        [self removeChooseTrackWithName:trackName];
-    }
-}
-- (IBAction)sureAction:(id)sender {
-    if (self.callback) {
-        self.chooseTrackArray = [NSMutableArray arrayWithArray:self.tempoArray];
-        self.callback(self.chooseTrackArray);
-    }
-    [self removeFromSuperview];
-}
-
-- (IBAction)cancleAction:(id)sender {
-    [self hideView];
-}
-
-- (void)hideView {
-    [self removeFromSuperview];
-}
-- (void)chooseTrackWithName:(NSString *)trackName {
-    [self.tempoArray addObject:trackName];
-}
-
-- (void)removeChooseTrackWithName:(NSString *)trackName {
-    [self.tempoArray removeObject:trackName];
-}
-- (void)showInView:(UIView *)displayView {
-    [displayView addSubview:self];
-}
-
-
-- (void)chooseTrackCallback:(ChooseTrackCallback)callback {
-    if (callback) {
-        self.callback = callback;
-    }
-}
-
-/*
-// Only override drawRect: if you perform custom drawing.
-// An empty implementation adversely affects performance during animation.
-- (void)drawRect:(CGRect)rect {
-    // Drawing code
-}
-*/
-
-@end

+ 0 - 113
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Channel/TrackChooseView.xib

@@ -1,113 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
-    <device id="retina6_1" orientation="portrait" appearance="light"/>
-    <dependencies>
-        <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
-        <capability name="System colors in document resources" minToolsVersion="11.0"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
-        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="TrackChooseView">
-            <rect key="frame" x="0.0" y="0.0" width="750" height="375"/>
-            <autoresizingMask key="autoresizingMask"/>
-            <subviews>
-                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="eNR-CP-hMc">
-                    <rect key="frame" x="215" y="32" width="320" height="311"/>
-                    <subviews>
-                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="image_alertTips" translatesAutoresizingMaskIntoConstraints="NO" id="GeC-WM-XZa">
-                            <rect key="frame" x="106" y="-4" width="108" height="31"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="31" id="Vqd-ny-i28"/>
-                                <constraint firstAttribute="width" constant="108" id="fr5-5C-Fjc"/>
-                            </constraints>
-                        </imageView>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="选择乐器" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jDn-Lm-9Nb">
-                            <rect key="frame" x="127" y="1.5" width="66" height="20"/>
-                            <fontDescription key="fontDescription" type="system" pointSize="16"/>
-                            <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                            <nil key="highlightedColor"/>
-                        </label>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="HLa-gh-ykH">
-                            <rect key="frame" x="10" y="40" width="300" height="221"/>
-                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                        </view>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="TuA-cX-WJb">
-                            <rect key="frame" x="110" y="271" width="100" height="30"/>
-                            <color key="backgroundColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <constraints>
-                                <constraint firstAttribute="width" constant="100" id="04l-xF-B07"/>
-                                <constraint firstAttribute="height" constant="30" id="Fpt-41-dXV"/>
-                            </constraints>
-                            <fontDescription key="fontDescription" type="system" pointSize="16"/>
-                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                            <state key="normal" title="确定"/>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                    <real key="value" value="15"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                            <connections>
-                                <action selector="sureAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="Jax-ON-cOH"/>
-                            </connections>
-                        </button>
-                    </subviews>
-                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                    <constraints>
-                        <constraint firstItem="GeC-WM-XZa" firstAttribute="centerX" secondItem="eNR-CP-hMc" secondAttribute="centerX" id="Ac7-xw-CrE"/>
-                        <constraint firstAttribute="width" constant="320" id="FfP-sW-0Os"/>
-                        <constraint firstAttribute="bottom" secondItem="TuA-cX-WJb" secondAttribute="bottom" constant="10" id="MlH-oo-9cl"/>
-                        <constraint firstItem="HLa-gh-ykH" firstAttribute="top" secondItem="eNR-CP-hMc" secondAttribute="top" constant="40" id="ObX-yh-RXp"/>
-                        <constraint firstItem="jDn-Lm-9Nb" firstAttribute="centerX" secondItem="GeC-WM-XZa" secondAttribute="centerX" id="Qqc-ww-Ctv"/>
-                        <constraint firstItem="TuA-cX-WJb" firstAttribute="top" secondItem="HLa-gh-ykH" secondAttribute="bottom" constant="10" id="UfX-Vl-d1X"/>
-                        <constraint firstAttribute="trailing" secondItem="HLa-gh-ykH" secondAttribute="trailing" constant="10" id="YLK-oy-QnV"/>
-                        <constraint firstItem="jDn-Lm-9Nb" firstAttribute="centerY" secondItem="GeC-WM-XZa" secondAttribute="centerY" id="kEM-Ki-Iwi"/>
-                        <constraint firstItem="GeC-WM-XZa" firstAttribute="top" secondItem="eNR-CP-hMc" secondAttribute="top" constant="-4" id="kas-ox-JDL"/>
-                        <constraint firstItem="HLa-gh-ykH" firstAttribute="leading" secondItem="eNR-CP-hMc" secondAttribute="leading" constant="10" id="oob-L8-Acp"/>
-                        <constraint firstItem="TuA-cX-WJb" firstAttribute="centerX" secondItem="eNR-CP-hMc" secondAttribute="centerX" id="vjk-rT-eyj"/>
-                    </constraints>
-                    <userDefinedRuntimeAttributes>
-                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                            <real key="value" value="12"/>
-                        </userDefinedRuntimeAttribute>
-                    </userDefinedRuntimeAttributes>
-                </view>
-                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="91q-38-ktZ">
-                    <rect key="frame" x="535" y="10" width="44" height="44"/>
-                    <constraints>
-                        <constraint firstAttribute="height" constant="44" id="cnq-7T-YJl"/>
-                        <constraint firstAttribute="width" constant="44" id="d4t-p7-m3i"/>
-                    </constraints>
-                    <state key="normal" image="cloud_cancle"/>
-                    <connections>
-                        <action selector="cancleAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="ar1-Sk-D9Q"/>
-                    </connections>
-                </button>
-            </subviews>
-            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-            <constraints>
-                <constraint firstItem="eNR-CP-hMc" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="32" id="NJh-Th-HQW"/>
-                <constraint firstItem="91q-38-ktZ" firstAttribute="centerY" secondItem="eNR-CP-hMc" secondAttribute="top" id="Tqw-hy-1Uc"/>
-                <constraint firstAttribute="bottom" secondItem="eNR-CP-hMc" secondAttribute="bottom" constant="32" id="UxN-d4-lNH"/>
-                <constraint firstItem="91q-38-ktZ" firstAttribute="leading" secondItem="eNR-CP-hMc" secondAttribute="trailing" id="f9i-84-h7Y"/>
-                <constraint firstItem="eNR-CP-hMc" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="lVN-0h-cpf"/>
-            </constraints>
-            <nil key="simulatedTopBarMetrics"/>
-            <nil key="simulatedBottomBarMetrics"/>
-            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
-            <connections>
-                <outlet property="contentView" destination="HLa-gh-ykH" id="1ag-Ko-i22"/>
-            </connections>
-            <point key="canvasLocation" x="195.6521739130435" y="24.107142857142858"/>
-        </view>
-    </objects>
-    <resources>
-        <image name="cloud_cancle" width="26" height="26"/>
-        <image name="image_alertTips" width="108" height="31"/>
-        <systemColor name="systemBackgroundColor">
-            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-        </systemColor>
-    </resources>
-</document>

+ 0 - 23
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Help/CloudFeedbackView.h

@@ -1,23 +0,0 @@
-//
-//  CloudFeedbackView.h
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/15.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-typedef void(^CloudFeedbackCallback)(NSString *content, NSString *type);
-
-@interface CloudFeedbackView : UIView
-
-+ (instancetype)shareInstance;
-
-- (void)submitCallback:(CloudFeedbackCallback)callback;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 126
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Help/CloudFeedbackView.m

@@ -1,126 +0,0 @@
-//
-//  CloudFeedbackView.m
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/15.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import "CloudFeedbackView.h"
-
-@interface CloudFeedbackView ()<UITextViewDelegate>
-@property (weak, nonatomic) IBOutlet UILabel *tipsLabel;
-
-@property (weak, nonatomic) IBOutlet UILabel *countLabel;
-
-@property (weak, nonatomic) IBOutlet UITextView *textView;
-
-@property (nonatomic, copy) CloudFeedbackCallback callback;
-
-@property (nonatomic, strong) NSString *typeString;
-
-@property (nonatomic, assign) NSInteger lastChooseIndex;
-
-@end
-
-
-
-@implementation CloudFeedbackView
-
-- (void)awakeFromNib {
-    [super awakeFromNib];
-    self.textView.delegate = self;
-}
-
-+ (instancetype)shareInstance {
-    CloudFeedbackView *view = [[[NSBundle mainBundle] loadNibNamed:@"CloudFeedbackView" owner:nil options:nil] firstObject];
-    return view;
-}
-
-- (void)submitCallback:(CloudFeedbackCallback)callback {
-    if (callback) {
-        self.callback = callback;
-    }
-}
-
-- (IBAction)TypeButonAction:(UIButton *)sender {
-    [sender setBackgroundColor:HexRGB(0xe2fff9)];
-    sender.layer.borderColor = THEMECOLOR.CGColor;
-    self.typeString = sender.titleLabel.text;
-    NSInteger index = sender.tag;
-    
-    if (index == self.lastChooseIndex || self.lastChooseIndex == 0) {
-        self.lastChooseIndex = index;
-        return;
-    }
-    else {
-        UIButton *preButton = (UIButton *)[self viewWithTag:self.lastChooseIndex];
-        [preButton setBackgroundColor:HexRGB(0x999999)];
-        preButton.layer.borderColor = HexRGB(0xf8f8f8).CGColor;
-        self.lastChooseIndex = index;
-    }
-}
-
-- (IBAction)sureAction:(id)sender {
-    [self endEditing:YES];
-    if (self.callback) {
-        if ([NSString isEmptyString:self.typeString]) {
-            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请选择问题类型"];
-            return;
-        }
-        else if ([NSString isEmptyString:self.textView.text]) {
-            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请描述您遇到的问题"];
-            return;
-        }
-        self.callback(self.textView.text, self.typeString);
-    }
-}
-
-#pragma mark   ---- delegate
-
-- (void)textViewDidBeginEditing:(UITextView *)textView {
-    self.tipsLabel.hidden = YES;
-}
-- (void)textViewDidEndEditing:(UITextView *)textView {
-    if ([NSString isEmptyString:textView.text]) {
-        self.tipsLabel.hidden = NO;
-    }
-}
-
-- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
-    if ([text isEqualToString:@"\n"]) {
-        [self endEditing:YES];
-        return YES;
-    }
-    if ([text isEqualToString:@""]) {
-        return YES;
-    }
-    // 输入控制
-    NSString *newString = [textView.text stringByReplacingCharactersInRange:range withString:text];
-    if (newString.length > 200) {
-        return NO;
-    }
-    self.countLabel.text = [NSString stringWithFormat:@"%zd/200", newString.length];
-    return YES;
-}
-
-
-- (BOOL)textViewShouldEndEditing:(UITextView *)textView {
-    [self endEditing:YES];
-    return YES;
-}
-
-- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
-    [self endEditing:YES];
-}
-
-
-/*
-// Only override drawRect: if you perform custom drawing.
-// An empty implementation adversely affects performance during animation.
-- (void)drawRect:(CGRect)rect {
-    // Drawing code
-}
-*/
-
-@end

+ 0 - 325
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Help/CloudFeedbackView.xib

@@ -1,325 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
-    <device id="retina6_1" orientation="portrait" appearance="light"/>
-    <dependencies>
-        <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
-        <capability name="System colors in document resources" minToolsVersion="11.0"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
-        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="CloudFeedbackView">
-            <rect key="frame" x="0.0" y="0.0" width="1162" height="515"/>
-            <autoresizingMask key="autoresizingMask"/>
-            <subviews>
-                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0Jt-Nx-mxp">
-                    <rect key="frame" x="421" y="97.5" width="320" height="320"/>
-                    <subviews>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="意见反馈" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="39T-t6-0Wv">
-                            <rect key="frame" x="127.5" y="12" width="65.5" height="22"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="22" id="Ma2-5f-LS5"/>
-                            </constraints>
-                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
-                            <color key="textColor" red="0.10196078431372549" green="0.10196078431372549" blue="0.10196078431372549" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <nil key="highlightedColor"/>
-                        </label>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Gq5-UG-UPH">
-                            <rect key="frame" x="0.0" y="45" width="320" height="1"/>
-                            <color key="backgroundColor" red="0.94117647058823528" green="0.94117647058823528" blue="0.94117647058823528" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="1" id="bXb-3D-Mpu"/>
-                            </constraints>
-                        </view>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="请选择问题类型" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TEQ-Mu-woj">
-                            <rect key="frame" x="18" y="70" width="100" height="20"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="20" id="jjb-5v-wg7"/>
-                            </constraints>
-                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
-                            <color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <nil key="highlightedColor"/>
-                        </label>
-                        <button opaque="NO" tag="1001" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7U7-1u-Czi">
-                            <rect key="frame" x="18" y="98" width="89.5" height="27"/>
-                            <color key="backgroundColor" red="0.97254901960784312" green="0.97254901960784312" blue="0.97254901960784312" alpha="1" colorSpace="calibratedRGB"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="27" id="mkM-2a-PEa"/>
-                            </constraints>
-                            <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                            <state key="normal" title="识别不准">
-                                <color key="titleColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
-                            </state>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                    <real key="value" value="6"/>
-                                </userDefinedRuntimeAttribute>
-                                <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
-                                    <real key="value" value="1"/>
-                                </userDefinedRuntimeAttribute>
-                                <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
-                                    <color key="value" red="0.97254901960784312" green="0.97254901960784312" blue="0.97254901960784312" alpha="1" colorSpace="calibratedRGB"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                            <connections>
-                                <action selector="TypeButonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="zAI-Ki-2V5"/>
-                            </connections>
-                        </button>
-                        <button opaque="NO" tag="1002" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="J1s-eN-oKW">
-                            <rect key="frame" x="115.5" y="98" width="89" height="27"/>
-                            <color key="backgroundColor" red="0.97254901959999995" green="0.97254901959999995" blue="0.97254901959999995" alpha="1" colorSpace="calibratedRGB"/>
-                            <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                            <state key="normal" title="无法评测">
-                                <color key="titleColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
-                            </state>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                    <real key="value" value="6"/>
-                                </userDefinedRuntimeAttribute>
-                                <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
-                                    <real key="value" value="1"/>
-                                </userDefinedRuntimeAttribute>
-                                <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
-                                    <color key="value" red="0.97254901960784312" green="0.97254901960784312" blue="0.97254901960784312" alpha="1" colorSpace="calibratedRGB"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                            <connections>
-                                <action selector="TypeButonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="U77-aX-4ha"/>
-                            </connections>
-                        </button>
-                        <button opaque="NO" tag="1003" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="x52-Ag-qNB">
-                            <rect key="frame" x="212.5" y="98" width="89.5" height="27"/>
-                            <color key="backgroundColor" red="0.97254901959999995" green="0.97254901959999995" blue="0.97254901959999995" alpha="1" colorSpace="calibratedRGB"/>
-                            <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                            <state key="normal" title="不出评测结果">
-                                <color key="titleColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
-                            </state>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                    <real key="value" value="6"/>
-                                </userDefinedRuntimeAttribute>
-                                <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
-                                    <real key="value" value="1"/>
-                                </userDefinedRuntimeAttribute>
-                                <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
-                                    <color key="value" red="0.97254901960784312" green="0.97254901960784312" blue="0.97254901960784312" alpha="1" colorSpace="calibratedRGB"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                            <connections>
-                                <action selector="TypeButonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="pQC-pc-EWq"/>
-                            </connections>
-                        </button>
-                        <button opaque="NO" tag="1004" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1Mw-7R-dLz">
-                            <rect key="frame" x="18" y="134" width="89.5" height="27"/>
-                            <color key="backgroundColor" red="0.97254901959999995" green="0.97254901959999995" blue="0.97254901959999995" alpha="1" colorSpace="calibratedRGB"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="27" id="db0-C7-Pdy"/>
-                            </constraints>
-                            <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                            <state key="normal" title="曲谱不一致">
-                                <color key="titleColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
-                            </state>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                    <real key="value" value="6"/>
-                                </userDefinedRuntimeAttribute>
-                                <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
-                                    <real key="value" value="1"/>
-                                </userDefinedRuntimeAttribute>
-                                <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
-                                    <color key="value" red="0.97254901960784312" green="0.97254901960784312" blue="0.97254901960784312" alpha="1" colorSpace="calibratedRGB"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                            <connections>
-                                <action selector="TypeButonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="u1y-qp-4qe"/>
-                            </connections>
-                        </button>
-                        <button opaque="NO" tag="1005" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9DQ-zy-Jq5">
-                            <rect key="frame" x="115.5" y="134" width="89" height="27"/>
-                            <color key="backgroundColor" red="0.97254901959999995" green="0.97254901959999995" blue="0.97254901959999995" alpha="1" colorSpace="calibratedRGB"/>
-                            <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                            <state key="normal" title="指法错误">
-                                <color key="titleColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
-                            </state>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                    <real key="value" value="6"/>
-                                </userDefinedRuntimeAttribute>
-                                <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
-                                    <real key="value" value="1"/>
-                                </userDefinedRuntimeAttribute>
-                                <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
-                                    <color key="value" red="0.97254901960784312" green="0.97254901960784312" blue="0.97254901960784312" alpha="1" colorSpace="calibratedRGB"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                            <connections>
-                                <action selector="TypeButonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="fMv-k4-1rs"/>
-                            </connections>
-                        </button>
-                        <button opaque="NO" tag="1006" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="JzE-X8-lLe">
-                            <rect key="frame" x="212.5" y="134" width="89.5" height="27"/>
-                            <color key="backgroundColor" red="0.97254901959999995" green="0.97254901959999995" blue="0.97254901959999995" alpha="1" colorSpace="calibratedRGB"/>
-                            <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                            <state key="normal" title="其他">
-                                <color key="titleColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
-                            </state>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                    <real key="value" value="6"/>
-                                </userDefinedRuntimeAttribute>
-                                <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
-                                    <real key="value" value="1"/>
-                                </userDefinedRuntimeAttribute>
-                                <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
-                                    <color key="value" red="0.97254901960784312" green="0.97254901960784312" blue="0.97254901960784312" alpha="1" colorSpace="calibratedRGB"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                            <connections>
-                                <action selector="TypeButonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="qB6-4P-wfV"/>
-                            </connections>
-                        </button>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fDw-RL-YZQ">
-                            <rect key="frame" x="20" y="171" width="284" height="71"/>
-                            <subviews>
-                                <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="l1z-4Y-3eT">
-                                    <rect key="frame" x="12" y="10" width="260" height="51"/>
-                                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                                    <color key="textColor" systemColor="labelColor"/>
-                                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
-                                    <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
-                                </textView>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0/200" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9Jw-La-2Hn">
-                                    <rect key="frame" x="244" y="47" width="34" height="15"/>
-                                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                                    <color key="textColor" red="0.80000000000000004" green="0.80000000000000004" blue="0.80000000000000004" alpha="1" colorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="请详细描述您遇到的问题,以便我们尽快为您解决!" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nvM-32-Z6W">
-                                    <rect key="frame" x="9" y="15" width="243" height="29"/>
-                                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                                    <color key="textColor" red="0.50196078431372548" green="0.50196078431372548" blue="0.50196078431372548" alpha="1" colorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                            </subviews>
-                            <color key="backgroundColor" red="0.97254901959999995" green="0.97254901959999995" blue="0.97254901959999995" alpha="1" colorSpace="calibratedRGB"/>
-                            <constraints>
-                                <constraint firstAttribute="trailing" secondItem="l1z-4Y-3eT" secondAttribute="trailing" constant="12" id="DrW-kV-bFE"/>
-                                <constraint firstItem="l1z-4Y-3eT" firstAttribute="top" secondItem="fDw-RL-YZQ" secondAttribute="top" constant="10" id="KKe-Sd-KsV"/>
-                                <constraint firstItem="nvM-32-Z6W" firstAttribute="top" secondItem="fDw-RL-YZQ" secondAttribute="top" constant="15" id="WnD-Kz-gA6"/>
-                                <constraint firstAttribute="bottom" secondItem="9Jw-La-2Hn" secondAttribute="bottom" constant="9" id="Zz7-nb-trk"/>
-                                <constraint firstItem="nvM-32-Z6W" firstAttribute="leading" secondItem="fDw-RL-YZQ" secondAttribute="leading" constant="9" id="aIL-ME-Sir"/>
-                                <constraint firstItem="l1z-4Y-3eT" firstAttribute="leading" secondItem="fDw-RL-YZQ" secondAttribute="leading" constant="12" id="aX5-em-K7L"/>
-                                <constraint firstAttribute="bottom" secondItem="l1z-4Y-3eT" secondAttribute="bottom" constant="10" id="cRb-ik-WSo"/>
-                                <constraint firstAttribute="height" constant="71" id="kLV-hO-8zU"/>
-                                <constraint firstAttribute="trailing" secondItem="nvM-32-Z6W" secondAttribute="trailing" constant="32" id="lNb-ym-wwt"/>
-                                <constraint firstAttribute="trailing" secondItem="9Jw-La-2Hn" secondAttribute="trailing" constant="6" id="y7h-9W-aTe"/>
-                            </constraints>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                    <real key="value" value="6"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                        </view>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="d27-7V-Wg8">
-                            <rect key="frame" x="65" y="274" width="190" height="34"/>
-                            <color key="backgroundColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="calibratedRGB"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="34" id="N3v-Xl-2MW"/>
-                                <constraint firstAttribute="width" constant="190" id="uxK-Vz-uCB"/>
-                            </constraints>
-                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
-                            <state key="normal" title="提交反馈"/>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                    <real key="value" value="17"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                            <connections>
-                                <action selector="sureAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="jAn-FI-sqc"/>
-                            </connections>
-                        </button>
-                    </subviews>
-                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                    <constraints>
-                        <constraint firstItem="9DQ-zy-Jq5" firstAttribute="leading" secondItem="1Mw-7R-dLz" secondAttribute="trailing" constant="8" id="06O-4g-wue"/>
-                        <constraint firstItem="1Mw-7R-dLz" firstAttribute="leading" secondItem="0Jt-Nx-mxp" secondAttribute="leading" constant="18" id="2WH-8E-XvK"/>
-                        <constraint firstItem="J1s-eN-oKW" firstAttribute="width" secondItem="7U7-1u-Czi" secondAttribute="width" id="32b-GC-Ka1"/>
-                        <constraint firstItem="J1s-eN-oKW" firstAttribute="height" secondItem="7U7-1u-Czi" secondAttribute="height" id="3Pw-Ri-nap"/>
-                        <constraint firstItem="7U7-1u-Czi" firstAttribute="top" secondItem="TEQ-Mu-woj" secondAttribute="bottom" constant="8" id="3R2-EC-nqd"/>
-                        <constraint firstItem="JzE-X8-lLe" firstAttribute="centerY" secondItem="1Mw-7R-dLz" secondAttribute="centerY" id="4Il-Nw-NoN"/>
-                        <constraint firstItem="d27-7V-Wg8" firstAttribute="centerX" secondItem="0Jt-Nx-mxp" secondAttribute="centerX" id="5FM-g1-YxC"/>
-                        <constraint firstItem="39T-t6-0Wv" firstAttribute="centerX" secondItem="0Jt-Nx-mxp" secondAttribute="centerX" id="5e2-4O-Fsp"/>
-                        <constraint firstItem="x52-Ag-qNB" firstAttribute="centerY" secondItem="7U7-1u-Czi" secondAttribute="centerY" id="5lJ-KP-9I0"/>
-                        <constraint firstAttribute="height" constant="320" id="76Q-k0-SSd"/>
-                        <constraint firstItem="7U7-1u-Czi" firstAttribute="leading" secondItem="0Jt-Nx-mxp" secondAttribute="leading" constant="18" id="7c9-x7-KoI"/>
-                        <constraint firstAttribute="trailing" secondItem="fDw-RL-YZQ" secondAttribute="trailing" constant="16" id="HP4-kF-sOC"/>
-                        <constraint firstAttribute="width" constant="320" id="LP9-VX-MX3"/>
-                        <constraint firstAttribute="trailing" secondItem="JzE-X8-lLe" secondAttribute="trailing" constant="18" id="Nz2-Yb-Rlm"/>
-                        <constraint firstItem="Gq5-UG-UPH" firstAttribute="top" secondItem="0Jt-Nx-mxp" secondAttribute="top" constant="45" id="UXl-Ug-AeJ"/>
-                        <constraint firstItem="J1s-eN-oKW" firstAttribute="leading" secondItem="7U7-1u-Czi" secondAttribute="trailing" constant="8" id="W0q-B2-4na"/>
-                        <constraint firstItem="JzE-X8-lLe" firstAttribute="width" secondItem="1Mw-7R-dLz" secondAttribute="width" id="WKN-Wm-9Yd"/>
-                        <constraint firstItem="x52-Ag-qNB" firstAttribute="leading" secondItem="J1s-eN-oKW" secondAttribute="trailing" constant="8" id="aBW-dd-CaO"/>
-                        <constraint firstAttribute="trailing" secondItem="Gq5-UG-UPH" secondAttribute="trailing" id="c0O-mK-lEW"/>
-                        <constraint firstItem="fDw-RL-YZQ" firstAttribute="leading" secondItem="0Jt-Nx-mxp" secondAttribute="leading" constant="20" id="d4z-sv-jem"/>
-                        <constraint firstItem="x52-Ag-qNB" firstAttribute="height" secondItem="7U7-1u-Czi" secondAttribute="height" id="ebh-5Z-mfM"/>
-                        <constraint firstItem="JzE-X8-lLe" firstAttribute="height" secondItem="1Mw-7R-dLz" secondAttribute="height" id="fn9-T1-lqv"/>
-                        <constraint firstItem="Gq5-UG-UPH" firstAttribute="leading" secondItem="0Jt-Nx-mxp" secondAttribute="leading" id="iGf-AP-6wJ"/>
-                        <constraint firstItem="9DQ-zy-Jq5" firstAttribute="height" secondItem="1Mw-7R-dLz" secondAttribute="height" id="j2F-03-fR7"/>
-                        <constraint firstItem="fDw-RL-YZQ" firstAttribute="top" secondItem="1Mw-7R-dLz" secondAttribute="bottom" constant="10" id="kke-Er-EGE"/>
-                        <constraint firstItem="TEQ-Mu-woj" firstAttribute="top" secondItem="Gq5-UG-UPH" secondAttribute="bottom" constant="24" id="l9h-eX-tM7"/>
-                        <constraint firstItem="TEQ-Mu-woj" firstAttribute="leading" secondItem="0Jt-Nx-mxp" secondAttribute="leading" constant="18" id="mbH-Py-0kV"/>
-                        <constraint firstAttribute="bottom" secondItem="d27-7V-Wg8" secondAttribute="bottom" constant="12" id="meP-fV-07D"/>
-                        <constraint firstItem="39T-t6-0Wv" firstAttribute="top" secondItem="0Jt-Nx-mxp" secondAttribute="top" constant="12" id="n3K-8r-3La"/>
-                        <constraint firstItem="9DQ-zy-Jq5" firstAttribute="centerY" secondItem="1Mw-7R-dLz" secondAttribute="centerY" id="nLM-s2-wmR"/>
-                        <constraint firstAttribute="trailing" secondItem="x52-Ag-qNB" secondAttribute="trailing" constant="18" id="ni0-Br-dtN"/>
-                        <constraint firstItem="x52-Ag-qNB" firstAttribute="width" secondItem="7U7-1u-Czi" secondAttribute="width" id="oIR-2W-yI8"/>
-                        <constraint firstItem="JzE-X8-lLe" firstAttribute="leading" secondItem="9DQ-zy-Jq5" secondAttribute="trailing" constant="8" id="rUr-IM-rz0"/>
-                        <constraint firstItem="1Mw-7R-dLz" firstAttribute="top" secondItem="7U7-1u-Czi" secondAttribute="bottom" constant="9" id="sf0-GH-t1q"/>
-                        <constraint firstItem="J1s-eN-oKW" firstAttribute="centerY" secondItem="7U7-1u-Czi" secondAttribute="centerY" id="vEG-9g-xuH"/>
-                        <constraint firstItem="9DQ-zy-Jq5" firstAttribute="width" secondItem="1Mw-7R-dLz" secondAttribute="width" id="wD2-ML-f5L"/>
-                    </constraints>
-                    <userDefinedRuntimeAttributes>
-                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                            <real key="value" value="10"/>
-                        </userDefinedRuntimeAttribute>
-                    </userDefinedRuntimeAttributes>
-                </view>
-                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ih1-GM-HgL">
-                    <rect key="frame" x="741" y="75.5" width="44" height="44"/>
-                    <constraints>
-                        <constraint firstAttribute="height" constant="44" id="9oe-3I-cob"/>
-                        <constraint firstAttribute="width" constant="44" id="QQk-YE-bdJ"/>
-                    </constraints>
-                    <state key="normal" image="cloud_cancle"/>
-                </button>
-            </subviews>
-            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.52000000000000002" colorSpace="custom" customColorSpace="sRGB"/>
-            <constraints>
-                <constraint firstItem="0Jt-Nx-mxp" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="9xt-7i-vZa"/>
-                <constraint firstItem="ih1-GM-HgL" firstAttribute="centerY" secondItem="0Jt-Nx-mxp" secondAttribute="top" id="ORp-y4-6jt"/>
-                <constraint firstItem="ih1-GM-HgL" firstAttribute="leading" secondItem="0Jt-Nx-mxp" secondAttribute="trailing" id="Yqg-ks-j0d"/>
-                <constraint firstItem="0Jt-Nx-mxp" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="vRQ-QD-vwY"/>
-            </constraints>
-            <nil key="simulatedTopBarMetrics"/>
-            <nil key="simulatedBottomBarMetrics"/>
-            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
-            <connections>
-                <outlet property="countLabel" destination="9Jw-La-2Hn" id="Pbq-Rz-Khb"/>
-                <outlet property="textView" destination="l1z-4Y-3eT" id="xeT-Xf-3MD"/>
-                <outlet property="tipsLabel" destination="nvM-32-Z6W" id="pKp-zJ-BqV"/>
-            </connections>
-            <point key="canvasLocation" x="-4.3478260869565224" y="-53.90625"/>
-        </view>
-    </objects>
-    <resources>
-        <image name="cloud_cancle" width="26" height="26"/>
-        <systemColor name="labelColor">
-            <color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-        </systemColor>
-        <systemColor name="systemBackgroundColor">
-            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-        </systemColor>
-    </resources>
-</document>

+ 0 - 23
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Help/CloudHelpView.h

@@ -1,23 +0,0 @@
-//
-//  CloudHelpView.h
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/15.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-typedef void(^CloudFeedbackAction)(void);
-
-@interface CloudHelpView : UIView
-
-+ (instancetype)shareInstance;
-
-- (void)feedbackCallback:(CloudFeedbackAction)callback;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 253
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Help/CloudHelpView.m

@@ -1,253 +0,0 @@
-//
-//  CloudHelpView.m
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/15.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import "CloudHelpView.h"
-#import <WebKit/WebKit.h>
-#import <KSToolLibrary/WeakWebViewScriptMessageDelegate.h>
-@interface CloudHelpView ()
-
-@property (weak, nonatomic) IBOutlet UIButton *guideButton;
-@property (weak, nonatomic) IBOutlet UIView *backView;
-
-@property (weak, nonatomic) IBOutlet UIButton *helpButton;
-@property (weak, nonatomic) IBOutlet UIView *lineView;
-@property (weak, nonatomic) IBOutlet UIView *baseView;
-@property (weak, nonatomic) IBOutlet NSLayoutConstraint *lineViewLeft;
-
-@property (nonatomic, strong) UIScrollView *baseScrollView;
-
-@property (nonatomic, strong) WKWebView *guideWebView;
-
-@property (nonatomic, strong) WKWebView *helpWebView;
-
-@property (nonatomic, strong) UIButton *feedbackButton;
-
-@property (nonatomic, strong) CloudFeedbackAction callback;
-
-@end
-
-@implementation CloudHelpView
-
-+ (instancetype)shareInstance {
-    CloudHelpView *view = [[[NSBundle mainBundle] loadNibNamed:@"CloudHelpView" owner:nil options:nil] firstObject];
-    [view configHelpView];
-    return view;
-}
-
-- (void)configHelpView {
-    
-    if (@available(iOS 11.0, *)) {
-        self.backView.layer.cornerRadius = 14;
-        self.backView.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMinXMaxYCorner; // 左上圆角
-    }
-    else {
-        UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:self.backView.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerBottomLeft cornerRadii:CGSizeMake(14, 14)];
-        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
-        maskLayer.frame = self.backView.bounds;
-        maskLayer.path = path.CGPath;
-        self.backView.layer.mask = maskLayer;
-    }
-
-    [self.baseView addSubview:self.baseScrollView];
-    [self.baseScrollView addSubview:self.guideWebView];
-    [self.baseScrollView addSubview:self.helpWebView];
-    [self setUserAgent];
-    [self.baseScrollView addSubview:self.feedbackButton];
-}
-
-
-
-- (void)setUserAgent {
-    
-    MJWeakSelf;
-    [self.guideWebView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id result, NSError *error) {
-        NSString *oldUserAgent = result;
-        NSString *newUserAgent = [NSString stringWithFormat:@"%@ %@",oldUserAgent,@"DAYAAPPI"];
-        weakSelf.guideWebView.customUserAgent = newUserAgent;
-        [weakSelf loadRequestIsGuide:YES];
-    }];
-    [self.helpWebView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id result, NSError *error) {
-        NSString *oldUserAgent = result;
-        NSString *newUserAgent = [NSString stringWithFormat:@"%@ %@",oldUserAgent,@"DAYAAPPI"];
-        weakSelf.helpWebView.customUserAgent = newUserAgent;
-        [weakSelf loadRequestIsGuide:NO];;
-    }];
-}
-
-- (void)loadRequestIsGuide:(BOOL)isGuide {
-    MJWeakSelf;
-    if (isGuide) {
-        [self.guideWebView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
-            NSLog(@"%@",result);
-            NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[weakSelf getUrlIsGuide:YES]] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0f];
-            [weakSelf.guideWebView loadRequest:request];
-        }];
-    }
-    else {
-        [self.helpWebView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
-            NSLog(@"%@",result);
-            NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[weakSelf getUrlIsGuide:NO]] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0f];
-            [weakSelf.helpWebView loadRequest:request];
-        }];
-    }
-}
-
-- (NSString *)getUrlIsGuide:(BOOL)isGuide {
-    NSString *tokenStr = UserDefault(TokenKey);
-    NSString *token = nil;
-    if (![NSString isEmptyString:tokenStr]) {
-        token = [[NSString stringWithFormat:@"Authorization=%@ %@", UserDefault(Token_type), tokenStr] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
-    }
-    if (isGuide) {
-        NSString *url = @"https://mteaonline.dayaedu.com/#/guide";
-        if (![NSString isEmptyString:token]) {
-            url = [NSString stringWithFormat:@"%@?%@",url,token];
-        }
-        return url;
-    }
-    else {
-        NSString *url = @"https://mstuonline.dayaedu.com/#/KeepRepaire?mode=accompany";
-        if (![NSString isEmptyString:token]) {
-            url = [NSString stringWithFormat:@"%@&%@",url,token];
-        }
-        return url;
-    }
-}
-
-
-- (void)feedbackCallback:(CloudFeedbackAction)callback {
-    if (callback) {
-        self.callback = callback;
-    }
-}
-
-- (IBAction)guideAction:(id)sender { // 投屏
-    [self configGuideChoose:YES];
-}
-
-- (IBAction)helpAction:(id)sender { // 帮助
-    [self configGuideChoose:NO];
-}
-
-- (void)configGuideChoose:(BOOL)isChooseSettingButton {
-    CGFloat positionX = 0.0f;
-    NSInteger pageIndex = 0;
-    if (isChooseSettingButton) {
-        [self.guideButton setTitleColor:THEMECOLOR forState:UIControlStateNormal];
-        [self.helpButton setTitleColor:HexRGB(0x1a1a1a) forState:UIControlStateNormal];
-        positionX = 65.0f;
-        pageIndex = 0;
-    }
-    else {
-        [self.guideButton setTitleColor:HexRGB(0x1a1a1a) forState:UIControlStateNormal];
-        [self.helpButton setTitleColor:THEMECOLOR forState:UIControlStateNormal];
-        positionX = 225.0f;
-        pageIndex = 1;
-    }
-    [UIView animateWithDuration:0.5f animations:^{
-        self.lineViewLeft.constant = positionX;
-        [self.baseScrollView setContentOffset:CGPointMake(pageIndex*320, 0)];
-    }];
-}
-
-- (IBAction)hideButtonAction:(id)sender {
-    [self removeFromSuperview];
-}
-
-- (void)feedbackButtonAction {
-    if (self.callback) {
-        self.callback();
-    }
-}
-
-#pragma mark ---- lazying
-- (UIScrollView *)baseScrollView {
-    if (!_baseScrollView) {
-        CGFloat height = KLandscapeHeight - 55;
-        _baseScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, height)];
-        [_baseScrollView setContentSize:CGSizeMake(CGRectGetHeight(self.baseView.frame)*2, height)];
-        _baseScrollView.scrollEnabled = NO;
-    }
-    return _baseScrollView;
-}
-
-- (WKWebView *)guideWebView {
-    if (!_guideWebView) {
-        _guideWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, KLandscapeHeight) configuration:[self getwebConfig]];
-        _guideWebView.scrollView.bounces = NO;
-    }
-    return _guideWebView;
-}
-
-- (WKWebView *)helpWebView {
-    if (!_helpWebView) {
-        _helpWebView = [[WKWebView alloc] initWithFrame:CGRectMake(320, 0, 320, KLandscapeHeight - 55) configuration:[self getwebConfig]];
-        _helpWebView.scrollView.bounces = NO;
-    }
-    return _helpWebView;
-}
-
-- (WKWebViewConfiguration *)getwebConfig {
-    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
-    config.selectionGranularity = WKSelectionGranularityDynamic;
-    config.allowsInlineMediaPlayback = YES;
-    if (@available(iOS 10.0, *)) {
-        config.mediaTypesRequiringUserActionForPlayback = NO;
-    } else {
-        // Fallback on earlier versions
-        config.requiresUserActionForMediaPlayback = NO;
-    }
-    config.processPool = [CloudHelpView singleWkProcessPool];
-    config.websiteDataStore = [WKWebsiteDataStore defaultDataStore];
-    //自定义的WKScriptMessageHandler 是为了解决内存不释放的问题
-    WeakWebViewScriptMessageDelegate *weakScriptMessageDelegate = [[WeakWebViewScriptMessageDelegate alloc] initWithDelegate:self];
-    //这个类主要用来做native与JavaScript的交互管理
-    WKUserContentController * wkUController = [[WKUserContentController alloc] init];
-    [wkUController addScriptMessageHandler:weakScriptMessageDelegate name:@"DAYA"];
-    config.userContentController = wkUController;
-    
-    WKPreferences *preferences = [WKPreferences new];
-    // 是否支出javaScript
-    preferences.javaScriptEnabled = YES;
-    //不通过用户交互,是否可以打开窗口
-    preferences.javaScriptCanOpenWindowsAutomatically = YES;
-    config.preferences = preferences;
-    return config;
-}
-
-- (UIButton *)feedbackButton {
-    if (!_feedbackButton) {
-        _feedbackButton = [UIButton buttonWithType:UIButtonTypeCustom];
-        _feedbackButton.frame = CGRectMake(320, KLandscapeHeight - 55 - 55, 320, 55);
-        [_feedbackButton setTitle:@"意见反馈 >" forState:UIControlStateNormal];
-        [_feedbackButton setTitleColor:THEMECOLOR forState:UIControlStateNormal];
-        [_feedbackButton.titleLabel setFont:[UIFont systemFontOfSize:14.0f]];
-        [_feedbackButton addTarget:self action:@selector(feedbackButtonAction) forControlEvents:UIControlEventTouchUpInside];
-    }
-    return _feedbackButton;
-}
-
-
-+ (WKProcessPool*)singleWkProcessPool {
-    static WKProcessPool *sharedPool;
-    static dispatch_once_t onceToken;
-    dispatch_once(&onceToken, ^{
-        sharedPool = [[WKProcessPool alloc] init];
-    });
-    return sharedPool;
-}
-
-/*
-// Only override drawRect: if you perform custom drawing.
-// An empty implementation adversely affects performance during animation.
-- (void)drawRect:(CGRect)rect {
-    // Drawing code
-}
-*/
-
-@end

+ 0 - 131
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/Help/CloudHelpView.xib

@@ -1,131 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
-    <device id="retina6_1" orientation="portrait" appearance="light"/>
-    <dependencies>
-        <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
-        <capability name="System colors in document resources" minToolsVersion="11.0"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
-        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="CloudHelpView">
-            <rect key="frame" x="0.0" y="0.0" width="664" height="386"/>
-            <autoresizingMask key="autoresizingMask"/>
-            <subviews>
-                <view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="obm-zW-QzQ">
-                    <rect key="frame" x="344" y="0.0" width="320" height="386"/>
-                    <subviews>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Pfo-si-2Hf">
-                            <rect key="frame" x="50" y="0.0" width="60" height="55"/>
-                            <constraints>
-                                <constraint firstAttribute="width" constant="60" id="uvn-eh-hGh"/>
-                            </constraints>
-                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
-                            <state key="normal" title="投屏">
-                                <color key="titleColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            </state>
-                            <connections>
-                                <action selector="guideAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="z9N-4C-3t8"/>
-                            </connections>
-                        </button>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="WNO-Ji-qbp">
-                            <rect key="frame" x="65" y="51" width="30" height="3"/>
-                            <color key="backgroundColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <constraints>
-                                <constraint firstAttribute="width" constant="30" id="JJC-YP-gAm"/>
-                                <constraint firstAttribute="height" constant="3" id="S3K-Kl-hfz"/>
-                            </constraints>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="layer.CornerRadius">
-                                    <real key="value" value="1.5"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                        </view>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uc4-t2-7YM">
-                            <rect key="frame" x="0.0" y="55" width="320" height="1"/>
-                            <color key="backgroundColor" red="0.94117647059999998" green="0.94117647059999998" blue="0.94117647059999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="1" id="k4O-rI-Awa"/>
-                            </constraints>
-                        </view>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="lBO-uK-4OU">
-                            <rect key="frame" x="210" y="0.0" width="60" height="55"/>
-                            <constraints>
-                                <constraint firstAttribute="width" constant="60" id="vu6-VN-5eC"/>
-                            </constraints>
-                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
-                            <state key="normal" title="帮助">
-                                <color key="titleColor" red="0.1019607843" green="0.1019607843" blue="0.1019607843" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            </state>
-                            <connections>
-                                <action selector="helpAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="1JP-jM-sMu"/>
-                            </connections>
-                        </button>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="71I-Qi-kjr">
-                            <rect key="frame" x="0.0" y="56" width="320" height="330"/>
-                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                        </view>
-                    </subviews>
-                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                    <constraints>
-                        <constraint firstAttribute="trailing" secondItem="uc4-t2-7YM" secondAttribute="trailing" id="0dz-Ph-iv1"/>
-                        <constraint firstItem="Pfo-si-2Hf" firstAttribute="top" secondItem="obm-zW-QzQ" secondAttribute="top" id="0so-tT-vKx"/>
-                        <constraint firstItem="uc4-t2-7YM" firstAttribute="leading" secondItem="obm-zW-QzQ" secondAttribute="leading" id="4V8-I7-BUQ"/>
-                        <constraint firstItem="uc4-t2-7YM" firstAttribute="top" secondItem="lBO-uK-4OU" secondAttribute="bottom" id="9GF-0F-mT8"/>
-                        <constraint firstItem="WNO-Ji-qbp" firstAttribute="leading" secondItem="obm-zW-QzQ" secondAttribute="leading" constant="65" id="Cel-5r-oZ9"/>
-                        <constraint firstItem="uc4-t2-7YM" firstAttribute="top" secondItem="WNO-Ji-qbp" secondAttribute="bottom" constant="1" id="Z93-Es-h8v"/>
-                        <constraint firstItem="71I-Qi-kjr" firstAttribute="top" secondItem="uc4-t2-7YM" secondAttribute="bottom" id="a6k-qz-AQp"/>
-                        <constraint firstAttribute="width" constant="320" id="gnO-9b-8yi"/>
-                        <constraint firstItem="lBO-uK-4OU" firstAttribute="centerX" secondItem="obm-zW-QzQ" secondAttribute="centerX" multiplier="1.5" id="ium-a0-a9D"/>
-                        <constraint firstItem="uc4-t2-7YM" firstAttribute="top" secondItem="Pfo-si-2Hf" secondAttribute="bottom" id="ixj-NX-tsw"/>
-                        <constraint firstAttribute="bottom" secondItem="71I-Qi-kjr" secondAttribute="bottom" id="j6y-lQ-MyW"/>
-                        <constraint firstItem="lBO-uK-4OU" firstAttribute="top" secondItem="obm-zW-QzQ" secondAttribute="top" id="odh-RK-gZ6"/>
-                        <constraint firstItem="Pfo-si-2Hf" firstAttribute="centerX" secondItem="obm-zW-QzQ" secondAttribute="centerX" multiplier="0.5" id="ps6-fp-tnP"/>
-                        <constraint firstItem="uc4-t2-7YM" firstAttribute="top" secondItem="obm-zW-QzQ" secondAttribute="top" constant="55" id="q58-oF-BP6"/>
-                        <constraint firstItem="71I-Qi-kjr" firstAttribute="leading" secondItem="obm-zW-QzQ" secondAttribute="leading" id="qjc-20-qyp"/>
-                        <constraint firstAttribute="trailing" secondItem="71I-Qi-kjr" secondAttribute="trailing" id="ruC-NP-2Gb"/>
-                    </constraints>
-                </view>
-                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9oz-N7-A8a">
-                    <rect key="frame" x="314" y="171" width="30" height="44"/>
-                    <constraints>
-                        <constraint firstAttribute="width" constant="30" id="EZT-YP-4uR"/>
-                        <constraint firstAttribute="height" constant="44" id="Pg5-h0-M6s"/>
-                    </constraints>
-                    <state key="normal" image="help_hide"/>
-                    <connections>
-                        <action selector="hideButtonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="srH-JR-kyz"/>
-                    </connections>
-                </button>
-            </subviews>
-            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.52000000000000002" colorSpace="custom" customColorSpace="sRGB"/>
-            <constraints>
-                <constraint firstItem="9oz-N7-A8a" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="9Y1-dp-fZY"/>
-                <constraint firstAttribute="bottom" secondItem="obm-zW-QzQ" secondAttribute="bottom" id="aNJ-Eu-aUX"/>
-                <constraint firstItem="obm-zW-QzQ" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="djf-ox-UZr"/>
-                <constraint firstItem="obm-zW-QzQ" firstAttribute="trailing" secondItem="iN0-l3-epB" secondAttribute="trailing" id="lR7-Xg-NWG"/>
-                <constraint firstItem="obm-zW-QzQ" firstAttribute="leading" secondItem="9oz-N7-A8a" secondAttribute="trailing" id="rqU-Um-xDZ"/>
-            </constraints>
-            <nil key="simulatedTopBarMetrics"/>
-            <nil key="simulatedBottomBarMetrics"/>
-            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
-            <connections>
-                <outlet property="backView" destination="obm-zW-QzQ" id="Xt4-WW-JX9"/>
-                <outlet property="baseView" destination="71I-Qi-kjr" id="CuG-VD-HGS"/>
-                <outlet property="guideButton" destination="Pfo-si-2Hf" id="yEj-8V-jim"/>
-                <outlet property="helpButton" destination="lBO-uK-4OU" id="dQs-Y4-hN3"/>
-                <outlet property="lineView" destination="WNO-Ji-qbp" id="WQ2-d8-T5g"/>
-                <outlet property="lineViewLeft" destination="Cel-5r-oZ9" id="5jX-dg-uBc"/>
-            </connections>
-            <point key="canvasLocation" x="257.97101449275362" y="-97.098214285714278"/>
-        </view>
-    </objects>
-    <resources>
-        <image name="help_hide" width="30" height="44"/>
-        <systemColor name="systemBackgroundColor">
-            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-        </systemColor>
-    </resources>
-</document>

+ 0 - 29
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/JudgePageView.h

@@ -1,29 +0,0 @@
-//
-//  JudgePageView.h
-//  MidiPlayer
-//
-//  Created by Kyle on 2021/12/7.
-//
-
-#import <UIKit/UIKit.h>
-#import "KSCloudSettingView.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface JudgePageView : UIView
-
-@property (nonatomic, assign) NSString *level; //评测难度
-
-@property (nonatomic, assign) BOOL saveVideo;   // 是否保存到相册
-
-@property (nonatomic, assign) BOOL accompanyOn; // 是否开启伴奏
-
-+ (instancetype)shareInstance;
-
-- (void)querySettingConfig;
-
-- (void)judgeSettingCallback:(CloudSettingCallback)callback;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 176
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/JudgePageView.m

@@ -1,176 +0,0 @@
-//
-//  JudgePageView.m
-//  MidiPlayer
-//
-//  Created by Kyle on 2021/12/7.
-//
-
-#import "JudgePageView.h"
-
-@interface JudgePageView ()
-
-@property (weak, nonatomic) IBOutlet UIButton *primerButton;
-
-@property (weak, nonatomic) IBOutlet UIButton *advancedButton;
-
-@property (weak, nonatomic) IBOutlet UIButton *masterButton;
-
-@property (weak, nonatomic) IBOutlet UIButton *saveButton;
-
-@property (weak, nonatomic) IBOutlet UIButton *accompanyButton;
-
-@property (nonatomic, copy) CloudSettingCallback callback;
-
-@property (nonatomic, strong) NSMutableDictionary *configDict;
-
-@end
-
-@implementation JudgePageView
-
-+ (instancetype)shareInstance {
-    JudgePageView *view = [[[NSBundle mainBundle] loadNibNamed:@"JudgePageView" owner:nil options:nil] firstObject];
-    [view querySettingConfig];
-    return view;
-}
-
-- (void)setButtonSelected:(BOOL)isSelected withButton:(UIButton *)button {
-    if (isSelected) {
-        button.backgroundColor = HexRGB(0xe2fff9);
-        button.layer.borderColor = THEMECOLOR.CGColor;
-        [button setTitleColor:THEMECOLOR forState:UIControlStateNormal];
-        [button.titleLabel setFont:[UIFont systemFontOfSize:14.0f weight:UIFontWeightMedium]];
-    }
-    else {
-        button.backgroundColor = HexRGB(0xf8f8f8);
-        button.layer.borderColor = HexRGB(0xf8f8f8).CGColor;
-        [button setTitleColor:HexRGB(0x666666) forState:UIControlStateNormal];
-        [button.titleLabel setFont:[UIFont systemFontOfSize:14.0f weight:UIFontWeightRegular]];
-    }
-}
-
-- (void)defaultSetting {
-    self.primerButton.layer.cornerRadius = 5.0f;
-    self.primerButton.layer.borderWidth = 1.0f;
-    
-    self.advancedButton.layer.cornerRadius = 5.0f;
-    self.advancedButton.layer.borderWidth = 1.0f;
-    
-    self.masterButton.layer.cornerRadius = 5.0f;
-    self.masterButton.layer.borderWidth = 1.0f;
-    
-    [self setButtonSelected:YES withButton:self.primerButton];
-    [self setButtonSelected:NO withButton:self.advancedButton];
-    [self setButtonSelected:NO withButton:self.masterButton];
-    self.level = @"BEGINNER";
-    self.accompanyOn = NO;
-    self.saveVideo = NO;
-}
-
-- (void)querySettingConfig {
-    [self defaultSetting];
-    
-    // 根据储存的配置项显示
-    NSDictionary *config = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"cloudConfig"];
-    
-    self.configDict = [NSMutableDictionary dictionaryWithDictionary:config];
-    self.level = [config ks_stringValueForKey:@"level"];
-    self.accompanyOn = [config ks_boolValueForKey:@"accompanyOn"];
-    self.saveVideo = [config ks_boolValueForKey:@"save"];
-    if ([self.level isEqualToString:@"BEGINNER"]) {
-        
-    }
-    else if ([self.level isEqualToString:@"ADVANCED"]) {
-        [self setButtonSelected:NO withButton:self.primerButton];
-        [self setButtonSelected:YES withButton:self.advancedButton];
-    }
-    else if ([self.level isEqualToString:@"PERFORMER"]) {
-        [self setButtonSelected:NO withButton:self.primerButton];
-        [self setButtonSelected:YES withButton:self.masterButton];
-    }
-    
-}
-
-- (void)synchronizeConfig {
-    [[NSUserDefaults standardUserDefaults] setObject:self.configDict forKey:@"cloudConfig"];
-    [[NSUserDefaults standardUserDefaults] synchronize];
-}
-
-- (void)judgeSettingCallback:(CloudSettingCallback)callback {
-    if (callback) {
-        self.callback = callback;
-    }
-}
-
-- (IBAction)levelButtonAction:(UIButton *)sender {
-    
-    NSInteger buttonIndex = sender.tag;
-    if (buttonIndex == 1001) {
-        self.level = @"BEGINNER";
-        [self setButtonSelected:YES withButton:self.primerButton];
-        [self setButtonSelected:NO withButton:self.advancedButton];
-        [self setButtonSelected:NO withButton:self.masterButton];
-        
-        [self.configDict setValue:@"BEGINNER" forKey:@"level"];
-    }
-    else if (buttonIndex == 1002) {
-        self.level = @"ADVANCED";
-        [self setButtonSelected:NO withButton:self.primerButton];
-        [self setButtonSelected:YES withButton:self.advancedButton];
-        [self setButtonSelected:NO withButton:self.masterButton];
-        [self.configDict setValue:@"ADVANCED" forKey:@"level"];
-    }
-    else {
-        self.level = @"PERFORMER";
-        [self setButtonSelected:NO withButton:self.primerButton];
-        [self setButtonSelected:NO withButton:self.advancedButton];
-        [self setButtonSelected:YES withButton:self.masterButton];
-        [self.configDict setValue:@"PERFORMER" forKey:@"level"];
-    }
-    [self synchronizeConfig];
-    
-    if (self.callback) {
-        self.callback(CLOUDSETTING_TYPE_LEVEL, NO, self.level);
-    }
-}
-
-- (IBAction)saveVideoAction:(UIButton *)sender {
-    self.saveVideo = !self.saveVideo;
-    [self.configDict setValue:@(self.saveVideo) forKey:@"save"];
-    [self synchronizeConfig];
-    if (self.callback) {
-        self.callback(CLOUDSETTING_TYPE_SAVEVIDEO, self.saveVideo, @"");
-    }
-}
-
-- (IBAction)accompanyAction:(id)sender {
-    self.accompanyOn = !self.accompanyOn;
-    [self.configDict setValue:@(self.accompanyOn) forKey:@"accompanyOn"];
-    [self synchronizeConfig];
-    if (self.callback) {
-        self.callback(CLOUDSETTING_TYPE_ACCOMPANY, self.accompanyOn, @"");
-    }
-    
-}
-
-#pragma mark -- setter
-- (void)setAccompanyOn:(BOOL)accompanyOn {
-    _accompanyOn = accompanyOn;
-    NSString *imageName = accompanyOn ? @"switch_on" : @"switch_off";
-    [self.accompanyButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
-}
-
-- (void)setSaveVideo:(BOOL)saveVideo {
-    _saveVideo = saveVideo;
-    NSString *imageName = saveVideo ? @"switch_on" : @"switch_off";
-    [self.saveButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
-}
-
-/*
-// Only override drawRect: if you perform custom drawing.
-// An empty implementation adversely affects performance during animation.
-- (void)drawRect:(CGRect)rect {
-    // Drawing code
-}
-*/
-
-@end

+ 0 - 157
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/JudgePageView.xib

@@ -1,157 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
-    <device id="retina6_1" orientation="portrait" appearance="light"/>
-    <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
-        <capability name="System colors in document resources" minToolsVersion="11.0"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
-        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="JudgePageView">
-            <rect key="frame" x="0.0" y="0.0" width="414" height="357"/>
-            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-            <subviews>
-                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="请选择评测难度" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6tM-MJ-pJi">
-                    <rect key="frame" x="18" y="14" width="100" height="20"/>
-                    <constraints>
-                        <constraint firstAttribute="height" constant="20" id="UhA-MQ-PwR"/>
-                    </constraints>
-                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
-                    <color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                    <nil key="highlightedColor"/>
-                </label>
-                <button opaque="NO" tag="1001" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Mix-L6-JTm">
-                    <rect key="frame" x="18" y="44" width="122.5" height="30"/>
-                    <color key="backgroundColor" red="0.88627450980392153" green="1" blue="0.97647058823529409" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                    <constraints>
-                        <constraint firstAttribute="height" constant="30" id="9PN-D0-3W4"/>
-                    </constraints>
-                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
-                    <state key="normal" title="入门级">
-                        <color key="titleColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                    </state>
-                    <connections>
-                        <action selector="levelButtonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="UAc-wl-i3a"/>
-                    </connections>
-                </button>
-                <button opaque="NO" tag="1002" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1Ba-L1-uR3">
-                    <rect key="frame" x="145.5" y="44" width="123" height="30"/>
-                    <color key="backgroundColor" red="0.97254901960784312" green="0.97254901960784312" blue="0.97254901960784312" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
-                    <state key="normal" title="进阶级">
-                        <color key="titleColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                    </state>
-                    <connections>
-                        <action selector="levelButtonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="R5s-ej-zFk"/>
-                    </connections>
-                </button>
-                <button opaque="NO" tag="1003" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="yaq-mM-z7i">
-                    <rect key="frame" x="273.5" y="44" width="122.5" height="30"/>
-                    <color key="backgroundColor" red="0.97254901960784312" green="0.97254901960784312" blue="0.97254901960784312" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
-                    <state key="normal" title="大师级">
-                        <color key="titleColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                    </state>
-                    <connections>
-                        <action selector="levelButtonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="HIW-wJ-OsT"/>
-                    </connections>
-                </button>
-                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ewd-ee-kt8">
-                    <rect key="frame" x="0.0" y="94" width="414" height="50"/>
-                    <subviews>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="保存到相册" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mBe-Xi-HzQ">
-                            <rect key="frame" x="25" y="16" width="76.5" height="18"/>
-                            <fontDescription key="fontDescription" type="system" pointSize="15"/>
-                            <color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <nil key="highlightedColor"/>
-                        </label>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="v9d-6q-6e7">
-                            <rect key="frame" x="342" y="0.0" width="47" height="50"/>
-                            <state key="normal" image="switch_off"/>
-                            <connections>
-                                <action selector="saveVideoAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="pM0-BB-58b"/>
-                            </connections>
-                        </button>
-                    </subviews>
-                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                    <constraints>
-                        <constraint firstItem="v9d-6q-6e7" firstAttribute="top" secondItem="ewd-ee-kt8" secondAttribute="top" id="7yN-C5-3LK"/>
-                        <constraint firstAttribute="height" constant="50" id="ABJ-aC-X3d"/>
-                        <constraint firstAttribute="trailing" secondItem="v9d-6q-6e7" secondAttribute="trailing" constant="25" id="Lg4-nm-UEh"/>
-                        <constraint firstItem="mBe-Xi-HzQ" firstAttribute="leading" secondItem="ewd-ee-kt8" secondAttribute="leading" constant="25" id="q3b-dc-YC5"/>
-                        <constraint firstItem="mBe-Xi-HzQ" firstAttribute="centerY" secondItem="ewd-ee-kt8" secondAttribute="centerY" id="xiw-AK-3l4"/>
-                        <constraint firstAttribute="bottom" secondItem="v9d-6q-6e7" secondAttribute="bottom" id="yCX-Tw-oXC"/>
-                    </constraints>
-                </view>
-                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wT6-4G-RF6">
-                    <rect key="frame" x="0.0" y="144" width="414" height="50"/>
-                    <subviews>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="开启伴奏" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EGX-eA-JmP">
-                            <rect key="frame" x="25" y="16" width="61.5" height="18"/>
-                            <fontDescription key="fontDescription" type="system" pointSize="15"/>
-                            <color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <nil key="highlightedColor"/>
-                        </label>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="TiY-1T-4xp">
-                            <rect key="frame" x="342" y="0.0" width="47" height="50"/>
-                            <state key="normal" image="switch_off"/>
-                            <connections>
-                                <action selector="accompanyAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="oDS-hQ-fsL"/>
-                            </connections>
-                        </button>
-                    </subviews>
-                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                    <constraints>
-                        <constraint firstAttribute="height" constant="50" id="HxP-dR-8c0"/>
-                        <constraint firstItem="EGX-eA-JmP" firstAttribute="centerY" secondItem="wT6-4G-RF6" secondAttribute="centerY" id="NEJ-PG-EAZ"/>
-                        <constraint firstItem="TiY-1T-4xp" firstAttribute="top" secondItem="wT6-4G-RF6" secondAttribute="top" id="Vuy-vz-yRz"/>
-                        <constraint firstItem="EGX-eA-JmP" firstAttribute="leading" secondItem="wT6-4G-RF6" secondAttribute="leading" constant="25" id="WqS-4b-dJf"/>
-                        <constraint firstAttribute="bottom" secondItem="TiY-1T-4xp" secondAttribute="bottom" id="nHp-fe-9n3"/>
-                        <constraint firstAttribute="trailing" secondItem="TiY-1T-4xp" secondAttribute="trailing" constant="25" id="vUS-JS-DBi"/>
-                    </constraints>
-                </view>
-            </subviews>
-            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-            <constraints>
-                <constraint firstItem="yaq-mM-z7i" firstAttribute="width" secondItem="Mix-L6-JTm" secondAttribute="width" id="6bo-sh-Nwi"/>
-                <constraint firstItem="wT6-4G-RF6" firstAttribute="trailing" secondItem="ewd-ee-kt8" secondAttribute="trailing" id="7o6-A3-2si"/>
-                <constraint firstItem="1Ba-L1-uR3" firstAttribute="height" secondItem="Mix-L6-JTm" secondAttribute="height" id="DLz-1P-vYA"/>
-                <constraint firstItem="6tM-MJ-pJi" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="14" id="GNi-xR-SgQ"/>
-                <constraint firstItem="6tM-MJ-pJi" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="18" id="JmM-tg-2JP"/>
-                <constraint firstItem="ewd-ee-kt8" firstAttribute="top" secondItem="Mix-L6-JTm" secondAttribute="bottom" constant="20" id="Ky4-rH-ieE"/>
-                <constraint firstItem="Mix-L6-JTm" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="18" id="N1w-be-fcb"/>
-                <constraint firstAttribute="trailing" secondItem="yaq-mM-z7i" secondAttribute="trailing" constant="18" id="Qni-vs-IQ5"/>
-                <constraint firstItem="yaq-mM-z7i" firstAttribute="centerY" secondItem="Mix-L6-JTm" secondAttribute="centerY" id="RHc-4i-LCz"/>
-                <constraint firstItem="ewd-ee-kt8" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="T2Z-Rf-LUn"/>
-                <constraint firstItem="1Ba-L1-uR3" firstAttribute="width" secondItem="Mix-L6-JTm" secondAttribute="width" id="VOu-dl-xiJ"/>
-                <constraint firstItem="Mix-L6-JTm" firstAttribute="top" secondItem="6tM-MJ-pJi" secondAttribute="bottom" constant="10" id="Xei-zn-Itl"/>
-                <constraint firstItem="yaq-mM-z7i" firstAttribute="leading" secondItem="1Ba-L1-uR3" secondAttribute="trailing" constant="5" id="YYC-2y-ScH"/>
-                <constraint firstItem="wT6-4G-RF6" firstAttribute="leading" secondItem="ewd-ee-kt8" secondAttribute="leading" id="cAn-uv-UNL"/>
-                <constraint firstAttribute="trailing" secondItem="ewd-ee-kt8" secondAttribute="trailing" id="fYt-iT-CUo"/>
-                <constraint firstItem="1Ba-L1-uR3" firstAttribute="centerY" secondItem="Mix-L6-JTm" secondAttribute="centerY" id="hx4-zc-P3c"/>
-                <constraint firstItem="1Ba-L1-uR3" firstAttribute="leading" secondItem="Mix-L6-JTm" secondAttribute="trailing" constant="5" id="udr-3Q-VlX"/>
-                <constraint firstItem="wT6-4G-RF6" firstAttribute="top" secondItem="ewd-ee-kt8" secondAttribute="bottom" id="xWz-Qo-3Pw"/>
-                <constraint firstItem="yaq-mM-z7i" firstAttribute="height" secondItem="Mix-L6-JTm" secondAttribute="height" id="ynh-O9-NS9"/>
-            </constraints>
-            <nil key="simulatedTopBarMetrics"/>
-            <nil key="simulatedBottomBarMetrics"/>
-            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
-            <connections>
-                <outlet property="accompanyButton" destination="TiY-1T-4xp" id="UXU-9m-y1O"/>
-                <outlet property="advancedButton" destination="1Ba-L1-uR3" id="mli-9q-Z1z"/>
-                <outlet property="masterButton" destination="yaq-mM-z7i" id="boo-lD-3gf"/>
-                <outlet property="primerButton" destination="Mix-L6-JTm" id="aCK-L5-fDs"/>
-                <outlet property="saveButton" destination="v9d-6q-6e7" id="mnk-y8-eQ9"/>
-            </connections>
-            <point key="canvasLocation" x="76.811594202898561" y="-12.388392857142856"/>
-        </view>
-    </objects>
-    <resources>
-        <image name="switch_off" width="47" height="24"/>
-        <systemColor name="systemBackgroundColor">
-            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-        </systemColor>
-    </resources>
-</document>

+ 0 - 36
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/KSCloudSettingView.h

@@ -1,36 +0,0 @@
-//
-//  KSCloudSettingView.h
-//  MidiPlayer
-//
-//  Created by Kyle on 2021/12/7.
-//
-
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-typedef NS_ENUM(NSInteger, CLOUDSETTING_TYPE) {
-    CLOUDSETTING_TYPE_EYESHIELD,    // 护眼模式
-    CLOUDSETTING_TYPE_SOUNDCHECK,   // 校音
-    CLOUDSETTING_TYPE_CAMERA,       // 摄像头
-    CLOUDSETTING_TYPE_REPEAT,       // 循环播放
-    CLOUDSETTING_TYPE_FINGER,       // 显示指法
-    CLOUDSETTING_TYPE_LEVEL,        // 评测级别
-    CLOUDSETTING_TYPE_SAVEVIDEO,    // 保存视频
-    CLOUDSETTING_TYPE_ACCOMPANY,    // 伴奏
-};
-
-
-typedef void(^CloudSettingCallback)(CLOUDSETTING_TYPE type, BOOL isOn, NSString *level);
-
-/// 云教练设置页面
-@interface KSCloudSettingView : UIView
-
-+ (instancetype)shareInstance;
-
-
-- (void)settingCallback:(CloudSettingCallback)callback;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 139
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/KSCloudSettingView.m

@@ -1,139 +0,0 @@
-//
-//  KSCloudSettingView.m
-//  MidiPlayer
-//
-//  Created by Kyle on 2021/12/7.
-//
-
-#import "KSCloudSettingView.h"
-#import "SettingPageView.h"
-#import "JudgePageView.h"
-
-@interface KSCloudSettingView ()
-
-@property (nonatomic, copy) CloudSettingCallback callback;
-
-@property (weak, nonatomic) IBOutlet UIButton *settingButton;
-
-@property (weak, nonatomic) IBOutlet UIButton *judgeButton;
-
-@property (weak, nonatomic) IBOutlet UIView *lineView;
-
-@property (weak, nonatomic) IBOutlet UIView *baseView;
-
-@property (weak, nonatomic) IBOutlet NSLayoutConstraint *lineViewLeft;
-
-@property (nonatomic, strong) UIScrollView *baseScrollView;
-
-@property (nonatomic, strong) SettingPageView *settingView;
-
-@property (nonatomic, strong) JudgePageView *judgeView;
-
-@end
-
-
-@implementation KSCloudSettingView
-
-+ (instancetype)shareInstance {
-    KSCloudSettingView *view = [[[NSBundle mainBundle] loadNibNamed:@"KSCloudSettingView" owner:nil options:nil] firstObject];
-    [view configSettingView];
-    return view;
-}
-
-- (void)settingCallback:(CloudSettingCallback)callback {
-    if (callback) {
-        self.callback = callback;
-    }
-}
-
-- (void)configSettingView {
-    
-    
-    [self.baseView addSubview:self.baseScrollView];
-    [self.baseScrollView addSubview:self.settingView];
-    [self.baseScrollView addSubview:self.judgeView];
-    
-}
-
-- (IBAction)settingAction:(id)sender { // 设置
-    [self configSettingChoose:YES];
-}
-
-- (IBAction)judgeAction:(id)sender { // 评测
-    [self configSettingChoose:NO];
-}
-
-- (IBAction)cancleAction:(id)sender {
-    [self removeFromSuperview];
-}
-
-- (void)configSettingChoose:(BOOL)isChooseSettingButton {
-    CGFloat positionX = 0.0f;
-    NSInteger pageIndex = 0;
-    if (isChooseSettingButton) {
-        [self.settingButton setTitleColor:THEMECOLOR forState:UIControlStateNormal];
-        [self.judgeButton setTitleColor:HexRGB(0x1a1a1a) forState:UIControlStateNormal];
-        positionX = 65.0f;
-        pageIndex = 0;
-    }
-    else {
-        [self.settingButton setTitleColor:HexRGB(0x1a1a1a) forState:UIControlStateNormal];
-        [self.judgeButton setTitleColor:THEMECOLOR forState:UIControlStateNormal];
-        positionX = 225.0f;
-        pageIndex = 1;
-    }
-    [UIView animateWithDuration:0.5f animations:^{
-        self.lineViewLeft.constant = positionX;
-        [self.baseScrollView setContentOffset:CGPointMake(pageIndex*320, 0)];
-    }];
-}
-
-#pragma mark ---- lazying
-- (UIScrollView *)baseScrollView {
-    if (!_baseScrollView) {
-        CGFloat height = CGRectGetHeight(self.frame) - 33*2 - 55;
-        _baseScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, height)];
-        [_baseScrollView setContentSize:CGSizeMake(320*2, height)];
-        _baseScrollView.scrollEnabled = NO;
-    }
-    return _baseScrollView;
-}
-
-- (SettingPageView *)settingView {
-    if (!_settingView) {
-        CGFloat height = CGRectGetHeight(self.frame) - 33*2 - 55;
-        _settingView = [SettingPageView shareInstance];
-        _settingView.frame = CGRectMake(0, 0, 320, height);
-        __weak typeof(self) weakSelf = self;
-        [_settingView settingCallback:^(CLOUDSETTING_TYPE type, BOOL isOn) {
-            if (weakSelf.callback) {
-                weakSelf.callback(type, isOn, @"");
-            }
-        }];
-    }
-    return _settingView;
-}
-
-- (JudgePageView *)judgeView {
-    if (!_judgeView) {
-        CGFloat height = CGRectGetHeight(self.frame) - 33*2 - 55;
-        _judgeView = [JudgePageView shareInstance];
-        _judgeView.frame = CGRectMake(320, 0, 320, height);
-        __weak typeof(self) weakSelf = self;
-        [_judgeView judgeSettingCallback:^(CLOUDSETTING_TYPE type, BOOL isOn, NSString * _Nonnull level) {
-            if (weakSelf.callback) {
-                weakSelf.callback(type, isOn, level);
-            }
-        }];
-    }
-    return _judgeView;
-}
-/*
-// Only override drawRect: if you perform custom drawing.
-// An empty implementation adversely affects performance during animation.
-- (void)drawRect:(CGRect)rect {
-    // Drawing code
-}
-*/
-
-@end

+ 0 - 135
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/KSCloudSettingView.xib

@@ -1,135 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
-    <device id="retina6_1" orientation="portrait" appearance="light"/>
-    <dependencies>
-        <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
-        <capability name="System colors in document resources" minToolsVersion="11.0"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
-        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="KSCloudSettingView">
-            <rect key="frame" x="0.0" y="0.0" width="765" height="340"/>
-            <autoresizingMask key="autoresizingMask"/>
-            <subviews>
-                <view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="hfV-D9-4RA">
-                    <rect key="frame" x="222.5" y="33" width="320" height="274"/>
-                    <subviews>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZaF-YM-MHQ">
-                            <rect key="frame" x="0.0" y="54" width="320" height="1"/>
-                            <color key="backgroundColor" red="0.94117647058823528" green="0.94117647058823528" blue="0.94117647058823528" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="1" id="JMv-iI-n4b"/>
-                            </constraints>
-                        </view>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="p8P-5R-8Rj">
-                            <rect key="frame" x="50" y="0.0" width="60" height="54"/>
-                            <constraints>
-                                <constraint firstAttribute="width" constant="60" id="OK4-wC-P1G"/>
-                            </constraints>
-                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
-                            <state key="normal" title="设置">
-                                <color key="titleColor" red="0.0039215686274509803" green="0.75686274509803919" blue="0.70980392156862748" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            </state>
-                            <connections>
-                                <action selector="settingAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="ef8-rX-DbF"/>
-                            </connections>
-                        </button>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="a7T-m6-cO3">
-                            <rect key="frame" x="210" y="0.0" width="60" height="54"/>
-                            <constraints>
-                                <constraint firstAttribute="width" constant="60" id="HYZ-j2-02K"/>
-                            </constraints>
-                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
-                            <state key="normal" title="评测">
-                                <color key="titleColor" red="0.10196078431372549" green="0.10196078431372549" blue="0.10196078431372549" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            </state>
-                            <connections>
-                                <action selector="judgeAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="yT1-jF-wEg"/>
-                            </connections>
-                        </button>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="C3c-hV-10p">
-                            <rect key="frame" x="65" y="50" width="30" height="3"/>
-                            <color key="backgroundColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <constraints>
-                                <constraint firstAttribute="width" constant="30" id="mPD-5O-93G"/>
-                                <constraint firstAttribute="height" constant="3" id="vgm-Wv-AR0"/>
-                            </constraints>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="layer.CornerRadius">
-                                    <real key="value" value="1.5"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                        </view>
-                        <view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pPQ-tv-M04">
-                            <rect key="frame" x="0.0" y="55" width="320" height="219"/>
-                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                        </view>
-                    </subviews>
-                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                    <constraints>
-                        <constraint firstAttribute="trailing" secondItem="ZaF-YM-MHQ" secondAttribute="trailing" id="0hN-uw-S9A"/>
-                        <constraint firstItem="ZaF-YM-MHQ" firstAttribute="top" secondItem="C3c-hV-10p" secondAttribute="bottom" constant="1" id="6n2-Bw-93p"/>
-                        <constraint firstItem="p8P-5R-8Rj" firstAttribute="centerX" secondItem="hfV-D9-4RA" secondAttribute="centerX" multiplier="0.5" id="AgX-v4-FXk"/>
-                        <constraint firstAttribute="bottom" secondItem="pPQ-tv-M04" secondAttribute="bottom" id="FdO-jV-SRW"/>
-                        <constraint firstItem="ZaF-YM-MHQ" firstAttribute="top" secondItem="a7T-m6-cO3" secondAttribute="bottom" id="LJK-pe-9BW"/>
-                        <constraint firstItem="pPQ-tv-M04" firstAttribute="leading" secondItem="hfV-D9-4RA" secondAttribute="leading" id="NMN-jt-5Dc"/>
-                        <constraint firstItem="ZaF-YM-MHQ" firstAttribute="top" secondItem="p8P-5R-8Rj" secondAttribute="bottom" id="OcI-9y-j24"/>
-                        <constraint firstItem="ZaF-YM-MHQ" firstAttribute="leading" secondItem="hfV-D9-4RA" secondAttribute="leading" id="RJY-gk-vSg"/>
-                        <constraint firstAttribute="trailing" secondItem="pPQ-tv-M04" secondAttribute="trailing" id="TVZ-d9-Jaw"/>
-                        <constraint firstItem="a7T-m6-cO3" firstAttribute="centerX" secondItem="hfV-D9-4RA" secondAttribute="centerX" multiplier="1.5" id="aBp-ee-0ie"/>
-                        <constraint firstAttribute="width" constant="320" id="apj-m7-hnD"/>
-                        <constraint firstItem="pPQ-tv-M04" firstAttribute="top" secondItem="ZaF-YM-MHQ" secondAttribute="bottom" id="npH-Ce-Fgh"/>
-                        <constraint firstItem="ZaF-YM-MHQ" firstAttribute="top" secondItem="hfV-D9-4RA" secondAttribute="top" constant="54" id="uxK-qx-D55"/>
-                        <constraint firstItem="C3c-hV-10p" firstAttribute="leading" secondItem="hfV-D9-4RA" secondAttribute="leading" constant="65" id="vrQ-K4-VVb"/>
-                        <constraint firstItem="p8P-5R-8Rj" firstAttribute="top" secondItem="hfV-D9-4RA" secondAttribute="top" id="yTP-om-2bY"/>
-                        <constraint firstItem="a7T-m6-cO3" firstAttribute="top" secondItem="hfV-D9-4RA" secondAttribute="top" id="zNK-WD-UU4"/>
-                    </constraints>
-                    <userDefinedRuntimeAttributes>
-                        <userDefinedRuntimeAttribute type="number" keyPath="layer.CornerRadius">
-                            <integer key="value" value="10"/>
-                        </userDefinedRuntimeAttribute>
-                    </userDefinedRuntimeAttributes>
-                </view>
-                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="q0f-Z3-hFt">
-                    <rect key="frame" x="542.5" y="11" width="44" height="44"/>
-                    <constraints>
-                        <constraint firstAttribute="height" constant="44" id="Gty-rQ-CAi"/>
-                        <constraint firstAttribute="width" constant="44" id="tQd-jw-Mrl"/>
-                    </constraints>
-                    <state key="normal" image="cloud_cancle"/>
-                    <connections>
-                        <action selector="cancleAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="MHR-ak-SfF"/>
-                    </connections>
-                </button>
-            </subviews>
-            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.52000000000000002" colorSpace="custom" customColorSpace="sRGB"/>
-            <constraints>
-                <constraint firstItem="hfV-D9-4RA" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="33" id="5jd-PQ-73w"/>
-                <constraint firstItem="q0f-Z3-hFt" firstAttribute="leading" secondItem="hfV-D9-4RA" secondAttribute="trailing" id="6p1-95-Who"/>
-                <constraint firstItem="q0f-Z3-hFt" firstAttribute="centerY" secondItem="hfV-D9-4RA" secondAttribute="top" id="AdV-NL-x1c"/>
-                <constraint firstItem="hfV-D9-4RA" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="Tyq-ZP-0uJ"/>
-                <constraint firstItem="hfV-D9-4RA" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="biw-7T-hGm"/>
-                <constraint firstAttribute="bottom" secondItem="hfV-D9-4RA" secondAttribute="bottom" constant="33" id="pMc-ew-3II"/>
-            </constraints>
-            <nil key="simulatedBottomBarMetrics"/>
-            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
-            <connections>
-                <outlet property="baseView" destination="pPQ-tv-M04" id="g36-p2-WKr"/>
-                <outlet property="judgeButton" destination="a7T-m6-cO3" id="iNa-m8-fej"/>
-                <outlet property="lineView" destination="C3c-hV-10p" id="feE-N6-23a"/>
-                <outlet property="lineViewLeft" destination="vrQ-K4-VVb" id="6zN-xC-hNi"/>
-                <outlet property="settingButton" destination="p8P-5R-8Rj" id="TAu-gf-cnz"/>
-            </connections>
-            <point key="canvasLocation" x="542.75362318840587" y="-44.866071428571423"/>
-        </view>
-    </objects>
-    <resources>
-        <image name="cloud_cancle" width="26" height="26"/>
-        <systemColor name="systemBackgroundColor">
-            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-        </systemColor>
-    </resources>
-</document>

+ 0 - 36
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/SettingPageView.h

@@ -1,36 +0,0 @@
-//
-//  SettingPageView.h
-//  MidiPlayer
-//
-//  Created by Kyle on 2021/12/7.
-//
-
-#import <UIKit/UIKit.h>
-#import "KSCloudSettingView.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-typedef void(^SettingCallback)(CLOUDSETTING_TYPE type, BOOL isOn);
-
-@interface SettingPageView : UIView
-
-@property (nonatomic, assign) BOOL eyeProtect;   // 护眼模式
-
-@property (nonatomic, assign) BOOL soundCheck;   // 校音提醒
-
-@property (nonatomic, assign) BOOL cameraOn;     // 摄像头开关
-
-@property (nonatomic, assign) BOOL repeatOn;     // 循环播放
-
-@property (nonatomic, assign) BOOL showFinger;   // 显示指法
-
-
-+ (instancetype)shareInstance;
-
-- (void)querySettingConfig;
-
-- (void)settingCallback:(SettingCallback)callback;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 155
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/SettingPageView.m

@@ -1,155 +0,0 @@
-//
-//  SettingPageView.m
-//  MidiPlayer
-//
-//  Created by Kyle on 2021/12/7.
-//
-
-#import "SettingPageView.h"
-
-@interface SettingPageView ()
-
-@property (weak, nonatomic) IBOutlet UIButton *eyeButton;
-
-@property (weak, nonatomic) IBOutlet UIButton *judgeButton;
-
-@property (weak, nonatomic) IBOutlet UIButton *cameraButton;
-
-@property (weak, nonatomic) IBOutlet UIButton *repeatButton;
-
-@property (weak, nonatomic) IBOutlet UIButton *fingerButton;
-
-@property (nonatomic, copy) SettingCallback callback;
-
-@property (nonatomic, strong) NSMutableDictionary *configDict;
-
-@end
-
-@implementation SettingPageView
-
-+ (instancetype)shareInstance {
-    SettingPageView *view = [[[NSBundle mainBundle] loadNibNamed:@"SettingPageView" owner:nil options:nil] firstObject];
-    [view querySettingConfig];
-    return view;
-}
-- (void)defaultSetting {
-    self.eyeProtect = NO;
-    self.soundCheck = YES;
-    self.cameraOn = NO;
-    self.repeatOn = YES;
-    self.showFinger = YES;
-}
-
-- (void)querySettingConfig {
-    [self defaultSetting];
-    // 根据储存的配置项显示
-    NSDictionary *config = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"cloudConfig"];
-    self.configDict = [NSMutableDictionary dictionaryWithDictionary:config];
-    
-    self.eyeProtect = [[config valueForKey:@"eyeshield"] boolValue];
-    self.soundCheck = [[config valueForKey:@"soundCheck"] boolValue];
-    self.cameraOn = [[config valueForKey:@"cameraOn"] boolValue];
-    self.repeatOn = [[config valueForKey:@"repeatOn"] boolValue];
-    self.showFinger = [[config valueForKey:@"showFinger"] boolValue];
-    
-}
-
-- (void)synchronizeConfig {
-    [[NSUserDefaults standardUserDefaults] setObject:self.configDict forKey:@"cloudConfig"];
-    [[NSUserDefaults standardUserDefaults] synchronize];
-}
-
-- (void)settingCallback:(SettingCallback)callback {
-    if (callback) {
-        self.callback = callback;
-    }
-}
-#pragma mark ---- button action
-// 护眼模式
-- (IBAction)settingAction:(id)sender {
-    self.eyeProtect = !self.eyeProtect;
-    [self.configDict setValue:@(self.eyeProtect) forKey:@"eyeshield"];
-    [self synchronizeConfig];
-    if (self.callback) {
-        self.callback(CLOUDSETTING_TYPE_EYESHIELD, self.eyeProtect);
-    }
-}
-
-- (IBAction)judgeAction:(id)sender {
-    self.soundCheck = !self.soundCheck;
-    [self.configDict setValue:@(self.soundCheck) forKey:@"soundCheck"];
-    [self synchronizeConfig];
-    if (self.callback) {
-        self.callback(CLOUDSETTING_TYPE_SOUNDCHECK, self.soundCheck);
-    }
-}
-
-- (IBAction)cameraAction:(id)sender {
-    self.cameraOn = !self.cameraOn;
-    [self.configDict setValue:@(self.cameraOn) forKey:@"cameraOn"];
-    [self synchronizeConfig];
-    if (self.callback) {
-        self.callback(CLOUDSETTING_TYPE_CAMERA, self.cameraOn);
-    }
-}
-
-- (IBAction)repeatAction:(id)sender {
-    self.repeatOn = !self.repeatOn;
-    [self.configDict setValue:@(self.repeatOn) forKey:@"repeatOn"];
-    [self synchronizeConfig];
-    if (self.callback) {
-        self.callback(CLOUDSETTING_TYPE_REPEAT, self.repeatOn);
-    }
-}
-- (IBAction)showFingerAction:(id)sender {
-    self.showFinger = !self.showFinger;
-    [self.configDict setValue:@(self.showFinger) forKey:@"showFinger"];
-    [self synchronizeConfig];
-    if (self.callback) {
-        self.callback(CLOUDSETTING_TYPE_FINGER, self.showFinger);
-    }
-}
-
-#pragma mark ----  setter
-- (void)setEyeProtect:(BOOL)eyeProtect {
-    _eyeProtect = eyeProtect;
-    NSString *imageName = eyeProtect ? @"switch_on" : @"switch_off";
-    [self.eyeButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
-    
-}
-
-- (void)setSoundCheck:(BOOL)soundCheck {
-    _soundCheck = soundCheck;
-    NSString *imageName = soundCheck ? @"switch_on" : @"switch_off";
-    [self.judgeButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
-}
-
-- (void)setCameraOn:(BOOL)cameraOn {
-    _cameraOn = cameraOn;
-    NSString *imageName = cameraOn ? @"switch_on" : @"switch_off";
-    [self.cameraButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
-    
-}
-
-- (void)setRepeatOn:(BOOL)repeatOn {
-    _repeatOn = repeatOn;
-    NSString *imageName = repeatOn ? @"switch_on" : @"switch_off";
-    [self.repeatButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
-    
-}
-- (void)setShowFinger:(BOOL)showFinger {
-    _showFinger = showFinger;
-    NSString *imageName = showFinger ? @"switch_on" : @"switch_off";
-    [self.fingerButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
-    
-}
-/*
-// Only override drawRect: if you perform custom drawing.
-// An empty implementation adversely affects performance during animation.
-- (void)drawRect:(CGRect)rect {
-    // Drawing code
-}
-*/
-
-
-@end

+ 0 - 190
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SettingView/SettingPageView.xib

@@ -1,190 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
-    <device id="retina6_1" orientation="portrait" appearance="light"/>
-    <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
-        <capability name="System colors in document resources" minToolsVersion="11.0"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
-        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="SettingPageView">
-            <rect key="frame" x="0.0" y="0.0" width="414" height="339"/>
-            <autoresizingMask key="autoresizingMask"/>
-            <subviews>
-                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="TPz-Lt-ID7">
-                    <rect key="frame" x="0.0" y="0.0" width="414" height="68"/>
-                    <subviews>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="护眼模式" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hjM-RO-Jsw">
-                            <rect key="frame" x="25" y="25" width="62" height="18"/>
-                            <fontDescription key="fontDescription" type="system" pointSize="15"/>
-                            <color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <nil key="highlightedColor"/>
-                        </label>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="md8-79-tRj">
-                            <rect key="frame" x="342" y="0.0" width="47" height="68"/>
-                            <state key="normal" image="switch_off"/>
-                            <connections>
-                                <action selector="settingAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="DLH-pG-G3y"/>
-                            </connections>
-                        </button>
-                    </subviews>
-                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                    <constraints>
-                        <constraint firstAttribute="bottom" secondItem="md8-79-tRj" secondAttribute="bottom" id="atg-yD-lBK"/>
-                        <constraint firstItem="hjM-RO-Jsw" firstAttribute="leading" secondItem="TPz-Lt-ID7" secondAttribute="leading" constant="25" id="cTH-K0-35d"/>
-                        <constraint firstAttribute="trailing" secondItem="md8-79-tRj" secondAttribute="trailing" constant="25" id="jNX-dW-Dfb"/>
-                        <constraint firstItem="hjM-RO-Jsw" firstAttribute="centerY" secondItem="TPz-Lt-ID7" secondAttribute="centerY" id="nAZ-Pi-kF0"/>
-                        <constraint firstItem="md8-79-tRj" firstAttribute="top" secondItem="TPz-Lt-ID7" secondAttribute="top" id="r0k-ZD-CFS"/>
-                    </constraints>
-                </view>
-                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wq8-rv-zdW">
-                    <rect key="frame" x="0.0" y="68" width="414" height="67.5"/>
-                    <subviews>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="校音提醒" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XQy-R8-0mY">
-                            <rect key="frame" x="25" y="24.5" width="62" height="18"/>
-                            <fontDescription key="fontDescription" type="system" pointSize="15"/>
-                            <color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <nil key="highlightedColor"/>
-                        </label>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3ZL-a9-mCu">
-                            <rect key="frame" x="342" y="0.0" width="47" height="67.5"/>
-                            <state key="normal" image="switch_off"/>
-                            <connections>
-                                <action selector="judgeAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="ZHW-it-NZn"/>
-                            </connections>
-                        </button>
-                    </subviews>
-                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                    <constraints>
-                        <constraint firstItem="3ZL-a9-mCu" firstAttribute="top" secondItem="wq8-rv-zdW" secondAttribute="top" id="1q5-mT-g66"/>
-                        <constraint firstAttribute="trailing" secondItem="3ZL-a9-mCu" secondAttribute="trailing" constant="25" id="Nbd-3b-VGJ"/>
-                        <constraint firstAttribute="bottom" secondItem="3ZL-a9-mCu" secondAttribute="bottom" id="YOl-mQ-kEz"/>
-                        <constraint firstItem="XQy-R8-0mY" firstAttribute="centerY" secondItem="wq8-rv-zdW" secondAttribute="centerY" id="aIc-ve-n5V"/>
-                        <constraint firstItem="XQy-R8-0mY" firstAttribute="leading" secondItem="wq8-rv-zdW" secondAttribute="leading" constant="25" id="zVu-mo-rhz"/>
-                    </constraints>
-                </view>
-                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="z67-Ah-wa8">
-                    <rect key="frame" x="0.0" y="135.5" width="414" height="68"/>
-                    <subviews>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="摄像头" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HW4-ck-jy7">
-                            <rect key="frame" x="25" y="25" width="46" height="18"/>
-                            <fontDescription key="fontDescription" type="system" pointSize="15"/>
-                            <color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <nil key="highlightedColor"/>
-                        </label>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7rE-UU-UnI">
-                            <rect key="frame" x="342" y="0.0" width="47" height="68"/>
-                            <state key="normal" image="switch_off"/>
-                            <connections>
-                                <action selector="cameraAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="lHw-xs-DUp"/>
-                            </connections>
-                        </button>
-                    </subviews>
-                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                    <constraints>
-                        <constraint firstAttribute="trailing" secondItem="7rE-UU-UnI" secondAttribute="trailing" constant="25" id="1Y2-MB-VhC"/>
-                        <constraint firstItem="HW4-ck-jy7" firstAttribute="leading" secondItem="z67-Ah-wa8" secondAttribute="leading" constant="25" id="3Cb-e9-Nij"/>
-                        <constraint firstAttribute="bottom" secondItem="7rE-UU-UnI" secondAttribute="bottom" id="9i1-IH-YVS"/>
-                        <constraint firstItem="7rE-UU-UnI" firstAttribute="top" secondItem="z67-Ah-wa8" secondAttribute="top" id="Kgw-at-gJp"/>
-                        <constraint firstItem="HW4-ck-jy7" firstAttribute="centerY" secondItem="z67-Ah-wa8" secondAttribute="centerY" id="mBn-qQ-Prm"/>
-                    </constraints>
-                </view>
-                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zDJ-Vf-KV4">
-                    <rect key="frame" x="0.0" y="203.5" width="414" height="67.5"/>
-                    <subviews>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="循环播放" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Gnw-gE-pov">
-                            <rect key="frame" x="25" y="25" width="61.5" height="18"/>
-                            <fontDescription key="fontDescription" type="system" pointSize="15"/>
-                            <color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <nil key="highlightedColor"/>
-                        </label>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="pfs-HS-b09">
-                            <rect key="frame" x="342" y="0.0" width="47" height="67.5"/>
-                            <state key="normal" image="switch_off"/>
-                            <connections>
-                                <action selector="repeatAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="4HJ-j5-F3s"/>
-                            </connections>
-                        </button>
-                    </subviews>
-                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                    <constraints>
-                        <constraint firstItem="pfs-HS-b09" firstAttribute="top" secondItem="zDJ-Vf-KV4" secondAttribute="top" id="4Aj-F1-5Xb"/>
-                        <constraint firstAttribute="trailing" secondItem="pfs-HS-b09" secondAttribute="trailing" constant="25" id="E64-KK-WZD"/>
-                        <constraint firstItem="Gnw-gE-pov" firstAttribute="leading" secondItem="zDJ-Vf-KV4" secondAttribute="leading" constant="25" id="JpA-ig-FAM"/>
-                        <constraint firstAttribute="bottom" secondItem="pfs-HS-b09" secondAttribute="bottom" id="kH0-d7-2UN"/>
-                        <constraint firstItem="Gnw-gE-pov" firstAttribute="centerY" secondItem="zDJ-Vf-KV4" secondAttribute="centerY" id="sJp-ZW-jHQ"/>
-                    </constraints>
-                </view>
-                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="V10-3p-7eW">
-                    <rect key="frame" x="0.0" y="271" width="414" height="68"/>
-                    <subviews>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="显示指法" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kKb-ZC-FIu">
-                            <rect key="frame" x="25" y="25" width="61.5" height="18"/>
-                            <fontDescription key="fontDescription" type="system" pointSize="15"/>
-                            <color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <nil key="highlightedColor"/>
-                        </label>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="gvo-y6-Ae5">
-                            <rect key="frame" x="342" y="0.0" width="47" height="68"/>
-                            <state key="normal" image="switch_off"/>
-                            <connections>
-                                <action selector="showFingerAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="VBb-pJ-HhL"/>
-                            </connections>
-                        </button>
-                    </subviews>
-                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                    <constraints>
-                        <constraint firstItem="gvo-y6-Ae5" firstAttribute="top" secondItem="V10-3p-7eW" secondAttribute="top" id="MXk-Nd-kGY"/>
-                        <constraint firstAttribute="trailing" secondItem="gvo-y6-Ae5" secondAttribute="trailing" constant="25" id="OAR-r7-irb"/>
-                        <constraint firstItem="kKb-ZC-FIu" firstAttribute="leading" secondItem="V10-3p-7eW" secondAttribute="leading" constant="25" id="bPa-kw-nNs"/>
-                        <constraint firstItem="kKb-ZC-FIu" firstAttribute="centerY" secondItem="V10-3p-7eW" secondAttribute="centerY" id="dO2-0S-Psh"/>
-                        <constraint firstAttribute="bottom" secondItem="gvo-y6-Ae5" secondAttribute="bottom" id="uxT-ep-RPh"/>
-                    </constraints>
-                </view>
-            </subviews>
-            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-            <constraints>
-                <constraint firstAttribute="trailing" secondItem="wq8-rv-zdW" secondAttribute="trailing" id="6wM-KH-uQK"/>
-                <constraint firstItem="zDJ-Vf-KV4" firstAttribute="height" secondItem="TPz-Lt-ID7" secondAttribute="height" id="Bhi-bK-WDf"/>
-                <constraint firstAttribute="bottom" secondItem="V10-3p-7eW" secondAttribute="bottom" id="CxM-Pd-ssC"/>
-                <constraint firstItem="wq8-rv-zdW" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="Erw-uP-QV5"/>
-                <constraint firstItem="TPz-Lt-ID7" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="HI5-MG-dPY"/>
-                <constraint firstItem="z67-Ah-wa8" firstAttribute="height" secondItem="TPz-Lt-ID7" secondAttribute="height" id="ILl-Ih-a4Q"/>
-                <constraint firstAttribute="trailing" secondItem="zDJ-Vf-KV4" secondAttribute="trailing" id="Irg-ee-Bmh"/>
-                <constraint firstItem="zDJ-Vf-KV4" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="KYH-Mi-Qp3"/>
-                <constraint firstAttribute="trailing" secondItem="TPz-Lt-ID7" secondAttribute="trailing" id="SJw-JV-J1f"/>
-                <constraint firstItem="V10-3p-7eW" firstAttribute="height" secondItem="TPz-Lt-ID7" secondAttribute="height" id="Uzr-qa-gr5"/>
-                <constraint firstItem="V10-3p-7eW" firstAttribute="top" secondItem="zDJ-Vf-KV4" secondAttribute="bottom" id="YLv-Yy-M9a"/>
-                <constraint firstItem="wq8-rv-zdW" firstAttribute="top" secondItem="TPz-Lt-ID7" secondAttribute="bottom" id="fhn-gJ-GfI"/>
-                <constraint firstItem="z67-Ah-wa8" firstAttribute="top" secondItem="wq8-rv-zdW" secondAttribute="bottom" id="glK-Rc-hfc"/>
-                <constraint firstAttribute="trailing" secondItem="V10-3p-7eW" secondAttribute="trailing" id="hal-ff-Oaq"/>
-                <constraint firstItem="wq8-rv-zdW" firstAttribute="height" secondItem="TPz-Lt-ID7" secondAttribute="height" id="nJP-su-1KL"/>
-                <constraint firstItem="z67-Ah-wa8" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="uL5-Ms-8Sr"/>
-                <constraint firstItem="TPz-Lt-ID7" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="uTR-sy-eZx"/>
-                <constraint firstAttribute="trailing" secondItem="z67-Ah-wa8" secondAttribute="trailing" id="ugX-F6-s7a"/>
-                <constraint firstItem="zDJ-Vf-KV4" firstAttribute="top" secondItem="z67-Ah-wa8" secondAttribute="bottom" id="vFX-hG-wz7"/>
-                <constraint firstItem="V10-3p-7eW" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="xYU-9u-VUc"/>
-                <constraint firstAttribute="bottom" secondItem="V10-3p-7eW" secondAttribute="bottom" id="yCa-rq-sI7"/>
-            </constraints>
-            <nil key="simulatedTopBarMetrics"/>
-            <nil key="simulatedBottomBarMetrics"/>
-            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
-            <connections>
-                <outlet property="cameraButton" destination="7rE-UU-UnI" id="4Ma-2q-NLS"/>
-                <outlet property="eyeButton" destination="md8-79-tRj" id="jRV-jI-RIg"/>
-                <outlet property="fingerButton" destination="gvo-y6-Ae5" id="guC-Hj-VS6"/>
-                <outlet property="judgeButton" destination="3ZL-a9-mCu" id="Cn6-tM-eEY"/>
-                <outlet property="repeatButton" destination="pfs-HS-b09" id="qeg-gI-XyC"/>
-            </connections>
-            <point key="canvasLocation" x="76.811594202898561" y="37.165178571428569"/>
-        </view>
-    </objects>
-    <resources>
-        <image name="switch_off" width="47" height="24"/>
-        <systemColor name="systemBackgroundColor">
-            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-        </systemColor>
-    </resources>
-</document>

+ 0 - 43
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SoundCheckView/SoundCheckView.h

@@ -1,43 +0,0 @@
-//
-//  SoundCheckView.h
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/13.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-typedef NS_ENUM(NSInteger, CLOSEACTION) {
-    CLOSEACTION_SKIP,
-    CLOSEACTION_CLOSECHECK,
-    CLOSEACTION_SUCCESS,
-};
-
-typedef NS_ENUM(NSInteger, LIGHTDISPLAY) {
-    LIGHTDISPLAY_LOW,   // 频率低了
-    LIGHTDISPLAY_RIGHT, // 频率正常
-    LIGHTDISPLAY_HIGH,  // 频率高了
-};
-
-typedef void(^SoundCheckCallback)(CLOSEACTION action);
-
-@interface SoundCheckView : UIView
-
-@property (nonatomic, assign) NSInteger pitch;
-
-@property (nonatomic, copy) SoundCheckCallback callback;
-
-+ (instancetype)shareInstance;
-
-- (void)configSoundCheckWithSubjectId:(NSString *)subjectId callback:(SoundCheckCallback)callback;
-
-- (void)showSuccessCheckEnd;
-
-- (void)showLightDisplay:(LIGHTDISPLAY)type;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 153
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SoundCheckView/SoundCheckView.m

@@ -1,153 +0,0 @@
-//
-//  SoundCheckView.m
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/13.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import "SoundCheckView.h"
-#import "LFPopupMenu.h"
-
-@interface SoundCheckView ()
-
-@property (weak, nonatomic) IBOutlet UIImageView *leftDot;
-
-@property (weak, nonatomic) IBOutlet UIImageView *midDot;
-
-@property (weak, nonatomic) IBOutlet UIImageView *rightDot;
-
-
-@property (weak, nonatomic) IBOutlet UIImageView *staffImageView;
-
-
-@end
-
-@implementation SoundCheckView
-
-+ (instancetype)shareInstance {
-    SoundCheckView *view = [[[NSBundle mainBundle] loadNibNamed:@"SoundCheckView" owner:nil options:nil] firstObject];
-    return view;
-}
-- (void)configSoundCheckWithSubjectId:(NSString *)subjectId callback:(SoundCheckCallback)callback {
-    if (callback) {
-        self.callback = callback;
-    }
-    [self configStaffImageWithSubjectId:subjectId];
-}
-
-- (void)configStaffImageWithSubjectId:(NSString *)subjectId {
-    NSString *imgName = @"";
-    if ([subjectId isEqualToString:@"12"] || [subjectId isEqualToString:@"4"]) { // 小号 || 单簧管
-        imgName = @"staff_C5";
-        self.pitch = 60;
-    }
-    else if ([subjectId isEqualToString:@"14"] || [subjectId isEqualToString:@"15"]) { // 长号 || 上低音号
-        imgName = @"staff_S";
-        self.pitch = 34;
-    }
-    else if ([subjectId isEqualToString:@"13"]) { // 圆号
-        imgName = @"staff_F";
-        self.pitch = 53;
-    }
-    else if ([subjectId isEqualToString:@"5"] || [subjectId isEqualToString:@"6"]) { // sax
-        imgName = @"staff_C5(C)";
-        self.pitch = 60;
-    }
-    else if ([subjectId isEqualToString:@"120"]) { // 竖笛
-        imgName = @"staff_A5";
-        self.pitch = 69;
-    }
-    else { // 剩余声部
-        imgName = @"staff_b-14";
-        self.pitch = 58;
-    }
-    [self.staffImageView setImage:[UIImage imageNamed:imgName]];
-}
-
-
-- (void)resetImage {
-    [self.leftDot setImage:[UIImage imageNamed:@"emptyDot"]];
-    [self.midDot setImage:[UIImage imageNamed:@"emptyDot"]];
-    [self.rightDot setImage:[UIImage imageNamed:@"emptyDot"]];
-}
-- (void)showLightDisplay:(LIGHTDISPLAY)type {
-    [self resetImage];
-    switch (type) {
-        case LIGHTDISPLAY_LOW:
-        {
-            [self.leftDot setImage:[UIImage imageNamed:@"sound_wrong"]];
-        }
-            break;
-        case LIGHTDISPLAY_RIGHT:
-        {
-            [self.midDot setImage:[UIImage imageNamed:@"sound_right"]];
-        }
-            break;
-        case LIGHTDISPLAY_HIGH:
-        {
-            [self.rightDot setImage:[UIImage imageNamed:@"sound_wrong"]];
-        }
-            break;
-        default:
-            break;
-    }
-}
-
-- (IBAction)cancleAction:(id)sender {
-    [self closeViewWithType:CLOSEACTION_SKIP];
-}
-
-- (IBAction)skipButtonAction:(UIButton *)sender {
-    [self showTipsView:sender];
-}
-
-- (void)showTipsView:(UIButton *)button {
-    MJWeakSelf;
-    LFPopupMenuItem *item1 = [LFPopupMenuItem createWithTitle:@"跳过本次" image:nil action:^{
-        // 跳过
-        [weakSelf closeViewWithType:CLOSEACTION_SKIP];
-    }];
-    LFPopupMenuItem *item2 = [LFPopupMenuItem createWithTitle:@"关闭校音" image:nil action:^{
-        // 关闭校音
-        [weakSelf closeViewWithType:CLOSEACTION_CLOSECHECK];
-    }];
-    
-    LFPopupMenu *menu = [[LFPopupMenu alloc] init];
-    menu.needBorder = YES;
-    menu.rowHeight = 40.0f;
-    menu.minWidth = 76;
-    menu.textColor = HexRGB(0x333333);
-    menu.textFont = [UIFont systemFontOfSize:12.0f weight:UIFontWeightMedium];
-    
-    [menu configWithItems:@[item1,item2]];
-    [menu showArrowToView:button];
-}
-
-- (void)closeViewWithType:(CLOSEACTION)type {
-    [self removeFromSuperview];
-    if (self.callback) {
-        self.callback(type);
-    }
-}
-
-- (void)successCheckCallback {
-    [self removeFromSuperview];
-    if (self.callback) {
-        self.callback(CLOSEACTION_SUCCESS);
-    }
-}
-
-- (void)showSuccessCheckEnd {
-    [self successCheckCallback];
-}
-
-/*
-// Only override drawRect: if you perform custom drawing.
-// An empty implementation adversely affects performance during animation.
-- (void)drawRect:(CGRect)rect {
-    // Drawing code
-}
-*/
-
-@end

+ 0 - 177
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SoundCheckView/SoundCheckView.xib

@@ -1,177 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
-    <device id="retina6_1" orientation="portrait" appearance="light"/>
-    <dependencies>
-        <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
-        <capability name="System colors in document resources" minToolsVersion="11.0"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
-        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="SoundCheckView">
-            <rect key="frame" x="0.0" y="0.0" width="907" height="422"/>
-            <autoresizingMask key="autoresizingMask"/>
-            <subviews>
-                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="redraw" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="soundCheck_bg" translatesAutoresizingMaskIntoConstraints="NO" id="DE8-bH-WR0">
-                    <rect key="frame" x="0.0" y="0.0" width="907" height="422"/>
-                </imageView>
-                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Q7x-bJ-NJm">
-                    <rect key="frame" x="10" y="10" width="44" height="44"/>
-                    <constraints>
-                        <constraint firstAttribute="height" constant="44" id="8NW-Mp-yYf"/>
-                        <constraint firstAttribute="width" constant="44" id="a1E-FX-ymR"/>
-                    </constraints>
-                    <state key="normal" image="cloudback_white"/>
-                    <connections>
-                        <action selector="cancleAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="r6I-rZ-iMK"/>
-                    </connections>
-                </button>
-                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cloud_music" translatesAutoresizingMaskIntoConstraints="NO" id="lv2-Oo-rwG">
-                    <rect key="frame" x="26" y="64" width="855" height="308"/>
-                    <constraints>
-                        <constraint firstAttribute="width" secondItem="lv2-Oo-rwG" secondAttribute="height" multiplier="286:103" id="czf-na-sj7"/>
-                    </constraints>
-                </imageView>
-                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="FA0-6u-T0j">
-                    <rect key="frame" x="206.5" y="40" width="494" height="314"/>
-                    <subviews>
-                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cloud_blackboard" translatesAutoresizingMaskIntoConstraints="NO" id="H1h-j5-1lu">
-                            <rect key="frame" x="0.0" y="0.0" width="494" height="314"/>
-                        </imageView>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="OCq-9O-8fJ">
-                            <rect key="frame" x="172" y="227" width="150" height="50"/>
-                            <subviews>
-                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="emptyDot" translatesAutoresizingMaskIntoConstraints="NO" id="hdh-04-p1S">
-                                    <rect key="frame" x="15" y="10" width="30" height="30"/>
-                                </imageView>
-                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="emptyDot" translatesAutoresizingMaskIntoConstraints="NO" id="LE9-0Y-6d3">
-                                    <rect key="frame" x="60" y="10" width="30" height="30"/>
-                                    <constraints>
-                                        <constraint firstAttribute="width" constant="30" id="ldo-1V-e4N"/>
-                                        <constraint firstAttribute="height" constant="30" id="mFT-3S-Kpi"/>
-                                    </constraints>
-                                </imageView>
-                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="emptyDot" translatesAutoresizingMaskIntoConstraints="NO" id="0B9-od-SoC">
-                                    <rect key="frame" x="105" y="10" width="30" height="30"/>
-                                </imageView>
-                            </subviews>
-                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                            <constraints>
-                                <constraint firstItem="LE9-0Y-6d3" firstAttribute="centerY" secondItem="hdh-04-p1S" secondAttribute="centerY" id="3yP-Y6-H1v"/>
-                                <constraint firstItem="LE9-0Y-6d3" firstAttribute="leading" secondItem="hdh-04-p1S" secondAttribute="trailing" constant="15" id="8ac-fR-jUz"/>
-                                <constraint firstItem="LE9-0Y-6d3" firstAttribute="centerY" secondItem="OCq-9O-8fJ" secondAttribute="centerY" id="GwT-jl-9Ic"/>
-                                <constraint firstAttribute="width" constant="150" id="OUm-fX-CBP"/>
-                                <constraint firstAttribute="height" constant="50" id="VUq-ud-m3T"/>
-                                <constraint firstItem="LE9-0Y-6d3" firstAttribute="centerX" secondItem="OCq-9O-8fJ" secondAttribute="centerX" id="dlM-dP-Ta5"/>
-                                <constraint firstItem="0B9-od-SoC" firstAttribute="centerY" secondItem="hdh-04-p1S" secondAttribute="centerY" id="fx0-EP-KhH"/>
-                                <constraint firstItem="0B9-od-SoC" firstAttribute="leading" secondItem="LE9-0Y-6d3" secondAttribute="trailing" constant="15" id="sFv-Gb-Rk8"/>
-                            </constraints>
-                        </view>
-                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="staff_C" translatesAutoresizingMaskIntoConstraints="NO" id="dw5-YO-FzD">
-                            <rect key="frame" x="127" y="127" width="240" height="70"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="70" id="KWY-Tw-37n"/>
-                                <constraint firstAttribute="width" constant="240" id="LKn-az-RPR"/>
-                            </constraints>
-                        </imageView>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="请演奏直到中间绿灯亮起" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cKL-Ai-eDg">
-                            <rect key="frame" x="168" y="197" width="158" height="20"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="20" id="f3w-ar-xHb"/>
-                            </constraints>
-                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
-                            <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                            <nil key="highlightedColor"/>
-                        </label>
-                    </subviews>
-                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                    <constraints>
-                        <constraint firstItem="dw5-YO-FzD" firstAttribute="centerX" secondItem="FA0-6u-T0j" secondAttribute="centerX" id="8TP-hN-kB8"/>
-                        <constraint firstAttribute="trailing" secondItem="H1h-j5-1lu" secondAttribute="trailing" id="Am4-Fd-A69"/>
-                        <constraint firstAttribute="width" secondItem="FA0-6u-T0j" secondAttribute="height" multiplier="494:314" id="Ok6-HV-AWa"/>
-                        <constraint firstItem="OCq-9O-8fJ" firstAttribute="centerX" secondItem="FA0-6u-T0j" secondAttribute="centerX" id="QpT-bj-z7Z"/>
-                        <constraint firstItem="H1h-j5-1lu" firstAttribute="leading" secondItem="FA0-6u-T0j" secondAttribute="leading" id="U0E-AZ-7LF"/>
-                        <constraint firstItem="H1h-j5-1lu" firstAttribute="top" secondItem="FA0-6u-T0j" secondAttribute="top" id="a9M-ya-ppz"/>
-                        <constraint firstAttribute="bottom" secondItem="H1h-j5-1lu" secondAttribute="bottom" id="evf-rJ-FT1"/>
-                        <constraint firstItem="OCq-9O-8fJ" firstAttribute="top" secondItem="cKL-Ai-eDg" secondAttribute="bottom" constant="10" id="gbJ-iC-jmF"/>
-                        <constraint firstItem="cKL-Ai-eDg" firstAttribute="centerX" secondItem="FA0-6u-T0j" secondAttribute="centerX" id="t6D-6o-Z0l"/>
-                        <constraint firstItem="cKL-Ai-eDg" firstAttribute="top" secondItem="dw5-YO-FzD" secondAttribute="bottom" id="teU-wM-41k"/>
-                    </constraints>
-                </view>
-                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="check_headPhone" translatesAutoresizingMaskIntoConstraints="NO" id="YlK-H1-rfX">
-                    <rect key="frame" x="236.5" y="287" width="95" height="135"/>
-                    <constraints>
-                        <constraint firstAttribute="width" secondItem="YlK-H1-rfX" secondAttribute="height" multiplier="19:27" id="dm0-fU-LSm"/>
-                    </constraints>
-                </imageView>
-                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="跳过本次" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8Dy-Po-zbc">
-                    <rect key="frame" x="785" y="24" width="74" height="22"/>
-                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="18"/>
-                    <nil key="textColor"/>
-                    <nil key="highlightedColor"/>
-                </label>
-                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="down_arrow" translatesAutoresizingMaskIntoConstraints="NO" id="Gze-Pn-Alp">
-                    <rect key="frame" x="864" y="30" width="14" height="10"/>
-                </imageView>
-                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0Z7-6c-ASS">
-                    <rect key="frame" x="785" y="15" width="93" height="40"/>
-                    <constraints>
-                        <constraint firstAttribute="height" constant="40" id="uX4-r8-D35"/>
-                    </constraints>
-                    <connections>
-                        <action selector="skipButtonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="W3C-fk-Wbk"/>
-                    </connections>
-                </button>
-            </subviews>
-            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-            <constraints>
-                <constraint firstItem="Gze-Pn-Alp" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="30" id="3yW-2D-HEN"/>
-                <constraint firstAttribute="trailing" secondItem="lv2-Oo-rwG" secondAttribute="trailing" constant="26" id="6ma-Pu-Tw8"/>
-                <constraint firstItem="YlK-H1-rfX" firstAttribute="leading" secondItem="FA0-6u-T0j" secondAttribute="leading" constant="30" id="75t-zn-cHr"/>
-                <constraint firstItem="Gze-Pn-Alp" firstAttribute="leading" secondItem="8Dy-Po-zbc" secondAttribute="trailing" constant="5" id="8hF-04-ruI"/>
-                <constraint firstItem="Q7x-bJ-NJm" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="Dku-jN-vJj"/>
-                <constraint firstItem="Gze-Pn-Alp" firstAttribute="centerY" secondItem="0Z7-6c-ASS" secondAttribute="centerY" id="K5X-ql-gIC"/>
-                <constraint firstItem="0Z7-6c-ASS" firstAttribute="leading" secondItem="8Dy-Po-zbc" secondAttribute="leading" id="KHT-b9-YyP"/>
-                <constraint firstItem="lv2-Oo-rwG" firstAttribute="top" secondItem="Q7x-bJ-NJm" secondAttribute="bottom" constant="10" id="Mgh-1M-5db"/>
-                <constraint firstItem="FA0-6u-T0j" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="Nly-GO-YZc"/>
-                <constraint firstItem="lv2-Oo-rwG" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="26" id="SVo-s8-PUO"/>
-                <constraint firstAttribute="trailing" secondItem="DE8-bH-WR0" secondAttribute="trailing" id="TAz-Gn-46Q"/>
-                <constraint firstItem="Gze-Pn-Alp" firstAttribute="trailing" secondItem="0Z7-6c-ASS" secondAttribute="trailing" id="Xt5-Z5-MkV"/>
-                <constraint firstItem="DE8-bH-WR0" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="aK9-i0-r7N"/>
-                <constraint firstAttribute="trailing" secondItem="Gze-Pn-Alp" secondAttribute="trailing" constant="29" id="bYk-qU-2I5"/>
-                <constraint firstItem="OCq-9O-8fJ" firstAttribute="top" secondItem="YlK-H1-rfX" secondAttribute="top" constant="-20" id="bvs-3l-u7h"/>
-                <constraint firstItem="DE8-bH-WR0" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="fFs-mc-dm4"/>
-                <constraint firstItem="FA0-6u-T0j" firstAttribute="top" secondItem="Q7x-bJ-NJm" secondAttribute="top" constant="30" id="feU-Hk-QNn"/>
-                <constraint firstAttribute="bottom" secondItem="DE8-bH-WR0" secondAttribute="bottom" id="jwC-i3-ICT"/>
-                <constraint firstItem="Gze-Pn-Alp" firstAttribute="centerY" secondItem="8Dy-Po-zbc" secondAttribute="centerY" id="k9w-ug-51F"/>
-                <constraint firstAttribute="bottom" secondItem="YlK-H1-rfX" secondAttribute="bottom" id="laE-no-0I1"/>
-                <constraint firstItem="Q7x-bJ-NJm" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="10" id="n47-CT-3ga"/>
-            </constraints>
-            <nil key="simulatedTopBarMetrics"/>
-            <nil key="simulatedBottomBarMetrics"/>
-            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
-            <connections>
-                <outlet property="leftDot" destination="hdh-04-p1S" id="Mz0-uF-8Nh"/>
-                <outlet property="midDot" destination="LE9-0Y-6d3" id="Wop-lD-frP"/>
-                <outlet property="rightDot" destination="0B9-od-SoC" id="GRI-oC-Mem"/>
-                <outlet property="staffImageView" destination="dw5-YO-FzD" id="g6B-dA-72c"/>
-            </connections>
-            <point key="canvasLocation" x="280.43478260869568" y="-74.330357142857139"/>
-        </view>
-    </objects>
-    <resources>
-        <image name="check_headPhone" width="95" height="135"/>
-        <image name="cloud_blackboard" width="494" height="314"/>
-        <image name="cloud_music" width="735" height="206"/>
-        <image name="cloudback_white" width="32" height="32"/>
-        <image name="down_arrow" width="14" height="10"/>
-        <image name="emptyDot" width="30" height="30"/>
-        <image name="soundCheck_bg" width="812" height="375"/>
-        <image name="staff_C" width="985.5" height="286.5"/>
-        <systemColor name="systemBackgroundColor">
-            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-        </systemColor>
-    </resources>
-</document>

+ 0 - 38
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SpeedSlider/KSSliderView.h

@@ -1,38 +0,0 @@
-//
-//  KSSliderView.h
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/13.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@protocol KSSliderDelegate <NSObject>
-
-@optional
-
-- (void)rateChangeAction:(NSInteger)rate;
-- (void)beginSwip;
-- (void)endSwip;
-
-@end
-
-@interface KSSliderView : UIView
-
-@property (nonatomic, assign) BOOL isVertical;
-
-@property (strong, nonatomic) NSNumberFormatter *numberFormatter;
-@property (nonatomic, assign) CGFloat minValue;
-@property (nonatomic, assign) CGFloat maxValue;
-@property (nonatomic, strong) UIColor *minimumTrackTintColor;
-@property (nonatomic, strong) UIColor *maxmumTrackTintColor;
-@property (nonatomic, assign) NSInteger rateValue;
-
-@property (nonatomic, unsafe_unretained)id<KSSliderDelegate>delegate;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 154
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SpeedSlider/KSSliderView.m

@@ -1,154 +0,0 @@
-//
-//  KSSliderView.m
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/13.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import "KSSliderView.h"
-#import "KSTrackingSlider.h"
-
-@interface KSSliderView ()<KSTrackingSliderDelegate>
-
-@property (nonatomic, strong) UIButton *addButton; // 加
-
-@property (nonatomic, strong) UIButton *subtractButton; // 减
-
-@property (nonatomic, strong) KSTrackingSlider *sliderBar;
-
-@end
-
-@implementation KSSliderView
-
-- (instancetype)initWithFrame:(CGRect)frame {
-    self = [super initWithFrame:frame];
-    if (self) {
-        [self setUpWithFrame:frame];
-    }
-    return self;
-}
-
-- (void)setUpWithFrame:(CGRect)frame {
-    self.layer.cornerRadius = 5.0f;
-    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
-    [formatter setNumberStyle:NSNumberFormatterDecimalStyle];
-    [formatter setRoundingMode:NSNumberFormatterRoundHalfUp];
-    [formatter setMaximumFractionDigits:0];
-    [formatter setMinimumFractionDigits:0];
-    _numberFormatter = formatter;
-    [self addButtons];
-    [self addSubview:self.sliderBar];
-}
-
-- (void)setRateValue:(NSInteger)rateValue {
-    _rateValue = rateValue;
-    self.sliderBar.value = rateValue;
-    if (self.delegate && [self.delegate respondsToSelector:@selector(rateChangeAction:)]) {
-        [self.delegate rateChangeAction:rateValue];
-    }
-}
-
-- (void)addButtons {
-    [self addSubview:self.addButton];
-    [self addSubview:self.subtractButton];
-}
-
-
-#pragma mark --- lazying
-
-- (UIButton *)addButton {
-    if (!_addButton) {
-        _addButton = [UIButton buttonWithType:UIButtonTypeCustom];
-        _addButton.frame = CGRectMake(5, 10, 40, 40);
-        [_addButton setImage:[UIImage imageNamed:@"img_speed_add"] forState:UIControlStateNormal];
-        [_addButton addTarget:self action:@selector(addValueAction:) forControlEvents:UIControlEventTouchUpInside];
-    }
-    return _addButton;
-}
-
-
-- (void)addValueAction:(UIButton *)sender {
-    self.rateValue = self.rateValue + 1;
-}
-
-- (UIButton *)subtractButton {
-    if (!_subtractButton) {
-        _subtractButton = [UIButton buttonWithType:UIButtonTypeCustom];
-        _subtractButton.frame = CGRectMake(5, CGRectGetHeight(self.frame) - 40, 40, 40);
-        [_subtractButton setImage:[UIImage imageNamed:@"img_speed_reduce"] forState:UIControlStateNormal];
-        [_subtractButton addTarget:self action:@selector(subtractAction:) forControlEvents:UIControlEventTouchUpInside];
-    }
-    return _subtractButton;
-}
-
-- (void)subtractAction:(UIButton *)sender {
-    self.rateValue = self.rateValue - 1;
-}
-
-- (KSTrackingSlider *)sliderBar {
-    if (!_sliderBar) {
-        CGFloat width = 160.0f;
-        CGFloat height = 50.0f;
-        _sliderBar = [[KSTrackingSlider alloc] initWithFrame:CGRectMake(height / 2.0f - width / 2.0f, width / 2.0f + 50 - height / 2.0f , width, height)];
-        _sliderBar.tintColor = HexRGB(0x01c1b5);
-        _sliderBar.delegate = self;
-        _sliderBar.minimumValue = 45;
-        _sliderBar.maximumValue = 270;
-    }
-    return _sliderBar;
-}
-- (void)currentValueOfSlider:(KSTrackingSlider *)slider {
-    self.rateValue = [_numberFormatter stringFromNumber:@(slider.value)].integerValue;
-}
-
-- (void)beginSwipSlider:(KSTrackingSlider *)slider {
-    if (self.delegate && [self.delegate respondsToSelector:@selector(beginSwip)]) {
-        [self.delegate beginSwip];
-    }
-}
-
-- (void)endSwipSlider:(KSTrackingSlider *)slider {
-    if (self.delegate && [self.delegate respondsToSelector:@selector(endSwip)]) {
-        [self.delegate endSwip];
-    }
-}
-
-- (void)setIsVertical:(BOOL)isVertical{
-    _isVertical = isVertical;
-    if (_isVertical == YES) {
-        self.sliderBar.transform = CGAffineTransformMakeRotation(-M_PI_2);
-
-    }else{
-        
-    }
-}
-- (void)setNumberFormatter:(NSNumberFormatter *)numberFormatter
-{
-    _numberFormatter = numberFormatter;
-}
-- (void)setMinValue:(CGFloat)minValue{
-    _minValue = minValue;
-    _sliderBar.minimumValue = minValue;
-}
-- (void)setMaxValue:(CGFloat)maxValue{
-    _maxValue = maxValue;
-    _sliderBar.maximumValue = maxValue;
-}
-- (void)setMinimumTrackTintColor:(UIColor *)minimumTrackTintColor{
-    _minimumTrackTintColor = minimumTrackTintColor;
-    _sliderBar.minimumTrackTintColor = minimumTrackTintColor;
-}
-- (void)setMaxmumTrackTintColor:(UIColor *)maxmumTrackTintColor{
-    _maxmumTrackTintColor = maxmumTrackTintColor;
-    _sliderBar.maximumTrackTintColor = maxmumTrackTintColor;
-}
-/*
-// Only override drawRect: if you perform custom drawing.
-// An empty implementation adversely affects performance during animation.
-- (void)drawRect:(CGRect)rect {
-    // Drawing code
-}
-*/
-
-@end

+ 0 - 29
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SpeedSlider/KSTrackingSlider.h

@@ -1,29 +0,0 @@
-//
-//  KSTrackingSlider.h
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/13.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
-@class KSTrackingSlider;
-
-@protocol KSTrackingSliderDelegate <NSObject>
-
-- (void)currentValueOfSlider:(KSTrackingSlider *_Nonnull)slider;
-- (void)beginSwipSlider:(KSTrackingSlider *_Nonnull)slider;
-- (void)endSwipSlider:(KSTrackingSlider *_Nonnull)slider;
-
-@end
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface KSTrackingSlider : UISlider
-
-@property (nonatomic, unsafe_unretained) id <KSTrackingSliderDelegate> delegate;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 70
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/SpeedSlider/KSTrackingSlider.m

@@ -1,70 +0,0 @@
-//
-//  KSTrackingSlider.m
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/13.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import "KSTrackingSlider.h"
-
-@implementation KSTrackingSlider
-
-- (instancetype)initWithFrame:(CGRect)frame {
-    self = [super initWithFrame:frame];
-    if (self) {
-        
-    }
-    return self;
-}
-
-#pragma mark --- subClassed
-
-- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
-    BOOL begin = [super beginTrackingWithTouch:touch withEvent:event];
-    if (begin) {
-        if ([self.delegate respondsToSelector:@selector(currentValueOfSlider:)]) {
-            [self.delegate currentValueOfSlider:self];
-        }
-        if ([self.delegate respondsToSelector:@selector(beginSwipSlider:)]) {
-            [self.delegate beginSwipSlider:self];
-        }
-    }
-    return begin;
-}
-
-- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
-{
-    BOOL continueTrack = [super continueTrackingWithTouch:touch withEvent:event];
-    if (continueTrack) {
-        if ([self.delegate respondsToSelector:@selector(currentValueOfSlider:)]) {
-            [self.delegate currentValueOfSlider:self];
-        }
-    }
-    return continueTrack;
-}
-- (void)cancelTrackingWithEvent:(UIEvent *)event
-{
-    [super cancelTrackingWithEvent:event];
-}
-
-- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
-{
-    [super endTrackingWithTouch:touch withEvent:event];
-    if ([self.delegate respondsToSelector:@selector(currentValueOfSlider:)]) {
-        [self.delegate currentValueOfSlider:self];
-    }
-    if ([self.delegate respondsToSelector:@selector(endSwipSlider:)]) {
-        [self.delegate endSwipSlider:self];
-    }
-}
-
-/*
-// Only override drawRect: if you perform custom drawing.
-// An empty implementation adversely affects performance during animation.
-- (void)drawRect:(CGRect)rect {
-    // Drawing code
-}
-*/
-
-@end

+ 0 - 25
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/StaffView/CloudControlButton.h

@@ -1,25 +0,0 @@
-//
-//  CloudControlButton.h
-//  MidiPlayer
-//
-//  Created by Kyle on 2021/12/6.
-//
-
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-@class CloudControlButton;
-
-typedef void(^ControlAction)(CloudControlButton *sender, BOOL isSelected);
-
-@interface CloudControlButton : UIView
-
-@property (nonatomic, assign) BOOL isSelected;
-
-+ (instancetype)createButtonWithImage:(NSString *)imageName selectImage:(NSString *)selectImage buttonTitle:(NSString *)buttonTitle selectTitle:(NSString *)selectTitle tag:(NSInteger)tag frame:(CGRect)frame callback:(ControlAction)callback;
-
-- (void)showSpeed:(NSInteger)speed;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 132
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/StaffView/CloudControlButton.m

@@ -1,132 +0,0 @@
-//
-//  CloudControlButton.m
-//  MidiPlayer
-//
-//  Created by Kyle on 2021/12/6.
-//
-
-#import "CloudControlButton.h"
-
-@interface CloudControlButton ()
-
-@property (nonatomic, strong) UILabel *titleLabel;
-
-@property (nonatomic, strong) UIButton *actionButton;
-
-@property (nonatomic, copy) ControlAction callback;
-
-@property (nonatomic, strong) NSString *buttonTitle;
-
-@property (nonatomic, strong) NSString *selectTitle;
-
-@property (nonatomic, strong) UILabel *speedLabel;
-@end
-
-@implementation CloudControlButton
-
-+ (instancetype)createButtonWithImage:(NSString *)imageName selectImage:(NSString *)selectImage buttonTitle:(NSString *)buttonTitle selectTitle:(NSString *)selectTitle tag:(NSInteger)tag frame:(CGRect)frame callback:(ControlAction)callback {
-    
-    CloudControlButton *controlButton = [[CloudControlButton alloc] initWithFrame:frame];
-    controlButton.tag = tag;
-    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
-    button.backgroundColor = [UIColor clearColor];
-    button.frame = CGRectMake(0, 0, frame.size.width, frame.size.width);
-    [button addTarget:controlButton action:@selector(buttonClickAction:) forControlEvents:UIControlEventTouchUpInside];
-    [button setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
-    [button setImage:[UIImage imageNamed:selectImage] forState:UIControlStateSelected];
-    [controlButton addSubview:button];
-    
-    [controlButton addSubview:controlButton.titleLabel];
-    controlButton.titleLabel.frame = CGRectMake(0, CGRectGetMaxX(button.frame) + 2, frame.size.width, 24);
-    controlButton.actionButton = button;
-    controlButton.buttonTitle = buttonTitle;
-    controlButton.selectTitle = selectTitle;
-    
-    controlButton.isSelected = NO;
-    if (callback) {
-        controlButton.callback = callback;
-    }
-    
-    return controlButton;
-}
-
-- (void)showSpeed:(NSInteger)speed {
-    if (!_speedLabel) {
-        UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
-        view.backgroundColor = UIColor.whiteColor;
-        view.layer.cornerRadius = 8.0f;
-        view.layer.borderColor = THEMECOLOR.CGColor;
-        view.layer.borderWidth = 1.0f;
-        [view addSubview:self.speedLabel];
-        [self addSubview:view];
-        
-        [view mas_makeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(self.actionButton.mas_right).offset(-8);
-            make.top.mas_equalTo(self.actionButton.mas_top);
-            make.height.mas_equalTo(16.0f);
-        }];
-        
-        [self.speedLabel mas_makeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(view.mas_left).offset(5);
-            make.right.mas_equalTo(view.mas_right).offset(-5);
-            make.centerY.mas_equalTo(view.mas_centerY);
-        }];
-
-    }
-    else {
-        
-    }
-    self.speedLabel.text = [NSString stringWithFormat:@"%zd", speed];
-}
-
-- (void)buttonClickAction:(UIButton *)sender {
-    
-    self.isSelected = !self.isSelected;
-    if (self.callback) {
-        self.callback(self, self.isSelected);
-    }
-}
-
-#pragma mark ---- setter
-- (void)setIsSelected:(BOOL)isSelected {
-    
-    _isSelected = isSelected;
-    self.actionButton.selected = isSelected;
-    if (isSelected) {
-        self.titleLabel.text = self.selectTitle;
-    }
-    else {
-        self.titleLabel.text = self.buttonTitle;
-    }
-}
-#pragma mark ----- lazying
-- (UILabel *)titleLabel {
-    
-    if (!_titleLabel) {
-        _titleLabel = [[UILabel alloc] init];
-        _titleLabel.textColor = UIColor.whiteColor;
-        _titleLabel.font = [UIFont systemFontOfSize:12.0f weight:UIFontWeightMedium];
-        _titleLabel.textAlignment = NSTextAlignmentCenter;
-    }
-    return _titleLabel;
-}
-
-- (UILabel *)speedLabel {
-    if (!_speedLabel) {
-        _speedLabel = [[UILabel alloc] init];
-        [_speedLabel setFont:[UIFont systemFontOfSize:10.0f]];
-        _speedLabel.textColor = THEMECOLOR;
-        _speedLabel.textAlignment = NSTextAlignmentCenter;
-    }
-    return _speedLabel;
-}
-
-/*
-// Only override drawRect: if you perform custom drawing.
-// An empty implementation adversely affects performance during animation.
-- (void)drawRect:(CGRect)rect {
-    // Drawing code
-}
-*/
-
-@end

+ 0 - 20
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/StaffView/ScoreAnimationView.h

@@ -1,20 +0,0 @@
-//
-//  ScoreAnimationView.h
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/10.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface ScoreAnimationView : UIView
-
-- (instancetype)initWithFrame:(CGRect)frame animitionDistance:(CGFloat)distance score:(NSInteger)score titleColor:(UIColor *)titleColor imageName:(NSString *)imageName;
-
-- (void)showInView:(UIView *)displayView;
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 76
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/StaffView/ScoreAnimationView.m

@@ -1,76 +0,0 @@
-//
-//  ScoreAnimationView.m
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/10.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import "ScoreAnimationView.h"
-
-@interface ScoreAnimationView ()
-
-@property (nonatomic, assign) CGFloat distanceY;
-
-@property (nonatomic, assign) NSInteger score;
-
-@property (nonatomic, strong) UIColor *scoreColor;
-
-@property (nonatomic, strong) NSString *imgName;
-
-@end
-
-@implementation ScoreAnimationView
-
-
-- (instancetype)initWithFrame:(CGRect)frame animitionDistance:(CGFloat)distance score:(NSInteger)score titleColor:(UIColor *)titleColor imageName:(NSString *)imageName {
-    self = [super initWithFrame:frame];
-    if (self) {
-        self.distanceY = distance;
-        self.score = score;
-        self.scoreColor = titleColor;
-        self.imgName = imageName;
-        [self configView];
-    }
-    return self;
-}
-
-
-- (void)configView {
-    UIImage *image = [UIImage imageNamed:self.imgName];
-    CGFloat rate = image.size.width / image.size.height;
-    UIImageView *scoreImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, rate * 40, 40)];
-    [scoreImage setImage:image];
-    [self addSubview:scoreImage];
-    UILabel *scoreLabel = [[UILabel alloc] init];
-    scoreLabel.frame = CGRectMake(CGRectGetMaxX(scoreImage.frame), 0, 40, 40);
-    scoreLabel.textAlignment = NSTextAlignmentLeft;
-    [scoreLabel setText:[NSString stringWithFormat:@"%zd",self.score]];
-    [scoreLabel setTextColor:self.scoreColor];
-    [scoreLabel setFont:[UIFont systemFontOfSize:18.0f weight:UIFontWeightBold]];
-    [self addSubview:scoreLabel];
-    
-}
-
-- (void)showInView:(UIView *)displayView {
-    [displayView addSubview:self];
-    
-    [UIView animateWithDuration:0.5f animations:^{
-        CGRect frame = self.frame;
-        frame.origin.y -= (self.distanceY + frame.size.height);
-        self.frame = frame;
-    } completion:^(BOOL finished) {
-        [self removeFromSuperview];
-    }];
-}
-
-
-/*
-// Only override drawRect: if you perform custom drawing.
-// An empty implementation adversely affects performance during animation.
-- (void)drawRect:(CGRect)rect {
-    // Drawing code
-}
-*/
-
-@end

+ 0 - 51
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/StaffView/StaffImageDisplayView.h

@@ -1,51 +0,0 @@
-//
-//  StaffImageDisplayView.h
-//  MidiPlayer
-//
-//  Created by Kyle on 2021/12/2.
-//
-
-#import <UIKit/UIKit.h>
-
-
-@interface KSMeasureLocationModel : NSObject
-
-@property (nonatomic, assign) CGFloat positionX;
-
-@property (nonatomic, assign) CGFloat positionY;
-
-@property (nonatomic, assign) CGFloat measureWidth;
-
-@property (nonatomic, assign) CGFloat measureHeight;
-
-@property (nonatomic, assign) NSInteger pageIndex;  // 当前page
-
-@property (nonatomic, strong) UIColor * _Nonnull fillColor; // 填充颜色
-
-@end
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-
-typedef void(^TapCallback)(CGFloat positionX, CGFloat positionY, NSInteger pageIndex);
-
-@interface StaffImageDisplayView : UIView
-
-@property (nonatomic, assign) NSInteger pageIndex;  // 当前page
-
-@property (nonatomic, strong) NSString *imageName;  // 图片名称
-
-- (instancetype)initWithImage:(NSString *)imageName pageIndex:(NSInteger)pageIndex frame:(CGRect)viewFrame;
-
-- (void)viewTapActionCallback:(TapCallback)callback;
-
-- (void)clearAllColorView;
-
-- (void)addColorView:(KSMeasureLocationModel *)model;
-
-- (void)drawColorView:(NSMutableArray *)viewLocatonArray;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 109
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/StaffView/StaffImageDisplayView.m

@@ -1,109 +0,0 @@
-//
-//  StaffImageDisplayView.m
-//  MidiPlayer
-//
-//  Created by Kyle on 2021/12/2.
-//
-
-#import "StaffImageDisplayView.h"
-
-@interface KSColorView : UIView
-
-@end
-
-@implementation KSColorView
-
-
-@end
-
-
-@implementation KSMeasureLocationModel
-
-@end
-
-
-@interface StaffImageDisplayView ()
-
-@property (nonatomic, strong) UIView *bgView;
-
-@property (nonatomic, strong) UIImageView *imageView;
-
-@property (nonatomic, copy) TapCallback callback;
-
-@end
-
-@implementation StaffImageDisplayView
-
-- (instancetype)initWithImage:(NSString *)imageName pageIndex:(NSInteger)pageIndex frame:(CGRect)viewFrame {
-    if (self = [super initWithFrame:viewFrame]) {
-        self.bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, viewFrame.size.width, viewFrame.size.height)];
-        self.bgView.backgroundColor = [UIColor clearColor];
-        [self addSubview:self.bgView];
-        
-        self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, viewFrame.size.width, viewFrame.size.height)];
-        self.imageView.userInteractionEnabled = YES;
-        [self addSubview:self.imageView];
-        
-        self.imageName = imageName;
-        self.pageIndex = pageIndex;
-    }
-    return self;
-}
-
-
-- (void)viewTapActionCallback:(TapCallback)callback {
-    if (callback) {
-        self.callback = callback;
-    }
-}
-
-- (void)clearAllColorView {
-    for (UIView *view in self.bgView.subviews) {
-        if ([view isKindOfClass:[KSColorView class]]) {
-            [view removeFromSuperview];
-        }
-    }
-}
-
-- (void)addColorView:(KSMeasureLocationModel *)model {
-    
-    KSColorView *colorView = [[KSColorView alloc] initWithFrame:CGRectMake(model.positionX, model.positionY, model.measureWidth, model.measureHeight)];
-    colorView.backgroundColor = model.fillColor;
-    [self.bgView addSubview:colorView];
-}
-
-- (void)drawColorView:(NSMutableArray *)viewLocatonArray {
-    for (KSMeasureLocationModel *model in viewLocatonArray) {
-        KSColorView *colorView = [[KSColorView alloc] initWithFrame:CGRectMake(model.positionX, model.positionY, model.measureWidth, model.measureHeight)];
-        colorView.backgroundColor = model.fillColor;
-        [self.bgView addSubview:colorView];
-    }
-}
-
-#pragma mark ------- setting
-- (void)setImageName:(NSString *)imageName {
-    _imageName = imageName;
-    [self.imageView setImage:[UIImage imageNamed:imageName]];
-}
-
-- (void)setPageIndex:(NSInteger)pageIndex {
-    _pageIndex = pageIndex;
-}
-
-- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
-    UITouch *touch = [touches anyObject];
-    CGPoint point = [touch locationInView:self];
-    if (self.callback) {
-        self.callback(point.x, point.y, self.pageIndex);
-    }
-}
-
-/*
-// Only override drawRect: if you perform custom drawing.
-// An empty implementation adversely affects performance during animation.
-- (void)drawRect:(CGRect)rect {
-    // Drawing code
-}
-*/
-
-@end

+ 0 - 39
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/TipsAlert/EvaluateResultAlert.h

@@ -1,39 +0,0 @@
-//
-//  EvaluateResultAlert.h
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/10.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-typedef NS_ENUM(NSInteger, EVALUATE_RESULT_ACTION) {
-    EVALUATE_RESULT_ACTION_CANCLE,  // 取消
-    EVALUATE_RESULT_ACTION_SUBMIT, // 上传到云端
-    EVALUATE_RESULT_ACTION_SHARE,  // 分享
-    EVALUATE_RESULT_ACTION_PRACTICE, // 练习
-    EVALUATE_RESULT_ACTION_TAYAGAIN, // 再试一次
-    EVALUATE_RESULT_ACTION_REPORT,   // 查看报告
-};
-
-typedef void(^EvaluateResultCallback)(EVALUATE_RESULT_ACTION action);
-
-@interface EvaluateResultAlert : UIView
-
-+ (instancetype)shareInstance;
-
-/// 配置页面显示
-/// @param score 分数
-/// @param intonation 音准
-/// @param cadence 节奏
-/// @param integrity 完整度
-- (void)configWithScore:(NSInteger)score intonation:(NSInteger)intonation cadence:(NSInteger)cadence integrity:(NSInteger)integrity;
-
-- (void)resultCallback:(EvaluateResultCallback)callback;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 144
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/TipsAlert/EvaluateResultAlert.m

@@ -1,144 +0,0 @@
-//
-//  EvaluateResultAlert.m
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/10.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import "EvaluateResultAlert.h"
-
-@interface EvaluateResultAlert ()
-
-@property (weak, nonatomic) IBOutlet UILabel *scoreLabel;
-
-@property (weak, nonatomic) IBOutlet UILabel *scoreDesc;
-// 音准
-@property (weak, nonatomic) IBOutlet UIView *intonationView;
-@property (weak, nonatomic) IBOutlet UILabel *intonationScore;
-@property (weak, nonatomic) IBOutlet UIView *intonationValueView;
-@property (weak, nonatomic) IBOutlet NSLayoutConstraint *intonationWidth;
-
-// 节奏
-@property (weak, nonatomic) IBOutlet UIView *rhythmView;
-@property (weak, nonatomic) IBOutlet UILabel *rhythmLabel;
-@property (weak, nonatomic) IBOutlet UIView *rhyhtmVauleView;
-@property (weak, nonatomic) IBOutlet NSLayoutConstraint *rhythmWidth;
-
-// 完整性
-@property (weak, nonatomic) IBOutlet UIView *integrityView;
-@property (weak, nonatomic) IBOutlet UILabel *integrityLabel;
-@property (weak, nonatomic) IBOutlet UIView *integrityValueView;
-@property (weak, nonatomic) IBOutlet NSLayoutConstraint *integrityWidth;
-
-
-@property (weak, nonatomic) IBOutlet UILabel *reportDesc;
-
-@property (weak, nonatomic) IBOutlet UIView *lineView;
-
-@property (nonatomic, copy) EvaluateResultCallback callback;
-
-@property (nonatomic, assign) NSInteger score;
-
-@property (nonatomic, assign) NSInteger intonation;
-
-@property (nonatomic, assign) NSInteger cadence;
-
-@property (nonatomic, assign) NSInteger integrity;
-@end
-
-@implementation EvaluateResultAlert
-
-+ (instancetype)shareInstance {
-    EvaluateResultAlert *view = [[[NSBundle mainBundle] loadNibNamed:@"EvaluateResultAlert" owner:nil options:nil] firstObject];
-    return view;
-}
-
-- (void)configWithScore:(NSInteger)score intonation:(NSInteger)intonation cadence:(NSInteger)cadence integrity:(NSInteger)integrity {
-    self.score = score;
-    self.intonation = intonation;
-    self.cadence = cadence;
-    self.integrity = integrity;
-}
-
-- (void)setScore:(NSInteger)score {
-    _score = score;
-    NSString *desc = @"";
-    NSString *reportMessage = @"";
-    if (score > 80) {
-        desc = @"你很棒";
-        reportMessage = @"你的演奏非常不错,音准的把握和节奏稍有瑕疵,完整性把握的很好~";
-    }
-    else if (score > 60) {
-        desc = @"展露头角";
-        reportMessage = @"你的演奏还不错,继续加油吧,加强音准,离完美就差一步啦~";
-    }
-    else if (score > 40) {
-        desc = @"突破自我";
-        reportMessage = @"你的演奏还不流畅,音准和节奏还需加强,科学的练习才能更完美哦~";
-    }
-    else if (score > 20) {
-        desc = @"还要加油哦~";
-        reportMessage = @"你的演奏还不熟练,音准和完整性还需加强,加紧训练才能有好成绩哦~";
-    }
-    else {
-        desc = @"敢于尝试";
-        reportMessage = @"你的演奏不太好,音准和完整性还需加强,再练一练吧~";
-    }
-    self.scoreLabel.text = [NSString stringWithFormat:@"%zd",score];
-    self.scoreDesc.text = desc;
-
-    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
-    [paragraphStyle setLineSpacing:4];//调整行间距
-    NSMutableAttributedString *attrs = [[NSMutableAttributedString alloc] initWithString:reportMessage attributes:@{NSParagraphStyleAttributeName:paragraphStyle,NSFontAttributeName:[UIFont systemFontOfSize:14.0f],NSForegroundColorAttributeName:HexRGB(0x808080)}];
-    self.reportDesc.attributedText = attrs;
-    
-}
-
-- (void)setIntonation:(NSInteger)intonation {
-    _intonation = intonation;
-    self.intonationScore.text = [NSString stringWithFormat:@"%zd",intonation];
-    [UIView animateWithDuration:0.3f animations:^{
-        self.integrityWidth.constant = 180 * (intonation/100.0f);
-    }];
-}
-
-- (void)setCadence:(NSInteger)cadence {
-    _cadence = cadence;
-    self.rhythmLabel.text = [NSString stringWithFormat:@"%zd",cadence];
-    [UIView animateWithDuration:0.3f animations:^{
-        self.rhythmWidth.constant = 180 * (cadence/100.0f);
-    }];
-}
-
-- (void)setIntegrity:(NSInteger)integrity {
-    _integrity = integrity;
-    self.integrityLabel.text = [NSString stringWithFormat:@"%zd",integrity];
-    [UIView animateWithDuration:0.3f animations:^{
-        self.integrityWidth.constant = 180 * (integrity/100.0f);
-    }];
-}
-
-- (void)resultCallback:(EvaluateResultCallback)callback {
-    if (callback) {
-        self.callback = callback;
-    }
-}
-
-- (IBAction)buttonClickAction:(UIButton *)sender {
-    NSInteger index = sender.tag - 1000;
-    if (self.callback) {
-        self.callback(index);
-    }
-}
-
-
-/*
-// Only override drawRect: if you perform custom drawing.
-// An empty implementation adversely affects performance during animation.
-- (void)drawRect:(CGRect)rect {
-    // Drawing code
-}
-*/
-
-@end

+ 0 - 391
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/TipsAlert/EvaluateResultAlert.xib

@@ -1,391 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
-    <device id="retina6_1" orientation="portrait" appearance="light"/>
-    <dependencies>
-        <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
-        <capability name="System colors in document resources" minToolsVersion="11.0"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
-        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="EvaluateResultAlert">
-            <rect key="frame" x="0.0" y="0.0" width="736" height="454"/>
-            <autoresizingMask key="autoresizingMask"/>
-            <subviews>
-                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kev-3r-AV2">
-                    <rect key="frame" x="95.5" y="24" width="545" height="415"/>
-                    <subviews>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9ti-sU-Ve9">
-                            <rect key="frame" x="181.5" y="0.0" width="363.5" height="415"/>
-                            <subviews>
-                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qHz-48-PaW">
-                                    <rect key="frame" x="18" y="26" width="4" height="18"/>
-                                    <color key="backgroundColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="calibratedRGB"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="18" id="DqZ-My-Ord"/>
-                                        <constraint firstAttribute="width" constant="4" id="hi7-S1-jpO"/>
-                                    </constraints>
-                                    <userDefinedRuntimeAttributes>
-                                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                            <real key="value" value="2"/>
-                                        </userDefinedRuntimeAttribute>
-                                    </userDefinedRuntimeAttributes>
-                                </view>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="智能评分" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="anF-LP-hlF">
-                                    <rect key="frame" x="30" y="24" width="74" height="22"/>
-                                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="18"/>
-                                    <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                                <button opaque="NO" tag="1001" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FA5-n2-FUc">
-                                    <rect key="frame" x="189.5" y="21" width="86" height="28"/>
-                                    <color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.93725490196078431" alpha="1" colorSpace="calibratedRGB"/>
-                                    <constraints>
-                                        <constraint firstAttribute="width" constant="86" id="Cww-TE-rnF"/>
-                                        <constraint firstAttribute="height" constant="28" id="fYt-SX-XQi"/>
-                                    </constraints>
-                                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
-                                    <state key="normal" title="上传到云端">
-                                        <color key="titleColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="calibratedRGB"/>
-                                    </state>
-                                    <userDefinedRuntimeAttributes>
-                                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                            <real key="value" value="14"/>
-                                        </userDefinedRuntimeAttribute>
-                                    </userDefinedRuntimeAttributes>
-                                    <connections>
-                                        <action selector="buttonClickAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="r6c-Zo-YwX"/>
-                                    </connections>
-                                </button>
-                                <button opaque="NO" tag="1002" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aFf-78-FUB">
-                                    <rect key="frame" x="283.5" y="21" width="66" height="28"/>
-                                    <color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.93725490196078431" alpha="1" colorSpace="calibratedRGB"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="28" id="0kj-eU-0Lb"/>
-                                        <constraint firstAttribute="width" constant="66" id="bN8-Zz-1EC"/>
-                                    </constraints>
-                                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
-                                    <state key="normal" title="分享">
-                                        <color key="titleColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="calibratedRGB"/>
-                                    </state>
-                                    <userDefinedRuntimeAttributes>
-                                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                            <real key="value" value="14"/>
-                                        </userDefinedRuntimeAttribute>
-                                    </userDefinedRuntimeAttributes>
-                                    <connections>
-                                        <action selector="buttonClickAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="oxR-3W-4P3"/>
-                                    </connections>
-                                </button>
-                                <button opaque="NO" tag="1003" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="N9k-Lb-OD5">
-                                    <rect key="frame" x="18" y="361" width="103" height="34"/>
-                                    <color key="backgroundColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="calibratedRGB"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="34" id="EAa-IF-fgH"/>
-                                    </constraints>
-                                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
-                                    <state key="normal" title="去练习"/>
-                                    <userDefinedRuntimeAttributes>
-                                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                            <real key="value" value="17"/>
-                                        </userDefinedRuntimeAttribute>
-                                    </userDefinedRuntimeAttributes>
-                                    <connections>
-                                        <action selector="buttonClickAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="sYQ-1S-l5u"/>
-                                    </connections>
-                                </button>
-                                <button opaque="NO" tag="1004" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qqs-xN-SGQ">
-                                    <rect key="frame" x="127" y="361" width="102.5" height="34"/>
-                                    <color key="backgroundColor" red="0.96862745098039216" green="0.57647058823529407" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
-                                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
-                                    <state key="normal" title="再试一次"/>
-                                    <userDefinedRuntimeAttributes>
-                                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                            <real key="value" value="17"/>
-                                        </userDefinedRuntimeAttribute>
-                                    </userDefinedRuntimeAttributes>
-                                    <connections>
-                                        <action selector="buttonClickAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="ufF-E1-csh"/>
-                                    </connections>
-                                </button>
-                                <button opaque="NO" tag="1005" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="EOy-Rm-p6b">
-                                    <rect key="frame" x="235.5" y="361" width="103" height="34"/>
-                                    <color key="backgroundColor" red="0.96862745098039216" green="0.70980392156862748" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
-                                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
-                                    <state key="normal" title="查看报告"/>
-                                    <userDefinedRuntimeAttributes>
-                                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                            <real key="value" value="17"/>
-                                        </userDefinedRuntimeAttribute>
-                                    </userDefinedRuntimeAttributes>
-                                    <connections>
-                                        <action selector="buttonClickAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="Tgi-ZH-3lq"/>
-                                    </connections>
-                                </button>
-                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="B2m-Gc-bZ4">
-                                    <rect key="frame" x="22" y="342" width="316.5" height="1"/>
-                                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="1" id="jbf-7j-0Js"/>
-                                    </constraints>
-                                </view>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="音准" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="u9l-uA-IVQ">
-                                    <rect key="frame" x="24" y="86" width="42" height="17"/>
-                                    <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="13"/>
-                                    <color key="textColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lV9-fw-Fkw">
-                                    <rect key="frame" x="76" y="84" width="180" height="21"/>
-                                    <subviews>
-                                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="d2B-ck-SlX">
-                                            <rect key="frame" x="0.0" y="0.0" width="0.0" height="21"/>
-                                            <color key="backgroundColor" red="0.0039215686274509803" green="0.75686274509803919" blue="0.70980392156862748" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
-                                            <constraints>
-                                                <constraint firstAttribute="width" id="qbr-4x-9un"/>
-                                            </constraints>
-                                        </view>
-                                    </subviews>
-                                    <color key="backgroundColor" red="0.96078431372549022" green="0.95686274509803915" blue="0.94901960784313721" alpha="1" colorSpace="calibratedRGB"/>
-                                    <constraints>
-                                        <constraint firstItem="d2B-ck-SlX" firstAttribute="top" secondItem="lV9-fw-Fkw" secondAttribute="top" id="bDK-RK-k7r"/>
-                                        <constraint firstAttribute="height" constant="21" id="pQa-YV-oev"/>
-                                        <constraint firstItem="d2B-ck-SlX" firstAttribute="leading" secondItem="lV9-fw-Fkw" secondAttribute="leading" id="r2k-1S-L8y"/>
-                                        <constraint firstAttribute="width" constant="180" id="w7S-UX-ntU"/>
-                                        <constraint firstAttribute="bottom" secondItem="d2B-ck-SlX" secondAttribute="bottom" id="wvz-Vs-JQV"/>
-                                    </constraints>
-                                </view>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bCl-zp-NUb">
-                                    <rect key="frame" x="266" y="94.5" width="0.0" height="0.0"/>
-                                    <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
-                                    <color key="textColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="节奏" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Tzk-7k-87s">
-                                    <rect key="frame" x="24" y="131" width="42" height="17"/>
-                                    <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="13"/>
-                                    <color key="textColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="aJS-TL-5oc">
-                                    <rect key="frame" x="76" y="129" width="180" height="21"/>
-                                    <subviews>
-                                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zV2-Tw-oe3">
-                                            <rect key="frame" x="0.0" y="0.0" width="0.0" height="21"/>
-                                            <color key="backgroundColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
-                                            <constraints>
-                                                <constraint firstAttribute="width" id="bs0-i5-6c0"/>
-                                            </constraints>
-                                        </view>
-                                    </subviews>
-                                    <color key="backgroundColor" red="0.96078431369999995" green="0.95686274510000002" blue="0.94901960780000005" alpha="1" colorSpace="calibratedRGB"/>
-                                    <constraints>
-                                        <constraint firstAttribute="bottom" secondItem="zV2-Tw-oe3" secondAttribute="bottom" id="7oR-mW-2GT"/>
-                                        <constraint firstItem="zV2-Tw-oe3" firstAttribute="top" secondItem="aJS-TL-5oc" secondAttribute="top" id="KC3-D9-GxU"/>
-                                        <constraint firstItem="zV2-Tw-oe3" firstAttribute="leading" secondItem="aJS-TL-5oc" secondAttribute="leading" id="fUK-ez-Zmq"/>
-                                    </constraints>
-                                </view>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0PX-DQ-geK">
-                                    <rect key="frame" x="266" y="139.5" width="0.0" height="0.0"/>
-                                    <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
-                                    <color key="textColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="完整性" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="J7e-ik-yVX">
-                                    <rect key="frame" x="24" y="176" width="42" height="17"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="17" id="ME6-xN-Kf8"/>
-                                        <constraint firstAttribute="width" constant="42" id="kzu-60-diG"/>
-                                    </constraints>
-                                    <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="13"/>
-                                    <color key="textColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qd3-W6-ODw">
-                                    <rect key="frame" x="76" y="174" width="180" height="21"/>
-                                    <subviews>
-                                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="aU3-L4-zQd">
-                                            <rect key="frame" x="0.0" y="0.0" width="0.0" height="21"/>
-                                            <color key="backgroundColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
-                                            <constraints>
-                                                <constraint firstAttribute="width" id="adA-kZ-k6W"/>
-                                            </constraints>
-                                        </view>
-                                    </subviews>
-                                    <color key="backgroundColor" red="0.96078431369999995" green="0.95686274510000002" blue="0.94901960780000005" alpha="1" colorSpace="calibratedRGB"/>
-                                    <constraints>
-                                        <constraint firstAttribute="bottom" secondItem="aU3-L4-zQd" secondAttribute="bottom" id="fGq-9o-0er"/>
-                                        <constraint firstItem="aU3-L4-zQd" firstAttribute="leading" secondItem="qd3-W6-ODw" secondAttribute="leading" id="rz6-bU-tJv"/>
-                                        <constraint firstItem="aU3-L4-zQd" firstAttribute="top" secondItem="qd3-W6-ODw" secondAttribute="top" id="yYd-cO-9jL"/>
-                                    </constraints>
-                                </view>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kw3-ma-jdO">
-                                    <rect key="frame" x="266" y="184.5" width="0.0" height="0.0"/>
-                                    <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
-                                    <color key="textColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZnY-N0-3Om">
-                                    <rect key="frame" x="24" y="322" width="321.5" height="0.0"/>
-                                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
-                                    <color key="textColor" red="0.50196078431372548" green="0.50196078431372548" blue="0.50196078431372548" alpha="1" colorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                            </subviews>
-                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                            <constraints>
-                                <constraint firstAttribute="trailing" secondItem="B2m-Gc-bZ4" secondAttribute="trailing" constant="25" id="0Ll-BW-cOb"/>
-                                <constraint firstItem="qqs-xN-SGQ" firstAttribute="width" secondItem="N9k-Lb-OD5" secondAttribute="width" id="0y5-Py-7qm"/>
-                                <constraint firstItem="aJS-TL-5oc" firstAttribute="height" secondItem="lV9-fw-Fkw" secondAttribute="height" id="1PQ-1o-fyY"/>
-                                <constraint firstItem="bCl-zp-NUb" firstAttribute="centerY" secondItem="u9l-uA-IVQ" secondAttribute="centerY" id="1mK-3w-dID"/>
-                                <constraint firstAttribute="trailing" secondItem="EOy-Rm-p6b" secondAttribute="trailing" constant="25" id="4FH-Df-3rl"/>
-                                <constraint firstItem="qqs-xN-SGQ" firstAttribute="height" secondItem="N9k-Lb-OD5" secondAttribute="height" id="5x1-sv-917"/>
-                                <constraint firstItem="qqs-xN-SGQ" firstAttribute="leading" secondItem="N9k-Lb-OD5" secondAttribute="trailing" constant="6" id="6xs-va-Kpg"/>
-                                <constraint firstItem="0PX-DQ-geK" firstAttribute="centerY" secondItem="Tzk-7k-87s" secondAttribute="centerY" id="9Ty-3v-Seg"/>
-                                <constraint firstItem="EOy-Rm-p6b" firstAttribute="leading" secondItem="qqs-xN-SGQ" secondAttribute="trailing" constant="6" id="AnC-5O-ZOv"/>
-                                <constraint firstItem="qHz-48-PaW" firstAttribute="top" secondItem="9ti-sU-Ve9" secondAttribute="top" constant="26" id="Bf4-ai-1BP"/>
-                                <constraint firstItem="qd3-W6-ODw" firstAttribute="leading" secondItem="lV9-fw-Fkw" secondAttribute="leading" id="D2p-Pj-34t"/>
-                                <constraint firstItem="aFf-78-FUB" firstAttribute="centerY" secondItem="anF-LP-hlF" secondAttribute="centerY" id="FCK-yo-Kp9"/>
-                                <constraint firstItem="Tzk-7k-87s" firstAttribute="top" secondItem="u9l-uA-IVQ" secondAttribute="bottom" constant="28" id="H7y-ps-gWy"/>
-                                <constraint firstItem="aFf-78-FUB" firstAttribute="leading" secondItem="FA5-n2-FUc" secondAttribute="trailing" constant="8" id="HUZ-wT-Le6"/>
-                                <constraint firstItem="aJS-TL-5oc" firstAttribute="width" secondItem="lV9-fw-Fkw" secondAttribute="width" id="HhG-Df-wZ4"/>
-                                <constraint firstItem="aJS-TL-5oc" firstAttribute="leading" secondItem="lV9-fw-Fkw" secondAttribute="leading" id="JaX-3z-5Ii"/>
-                                <constraint firstItem="kw3-ma-jdO" firstAttribute="centerY" secondItem="J7e-ik-yVX" secondAttribute="centerY" id="Jsv-0c-3NB"/>
-                                <constraint firstItem="lV9-fw-Fkw" firstAttribute="leading" secondItem="u9l-uA-IVQ" secondAttribute="trailing" constant="10" id="MY4-pt-KZB"/>
-                                <constraint firstItem="N9k-Lb-OD5" firstAttribute="top" secondItem="B2m-Gc-bZ4" secondAttribute="bottom" constant="18" id="MvV-Yg-H1P"/>
-                                <constraint firstItem="qqs-xN-SGQ" firstAttribute="bottom" secondItem="N9k-Lb-OD5" secondAttribute="bottom" id="NgX-Kg-1IT"/>
-                                <constraint firstAttribute="bottom" secondItem="N9k-Lb-OD5" secondAttribute="bottom" constant="20" id="P4h-rt-go9"/>
-                                <constraint firstItem="kw3-ma-jdO" firstAttribute="leading" secondItem="bCl-zp-NUb" secondAttribute="leading" id="Qwk-k1-LwN"/>
-                                <constraint firstItem="Tzk-7k-87s" firstAttribute="height" secondItem="u9l-uA-IVQ" secondAttribute="height" id="StV-Ao-1YB"/>
-                                <constraint firstItem="Tzk-7k-87s" firstAttribute="trailing" secondItem="u9l-uA-IVQ" secondAttribute="trailing" id="Tjh-Ib-jqQ"/>
-                                <constraint firstAttribute="trailing" secondItem="ZnY-N0-3Om" secondAttribute="trailing" constant="18" id="TsD-QX-8Vh"/>
-                                <constraint firstItem="J7e-ik-yVX" firstAttribute="top" secondItem="Tzk-7k-87s" secondAttribute="bottom" constant="28" id="V46-Hp-dso"/>
-                                <constraint firstItem="Tzk-7k-87s" firstAttribute="width" secondItem="u9l-uA-IVQ" secondAttribute="width" id="Vem-uQ-w6K"/>
-                                <constraint firstItem="J7e-ik-yVX" firstAttribute="trailing" secondItem="u9l-uA-IVQ" secondAttribute="trailing" id="YCn-51-m0o"/>
-                                <constraint firstItem="N9k-Lb-OD5" firstAttribute="leading" secondItem="9ti-sU-Ve9" secondAttribute="leading" constant="18" id="Ygk-CA-dmb"/>
-                                <constraint firstItem="anF-LP-hlF" firstAttribute="leading" secondItem="qHz-48-PaW" secondAttribute="trailing" constant="8" id="ZWk-LI-a0b"/>
-                                <constraint firstItem="bCl-zp-NUb" firstAttribute="leading" secondItem="lV9-fw-Fkw" secondAttribute="trailing" constant="10" id="a9o-Fa-wbA"/>
-                                <constraint firstItem="0PX-DQ-geK" firstAttribute="leading" secondItem="bCl-zp-NUb" secondAttribute="leading" id="aaD-pL-Tdx"/>
-                                <constraint firstItem="EOy-Rm-p6b" firstAttribute="width" secondItem="N9k-Lb-OD5" secondAttribute="width" id="b6b-G0-aw3"/>
-                                <constraint firstItem="EOy-Rm-p6b" firstAttribute="bottom" secondItem="N9k-Lb-OD5" secondAttribute="bottom" id="cew-ZA-UoY"/>
-                                <constraint firstItem="J7e-ik-yVX" firstAttribute="height" secondItem="u9l-uA-IVQ" secondAttribute="height" id="dUV-3d-78J"/>
-                                <constraint firstItem="qd3-W6-ODw" firstAttribute="height" secondItem="lV9-fw-Fkw" secondAttribute="height" id="dXq-wT-uiN"/>
-                                <constraint firstItem="u9l-uA-IVQ" firstAttribute="top" secondItem="anF-LP-hlF" secondAttribute="bottom" constant="40" id="eBH-Kl-b0w"/>
-                                <constraint firstItem="qd3-W6-ODw" firstAttribute="centerY" secondItem="J7e-ik-yVX" secondAttribute="centerY" id="fZs-U9-5oF"/>
-                                <constraint firstItem="B2m-Gc-bZ4" firstAttribute="top" secondItem="ZnY-N0-3Om" secondAttribute="bottom" constant="20" id="hee-RI-XsM"/>
-                                <constraint firstItem="qd3-W6-ODw" firstAttribute="width" secondItem="lV9-fw-Fkw" secondAttribute="width" id="ifa-aV-FqI"/>
-                                <constraint firstAttribute="trailing" secondItem="aFf-78-FUB" secondAttribute="trailing" constant="14" id="k3w-ZR-Clf"/>
-                                <constraint firstItem="anF-LP-hlF" firstAttribute="centerY" secondItem="qHz-48-PaW" secondAttribute="centerY" id="kY3-jz-wOn"/>
-                                <constraint firstItem="J7e-ik-yVX" firstAttribute="width" secondItem="u9l-uA-IVQ" secondAttribute="width" id="lnf-vz-BTx"/>
-                                <constraint firstItem="FA5-n2-FUc" firstAttribute="centerY" secondItem="anF-LP-hlF" secondAttribute="centerY" id="n3R-a3-rrN"/>
-                                <constraint firstItem="EOy-Rm-p6b" firstAttribute="height" secondItem="N9k-Lb-OD5" secondAttribute="height" id="nRz-Ve-yEn"/>
-                                <constraint firstItem="aJS-TL-5oc" firstAttribute="centerY" secondItem="Tzk-7k-87s" secondAttribute="centerY" id="o2E-z3-pga"/>
-                                <constraint firstItem="B2m-Gc-bZ4" firstAttribute="leading" secondItem="9ti-sU-Ve9" secondAttribute="leading" constant="22" id="qfD-HZ-Ru4"/>
-                                <constraint firstItem="lV9-fw-Fkw" firstAttribute="centerY" secondItem="u9l-uA-IVQ" secondAttribute="centerY" id="r6X-cJ-CxD"/>
-                                <constraint firstItem="J7e-ik-yVX" firstAttribute="leading" secondItem="9ti-sU-Ve9" secondAttribute="leading" constant="24" id="rj2-MB-Xkx"/>
-                                <constraint firstItem="ZnY-N0-3Om" firstAttribute="leading" secondItem="9ti-sU-Ve9" secondAttribute="leading" constant="24" id="vVX-Um-Wsa"/>
-                                <constraint firstItem="qHz-48-PaW" firstAttribute="leading" secondItem="9ti-sU-Ve9" secondAttribute="leading" constant="18" id="yQQ-hp-WN0"/>
-                            </constraints>
-                        </view>
-                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="evaluate_logo" translatesAutoresizingMaskIntoConstraints="NO" id="clo-Lu-5re">
-                            <rect key="frame" x="14" y="62" width="145.5" height="143.5"/>
-                            <constraints>
-                                <constraint firstAttribute="width" secondItem="clo-Lu-5re" secondAttribute="height" multiplier="145:143" id="R5I-oV-F9j"/>
-                            </constraints>
-                        </imageView>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fjf-Cx-HBS">
-                            <rect key="frame" x="75" y="215.5" width="0.0" height="0.0"/>
-                            <fontDescription key="fontDescription" type="boldSystem" pointSize="38"/>
-                            <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                            <nil key="highlightedColor"/>
-                        </label>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Qbk-ED-W1i">
-                            <rect key="frame" x="87" y="215.5" width="0.0" height="0.0"/>
-                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="23"/>
-                            <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                            <nil key="highlightedColor"/>
-                        </label>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="分" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9eP-w3-Oz4">
-                            <rect key="frame" x="75" y="180.5" width="24" height="28"/>
-                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="23"/>
-                            <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                            <nil key="highlightedColor"/>
-                        </label>
-                    </subviews>
-                    <color key="backgroundColor" red="0.0039215686274509803" green="0.75686274509803919" blue="0.70980392156862748" alpha="1" colorSpace="calibratedRGB"/>
-                    <constraints>
-                        <constraint firstItem="9eP-w3-Oz4" firstAttribute="leading" secondItem="fjf-Cx-HBS" secondAttribute="trailing" id="50u-Cc-Ao9"/>
-                        <constraint firstItem="clo-Lu-5re" firstAttribute="leading" secondItem="kev-3r-AV2" secondAttribute="leading" constant="14" id="9wJ-QD-J4c"/>
-                        <constraint firstAttribute="bottom" secondItem="9ti-sU-Ve9" secondAttribute="bottom" id="Eyh-rc-wKX"/>
-                        <constraint firstItem="clo-Lu-5re" firstAttribute="top" secondItem="kev-3r-AV2" secondAttribute="top" constant="62" id="F5F-QP-1Q4"/>
-                        <constraint firstItem="9ti-sU-Ve9" firstAttribute="leading" secondItem="clo-Lu-5re" secondAttribute="trailing" constant="22" id="HJO-Yz-Sj6"/>
-                        <constraint firstAttribute="width" constant="545" id="PBs-mS-Jsg"/>
-                        <constraint firstItem="9ti-sU-Ve9" firstAttribute="leading" secondItem="kev-3r-AV2" secondAttribute="centerX" multiplier="2/3" id="Pz9-QB-6ac"/>
-                        <constraint firstItem="Qbk-ED-W1i" firstAttribute="centerX" secondItem="clo-Lu-5re" secondAttribute="centerX" id="RSO-m9-77y"/>
-                        <constraint firstItem="fjf-Cx-HBS" firstAttribute="centerX" secondItem="clo-Lu-5re" secondAttribute="centerX" constant="-12" id="VRl-jd-YiN"/>
-                        <constraint firstItem="9eP-w3-Oz4" firstAttribute="bottom" secondItem="fjf-Cx-HBS" secondAttribute="bottom" constant="-7" id="bm0-jX-3Sx"/>
-                        <constraint firstItem="9ti-sU-Ve9" firstAttribute="top" secondItem="kev-3r-AV2" secondAttribute="top" id="h7j-uV-HOs"/>
-                        <constraint firstItem="Qbk-ED-W1i" firstAttribute="top" secondItem="fjf-Cx-HBS" secondAttribute="bottom" id="ioQ-H8-Dhi"/>
-                        <constraint firstAttribute="trailing" secondItem="9ti-sU-Ve9" secondAttribute="trailing" id="jdw-Gv-9To"/>
-                        <constraint firstItem="fjf-Cx-HBS" firstAttribute="top" secondItem="clo-Lu-5re" secondAttribute="bottom" constant="10" id="zL2-rC-Vbr"/>
-                    </constraints>
-                    <userDefinedRuntimeAttributes>
-                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                            <real key="value" value="20"/>
-                        </userDefinedRuntimeAttribute>
-                    </userDefinedRuntimeAttributes>
-                </view>
-                <button opaque="NO" tag="1000" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ECe-lf-Wo6">
-                    <rect key="frame" x="640.5" y="2" width="44" height="44"/>
-                    <constraints>
-                        <constraint firstAttribute="height" constant="44" id="72Y-ys-SLx"/>
-                        <constraint firstAttribute="width" constant="44" id="BEV-8f-Nl5"/>
-                    </constraints>
-                    <state key="normal" image="cloud_cancle"/>
-                    <connections>
-                        <action selector="buttonClickAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="rhv-1p-kya"/>
-                    </connections>
-                </button>
-            </subviews>
-            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.52000000000000002" colorSpace="custom" customColorSpace="calibratedRGB"/>
-            <constraints>
-                <constraint firstAttribute="bottom" secondItem="kev-3r-AV2" secondAttribute="bottom" constant="15" id="8Zy-2w-zN8"/>
-                <constraint firstItem="ECe-lf-Wo6" firstAttribute="centerY" secondItem="kev-3r-AV2" secondAttribute="top" id="DUE-TX-w7J"/>
-                <constraint firstItem="kev-3r-AV2" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="QaD-fh-unz"/>
-                <constraint firstItem="kev-3r-AV2" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="24" id="hYe-gN-0u7"/>
-                <constraint firstItem="ECe-lf-Wo6" firstAttribute="leading" secondItem="kev-3r-AV2" secondAttribute="trailing" id="tdE-sB-9hR"/>
-            </constraints>
-            <nil key="simulatedTopBarMetrics"/>
-            <nil key="simulatedBottomBarMetrics"/>
-            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
-            <connections>
-                <outlet property="integrityLabel" destination="kw3-ma-jdO" id="7D9-hn-DGT"/>
-                <outlet property="integrityValueView" destination="aU3-L4-zQd" id="qik-rX-eB1"/>
-                <outlet property="integrityView" destination="qd3-W6-ODw" id="boe-4l-XqJ"/>
-                <outlet property="integrityWidth" destination="adA-kZ-k6W" id="tiT-Fe-MM1"/>
-                <outlet property="intonationScore" destination="bCl-zp-NUb" id="erm-vk-XsR"/>
-                <outlet property="intonationValueView" destination="d2B-ck-SlX" id="0Jy-Ok-czQ"/>
-                <outlet property="intonationView" destination="lV9-fw-Fkw" id="fYQ-vK-OgC"/>
-                <outlet property="intonationWidth" destination="qbr-4x-9un" id="59O-c4-FDQ"/>
-                <outlet property="lineView" destination="B2m-Gc-bZ4" id="dWv-E0-YIg"/>
-                <outlet property="reportDesc" destination="ZnY-N0-3Om" id="Mtw-T0-rVh"/>
-                <outlet property="rhyhtmVauleView" destination="zV2-Tw-oe3" id="kEh-Ed-MHt"/>
-                <outlet property="rhythmLabel" destination="0PX-DQ-geK" id="b3m-fm-MtQ"/>
-                <outlet property="rhythmView" destination="aJS-TL-5oc" id="7dF-52-tZH"/>
-                <outlet property="rhythmWidth" destination="bs0-i5-6c0" id="2MX-1r-sJX"/>
-                <outlet property="scoreDesc" destination="Qbk-ED-W1i" id="BUa-zv-opz"/>
-                <outlet property="scoreLabel" destination="fjf-Cx-HBS" id="cyy-jn-IRU"/>
-            </connections>
-            <point key="canvasLocation" x="-49.275362318840585" y="-4.0178571428571423"/>
-        </view>
-    </objects>
-    <resources>
-        <image name="cloud_cancle" width="26" height="26"/>
-        <image name="evaluate_logo" width="166" height="143"/>
-        <systemColor name="systemBackgroundColor">
-            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-        </systemColor>
-    </resources>
-</document>

+ 0 - 22
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/TipsAlert/NoWiredTipsAlert.h

@@ -1,22 +0,0 @@
-//
-//  NoWiredTipsAlert.h
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/12.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-typedef void(^CheckWiredCallback)(void);
-
-@interface NoWiredTipsAlert : UIView
-
-+ (instancetype)shareInstance;
-
-- (void)showAlertInView:(UIView *)displayView callback:(CheckWiredCallback)callback;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 49
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/TipsAlert/NoWiredTipsAlert.m

@@ -1,49 +0,0 @@
-//
-//  NoWiredTipsAlert.m
-//  StudentDaya
-//
-//  Created by Kyle on 2021/12/12.
-//  Copyright © 2021 DayaMusic. All rights reserved.
-//
-
-#import "NoWiredTipsAlert.h"
-
-@interface NoWiredTipsAlert ()
-
-@property (nonatomic, copy) CheckWiredCallback callback;
-
-@end
-
-@implementation NoWiredTipsAlert
-
-+ (instancetype)shareInstance {
-    NoWiredTipsAlert *alert = [[[NSBundle mainBundle] loadNibNamed:@"NoWiredTipsAlert" owner:nil options:nil] firstObject];
-    return alert;
-}
-
-- (void)showAlertInView:(UIView *)displayView callback:(nonnull CheckWiredCallback)callback {
-    if (callback) {
-        self.callback = callback;
-    }
-    [displayView addSubview:self];
-}
-
-- (void)hiddenView {
-    [self removeFromSuperview];
-}
-- (IBAction)hiddenAlert:(id)sender {
-    [self hiddenView];
-    if (self.callback) {
-        self.callback();
-    }
-}
-
-/*
-// Only override drawRect: if you perform custom drawing.
-// An empty implementation adversely affects performance during animation.
-- (void)drawRect:(CGRect)rect {
-    // Drawing code
-}
-*/
-
-@end

+ 0 - 121
KulexiuForStudent/KulexiuForStudent/Module/CloudEngine/View/TipsAlert/NoWiredTipsAlert.xib

@@ -1,121 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
-    <device id="retina6_1" orientation="portrait" appearance="light"/>
-    <dependencies>
-        <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
-        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
-        <capability name="System colors in document resources" minToolsVersion="11.0"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
-        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="NoWiredTipsAlert">
-            <rect key="frame" x="0.0" y="0.0" width="663" height="423"/>
-            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-            <subviews>
-                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ah5-xM-cyD">
-                    <rect key="frame" x="199.5" y="86.5" width="264" height="250"/>
-                    <subviews>
-                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="evaluate_logo" translatesAutoresizingMaskIntoConstraints="NO" id="qZY-An-3Kg">
-                            <rect key="frame" x="49" y="30" width="166" height="143"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="143" id="3in-lr-fgk"/>
-                                <constraint firstAttribute="width" constant="166" id="IFQ-Q4-07P"/>
-                            </constraints>
-                        </imageView>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="请佩戴耳机以保证测评准确率~" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ww5-Ot-JpL">
-                            <rect key="frame" x="32" y="169" width="200" height="17"/>
-                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
-                            <color key="textColor" red="0.50196078430000002" green="0.50196078430000002" blue="0.50196078430000002" alpha="1" colorSpace="calibratedRGB"/>
-                            <nil key="highlightedColor"/>
-                        </label>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="psJ-YC-Q92">
-                            <rect key="frame" x="74.5" y="198" width="115" height="34"/>
-                            <color key="backgroundColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="calibratedRGB"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="34" id="Zgp-9F-Slx"/>
-                                <constraint firstAttribute="width" constant="115" id="pxl-hG-rB3"/>
-                            </constraints>
-                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
-                            <state key="normal" title="我知道了"/>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                    <real key="value" value="17"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                            <connections>
-                                <action selector="hiddenAlert:" destination="iN0-l3-epB" eventType="touchUpInside" id="3Qo-d6-rzW"/>
-                            </connections>
-                        </button>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="M3R-Ao-jkS">
-                            <rect key="frame" x="224" y="0.0" width="40" height="40"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="40" id="2jV-nA-GNI"/>
-                                <constraint firstAttribute="width" constant="40" id="YUL-Dj-pqb"/>
-                            </constraints>
-                            <state key="normal" image="check_cancle"/>
-                            <connections>
-                                <action selector="hiddenAlert:" destination="iN0-l3-epB" eventType="touchUpInside" id="e5e-J3-AiO"/>
-                            </connections>
-                        </button>
-                    </subviews>
-                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                    <constraints>
-                        <constraint firstItem="qZY-An-3Kg" firstAttribute="top" secondItem="ah5-xM-cyD" secondAttribute="top" constant="30" id="De8-6b-L70"/>
-                        <constraint firstAttribute="height" constant="250" id="KeG-CA-jys"/>
-                        <constraint firstItem="psJ-YC-Q92" firstAttribute="top" secondItem="Ww5-Ot-JpL" secondAttribute="bottom" constant="12" id="Qgm-um-k6z"/>
-                        <constraint firstAttribute="bottom" secondItem="psJ-YC-Q92" secondAttribute="bottom" constant="18" id="UCm-R8-q2q"/>
-                        <constraint firstAttribute="width" constant="264" id="bhW-0f-M08"/>
-                        <constraint firstItem="qZY-An-3Kg" firstAttribute="centerX" secondItem="ah5-xM-cyD" secondAttribute="centerX" id="jQI-en-d6F"/>
-                        <constraint firstAttribute="trailing" secondItem="M3R-Ao-jkS" secondAttribute="trailing" id="rNj-l9-iuh"/>
-                        <constraint firstItem="psJ-YC-Q92" firstAttribute="centerX" secondItem="ah5-xM-cyD" secondAttribute="centerX" id="uAS-Rq-Oqx"/>
-                        <constraint firstItem="M3R-Ao-jkS" firstAttribute="top" secondItem="ah5-xM-cyD" secondAttribute="top" id="w48-wT-LqO"/>
-                        <constraint firstItem="Ww5-Ot-JpL" firstAttribute="centerX" secondItem="ah5-xM-cyD" secondAttribute="centerX" id="zJm-80-LOi"/>
-                    </constraints>
-                    <userDefinedRuntimeAttributes>
-                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                            <real key="value" value="20"/>
-                        </userDefinedRuntimeAttribute>
-                    </userDefinedRuntimeAttributes>
-                </view>
-                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="image_alertTips" translatesAutoresizingMaskIntoConstraints="NO" id="8aD-n1-PzY">
-                    <rect key="frame" x="277.5" y="82.5" width="108" height="31"/>
-                    <constraints>
-                        <constraint firstAttribute="width" constant="108" id="1s5-7T-qTb"/>
-                        <constraint firstAttribute="height" constant="31" id="mJd-Tf-sEM"/>
-                    </constraints>
-                </imageView>
-                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="提示" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yjg-xn-pKL">
-                    <rect key="frame" x="315" y="88" width="33" height="20"/>
-                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
-                    <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                    <nil key="highlightedColor"/>
-                </label>
-            </subviews>
-            <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
-            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
-            <constraints>
-                <constraint firstItem="8aD-n1-PzY" firstAttribute="top" secondItem="ah5-xM-cyD" secondAttribute="top" constant="-4" id="0PS-g0-dfi"/>
-                <constraint firstItem="yjg-xn-pKL" firstAttribute="centerX" secondItem="8aD-n1-PzY" secondAttribute="centerX" id="Py6-YQ-Ghs"/>
-                <constraint firstItem="ah5-xM-cyD" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="Uql-9x-IBE"/>
-                <constraint firstItem="yjg-xn-pKL" firstAttribute="centerY" secondItem="8aD-n1-PzY" secondAttribute="centerY" id="b07-Ty-0MM"/>
-                <constraint firstItem="8aD-n1-PzY" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="nAr-bf-6o6"/>
-                <constraint firstItem="ah5-xM-cyD" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="qI8-qZ-zsf"/>
-            </constraints>
-            <nil key="simulatedTopBarMetrics"/>
-            <nil key="simulatedBottomBarMetrics"/>
-            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
-            <point key="canvasLocation" x="136.95652173913044" y="-88.727678571428569"/>
-        </view>
-    </objects>
-    <resources>
-        <image name="check_cancle" width="14" height="14"/>
-        <image name="evaluate_logo" width="166" height="143"/>
-        <image name="image_alertTips" width="108" height="31"/>
-        <systemColor name="systemBackgroundColor">
-            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-        </systemColor>
-    </resources>
-</document>

+ 28 - 16
KulexiuForStudent/KulexiuForStudent/Module/Course/AccompanyCourse/Controller/AccompanyDetailViewController.m

@@ -592,25 +592,37 @@
 
 // 加入房间
 - (void)joinClassRoom {
+    
     // 加入房间前判断摄像头和麦克风逻辑
-    PREMISSIONTYPE micEnable = [RecordCheckManager checkMicPermissionAvaiable];
-    PREMISSIONTYPE cameraEnable = [RecordCheckManager checkCameraPremissionAvaiable];
-    if (micEnable == PREMISSIONTYPE_YES && cameraEnable == PREMISSIONTYPE_YES) {
-        // 进入教室
-        // 判断是否进行课前检测
-        [self.classManager joinRoomWithId:self.courseId subjectName:self.homeworkModel.subjectName classEndTime:self.homeworkModel.endTime inViewController:self];
-    }
-    else {
-        if (micEnable == PREMISSIONTYPE_NO && cameraEnable == PREMISSIONTYPE_NO) { // 如果麦克风权限和摄像头权限都没有
-            [self showAlertWithMessage:@"请开启相机和麦克风访问权限" type:CHECKDEVICETYPE_BOTH];
-        }
-        else if (micEnable == PREMISSIONTYPE_NO) { // 如果没有麦克风权限
-            [self showAlertWithMessage:@"请开启麦克风访问权限" type:CHECKDEVICETYPE_MIC];
+    [RecordCheckManager checkCameraPremissionAvaiableCallback:^(PREMISSIONTYPE type) {
+        [self afterCheckCameraCheckMic:type];
+    }];
+}
+
+- (void)afterCheckCameraCheckMic:(PREMISSIONTYPE)cameraType {
+    [RecordCheckManager checkMicPermissionAvaiableCallback:^(PREMISSIONTYPE type) {
+        if (type == PREMISSIONTYPE_YES && cameraType == PREMISSIONTYPE_YES) {
+            // 判断是否进行课前检测
+            [self.classManager joinRoomWithId:self.courseId subjectName:self.homeworkModel.subjectName classEndTime:self.homeworkModel.endTime inViewController:self];
         }
-        else if (cameraEnable == PREMISSIONTYPE_NO) { // 如果没有摄像头权限
-            [self showAlertWithMessage:@"请开启相机访问权限" type:CHECKDEVICETYPE_CAMREA];
+        else {
+            NSString *content = @"";
+            CHECKDEVICETYPE checkType = CHECKDEVICETYPE_BOTH;
+            if (cameraType == PREMISSIONTYPE_NO && type == PREMISSIONTYPE_NO) {
+                content = @"请开启相机和麦克风访问权限";
+                checkType = CHECKDEVICETYPE_BOTH;
+            }
+            else if (cameraType == PREMISSIONTYPE_NO && type == PREMISSIONTYPE_YES) {
+                content =  @"请开启相机访问权限";
+                checkType = CHECKDEVICETYPE_CAMREA;
+            }
+            else if (cameraType == PREMISSIONTYPE_YES && type == PREMISSIONTYPE_NO) {
+                content = @"请开启麦克风访问权限";
+                checkType = CHECKDEVICETYPE_MIC;
+            }
+            [self showAlertWithMessage:content type:checkType];
         }
-    }
+    }];    
 }
 
 - (void)showAlertWithMessage:(NSString *)message type:(CHECKDEVICETYPE)deviceType {

+ 28 - 17
KulexiuForStudent/KulexiuForStudent/Module/Course/MusicRoom/Controller/MusicRoomDetailViewController.m

@@ -515,26 +515,37 @@
 // 加入房间
 - (void)joinClassRoom {
     // 加入房间前判断摄像头和麦克风逻辑
-    PREMISSIONTYPE micEnable = [RecordCheckManager checkMicPermissionAvaiable];
-    PREMISSIONTYPE cameraEnable = [RecordCheckManager checkPhotoLibraryPremissionAvaiable];
-    if (micEnable == PREMISSIONTYPE_YES && cameraEnable == PREMISSIONTYPE_YES) {
-        // 进入教室
-        // 判断是否进行课前检测
-        [self.classManager joinRoomWithId:self.courseId subjectName:self.homeworkModel.subjectName classEndTime:self.homeworkModel.endTime inViewController:self];
-    }
-    else {
-        if (micEnable == PREMISSIONTYPE_NO && cameraEnable == PREMISSIONTYPE_NO) { // 如果麦克风权限和摄像头权限都没有
-            [self showAlertWithMessage:@"请开启相机和麦克风访问权限" type:CHECKDEVICETYPE_BOTH];
-        }
-        else if (micEnable == PREMISSIONTYPE_NO) { // 如果没有麦克风权限
-            [self showAlertWithMessage:@"请开启麦克风访问权限" type:CHECKDEVICETYPE_MIC];
+    [RecordCheckManager checkCameraPremissionAvaiableCallback:^(PREMISSIONTYPE type) {
+        [self afterCheckCameraCheckMic:type];
+    }];
+}
+
+- (void)afterCheckCameraCheckMic:(PREMISSIONTYPE)cameraType {
+    [RecordCheckManager checkMicPermissionAvaiableCallback:^(PREMISSIONTYPE type) {
+        if (type == PREMISSIONTYPE_YES && cameraType == PREMISSIONTYPE_YES) {
+            // 判断是否进行课前检测
+            [self.classManager joinRoomWithId:self.courseId subjectName:self.homeworkModel.subjectName classEndTime:self.homeworkModel.endTime inViewController:self];
         }
-        else if (cameraEnable == PREMISSIONTYPE_NO) { // 如果没有摄像头权限
-            [self showAlertWithMessage:@"请开启相机访问权限" type:CHECKDEVICETYPE_CAMREA];
+        else {
+            NSString *content = @"";
+            CHECKDEVICETYPE checkType = CHECKDEVICETYPE_BOTH;
+            if (cameraType == PREMISSIONTYPE_NO && type == PREMISSIONTYPE_NO) {
+                content = @"请开启相机和麦克风访问权限";
+                checkType = CHECKDEVICETYPE_BOTH;
+            }
+            else if (cameraType == PREMISSIONTYPE_NO && type == PREMISSIONTYPE_YES) {
+                content =  @"请开启相机访问权限";
+                checkType = CHECKDEVICETYPE_CAMREA;
+            }
+            else if (cameraType == PREMISSIONTYPE_YES && type == PREMISSIONTYPE_NO) {
+                content = @"请开启麦克风访问权限";
+                checkType = CHECKDEVICETYPE_MIC;
+            }
+            [self showAlertWithMessage:content type:checkType];
         }
-    }
+    }];
+    
 }
-
 - (void)showAlertWithMessage:(NSString *)message type:(CHECKDEVICETYPE)deviceType {
     [KSPremissionAlert shareInstanceDisplayImage:deviceType message:message showInView:self.view cancel:^{
         

+ 7 - 8
KulexiuForStudent/KulexiuForStudent/Module/Home/Controller/HomeViewController.m

@@ -1598,16 +1598,15 @@
 
 - (void)showScanView {
     // 判断是否有权限
-    PREMISSIONTYPE albumEnable = [RecordCheckManager checkCameraPremissionAvaiable];
-    if (albumEnable == PREMISSIONTYPE_YES) { // 如果有权限
-        KSScanViewController *ctrl = [[KSScanViewController alloc] init];
-        [self.navigationController pushViewController:ctrl animated:YES];
-    }
-    else {
-        if (albumEnable == PREMISSIONTYPE_NO) {
+    [RecordCheckManager checkCameraPremissionAvaiableCallback:^(PREMISSIONTYPE type) {
+        if (type == PREMISSIONTYPE_YES) {
+            KSScanViewController *ctrl = [[KSScanViewController alloc] init];
+            [self.navigationController pushViewController:ctrl animated:YES];
+        }
+        else {
             [self showAlertWithMessage:@"请开启相机访问权限" type:CHECKDEVICETYPE_CAMREA];
         }
-    }
+    }];
 }
 
 - (dispatch_group_t)requestGroup {

+ 7 - 8
KulexiuForStudent/KulexiuForStudent/Module/Mine/Controller/MineViewController.m

@@ -284,16 +284,15 @@
 
 - (void)scanAction {
     // 判断是否有权限
-    PREMISSIONTYPE albumEnable = [RecordCheckManager checkCameraPremissionAvaiable];
-    if (albumEnable == PREMISSIONTYPE_YES) { // 如果有权限
-        KSScanViewController *ctrl = [[KSScanViewController alloc] init];
-        [self.navigationController pushViewController:ctrl animated:YES];
-    }
-    else {
-        if (albumEnable == PREMISSIONTYPE_NO) {
+    [RecordCheckManager checkCameraPremissionAvaiableCallback:^(PREMISSIONTYPE type) {
+        if (type == PREMISSIONTYPE_YES) {
+            KSScanViewController *ctrl = [[KSScanViewController alloc] init];
+            [self.navigationController pushViewController:ctrl animated:YES];
+        }
+        else {
             [self showAlertWithMessage:@"请开启相机访问权限" type:CHECKDEVICETYPE_CAMREA];
         }
-    }
+    }];
 }
 
 - (void)showAlertWithMessage:(NSString *)message type:(CHECKDEVICETYPE)deviceType {

+ 6 - 8
KulexiuForStudent/KulexiuForStudent/Module/Mine/Scan/Controller/KSScanViewController.m

@@ -154,16 +154,14 @@
     }
     else {  // 选择相册
         // 判断是否有权限
-        PREMISSIONTYPE albumEnable = [RecordCheckManager checkPhotoLibraryPremissionAvaiable];
-        if (albumEnable == PREMISSIONTYPE_YES) { // 如果有权限
-            [self choosePhoneScan];
-        }
-        else {
-            if (albumEnable == PREMISSIONTYPE_NO) {
+        [RecordCheckManager checkPhotoLibraryPremissionAvaiableCallback:^(PREMISSIONTYPE type) {
+            if (type == PREMISSIONTYPE_YES) {
+                [self choosePhoneScan];
+            }
+            else {
                 [self showAlertWithMessage:@"请开启相册访问权限" type:CHECKDEVICETYPE_CAMREA];
             }
-        }
-        
+        }];
     }
 }
 - (void)showAlertWithMessage:(NSString *)message type:(CHECKDEVICETYPE)deviceType {

BIN
KulexiuForStudent/KulexiuForStudent/ToolKit/CloudAccompanyLibrary.framework/CloudAccompanyLibrary


+ 34 - 0
KulexiuForStudent/KulexiuForStudent/ToolKit/CloudAccompanyLibrary.framework/Headers/KSCloudWebViewController.h

@@ -10,6 +10,13 @@
 #import <KSToolLibrary/WeakWebViewScriptMessageDelegate.h>
 #import <KSToolLibrary/UINavigationController+KSNavigationBar.h>
 
+typedef NS_ENUM(NSInteger, CHECK_DELAY_TYPE) {
+    CHECK_DELAY_TYPE_START,
+    CHECK_DELAY_TYPE_FAILED,  // 失败
+    CHECK_DELAY_TYPE_SUCCESS, // 成功
+    CHECK_DELAY_TYPE_CANCEL,  // 取消延迟检测流程
+};
+
 @class KSCloudWebViewController;
 
 @protocol KSCloudWebViewControllerDelegate <NSObject>
@@ -40,6 +47,16 @@
 // 错误上报回调 ,额外需填写当前版本
 - (void)cloudPageOccourError:(NSMutableDictionary *_Nonnull)uploadParm;
 
+
+#pragma mark ----- 延迟检测相关
+// 显示延迟检测
+- (void)showDelayCheckViewDisplay:(UIView *_Nonnull)displayView callBackController:(KSCloudWebViewController *_Nonnull)controller;
+// 修改检测状态
+- (void)changeDelayCheckStatus:(CHECK_DELAY_TYPE)checkStatus;
+// 回调当前耳机状态
+- (void)displayCurrentHeadsetTypes:(NSDictionary *_Nonnull)parm;
+// socket连接成功回调
+- (void)socketConnectedCallback;
 @end
 
 NS_ASSUME_NONNULL_BEGIN
@@ -81,6 +98,23 @@ NS_ASSUME_NONNULL_BEGIN
 
 // 合成完成后回调
 - (void)musicPublishCallBack;
+// 重播
+- (void)retryEvaluatingMusic;
+
+- (void)checkAudioType;
+// socket是否连接上
+- (BOOL)isSocketConnected;
+
+// 开始App延迟检测
+- (void)startAppDelayCheck;
+// 取消延迟检测流程
+- (void)cancelAppDelayCheck;
+// 延迟检测中断
+- (void)checkDelayBreak;
+
+- (void)finishDelayCheck;
+
+- (void)connectSocket;
 
 @end
 

BIN
KulexiuForStudent/KulexiuForStudent/ToolKit/CloudAccompanyLibrary.framework/_CodeSignature/CodeDirectory


BIN
KulexiuForStudent/KulexiuForStudent/ToolKit/CloudAccompanyLibrary.framework/_CodeSignature/CodeRequirements-1


+ 3 - 3
KulexiuForStudent/KulexiuForStudent/ToolKit/CloudAccompanyLibrary.framework/_CodeSignature/CodeResources

@@ -58,7 +58,7 @@
 		</data>
 		<key>Headers/KSCloudWebViewController.h</key>
 		<data>
-		pZOk0rtmzLtLAH9cSM9y5V6aZ/k=
+		zdPduXm8/0MzlDLm3KlHZ6du4GI=
 		</data>
 		<key>Headers/KSVideoRecordManager.h</key>
 		<data>
@@ -222,11 +222,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			pZOk0rtmzLtLAH9cSM9y5V6aZ/k=
+			zdPduXm8/0MzlDLm3KlHZ6du4GI=
 			</data>
 			<key>hash2</key>
 			<data>
-			RO0ZS6NoI6TZn40r/kX+ncngS2X+PI+xR65M5qT1qUs=
+			UT4btEVKKOf+tZgqaS8Lp6gJWWQh+a6BsV/MWK1hAuQ=
 			</data>
 		</dict>
 		<key>Headers/KSVideoRecordManager.h</key>

BIN
KulexiuForStudent/KulexiuForStudent/ToolKit/CloudAccompanyLibrary.framework/_CodeSignature/CodeSignature


+ 0 - 1
KulexiuForStudent/KulexiuForStudent/ToolKit/KSToolLibrary.framework/Headers/KSAQRecordManager.h

@@ -9,7 +9,6 @@
 #import <Foundation/Foundation.h>
 #import <KSToolLibrary/KSAudioSessionManager.h>
 
-
 NS_ASSUME_NONNULL_BEGIN
 
 @class KSAQRecordManager;

+ 7 - 3
KulexiuForStudent/KulexiuForStudent/ToolKit/KSToolLibrary.framework/Headers/RecordCheckManager.h

@@ -14,13 +14,17 @@ typedef NS_ENUM(NSInteger, PREMISSIONTYPE) {
     PREMISSIONTYPE_YES,
 };
 
+typedef void(^RecordCheckCallback)(PREMISSIONTYPE type);
+
 NS_ASSUME_NONNULL_BEGIN
 
 @interface RecordCheckManager : NSObject
 
-+ (PREMISSIONTYPE)checkMicPermissionAvaiable;
-+ (PREMISSIONTYPE)checkCameraPremissionAvaiable;
-+ (PREMISSIONTYPE)checkPhotoLibraryPremissionAvaiable;
++ (void)checkMicPermissionAvaiableCallback:(RecordCheckCallback)callback;
+
++ (void)checkCameraPremissionAvaiableCallback:(RecordCheckCallback)callback;
+
++ (void)checkPhotoLibraryPremissionAvaiableCallback:(RecordCheckCallback)callback;
 
 @end
 

BIN
KulexiuForStudent/KulexiuForStudent/ToolKit/KSToolLibrary.framework/KSToolLibrary