Index: apps/plugins/SUBDIRS =================================================================== --- apps/plugins/SUBDIRS (revision 20858) +++ apps/plugins/SUBDIRS (working copy) @@ -43,7 +43,7 @@ /* For all the swcodec targets */ #if CONFIG_CODEC == SWCODEC midi -/* beatbox */ +beatbox #ifndef RB_PROFILE mpegplayer #endif Index: apps/plugins/CATEGORIES =================================================================== --- apps/plugins/CATEGORIES (revision 20858) +++ apps/plugins/CATEGORIES (working copy) @@ -1,6 +1,7 @@ alpine_cdc,apps autostart,apps battery_bench,apps +beatbox,apps blackjack,games bounce,demos brickmania,games Index: apps/plugins/viewers.config =================================================================== --- apps/plugins/viewers.config (revision 20858) +++ apps/plugins/viewers.config (working copy) @@ -1,4 +1,5 @@ ch8,viewers/chip8,0 +bpf,apps/beatbox,0 txt,viewers/viewer,1 nfo,viewers/viewer,1 txt,apps/text_editor,2 @@ -14,7 +15,7 @@ gbc,viewers/rockboy,6 sgb,viewers/rockboy,6 m3u,viewers/iriverify,- -mid,viewers/midi,7 +mid,viewers/midi,7 rmi,viewers/midi,7 rsp,viewers/searchengine,8 sok,games/sokoban,1 Index: apps/plugins/beatbox/beatbox.c =================================================================== --- apps/plugins/beatbox/beatbox.c (revision 20858) +++ apps/plugins/beatbox/beatbox.c (working copy) @@ -19,69 +19,159 @@ ****************************************************************************/ #include "plugin.h" -#include "midi/guspat.h" -#include "midi/midiutil.h" -#include "midi/synth.h" -#include "midi/sequencer.h" -#include "midi/midifile.h" +#include "../midi/guspat.h" +#include "../midi/midiutil.h" +#include "../midi/synth.h" +#include "../midi/sequencer.h" +#include "../midi/midifile.h" PLUGIN_HEADER PLUGIN_IRAM_DECLARE -/* variable button definitions */ -#if CONFIG_KEYPAD == RECORDER_PAD -#define BTN_QUIT BUTTON_OFF -#define BTN_RIGHT BUTTON_RIGHT -#define BTN_UP BUTTON_UP -#define BTN_DOWN BUTTON_DOWN +/*------------------------------------------------------------------------------ + insanepotato's magical button guess-mapper thing. =D + This will try automatically define keymappings. The mappings defined + by this can be overridden (for comfort or other reasons) bellow. + An example partial mapping overide is done bellow (c200 override) +------------------------------------------------------------------------------*/ +/* attempt to set the directional buttons */ +#ifdef BUTTON_UP + #define BEATBOX_UP BUTTON_UP +#else + #warning No key mapping: no up button +#endif -#elif CONFIG_KEYPAD == ONDIO_PAD -#define BTN_QUIT BUTTON_OFF -#define BTN_RIGHT BUTTON_RIGHT -#define BTN_UP BUTTON_UP -#define BTN_DOWN BUTTON_DOWN +#ifdef BUTTON_DOWN + #define BEATBOX_DOWN BUTTON_DOWN +#else + #warning No key mapping: no down button +#endif -#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD) -#define BTN_QUIT BUTTON_OFF -#define BTN_RIGHT BUTTON_RIGHT -#define BTN_UP BUTTON_UP -#define BTN_DOWN BUTTON_DOWN +#ifdef BUTTON_LEFT + #define BEATBOX_LEFT BUTTON_LEFT +#else + #warning No key mapping: no left button +#endif -#define BTN_RC_QUIT BUTTON_RC_STOP +#ifdef BUTTON_RIGHT + #define BEATBOX_RIGHT BUTTON_RIGHT +#else + #warning No key mapping: no right button +#endif -#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \ - (CONFIG_KEYPAD == IPOD_1G2G_PAD) -#define BTN_QUIT (BUTTON_SELECT | BUTTON_MENU) -#define BTN_RIGHT BUTTON_RIGHT -#define BTN_UP BUTTON_SCROLL_FWD -#define BTN_DOWN BUTTON_SCROLL_BACK +/* attempt to set the select button */ +/* order: select, record, playlist, menu */ +#ifdef BUTTON_SELECT + #define BEATBOX_SELECT BUTTON_SELECT +#else + #ifdef BUTTON_REC + #define BEATBOX_SELECT BUTTON_REC + #else + #ifdef BUTTON_PLAYLIST + #define BEATBOX_SELECT BUTTON_PLAYLIST + #else + #ifdef BUTTON_MENU + #define BEATBOX_SELECT MENU + #else + #warning No key mapping: no select button + #endif + #endif + #endif +#endif -#elif (CONFIG_KEYPAD == GIGABEAT_PAD) -#define BTN_QUIT BUTTON_POWER -#define BTN_RIGHT BUTTON_RIGHT -#define BTN_UP BUTTON_UP -#define BTN_DOWN BUTTON_DOWN +/* attempt to set the play button */ +/* order: play, on, vol_up, scroll_forward */ +#ifdef BUTTON_PLAY + #define BEATBOX_PLAY BUTTON_PLAY +#else + #ifdef BUTTON_ON + #define BEATBOX_PLAY BUTTON_ON + #else + #ifdef BUTTON_VOL_UP + #define BEATBOX_PLAY BUTTON_VOL_UP + #else + #ifdef BUTTON_SCROLL_FWD + #define BEATBOX_PLAY BUTTON_SCROLL_BACK + #else + #warning No key mapping: no play button + #endif + #endif + #endif +#endif -#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ -(CONFIG_KEYPAD == SANSA_C200_PAD) -#define BTN_QUIT BUTTON_POWER -#define BTN_RIGHT BUTTON_RIGHT -#define BTN_UP BUTTON_UP -#define BTN_DOWN BUTTON_DOWN +/* attempt to set the stop button */ +/* order: stop, off, vol_down, scroll_back, home,power */ +#ifdef BUTTON_STOP + #define BEATBOX_STOP BUTTON_STOP +#else + #ifdef BUTTON_OFF + #define BEATBOX_STOP BUTTON_OFF + #else + #ifdef BUTTON_VOL_DOWN + #define BEATBOX_STOP BUTTON_VOL_DOWN + #else + #ifdef BUTTON_SCROLL_BACK + #define BEATBOX_STOP BUTTON_SCROLL_BACK + #else + #ifdef BUTTON_POWER + #define BEATBOX_STOP BUTTON_POWER + #else + #ifdef BUTTON_HOME + #define BEATBOX_STOP BUTTON_HOME + #else + #warning No key mapping: no stop button + #endif + #endif + #endif + #endif + #endif +#endif -#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD -#define BTN_QUIT BUTTON_POWER -#define BTN_RIGHT BUTTON_RIGHT -#define BTN_UP BUTTON_UP -#define BTN_DOWN BUTTON_DOWN -#elif CONFIG_KEYPAD == IRIVER_H10_PAD -#define BTN_QUIT BUTTON_POWER -#define BTN_RIGHT BUTTON_RIGHT -#define BTN_UP BUTTON_SCROLL_UP -#define BTN_DOWN BUTTON_SCROLL_DOWN +/*------------------------------------------ + Manual overides here +------------------------------------------*/ +#if (CONFIG_KEYPAD == CUSTOM_PAD_GOES_HERE) +#define BEATBOX_UP BUTTON_UP +#define BEATBOX_DOWN BUTTON_DOWN +#define BEATBOX_LEFT BUTTON_LEFT +#define BEATBOX_RIGHT BUTTON_RIGHT +#define BEATBOX_SELECT BUTTON_SELECT +#define BEATBOX_PLAY BUTTON_ON +#define BEATBOX_STOP BUTTON_OFF +/* partial override to the c200 keypad, for more intuitive use */ +#elif (CONFIG_KEYPAD == SANSA_C200_PAD) +#define BEATBOX_PLAY BUTTON_REC +#define BEATBOX_STOP BUTTON_POWER + +/* partial override to the h10 keypad, h10 is missing some directional btns */ +#elif (CONFIG_KEYPAD == IRIVER_H10_PAD) +#define BEATBOX_UP BUTTON_SCROLL_UP +#define BEATBOX_DOWN BUTTON_SCROLL_DOWN +#define BEATBOX_SELECT BUTTON_REW +#define BEATBOX_STOP BUTTON_POWER + +/* m3 keypad has weird pad */ +#elif CONFIG_KEYPAD == IAUDIO_M3_PAD +#define BEATBOX_LEFT BUTTON_RC_REW +#define BEATBOX_RIGHT BUTTON_RC_FF +#define BEATBOX_UP BUTTON_RC_VOL_UP +#define BEATBOX_DOWN BUTTON_RC_VOL_DOWN +#define BEATBOX_SELECT BUTTON_RC_REC +#define BEATBOX_PLAY BUTTON_RC_PLAY +#define BEATBOX_STOP BUTTON_RC_MENU + +/* ipods */ +#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ + (CONFIG_KEYPAD == IPOD_3G_PAD) || \ + (CONFIG_KEYPAD == IPOD_1G2G_PAD) +#define BEATBOX_UP BUTTON_SCROLL_FWD +#define BEATBOX_DOWN BUTTON_SCROLL_BACK +#define BEATBOX_SELECT BUTTON_SELECT +#define BEATBOX_PLAY BUTTON_PLAY +#define BEATBOX_STOP BUTTON_MENU #endif @@ -185,34 +275,22 @@ #define STATE_PAUSED 1 #define STATE_PLAYING 2 - -#define BEATBOX_UP BUTTON_UP -#define BEATBOX_DOWN BUTTON_DOWN -#define BEATBOX_LEFT BUTTON_LEFT -#define BEATBOX_RIGHT BUTTON_RIGHT -#define BEATBOX_SELECT BUTTON_SELECT - - -#define BEATBOX_PLAY BUTTON_ON -#define BEATBOX_STOP BUTTON_OFF - - #define VAL_NONE 0 #define VAL_ENABLED 1 #define VAL_LOOP 2 #define H_NUMCELLS 24 -#define V_NUMCELLS 8 +#define V_NUMCELLS 10 /* was 8, 2 cells added: clash1 and Mute Triangle */ #define HILIGHT_NONE 0 #define HILIGHT_PLAY 1 #define HILIGHT_USER 2 -#define CELL_XSIZE 9 -#define CELL_YSIZE 9 +#define CELL_XSIZE (LCD_WIDTH/H_NUMCELLS) /* was 9 */ +#define CELL_YSIZE (LCD_HEIGHT/V_NUMCELLS) /* was 9 */ -#define GRID_XPOS 2 -#define GRID_YPOS 10 +#define GRID_XPOS 0 /* was 2 */ +#define GRID_YPOS 0 /* was 10 */ #define COLOR_NAME_TEXT LCD_RGBPACK(0xFF,0xFF,0xFF) @@ -231,8 +309,15 @@ int playState=STATE_STOPPED, stepFlag=0; +int number_of_samples IBSS_ATTR; /* the number of samples in the current tick */ +int playing_time IBSS_ATTR; /* How many seconds into the file have we been playing? */ +int samples_this_second IBSS_ATTR; /* How many samples produced during this second so far? */ -enum plugin_status plugin_start(const void* parameter) +bool load_file(const void* file); /* Function defined before menu function */ +int beatboxmain(bool file_loaded); /* Function defined at end of file */ + + +enum plugin_status plugin_start(const void* file) { int retval = 0; @@ -262,8 +347,19 @@ #endif rb->pcm_set_frequency(SAMPLE_RATE); // 44100 22050 11025 + bool file_loaded = false; + /* load file */ + if(file) + { + if(!load_file(file)) + { + file_loaded = false; + rb->splash(HZ,"Load failed ;("); + } else + file_loaded = true; + } - retval = beatboxmain(); + retval = beatboxmain(file_loaded); #ifdef RB_PROFILE rb->profstop(); @@ -303,7 +399,9 @@ for(i=0; ilcd_set_foreground(COLOR_NAME_TEXT); @@ -420,9 +519,17 @@ } } +void reset_track_data() +{ + int i,j; + for(i=0; iopen(file, O_RDONLY); + if (fd==-1) + return false; + + /* empty file */ + /* int used for filesize, as its HIGHLY UNLIKELY that bb patern filesize */ + /* will ever exceed the limits of an int */ + int file_size = rb->filesize(fd); + if (file_size==-1) + { + rb->close(fd); + return false; + } + + /* incomplete file */ + /* complete file is one where there is at least */ + /* H_NUMCELLS*V_NUMCELLS characters */ + if (file_size<(H_NUMCELLS*V_NUMCELLS)) + { + rb->close(fd); + return false; + } + + /* begin loading data */ + /* '!' means the line is a comment */ + /* '0' means off */ + /* '1' means on */ + /* 'L' means loop */ + char buf[80]; + int i,len,data_start; + int x=0; + int y=0; + while(rb->read_line(fd, buf, file_size)){ + len = rb->strlen(buf); + len--; + /* skip empty lines and comments */ + for(data_start=0; data_startstrcpy(filename,"/"); + rb->kbd_input(filename,MAX_PATH-4); + rb->strcat(filename, ".bpf"); + } + + /* cant open */ + int fd = rb->open(filename,O_WRONLY|O_CREAT|O_TRUNC); + if (fd==-1) + return false; + + if (!overwrite) + /* current directory may have changed */ + rb->reload_directory(); + + rb->lcd_clear_display(); + + int i,j; + for(i=0; ifdprintf(fd,"0"); + break; + case VAL_ENABLED: + rb->fdprintf(fd,"1"); + break; + case VAL_LOOP: + rb->fdprintf(fd,"L"); + break; + } + } + rb->fdprintf(fd,"\n"); + } + + rb->close(fd); + return true; +} + +/* Adapted from chopper.c =] */ +static int beatboxMenu(int menunum) +{ + int result = (menunum==0)?0:1; + int res = 0; + bool menu_quit = false; + + /*static const struct opt_items levels[2] = { + { "Normal", -1 }, + { "Steep", -1 }, + };*/ + + MENUITEM_STRINGLIST(menu,"Beatbox Menu",NULL,"Save","Clear","Resume","Quit"); + +#ifdef HAVE_LCD_COLOR + rb->lcd_set_foreground(LCD_WHITE); + rb->lcd_set_background(LCD_BLACK); +#elif LCD_DEPTH == 2 + rb->lcd_set_foreground(LCD_BLACK); + rb->lcd_set_background(LCD_WHITE); +#endif + + rb->lcd_clear_display(); + + while (!menu_quit) { + switch(rb->do_menu(&menu, &result, NULL, false)) + { + case 0: /* Save drum pattern */ + menu_quit=true; + res = -1; + if(!save_file(1)) + rb->splash(HZ,"Changes NOT saved"); + + drawGrid(); + updateDisplay(); + redrawScreen(1); + showDrumName(yCursor); + break; + case 1: /* Clear drum pattern */ + menu_quit=true; + res = -1; + reset_track_data(); + drawGrid(); + updateDisplay(); + redrawScreen(1); + showDrumName(yCursor); + break; + case 2: /* Resume */ + menu_quit=true; + res = -1; + drawGrid(); + updateDisplay(); + redrawScreen(1); + showDrumName(yCursor); + break; + case 3: /* Quit */ + menu_quit=true; + res = PLUGIN_OK; + break; + case MENU_ATTACHED_USB: /* USB Plugged in */ + /* TODO: save a tmp pat when USB Plugged in */ + menu_quit=true; + res = PLUGIN_USB_CONNECTED; + break; + } + } +// rb->lcd_clear_display(); + return res; +} + +int beatboxmain(bool file_loaded) +{ int vol=0; @@ -517,34 +827,38 @@ resetPosition(); - int i, j; + if( !file_loaded ) + { + int i, j; - /* Start at 16 cells/loop for now. User can un-loop if more are needed */ - for(i=0; ilcd_update(); while(!quit) @@ -623,9 +937,17 @@ if(yCursor > 0) { yCursor--; + updateDisplay(); + redrawScreen(0); showDrumName(yCursor); + rb->lcd_update(); + } else + { + yCursor = V_NUMCELLS-1; updateDisplay(); redrawScreen(0); + showDrumName(yCursor); + rb->lcd_update(); } } break; @@ -639,9 +961,17 @@ if(yCursor < V_NUMCELLS-1) { yCursor++; + updateDisplay(); + redrawScreen(0); showDrumName(yCursor); + rb->lcd_update(); + } else + { + yCursor = 0; updateDisplay(); redrawScreen(0); + showDrumName(yCursor); + rb->lcd_update(); } } break; @@ -657,6 +987,11 @@ xCursor--; updateDisplay(); redrawScreen(0); + } else + { + xCursor = H_NUMCELLS-1; + updateDisplay(); + redrawScreen(0); } } break; @@ -672,6 +1007,11 @@ xCursor++; updateDisplay(); redrawScreen(0); + }else + { + xCursor = 0; + updateDisplay(); + redrawScreen(0); } } break; @@ -713,10 +1053,15 @@ { if(playState == STATE_STOPPED) { - quit=1; + /* quit=1; */ + /* instead of quiting, open menu */ + int ret = beatboxMenu(0); + if (ret != -1){ return PLUGIN_OK; } + updateDisplay(); + redrawScreen(0); } else { - playState =STATE_STOPPED; + playState = STATE_STOPPED; resetPosition(); updateDisplay(); redrawScreen(0); Index: apps/plugins/beatbox/beatbox.make =================================================================== --- apps/plugins/beatbox/beatbox.make (revision 0) +++ apps/plugins/beatbox/beatbox.make (revision 0) @@ -0,0 +1,21 @@ +# __________ __ ___. +# Open \______ \ ____ ____ | | _\_ |__ _______ ___ +# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# + +BEATBOXSRCDIR := $(APPSDIR)/plugins/beatbox +BEATBOXBUILDDIR := $(BUILDDIR)/apps/plugins/beatbox + +ROCKS += $(BEATBOXBUILDDIR)/beatbox.rock + +BEATBOX_SRC := $(call preprocess, $(BEATBOXSRCDIR)/SOURCES) +BEATBOX_OBJ := $(call c2obj, $(BEATBOX_SRC)) + +# add source files to OTHER_SRC to get automatic dependencies +OTHER_SRC += $(BEATBOX_SRC) + + +$(BEATBOXBUILDDIR)/beatbox.rock: $(BEATBOX_OBJ)