From 16cd64236e4e01dabeafd59c6462f538788c1772 Mon Sep 17 00:00:00 2001 From: Stuart Martin Date: Tue, 30 Apr 2002 19:16:15 +0000 Subject: functions for playlist manipulation git-svn-id: svn://svn.rockbox.org/rockbox/trunk@333 a1c6a512-1295-4272-9138-f99709370657 --- firmware/playlist.c | 349 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 349 insertions(+) create mode 100644 firmware/playlist.c (limited to 'firmware/playlist.c') 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 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 by wavey@wavey.org + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include "playlist.h" +#include "debug.h" +#include "disk.h" + +/* + * load playlist info from disk + */ +int reload_playlist_info( playlist_info_t *playlist ) +{ + debug( "reload_playlist_info()\n" ); + + /* this is a TEMP stub version */ + + /* return a dummy playlist entry */ + + sprintf( playlist->filename, "\\playlists\\1.m3u" ); + + playlist->indices_count = 4; + + playlist->indices = (void *)malloc( playlist->indices_count * sizeof( int ) ); + + playlist->indices[0] = 3; + playlist->indices[1] = 2; + playlist->indices[2] = 1; + playlist->indices[3] = 9; + + playlist->index = 3; + + return 1; +} + +/* + * read the contents of an m3u file from disk and store + * the indices of each listed track in an array + */ +void load_playlist( playlist_info_t *playlist, const char *filename ) { + + char *m3u_buf = NULL; + char debug_message[128]; + + sprintf( debug_message, "load_playlist( %s )\n", filename ); + debug( debug_message ); + + /* read file */ + + read_file_into_buffer( &m3u_buf, filename ); + + /* store playlist filename */ + + sprintf( playlist->filename, filename ); + + /* add track indices to playlist data structure */ + + add_indices_to_playlist( m3u_buf, playlist ); +} + +/* + * remove any filename and indices associated with the playlist + */ +void empty_playlist( playlist_info_t *playlist ) { + + debug( "empty_playlist()\n" ); + + playlist->filename[0] = '\0'; + playlist->indices_count = 0; + free( (void *)(playlist->indices) ); + playlist->indices = NULL; + playlist->index = 0; +} + +/* + * calculate track offsets within a playlist buffer + */ +void add_indices_to_playlist( char *buf, playlist_info_t *playlist ) +{ + char *p; + int i = 0; + + /*debug( "add_indices_to_playlist()\n" ); */ + + p = buf; + + /* loop thru buffer, store index whenever we get a new line */ + + while( p[i] != '\0' ) + { + /* move thru (any) newlines */ + + while( ( p[i] != '\0' ) && ( ( p[i] == '\n' ) || ( p[i] == '\r' ) ) ) + { + i++; + } + + /* did we get to the end of the buffer? */ + + if( p[i] == '\0' ) + { + break; + } + + /* we're now at the start of a new track filename. store index */ + + extend_indices( playlist, i ); + + /* we're now inside a track name. move to next newline */ + + while( ( p[i] != '\0' ) && ( ( p[i] != '\n' ) && ( p[i] != '\r' ) ) ) + { + i++; + } + } +} + +/* + * extend the array of ints + */ +void extend_indices( playlist_info_t *playlist, int new_index ) +{ + /*sprintf( debug_message, "extend_indices(%d)\n", new_index ); + debug( debug_message );*/ + + /* increase array size count */ + + playlist->indices_count++; + + /* increase size of array to new count size */ + + playlist->indices = (int *)realloc( playlist->indices, (playlist->indices_count) * sizeof( int ) ); + + /* add new element to end of array */ + + playlist->indices[ playlist->indices_count - 1 ] = new_index; +} + +track_t next_playlist_track( playlist_info_t *playlist ) { + + track_t track; + sprintf( track.filename, "boogie" ); + return track; +} + +/* + * randomly rearrange the array of indices for the playlist + */ +void randomise_playlist( playlist_info_t *playlist ) { + + unsigned seed; + int count = 0; + int candidate; + int adjusted_candidate; + int found_next_number; + int index_list[ playlist->indices_count ]; + int *randomised_list; + int i; + + debug( "randomise_playlist()\n" ); + + /* create dynamic storage for randomised list so it can be freed later */ + + randomised_list = (int *)malloc( playlist->indices_count * sizeof( int ) ); + + /* use date as random seed */ + + seed = time(0); + srand( seed ); + + /* randomise entire indices list */ + + while( count < playlist->indices_count ) + { + found_next_number = 0; + + /* loop until we successfully get the next number */ + + while( ! found_next_number ) + { + /* get the next random number */ + + candidate = rand(); + + /* the rand is from 0 to RAND_MAX, so adjust to our value range */ + + adjusted_candidate = candidate % ( playlist->indices_count + 1 ); + + /* has this number already been used? */ + + if( is_unused_random_in_list( adjusted_candidate, index_list, playlist->indices_count ) ) + { + /* store value found at random location in original list */ + + index_list[ count ] = adjusted_candidate; + + /* leave loop */ + + found_next_number = 1; + } + } + + /* move along */ + + count++; + } + + /* populate actual replacement list with values + * found at indexes specified in index_list */ + + for( i = 0; i < playlist->indices_count; i++ ) + { + randomised_list[i] = playlist->indices[ index_list[ i ] ]; + } + + /* release memory from old array */ + + free( (void *)playlist->indices ); + + /* use newly randomise list */ + + playlist->indices = randomised_list; +} + +/* + * check if random number has been used previously + */ +int is_unused_random_in_list( int number, int *new_list, int count ) +{ + int i = 0; + int *p = new_list; + + /* examine all in list */ + + while( i < count ) + { + /* did we find the number in the list already? */ + + if( p[i] == number ) + { + /* yes - return false */ + + return 0; + } + + /* move along list */ + + i++; + } + + /* if we got here, we didn't find the number. return true */ + + return 1; +} + +/* + * dump the details of a track to stdout + */ +void display_playlist_track( track_t *track ) +{ + debugf( "track: %s\n", track->filename ); +} + +/* + * dump the current playlist info + */ +void display_current_playlist( playlist_info_t *playlist ) +{ + char indices[2048]; + indices[0]='\0'; + + /*debug( "\ndisplay_current_playlist()\n" ); */ + + if( playlist->indices_count != 0 ) + { + get_indices_as_string( indices, playlist ); + } + + debugf( "\nfilename:\t%s\ntotal:\t\t%d\nindices:\t%s\ncurrent index:\t%d\n\n", + playlist->filename, + playlist->indices_count, + indices, + playlist->index ); +} + +/* + * produce a string of the playlist indices + */ +void get_indices_as_string( char *string, playlist_info_t *playlist ) +{ + char tmp[8]; + int count = 0; + int *p = playlist->indices; + + /*debug( "get_indices_as_string()\n" ); */ + + while( count < playlist->indices_count ) { + + if( strlen( string ) == 0 ) + { + /* first iteration - no comma */ + + sprintf( tmp, "%d", p[count] ); + } + else + { + /* normal iteration - insert comma */ + + sprintf( tmp, ",%d", p[count] ); + } + + strcat( string, tmp ); + + count++; + } +} + +/* + Session Start (devlin.openprojects.net:alan): Thu Apr 25 15:13:27 2002 + for shuffle mode, it's really easy to use the array as a random stack + just peek one randomly and exchange it with the last element in the stack + when stack is void, just grow the stack with its initial size : elements are still there but in a random order + note : + a stack is void when all songs were played + it is an O(1) algo + i don't see how you can do it with a list +*/ + + -- cgit v1.2.3