summaryrefslogtreecommitdiff
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
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
-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
32#define BTN_RIGHT BUTTON_RIGHT 32#define BTN_RIGHT BUTTON_RIGHT
33#define BTN_UP BUTTON_UP 33#define BTN_UP BUTTON_UP
34#define BTN_DOWN BUTTON_DOWN 34#define BTN_DOWN BUTTON_DOWN
35#define BTN_LEFT BUTTON_LEFT
35 36
36#elif CONFIG_KEYPAD == ONDIO_PAD 37#elif CONFIG_KEYPAD == ONDIO_PAD
37#define BTN_QUIT BUTTON_OFF 38#define BTN_QUIT BUTTON_OFF
38#define BTN_RIGHT BUTTON_RIGHT 39#define BTN_RIGHT BUTTON_RIGHT
39#define BTN_UP BUTTON_UP 40#define BTN_UP BUTTON_UP
40#define BTN_DOWN BUTTON_DOWN 41#define BTN_DOWN BUTTON_DOWN
42#define BTN_LEFT BUTTON_LEFT
41 43
42#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD) 44#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
43#define BTN_QUIT BUTTON_OFF 45#define BTN_QUIT BUTTON_OFF
44#define BTN_RIGHT BUTTON_RIGHT 46#define BTN_RIGHT BUTTON_RIGHT
45#define BTN_UP BUTTON_UP 47#define BTN_UP BUTTON_UP
46#define BTN_DOWN BUTTON_DOWN 48#define BTN_DOWN BUTTON_DOWN
49#define BTN_LEFT BUTTON_LEFT
47 50
48#define BTN_RC_QUIT BUTTON_RC_STOP 51#define BTN_RC_QUIT BUTTON_RC_STOP
49 52
@@ -51,12 +54,14 @@ PLUGIN_IRAM_DECLARE
51 (CONFIG_KEYPAD == IPOD_1G2G_PAD) 54 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
52#define BTN_QUIT (BUTTON_SELECT | BUTTON_MENU) 55#define BTN_QUIT (BUTTON_SELECT | BUTTON_MENU)
53#define BTN_RIGHT BUTTON_RIGHT 56#define BTN_RIGHT BUTTON_RIGHT
57#define BTN_LEFT BUTTON_LEFT
54#define BTN_UP BUTTON_SCROLL_FWD 58#define BTN_UP BUTTON_SCROLL_FWD
55#define BTN_DOWN BUTTON_SCROLL_BACK 59#define BTN_DOWN BUTTON_SCROLL_BACK
56 60
57#elif (CONFIG_KEYPAD == GIGABEAT_PAD) 61#elif (CONFIG_KEYPAD == GIGABEAT_PAD)
58#define BTN_QUIT BUTTON_POWER 62#define BTN_QUIT BUTTON_POWER
59#define BTN_RIGHT BUTTON_RIGHT 63#define BTN_RIGHT BUTTON_RIGHT
64#define BTN_LEFT BUTTON_LEFT
60#define BTN_UP BUTTON_UP 65#define BTN_UP BUTTON_UP
61#define BTN_DOWN BUTTON_DOWN 66#define BTN_DOWN BUTTON_DOWN
62 67
@@ -64,24 +69,28 @@ PLUGIN_IRAM_DECLARE
64(CONFIG_KEYPAD == SANSA_C200_PAD) 69(CONFIG_KEYPAD == SANSA_C200_PAD)
65#define BTN_QUIT BUTTON_POWER 70#define BTN_QUIT BUTTON_POWER
66#define BTN_RIGHT BUTTON_RIGHT 71#define BTN_RIGHT BUTTON_RIGHT
72#define BTN_LEFT BUTTON_LEFT
67#define BTN_UP BUTTON_UP 73#define BTN_UP BUTTON_UP
68#define BTN_DOWN BUTTON_DOWN 74#define BTN_DOWN BUTTON_DOWN
69 75
70#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD 76#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
71#define BTN_QUIT BUTTON_POWER 77#define BTN_QUIT BUTTON_POWER
72#define BTN_RIGHT BUTTON_RIGHT 78#define BTN_RIGHT BUTTON_RIGHT
79#define BTN_LEFT BUTTON_LEFT
73#define BTN_UP BUTTON_UP 80#define BTN_UP BUTTON_UP
74#define BTN_DOWN BUTTON_DOWN 81#define BTN_DOWN BUTTON_DOWN
75 82
76#elif CONFIG_KEYPAD == IRIVER_H10_PAD 83#elif CONFIG_KEYPAD == IRIVER_H10_PAD
77#define BTN_QUIT BUTTON_POWER 84#define BTN_QUIT BUTTON_POWER
78#define BTN_RIGHT BUTTON_RIGHT 85#define BTN_RIGHT BUTTON_RIGHT
86#define BTN_LEFT BUTTON_LEFT
79#define BTN_UP BUTTON_SCROLL_UP 87#define BTN_UP BUTTON_SCROLL_UP
80#define BTN_DOWN BUTTON_SCROLL_DOWN 88#define BTN_DOWN BUTTON_SCROLL_DOWN
81 89
82#elif CONFIG_KEYPAD == MROBE500_PAD 90#elif CONFIG_KEYPAD == MROBE500_PAD
83#define BTN_QUIT BUTTON_POWER 91#define BTN_QUIT BUTTON_POWER
84#define BTN_RIGHT BUTTON_RIGHT 92#define BTN_RIGHT BUTTON_RIGHT
93#define BTN_LEFT BUTTON_LEFT
85#define BTN_UP BUTTON_RC_PLAY 94#define BTN_UP BUTTON_RC_PLAY
86#define BTN_DOWN BUTTON_RC_DOWN 95#define BTN_DOWN BUTTON_RC_DOWN
87 96
@@ -96,6 +105,10 @@ PLUGIN_IRAM_DECLARE
96struct MIDIfile * mf IBSS_ATTR; 105struct MIDIfile * mf IBSS_ATTR;
97 106
98int numberOfSamples IBSS_ATTR; /* the number of samples in the current tick */ 107int numberOfSamples IBSS_ATTR; /* the number of samples in the current tick */
108int playingTime IBSS_ATTR; /* How many seconds into the file have we been playing? */
109int samplesThisSecond IBSS_ATTR; /* How many samples produced during this second so far? */
110
111
99long bpm IBSS_ATTR; 112long bpm IBSS_ATTR;
100 113
101int32_t gmbuf[BUF_SIZE*NBUF]; 114int32_t gmbuf[BUF_SIZE*NBUF];
@@ -255,6 +268,9 @@ static int midimain(void * filename)
255 tick(); 268 tick();
256 } while(notesUsed == 0); 269 } while(notesUsed == 0);
257 270
271 playingTime = 0;
272 samplesThisSecond = 0;
273
258 synthbuf(); 274 synthbuf();
259 rb->pcm_play_data(&get_more, NULL, 0); 275 rb->pcm_play_data(&get_more, NULL, 0);
260 276
@@ -295,17 +311,71 @@ static int midimain(void * filename)
295 } 311 }
296 break; 312 break;
297 313
314
315 case BTN_LEFT:
316 {
317 /* Rewinding is tricky. Basically start the file over */
318 /* but run through the tracks without the synth running */
319
320 int desiredTime = playingTime - 5; /* Rewind 5 sec */
321
322 if(desiredTime < 0)
323 desiredTime = 0;
324
325 /* Set controllers to default values */
326 resetControllers();
327
328 /* Set the tempo to defalt */
329 bpm=mf->div*1000000/tempo;
330 numberOfSamples=SAMPLE_RATE/bpm;
331
332
333 /* Reset the tracks to start */
334 rewindFile();
335
336 /* Reset the time counter to 0 */
337 playingTime = 0;
338 samplesThisSecond = 0;
339
340 /* Quickly run through any initial things that occur before notes */
341 do
342 {
343 notesUsed = 0;
344 for(a=0; a<MAX_VOICES; a++)
345 if(voices[a].isUsed == 1)
346 notesUsed++;
347 tick();
348 } while(notesUsed == 0);
349
350 /* Reset the time counter to 0 */
351 playingTime = 0;
352 samplesThisSecond = 0;
353
354
355
356 /* Tick until goal is reached */
357 while(playingTime < desiredTime)
358 tick();
359
360 break;
361 }
362
298 case BTN_RIGHT: 363 case BTN_RIGHT:
299 { 364 {
300 /* Skip 3 seconds */ 365 /* Skip 5 seconds forward */
366 /* Skipping forward is easy */
301 /* Should skip length be retrieved from the RB settings? */ 367 /* Should skip length be retrieved from the RB settings? */
302 int samp = 3*SAMPLE_RATE; 368 int samp = 5*SAMPLE_RATE;
369
370 /* Have the issue where numberOfSamples changes within this tick */
303 int tickCount = samp / numberOfSamples; 371 int tickCount = samp / numberOfSamples;
304 int a=0; 372 int a=0;
305 for(a=0; a<tickCount; a++) 373 for(a=0; a<tickCount; a++)
306 tick(); 374 tick();
307 break; 375 break;
308 } 376 }
377
378
309#ifdef BTN_RC_QUIT 379#ifdef BTN_RC_QUIT
310 case BTN_RC_QUIT: 380 case BTN_RC_QUIT:
311#endif 381#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 @@
22#include "synth.h" 22#include "synth.h"
23 23
24extern struct plugin_api * rb; 24extern struct plugin_api * rb;
25extern int playingTime IBSS_ATTR;
26extern int samplesThisSecond IBSS_ATTR;
25 27
26long tempo=375000; 28long tempo=375000;
27 29
@@ -239,7 +241,7 @@ inline void pressNote(int ch, int note, int vol)
239 { 241 {
240 if(drumSet[note]!=NULL) 242 if(drumSet[note]!=NULL)
241 { 243 {
242 if(note<35) 244 if(note<35)
243 printf("NOTE LESS THAN 35, AND A DRUM PATCH EXISTS FOR THIS? WHAT THE HELL?"); 245 printf("NOTE LESS THAN 35, AND A DRUM PATCH EXISTS FOR THIS? WHAT THE HELL?");
244 246
245 struct GWaveform * wf = drumSet[note]->waveforms[0]; 247 struct GWaveform * wf = drumSet[note]->waveforms[0];
@@ -364,6 +366,16 @@ static void sendEvent(struct Event * ev)
364 } 366 }
365} 367}
366 368
369void rewindFile()
370{
371 int i=0;
372 for(i=0; i<mf->numTracks; i++)
373 {
374 mf->tracks[i]->delta = 0;
375 mf->tracks[i]->pos = 0;
376 }
377}
378
367int tick(void) ICODE_ATTR; 379int tick(void) ICODE_ATTR;
368int tick(void) 380int tick(void)
369{ 381{
@@ -419,6 +431,15 @@ int tick(void)
419 } 431 }
420 } 432 }
421 433
434 samplesThisSecond += numberOfSamples;
435
436 while(samplesThisSecond >= SAMPLE_RATE)
437 {
438 samplesThisSecond -= SAMPLE_RATE;
439 playingTime++;
440// printf("Time: %d sec\n", playingTime);
441 }
442
422 if(tracksAdv != 0) 443 if(tracksAdv != 0)
423 return 1; 444 return 1;
424 else 445 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);
21 21
22/* used by beatbox */ 22/* used by beatbox */
23void pressNote(int ch, int note, int vol); 23void pressNote(int ch, int note, int vol);
24void rewindFile();
24 25
25extern long tempo; 26extern long tempo;
26 27
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)
43 rb->lseek(file, -1, SEEK_CUR); 43 rb->lseek(file, -1, SEEK_CUR);
44} 44}
45 45
46/* Filename is the name of the config file */ 46void resetControllers()
47/* The MIDI file should have been loaded at this point */
48int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
49{ 47{
50 char patchUsed[128];
51 char drumUsed[128];
52 int a=0; 48 int a=0;
53 for(a=0; a<MAX_VOICES; a++) 49 for(a=0; a<MAX_VOICES; a++)
54 { 50 {
@@ -71,6 +67,18 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
71 chLastCtrlMSB[a]=0; /* Set to pitch bend depth */ 67 chLastCtrlMSB[a]=0; /* Set to pitch bend depth */
72 chLastCtrlLSB[a]=0; /* Set to pitch bend depth */ 68 chLastCtrlLSB[a]=0; /* Set to pitch bend depth */
73 } 69 }
70}
71
72/* Filename is the name of the config file */
73/* The MIDI file should have been loaded at this point */
74int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
75{
76 char patchUsed[128];
77 char drumUsed[128];
78 int a=0;
79
80 resetControllers();
81
74 for(a=0; a<128; a++) 82 for(a=0; a<128; a++)
75 { 83 {
76 patchSet[a]=NULL; 84 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);
20void setPoint(struct SynthObject * so, int pt); 20void setPoint(struct SynthObject * so, int pt);
21void synthSamples(int32_t *buf_ptr, unsigned int num_samples); 21void synthSamples(int32_t *buf_ptr, unsigned int num_samples);
22 22
23void resetControllers();
24
23static inline struct Event * getEvent(struct Track * tr, int evNum) 25static inline struct Event * getEvent(struct Track * tr, int evNum)
24{ 26{
25 return tr->dataBlock + (evNum*sizeof(struct Event)); 27 return tr->dataBlock + (evNum*sizeof(struct Event));