ToneTuningViewController.m 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. //
  2. // ToneTuningViewController.m
  3. // KulexiuForStudent
  4. //
  5. // Created by 王智 on 2022/10/13.
  6. //
  7. #import "ToneTuningViewController.h"
  8. #import "TuningNavView.h"
  9. #import <KSTunerLibrary/KSTunerLibrary-Swift.h>
  10. #import "ToneTuningBodyView.h"
  11. #import "DialPlateView.h"
  12. #import "TuningForkSettingView.h"
  13. #import <AVFoundation/AVFoundation.h>
  14. #import "TunerSettingView.h"
  15. #import <KSChoosePicker.h>
  16. #import "WidgetViewController.h"
  17. #import "MetronomeManager.h"
  18. @interface ToneTuningViewController ()<TunerDelegate>
  19. @property (nonatomic, strong) TuningNavView *navView;
  20. @property (nonatomic, assign) BOOL isRuning;
  21. @property (nonatomic, strong) Tuner *tuner;
  22. @property (nonatomic, strong) ToneTuningBodyView *bodyView;
  23. @property (nonatomic, strong) DialPlateView *plateView;
  24. @property (nonatomic, assign) BOOL isTransfer;
  25. @property (nonatomic, strong) TuningForkSettingView *forkView;
  26. @property (nonatomic, assign) NSInteger chooseFrequence;
  27. @property (nonatomic, strong) TunerForkManager *forkManager;
  28. @property (nonatomic, strong) TunerSettingView *settingView;
  29. @property (nonatomic, strong) KSChoosePicker *instrumentPicker;
  30. @property (nonatomic, assign) NSInteger lastChooseIndex;
  31. @property (nonatomic, strong) NSArray *instrumentArray;
  32. @property (nonatomic, strong) NSArray *picthRateArray;
  33. // 判断是否选择移调乐器
  34. @property (nonatomic, assign) NSInteger toneChangeRate;
  35. @property (nonatomic, strong) NSArray *picthDescArray;
  36. // A4 频率
  37. @property (nonatomic, assign) NSInteger A4Frequence;
  38. @end
  39. @implementation ToneTuningViewController
  40. - (void)viewDidLoad {
  41. [super viewDidLoad];
  42. // Do any additional setup after loading the view.
  43. self.ks_prefersNavigationBarHidden = YES;
  44. [self configDefault];
  45. [self configUI];
  46. [self setupAudioSession];
  47. [self addNotification];
  48. }
  49. - (void)addNotification {
  50. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stopPlayBeat) name:ERROR_NOTIFICATION object:nil];
  51. }
  52. - (void)configDefault {
  53. self.chooseFrequence = A4_FREQUENCE_INTABLE;
  54. self.A4Frequence = DEFALUT_A4FREQUENCE;
  55. self.isTransfer = NO;
  56. }
  57. - (void)setupAudioSession {
  58. AVAudioSession *audioSession = [AVAudioSession sharedInstance];
  59. NSError *err = nil;
  60. AVAudioSessionCategory category = AVAudioSessionCategoryPlayAndRecord;
  61. if (@available(iOS 10.0, *)) {
  62. [audioSession setCategory:category mode:AVAudioSessionModeDefault options:AVAudioSessionCategoryOptionAllowBluetooth|AVAudioSessionCategoryOptionAllowBluetoothA2DP|AVAudioSessionCategoryOptionDefaultToSpeaker|AVAudioSessionCategoryOptionMixWithOthers error:&err];
  63. }
  64. else {
  65. [audioSession setCategory:category withOptions:AVAudioSessionCategoryOptionAllowBluetooth|AVAudioSessionCategoryOptionDefaultToSpeaker|AVAudioSessionCategoryOptionMixWithOthers error:&err];
  66. }
  67. [audioSession setActive:YES error:&err];
  68. }
  69. - (void)configUI {
  70. self.scrollView.backgroundColor = [UIColor clearColor];
  71. [self.scrollView mas_remakeConstraints:^(MASConstraintMaker *make) {
  72. make.left.right.mas_equalTo(self.view);
  73. make.top.mas_equalTo(self.view.mas_top).offset(kNaviBarHeight);
  74. make.bottom.mas_equalTo(self.view.mas_bottom);
  75. }];
  76. // 背景图
  77. UIImage *bgImage = [UIImage imageNamed:@"gadget_bg"];
  78. UIImageView *imageView = [[UIImageView alloc] initWithImage:bgImage];
  79. imageView.contentMode = UIViewContentModeRedraw;
  80. [self.view addSubview:imageView];
  81. [imageView mas_makeConstraints:^(MASConstraintMaker *make) {
  82. make.left.right.top.bottom.mas_equalTo(self.view);
  83. }];
  84. [self.view bringSubviewToFront:self.scrollView];
  85. [self.view addSubview:self.navView];
  86. [self.navView mas_makeConstraints:^(MASConstraintMaker *make) {
  87. make.top.left.right.mas_equalTo(self.view);
  88. make.height.mas_equalTo(kNaviBarHeight);
  89. }];
  90. [self.scrollView addSubview:self.bodyView];
  91. self.bodyView.A4Frequence = self.A4Frequence;
  92. [self.bodyView mas_makeConstraints:^(MASConstraintMaker *make) {
  93. make.left.right.mas_equalTo(self.view);
  94. make.top.mas_equalTo(self.scrollView.mas_top);
  95. make.bottom.mas_equalTo(self.scrollView.mas_bottom);
  96. }];
  97. [self.bodyView.plateView addSubview:self.plateView];
  98. [self.plateView mas_makeConstraints:^(MASConstraintMaker *make) {
  99. make.top.bottom.left.right.mas_equalTo(self.bodyView.plateView);
  100. }];
  101. }
  102. - (void)viewDidAppear:(BOOL)animated {
  103. [super viewDidAppear:animated];
  104. [self startTuner];
  105. }
  106. - (void)viewWillAppear:(BOOL)animated {
  107. [super viewWillAppear:animated];
  108. self.bodyView.speedValue.text = [NSString stringWithFormat:@"BPM=%d",METRONOME_MANAGER.speed];
  109. self.bodyView.metronomePlayStatus = METRONOME_MANAGER.isPlaying;
  110. self.bodyView.beatType.text = [METRONOME_MANAGER getTypeString];
  111. [self changeRhythm];
  112. }
  113. - (void)viewWillDisappear:(BOOL)animated {
  114. [super viewWillDisappear:animated];
  115. [self stopTuner];
  116. [self stopForkPlay];
  117. BOOL isBack = [self isViewPopDismiss];
  118. if (isBack) {
  119. [METRONOME_MANAGER stopPlay];
  120. [METRONOME_MANAGER resetDefaultConfig];
  121. [self removeTuner];
  122. }
  123. }
  124. - (void)startTuner {
  125. @try {
  126. if (self.isRuning == NO) {
  127. self.isRuning = YES;
  128. [self.tuner start];
  129. }
  130. } @catch (NSException *exception) {
  131. NSLog(@"--exception -- %@",exception);
  132. } @finally {
  133. }
  134. }
  135. - (void)stopTuner {
  136. if (self.isRuning) {
  137. self.isRuning = NO;
  138. [self.tuner stop];
  139. }
  140. }
  141. - (void)removeTuner {
  142. if (_tuner) {
  143. [_tuner freeTuner];
  144. _tuner = nil;
  145. NSLog(@"--- free tuner ");
  146. }
  147. }
  148. - (CAGradientLayer *)createGradientLayerFromColor:(UIColor *)fromColor startPoint:(CGPoint)startPoint endColor:(UIColor *)endColor endPoint:(CGPoint)endPoint bounds:(CGRect)bounds {
  149. CAGradientLayer *gradientLayer = [CAGradientLayer layer];
  150. gradientLayer.colors = @[(__bridge id)fromColor.CGColor, (__bridge id)endColor.CGColor];
  151. gradientLayer.startPoint = startPoint;
  152. gradientLayer.endPoint = endPoint;
  153. gradientLayer.frame = bounds;
  154. gradientLayer.locations = @[@(0),@(1.0f)];
  155. return gradientLayer;
  156. }
  157. - (TuningNavView *)navView {
  158. if (!_navView) {
  159. _navView = [TuningNavView shareInstance];
  160. MJWeakSelf;
  161. [_navView navActionCallback:^(BOOL isBack) {
  162. if (isBack) {
  163. [weakSelf backAction];
  164. }
  165. else {
  166. [weakSelf showSettingView];
  167. }
  168. }];
  169. }
  170. return _navView;
  171. }
  172. - (void)showSettingView {
  173. [self.settingView showView];
  174. }
  175. - (Tuner *)tuner {
  176. if (!_tuner) {
  177. _tuner = [[Tuner alloc] initWithThreshold:0 smoothing:0.25];
  178. _tuner.delegate = self;
  179. }
  180. return _tuner;
  181. }
  182. - (void)tunerDidUpdate:(Tuner *)tuner output:(TunerOutput *)output {
  183. if (output.amplitude < 0.01) {
  184. }
  185. else {
  186. TunerOutput *transferOutput = [tuner getTransferPitchWithA4Frequency:self.A4Frequence toneChangeRate:self.toneChangeRate output:output];
  187. /**
  188. 如果知道两个音a和b的频率,两个音相距的音分值n可用下列公式计算(类似分贝定义式的形式,目的是为了使指数形式的物理单位线性化,使其化为对数):
  189. n=1200 *log2(a/b) == 3986 *log10(a/b)
  190. */
  191. Float32 cents = log2(transferOutput.frequency/transferOutput.midFrequence) * 1200;
  192. // Float32 cents = log2(transferOutput.frequency / (transferOutput.frequency - transferOutput.distance)) *1200;
  193. if (lround(transferOutput.frequency) == lround(transferOutput.midFrequence)) {
  194. cents = 0;
  195. }
  196. if (cents > 50) {
  197. cents = 50;
  198. }
  199. else if (cents < -50) {
  200. cents = 50;
  201. }
  202. self.plateView.gaugeView.value = (NSInteger)cents;
  203. self.bodyView.distance = (NSInteger)cents;
  204. // 调整频率后
  205. float rate = 0.0;
  206. if (labs((int)cents) <= 10) {
  207. self.bodyView.frequenceCorrect = YES;
  208. }
  209. else {
  210. self.bodyView.frequenceCorrect = NO;
  211. }
  212. int distance = abs((int)cents) > 50 ? 50 : abs((int)cents);
  213. rate = (50.0 - distance) / 50;
  214. self.bodyView.rateFrequence = rate;
  215. if (self.isTransfer == NO) {
  216. self.bodyView.nomalPitch.text = [NSString stringWithFormat:@"%@%zd",output.pitch, output.octave];
  217. self.bodyView.pitchFrequenceLabel.text = [NSString stringWithFormat:@"%@%zd:%.0fHz", output.pitch, output.octave, output.midFrequence / A4_FREQUENCE_INTABLE *self.A4Frequence];
  218. self.bodyView.preFrequence.text = [NSString stringWithFormat:@"%@%zd",output.prePitch, output.preOctave];
  219. self.bodyView.nextFrequence.text = [NSString stringWithFormat:@"%@%zd",output.nextPitch, output.nextOctave];
  220. }
  221. else {
  222. self.bodyView.transferNomalPitch.text = [NSString stringWithFormat:@"%@%zd",transferOutput.pitch,transferOutput.octave];
  223. self.bodyView.transferDesc.text = self.settingView.transferPicthDesc;
  224. self.bodyView.transferPitch.text = [NSString stringWithFormat:@"%@%zd",transferOutput.transferPitch, transferOutput.transferOctave];
  225. self.bodyView.pitchFrequenceLabel.text = [NSString stringWithFormat:@"%@%zd:%.0fHz", transferOutput.transferPitch, transferOutput.transferOctave, transferOutput.midFrequence];
  226. self.bodyView.preFrequence.text = [NSString stringWithFormat:@"%@%zd",transferOutput.prePitch, transferOutput.preOctave];
  227. self.bodyView.nextFrequence.text = [NSString stringWithFormat:@"%@%zd",transferOutput.nextPitch, transferOutput.nextOctave];
  228. }
  229. }
  230. NSLog(@"-------- %@%zd --- distance :%f frequence : %f" , output.pitch, output.octave, output.distance, output.frequency);
  231. }
  232. #pragma mark ---- lazying
  233. - (ToneTuningBodyView *)bodyView {
  234. if (!_bodyView) {
  235. _bodyView = [ToneTuningBodyView shareInstance];
  236. MJWeakSelf;
  237. [_bodyView tuningViewAction:^(TUNINGACTION action, NSInteger frequence) {
  238. [weakSelf tuningAction:action frequence:frequence];
  239. }];
  240. }
  241. return _bodyView;
  242. }
  243. - (void)tuningAction:(TUNINGACTION)action frequence:(NSInteger)frequence {
  244. switch (action) {
  245. case TUNINGACTION_FORKSETTING: // 音叉设置
  246. {
  247. [self.forkView showView];
  248. // 停止播放节拍器
  249. [self stopPlayBeat];
  250. }
  251. break;
  252. case TUNINGACTION_FREQUENCE: // 调整频率
  253. {
  254. self.A4Frequence = frequence;
  255. self.settingView.A4Frequence = frequence;
  256. self.tuner.A4Frequence = frequence;
  257. self.forkView.A4Frequence = frequence;
  258. if (self.bodyView.isPlaying) {
  259. CGFloat changefrequence = frequence / A4_FREQUENCE_INTABLE * self.chooseFrequence;
  260. [self.forkManager changeFrequenceWithFrequence:changefrequence];
  261. }
  262. }
  263. break;
  264. case TUNINGACTION_PLAY: // 播放音叉
  265. {
  266. [self startForkPlay];
  267. // 停止播放节拍器
  268. [self stopPlayBeat];
  269. }
  270. break;
  271. case TUNINGACTION_STOP: // 停止音叉
  272. {
  273. [self stopForkPlay];
  274. }
  275. break;
  276. case TUNINGACTION_BEATPLAY:
  277. {
  278. [self startPlayBeat];
  279. // 停止音叉
  280. [self stopForkPlay];
  281. }
  282. break;
  283. case TUNINGACTION_BEATSTOP:
  284. {
  285. [self stopPlayBeat];
  286. }
  287. break;
  288. case TUNINGACTION_BEATCHOOSE:
  289. {
  290. [self beatChoose];
  291. }
  292. break;
  293. case TUNINGACTION_RHYTHMCHOOSE: // 选择节奏
  294. {
  295. [self chooseRhythmType];
  296. }
  297. break;
  298. case TUNINGACTION_METRONOME:
  299. {
  300. WidgetViewController *ctrl = [[WidgetViewController alloc] init];
  301. [self.navigationController pushViewController:ctrl animated:YES];
  302. }
  303. break;
  304. default:
  305. break;
  306. }
  307. }
  308. - (void)chooseRhythmType {
  309. [METRONOME_MANAGER rhythmChooseCallback:^(RHYTHM_TYPE thythmType) {
  310. [self stopPlayBeat];
  311. [self changeRhythm];
  312. }];
  313. }
  314. - (void)changeRhythm {
  315. // 显示
  316. NSString *imageName = [METRONOME_MANAGER imageWithType:METRONOME_MANAGER.rhythmType];
  317. [self.bodyView.rhythmImage setImage:[UIImage imageNamed:imageName]];
  318. }
  319. - (void)startForkPlay {
  320. CGFloat changefrequence = self.A4Frequence / A4_FREQUENCE_INTABLE * self.chooseFrequence;
  321. [self.forkManager setupWithFrequence:changefrequence];
  322. }
  323. - (void)stopForkPlay {
  324. self.bodyView.isPlaying = NO;
  325. [self.forkManager stop];
  326. }
  327. #pragma mark ---- 节拍器
  328. - (void)startPlayBeat {
  329. self.bodyView.metronomePlayStatus = YES;
  330. [METRONOME_MANAGER startPlay];
  331. }
  332. - (void)stopPlayBeat {
  333. self.bodyView.metronomePlayStatus = NO;
  334. [METRONOME_MANAGER stopPlay];
  335. }
  336. - (void)beatChoose {
  337. [METRONOME_MANAGER beatChooseCallback:^(KSWidgeMetronomeType type) {
  338. [self disPlayBeat];
  339. [self changeRhythm];
  340. }];
  341. }
  342. - (void)disPlayBeat {
  343. self.bodyView.metronomePlayStatus = NO;
  344. [self stopPlayBeat];
  345. self.bodyView.beatType.text = [METRONOME_MANAGER getTypeString];
  346. }
  347. - (DialPlateView *)plateView {
  348. if (!_plateView) {
  349. _plateView = [[DialPlateView alloc] init];
  350. }
  351. return _plateView;
  352. }
  353. #pragma mark ------ forkSetting
  354. - (TuningForkSettingView *)forkView {
  355. if (!_forkView) {
  356. _forkView = [TuningForkSettingView shareInstance];
  357. _forkView.frame = CGRectMake(0, 0, KPortraitWidth, KPortraitHeight);
  358. MJWeakSelf;
  359. [_forkView forkSettingAction:^(CGFloat frequence, BOOL isSure) {
  360. NSLog(@"----- frequence %f", frequence);
  361. weakSelf.chooseFrequence = frequence;
  362. if (weakSelf.bodyView.isPlaying) {
  363. CGFloat changefrequence = frequence / A4_FREQUENCE_INTABLE * self.A4Frequence;
  364. [weakSelf.forkManager changeFrequenceWithFrequence:changefrequence];
  365. }
  366. else {
  367. if (isSure) {
  368. [weakSelf stopForkPlay];
  369. }
  370. else {
  371. if (weakSelf.forkManager.isPlay) {
  372. CGFloat changefrequence = frequence / A4_FREQUENCE_INTABLE * self.A4Frequence;
  373. [weakSelf.forkManager changeFrequenceWithFrequence:changefrequence];
  374. }
  375. else {
  376. [weakSelf startForkPlay];
  377. }
  378. }
  379. }
  380. }];
  381. }
  382. return _forkView;
  383. }
  384. - (TunerForkManager *)forkManager {
  385. if (!_forkManager) {
  386. _forkManager = [[TunerForkManager alloc] init];
  387. }
  388. return _forkManager;
  389. }
  390. - (TunerSettingView *)settingView {
  391. if (!_settingView) {
  392. _settingView = [TunerSettingView shareInstance];
  393. _settingView.A4Frequence = self.A4Frequence;
  394. _settingView.frame = CGRectMake(0, 0, KPortraitWidth, KPortraitHeight);
  395. MJWeakSelf;
  396. [_settingView tunerSettingAction:^(TUNETSETTING_ACTION action, NSInteger toneChangeRate, NSInteger frequence) {
  397. [weakSelf tunerSettingAction:action picthRate:toneChangeRate frequence:frequence];
  398. }];
  399. }
  400. return _settingView;
  401. }
  402. - (void)tunerSettingAction:(TUNETSETTING_ACTION)action picthRate:(NSInteger)toneChangeRate frequence:(NSInteger)frequence {
  403. if (action == TUNETSETTING_ACTION_INSTRUMENT) {
  404. // 选择乐器
  405. MJWeakSelf;
  406. self.instrumentPicker = [[KSChoosePicker alloc] initWithTitle:@"" sourceData:self.instrumentArray lastChooseIndex:self.lastChooseIndex sureButtonColor:CLIENT_THEMECOLOR chooseReturnWithBlock:^(NSString * _Nonnull returnValue, NSInteger chooseIndex) {
  407. weakSelf.lastChooseIndex = chooseIndex;
  408. weakSelf.settingView.instrumentLabel.text = returnValue;
  409. NSInteger pitchRate = [weakSelf.picthRateArray[chooseIndex] integerValue];
  410. weakSelf.A4Frequence = frequence;
  411. weakSelf.settingView.toneChangeRate = pitchRate;
  412. weakSelf.settingView.transferPicthDesc = weakSelf.picthDescArray[chooseIndex];
  413. } cancel:^{
  414. }];
  415. [self.instrumentPicker showPicker];
  416. }
  417. else if (action == TUNETSETTING_ACTION_SURE) {
  418. // 设置成功
  419. self.A4Frequence = frequence;
  420. self.bodyView.A4Frequence = frequence;
  421. self.toneChangeRate = toneChangeRate;
  422. self.tuner.A4Frequence = frequence;
  423. self.forkView.A4Frequence = frequence;
  424. if (self.bodyView.isPlaying) {
  425. CGFloat changefrequence = frequence / A4_FREQUENCE_INTABLE * self.chooseFrequence;
  426. [self.forkManager changeFrequenceWithFrequence:changefrequence];
  427. }
  428. }
  429. }
  430. - (NSArray *)instrumentArray {
  431. if (!_instrumentArray) {
  432. _instrumentArray = @[@"没有移调",
  433. @"葫芦丝:C调",@"葫芦丝:D调",@"葫芦丝:降B调",@"葫芦丝:F调",@"葫芦丝:G调",
  434. @"排箫:C调",@"排箫:D调",@"排箫:E调",@"排箫:F调",@"排箫:G调",
  435. @"竖笛:C调",@"竖笛:中音F调",
  436. @"口风琴:C调",
  437. @"陶笛:SC调",@"陶笛:AC调",@"陶笛:AG调",@"陶笛:AF调",@"陶笛:BC调",
  438. @"长笛:C调",@"高音萨克斯:降B调",@"中音萨克斯:降E调",@"单簧管:降B调",@"双簧管:C调",@"小号:降B调",@"长号:C调",@"圆号:F调",@"大号:降B调",@"上低音号:C调",@"上低音号:降B调"];
  439. }
  440. return _instrumentArray;
  441. }
  442. - (NSArray *)picthRateArray {
  443. if (!_picthRateArray) {
  444. _picthRateArray = @[@0,
  445. @-12,@-2,@-11,@-5,@-7,
  446. @-12,@-14,@-16,@-17,@-19,
  447. @-12,@-5,
  448. @0,
  449. @-24,@-12,@-7,@-12,@0,
  450. @0,@-10,@-3,@-10,@0,@-10,@0,@-5,@-10,@0,@-10];
  451. }
  452. return _picthRateArray;
  453. }
  454. - (NSArray *)picthDescArray {
  455. if (!_picthDescArray) {
  456. _picthDescArray = @[@"C ins.",
  457. @"C ins.",@"D ins.",@"B♭ ins.",@"F ins.",@"G ins.",
  458. @"C ins.",@"D ins.",@"E ins.",@"F ins.",@"G ins.",
  459. @"C ins.",@"F ins.",
  460. @"C ins.",
  461. @"C ins.",@"C ins.",@"G ins.",@"F ins.",@"C ins.",
  462. @"C ins.",@"B♭ ins.",@"E♭ ins.",@"B♭ ins.",@"C ins.",@"B♭ ins.",@"C ins.",@"F ins.",@"B♭ ins.",@"C ins.",@"B♭ ins."];
  463. }
  464. return _picthDescArray;
  465. }
  466. - (void)setToneChangeRate:(NSInteger)toneChangeRate {
  467. _toneChangeRate = toneChangeRate;
  468. self.tuner.toneChangeRate = toneChangeRate;
  469. if (_toneChangeRate == 0) { //
  470. self.isTransfer = NO;
  471. }
  472. else {
  473. self.isTransfer = YES;
  474. }
  475. }
  476. - (void)setIsTransfer:(BOOL)isTransfer {
  477. _isTransfer = isTransfer;
  478. self.bodyView.isTransfer = isTransfer;
  479. }
  480. - (void)dealloc {
  481. [[NSNotificationCenter defaultCenter] removeObserver:self];
  482. NSLog(@"----- toneturning dealloc");
  483. }
  484. /*
  485. #pragma mark - Navigation
  486. // In a storyboard-based application, you will often want to do a little preparation before navigation
  487. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  488. // Get the new view controller using [segue destinationViewController].
  489. // Pass the selected object to the new view controller.
  490. }
  491. */
  492. @end