/*************************************************************************** * __________ __ ___. * 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 "playlist.h" #include #include "sprintf.h" #include "debug.h" #include "mpeg.h" #include "lcd.h" #include "kernel.h" #include "settings.h" #include "status.h" #include "applimits.h" #ifdef HAVE_LCD_BITMAP #include "icons.h" #include "widgets.h" #endif #include "lang.h" static struct playlist_info playlist; #define PLAYLIST_BUFFER_SIZE (AVERAGE_FILENAME_LENGTH*MAX_FILES_IN_DIR) static unsigned char playlist_buffer[PLAYLIST_BUFFER_SIZE]; static int playlist_end_pos = 0; static char now_playing[MAX_PATH+1]; void playlist_clear(void) { playlist_end_pos = 0; playlist_buffer[0] = 0; } int playlist_add(char *filename) { int len = strlen(filename); if(len+2 > PLAYLIST_BUFFER_SIZE - playlist_end_pos) return -1; strcpy(&playlist_buffer[playlist_end_pos], filename); playlist_end_pos += len; playlist_buffer[playlist_end_pos++] = '\n'; playlist_buffer[playlist_end_pos] = '\0'; return 0; } static int get_next_index(int steps) { int current_index = playlist.index; int next_index = -1; switch (global_settings.repeat_mode) { case REPEAT_OFF: if (current_index < playlist.first_index) current_index += playlist.amount; current_index -= playlist.first_index; next_index = current_index+steps; if ((next_index < 0) || (next_index >= playlist.amount)) next_index = -1; else next_index = (next_index+playlist.first_index)%playlist.amount; break; case REPEAT_ONE: next_index = current_index; break; case REPEAT_ALL: default: next_index = (current_index+steps) % playlist.amount; while (next_index < 0) next_index += playlist.amount; break; } return next_index; } /* the mpeg thread might ask us */ int playlist_amount(void) { return playlist.amount; } int playlist_first_index(void) { return playlist.first_index; } char *playlist_name(char *buf, int buf_size) { char *sep; snprintf(buf, buf_size, "%s", playlist.filename+playlist.dirlen); if (0 == buf[0]) return NULL; /* Remove extension */ sep = strrchr(buf, '.'); if (NULL != sep) *sep = 0; return buf; } int playlist_next(int steps) { playlist.index = get_next_index(steps); return playlist.index; } char* playlist_peek(int steps) { int seek; int max; int fd; int i; char *buf; char dir_buf[MAX_PATH+1]; char *dir_end; int index; index = get_next_index(steps); if (index >= 0) seek = playlist.indices[index]; else return NULL; if(playlist.in_ram) { buf = playlist_buffer + seek; max = playlist_end_pos - seek; } else { fd = open(playlist.filename, O_RDONLY); if(-1 != fd) { buf = playlist_buffer; lseek(fd, seek, SEEK_SET); max = read(fd, buf, MAX_PATH); close(fd); } else return NULL; } /* Zero-terminate the file name */ seek=0; while((buf[seek] != '\n') && (buf[seek] != '\r') && (seek < max)) seek++; /* Now work back killing white space */ while((buf[seek-1] == ' ') || (buf[seek-1] == '\t')) seek--; buf[seek]=0; /* replace backslashes with forward slashes */ for ( i=0; i= MAX_PLAYLIST_SIZE ) { if(!playlist.in_ram) close(fd); lcd_clear_display(); lcd_puts(0,0,str(LANG_PLAYINDICES_PLAYLIST)); lcd_puts(0,1,str(LANG_PLAYINDICES_BUFFER)); lcd_update(); sleep(HZ*2); lcd_clear_display(); return; } /* Update the screen if it takes very long */ if(!playlist.in_ram) { if ( current_tick >= next_tick ) { next_tick = current_tick + HZ; snprintf(line, sizeof line, str(LANG_PLAYINDICES_AMOUNT), playlist.amount); lcd_puts(0,1,line); status_draw(); lcd_update(); } } } } } i+= count; if(playlist.in_ram) break; } if(!playlist.in_ram) { snprintf(line, sizeof line, str(LANG_PLAYINDICES_AMOUNT), playlist.amount); lcd_puts(0,1,line); status_draw(); lcd_update(); close(fd); } } /* * randomly rearrange the array of indices for the playlist */ void randomise_playlist( unsigned int seed ) { int count; int candidate; int store; /* seed with the given seed */ srand( seed ); /* randomise entire indices list */ for(count = playlist.amount - 1; count >= 0; count--) { /* the rand is from 0 to RAND_MAX, so adjust to our value range */ candidate = rand() % (count + 1); /* now swap the values at the 'count' and 'candidate' positions */ store = playlist.indices[candidate]; playlist.indices[candidate] = playlist.indices[count]; playlist.indices[count] = store; } mpeg_flush_and_reload_tracks(); } static int compare(const void* p1, const void* p2) { int* e1 = (int*) p1; int* e2 = (int*) p2; return *e1 - *e2; } /* * Sort the array of indices for the playlist. If start_current is true then * set the index to the new index of the current song. */ void sort_playlist(bool start_current) { int i; int current = playlist.indices[playlist.index]; if (playlist.amount > 0) { qsort(&playlist.indices, playlist.amount, sizeof(playlist.indices[0]), compare); } if (start_current) { /* Set the index to the current song */ for (i=0; i