summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorStepan Moskovchenko <stevenm@rockbox.org>2007-11-03 04:09:38 +0000
committerStepan Moskovchenko <stevenm@rockbox.org>2007-11-03 04:09:38 +0000
commitcd963d84ca5417ee443ea3f1d7cf13040ab9e5e7 (patch)
treedf9644e33cc866bdf1b92dc25a6b647e70770232 /apps
parentdc58c3d92e88bd1be3b73b2887c8856687d5002f (diff)
downloadrockbox-cd963d84ca5417ee443ea3f1d7cf13040ab9e5e7.tar.gz
rockbox-cd963d84ca5417ee443ea3f1d7cf13040ab9e5e7.zip
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
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/midi/midiplay.c74
-rw-r--r--apps/plugins/midi/sequencer.c23
-rw-r--r--apps/plugins/midi/sequencer.h1
-rw-r--r--apps/plugins/midi/synth.c18
-rw-r--r--apps/plugins/midi/synth.h2
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; a<MAX_VOICES; a++)
+ if(voices[a].isUsed == 1)
+ notesUsed++;
+ tick();
+ } while(notesUsed == 0);
+
+ /* Reset the time counter to 0 */
+ playingTime = 0;
+ samplesThisSecond = 0;
+
+
+
+ /* Tick until goal is reached */
+ while(playingTime < desiredTime)
+ tick();
+
+ break;
+ }
+
case BTN_RIGHT:
{
- /* Skip 3 seconds */
+ /* Skip 5 seconds forward */
+ /* Skipping forward is easy */
/* Should skip length be retrieved from the RB settings? */
- int samp = 3*SAMPLE_RATE;
+ int samp = 5*SAMPLE_RATE;
+
+ /* Have the issue where numberOfSamples changes within this tick */
int tickCount = samp / numberOfSamples;
int a=0;
for(a=0; a<tickCount; a++)
tick();
break;
}
+
+
#ifdef BTN_RC_QUIT
case BTN_RC_QUIT:
#endif
diff --git a/apps/plugins/midi/sequencer.c b/apps/plugins/midi/sequencer.c
index c4ddfcf95a..f0af3fecd0 100644
--- a/apps/plugins/midi/sequencer.c
+++ b/apps/plugins/midi/sequencer.c
@@ -22,6 +22,8 @@
#include "synth.h"
extern struct plugin_api * rb;
+extern int playingTime IBSS_ATTR;
+extern int samplesThisSecond IBSS_ATTR;
long tempo=375000;
@@ -239,7 +241,7 @@ inline void pressNote(int ch, int note, int vol)
{
if(drumSet[note]!=NULL)
{
- if(note<35)
+ if(note<35)
printf("NOTE LESS THAN 35, AND A DRUM PATCH EXISTS FOR THIS? WHAT THE HELL?");
struct GWaveform * wf = drumSet[note]->waveforms[0];
@@ -364,6 +366,16 @@ static void sendEvent(struct Event * ev)
}
}
+void rewindFile()
+{
+ int i=0;
+ for(i=0; i<mf->numTracks; 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; a<MAX_VOICES; a++)
{
@@ -71,6 +67,18 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
chLastCtrlMSB[a]=0; /* Set to pitch bend depth */
chLastCtrlLSB[a]=0; /* Set to pitch bend depth */
}
+}
+
+/* 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)
+{
+ char patchUsed[128];
+ char drumUsed[128];
+ int a=0;
+
+ resetControllers();
+
for(a=0; a<128; a++)
{
patchSet[a]=NULL;
diff --git a/apps/plugins/midi/synth.h b/apps/plugins/midi/synth.h
index 5f9edf89e5..aaaf2bbd74 100644
--- a/apps/plugins/midi/synth.h
+++ b/apps/plugins/midi/synth.h
@@ -20,6 +20,8 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig);
void setPoint(struct SynthObject * so, int pt);
void synthSamples(int32_t *buf_ptr, unsigned int num_samples);
+void resetControllers();
+
static inline struct Event * getEvent(struct Track * tr, int evNum)
{
return tr->dataBlock + (evNum*sizeof(struct Event));