summaryrefslogtreecommitdiff
path: root/apps/tagtree.c
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2024-09-02 22:55:37 -0400
committerWilliam Wilgus <me.theuser@yahoo.com>2024-09-04 10:58:24 -0400
commit55e1a78cf8201fa2f19f76feeb22cfb9ff526cc7 (patch)
tree09a7510efb7fab878d4506357845bfaad2d9565c /apps/tagtree.c
parent34e54b33f790858998de6f224458b93e54424ed9 (diff)
downloadrockbox-55e1a78cf8201fa2f19f76feeb22cfb9ff526cc7.tar.gz
rockbox-55e1a78cf8201fa2f19f76feeb22cfb9ff526cc7.zip
Reworks to the shuffle system
spread remaining songs amongst segments bit of code clean-up Change-Id: I198b54978eb9d111e060bb9aca3d71c348cad7c9
Diffstat (limited to 'apps/tagtree.c')
-rw-r--r--apps/tagtree.c91
1 files changed, 62 insertions, 29 deletions
diff --git a/apps/tagtree.c b/apps/tagtree.c
index 8f6b1419a9..562ad44863 100644
--- a/apps/tagtree.c
+++ b/apps/tagtree.c
@@ -2139,8 +2139,10 @@ static void swap_array_bool(bool *a, bool *b)
2139} 2139}
2140 2140
2141/** 2141/**
2142 * Randomly shuffle an array using the Fisher-Yates algorithm : https://en.wikipedia.org/wiki/Random_permutation 2142 * Randomly shuffle an array using the Fisher-Yates algorithm :
2143 * This algorithm has a linear complexity. Don't forget to srand before call to use it with a relevant seed. 2143 * https://en.wikipedia.org/wiki/Random_permutation
2144 * This algorithm has a linear complexity. Don't forget to srand
2145 * before call to use it with a relevant seed.
2144 */ 2146 */
2145static void shuffle_bool_array(bool array[], int size) 2147static void shuffle_bool_array(bool array[], int size)
2146{ 2148{
@@ -2151,14 +2153,15 @@ static void shuffle_bool_array(bool array[], int size)
2151 } 2153 }
2152} 2154}
2153 2155
2154static bool fill_selective_random_playlist_indexes(int current_segment_n, int current_segment_max_available_space) 2156static bool fill_random_playlist_indexes(int current_segment_n,
2157 int current_segment_max_space)
2155{ 2158{
2156 if (current_segment_n == 0 || current_segment_max_available_space == 0) 2159 if (current_segment_n == 0 || current_segment_max_space == 0)
2157 return false; 2160 return false;
2158 if (current_segment_max_available_space > current_segment_n) 2161 if (current_segment_max_space > current_segment_n)
2159 current_segment_max_available_space = current_segment_n; 2162 current_segment_max_space = current_segment_n;
2160 for (int i = 0; i < current_segment_n; i++) 2163 for (int i = 0; i < current_segment_n; i++)
2161 selective_random_playlist_indexes[i] = i < current_segment_max_available_space; 2164 selective_random_playlist_indexes[i] = i < current_segment_max_space;
2162 srand(current_tick); 2165 srand(current_tick);
2163 shuffle_bool_array(selective_random_playlist_indexes, current_segment_n); 2166 shuffle_bool_array(selective_random_playlist_indexes, current_segment_n);
2164 return true; 2167 return true;
@@ -2205,20 +2208,27 @@ static bool insert_all_playlist(struct tree_context *c,
2205 return false; 2208 return false;
2206 } 2209 }
2207 } 2210 }
2211
2208 last_tick = current_tick + HZ/2; /* Show splash after 0.5 seconds have passed */ 2212 last_tick = current_tick + HZ/2; /* Show splash after 0.5 seconds have passed */
2209 splash_progress_set_delay(HZ / 2); /* wait 1/2 sec before progress */ 2213 splash_progress_set_delay(HZ / 2); /* wait 1/2 sec before progress */
2210 n = c->filesindir; 2214 n = c->filesindir;
2215
2216 int max_playlist_size = playlist_get_current()->max_playlist_size;
2217 int playlist_amount = playlist_get_current()->amount;
2211 int segment_size = INSERT_ALL_PLAYLIST_MAX_SEGMENT_SIZE; 2218 int segment_size = INSERT_ALL_PLAYLIST_MAX_SEGMENT_SIZE;
2212 int segments_count = n / segment_size; 2219 int segments_count = n / segment_size;
2213 int leftovers_segment_size = n % segment_size; 2220 int leftovers_segment_size = n - (segments_count * segment_size);
2214 bool fill_randomly = false; 2221 bool fill_randomly = false;
2215 if (playlist == NULL) { 2222
2216 bool will_exceed = n > playlist_get_current()->max_playlist_size; 2223 if (playlist == NULL)
2224 {
2225 bool will_exceed = n > max_playlist_size;
2217 fill_randomly = will_exceed; 2226 fill_randomly = will_exceed;
2218 } 2227 }
2219 if (leftovers_segment_size > 0 && fill_randomly) 2228 if (leftovers_segment_size > 0 && fill_randomly)
2220 { 2229 {
2221 /* We need to re-balance the segments so the randomness will be coherent and balanced the same through all segments */ 2230 /* We need to re-balance the segments so the randomness will be
2231 * coherent and balanced the same through all segments */
2222 while (leftovers_segment_size + segments_count < segment_size) 2232 while (leftovers_segment_size + segments_count < segment_size)
2223 { 2233 {
2224 segment_size--; // -1 to all other segments 2234 segment_size--; // -1 to all other segments
@@ -2227,40 +2237,58 @@ static bool insert_all_playlist(struct tree_context *c,
2227 } 2237 }
2228 if (leftovers_segment_size > 0) 2238 if (leftovers_segment_size > 0)
2229 segments_count += 1; 2239 segments_count += 1;
2230 int max_available_space = playlist_get_current()->max_playlist_size - playlist_get_current()->amount; 2240
2231 int max_available_space_per_segment = max_available_space / segments_count; 2241 int max_available_space = max_playlist_size - playlist_amount;
2242 int max_space_per_segment = max_available_space / segments_count;
2243
2244 int remaining_space =
2245 max_available_space - (max_space_per_segment * segments_count);
2246
2232 if (fill_randomly) 2247 if (fill_randomly)
2233 { 2248 {
2234 talk_id(LANG_RANDOM_SHUFFLE_RANDOM_SELECTIVE_SONGS_SUMMARY, true); 2249 talk_id(LANG_RANDOM_SHUFFLE_RANDOM_SELECTIVE_SONGS_SUMMARY, true);
2235 splashf(HZ * 3, str(LANG_RANDOM_SHUFFLE_RANDOM_SELECTIVE_SONGS_SUMMARY), 2250 splashf(HZ * 3, str(LANG_RANDOM_SHUFFLE_RANDOM_SELECTIVE_SONGS_SUMMARY),
2236 max_available_space_per_segment * segments_count); 2251 max_space_per_segment * segments_count + remaining_space);
2237 /* logf("sz=%d lsz=%d sc=%d rcps=%d", segment_size, leftovers_segment_size, 2252 /* logf("sz=%d lsz=%d sc=%d rcps=%d", segment_size, leftovers_segment_size,
2238 segments_count, max_available_space_per_segment); */ 2253 segments_count, max_available_space_per_segment); */
2239 } 2254 }
2255
2256 bool exit_loop_now = false;
2240 for (int i = 0; i < segments_count; i++) 2257 for (int i = 0; i < segments_count; i++)
2241 { 2258 {
2242 bool is_leftovers_segment = leftovers_segment_size > 0 && i + 1 >= segments_count; 2259 int cur_segment_size = segment_size;
2260 int cur_segment_start = i * segment_size;
2261 int cur_segment_end;
2262 int space_per_segment = max_space_per_segment;
2263
2264 if (i + 1 >= segments_count && leftovers_segment_size > 0)
2265 {
2266 /* add any remaining tracks to the last segment */
2267 space_per_segment += remaining_space;
2268 cur_segment_size = leftovers_segment_size;
2269 }
2270 else if (fill_randomly)
2271 {
2272 /* add an extra track to some of the segments */
2273 if (remaining_space > 0 && (i & 7) != 7)
2274 {
2275 space_per_segment++;
2276 remaining_space--;
2277 }
2278 }
2243 if (fill_randomly) 2279 if (fill_randomly)
2244 { 2280 {
2245 if (is_leftovers_segment) 2281 fill_randomly = fill_random_playlist_indexes(cur_segment_size,
2246 fill_randomly = fill_selective_random_playlist_indexes(leftovers_segment_size, max_available_space_per_segment); 2282 space_per_segment);
2247 else
2248 fill_randomly = fill_selective_random_playlist_indexes(segment_size, max_available_space_per_segment);
2249 } 2283 }
2250 bool exit_loop_now = false; 2284
2251 int cur_segment_start = i * segment_size; 2285 cur_segment_end = cur_segment_start + cur_segment_size;
2252 int cur_segment_end; 2286
2253 if (is_leftovers_segment)
2254 cur_segment_end = cur_segment_start + leftovers_segment_size;
2255 else
2256 cur_segment_end = cur_segment_start + segment_size;
2257 for (int j = cur_segment_start; j < cur_segment_end && !exit_loop_now; j++) 2287 for (int j = cur_segment_start; j < cur_segment_end && !exit_loop_now; j++)
2258 { 2288 {
2259 if (fill_randomly && !selective_random_playlist_indexes[j % segment_size])
2260 continue;
2261 splash_progress(j, n, "%s (%s)", str(LANG_WAIT), str(LANG_OFF_ABORT));
2262 if (TIME_AFTER(current_tick, last_tick + HZ/4)) 2289 if (TIME_AFTER(current_tick, last_tick + HZ/4))
2263 { 2290 {
2291 splash_progress(j, n, "%s (%s)", str(LANG_WAIT), str(LANG_OFF_ABORT));
2264 if (action_userabort(TIMEOUT_NOBLOCK)) 2292 if (action_userabort(TIMEOUT_NOBLOCK))
2265 { 2293 {
2266 exit_loop_now = true; 2294 exit_loop_now = true;
@@ -2268,8 +2296,13 @@ static bool insert_all_playlist(struct tree_context *c,
2268 } 2296 }
2269 last_tick = current_tick; 2297 last_tick = current_tick;
2270 } 2298 }
2299
2300 if (fill_randomly && !selective_random_playlist_indexes[j % segment_size])
2301 continue;
2302
2271 if (!tagcache_retrieve(&tcs, tagtree_get_entry(c, j)->extraseek, tcs.type, buf, sizeof buf)) 2303 if (!tagcache_retrieve(&tcs, tagtree_get_entry(c, j)->extraseek, tcs.type, buf, sizeof buf))
2272 continue; 2304 continue;
2305
2273 if (playlist == NULL) 2306 if (playlist == NULL)
2274 { 2307 {
2275 if (playlist_insert_track(NULL, buf, position, queue, false) < 0) { 2308 if (playlist_insert_track(NULL, buf, position, queue, false) < 0) {