From 8d5a6609a33f3269bc80975b81e0e859a056d952 Mon Sep 17 00:00:00 2001 From: Brandon Low Date: Sat, 21 Jan 2006 23:43:57 +0000 Subject: 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 --- apps/abrepeat.h | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 6 deletions(-) (limited to 'apps/abrepeat.h') 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 #ifdef AB_REPEAT_ENABLE +#include "audio.h" +#include "kernel.h" +#include #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 -- cgit v1.2.3