1#include "PlayList.h" 2 3#include <OS.h> 4 5#include <stdlib.h> 6#include <string.h> 7 8//#define DEBUG_PLAYLIST 9 10#ifdef DEBUG_PLAYLIST 11#include <stdio.h> 12#define STRACE(x) printf x 13#else 14#define STRACE(x) /* nothing */ 15#endif 16 17 18PlayList::PlayList(int16 count, int16 start) 19 : 20 fTrackCount(count), 21 fTrackIndex(0), 22 fStartingTrack(start), 23 fRandom(false), 24 fLoop(false) 25{ 26 STRACE(("PlayList(count=%d,start=%d)\n",count,start)); 27 28 srand(real_time_clock_usecs()); 29 30 if (fTrackCount < 0) 31 fTrackCount = 0; 32 else if (fTrackCount > 500) 33 fTrackCount = 500; 34 35 if (fStartingTrack >= fTrackCount) 36 fStartingTrack = fTrackCount - 1; 37 38 if (fStartingTrack < 1) 39 fStartingTrack = 1; 40 41 memset(fTrackList, -1, 500); 42 43 Unrandomize(); 44} 45 46 47void 48PlayList::SetTrackCount(const int16 &count) 49{ 50 fLocker.Lock(); 51 52 STRACE(("PlayList::SetTrackCount(%d)\n",count)); 53 54 if (count <= 0) { 55 fTrackCount = 0; 56 fTrackIndex = 0; 57 } 58 else if (count > 500) 59 fTrackCount = 500; 60 else 61 fTrackCount = count; 62 63 memset(fTrackList, -1, 500); 64 SetShuffle(IsShuffled()); 65 66 fLocker.Unlock(); 67} 68 69 70void 71PlayList::SetStartingTrack(const int16 &start) 72{ 73 fLocker.Lock(); 74 75 STRACE(("PlayList::SetStartingTrack(%d)\n",start)); 76 77 fStartingTrack = start; 78 79 fLocker.Unlock(); 80} 81 82 83void 84PlayList::Rewind() 85{ 86 STRACE(("PlayList::Rewind()\n")); 87 fLocker.Lock(); 88 89 fTrackIndex = 0; 90 91 fLocker.Unlock(); 92} 93 94 95void 96PlayList::SetShuffle(const bool &random) 97{ 98 STRACE(("PlayList::SetShuffle(%s)\n", random ? "random" : "sequential")); 99 fLocker.Lock(); 100 101 if (random) 102 Randomize(); 103 else 104 Unrandomize(); 105 106 fRandom = random; 107 108 fLocker.Unlock(); 109} 110 111 112void 113PlayList::SetLoop(const bool &loop) 114{ 115 STRACE(("PlayList::SetLoop(%s)\n", loop ? "loop" : "non-loop")); 116 fLocker.Lock(); 117 118 fLoop = loop; 119 120 fLocker.Unlock(); 121} 122 123 124void 125PlayList::SetCurrentTrack(const int16 &track) 126{ 127 STRACE(("PlayList::SetCurrentTrack(%d)\n",track)); 128 129 if (track < 0 || track > fTrackCount) 130 return; 131 132 fLocker.Lock(); 133 134 for (int16 i = 0; i < fTrackCount; i++) { 135 if (fTrackList[i] == track) { 136 fTrackIndex = i; 137 break; 138 } 139 } 140 141 fLocker.Unlock(); 142} 143 144 145int16 146PlayList::GetCurrentTrack() 147{ 148 fLocker.Lock(); 149 150 int16 value = fTrackList[fTrackIndex]; 151// STRACE(("PlayList::GetCurrentTrack()=%d\n",value)); 152 153 fLocker.Unlock(); 154 return value; 155} 156 157 158int16 159PlayList::GetNextTrack() 160{ 161 fLocker.Lock(); 162 163 if (fTrackCount < 1) { 164 fLocker.Unlock(); 165 STRACE(("PlayList::GetNextTrack()=-1 (no tracks)\n")); 166 return -1; 167 } 168 169 if (fTrackIndex > (fTrackCount - fStartingTrack)) { 170 if (fLoop) 171 fTrackIndex = 0; 172 else { 173 fLocker.Unlock(); 174 STRACE(("PlayList::GetNextTrack()=-1 (track index out of range)\n")); 175 return -1; 176 } 177 } 178 else 179 fTrackIndex++; 180 181 int16 value = fTrackList[fTrackIndex]; 182 STRACE(("PlayList::GetNextTrack()=%d\n",value)); 183 184 fLocker.Unlock(); 185 return value; 186} 187 188 189int16 190PlayList::GetPreviousTrack() 191{ 192 fLocker.Lock(); 193 194 if (fTrackCount < 1) { 195 fLocker.Unlock(); 196 STRACE(("PlayList::GetPreviousTrack()=-1 (no tracks)\n")); 197 return -1; 198 } 199 200 if (fTrackIndex == 0) { 201 if (fLoop) 202 fTrackIndex = (fTrackCount - fStartingTrack); 203 else { 204 fLocker.Unlock(); 205 STRACE(("PlayList::GetPreviousTrack()=-1 (track index out of range)\n")); 206 return -1; 207 } 208 } 209 else 210 fTrackIndex--; 211 212 int16 value = fTrackList[fTrackIndex]; 213 STRACE(("PlayList::GetPreviousTrack()=%d\n",value)); 214 fLocker.Unlock(); 215 return value; 216} 217 218 219int16 220PlayList::GetLastTrack() 221{ 222 fLocker.Lock(); 223 224 if (fTrackCount < 1) { 225 fLocker.Unlock(); 226 STRACE(("PlayList::GetLastTrack()=-1 (no tracks)\n")); 227 return -1; 228 } 229 230 fTrackIndex = fTrackCount - 1; 231 int16 value = fTrackList[fTrackIndex]; 232 STRACE(("PlayList::GetLastTrack()=%d\n",value)); 233 fLocker.Unlock(); 234 return value; 235} 236 237 238int16 239PlayList::GetFirstTrack() 240{ 241 fLocker.Lock(); 242 243 if (fTrackCount < 1) { 244 fLocker.Unlock(); 245 STRACE(("PlayList::GetFirstTrack()=-1 (no tracks)\n")); 246 return -1; 247 } 248 249 fTrackIndex = 0; 250 int16 value = fTrackList[fTrackIndex]; 251 STRACE(("PlayList::GetFirstTrack()=%d\n",value)); 252 fLocker.Unlock(); 253 return value; 254} 255 256 257void 258PlayList::Randomize() 259{ 260 STRACE(("PlayList::Randomize()\n")); 261 262 // Reinitialize the count 263 for (int16 i = fStartingTrack; i <= fTrackCount; i++) 264 fTrackList[i - fStartingTrack] = i; 265 266 // There are probably *much* better ways to do this, 267 // but this is the only one I could think of. :( 268 269 int32 listcount = (fTrackCount - fStartingTrack); 270 int32 swapcount = listcount * 2; 271 272 int16 temp, first, second; 273 for (int32 i = 0; i < swapcount; i++) { 274 // repeatedly pick two elements at random and swap them 275 // This way we are sure to not have any duplicates and still have 276 // all tracks eventually be played. 277 278 first = (int16)(listcount * ((float)rand() / RAND_MAX)); 279 second = (int16)(listcount * ((float)rand() / RAND_MAX)); 280 281 temp = fTrackList[first]; 282 fTrackList[first] = fTrackList[second]; 283 fTrackList[second] = temp; 284 } 285 286 #ifdef DEBUG_PLAYLIST 287 for (int16 i = fStartingTrack; i <= fTrackCount; i++) 288 printf("\tSlot %d: track %d\n", i, fTrackList[i]); 289 #endif 290} 291 292 293void 294PlayList::Unrandomize() 295{ 296 STRACE(("PlayList::Unrandomize()\n")); 297 for (int16 i = fStartingTrack; i <= fTrackCount; i++) 298 fTrackList[i - fStartingTrack] = i; 299} 300