Index: apps/plugins/SUBDIRS =================================================================== --- apps/plugins/SUBDIRS (revision 20325) +++ 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/viewers.config =================================================================== --- apps/plugins/viewers.config (revision 20325) +++ 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.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) Property changes on: apps/plugins/beatbox/beatbox.make ___________________________________________________________________ Added: svn:executable + * Index: apps/plugins/beatbox/beatbox.c =================================================================== --- apps/plugins/beatbox/beatbox.c (revision 20325) +++ apps/plugins/beatbox/beatbox.c (working copy) @@ -19,69 +19,149 @@ ****************************************************************************/ #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 #endif @@ -185,36 +265,29 @@ #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: cymbals and maraca thing */ #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 */ +/* This was somewhere in the middle of the file before */ +#define NAME_POSX 10 +#define NAME_POSY (LCD_HEIGHT-(2*CELL_YSIZE)) /* was 100, which doesnt */ + /* fit on all screens */ + #define COLOR_NAME_TEXT LCD_RGBPACK(0xFF,0xFF,0xFF) #define COLOR_NORMAL LCD_RGBPACK(0xFF,0xFF,0xFF) #define COLOR_PLAY LCD_RGBPACK(0xFF,0xFF,0x00) @@ -231,9 +304,29 @@ int playState=STATE_STOPPED, stepFlag=0; +int playingTime IBSS_ATTR; /* How many seconds into the file have we been playing? */ +int samplesThisSecond IBSS_ATTR; /* How many samples produced during this second so far? */ -enum plugin_status plugin_start(const void* parameter) + +unsigned char trackPos[V_NUMCELLS]; +unsigned char trackData[H_NUMCELLS][V_NUMCELLS]; +unsigned char trackMap[V_NUMCELLS] = {38, 39, 40, 41, 42, 43, 44, 56, 57, 58}; + +struct Cell { + unsigned char val; + int color; +}; + +struct Cell pattern[H_NUMCELLS][V_NUMCELLS]; +struct Cell dispPattern[H_NUMCELLS][V_NUMCELLS]; + +/* function prototype to load file*/ +bool load_file(const void* file); + + +enum plugin_status plugin_start(const void* file) +{ int retval = 0; PLUGIN_IRAM_INIT(rb) @@ -253,15 +346,26 @@ printf("\nINIT ERROR\n"); return -1; } -//#ifndef SIMULATOR +/* #ifndef SIMULATOR */ rb->pcm_play_stop(); #if INPUT_SRC_CAPS != 0 /* Select playback */ rb->audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); rb->audio_set_output_source(AUDIO_SRC_PLAYBACK); #endif - rb->pcm_set_frequency(SAMPLE_RATE); // 44100 22050 11025 + rb->pcm_set_frequency(SAMPLE_RATE); /* 44100 22050 11025 */ + /* load file */ + if(file) + { + if(!load_file(file)) + rb->splash(HZ,"Load failed =("); + } else { + int i; + /* Start at 16 cells/loop for now. User can un-loop if more are needed */ + for(i=0; ilcd_set_foreground(COLOR_NAME_TEXT); rb->lcd_putsxy(NAME_POSX, NAME_POSY, drumNames[trackMap[trackNum]-35]); } -void updateDisplay() + +void update_display() { int i, j; int grayOut=0; @@ -400,13 +488,13 @@ } -void resetPosition() +void reset_position() { int i; for(i=0; ilcd_update(); } + void get_more(unsigned char** start, size_t* size) { #ifndef SYNC if(lastswap!=swap) { -// printf("Buffer miss!"); // Comment out the printf to make missses less noticable. + /* Comment out the printf to make missses less noticable. */ + /* printf("Buffer miss!"); */ } - #else - synthbuf(); // For some reason midiplayer crashes when an update is forced + synthbuf(); /* For some reason midiplayer crashes when an update is forced */ #endif *size = BUF_SIZE*sizeof(short); @@ -503,6 +599,215 @@ #endif } + +/* Adapted from viewer.c */ +/* Returns false on fail */ +bool load_file(const void* file) +{ + /* null file */ + if (!file) + return false; + + /* cant open */ + int fd = rb->open(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_startdebugf("x:%d y:%d \n",x,y); + + if((x==H_NUMCELLS)&&(y==V_NUMCELLS)) + break; + } + + return true; +} + + +/* Adapted from viewer.c */ +/* Returns false on fail */ +static char filename[MAX_PATH]; +bool save_file(int overwrite) +{ + if (!filename[0] || !overwrite) + { + rb->strcpy(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"); + + draw_grid(); + update_display(); + redraw_screen(1); + show_drum_name(yCursor); + break; + case 1: /* Clear drum pattern */ + menu_quit=true; + res = -1; + reset_track_data(); + draw_grid(); + update_display(); + redraw_screen(1); + show_drum_name(yCursor); + break; + case 2: /* Resume */ + menu_quit=true; + res = -1; + draw_grid(); + update_display(); + redraw_screen(1); + show_drum_name(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() { int vol=0; @@ -515,15 +820,9 @@ rb->lcd_set_background(0x000000); rb->lcd_clear_display(); - resetPosition(); + reset_position(); - 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) { #ifndef SYNC @@ -558,8 +857,8 @@ { advancePosition(); sendEvents(); - updateDisplay(); - redrawScreen(0); + update_display(); + redraw_screen(0); stepFlag=0; } @@ -595,11 +894,11 @@ case BTN_RIGHT: { //pressNote(9, 40, 127); - // resetPosition(); + // reset_position(); advancePosition(); sendEvents(); - updateDisplay(); - redrawScreen(0); + update_display(); + redraw_screen(0); break; } @@ -607,9 +906,9 @@ { // isPlaying=1; - resetPosition(); - updateDisplay(); - redrawScreen(0); + reset_position(); + update_display(); + redraw_screen(0); //pressNote(9, 39, 127); break; } @@ -623,9 +922,9 @@ if(yCursor > 0) { yCursor--; - showDrumName(yCursor); - updateDisplay(); - redrawScreen(0); + update_display(); + redraw_screen(0); + show_drum_name(yCursor); } } break; @@ -639,9 +938,9 @@ if(yCursor < V_NUMCELLS-1) { yCursor++; - showDrumName(yCursor); - updateDisplay(); - redrawScreen(0); + update_display(); + redraw_screen(0); + show_drum_name(yCursor); } } break; @@ -655,8 +954,8 @@ if(xCursor > 0) { xCursor--; - updateDisplay(); - redrawScreen(0); + update_display(); + redraw_screen(0); } } break; @@ -670,8 +969,8 @@ if(xCursor < H_NUMCELLS-1) { xCursor++; - updateDisplay(); - redrawScreen(0); + update_display(); + redraw_screen(0); } } break; @@ -688,8 +987,8 @@ trackData[xCursor][yCursor] = cv; - updateDisplay(); - redrawScreen(0); + update_display(); + redraw_screen(0); } break; } @@ -701,8 +1000,8 @@ playState = STATE_PAUSED; else { - updateDisplay(); - redrawScreen(0); + update_display(); + redraw_screen(0); sendEvents(); playState = STATE_PLAYING; } @@ -713,13 +1012,18 @@ { if(playState == STATE_STOPPED) { - quit=1; + /* quit=1; */ + /* instead of quiting, open menu */ + int ret = beatboxMenu(0); + if (ret != -1){ return PLUGIN_OK; } + update_display(); + redraw_screen(0); } else { - playState =STATE_STOPPED; - resetPosition(); - updateDisplay(); - redrawScreen(0); + playState = STATE_STOPPED; + reset_position(); + update_display(); + redraw_screen(0); } break; } @@ -728,6 +1032,5 @@ } - return 0; + return PLUGIN_OK; } -