summaryrefslogtreecommitdiff
path: root/apps/plugins/midi
diff options
context:
space:
mode:
authorNils Wallménius <nils@rockbox.org>2007-09-24 15:57:32 +0000
committerNils Wallménius <nils@rockbox.org>2007-09-24 15:57:32 +0000
commit0e49605aaae01722a618dfdc64a328cc0e92bc04 (patch)
treee3241b18fae86271c5f3f9e18f819dc9c2ea29f3 /apps/plugins/midi
parente24975a35fbf564966b73dbaef766e215f7427d4 (diff)
downloadrockbox-0e49605aaae01722a618dfdc64a328cc0e92bc04.tar.gz
rockbox-0e49605aaae01722a618dfdc64a328cc0e92bc04.zip
Move all of midiplay into its subdir and add a Makefile for it, add header files as necessary.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14841 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/midi')
-rw-r--r--apps/plugins/midi/Makefile74
-rw-r--r--apps/plugins/midi/SOURCES6
-rw-r--r--apps/plugins/midi/guspat.c9
-rw-r--r--apps/plugins/midi/guspat.h1
-rw-r--r--apps/plugins/midi/midifile.c7
-rw-r--r--apps/plugins/midi/midifile.h21
-rw-r--r--apps/plugins/midi/midiplay.c318
-rw-r--r--apps/plugins/midi/midiutil.c118
-rw-r--r--apps/plugins/midi/midiutil.h172
-rw-r--r--apps/plugins/midi/sequencer.c8
-rw-r--r--apps/plugins/midi/sequencer.h23
-rw-r--r--apps/plugins/midi/synth.c38
-rw-r--r--apps/plugins/midi/synth.h50
13 files changed, 687 insertions, 158 deletions
diff --git a/apps/plugins/midi/Makefile b/apps/plugins/midi/Makefile
new file mode 100644
index 0000000000..0d81c87b4b
--- /dev/null
+++ b/apps/plugins/midi/Makefile
@@ -0,0 +1,74 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id $
8#
9
10INCLUDES = -I$(APPSDIR) -I.. -I. $(TARGET_INC) -I$(FIRMDIR)/include -I$(FIRMDIR)/export \
11 -I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(OUTDIR) -I$(BUILDDIR)
12CFLAGS = $(INCLUDES) $(GCCOPTS) $(TARGET) $(EXTRA_DEFINES) \
13 -DTARGET_ID=$(TARGET_ID) -DMEM=${MEMORYSIZE} -DPLUGIN
14
15ifdef APPEXTRA
16 INCLUDES += $(patsubst %,-I$(APPSDIR)/%,$(subst :, ,$(APPEXTRA)))
17endif
18
19LINKFILE := $(OBJDIR)/link.lds
20DEPFILE = $(OBJDIR)/dep-midiplay
21
22# This sets up 'SRC' based on the files mentioned in SOURCES
23include $(TOOLSDIR)/makesrc.inc
24
25SOURCES = $(SRC)
26OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
27DIRS = .
28
29ifndef SIMVER
30 LDS := ../plugin.lds
31 OUTPUT = $(OUTDIR)/midiplay.rock
32else ## simulators
33 OUTPUT = $(OUTDIR)/midiplay.rock
34endif
35
36all: $(OUTPUT)
37
38ifndef SIMVER
39$(OBJDIR)/midiplay.elf: $(OBJS) $(LINKFILE) $(BITMAPLIBS)
40 $(call PRINTS,LD $(@F))$(CC) $(CFLAGS) -o $@ $(OBJS) -L$(BUILDDIR) -lplugin -lgcc \
41 $(LINKBITMAPS) -T$(LINKFILE) -Wl,-Map,$(OBJDIR)/midiplay.map
42
43$(OUTPUT): $(OBJDIR)/midiplay.elf
44 $(call PRINTS,OBJCOPY $(@F))$(OC) -O binary $< $@
45else
46
47###################################################
48# This is the SDL simulator version
49
50$(OUTPUT): $(OBJS)
51 $(call PRINTS,LD $(@F))$(CC) $(CFLAGS) $(SHARED_FLAG) $(OBJS) -L$(BUILDDIR) -lplugin $(LINKBITMAPS) -o $@
52ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
53# 'x' must be kept or you'll have "Win32 error 5"
54# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
55# #define ERROR_ACCESS_DENIED 5L
56else
57 @chmod -x $@
58endif
59
60endif # end of simulator section
61
62include $(TOOLSDIR)/make.inc
63
64# MEMORYSIZE should be passed on to this makefile with the chosen memory size
65# given in number of MB
66$(LINKFILE): $(LDS)
67 $(call PRINTS,build $(@F))cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) \
68 $(DEFINES) -E -P - >$@
69
70clean:
71 $(call PRINTS,cleaning midiplay)rm -rf $(OBJDIR)/midiplay
72 $(SILENT)rm -f $(OBJDIR)/midiplay.* $(DEPFILE)
73
74-include $(DEPFILE)
diff --git a/apps/plugins/midi/SOURCES b/apps/plugins/midi/SOURCES
new file mode 100644
index 0000000000..74c0bf1396
--- /dev/null
+++ b/apps/plugins/midi/SOURCES
@@ -0,0 +1,6 @@
1midifile.c
2midiutil.c
3sequencer.c
4guspat.c
5synth.c
6midiplay.c
diff --git a/apps/plugins/midi/guspat.c b/apps/plugins/midi/guspat.c
index 2168766eab..f44e542e2d 100644
--- a/apps/plugins/midi/guspat.c
+++ b/apps/plugins/midi/guspat.c
@@ -5,6 +5,7 @@
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$
8 * 9 *
9 * Copyright (C) 2005 Stepan Moskovchenko 10 * Copyright (C) 2005 Stepan Moskovchenko
10 * 11 *
@@ -15,7 +16,9 @@
15 * KIND, either express or implied. 16 * KIND, either express or implied.
16 * 17 *
17 ****************************************************************************/ 18 ****************************************************************************/
18 19#include "plugin.h"
20#include "guspat.h"
21#include "midiutil.h"
19 22
20extern struct plugin_api * rb; 23extern struct plugin_api * rb;
21 24
@@ -119,8 +122,6 @@ struct GWaveform * loadWaveform(int file)
119 return wav; 122 return wav;
120} 123}
121 124
122
123
124int selectWaveform(struct GPatch * pat, int midiNote) 125int selectWaveform(struct GPatch * pat, int midiNote)
125{ 126{
126 /* We divide by 100 here because everyone's freq formula is slightly different */ 127 /* We divide by 100 here because everyone's freq formula is slightly different */
@@ -137,7 +138,6 @@ int selectWaveform(struct GPatch * pat, int midiNote)
137 return 0; 138 return 0;
138} 139}
139 140
140
141struct GPatch * gusload(char * filename) 141struct GPatch * gusload(char * filename)
142{ 142{
143 struct GPatch * gp = (struct GPatch *)malloc(sizeof(struct GPatch)); 143 struct GPatch * gp = (struct GPatch *)malloc(sizeof(struct GPatch));
@@ -196,3 +196,4 @@ struct GPatch * gusload(char * filename)
196 196
197 return gp; 197 return gp;
198} 198}
199
diff --git a/apps/plugins/midi/guspat.h b/apps/plugins/midi/guspat.h
index e35f54b57a..3f858cd909 100644
--- a/apps/plugins/midi/guspat.h
+++ b/apps/plugins/midi/guspat.h
@@ -5,6 +5,7 @@
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$
8 * 9 *
9 * Copyright (C) 2005 Stepan Moskovchenko 10 * Copyright (C) 2005 Stepan Moskovchenko
10 * 11 *
diff --git a/apps/plugins/midi/midifile.c b/apps/plugins/midi/midifile.c
index 7161818421..1fa648ff50 100644
--- a/apps/plugins/midi/midifile.c
+++ b/apps/plugins/midi/midifile.c
@@ -5,6 +5,7 @@
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$
8 * 9 *
9 * Copyright (C) 2005 Stepan Moskovchenko 10 * Copyright (C) 2005 Stepan Moskovchenko
10 * 11 *
@@ -15,8 +16,8 @@
15 * KIND, either express or implied. 16 * KIND, either express or implied.
16 * 17 *
17 ****************************************************************************/ 18 ****************************************************************************/
18 19#include "plugin.h"
19 20#include "midiutil.h"
20 21
21extern struct plugin_api * rb; 22extern struct plugin_api * rb;
22 23
@@ -234,7 +235,6 @@ struct Track * readTrack(int file)
234 return trk; 235 return trk;
235} 236}
236 237
237
238int readID(int file) 238int readID(int file)
239{ 239{
240 char id[5]; 240 char id[5];
@@ -318,4 +318,3 @@ void unloadFile(struct MIDIfile * mf)
318} 318}
319*/ 319*/
320 320
321
diff --git a/apps/plugins/midi/midifile.h b/apps/plugins/midi/midifile.h
new file mode 100644
index 0000000000..a1024d500b
--- /dev/null
+++ b/apps/plugins/midi/midifile.h
@@ -0,0 +1,21 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Stepan Moskovchenko
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20struct MIDIfile * loadFile(char * filename);
21
diff --git a/apps/plugins/midi/midiplay.c b/apps/plugins/midi/midiplay.c
new file mode 100644
index 0000000000..7a1176b1c9
--- /dev/null
+++ b/apps/plugins/midi/midiplay.c
@@ -0,0 +1,318 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Karl Kurbjun based on midi2wav by Stepan Moskovchenko
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "plugin.h"
20#include "guspat.h"
21#include "midiutil.h"
22#include "synth.h"
23#include "sequencer.h"
24#include "midifile.h"
25
26PLUGIN_HEADER
27PLUGIN_IRAM_DECLARE
28
29/* variable button definitions */
30#if CONFIG_KEYPAD == RECORDER_PAD
31#define BTN_QUIT BUTTON_OFF
32#define BTN_RIGHT BUTTON_RIGHT
33#define BTN_UP BUTTON_UP
34#define BTN_DOWN BUTTON_DOWN
35
36#elif CONFIG_KEYPAD == ONDIO_PAD
37#define BTN_QUIT BUTTON_OFF
38#define BTN_RIGHT BUTTON_RIGHT
39#define BTN_UP BUTTON_UP
40#define BTN_DOWN BUTTON_DOWN
41
42#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
43#define BTN_QUIT BUTTON_OFF
44#define BTN_RIGHT BUTTON_RIGHT
45#define BTN_UP BUTTON_UP
46#define BTN_DOWN BUTTON_DOWN
47
48#define BTN_RC_QUIT BUTTON_RC_STOP
49
50#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
51 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
52#define BTN_QUIT (BUTTON_SELECT | BUTTON_MENU)
53#define BTN_RIGHT BUTTON_RIGHT
54#define BTN_UP BUTTON_SCROLL_FWD
55#define BTN_DOWN BUTTON_SCROLL_BACK
56
57#elif (CONFIG_KEYPAD == GIGABEAT_PAD)
58#define BTN_QUIT BUTTON_POWER
59#define BTN_RIGHT BUTTON_RIGHT
60#define BTN_UP BUTTON_UP
61#define BTN_DOWN BUTTON_DOWN
62
63#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
64(CONFIG_KEYPAD == SANSA_C200_PAD)
65#define BTN_QUIT BUTTON_POWER
66#define BTN_RIGHT BUTTON_RIGHT
67#define BTN_UP BUTTON_UP
68#define BTN_DOWN BUTTON_DOWN
69
70#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
71#define BTN_QUIT BUTTON_POWER
72#define BTN_RIGHT BUTTON_RIGHT
73#define BTN_UP BUTTON_UP
74#define BTN_DOWN BUTTON_DOWN
75
76#elif CONFIG_KEYPAD == IRIVER_H10_PAD
77#define BTN_QUIT BUTTON_POWER
78#define BTN_RIGHT BUTTON_RIGHT
79#define BTN_UP BUTTON_SCROLL_UP
80#define BTN_DOWN BUTTON_SCROLL_DOWN
81
82#endif
83
84#undef SYNC
85
86#ifdef SIMULATOR
87 #define SYNC
88#endif
89
90struct MIDIfile * mf IBSS_ATTR;
91
92int numberOfSamples IBSS_ATTR;
93long bpm IBSS_ATTR;
94
95long gmbuf[BUF_SIZE*NBUF];
96
97int quit=0;
98struct plugin_api * rb;
99
100enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
101{
102 int retval = 0;
103
104 PLUGIN_IRAM_INIT(api)
105
106 rb = api;
107 if(parameter == NULL)
108 {
109 rb->splash(HZ*2, " Play .MID file ");
110 return PLUGIN_OK;
111 }
112 rb->lcd_setfont(0);
113
114#if defined(HAVE_ADJUSTABLE_CPU_FREQ)
115 rb->cpu_boost(true);
116#endif
117
118 printf("%s", parameter);
119 /* rb->splash(HZ, true, parameter); */
120
121#ifdef RB_PROFILE
122 rb->profile_thread();
123#endif
124
125 retval = midimain(parameter);
126
127#ifdef RB_PROFILE
128 rb->profstop();
129#endif
130
131 rb->pcm_play_stop();
132 rb->pcm_set_frequency(HW_SAMPR_DEFAULT);
133
134#if defined(HAVE_ADJUSTABLE_CPU_FREQ)
135 rb->cpu_boost(false);
136#endif
137
138 rb->splash(HZ, "FINISHED PLAYING");
139
140 if(retval == -1)
141 return PLUGIN_ERROR;
142 return PLUGIN_OK;
143}
144
145bool swap=0;
146bool lastswap=1;
147
148inline void synthbuf(void)
149{
150 long *outptr;
151 register int i;
152 static int currentSample=0;
153 int synthtemp[2];
154
155#ifndef SYNC
156 if(lastswap==swap) return;
157 lastswap=swap;
158
159 outptr=(swap ? gmbuf : gmbuf+BUF_SIZE);
160#else
161 outptr=gmbuf;
162#endif
163
164 for(i=0; i<BUF_SIZE/2; i++)
165 {
166 synthSample(&synthtemp[0], &synthtemp[1]);
167 currentSample++;
168 *outptr=((synthtemp[0]&0xFFFF) << 16) | (synthtemp[1]&0xFFFF);
169 outptr++;
170 if(currentSample==numberOfSamples)
171 {
172 if( tick() == 0 ) quit=1;
173 currentSample=0;
174 }
175 }
176}
177
178void get_more(unsigned char** start, size_t* size)
179{
180#ifndef SYNC
181 if(lastswap!=swap)
182 {
183 printf("Buffer miss!"); // Comment out the printf to make missses less noticable.
184 }
185
186#else
187 synthbuf(); // For some reason midiplayer crashes when an update is forced
188#endif
189
190 *size = BUF_SIZE*sizeof(short);
191#ifndef SYNC
192 *start = (unsigned char*)((swap ? gmbuf : gmbuf + BUF_SIZE));
193 swap=!swap;
194#else
195 *start = (unsigned char*)(gmbuf);
196#endif
197}
198
199int midimain(void * filename)
200{
201 int notesUsed = 0;
202 int a=0;
203 printf("Loading file");
204 mf= loadFile(filename);
205
206 if(mf == NULL)
207 {
208 printf("Error loading file.");
209 return -1;
210 }
211
212 if (initSynth(mf, ROCKBOX_DIR "/patchset/patchset.cfg",
213 ROCKBOX_DIR "/patchset/drums.cfg") == -1)
214 return -1;
215
216//#ifndef SIMULATOR
217 rb->pcm_play_stop();
218#if INPUT_SRC_CAPS != 0
219 /* Select playback */
220 rb->audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
221 rb->audio_set_output_source(AUDIO_SRC_PLAYBACK);
222#endif
223 rb->pcm_set_frequency(SAMPLE_RATE); // 44100 22050 11025
224//#endif
225
226 /*
227 * tick() will do one MIDI clock tick. Then, there's a loop here that
228 * will generate the right number of samples per MIDI tick. The whole
229 * MIDI playback is timed in terms of this value.. there are no forced
230 * delays or anything. It just produces enough samples for each tick, and
231 * the playback of these samples is what makes the timings right.
232 *
233 * This seems to work quite well. On a laptop, anyway.
234 */
235
236 printf("Okay, starting sequencing");
237
238 bpm=mf->div*1000000/tempo;
239 numberOfSamples=SAMPLE_RATE/bpm;
240
241
242
243 /* Skip over any junk in the beginning of the file, so start playing */
244 /* after the first note event */
245 do
246 {
247 notesUsed = 0;
248 for(a=0; a<MAX_VOICES; a++)
249 if(voices[a].isUsed == 1)
250 notesUsed++;
251 tick();
252 } while(notesUsed == 0);
253
254 synthbuf();
255//#ifndef SIMULATOR
256 rb->pcm_play_data(&get_more, NULL, 0);
257//#endif
258
259 int vol=0;
260
261 while(!quit)
262 {
263 #ifndef SYNC
264 synthbuf();
265 #endif
266 rb->yield();
267
268 /* Prevent idle poweroff */
269 rb->reset_poweroff_timer();
270
271 /* Code taken from Oscilloscope plugin */
272 switch(rb->button_get(false))
273 {
274 case BTN_UP:
275 case BTN_UP | BUTTON_REPEAT:
276 vol = rb->global_settings->volume;
277 if (vol < rb->sound_max(SOUND_VOLUME))
278 {
279 vol++;
280 rb->sound_set(SOUND_VOLUME, vol);
281 rb->global_settings->volume = vol;
282 }
283 break;
284
285 case BTN_DOWN:
286 case BTN_DOWN | BUTTON_REPEAT:
287 vol = rb->global_settings->volume;
288 if (vol > rb->sound_min(SOUND_VOLUME))
289 {
290 vol--;
291 rb->sound_set(SOUND_VOLUME, vol);
292 rb->global_settings->volume = vol;
293 }
294 break;
295
296 case BTN_RIGHT:
297 {
298 /* Skip 3 seconds */
299 /* Should skip length be retrieved from the RB settings? */
300 int samp = 3*SAMPLE_RATE;
301 int tickCount = samp / numberOfSamples;
302 int a=0;
303 for(a=0; a<tickCount; a++)
304 tick();
305 break;
306 }
307#ifdef BTN_RC_QUIT
308 case BTN_RC_QUIT:
309#endif
310 case BTN_QUIT:
311 quit=1;
312 }
313
314
315 }
316
317 return 0;
318}
diff --git a/apps/plugins/midi/midiutil.c b/apps/plugins/midi/midiutil.c
index 0607c1ab3c..7cb128fb84 100644
--- a/apps/plugins/midi/midiutil.c
+++ b/apps/plugins/midi/midiutil.c
@@ -5,6 +5,7 @@
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$
8 * 9 *
9 * Copyright (C) 2005 Stepan Moskovchenko 10 * Copyright (C) 2005 Stepan Moskovchenko
10 * 11 *
@@ -15,134 +16,23 @@
15 * KIND, either express or implied. 16 * KIND, either express or implied.
16 * 17 *
17 ****************************************************************************/ 18 ****************************************************************************/
18 19#include "plugin.h"
19 20#include "midiutil.h"
20#define BYTE unsigned char
21
22//Data chunk ID types, returned by readID()
23#define ID_UNKNOWN -1
24#define ID_MTHD 1
25#define ID_MTRK 2
26#define ID_EOF 3
27#define ID_RIFF 4
28
29
30//MIDI Commands
31#define MIDI_NOTE_OFF 128
32#define MIDI_NOTE_ON 144
33#define MIDI_AFTERTOUCH 160
34#define MIDI_CONTROL 176
35#define MIDI_PRGM 192
36#define MIDI_PITCHW 224
37
38
39//MIDI Controllers
40#define CTRL_VOLUME 7
41#define CTRL_BALANCE 8
42#define CTRL_PANNING 10
43#define CHANNEL 1
44
45//Most of these are deprecated.. rampdown is used, maybe one other one too
46#define STATE_ATTACK 1
47#define STATE_DECAY 2
48#define STATE_SUSTAIN 3
49#define STATE_RELEASE 4
50#define STATE_RAMPDOWN 5
51
52//Loop states
53#define STATE_LOOPING 7
54#define STATE_NONLOOPING 8
55
56//Various bits in the GUS mode byte
57#define LOOP_ENABLED 4
58#define LOOP_PINGPONG 8
59#define LOOP_REVERSE 16
60
61#define LOOPDIR_FORWARD 0
62#define LOOPDIR_REVERSE 1
63
64 21
65extern struct plugin_api * rb; 22extern struct plugin_api * rb;
66 23
67int printf(const char *fmt, ...);
68
69int chVol[16] IBSS_ATTR; /* Channel volume */ 24int chVol[16] IBSS_ATTR; /* Channel volume */
70int chPanLeft[16] IBSS_ATTR; /* Channel panning */ 25int chPanLeft[16] IBSS_ATTR; /* Channel panning */
71int chPanRight[16] IBSS_ATTR; 26int chPanRight[16] IBSS_ATTR;
72int chPat[16] IBSS_ATTR; /* Channel patch */ 27int chPat[16] IBSS_ATTR; /* Channel patch */
73int chPW[16] IBSS_ATTR; /* Channel pitch wheel, MSB only */ 28int chPW[16] IBSS_ATTR; /* Channel pitch wheel, MSB only */
74 29
75
76struct GPatch * gusload(char *); 30struct GPatch * gusload(char *);
77struct GPatch * patchSet[128]; 31struct GPatch * patchSet[128];
78struct GPatch * drumSet[128]; 32struct GPatch * drumSet[128];
79 33
80struct Event
81{
82 unsigned int delta;
83 unsigned char status, d1, d2;
84 unsigned int len;
85 unsigned char * evData;
86};
87
88struct Track
89{
90 unsigned int size;
91 unsigned int numEvents;
92 unsigned int delta; /* For sequencing */
93 unsigned int pos; /* For sequencing */
94 void * dataBlock;
95};
96
97
98struct MIDIfile
99{
100 int Length;
101 unsigned short numTracks;
102 unsigned short div; /* Time division, X ticks per millisecond */
103 struct Track * tracks[48];
104 unsigned char patches[128];
105 int numPatches;
106};
107
108/*
109struct SynthObject
110{
111 struct GWaveform * wf;
112 unsigned int delta;
113 unsigned int decay;
114 unsigned int cp;
115 unsigned char state, loopState, loopDir;
116 unsigned char note, vol, ch, isUsed;
117 int curRate, curOffset, targetOffset;
118 unsigned int curPoint;
119};
120*/
121
122struct SynthObject
123{
124 struct GWaveform * wf;
125 int delta;
126 int decay;
127 unsigned int cp; /* unsigned int */
128 int state, loopState, loopDir;
129 int note, vol, ch, isUsed;
130 int curRate, curOffset, targetOffset;
131 int curPoint;
132 signed short int volscale;
133};
134
135struct SynthObject voices[MAX_VOICES] IBSS_ATTR; 34struct SynthObject voices[MAX_VOICES] IBSS_ATTR;
136 35
137void sendEvent(struct Event * ev);
138inline void setPoint(struct SynthObject * so, int pt);
139struct Event * getEvent(struct Track * tr, int evNum);
140int readTwoBytes(int file);
141int readFourBytes(int file);
142int readVarData(int file);
143int midimain(void * filename);
144
145
146void *alloc(int size) 36void *alloc(int size)
147{ 37{
148 static char *offset = NULL; 38 static char *offset = NULL;
@@ -180,7 +70,6 @@ void *alloc(int size)
180 return ret; 70 return ret;
181} 71}
182 72
183
184/* Rick's code */ 73/* Rick's code */
185/* 74/*
186void *alloc(int size) 75void *alloc(int size)
@@ -267,3 +156,4 @@ void exit(int code)
267{ 156{
268 code = code; /* Stub function, kill warning for now */ 157 code = code; /* Stub function, kill warning for now */
269} 158}
159
diff --git a/apps/plugins/midi/midiutil.h b/apps/plugins/midi/midiutil.h
new file mode 100644
index 0000000000..cfaa4fb2fe
--- /dev/null
+++ b/apps/plugins/midi/midiutil.h
@@ -0,0 +1,172 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Stepan Moskovchenko
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#define FRACTSIZE 10
21
22#define BUF_SIZE 256
23#define NBUF 2
24
25
26#ifndef SIMULATOR
27
28#if (HW_SAMPR_CAPS & SAMPR_CAP_22)
29#define SAMPLE_RATE SAMPR_22 // 44100 22050 11025
30#else
31#define SAMPLE_RATE SAMPR_44 // 44100 22050 11025
32#endif
33
34#define MAX_VOICES 20 // Note: 24 midi channels is the minimum general midi
35 // spec implementation
36
37#else // Simulator requires 44100, and we can afford to use more voices
38
39#define SAMPLE_RATE SAMPR_44
40#define MAX_VOICES 48
41
42#endif
43
44#define BYTE unsigned char
45
46//Data chunk ID types, returned by readID()
47#define ID_UNKNOWN -1
48#define ID_MTHD 1
49#define ID_MTRK 2
50#define ID_EOF 3
51#define ID_RIFF 4
52
53//MIDI Commands
54#define MIDI_NOTE_OFF 128
55#define MIDI_NOTE_ON 144
56#define MIDI_AFTERTOUCH 160
57#define MIDI_CONTROL 176
58#define MIDI_PRGM 192
59#define MIDI_PITCHW 224
60
61//MIDI Controllers
62#define CTRL_VOLUME 7
63#define CTRL_BALANCE 8
64#define CTRL_PANNING 10
65#define CHANNEL 1
66
67//Most of these are deprecated.. rampdown is used, maybe one other one too
68#define STATE_ATTACK 1
69#define STATE_DECAY 2
70#define STATE_SUSTAIN 3
71#define STATE_RELEASE 4
72#define STATE_RAMPDOWN 5
73
74//Loop states
75#define STATE_LOOPING 7
76#define STATE_NONLOOPING 8
77
78//Various bits in the GUS mode byte
79#define LOOP_ENABLED 4
80#define LOOP_PINGPONG 8
81#define LOOP_REVERSE 16
82
83#define LOOPDIR_FORWARD 0
84#define LOOPDIR_REVERSE 1
85
86struct MIDIfile
87{
88 int Length;
89 unsigned short numTracks;
90 unsigned short div; /* Time division, X ticks per millisecond */
91 struct Track * tracks[48];
92 unsigned char patches[128];
93 int numPatches;
94};
95
96/*
97struct SynthObject
98{
99 struct GWaveform * wf;
100 unsigned int delta;
101 unsigned int decay;
102 unsigned int cp;
103 unsigned char state, loopState, loopDir;
104 unsigned char note, vol, ch, isUsed;
105 int curRate, curOffset, targetOffset;
106 unsigned int curPoint;
107};
108*/
109
110struct SynthObject
111{
112 struct GWaveform * wf;
113 int delta;
114 int decay;
115 unsigned int cp; /* unsigned int */
116 int state, loopState, loopDir;
117 int note, vol, ch, isUsed;
118 int curRate, curOffset, targetOffset;
119 int curPoint;
120 signed short int volscale;
121};
122
123struct Event
124{
125 unsigned int delta;
126 unsigned char status, d1, d2;
127 unsigned int len;
128 unsigned char * evData;
129};
130
131struct Track
132{
133 unsigned int size;
134 unsigned int numEvents;
135 unsigned int delta; /* For sequencing */
136 unsigned int pos; /* For sequencing */
137 void * dataBlock;
138};
139
140int printf(const char *fmt, ...);
141int midimain(void * filename);
142unsigned char readChar(int file);
143void sendEvent(struct Event * ev);
144inline void setPoint(struct SynthObject * so, int pt);
145struct Event * getEvent(struct Track * tr, int evNum);
146int readTwoBytes(int file);
147int readFourBytes(int file);
148int readVarData(int file);
149int eof(int fd);
150unsigned char * readData(int file, int len);
151void exit(int code);
152
153#define malloc(n) my_malloc(n)
154void * my_malloc(int size);
155
156extern struct SynthObject voices[MAX_VOICES];
157
158extern int chVol[16]; /* Channel volume */
159extern int chPanLeft[16]; /* Channel panning */
160extern int chPanRight[16];
161extern int chPat[16]; /* Channel patch */
162extern int chPW[16]; /* Channel pitch wheel, MSB only */
163
164extern struct GPatch * gusload(char *);
165extern struct GPatch * patchSet[128];
166extern struct GPatch * drumSet[128];
167
168extern struct MIDIfile * mf;
169
170extern int numberOfSamples;
171extern long bpm;
172
diff --git a/apps/plugins/midi/sequencer.c b/apps/plugins/midi/sequencer.c
index 68c29f35ad..473b7e4e2c 100644
--- a/apps/plugins/midi/sequencer.c
+++ b/apps/plugins/midi/sequencer.c
@@ -5,6 +5,7 @@
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$
8 * 9 *
9 * Copyright (C) 2005 Stepan Moskovchenko 10 * Copyright (C) 2005 Stepan Moskovchenko
10 * 11 *
@@ -15,6 +16,9 @@
15 * KIND, either express or implied. 16 * KIND, either express or implied.
16 * 17 *
17 ****************************************************************************/ 18 ****************************************************************************/
19#include "plugin.h"
20#include "midiutil.h"
21#include "guspat.h"
18 22
19void setVolScale(int a); 23void setVolScale(int a);
20 24
@@ -22,7 +26,6 @@ extern struct plugin_api * rb;
22 26
23long tempo=375000; 27long tempo=375000;
24 28
25
26inline void setVol(int ch, int vol) 29inline void setVol(int ch, int vol)
27{ 30{
28 int a=0; 31 int a=0;
@@ -119,7 +122,6 @@ long pitchTbl[] ICONST_ATTR={
119 73297,73330,73363,73396,73429,73462,73495,73528 122 73297,73330,73363,73396,73429,73462,73495,73528
120}; 123};
121 124
122
123void findDelta(struct SynthObject * so, int ch, int note) 125void findDelta(struct SynthObject * so, int ch, int note)
124{ 126{
125 127
@@ -147,7 +149,6 @@ inline void setPW(int ch, int msb, int lsb)
147 } 149 }
148} 150}
149 151
150
151/* Sets the volume scaling by channel volume and note volume */ 152/* Sets the volume scaling by channel volume and note volume */
152/* This way we can do the multiplication/indexing once per */ 153/* This way we can do the multiplication/indexing once per */
153/* MIDI event at the most, instead of once per sample. */ 154/* MIDI event at the most, instead of once per sample. */
@@ -375,3 +376,4 @@ int tick(void)
375 else 376 else
376 return 0; 377 return 0;
377} 378}
379
diff --git a/apps/plugins/midi/sequencer.h b/apps/plugins/midi/sequencer.h
new file mode 100644
index 0000000000..cfa81f99c6
--- /dev/null
+++ b/apps/plugins/midi/sequencer.h
@@ -0,0 +1,23 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Stepan Moskovchenko
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20int tick(void);
21
22extern long tempo;
23
diff --git a/apps/plugins/midi/synth.c b/apps/plugins/midi/synth.c
index 00a01e41cb..917a8ae13d 100644
--- a/apps/plugins/midi/synth.c
+++ b/apps/plugins/midi/synth.c
@@ -5,6 +5,7 @@
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$
8 * 9 *
9 * Copyright (C) 2005 Stepan Moskovchenko 10 * Copyright (C) 2005 Stepan Moskovchenko
10 * 11 *
@@ -15,6 +16,10 @@
15 * KIND, either express or implied. 16 * KIND, either express or implied.
16 * 17 *
17 ****************************************************************************/ 18 ****************************************************************************/
19#include "plugin.h"
20#include "guspat.h"
21#include "midiutil.h"
22#include "synth.h"
18 23
19extern struct plugin_api * rb; 24extern struct plugin_api * rb;
20 25
@@ -43,8 +48,6 @@ void readTextBlock(int file, char * buf)
43 rb->lseek(file, -1, SEEK_CUR); 48 rb->lseek(file, -1, SEEK_CUR);
44} 49}
45 50
46
47
48/* Filename is the name of the config file */ 51/* Filename is the name of the config file */
49/* The MIDI file should have been loaded at this point */ 52/* The MIDI file should have been loaded at this point */
50int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig) 53int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
@@ -400,34 +403,3 @@ signed short int synthVoice(struct SynthObject * so)
400 return s*so->volscale>>14; 403 return s*so->volscale>>14;
401} 404}
402 405
403
404
405
406
407inline void synthSample(int * mixL, int * mixR)
408{
409 register int dL=0;
410 register int dR=0;
411 register short sample=0;
412 register struct SynthObject *voicept=voices;
413 struct SynthObject *lastvoice=&voices[MAX_VOICES];
414
415 while(voicept!=lastvoice)
416 {
417 if(voicept->isUsed==1)
418 {
419 sample = synthVoice(voicept);
420 dL += (sample*chPanLeft[voicept->ch])>>7;
421 dR += (sample*chPanRight[voicept->ch])>>7;
422 }
423 voicept++;
424 }
425
426 *mixL=dL;
427 *mixR=dR;
428
429 /* TODO: Automatic Gain Control, anyone? */
430 /* Or, should this be implemented on the DSP's output volume instead? */
431
432 return; /* No more ghetto lowpass filter.. linear intrpolation works well. */
433}
diff --git a/apps/plugins/midi/synth.h b/apps/plugins/midi/synth.h
new file mode 100644
index 0000000000..daaf26d5f6
--- /dev/null
+++ b/apps/plugins/midi/synth.h
@@ -0,0 +1,50 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Stepan Moskovchenko
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig);
21signed short int synthVoice(struct SynthObject * so);
22
23static inline void synthSample(int * mixL, int * mixR)
24{
25 register int dL=0;
26 register int dR=0;
27 register short sample=0;
28 register struct SynthObject *voicept=voices;
29 struct SynthObject *lastvoice=&voices[MAX_VOICES];
30
31 while(voicept!=lastvoice)
32 {
33 if(voicept->isUsed==1)
34 {
35 sample = synthVoice(voicept);
36 dL += (sample*chPanLeft[voicept->ch])>>7;
37 dR += (sample*chPanRight[voicept->ch])>>7;
38 }
39 voicept++;
40 }
41
42 *mixL=dL;
43 *mixR=dR;
44
45 /* TODO: Automatic Gain Control, anyone? */
46 /* Or, should this be implemented on the DSP's output volume instead? */
47
48 return; /* No more ghetto lowpass filter.. linear intrpolation works well. */
49}
50