summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/playlist.c349
1 files changed, 349 insertions, 0 deletions
diff --git a/firmware/playlist.c b/firmware/playlist.c
new file mode 100644
index 0000000000..47764c12b6
--- /dev/null
+++ b/firmware/playlist.c
@@ -0,0 +1,349 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by wavey@wavey.org
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <stdio.h>
21#include <malloc.h>
22#include <time.h>
23#include <stdlib.h>
24#include <string.h>
25#include "playlist.h"
26#include "debug.h"
27#include "disk.h"
28
29/*
30 * load playlist info from disk
31 */
32int reload_playlist_info( playlist_info_t *playlist )
33{
34 debug( "reload_playlist_info()\n" );
35
36 /* this is a TEMP stub version */
37
38 /* return a dummy playlist entry */
39
40 sprintf( playlist->filename, "\\playlists\\1.m3u" );
41
42 playlist->indices_count = 4;
43
44 playlist->indices = (void *)malloc( playlist->indices_count * sizeof( int ) );
45
46 playlist->indices[0] = 3;
47 playlist->indices[1] = 2;
48 playlist->indices[2] = 1;
49 playlist->indices[3] = 9;
50
51 playlist->index = 3;
52
53 return 1;
54}
55
56/*
57 * read the contents of an m3u file from disk and store
58 * the indices of each listed track in an array
59 */
60void load_playlist( playlist_info_t *playlist, const char *filename ) {
61
62 char *m3u_buf = NULL;
63 char debug_message[128];
64
65 sprintf( debug_message, "load_playlist( %s )\n", filename );
66 debug( debug_message );
67
68 /* read file */
69
70 read_file_into_buffer( &m3u_buf, filename );
71
72 /* store playlist filename */
73
74 sprintf( playlist->filename, filename );
75
76 /* add track indices to playlist data structure */
77
78 add_indices_to_playlist( m3u_buf, playlist );
79}
80
81/*
82 * remove any filename and indices associated with the playlist
83 */
84void empty_playlist( playlist_info_t *playlist ) {
85
86 debug( "empty_playlist()\n" );
87
88 playlist->filename[0] = '\0';
89 playlist->indices_count = 0;
90 free( (void *)(playlist->indices) );
91 playlist->indices = NULL;
92 playlist->index = 0;
93}
94
95/*
96 * calculate track offsets within a playlist buffer
97 */
98void add_indices_to_playlist( char *buf, playlist_info_t *playlist )
99{
100 char *p;
101 int i = 0;
102
103 /*debug( "add_indices_to_playlist()\n" ); */
104
105 p = buf;
106
107 /* loop thru buffer, store index whenever we get a new line */
108
109 while( p[i] != '\0' )
110 {
111 /* move thru (any) newlines */
112
113 while( ( p[i] != '\0' ) && ( ( p[i] == '\n' ) || ( p[i] == '\r' ) ) )
114 {
115 i++;
116 }
117
118 /* did we get to the end of the buffer? */
119
120 if( p[i] == '\0' )
121 {
122 break;
123 }
124
125 /* we're now at the start of a new track filename. store index */
126
127 extend_indices( playlist, i );
128
129 /* we're now inside a track name. move to next newline */
130
131 while( ( p[i] != '\0' ) && ( ( p[i] != '\n' ) && ( p[i] != '\r' ) ) )
132 {
133 i++;
134 }
135 }
136}
137
138/*
139 * extend the array of ints
140 */
141void extend_indices( playlist_info_t *playlist, int new_index )
142{
143 /*sprintf( debug_message, "extend_indices(%d)\n", new_index );
144 debug( debug_message );*/
145
146 /* increase array size count */
147
148 playlist->indices_count++;
149
150 /* increase size of array to new count size */
151
152 playlist->indices = (int *)realloc( playlist->indices, (playlist->indices_count) * sizeof( int ) );
153
154 /* add new element to end of array */
155
156 playlist->indices[ playlist->indices_count - 1 ] = new_index;
157}
158
159track_t next_playlist_track( playlist_info_t *playlist ) {
160
161 track_t track;
162 sprintf( track.filename, "boogie" );
163 return track;
164}
165
166/*
167 * randomly rearrange the array of indices for the playlist
168 */
169void randomise_playlist( playlist_info_t *playlist ) {
170
171 unsigned seed;
172 int count = 0;
173 int candidate;
174 int adjusted_candidate;
175 int found_next_number;
176 int index_list[ playlist->indices_count ];
177 int *randomised_list;
178 int i;
179
180 debug( "randomise_playlist()\n" );
181
182 /* create dynamic storage for randomised list so it can be freed later */
183
184 randomised_list = (int *)malloc( playlist->indices_count * sizeof( int ) );
185
186 /* use date as random seed */
187
188 seed = time(0);
189 srand( seed );
190
191 /* randomise entire indices list */
192
193 while( count < playlist->indices_count )
194 {
195 found_next_number = 0;
196
197 /* loop until we successfully get the next number */
198
199 while( ! found_next_number )
200 {
201 /* get the next random number */
202
203 candidate = rand();
204
205 /* the rand is from 0 to RAND_MAX, so adjust to our value range */
206
207 adjusted_candidate = candidate % ( playlist->indices_count + 1 );
208
209 /* has this number already been used? */
210
211 if( is_unused_random_in_list( adjusted_candidate, index_list, playlist->indices_count ) )
212 {
213 /* store value found at random location in original list */
214
215 index_list[ count ] = adjusted_candidate;
216
217 /* leave loop */
218
219 found_next_number = 1;
220 }
221 }
222
223 /* move along */
224
225 count++;
226 }
227
228 /* populate actual replacement list with values
229 * found at indexes specified in index_list */
230
231 for( i = 0; i < playlist->indices_count; i++ )
232 {
233 randomised_list[i] = playlist->indices[ index_list[ i ] ];
234 }
235
236 /* release memory from old array */
237
238 free( (void *)playlist->indices );
239
240 /* use newly randomise list */
241
242 playlist->indices = randomised_list;
243}
244
245/*
246 * check if random number has been used previously
247 */
248int is_unused_random_in_list( int number, int *new_list, int count )
249{
250 int i = 0;
251 int *p = new_list;
252
253 /* examine all in list */
254
255 while( i < count )
256 {
257 /* did we find the number in the list already? */
258
259 if( p[i] == number )
260 {
261 /* yes - return false */
262
263 return 0;
264 }
265
266 /* move along list */
267
268 i++;
269 }
270
271 /* if we got here, we didn't find the number. return true */
272
273 return 1;
274}
275
276/*
277 * dump the details of a track to stdout
278 */
279void display_playlist_track( track_t *track )
280{
281 debugf( "track: %s\n", track->filename );
282}
283
284/*
285 * dump the current playlist info
286 */
287void display_current_playlist( playlist_info_t *playlist )
288{
289 char indices[2048];
290 indices[0]='\0';
291
292 /*debug( "\ndisplay_current_playlist()\n" ); */
293
294 if( playlist->indices_count != 0 )
295 {
296 get_indices_as_string( indices, playlist );
297 }
298
299 debugf( "\nfilename:\t%s\ntotal:\t\t%d\nindices:\t%s\ncurrent index:\t%d\n\n",
300 playlist->filename,
301 playlist->indices_count,
302 indices,
303 playlist->index );
304}
305
306/*
307 * produce a string of the playlist indices
308 */
309void get_indices_as_string( char *string, playlist_info_t *playlist )
310{
311 char tmp[8];
312 int count = 0;
313 int *p = playlist->indices;
314
315 /*debug( "get_indices_as_string()\n" ); */
316
317 while( count < playlist->indices_count ) {
318
319 if( strlen( string ) == 0 )
320 {
321 /* first iteration - no comma */
322
323 sprintf( tmp, "%d", p[count] );
324 }
325 else
326 {
327 /* normal iteration - insert comma */
328
329 sprintf( tmp, ",%d", p[count] );
330 }
331
332 strcat( string, tmp );
333
334 count++;
335 }
336}
337
338/*
339 Session Start (devlin.openprojects.net:alan): Thu Apr 25 15:13:27 2002
340 <alan> for shuffle mode, it's really easy to use the array as a random stack
341 <alan> just peek one randomly and exchange it with the last element in the stack
342 <alan> when stack is void, just grow the stack with its initial size : elements are still there but in a random order
343 <alan> note :
344 <alan> a stack is void when all songs were played
345 <alan> it is an O(1) algo
346 <alan> i don't see how you can do it with a list
347*/
348
349