summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNils Wallménius <nils@rockbox.org>2007-10-08 19:28:41 +0000
committerNils Wallménius <nils@rockbox.org>2007-10-08 19:28:41 +0000
commitf619f8167646632d6eab10f529638eebbdda6af6 (patch)
tree119a1f4051d59808a25612421f613cb09ee1e9d5
parentd712e252fecf814a48814034a55ba60a1b194598 (diff)
downloadrockbox-f619f8167646632d6eab10f529638eebbdda6af6.tar.gz
rockbox-f619f8167646632d6eab10f529638eebbdda6af6.zip
Change loop structure for sample synthesizing. Gives a nice speedup on both coldfire and arm targets.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15036 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/midi/midiplay.c39
-rw-r--r--apps/plugins/midi/synth.c46
-rw-r--r--apps/plugins/midi/synth.h55
3 files changed, 64 insertions, 76 deletions
diff --git a/apps/plugins/midi/midiplay.c b/apps/plugins/midi/midiplay.c
index c557433dce..99f05718d6 100644
--- a/apps/plugins/midi/midiplay.c
+++ b/apps/plugins/midi/midiplay.c
@@ -148,32 +148,31 @@ bool lastswap=1;
148 148
149static inline void synthbuf(void) 149static inline void synthbuf(void)
150{ 150{
151 int32_t *outptr; 151 int32_t *outptr;
152 register int i; 152 int i;
153 int currentSample=0;
154 int synthtemp[2];
155 153
156#ifndef SYNC 154#ifndef SYNC
157 if(lastswap==swap) return; 155 if(lastswap==swap) return;
158 lastswap=swap; 156 lastswap=swap;
159 157
160 outptr=(swap ? gmbuf : gmbuf+BUF_SIZE); 158 outptr=(swap ? gmbuf : gmbuf+BUF_SIZE);
161#else 159#else
162 outptr=gmbuf; 160 outptr=gmbuf;
163#endif 161#endif
164 162
165 for(i=0; i<BUF_SIZE; i++) 163 for(i=0; i<BUF_SIZE/numberOfSamples; i++)
166 { 164 {
167 synthSample(&synthtemp[0], &synthtemp[1]); 165 synthSamples((int32_t*)outptr, numberOfSamples);
168 currentSample++; 166 outptr += numberOfSamples;
169 *outptr=((synthtemp[0]&0xFFFF) << 16) | (synthtemp[1]&0xFFFF); 167 if( tick() == 0 )
170 outptr++; 168 quit=1;
171 if(currentSample==numberOfSamples) 169 }
172 { 170
173 if( tick() == 0 ) quit=1; 171 if(BUF_SIZE%numberOfSamples)
174 currentSample=0; 172 {
175 } 173 synthSamples((int32_t*)outptr, BUF_SIZE%numberOfSamples);
176 } 174 outptr += BUF_SIZE%numberOfSamples;
175 }
177} 176}
178 177
179void get_more(unsigned char** start, size_t* size) 178void get_more(unsigned char** start, size_t* size)
diff --git a/apps/plugins/midi/synth.c b/apps/plugins/midi/synth.c
index 327f32e288..568c7bb1ce 100644
--- a/apps/plugins/midi/synth.c
+++ b/apps/plugins/midi/synth.c
@@ -255,8 +255,7 @@ inline void stopVoice(struct SynthObject * so)
255 so->decay = 0; 255 so->decay = 0;
256} 256}
257 257
258int synthVoice(struct SynthObject * so) ICODE_ATTR; 258static inline int synthVoice(struct SynthObject * so)
259int synthVoice(struct SynthObject * so)
260{ 259{
261 struct GWaveform * wf; 260 struct GWaveform * wf;
262 register int s; 261 register int s;
@@ -404,3 +403,46 @@ int synthVoice(struct SynthObject * so)
404 return s*so->volscale>>14; 403 return s*so->volscale>>14;
405} 404}
406 405
406/* synth num_samples samples and write them to the */
407/* buffer pointed to by buf_ptr */
408void synthSamples(int32_t *buf_ptr, unsigned int num_samples) ICODE_ATTR;
409void synthSamples(int32_t *buf_ptr, unsigned int num_samples)
410{
411 int i;
412 register int dL;
413 register int dR;
414 register int sample;
415 register struct SynthObject *voicept;
416 while(num_samples>0)
417 {
418 dL=0;
419 dR=0;
420 voicept=&voices[0];
421
422 for(i=MAX_VOICES; i > 0; i--)
423 {
424 if(voicept->isUsed==1)
425 {
426 sample = synthVoice(voicept);
427 dL += sample;
428 sample *= chPan[voicept->ch];
429 dR += sample;
430 }
431 voicept++;
432 }
433
434 dL = (dL << 7) - dR;
435
436 /* combine the left and right 16 bit samples into 32 bits and write */
437 /* to the buffer, left sample in the high word and right in the low word */
438 *buf_ptr=(((dL&0x7FFF80) << 9) | ((dR&0x7FFF80) >> 7));
439
440 buf_ptr++;
441 num_samples--;
442 }
443 /* TODO: Automatic Gain Control, anyone? */
444 /* Or, should this be implemented on the DSP's output volume instead? */
445
446 return; /* No more ghetto lowpass filter. Linear interpolation works well. */
447}
448
diff --git a/apps/plugins/midi/synth.h b/apps/plugins/midi/synth.h
index e04f9f4bd5..5f9edf89e5 100644
--- a/apps/plugins/midi/synth.h
+++ b/apps/plugins/midi/synth.h
@@ -17,61 +17,8 @@
17 * 17 *
18 ****************************************************************************/ 18 ****************************************************************************/
19int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig); 19int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig);
20int synthVoice(struct SynthObject * so);
21void setPoint(struct SynthObject * so, int pt); 20void setPoint(struct SynthObject * so, int pt);
22 21void synthSamples(int32_t *buf_ptr, unsigned int num_samples);
23static inline void synthSample(int * mixL, int * mixR)
24{
25 int i;
26 register int dL=0;
27 register int dR=0;
28 register int sample = 0;
29 register struct SynthObject *voicept=voices;
30
31 for(i=MAX_VOICES/2; i > 0; i--)
32 {
33 if(voicept->isUsed==1)
34 {
35 sample = synthVoice(voicept);
36 dL += sample;
37 sample *= chPan[voicept->ch];
38 dR += sample;
39 }
40 voicept++;
41 if(voicept->isUsed==1)
42 {
43 sample = synthVoice(voicept);
44 dL += sample;
45 sample *= chPan[voicept->ch];
46 dR += sample;
47 }
48 voicept++;
49 }
50
51/* if MAX_VOICES is not even we do this to get the last voice */
52#if MAX_VOICES%2
53 if (MAX_VOICES%2)
54 {
55 if(voicept->isUsed==1)
56 {
57 sample = synthVoice(voicept);
58 dL += sample;
59 sample *= chPan[voicept->ch];
60 dR += sample;
61 }
62 }
63#endif
64
65 dL = (dL << 7) - dR;
66
67 *mixL=dL >> 7;
68 *mixR=dR >> 7;
69
70 /* TODO: Automatic Gain Control, anyone? */
71 /* Or, should this be implemented on the DSP's output volume instead? */
72
73 return; /* No more ghetto lowpass filter. Linear interpolation works well. */
74}
75 22
76static inline struct Event * getEvent(struct Track * tr, int evNum) 23static inline struct Event * getEvent(struct Track * tr, int evNum)
77{ 24{