1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 Karl Kurbjun based on midi2wav by Stepan Moskovchenko
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 #include "midi/guspat.h"
24 #include "midi/midiutil.h"
25 #include "midi/synth.h"
26 #include "midi/sequencer.h"
27 #include "midi/midifile.h"
30 /* variable button definitions */
31 #if CONFIG_KEYPAD == RECORDER_PAD
32 #define BTN_QUIT BUTTON_OFF
33 #define BTN_RIGHT BUTTON_RIGHT
34 #define BTN_UP BUTTON_UP
35 #define BTN_DOWN BUTTON_DOWN
37 #elif CONFIG_KEYPAD == ONDIO_PAD
38 #define BTN_QUIT BUTTON_OFF
39 #define BTN_RIGHT BUTTON_RIGHT
40 #define BTN_UP BUTTON_UP
41 #define BTN_DOWN BUTTON_DOWN
43 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
44 #define BTN_QUIT BUTTON_OFF
45 #define BTN_RIGHT BUTTON_RIGHT
46 #define BTN_UP BUTTON_UP
47 #define BTN_DOWN BUTTON_DOWN
49 #define BTN_RC_QUIT BUTTON_RC_STOP
51 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
52 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
53 #define BTN_QUIT (BUTTON_SELECT | BUTTON_MENU)
54 #define BTN_RIGHT BUTTON_RIGHT
55 #define BTN_UP BUTTON_SCROLL_FWD
56 #define BTN_DOWN BUTTON_SCROLL_BACK
58 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
59 #define BTN_QUIT BUTTON_POWER
60 #define BTN_RIGHT BUTTON_RIGHT
61 #define BTN_UP BUTTON_UP
62 #define BTN_DOWN BUTTON_DOWN
64 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
65 (CONFIG_KEYPAD == SANSA_C200_PAD)
66 #define BTN_QUIT BUTTON_POWER
67 #define BTN_RIGHT BUTTON_RIGHT
68 #define BTN_UP BUTTON_UP
69 #define BTN_DOWN BUTTON_DOWN
72 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
73 #define BTN_QUIT BUTTON_POWER
74 #define BTN_RIGHT BUTTON_RIGHT
75 #define BTN_UP BUTTON_UP
76 #define BTN_DOWN BUTTON_DOWN
78 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
79 #define BTN_QUIT BUTTON_POWER
80 #define BTN_RIGHT BUTTON_RIGHT
81 #define BTN_UP BUTTON_SCROLL_UP
82 #define BTN_DOWN BUTTON_SCROLL_DOWN
84 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
85 #define BTN_QUIT BUTTON_POWER
86 #define BTN_RIGHT BUTTON_RIGHT
87 #define BTN_UP BUTTON_UP
88 #define BTN_DOWN BUTTON_DOWN
90 #elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD
91 #define BTN_QUIT BUTTON_POWER
92 #define BTN_RIGHT BUTTON_NEXT
93 #define BTN_UP BUTTON_UP
94 #define BTN_DOWN BUTTON_DOWN
96 #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
97 #define BTN_QUIT BUTTON_POWER
98 #define BTN_RIGHT BUTTON_NEXT
99 #define BTN_UP BUTTON_UP
100 #define BTN_DOWN BUTTON_DOWN
102 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
103 #define BTN_QUIT BUTTON_PLAY
104 #define BTN_RIGHT BUTTON_RIGHT
105 #define BTN_UP BUTTON_UP
106 #define BTN_DOWN BUTTON_DOWN
108 #elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
109 #define BTN_QUIT BUTTON_REC
110 #define BTN_RIGHT BUTTON_NEXT
111 #define BTN_UP BUTTON_UP
112 #define BTN_DOWN BUTTON_DOWN
122 #if (HW_SAMPR_CAPS & SAMPR_CAP_22)
123 #define SAMPLE_RATE SAMPR_22 // 44100 22050 11025
125 #define SAMPLE_RATE SAMPR_44 // 44100 22050 11025
128 #define MAX_VOICES 20 // Note: 24 midi channels is the minimum general midi
129 // spec implementation
131 #else // Simulator requires 44100, and we can afford to use more voices
133 #define SAMPLE_RATE SAMPR_44
134 #define MAX_VOICES 48
144 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
148 struct MIDIfile
* mf IBSS_ATTR
;
150 int numberOfSamples IBSS_ATTR
;
153 const unsigned char * drumNames
[]={
209 long gmbuf
[BUF_SIZE
*NBUF
];
213 #define STATE_STOPPED 0
214 #define STATE_PAUSED 1
215 #define STATE_PLAYING 2
218 #define BEATBOX_UP BUTTON_UP
219 #define BEATBOX_DOWN BUTTON_DOWN
220 #define BEATBOX_LEFT BUTTON_LEFT
221 #define BEATBOX_RIGHT BUTTON_RIGHT
222 #define BEATBOX_SELECT BUTTON_SELECT
225 #define BEATBOX_PLAY BUTTON_ON
226 #define BEATBOX_STOP BUTTON_OFF
230 #define VAL_ENABLED 1
233 #define H_NUMCELLS 24
236 #define HILIGHT_NONE 0
237 #define HILIGHT_PLAY 1
238 #define HILIGHT_USER 2
247 #define COLOR_NAME_TEXT LCD_RGBPACK(0xFF,0xFF,0xFF)
248 #define COLOR_NORMAL LCD_RGBPACK(0xFF,0xFF,0xFF)
249 #define COLOR_PLAY LCD_RGBPACK(0xFF,0xFF,0x00)
250 #define COLOR_DISABLED LCD_RGBPACK(0xA0,0xA0,0xA0)
251 #define COLOR_LOOPCELL LCD_RGBPACK(0xC0,0xC0,0xC0)
252 #define COLOR_EDIT LCD_RGBPACK(0x30,0x30,0xFF)
253 #define COLOR_GRID LCD_RGBPACK(0xD0,0xD0,0xD0)
255 #define EDITSTATE_PATTERN 0
257 int xCursor
=0, yCursor
=0;
259 int editState
=EDITSTATE_PATTERN
;
261 int playState
=STATE_STOPPED
, stepFlag
=0;
264 enum plugin_status
plugin_start(const void* parameter
)
270 #if defined(HAVE_ADJUSTABLE_CPU_FREQ)
275 rb
->profile_thread();
277 if (initSynth(NULL
, ROCKBOX_DIR
"/patchset/patchset.cfg",
278 ROCKBOX_DIR
"/patchset/drums.cfg") == -1)
280 printf("\nINIT ERROR\n");
285 #if INPUT_SRC_CAPS != 0
286 /* Select playback */
287 rb
->audio_set_input_source(AUDIO_SRC_PLAYBACK
, SRCF_PLAYBACK
);
288 rb
->audio_set_output_source(AUDIO_SRC_PLAYBACK
);
290 rb
->pcm_set_frequency(SAMPLE_RATE
); // 44100 22050 11025
293 retval
= beatboxmain();
300 rb
->pcm_set_frequency(HW_SAMPR_DEFAULT
);
302 #if defined(HAVE_ADJUSTABLE_CPU_FREQ)
303 rb
->cpu_boost(false);
315 inline void synthbuf(void)
319 static int currentSample
=0;
323 if(lastswap
==swap
) return;
326 outptr
=(swap
? gmbuf
: gmbuf
+BUF_SIZE
);
331 for(i
=0; i
<BUF_SIZE
/2; i
++)
333 synthSample(&synthtemp
[0], &synthtemp
[1]);
335 *outptr
=((synthtemp
[0]&0xFFFF) << 16) | (synthtemp
[1]&0xFFFF);
337 if(currentSample
==numberOfSamples
)
339 if(playState
== STATE_PLAYING
)
353 unsigned char trackPos
[V_NUMCELLS
];
354 unsigned char trackData
[H_NUMCELLS
][V_NUMCELLS
];
355 unsigned char trackMap
[V_NUMCELLS
] = {38, 39, 40, 41, 42, 43, 44, 56};
364 struct Cell pattern
[H_NUMCELLS
][V_NUMCELLS
];
365 struct Cell dispPattern
[H_NUMCELLS
][V_NUMCELLS
];
368 void advancePosition()
371 for(i
=0; i
<V_NUMCELLS
; i
++)
374 if(trackPos
[i
] == H_NUMCELLS
|| trackData
[trackPos
[i
]][i
] == VAL_LOOP
)
383 for(i
=0; i
<V_NUMCELLS
; i
++)
385 if(trackData
[trackPos
[i
]][i
] == VAL_ENABLED
)
386 pressNote(9, trackMap
[i
], 127);
391 #define NAME_POSY 100
392 void showDrumName(int trackNum
)
394 rb
->lcd_set_foreground(COLOR_NAME_TEXT
);
395 rb
->lcd_putsxy(NAME_POSX
, NAME_POSY
, drumNames
[trackMap
[trackNum
]-35]);
403 for(j
=0; j
<V_NUMCELLS
; j
++)
406 for(i
=0; i
<H_NUMCELLS
; i
++)
408 pattern
[i
][j
].color
= COLOR_NORMAL
;
409 pattern
[i
][j
].val
= trackData
[i
][j
];
412 pattern
[i
][j
].color
= COLOR_PLAY
;
415 pattern
[i
][j
].color
= COLOR_DISABLED
;
417 if(trackData
[i
][j
] == VAL_LOOP
)
419 pattern
[i
][j
].color
= COLOR_LOOPCELL
;
423 if(xCursor
== i
&& yCursor
== j
&& editState
== EDITSTATE_PATTERN
)
424 pattern
[i
][j
].color
= COLOR_EDIT
;
433 for(i
=0; i
<V_NUMCELLS
; i
++)
440 for(i
=0; i
<H_NUMCELLS
; i
++)
441 for(j
=0; j
<V_NUMCELLS
; j
++)
443 pattern
[i
][j
].val
=VAL_NONE
;
444 dispPattern
[i
][j
].val
=VAL_NONE
;
445 pattern
[i
][j
].color
= 0;
446 dispPattern
[i
][j
].color
= 0;
457 rb
->lcd_set_foreground(COLOR_GRID
);
459 for(i
=0; i
<H_NUMCELLS
+1; i
++)
460 rb
->lcd_vline(i
*CELL_XSIZE
+GRID_XPOS
, GRID_YPOS
, GRID_YPOS
+CELL_YSIZE
*V_NUMCELLS
);
462 for(i
=0; i
<V_NUMCELLS
+1; i
++)
463 rb
->lcd_hline(GRID_XPOS
, GRID_XPOS
+CELL_XSIZE
*H_NUMCELLS
, GRID_YPOS
+i
*CELL_YSIZE
);
469 void drawCell(int i
, int j
)
473 cellX
= GRID_XPOS
+ CELL_XSIZE
*i
+1;
474 cellY
= GRID_YPOS
+ CELL_YSIZE
*j
+1;
476 rb
->lcd_set_foreground(pattern
[i
][j
].color
);
477 rb
->lcd_fillrect(cellX
, cellY
, CELL_XSIZE
-1, CELL_YSIZE
-1);
479 rb
->lcd_set_foreground(0);
481 if(pattern
[i
][j
].val
== VAL_LOOP
)
483 rb
->lcd_drawline(cellX
, cellY
, cellX
+CELL_XSIZE
-2, cellY
+CELL_YSIZE
-2);
486 if(pattern
[i
][j
].val
== VAL_ENABLED
)
488 rb
->lcd_fillrect(cellX
+1, cellY
+1, CELL_XSIZE
-3, CELL_YSIZE
-3);
493 void redrawScreen(unsigned char force
)
497 for(i
=0; i
<H_NUMCELLS
; i
++)
499 for(j
=0; j
<V_NUMCELLS
; j
++)
501 if(force
|| (pattern
[i
][j
].val
!= dispPattern
[i
][j
].val
|| pattern
[i
][j
].color
!= dispPattern
[i
][j
].color
))
504 dispPattern
[i
][j
].val
= pattern
[i
][j
].val
;
505 dispPattern
[i
][j
].color
= pattern
[i
][j
].color
;
512 void get_more(unsigned char** start
, size_t* size
)
517 // printf("Buffer miss!"); // Comment out the printf to make missses less noticable.
521 synthbuf(); // For some reason midiplayer crashes when an update is forced
524 *size
= BUF_SIZE
*sizeof(short);
526 *start
= (unsigned char*)((swap
? gmbuf
: gmbuf
+ BUF_SIZE
));
529 *start
= (unsigned char*)(gmbuf
);
538 numberOfSamples
=44100/10;
540 rb
->pcm_play_data(&get_more
, NULL
, 0);
542 rb
->lcd_set_background(0x000000);
543 rb
->lcd_clear_display();
549 /* Start at 16 cells/loop for now. User can un-loop if more are needed */
550 for(i
=0; i
<V_NUMCELLS
; i
++)
551 trackData
[16][i
] = VAL_LOOP
;
554 /* Very very rough beat to 'Goodbye Horses'
555 trackData[16][3] = VAL_LOOP;
556 trackData[16][2] = VAL_LOOP;
562 trackData[12][3] = 1;
563 trackData[13][3] = 1;
567 trackData[10][2] = 1;
568 trackData[14][2] = 1;
572 showDrumName(yCursor
);
593 /* Prevent idle poweroff */
594 rb
->reset_poweroff_timer();
596 /* Code taken from Oscilloscope plugin */
597 switch(rb
->button_get(false))
601 case BTN_UP | BUTTON_REPEAT:
602 vol = rb->global_settings->volume;
603 if (vol < rb->sound_max(SOUND_VOLUME))
606 rb->sound_set(SOUND_VOLUME, vol);
607 rb->global_settings->volume = vol;
612 case BTN_DOWN | BUTTON_REPEAT:
613 vol = rb->global_settings->volume;
614 if (vol > rb->sound_min(SOUND_VOLUME))
617 rb->sound_set(SOUND_VOLUME, vol);
618 rb->global_settings->volume = vol;
624 //pressNote(9, 40, 127);
640 //pressNote(9, 39, 127);
646 case BEATBOX_UP
| BUTTON_REPEAT
:
648 if(editState
== EDITSTATE_PATTERN
)
653 showDrumName(yCursor
);
662 case BEATBOX_DOWN
| BUTTON_REPEAT
:
664 if(editState
== EDITSTATE_PATTERN
)
666 if(yCursor
< V_NUMCELLS
-1)
669 showDrumName(yCursor
);
678 case BEATBOX_LEFT
| BUTTON_REPEAT
:
680 if(editState
== EDITSTATE_PATTERN
)
693 case BEATBOX_RIGHT
| BUTTON_REPEAT
:
695 if(editState
== EDITSTATE_PATTERN
)
697 if(xCursor
< H_NUMCELLS
-1)
709 if(editState
== EDITSTATE_PATTERN
)
711 int cv
= trackData
[xCursor
][yCursor
];
716 trackData
[xCursor
][yCursor
] = cv
;
727 if(playState
== STATE_PLAYING
)
728 playState
= STATE_PAUSED
;
734 playState
= STATE_PLAYING
;
741 if(playState
== STATE_STOPPED
)
746 playState
=STATE_STOPPED
;