zero_tracker.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. #include <furi.h>
  2. #include <gui/gui.h>
  3. #include <gui/view_dispatcher.h>
  4. #include <notification/notification_messages.h>
  5. #include "zero_tracker.h"
  6. #include "tracker_engine/tracker.h"
  7. #include "view/tracker_view.h"
  8. // Channel p_0_channels[] = {
  9. // {
  10. // .rows =
  11. // {
  12. // // 1/4
  13. // ROW_MAKE(NOTE_C3, EffectArpeggio, EFFECT_DATA_2(4, 7)),
  14. // ROW_MAKE(0, EffectArpeggio, EFFECT_DATA_2(4, 7)),
  15. // ROW_MAKE(NOTE_C4, EffectSlideToNote, 0x20),
  16. // ROW_MAKE(0, EffectSlideToNote, 0x20),
  17. // //
  18. // ROW_MAKE(0, EffectSlideToNote, 0x20),
  19. // ROW_MAKE(0, EffectSlideToNote, 0x20),
  20. // ROW_MAKE(0, EffectSlideToNote, 0x20),
  21. // ROW_MAKE(0, EffectSlideToNote, 0x20),
  22. // //
  23. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)),
  24. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)),
  25. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)),
  26. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)),
  27. // //
  28. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)),
  29. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)),
  30. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)),
  31. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)),
  32. // // 2/4
  33. // ROW_MAKE(NOTE_C3, EffectSlideDown, 0x20),
  34. // ROW_MAKE(0, EffectSlideDown, 0x20),
  35. // ROW_MAKE(NOTE_C4, EffectVibrato, EFFECT_DATA_2(3, 3)),
  36. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)),
  37. // //
  38. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)),
  39. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)),
  40. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)),
  41. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)),
  42. // //
  43. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)),
  44. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)),
  45. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)),
  46. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)),
  47. // //
  48. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)),
  49. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)),
  50. // ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)),
  51. // ROW_MAKE(NOTE_OFF, EffectVibrato, EFFECT_DATA_2(3, 3)),
  52. // // 3/4
  53. // ROW_MAKE(NOTE_C3, EffectArpeggio, EFFECT_DATA_2(4, 7)),
  54. // ROW_MAKE(0, EffectArpeggio, EFFECT_DATA_2(4, 7)),
  55. // ROW_MAKE(NOTE_OFF, 0, 0),
  56. // ROW_MAKE(0, 0, 0),
  57. // //
  58. // ROW_MAKE(0, 0, 0),
  59. // ROW_MAKE(0, 0, 0),
  60. // ROW_MAKE(0, 0, 0),
  61. // ROW_MAKE(0, 0, 0),
  62. // //
  63. // ROW_MAKE(NOTE_C2, EffectPWM, 60),
  64. // ROW_MAKE(0, EffectPWM, 32),
  65. // ROW_MAKE(0, EffectPWM, 12),
  66. // ROW_MAKE(NOTE_OFF, 0, 0),
  67. // //
  68. // ROW_MAKE(0, 0, 0),
  69. // ROW_MAKE(0, 0, 0),
  70. // ROW_MAKE(0, 0, 0),
  71. // ROW_MAKE(0, 0, 0),
  72. // // 4/4
  73. // ROW_MAKE(NOTE_C3, EffectSlideDown, 0x20),
  74. // ROW_MAKE(0, EffectSlideDown, 0x20),
  75. // ROW_MAKE(0, EffectSlideDown, 0x20),
  76. // ROW_MAKE(NOTE_OFF, 0, 0),
  77. // //
  78. // ROW_MAKE(0, 0, 0),
  79. // ROW_MAKE(0, 0, 0),
  80. // ROW_MAKE(0, 0, 0),
  81. // ROW_MAKE(0, 0, 0),
  82. // //
  83. // ROW_MAKE(NOTE_C2, EffectPWM, 60),
  84. // ROW_MAKE(0, EffectPWM, 32),
  85. // ROW_MAKE(0, EffectPWM, 12),
  86. // ROW_MAKE(NOTE_OFF, 0, 0),
  87. // //
  88. // ROW_MAKE(0, 0, 0),
  89. // ROW_MAKE(0, 0, 0),
  90. // ROW_MAKE(0, 0, 0),
  91. // ROW_MAKE(0, 0, 0),
  92. // },
  93. // },
  94. // };
  95. Channel p_0_channels[] = {
  96. {
  97. .rows =
  98. {
  99. //
  100. ROW_MAKE(NOTE_A4, EffectArpeggio, EFFECT_DATA_2(4, 7)),
  101. ROW_MAKE(NOTE_C3, 0, 0),
  102. ROW_MAKE(NOTE_F2, 0, 0),
  103. ROW_MAKE(NOTE_C3, 0, 0),
  104. //
  105. ROW_MAKE(NOTE_E4, 0, 0),
  106. ROW_MAKE(NOTE_C3, 0, 0),
  107. ROW_MAKE(NOTE_E4, EffectPWM, 50),
  108. ROW_MAKE(NOTE_OFF, 0, 0),
  109. //
  110. ROW_MAKE(NOTE_A4, 0, 0),
  111. ROW_MAKE(0, EffectPWM, 55),
  112. ROW_MAKE(0, EffectPWM, 45),
  113. ROW_MAKE(NOTE_OFF, 0, 0),
  114. //
  115. ROW_MAKE(NOTE_E5, 0, 0),
  116. ROW_MAKE(0, EffectPWM, 55),
  117. ROW_MAKE(0, EffectPWM, 45),
  118. ROW_MAKE(NOTE_OFF, 0, 0),
  119. //
  120. ROW_MAKE(NOTE_D5, 0, 0),
  121. ROW_MAKE(NOTE_C3, EffectSlideDown, 0x30),
  122. ROW_MAKE(NOTE_F2, 0, 0),
  123. ROW_MAKE(NOTE_C3, 0, 0),
  124. //
  125. ROW_MAKE(NOTE_C5, 0, 0),
  126. ROW_MAKE(NOTE_C3, 0, 0),
  127. ROW_MAKE(NOTE_C5, 0, 0),
  128. ROW_MAKE(NOTE_OFF, 0, 0),
  129. //
  130. ROW_MAKE(NOTE_A4, 0, 0),
  131. ROW_MAKE(0, 0, 0),
  132. ROW_MAKE(0, 0, 0),
  133. ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)),
  134. //
  135. ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)),
  136. ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)),
  137. ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)),
  138. ROW_MAKE(NOTE_OFF, 0, 0),
  139. //
  140. ROW_MAKE(NOTE_B4, EffectArpeggio, EFFECT_DATA_2(4, 7)),
  141. ROW_MAKE(NOTE_D3, 0, 0),
  142. ROW_MAKE(NOTE_G2, 0, 0),
  143. ROW_MAKE(NOTE_D3, 0, 0),
  144. //
  145. ROW_MAKE(NOTE_E4, 0, 0),
  146. ROW_MAKE(NOTE_D3, 0, 0),
  147. ROW_MAKE(NOTE_E4, EffectPWM, 50),
  148. ROW_MAKE(NOTE_OFF, 0, 0),
  149. //
  150. ROW_MAKE(NOTE_A4, 0, 0),
  151. ROW_MAKE(0, EffectPWM, 55),
  152. ROW_MAKE(0, EffectPWM, 45),
  153. ROW_MAKE(NOTE_OFF, 0, 0),
  154. //
  155. ROW_MAKE(NOTE_E5, 0, 0),
  156. ROW_MAKE(0, EffectPWM, 55),
  157. ROW_MAKE(0, EffectPWM, 45),
  158. ROW_MAKE(NOTE_OFF, 0, 0),
  159. //
  160. ROW_MAKE(NOTE_D5, 0, 0),
  161. ROW_MAKE(NOTE_D3, EffectSlideDown, 0x3F),
  162. ROW_MAKE(NOTE_G2, 0, 0),
  163. ROW_MAKE(NOTE_D3, 0, 0),
  164. //
  165. ROW_MAKE(NOTE_C5, 0, 0),
  166. ROW_MAKE(NOTE_D3, 0, 0),
  167. ROW_MAKE(NOTE_C5, 0, 0),
  168. ROW_MAKE(NOTE_OFF, 0, 0),
  169. //
  170. ROW_MAKE(NOTE_A4, 0, 0),
  171. ROW_MAKE(0, 0, 0),
  172. ROW_MAKE(0, 0, 0),
  173. ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)),
  174. //
  175. ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)),
  176. ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)),
  177. ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)),
  178. ROW_MAKE(NOTE_OFF, 0, 0),
  179. },
  180. },
  181. };
  182. Channel p_1_channels[] = {
  183. {
  184. .rows =
  185. {
  186. //
  187. ROW_MAKE(NOTE_C5, EffectArpeggio, EFFECT_DATA_2(4, 7)),
  188. ROW_MAKE(NOTE_E3, 0, 0),
  189. ROW_MAKE(NOTE_A2, 0, 0),
  190. ROW_MAKE(NOTE_E3, 0, 0),
  191. //
  192. ROW_MAKE(NOTE_B4, 0, 0),
  193. ROW_MAKE(NOTE_E3, 0, 0),
  194. ROW_MAKE(NOTE_B4, EffectPWM, 50),
  195. ROW_MAKE(NOTE_OFF, 0, 0),
  196. //
  197. ROW_MAKE(NOTE_G4, 0, 0),
  198. ROW_MAKE(0, EffectPWM, 55),
  199. ROW_MAKE(0, EffectPWM, 45),
  200. ROW_MAKE(NOTE_OFF, 0, 0),
  201. //
  202. ROW_MAKE(NOTE_C5, 0, 0),
  203. ROW_MAKE(0, EffectPWM, 55),
  204. ROW_MAKE(0, EffectPWM, 45),
  205. ROW_MAKE(NOTE_OFF, 0, 0),
  206. //
  207. ROW_MAKE(NOTE_C6, 0, 0),
  208. ROW_MAKE(NOTE_E3, EffectSlideDown, 0x30),
  209. ROW_MAKE(NOTE_A2, 0, 0),
  210. ROW_MAKE(NOTE_E3, 0, 0),
  211. //
  212. ROW_MAKE(NOTE_B4, 0, 0),
  213. ROW_MAKE(NOTE_E3, 0, 0),
  214. ROW_MAKE(NOTE_B4, EffectPWM, 50),
  215. ROW_MAKE(NOTE_OFF, 0, 0),
  216. //
  217. ROW_MAKE(NOTE_G4, 0, 0),
  218. ROW_MAKE(0, 0, 0),
  219. ROW_MAKE(0, 0, 0),
  220. ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)),
  221. //
  222. ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)),
  223. ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)),
  224. ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)),
  225. ROW_MAKE(NOTE_OFF, 0, 0),
  226. //
  227. ROW_MAKE(NOTE_C5, EffectArpeggio, EFFECT_DATA_2(4, 7)),
  228. ROW_MAKE(NOTE_E3, 0, 0),
  229. ROW_MAKE(NOTE_A2, 0, 0),
  230. ROW_MAKE(NOTE_E3, 0, 0),
  231. //
  232. ROW_MAKE(NOTE_B4, 0, 0),
  233. ROW_MAKE(NOTE_E3, 0, 0),
  234. ROW_MAKE(NOTE_B4, EffectPWM, 50),
  235. ROW_MAKE(NOTE_OFF, 0, 0),
  236. //
  237. ROW_MAKE(NOTE_G4, 0, 0),
  238. ROW_MAKE(0, EffectPWM, 55),
  239. ROW_MAKE(0, EffectPWM, 45),
  240. ROW_MAKE(NOTE_OFF, 0, 0),
  241. //
  242. ROW_MAKE(NOTE_D5, 0, 0),
  243. ROW_MAKE(0, EffectPWM, 55),
  244. ROW_MAKE(0, EffectPWM, 45),
  245. ROW_MAKE(NOTE_OFF, 0, 0),
  246. //
  247. ROW_MAKE(NOTE_C6, 0, 0),
  248. ROW_MAKE(NOTE_E3, EffectSlideDown, 0x30),
  249. ROW_MAKE(NOTE_A2, 0, 0),
  250. ROW_MAKE(NOTE_E3, 0, 0),
  251. //
  252. ROW_MAKE(NOTE_B4, 0, 0),
  253. ROW_MAKE(NOTE_E3, 0, 0),
  254. ROW_MAKE(NOTE_B4, EffectPWM, 50),
  255. ROW_MAKE(NOTE_OFF, 0, 0),
  256. //
  257. ROW_MAKE(NOTE_G4, 0, 0),
  258. ROW_MAKE(0, 0, 0),
  259. ROW_MAKE(0, 0, 0),
  260. ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)),
  261. //
  262. ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)),
  263. ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)),
  264. ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)),
  265. ROW_MAKE(NOTE_OFF, 0, 0),
  266. },
  267. },
  268. };
  269. Channel p_2_channels[] = {
  270. {
  271. .rows =
  272. {
  273. //
  274. ROW_MAKE(NOTE_C5, EffectArpeggio, EFFECT_DATA_2(4, 7)),
  275. ROW_MAKE(NOTE_E3, 0, 0),
  276. ROW_MAKE(NOTE_A2, 0, 0),
  277. ROW_MAKE(NOTE_E3, 0, 0),
  278. //
  279. ROW_MAKE(NOTE_C5, 0, 0),
  280. ROW_MAKE(NOTE_A4, 0, 0),
  281. ROW_MAKE(NOTE_C5, 0, 0),
  282. ROW_MAKE(NOTE_A4, 0, 0),
  283. //
  284. ROW_MAKE(NOTE_C5, EffectPWM, 55),
  285. ROW_MAKE(NOTE_A4, EffectPWM, 45),
  286. ROW_MAKE(NOTE_C5, EffectPWM, 35),
  287. ROW_MAKE(NOTE_OFF, 0, 0),
  288. //
  289. ROW_MAKE(NOTE_C5, 0, 0),
  290. ROW_MAKE(NOTE_A4, 0, 0),
  291. ROW_MAKE(NOTE_C5, EffectPWM, 55),
  292. ROW_MAKE(NOTE_OFF, 0, 0),
  293. //
  294. ROW_MAKE(NOTE_D5, 0, 0),
  295. ROW_MAKE(NOTE_E3, EffectSlideDown, 0x30),
  296. ROW_MAKE(NOTE_A2, 0, 0),
  297. ROW_MAKE(NOTE_E3, 0, 0),
  298. //
  299. ROW_MAKE(NOTE_OFF, 0, 0),
  300. ROW_MAKE(NOTE_E3, 0, 0),
  301. ROW_MAKE(NOTE_B4, EffectPWM, 55),
  302. ROW_MAKE(NOTE_OFF, 0, 0),
  303. //
  304. ROW_MAKE(NOTE_D5, 0, 0),
  305. ROW_MAKE(NOTE_B4, 0, 0),
  306. ROW_MAKE(NOTE_D5, EffectPWM, 55),
  307. ROW_MAKE(NOTE_B4, EffectPWM, 55),
  308. //
  309. ROW_MAKE(NOTE_D5, EffectPWM, 45),
  310. ROW_MAKE(NOTE_B4, EffectPWM, 45),
  311. ROW_MAKE(NOTE_D5, EffectPWM, 35),
  312. ROW_MAKE(NOTE_OFF, 0, 0),
  313. //
  314. ROW_MAKE(NOTE_D5, EffectArpeggio, EFFECT_DATA_2(4, 7)),
  315. ROW_MAKE(NOTE_E3, 0, 0),
  316. ROW_MAKE(NOTE_A2, 0, 0),
  317. ROW_MAKE(NOTE_E3, 0, 0),
  318. //
  319. ROW_MAKE(NOTE_E5, 0, 0),
  320. ROW_MAKE(NOTE_C5, 0, 0),
  321. ROW_MAKE(NOTE_E5, 0, 0),
  322. ROW_MAKE(NOTE_C5, 0, 0),
  323. //
  324. ROW_MAKE(NOTE_E5, EffectPWM, 55),
  325. ROW_MAKE(NOTE_C5, EffectPWM, 45),
  326. ROW_MAKE(NOTE_E5, EffectPWM, 35),
  327. ROW_MAKE(NOTE_OFF, 0, 0),
  328. //
  329. ROW_MAKE(NOTE_E5, 0, 0),
  330. ROW_MAKE(NOTE_C5, 0, 0),
  331. ROW_MAKE(NOTE_E5, EffectPWM, 55),
  332. ROW_MAKE(NOTE_OFF, 0, 0),
  333. //
  334. ROW_MAKE(NOTE_D5, 0, 0),
  335. ROW_MAKE(NOTE_E3, EffectSlideDown, 0x30),
  336. ROW_MAKE(NOTE_A2, 0, 0),
  337. ROW_MAKE(NOTE_E3, 0, 0),
  338. //
  339. ROW_MAKE(NOTE_OFF, 0, 0),
  340. ROW_MAKE(NOTE_E3, 0, 0),
  341. ROW_MAKE(NOTE_B4, EffectPWM, 55),
  342. ROW_MAKE(NOTE_OFF, 0, 0),
  343. //
  344. ROW_MAKE(NOTE_D5, 0, 0),
  345. ROW_MAKE(NOTE_B4, 0, 0),
  346. ROW_MAKE(NOTE_D5, EffectPWM, 55),
  347. ROW_MAKE(NOTE_B4, EffectPWM, 55),
  348. //
  349. ROW_MAKE(NOTE_D5, EffectPWM, 45),
  350. ROW_MAKE(NOTE_B4, EffectPWM, 45),
  351. ROW_MAKE(NOTE_D5, EffectPWM, 35),
  352. ROW_MAKE(NOTE_OFF, 0, 0),
  353. },
  354. },
  355. };
  356. Channel p_3_channels[] = {
  357. {
  358. .rows =
  359. {
  360. //
  361. ROW_MAKE(NOTE_Ds5, EffectArpeggio, EFFECT_DATA_2(4, 6)),
  362. ROW_MAKE(NOTE_C5, 0, 0),
  363. ROW_MAKE(NOTE_Ds5, 0, 0),
  364. ROW_MAKE(NOTE_C5, EffectPWM, 55),
  365. //
  366. ROW_MAKE(NOTE_Ds5, EffectPWM, 45),
  367. ROW_MAKE(NOTE_C5, EffectPWM, 35),
  368. ROW_MAKE(NOTE_Ds5, EffectPWM, 30),
  369. ROW_MAKE(NOTE_OFF, 0, 0),
  370. //
  371. ROW_MAKE(NOTE_D5, 0, 0),
  372. ROW_MAKE(NOTE_B4, 0, 0),
  373. ROW_MAKE(NOTE_D5, 0, 0),
  374. ROW_MAKE(NOTE_B4, EffectPWM, 55),
  375. //
  376. ROW_MAKE(NOTE_D5, EffectPWM, 45),
  377. ROW_MAKE(NOTE_B4, EffectPWM, 35),
  378. ROW_MAKE(NOTE_D5, EffectPWM, 30),
  379. ROW_MAKE(NOTE_OFF, 0, 0),
  380. //
  381. ROW_MAKE(NOTE_Cs5, EffectArpeggio, EFFECT_DATA_2(4, 6)),
  382. ROW_MAKE(NOTE_As4, 0, 0),
  383. ROW_MAKE(NOTE_Cs5, 0, 0),
  384. ROW_MAKE(NOTE_As4, EffectPWM, 55),
  385. //
  386. ROW_MAKE(NOTE_Cs5, EffectPWM, 45),
  387. ROW_MAKE(NOTE_As4, EffectPWM, 35),
  388. ROW_MAKE(NOTE_Cs5, EffectPWM, 30),
  389. ROW_MAKE(NOTE_OFF, 0, 0),
  390. //
  391. ROW_MAKE(NOTE_C5, 0, 0),
  392. ROW_MAKE(NOTE_A4, 0, 0),
  393. ROW_MAKE(NOTE_C5, 0, 0),
  394. ROW_MAKE(NOTE_A4, EffectPWM, 55),
  395. //
  396. ROW_MAKE(NOTE_C5, EffectPWM, 45),
  397. ROW_MAKE(NOTE_A4, EffectPWM, 35),
  398. ROW_MAKE(NOTE_C5, EffectPWM, 30),
  399. ROW_MAKE(NOTE_OFF, 0, 0),
  400. //
  401. ROW_MAKE(NOTE_B4, EffectArpeggio, EFFECT_DATA_2(4, 6)),
  402. ROW_MAKE(NOTE_Gs4, 0, 0),
  403. ROW_MAKE(NOTE_B4, 0, 0),
  404. ROW_MAKE(NOTE_Gs4, EffectPWM, 55),
  405. //
  406. ROW_MAKE(NOTE_B4, EffectPWM, 45),
  407. ROW_MAKE(NOTE_Gs4, EffectPWM, 35),
  408. ROW_MAKE(NOTE_B4, EffectPWM, 30),
  409. ROW_MAKE(NOTE_OFF, 0, 0),
  410. //
  411. ROW_MAKE(NOTE_C5, 0, 0),
  412. ROW_MAKE(NOTE_A4, 0, 0),
  413. ROW_MAKE(NOTE_C5, 0, 0),
  414. ROW_MAKE(NOTE_A4, EffectPWM, 55),
  415. //
  416. ROW_MAKE(NOTE_C5, EffectPWM, 45),
  417. ROW_MAKE(NOTE_A4, EffectPWM, 35),
  418. ROW_MAKE(NOTE_C5, EffectPWM, 30),
  419. ROW_MAKE(NOTE_OFF, 0, 0),
  420. //
  421. ROW_MAKE(NOTE_Cs5, EffectArpeggio, EFFECT_DATA_2(4, 6)),
  422. ROW_MAKE(NOTE_As4, 0, 0),
  423. ROW_MAKE(NOTE_Cs5, 0, 0),
  424. ROW_MAKE(NOTE_As4, EffectPWM, 55),
  425. //
  426. ROW_MAKE(NOTE_Cs5, EffectPWM, 45),
  427. ROW_MAKE(NOTE_As4, EffectPWM, 35),
  428. ROW_MAKE(NOTE_Cs5, EffectPWM, 30),
  429. ROW_MAKE(NOTE_OFF, 0, 0),
  430. //
  431. ROW_MAKE(NOTE_D5, 0, 0),
  432. ROW_MAKE(NOTE_B4, 0, 0),
  433. ROW_MAKE(NOTE_D5, 0, 0),
  434. ROW_MAKE(NOTE_B4, EffectPWM, 55),
  435. //
  436. ROW_MAKE(NOTE_D5, EffectPWM, 45),
  437. ROW_MAKE(NOTE_B4, EffectPWM, 35),
  438. ROW_MAKE(NOTE_D5, EffectPWM, 30),
  439. ROW_MAKE(NOTE_OFF, 0, 0),
  440. },
  441. },
  442. };
  443. Pattern patterns[] = {
  444. {.channels = p_0_channels},
  445. {.channels = p_1_channels},
  446. {.channels = p_2_channels},
  447. {.channels = p_3_channels},
  448. };
  449. uint8_t order_list[] = {
  450. 0,
  451. 1,
  452. 0,
  453. 2,
  454. 0,
  455. 1,
  456. 0,
  457. 3,
  458. };
  459. Song song = {
  460. .channels_count = 1,
  461. .patterns_count = sizeof(patterns) / sizeof(patterns[0]),
  462. .patterns = patterns,
  463. .order_list_size = sizeof(order_list) / sizeof(order_list[0]),
  464. .order_list = order_list,
  465. .ticks_per_second = 60,
  466. };
  467. void tracker_message(TrackerMessage message, void* context) {
  468. FuriMessageQueue* queue = context;
  469. furi_assert(queue);
  470. furi_message_queue_put(queue, &message, 0);
  471. }
  472. int32_t zero_tracker_app(void* p) {
  473. UNUSED(p);
  474. NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
  475. notification_message(notification, &sequence_display_backlight_enforce_on);
  476. Gui* gui = furi_record_open(RECORD_GUI);
  477. ViewDispatcher* view_dispatcher = view_dispatcher_alloc();
  478. TrackerView* tracker_view = tracker_view_alloc();
  479. tracker_view_set_song(tracker_view, &song);
  480. view_dispatcher_add_view(view_dispatcher, 0, tracker_view_get_view(tracker_view));
  481. view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
  482. view_dispatcher_switch_to_view(view_dispatcher, 0);
  483. FuriMessageQueue* queue = furi_message_queue_alloc(8, sizeof(TrackerMessage));
  484. Tracker* tracker = tracker_alloc();
  485. tracker_set_message_callback(tracker, tracker_message, queue);
  486. tracker_set_song(tracker, &song);
  487. tracker_start(tracker);
  488. while(1) {
  489. TrackerMessage message;
  490. FuriStatus status = furi_message_queue_get(queue, &message, portMAX_DELAY);
  491. if(status == FuriStatusOk) {
  492. if(message.type == TrackerPositionChanged) {
  493. uint8_t order_list_index = message.data.position.order_list_index;
  494. uint8_t row = message.data.position.row;
  495. uint8_t pattern = song.order_list[order_list_index];
  496. tracker_view_set_position(tracker_view, order_list_index, row);
  497. FURI_LOG_I("Tracker", "O:%d P:%d R:%d", order_list_index, pattern, row);
  498. } else if(message.type == TrackerEndOfSong) {
  499. FURI_LOG_I("Tracker", "End of song");
  500. break;
  501. }
  502. }
  503. }
  504. tracker_stop(tracker);
  505. tracker_free(tracker);
  506. furi_message_queue_free(queue);
  507. furi_delay_ms(500);
  508. view_dispatcher_remove_view(view_dispatcher, 0);
  509. tracker_view_free(tracker_view);
  510. view_dispatcher_free(view_dispatcher);
  511. notification_message(notification, &sequence_display_backlight_enforce_auto);
  512. furi_record_close(RECORD_NOTIFICATION);
  513. furi_record_close(RECORD_GUI);
  514. return 0;
  515. }