From cd963d84ca5417ee443ea3f1d7cf13040ab9e5e7 Mon Sep 17 00:00:00 2001 From: Stepan Moskovchenko Date: Sat, 3 Nov 2007 04:09:38 +0000 Subject: MIDI: Allow seeking forward and backward using the left/right keys. Currently seeks in 5 second increments, but this can be set to any amount. Also implemented a counter for playing time, which can pretty easily be used to determine the length of the file, in seconds, before playing it. The time isn't displayed anywhere right now, but all this can be useful if this thing is turned into a codec, or at least gets a nice UI. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15418 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/midi/midiplay.c | 74 +++++++++++++++++++++++++++++++++++++++++-- apps/plugins/midi/sequencer.c | 23 +++++++++++++- apps/plugins/midi/sequencer.h | 1 + apps/plugins/midi/synth.c | 18 ++++++++--- apps/plugins/midi/synth.h | 2 ++ 5 files changed, 110 insertions(+), 8 deletions(-) diff --git a/apps/plugins/midi/midiplay.c b/apps/plugins/midi/midiplay.c index a5ecfdf1f7..e1710e8eac 100644 --- a/apps/plugins/midi/midiplay.c +++ b/apps/plugins/midi/midiplay.c @@ -32,18 +32,21 @@ PLUGIN_IRAM_DECLARE #define BTN_RIGHT BUTTON_RIGHT #define BTN_UP BUTTON_UP #define BTN_DOWN BUTTON_DOWN +#define BTN_LEFT BUTTON_LEFT #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 +#define BTN_LEFT BUTTON_LEFT #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 +#define BTN_LEFT BUTTON_LEFT #define BTN_RC_QUIT BUTTON_RC_STOP @@ -51,12 +54,14 @@ PLUGIN_IRAM_DECLARE (CONFIG_KEYPAD == IPOD_1G2G_PAD) #define BTN_QUIT (BUTTON_SELECT | BUTTON_MENU) #define BTN_RIGHT BUTTON_RIGHT +#define BTN_LEFT BUTTON_LEFT #define BTN_UP BUTTON_SCROLL_FWD #define BTN_DOWN BUTTON_SCROLL_BACK #elif (CONFIG_KEYPAD == GIGABEAT_PAD) #define BTN_QUIT BUTTON_POWER #define BTN_RIGHT BUTTON_RIGHT +#define BTN_LEFT BUTTON_LEFT #define BTN_UP BUTTON_UP #define BTN_DOWN BUTTON_DOWN @@ -64,24 +69,28 @@ PLUGIN_IRAM_DECLARE (CONFIG_KEYPAD == SANSA_C200_PAD) #define BTN_QUIT BUTTON_POWER #define BTN_RIGHT BUTTON_RIGHT +#define BTN_LEFT BUTTON_LEFT #define BTN_UP BUTTON_UP #define BTN_DOWN BUTTON_DOWN #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD #define BTN_QUIT BUTTON_POWER #define BTN_RIGHT BUTTON_RIGHT +#define BTN_LEFT BUTTON_LEFT #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_LEFT BUTTON_LEFT #define BTN_UP BUTTON_SCROLL_UP #define BTN_DOWN BUTTON_SCROLL_DOWN #elif CONFIG_KEYPAD == MROBE500_PAD #define BTN_QUIT BUTTON_POWER #define BTN_RIGHT BUTTON_RIGHT +#define BTN_LEFT BUTTON_LEFT #define BTN_UP BUTTON_RC_PLAY #define BTN_DOWN BUTTON_RC_DOWN @@ -96,6 +105,10 @@ PLUGIN_IRAM_DECLARE struct MIDIfile * mf IBSS_ATTR; int numberOfSamples IBSS_ATTR; /* the number of samples in the current tick */ +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? */ + + long bpm IBSS_ATTR; int32_t gmbuf[BUF_SIZE*NBUF]; @@ -255,6 +268,9 @@ static int midimain(void * filename) tick(); } while(notesUsed == 0); + playingTime = 0; + samplesThisSecond = 0; + synthbuf(); rb->pcm_play_data(&get_more, NULL, 0); @@ -295,17 +311,71 @@ static int midimain(void * filename) } break; + + case BTN_LEFT: + { + /* Rewinding is tricky. Basically start the file over */ + /* but run through the tracks without the synth running */ + + int desiredTime = playingTime - 5; /* Rewind 5 sec */ + + if(desiredTime < 0) + desiredTime = 0; + + /* Set controllers to default values */ + resetControllers(); + + /* Set the tempo to defalt */ + bpm=mf->div*1000000/tempo; + numberOfSamples=SAMPLE_RATE/bpm; + + + /* Reset the tracks to start */ + rewindFile(); + + /* Reset the time counter to 0 */ + playingTime = 0; + samplesThisSecond = 0; + + /* Quickly run through any initial things that occur before notes */ + do + { + notesUsed = 0; + for(a=0; awaveforms[0]; @@ -364,6 +366,16 @@ static void sendEvent(struct Event * ev) } } +void rewindFile() +{ + int i=0; + for(i=0; inumTracks; i++) + { + mf->tracks[i]->delta = 0; + mf->tracks[i]->pos = 0; + } +} + int tick(void) ICODE_ATTR; int tick(void) { @@ -419,6 +431,15 @@ int tick(void) } } + samplesThisSecond += numberOfSamples; + + while(samplesThisSecond >= SAMPLE_RATE) + { + samplesThisSecond -= SAMPLE_RATE; + playingTime++; +// printf("Time: %d sec\n", playingTime); + } + if(tracksAdv != 0) return 1; else diff --git a/apps/plugins/midi/sequencer.h b/apps/plugins/midi/sequencer.h index 3d05d4c8dd..0a70b98a1b 100644 --- a/apps/plugins/midi/sequencer.h +++ b/apps/plugins/midi/sequencer.h @@ -21,6 +21,7 @@ int tick(void); /* used by beatbox */ void pressNote(int ch, int note, int vol); +void rewindFile(); extern long tempo; diff --git a/apps/plugins/midi/synth.c b/apps/plugins/midi/synth.c index 4e04975e0b..ca59c76a8b 100644 --- a/apps/plugins/midi/synth.c +++ b/apps/plugins/midi/synth.c @@ -43,12 +43,8 @@ void readTextBlock(int file, char * buf) rb->lseek(file, -1, SEEK_CUR); } -/* Filename is the name of the config file */ -/* The MIDI file should have been loaded at this point */ -int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig) +void resetControllers() { - char patchUsed[128]; - char drumUsed[128]; int a=0; for(a=0; adataBlock + (evNum*sizeof(struct Event)); -- cgit v1.2.3