⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 playlist.c

📁 一款MP3 Player Firmware 的原代码,非常有参考价值
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <string.h>#include "as31glue.h"#include "printf.h"#include "paulmon2.h"#include "display.h"#include "malloc.h"#include "dirlist.h"#include "playlist.h"#include "stricmp.h"#include "rand.h"#include "main.h"simm_id current_playlist;simm_id first_playlist;simm_id last_playlist;simm_id start_rand_playlist;simm_id head_rand_playlist;simm_id tail_rand_playlist;simm_id start_all_rand;simm_id head_all_rand;simm_id tail_all_rand;unsigned int num_unrand_lists;unsigned int num_unrand_all_files;static playlist_list_t *dirrand_current_list;static unsigned int addr6_backup, addr7_backup;play_modes_t play_mode;static void dirrand_initialize(void);static simm_id dirrand_new_list(simm_id /* playlist_list_t */ list_id, unsigned char use_current_file);static void dirrand_randomize_incremental(simm_id /* playlist_t */ current);static void plstrand_initialize(void);static void plstrand_randomize_incremental(simm_id /* playlist_list_t */ list_id);static void allrand_initialize(void);static void allrand_randomize_incremental(simm_id /* playlist_list_t */ list_id);// #define VERBOSE_DEBUGvoid playlist_init(void){  first_playlist=0;  last_playlist=0;  current_playlist=0;}extern data simm_id temp_id;void playlist_create(simm_id pl_name) {  // simm_id temp_id;  playlist_list_t * pl_l_struct;  temp_id = simm_malloc((unsigned int)(sizeof(struct playlist_list_struct)));  if(first_playlist == 0)    {      first_playlist = temp_id;      last_playlist = temp_id;      pl_l_struct = addr6(temp_id);      pl_l_struct->prev_sequential = 0;    }  else    {      pl_l_struct = Addr6(last_playlist);      pl_l_struct->next_sequential = temp_id;      pl_l_struct = addr6(temp_id);      pl_l_struct->prev_sequential = last_playlist;      last_playlist = temp_id;    }  current_playlist = temp_id;  pl_l_struct->next_sequential = 0;  pl_l_struct->playlist_start_sequential = 0;  pl_l_struct->playlist_end_sequential = 0;  pl_l_struct->num_unrand_files = 0;  pl_l_struct->name = pl_name;  //printf("playlist %s created\r\n", Addr6(pl_name));}void playlist_add_file(simm_id /* struct filelist_struct */ fl_rec) // Add file to current playlist{  // xdata simm_id temp_id;  playlist_list_t * pl_l_struct;  playlist_t * pl_struct;  filelist_t * fl_struct;    pl_l_struct = Addr6(current_playlist);  pl_l_struct->num_unrand_files++;  temp_id = simm_malloc((unsigned int)(sizeof(struct playlist_struct)));  if (pl_l_struct->playlist_start_sequential == 0)    {      pl_l_struct->playlist_start_sequential = temp_id;      pl_l_struct->playlist_end_sequential = temp_id;      pl_struct = addr7(temp_id);      memset(pl_struct, 0, sizeof(struct playlist_struct));      pl_struct->prev_sequential = 0;  // done by memset    }  else    {      pl_struct = Addr7(pl_l_struct->playlist_end_sequential);      pl_struct->next_sequential = temp_id;       pl_struct = addr7(temp_id);      memset(pl_struct, 0, sizeof(struct playlist_struct));      pl_struct->prev_sequential = pl_l_struct->playlist_end_sequential;      pl_l_struct->playlist_end_sequential = temp_id;    }  pl_struct->playlist = current_playlist;  pl_struct->next_sequential = 0;  // done by memset  pl_struct->fl_rec = fl_rec;  fl_struct = Addr6(fl_rec);  fl_struct->pl_entry = temp_id;}void playlist_show(void) // Shows the Current Playlist{	playlist_t * pl_struct;	filelist_t * fl_struct;  	temp_id = ((playlist_list_t *)Addr7(current_playlist))->playlist_start_sequential;	while(temp_id != 0) {		pl_struct = addr6(temp_id);		fl_struct = Addr7(pl_struct->fl_rec);		print_hex32(pl_struct->prev_sequential);		print_hex32(temp_id);		print_hex32(pl_struct->next_sequential);		print_str(Addr6(fl_struct->long_name));		print_crlf();		temp_id = ((playlist_t *)addr6(temp_id))->next_sequential;	}}void playlist_delete(playlist_list_t *p){	print("deleting empty playlist: ");	print_str(Addr7(p->name));	print_crlf();	if (p->prev_sequential) {		((playlist_list_t *)Addr7(p->prev_sequential))->next_sequential =			p->next_sequential;	} else {		first_playlist = p->next_sequential;	}	if (p->next_sequential) {		((playlist_list_t *)Addr7(p->next_sequential))->prev_sequential =			p->prev_sequential;	} else {		last_playlist = p->next_sequential;	}	simm_free(simm_id_from_pointer(p));}void playlist_purge_empty(void){	playlist_list_t * pl_l_struct;		temp_id = first_playlist;	while (temp_id) {		pl_l_struct = addr6(temp_id);		temp_id = pl_l_struct->next_sequential;		if (pl_l_struct->playlist_start_sequential == 0) {			playlist_delete(pl_l_struct);		}	}}void playlist_show_all() // Show all playlists{	playlist_list_t * pl_l_struct;	current_playlist = first_playlist;	while (current_playlist != 0) {		pl_l_struct = Addr6(current_playlist);		print("\r\nPlaylist: ");		print_hex32(pl_l_struct->prev_sequential);		print_hex32(current_playlist);		print_hex32(pl_l_struct->next_sequential);		print("\"");		print_str(Addr7(pl_l_struct->name));		print("\"\r\n");		playlist_show();		print_crlf();		pl_l_struct = Addr6(current_playlist);		current_playlist = pl_l_struct->next_sequential;	}	current_playlist = first_playlist; // Reset to first}void play_mode_change(void){	switch (play_mode) {	case MODE_DIRONLY:    // sequential within one directory	case MODE_SEQNTIAL:   // sequential among all directories		break;	case MODE_PLSTRAND:   // seq within each dir, choose dirs randomly		plstrand_initialize();		update_rand_seed_needed = 1;		break;	case MODE_DIRRAND:    // randomly choose files within 1 dir		dirrand_initialize();		update_rand_seed_needed = 1;		break;	case MODE_ALLRAND:    // randomly choose files among all dirs	case MODE_KEYRAND:    // play all files sequentially until a key is pressed		allrand_initialize();		update_rand_seed_needed = 1;		break;	default:		break;	}	update_mode_needed = 1;	update_playlist_state_needed = 1;	param_restart_write_timer(15);}void save_play_mode(void){	ibuf[0] = play_mode;	write_flash_param(PARAM_PLAY_MODE, ibuf);	update_mode_needed = 0;	print("saved play mode = ");	print_hex16(play_mode);	print_crlf();}void play_mode_toggle(void){	if (play_mode == MODE_SEQNTIAL) {		play_mode = MODE_ALLRAND;	} else {		play_mode = MODE_SEQNTIAL;	}	play_mode_change();}void play_mode_next(void){	printf("play_mode = %d\r\n", play_mode);	if (play_mode >= MODE_MAX) {		play_mode = MODE_MIN;	} else {		play_mode++;	}	printf("play_mode = %d\r\n", play_mode);	play_mode_change();}void play_mode_prev(void){	if (play_mode <= MODE_MIN) {		play_mode = MODE_MAX;	} else {		play_mode--;	}	play_mode_change();}void play_mode_set(play_modes_t new_play_mode){	play_mode = new_play_mode;	play_mode_change();}#pragma CALLEE-SAVES sdcc_bug_587536_workaroundstatic void sdcc_bug_587536_workaround(void xdata *p){ p; }/*simm_id file_ptr(playlist_t *p, xdata int file_num){	int i;	playlist_t 	for(i=file_num;i!=0;i++) {			}	}*/simm_id next_file_ptr(playlist_t *p, unsigned char keyflag){	#ifdef VERBOSE_DEBUG	print("begin next_file_ptr, p=");	print_hex32(simm_id_from_pointer(p));	print_crlf();	#endif	switch (play_mode) {	  case MODE_DIRONLY:	// sequential within one directory		if (p->next_sequential) {			return p->next_sequential;		} else {			return ((playlist_list_t *)Addr6(p->playlist))->playlist_start_sequential;		}	  case MODE_SEQNTIAL:	// sequential among all directories	  case MODE_PLSTRAND:	// seq within each dir, choose dirs randomly		if (p->next_sequential) {			return p->next_sequential;		} else {			return next_playlist_ptr(p, 0);		}	  case MODE_DIRRAND:	// randomly choose files within 1 dir		if (p->next_random == 0) {			dirrand_randomize_incremental(simm_id_from_pointer(p));		}		sdcc_bug_587536_workaround(p);		return p->next_random;	  case MODE_KEYRAND:    // play all files sequentially until a key is pressed		if (keyflag == 0) {			// no key pressed so act as MODE_SEQNTIAL			if (p->next_sequential) {				return p->next_sequential;			} else {				return next_playlist_ptr(p, 0);			}		}		sdcc_bug_587536_workaround(p);	    // else fall through	  case MODE_ALLRAND:	// randomly choose files among all dirs		if (p->next_random == 0) {			allrand_randomize_incremental(simm_id_from_pointer(p));		}		sdcc_bug_587536_workaround(p);		return p->next_random;	  default:		break;	}	return 0;}simm_id prev_file_ptr(playlist_t *p){	switch (play_mode) {	  case MODE_DIRONLY:	// sequential within one directory		if (p->prev_sequential) {			return p->prev_sequential;		} else {			return ((playlist_list_t *)Addr6(p->playlist))->playlist_end_sequential;		}	  case MODE_SEQNTIAL:	// sequential among all directories	  case MODE_PLSTRAND:	// seq within each dir, choose dirs randomly		if (p->prev_sequential) {			return p->prev_sequential;		} else {			p = (playlist_t *)addr6(prev_playlist_ptr(p));			return ((playlist_list_t *)Addr6(p->playlist))->playlist_end_sequential;		}	  case MODE_DIRRAND:	// randomly choose files within 1 dir		if (p->prev_random == 0) {			dirrand_randomize_incremental(simm_id_from_pointer(p));		}		sdcc_bug_587536_workaround(p);		return p->prev_random;	  case MODE_KEYRAND:    // play all files sequentially until a key is pressed                                // no decision, must be here due to keypress 	  case MODE_ALLRAND:	// randomly choose files among all dirs		if (p->prev_random == 0) {			allrand_randomize_incremental(simm_id_from_pointer(p));		}		sdcc_bug_587536_workaround(p);		return p->prev_random;	  default:		break;	}	return 0;}simm_id next_playlist_ptr(playlist_t *p, unsigned char keyflag){	playlist_list_t *list;	list = (playlist_list_t *)Addr6(p->playlist);	switch (play_mode) {	  case MODE_KEYRAND:    // play all files sequentially until a key is pressed		if (keyflag != 0) {			// keypress so act as MODE_ALLRAND			return next_file_ptr(p, 1);		}	    // else fall through	  case MODE_DIRONLY:	// sequential within one directory	  case MODE_SEQNTIAL:	// sequential among all directories		if (list->next_sequential) {			return ((playlist_list_t *)addr6(list->next_sequential))->playlist_start_sequential;		} else {			return ((playlist_list_t *)Addr6(first_playlist))->playlist_start_sequential;		}	  case MODE_DIRRAND:	// randomly choose files within 1 dir		if (list->next_sequential) {			return dirrand_new_list(list->next_sequential, 0);		} else {			return dirrand_new_list(first_playlist, 0);		}	  case MODE_PLSTRAND:	// seq within each dir, choose dirs randomly		if (list->next_random == 0) {			plstrand_randomize_incremental(simm_id_from_pointer(list));		}		sdcc_bug_587536_workaround(list);		return ((playlist_list_t *)Addr6(list->next_random))->playlist_start_sequential;	  case MODE_ALLRAND:	// randomly choose files among all dirs		return next_file_ptr(p, 0);	  default:		break;	}	return 0;}simm_id prev_playlist_ptr(playlist_t *p){	playlist_list_t *list;	list = Addr6(p->playlist);	switch (play_mode) {	  case MODE_DIRONLY:	// sequential within one directory	  case MODE_SEQNTIAL:	// sequential among all directories		if (list->prev_sequential) {			return ((playlist_list_t *)addr6(list->prev_sequential))->playlist_start_sequential;		} else {			return ((playlist_list_t *)Addr6(last_playlist))->playlist_start_sequential;		}	  case MODE_DIRRAND:	// randomly choose files within 1 dir		if (list->prev_sequential) {			return dirrand_new_list(list->prev_sequential, 0);		} else {			return dirrand_new_list(last_playlist, 0);		}	  case MODE_PLSTRAND:	// seq within each dir, choose dirs randomly		if (list->prev_random == 0) {			plstrand_randomize_incremental(simm_id_from_pointer(list));		}		sdcc_bug_587536_workaround(list);		return ((playlist_list_t *)Addr6(list->prev_random))->playlist_start_sequential;	  case MODE_KEYRAND:    // play all files sequentially until a key is pressed                                // no decision, must be here due to keypress 	  case MODE_ALLRAND:	// randomly choose files among all dirs		return prev_file_ptr(p);	  default:		break;	}	return 0;}unsigned longplaylist_to_state(playlist_t *p){	playlist_state_t state;	playlist_list_t *list;	if (play_mode == MODE_SEQNTIAL || play_mode == MODE_DIRONLY) {		state.part.song_offset = 0;		while (p->prev_sequential) {			p = Addr7(p->prev_sequential);			state.part.song_offset++;		}	} else {		state.part.song_offset = 0xFFFF;	}	if (play_mode == MODE_SEQNTIAL || play_mode == MODE_DIRONLY	  || play_mode == MODE_DIRRAND) {		state.part.list_offset = 0;		list = Addr7(p->playlist);		while (list->prev_sequential) {			list = Addr7(list->prev_sequential);			state.part.list_offset++;		}	} else {		state.part.list_offset = 0xFFFF;	}	print("playlist state = ");	print_hex32(state.whole);	print_crlf();	return state.whole;}simm_idstate_to_playlist(unsigned long state_in){	playlist_state_t state;	playlist_t *song;	playlist_list_t *list;	state.whole = state_in;	list = Addr7(first_playlist);	if (state.part.list_offset != 0xFFFF) {		while (state.part.list_offset && list->next_sequential) {			list = Addr7(list->next_sequential);			state.part.list_offset--;		}	}	song = Addr7(list->playlist_start_sequential);	if (state.part.song_offset != 0xFFFF) {		while (state.part.song_offset && song->next_sequential) {			song = Addr7(song->next_sequential);			state.part.song_offset--;		}	}	return simm_id_from_pointer(song);}/*************************************************************************************//* Randomization code for MODE_DIRRAND (randomly choose files within 1 dir)          *//*************************************************************************************/// Dir Rand mode is tricky to implement.  Though the purpose is to// play all files in one directory in random order, the user can

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -