summaryrefslogtreecommitdiff
path: root/apps/abrepeat.h
diff options
context:
space:
mode:
Diffstat (limited to 'apps/abrepeat.h')
-rw-r--r--apps/abrepeat.h80
1 files changed, 74 insertions, 6 deletions
diff --git a/apps/abrepeat.h b/apps/abrepeat.h
index 113a1f5ee6..143e57b371 100644
--- a/apps/abrepeat.h
+++ b/apps/abrepeat.h
@@ -20,27 +20,95 @@
20#define _ABREPEAT_H_ 20#define _ABREPEAT_H_
21 21
22#include "system.h" 22#include "system.h"
23#include <stdbool.h>
24 23
25#ifdef AB_REPEAT_ENABLE 24#ifdef AB_REPEAT_ENABLE
25#include "audio.h"
26#include "kernel.h"
27#include <stdbool.h>
26 28
27#define AB_MARKER_NONE 0 29#define AB_MARKER_NONE 0
28 30
31#if (AB_REPEAT_ENABLE == 1)
32#include "settings.h"
33#endif
34
29void ab_repeat_init(void); 35void ab_repeat_init(void);
30bool ab_repeat_mode_enabled(void); // test if a/b repeat is enabled
31bool ab_A_marker_set(void);
32bool ab_B_marker_set(void);
33unsigned int ab_get_A_marker(void); 36unsigned int ab_get_A_marker(void);
34unsigned int ab_get_B_marker(void); 37unsigned int ab_get_B_marker(void);
35bool ab_reached_B_marker(unsigned int song_position);
36bool ab_before_A_marker(unsigned int song_position); 38bool ab_before_A_marker(unsigned int song_position);
37bool ab_after_A_marker(unsigned int song_position); 39bool ab_after_A_marker(unsigned int song_position);
38void ab_jump_to_A_marker(void); 40void ab_jump_to_A_marker(void);
39void ab_reset_markers(void); 41void ab_reset_markers(void);
40void ab_set_A_marker(unsigned int song_position); 42void ab_set_A_marker(unsigned int song_position);
41void ab_set_B_marker(unsigned int song_position); 43void ab_set_B_marker(unsigned int song_position);
44#if (CONFIG_CODEC == SWCODEC)
45void ab_end_of_track_report(void);
46#endif
42#ifdef HAVE_LCD_BITMAP 47#ifdef HAVE_LCD_BITMAP
43void ab_draw_markers(int capacity, int x, int y, int w, int h); 48#include "screen_access.h"
49void ab_draw_markers(struct screen * screen, int capacity,
50 int x, int y, int h);
51#endif
52
53/* These functions really need to be inlined for speed */
54extern unsigned int ab_A_marker;
55extern unsigned int ab_B_marker;
56
57static inline bool ab_A_marker_set(void)
58{
59 return ab_A_marker != AB_MARKER_NONE;
60}
61
62static inline bool ab_B_marker_set(void)
63{
64 return ab_B_marker != AB_MARKER_NONE;
65}
66
67static inline bool ab_repeat_mode_enabled(void)
68{
69#if (AB_REPEAT_ENABLE == 2)
70 return ab_A_marker_set() || ab_B_marker_set();
71#else
72 return global_settings.repeat_mode == REPEAT_AB;
73#endif
74}
75
76static inline bool ab_reached_B_marker(unsigned int song_position)
77{
78/* following is the size of the window in which we'll detect that the B marker
79was hit; it must be larger than the frequency (in milliseconds) at which this
80function is called otherwise detection of the B marker will be unreliable */
81#if (CONFIG_CODEC == SWCODEC)
82/* On swcodec, the worst case seems to be 9600kHz with 1024 samples between
83 * calls, meaning ~9 calls per second, look within 1/5 of a second */
84#define B_MARKER_DETECT_WINDOW 200
85#else
86/* we assume that this function will be called on each system tick and derive
87the window size from this with a generous margin of error (note: the number
88of ticks per second is given by HZ) */
89#define B_MARKER_DETECT_WINDOW ((1000/HZ)*10)
90#endif
91 if (ab_B_marker != AB_MARKER_NONE)
92 {
93 if ( (song_position >= ab_B_marker)
94 && (song_position <= (ab_B_marker+B_MARKER_DETECT_WINDOW)) )
95 return true;
96 }
97 return false;
98}
99
100#if (CONFIG_CODEC == SWCODEC)
101static inline void ab_position_report(unsigned long position)
102{
103 if (ab_repeat_mode_enabled())
104 {
105 if ( !(audio_status() & AUDIO_STATUS_PAUSE) &&
106 ab_reached_B_marker(position) )
107 {
108 ab_jump_to_A_marker();
109 }
110 }
111}
44#endif 112#endif
45 113
46#endif 114#endif