summaryrefslogtreecommitdiff
path: root/apps/abrepeat.h
diff options
context:
space:
mode:
authorBrandon Low <lostlogic@rockbox.org>2006-01-21 23:43:57 +0000
committerBrandon Low <lostlogic@rockbox.org>2006-01-21 23:43:57 +0000
commit8d5a6609a33f3269bc80975b81e0e859a056d952 (patch)
tree9bef78c29941956fc6473f58e1657624c150f2d5 /apps/abrepeat.h
parent0a9179cb0a4bda8191fcfcb45404ea361fcacdc5 (diff)
AB-repeat mode for software codecs. Accessible through menu as a repeat mode, with buttom mappings much like those on other rockbox targets for now.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8409 a1c6a512-1295-4272-9138-f99709370657
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 @@
#define _ABREPEAT_H_
#include "system.h"
-#include <stdbool.h>
#ifdef AB_REPEAT_ENABLE
+#include "audio.h"
+#include "kernel.h"
+#include <stdbool.h>
#define AB_MARKER_NONE 0
+#if (AB_REPEAT_ENABLE == 1)
+#include "settings.h"
+#endif
+
void ab_repeat_init(void);
-bool ab_repeat_mode_enabled(void); // test if a/b repeat is enabled
-bool ab_A_marker_set(void);
-bool ab_B_marker_set(void);
unsigned int ab_get_A_marker(void);
unsigned int ab_get_B_marker(void);
-bool ab_reached_B_marker(unsigned int song_position);
bool ab_before_A_marker(unsigned int song_position);
bool ab_after_A_marker(unsigned int song_position);
void ab_jump_to_A_marker(void);
void ab_reset_markers(void);
void ab_set_A_marker(unsigned int song_position);
void ab_set_B_marker(unsigned int song_position);
+#if (CONFIG_CODEC == SWCODEC)
+void ab_end_of_track_report(void);
+#endif
#ifdef HAVE_LCD_BITMAP
-void ab_draw_markers(int capacity, int x, int y, int w, int h);
+#include "screen_access.h"
+void ab_draw_markers(struct screen * screen, int capacity,
+ int x, int y, int h);
+#endif
+
+/* These functions really need to be inlined for speed */
+extern unsigned int ab_A_marker;
+extern unsigned int ab_B_marker;
+
+static inline bool ab_A_marker_set(void)
+{
+ return ab_A_marker != AB_MARKER_NONE;
+}
+
+static inline bool ab_B_marker_set(void)
+{
+ return ab_B_marker != AB_MARKER_NONE;
+}
+
+static inline bool ab_repeat_mode_enabled(void)
+{
+#if (AB_REPEAT_ENABLE == 2)
+ return ab_A_marker_set() || ab_B_marker_set();
+#else
+ return global_settings.repeat_mode == REPEAT_AB;
+#endif
+}
+
+static inline bool ab_reached_B_marker(unsigned int song_position)
+{
+/* following is the size of the window in which we'll detect that the B marker
+was hit; it must be larger than the frequency (in milliseconds) at which this
+function is called otherwise detection of the B marker will be unreliable */
+#if (CONFIG_CODEC == SWCODEC)
+/* On swcodec, the worst case seems to be 9600kHz with 1024 samples between
+ * calls, meaning ~9 calls per second, look within 1/5 of a second */
+#define B_MARKER_DETECT_WINDOW 200
+#else
+/* we assume that this function will be called on each system tick and derive
+the window size from this with a generous margin of error (note: the number
+of ticks per second is given by HZ) */
+#define B_MARKER_DETECT_WINDOW ((1000/HZ)*10)
+#endif
+ if (ab_B_marker != AB_MARKER_NONE)
+ {
+ if ( (song_position >= ab_B_marker)
+ && (song_position <= (ab_B_marker+B_MARKER_DETECT_WINDOW)) )
+ return true;
+ }
+ return false;
+}
+
+#if (CONFIG_CODEC == SWCODEC)
+static inline void ab_position_report(unsigned long position)
+{
+ if (ab_repeat_mode_enabled())
+ {
+ if ( !(audio_status() & AUDIO_STATUS_PAUSE) &&
+ ab_reached_B_marker(position) )
+ {
+ ab_jump_to_A_marker();
+ }
+ }
+}
#endif
#endif